Merge "Use HOST_LIBRARY_PATH to access host shared libraries."
diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc
index 1cfd194..16c1e00 100644
--- a/compiler/driver/compiler_driver.cc
+++ b/compiler/driver/compiler_driver.cc
@@ -560,9 +560,8 @@
soa.AddLocalReference<jobject>(method->GetDeclaringClass()->GetClassLoader()));
jclass_loader = soa.Env()->NewGlobalRef(local_class_loader.get());
// Find the dex_file
- MethodHelper mh(method);
- dex_file = &mh.GetDexFile();
- class_def_idx = mh.GetClassDefIndex();
+ dex_file = method->GetDexFile();
+ class_def_idx = method->GetClassDefIndex();
}
const DexFile::CodeItem* code_item = dex_file->GetCodeItem(method->GetCodeItemOffset());
self->TransitionFromRunnableToSuspended(kNative);
@@ -630,7 +629,7 @@
static void ResolveExceptionsForMethod(MethodHelper* mh,
std::set<std::pair<uint16_t, const DexFile*>>& exceptions_to_resolve)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- const DexFile::CodeItem* code_item = mh->GetCodeItem();
+ const DexFile::CodeItem* code_item = mh->GetMethod()->GetCodeItem();
if (code_item == NULL) {
return; // native or abstract method
}
@@ -650,10 +649,10 @@
uint16_t encoded_catch_handler_handlers_type_idx =
DecodeUnsignedLeb128(&encoded_catch_handler_list);
// Add to set of types to resolve if not already in the dex cache resolved types
- if (!mh->IsResolvedTypeIdx(encoded_catch_handler_handlers_type_idx)) {
+ if (!mh->GetMethod()->IsResolvedTypeIdx(encoded_catch_handler_handlers_type_idx)) {
exceptions_to_resolve.insert(
std::pair<uint16_t, const DexFile*>(encoded_catch_handler_handlers_type_idx,
- &mh->GetDexFile()));
+ mh->GetMethod()->GetDexFile()));
}
// ignore address associated with catch handler
DecodeUnsignedLeb128(&encoded_catch_handler_list);
@@ -669,15 +668,14 @@
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
std::set<std::pair<uint16_t, const DexFile*>>* exceptions_to_resolve =
reinterpret_cast<std::set<std::pair<uint16_t, const DexFile*>>*>(arg);
- MethodHelper mh;
+ StackHandleScope<1> hs(Thread::Current());
+ MethodHelper mh(hs.NewHandle<mirror::ArtMethod>(nullptr));
for (size_t i = 0; i < c->NumVirtualMethods(); ++i) {
- mirror::ArtMethod* m = c->GetVirtualMethod(i);
- mh.ChangeMethod(m);
+ mh.ChangeMethod(c->GetVirtualMethod(i));
ResolveExceptionsForMethod(&mh, *exceptions_to_resolve);
}
for (size_t i = 0; i < c->NumDirectMethods(); ++i) {
- mirror::ArtMethod* m = c->GetDirectMethod(i);
- mh.ChangeMethod(m);
+ mh.ChangeMethod(c->GetDirectMethod(i));
ResolveExceptionsForMethod(&mh, *exceptions_to_resolve);
}
return true;
@@ -1117,8 +1115,7 @@
*stats_flags |= kFlagDirectCallToBoot | kFlagDirectMethodToBoot;
}
if (!use_dex_cache && compiling_boot) {
- MethodHelper mh(method);
- if (!IsImageClass(mh.GetDeclaringClassDescriptor())) {
+ if (!IsImageClass(method->GetDeclaringClassDescriptor())) {
// We can only branch directly to Methods that are resolved in the DexCache.
// Otherwise we won't invoke the resolution trampoline.
use_dex_cache = true;
@@ -1131,8 +1128,10 @@
target_method->dex_method_index = method->GetDexMethodIndex();
} else {
if (no_guarantee_of_dex_cache_entry) {
+ StackHandleScope<1> hs(Thread::Current());
+ MethodHelper mh(hs.NewHandle(method));
// See if the method is also declared in this dex cache.
- uint32_t dex_method_idx = MethodHelper(method).FindDexMethodIndexInOtherDexFile(
+ uint32_t dex_method_idx = mh.FindDexMethodIndexInOtherDexFile(
*target_method->dex_file, target_method->dex_method_index);
if (dex_method_idx != DexFile::kDexNoIndex) {
target_method->dex_method_index = dex_method_idx;
diff --git a/oatdump/oatdump.cc b/oatdump/oatdump.cc
index d51179e..12970fc 100644
--- a/oatdump/oatdump.cc
+++ b/oatdump/oatdump.cc
@@ -209,7 +209,6 @@
}
const void* GetQuickOatCode(mirror::ArtMethod* m) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- MethodHelper mh(m);
for (size_t i = 0; i < oat_dex_files_.size(); i++) {
const OatFile::OatDexFile* oat_dex_file = oat_dex_files_[i];
CHECK(oat_dex_file != nullptr);
@@ -220,7 +219,7 @@
<< "': " << error_msg;
} else {
const DexFile::ClassDef* class_def =
- dex_file->FindClassDef(mh.GetDeclaringClassDescriptor());
+ dex_file->FindClassDef(m->GetDeclaringClassDescriptor());
if (class_def != NULL) {
uint16_t class_def_index = dex_file->GetIndexForClassDef(*class_def);
const OatFile::OatClass oat_class = oat_dex_file->GetOatClass(class_def_index);
@@ -1094,11 +1093,11 @@
}
} else if (method->IsAbstract() || method->IsCalleeSaveMethod() ||
method->IsResolutionMethod() || method->IsImtConflictMethod() ||
- MethodHelper(method).IsClassInitializer()) {
+ method->IsClassInitializer()) {
DCHECK(method->GetNativeGcMap() == NULL) << PrettyMethod(method);
DCHECK(method->GetMappingTable() == NULL) << PrettyMethod(method);
} else {
- const DexFile::CodeItem* code_item = MethodHelper(method).GetCodeItem();
+ const DexFile::CodeItem* code_item = method->GetCodeItem();
size_t dex_instruction_bytes = code_item->insns_size_in_code_units_ * 2;
state->stats_.dex_instruction_bytes += dex_instruction_bytes;
diff --git a/runtime/check_jni.cc b/runtime/check_jni.cc
index 46c4389..a816489 100644
--- a/runtime/check_jni.cc
+++ b/runtime/check_jni.cc
@@ -129,7 +129,7 @@
// such as NewByteArray.
// If -verbose:third-party-jni is on, we want to log any JNI function calls
// made by a third-party native method.
- std::string class_name(MethodHelper(method).GetDeclaringClassDescriptor());
+ std::string class_name(method->GetDeclaringClassDescriptor());
if (!vm->trace.empty() && class_name.find(vm->trace) != std::string::npos) {
return true;
}
@@ -284,7 +284,7 @@
if (m == nullptr) {
return;
}
- if (*expectedType != MethodHelper(m).GetShorty()[0]) {
+ if (*expectedType != m->GetShorty()[0]) {
JniAbortF(function_name_, "the return type of %s does not match %s",
function_name_, PrettyMethod(m).c_str());
}
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 28164cd..7385382 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -2754,7 +2754,7 @@
}
static void CheckProxyConstructor(mirror::ArtMethod* constructor);
-static void CheckProxyMethod(mirror::ArtMethod* method,
+static void CheckProxyMethod(Handle<mirror::ArtMethod> method,
Handle<mirror::ArtMethod> prototype);
mirror::Class* ClassLinker::CreateProxyClass(ScopedObjectAccessAlreadyRunnable& soa, jstring name,
@@ -2876,11 +2876,12 @@
CHECK(klass->GetIFields() == nullptr);
CheckProxyConstructor(klass->GetDirectMethod(0));
for (size_t i = 0; i < num_virtual_methods; ++i) {
- StackHandleScope<1> hs(self);
+ StackHandleScope<2> hs(self);
mirror::ObjectArray<mirror::ArtMethod>* decoded_methods =
soa.Decode<mirror::ObjectArray<mirror::ArtMethod>*>(methods);
Handle<mirror::ArtMethod> prototype(hs.NewHandle(decoded_methods->Get(i)));
- CheckProxyMethod(klass->GetVirtualMethod(i), prototype);
+ Handle<mirror::ArtMethod> virtual_method(hs.NewHandle(klass->GetVirtualMethod(i)));
+ CheckProxyMethod(virtual_method, prototype);
}
mirror::String* decoded_name = soa.Decode<mirror::String*>(name);
@@ -2961,9 +2962,9 @@
static void CheckProxyConstructor(mirror::ArtMethod* constructor)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
CHECK(constructor->IsConstructor());
- MethodHelper mh(constructor);
- CHECK_STREQ(mh.GetName(), "<init>");
- CHECK_STREQ(mh.GetSignature().ToString().c_str(), "(Ljava/lang/reflect/InvocationHandler;)V");
+ CHECK_STREQ(constructor->GetName(), "<init>");
+ CHECK_STREQ(constructor->GetSignature().ToString().c_str(),
+ "(Ljava/lang/reflect/InvocationHandler;)V");
DCHECK(constructor->IsPublic());
}
@@ -2996,7 +2997,7 @@
return method;
}
-static void CheckProxyMethod(mirror::ArtMethod* method, Handle<mirror::ArtMethod> prototype)
+static void CheckProxyMethod(Handle<mirror::ArtMethod> method, Handle<mirror::ArtMethod> prototype)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
// Basic sanity
CHECK(!prototype->IsFinal());
@@ -3011,9 +3012,9 @@
CHECK_EQ(prototype->GetDexMethodIndex(), method->GetDexMethodIndex());
MethodHelper mh(method);
- MethodHelper mh2(prototype.Get());
- CHECK_STREQ(mh.GetName(), mh2.GetName());
- CHECK_STREQ(mh.GetShorty(), mh2.GetShorty());
+ MethodHelper mh2(prototype);
+ CHECK_STREQ(method->GetName(), prototype->GetName());
+ CHECK_STREQ(method->GetShorty(), prototype->GetShorty());
// More complex sanity - via dex cache
CHECK_EQ(mh.GetReturnType(), mh2.GetReturnType());
}
@@ -3268,16 +3269,18 @@
return true;
}
// Begin with the methods local to the superclass.
- MethodHelper mh;
- MethodHelper super_mh;
+ StackHandleScope<2> hs(Thread::Current());
+ MethodHelper mh(hs.NewHandle<mirror::ArtMethod>(nullptr));
+ MethodHelper super_mh(hs.NewHandle<mirror::ArtMethod>(nullptr));
if (klass->HasSuperClass() &&
klass->GetClassLoader() != klass->GetSuperClass()->GetClassLoader()) {
for (int i = klass->GetSuperClass()->GetVTable()->GetLength() - 1; i >= 0; --i) {
mh.ChangeMethod(klass->GetVTable()->GetWithoutChecks(i));
super_mh.ChangeMethod(klass->GetSuperClass()->GetVTable()->GetWithoutChecks(i));
- bool is_override = mh.GetMethod() != super_mh.GetMethod();
- if (is_override && !mh.HasSameSignatureWithDifferentClassLoaders(&super_mh)) {
- ThrowLinkageError(klass.Get(), "Class %s method %s resolves differently in superclass %s",
+ if (mh.GetMethod() != super_mh.GetMethod() &&
+ !mh.HasSameSignatureWithDifferentClassLoaders(&super_mh)) {
+ ThrowLinkageError(klass.Get(),
+ "Class %s method %s resolves differently in superclass %s",
PrettyDescriptor(klass.Get()).c_str(),
PrettyMethod(mh.GetMethod()).c_str(),
PrettyDescriptor(klass->GetSuperClass()).c_str());
@@ -3291,9 +3294,10 @@
for (uint32_t j = 0; j < num_methods; ++j) {
mh.ChangeMethod(klass->GetIfTable()->GetMethodArray(i)->GetWithoutChecks(j));
super_mh.ChangeMethod(klass->GetIfTable()->GetInterface(i)->GetVirtualMethod(j));
- bool is_override = mh.GetMethod() != super_mh.GetMethod();
- if (is_override && !mh.HasSameSignatureWithDifferentClassLoaders(&super_mh)) {
- ThrowLinkageError(klass.Get(), "Class %s method %s resolves differently in interface %s",
+ if (mh.GetMethod() != super_mh.GetMethod() &&
+ !mh.HasSameSignatureWithDifferentClassLoaders(&super_mh)) {
+ ThrowLinkageError(klass.Get(),
+ "Class %s method %s resolves differently in interface %s",
PrettyDescriptor(klass.Get()).c_str(),
PrettyMethod(mh.GetMethod()).c_str(),
PrettyDescriptor(klass->GetIfTable()->GetInterface(i)).c_str());
@@ -3335,7 +3339,7 @@
if (!LinkSuperClass(klass)) {
return false;
}
- if (!LinkMethods(klass, interfaces)) {
+ if (!LinkMethods(self, klass, interfaces)) {
return false;
}
if (!LinkInstanceFields(klass)) {
@@ -3454,7 +3458,7 @@
}
// Populate the class vtable and itable. Compute return type indices.
-bool ClassLinker::LinkMethods(Handle<mirror::Class> klass,
+bool ClassLinker::LinkMethods(Thread* self, Handle<mirror::Class> klass,
Handle<mirror::ObjectArray<mirror::Class>> interfaces) {
if (klass->IsInterface()) {
// No vtable.
@@ -3470,20 +3474,19 @@
return LinkInterfaceMethods(klass, interfaces);
} else {
// Link virtual and interface method tables
- return LinkVirtualMethods(klass) && LinkInterfaceMethods(klass, interfaces);
+ return LinkVirtualMethods(self, klass) && LinkInterfaceMethods(klass, interfaces);
}
return true;
}
-bool ClassLinker::LinkVirtualMethods(Handle<mirror::Class> klass) {
- Thread* self = Thread::Current();
+bool ClassLinker::LinkVirtualMethods(Thread* self, Handle<mirror::Class> klass) {
if (klass->HasSuperClass()) {
- uint32_t max_count = (klass->NumVirtualMethods() +
- klass->GetSuperClass()->GetVTable()->GetLength());
+ uint32_t max_count = klass->NumVirtualMethods() +
+ klass->GetSuperClass()->GetVTable()->GetLength();
size_t actual_count = klass->GetSuperClass()->GetVTable()->GetLength();
CHECK_LE(actual_count, max_count);
// TODO: do not assign to the vtable field until it is fully constructed.
- StackHandleScope<1> hs(self);
+ StackHandleScope<3> hs(self);
Handle<mirror::ObjectArray<mirror::ArtMethod>> vtable(
hs.NewHandle(klass->GetSuperClass()->GetVTable()->CopyOf(self, max_count)));
if (UNLIKELY(vtable.Get() == NULL)) {
@@ -3491,20 +3494,22 @@
return false;
}
// See if any of our virtual methods override the superclass.
+ MethodHelper local_mh(hs.NewHandle<mirror::ArtMethod>(nullptr));
+ MethodHelper super_mh(hs.NewHandle<mirror::ArtMethod>(nullptr));
for (size_t i = 0; i < klass->NumVirtualMethods(); ++i) {
mirror::ArtMethod* local_method = klass->GetVirtualMethodDuringLinking(i);
- MethodHelper local_mh(local_method);
+ local_mh.ChangeMethod(local_method);
size_t j = 0;
for (; j < actual_count; ++j) {
mirror::ArtMethod* super_method = vtable->Get(j);
- MethodHelper super_mh(super_method);
+ super_mh.ChangeMethod(super_method);
if (local_mh.HasSameNameAndSignature(&super_mh)) {
if (klass->CanAccessMember(super_method->GetDeclaringClass(),
super_method->GetAccessFlags())) {
if (super_method->IsFinal()) {
ThrowLinkageError(klass.Get(), "Method %s overrides final method in class %s",
PrettyMethod(local_method).c_str(),
- super_mh.GetDeclaringClassDescriptor());
+ super_method->GetDeclaringClassDescriptor());
return false;
}
vtable->Set<false>(j, local_method);
@@ -3513,7 +3518,7 @@
} else {
LOG(WARNING) << "Before Android 4.1, method " << PrettyMethod(local_method)
<< " would have incorrectly overridden the package-private method in "
- << PrettyDescriptor(super_mh.GetDeclaringClassDescriptor());
+ << PrettyDescriptor(super_method->GetDeclaringClassDescriptor());
}
}
}
@@ -3539,7 +3544,7 @@
}
klass->SetVTable(vtable.Get());
} else {
- CHECK(klass.Get() == GetClassRoot(kJavaLangObject));
+ CHECK_EQ(klass.Get(), GetClassRoot(kJavaLangObject));
uint32_t num_virtual_methods = klass->NumVirtualMethods();
if (!IsUint(16, num_virtual_methods)) {
ThrowClassFormatError(klass.Get(), "Too many methods: %d", num_virtual_methods);
@@ -3565,8 +3570,9 @@
bool ClassLinker::LinkInterfaceMethods(Handle<mirror::Class> klass,
Handle<mirror::ObjectArray<mirror::Class>> interfaces) {
Thread* const self = Thread::Current();
+ Runtime* const runtime = Runtime::Current();
// Set the imt table to be all conflicts by default.
- klass->SetImTable(Runtime::Current()->GetDefaultImt());
+ klass->SetImTable(runtime->GetDefaultImt());
size_t super_ifcount;
if (klass->HasSuperClass()) {
super_ifcount = klass->GetSuperClass()->GetIfTableCount();
@@ -3604,7 +3610,7 @@
return true;
}
}
- StackHandleScope<2> hs(self);
+ StackHandleScope<4> hs(self);
Handle<mirror::IfTable> iftable(hs.NewHandle(AllocIfTable(self, ifcount)));
if (UNLIKELY(iftable.Get() == NULL)) {
CHECK(self->IsExceptionPending()); // OOME.
@@ -3684,6 +3690,8 @@
CHECK(self->IsExceptionPending()); // OOME.
return false;
}
+ MethodHelper interface_mh(hs.NewHandle<mirror::ArtMethod>(nullptr));
+ MethodHelper vtable_mh(hs.NewHandle<mirror::ArtMethod>(nullptr));
std::vector<mirror::ArtMethod*> miranda_list;
for (size_t i = 0; i < ifcount; ++i) {
size_t num_methods = iftable->GetInterface(i)->NumVirtualMethods();
@@ -3700,7 +3708,7 @@
hs.NewHandle(klass->GetVTableDuringLinking()));
for (size_t j = 0; j < num_methods; ++j) {
mirror::ArtMethod* interface_method = iftable->GetInterface(i)->GetVirtualMethod(j);
- MethodHelper interface_mh(interface_method);
+ interface_mh.ChangeMethod(interface_method);
int32_t k;
// For each method listed in the interface's method list, find the
// matching method in our class's method list. We want to favor the
@@ -3712,7 +3720,7 @@
// matter which direction we go. We walk it backward anyway.)
for (k = vtable->GetLength() - 1; k >= 0; --k) {
mirror::ArtMethod* vtable_method = vtable->Get(k);
- MethodHelper vtable_mh(vtable_method);
+ vtable_mh.ChangeMethod(vtable_method);
if (interface_mh.HasSameNameAndSignature(&vtable_mh)) {
if (!vtable_method->IsAbstract() && !vtable_method->IsPublic()) {
ThrowIllegalAccessError(
@@ -3729,7 +3737,7 @@
imtable->Set<false>(imt_index, vtable_method);
imtable_changed = true;
} else {
- imtable->Set<false>(imt_index, Runtime::Current()->GetImtConflictMethod());
+ imtable->Set<false>(imt_index, runtime->GetImtConflictMethod());
}
break;
}
@@ -3737,11 +3745,10 @@
if (k < 0) {
StackHandleScope<1> hs(self);
auto miranda_method = hs.NewHandle<mirror::ArtMethod>(nullptr);
- for (size_t mir = 0; mir < miranda_list.size(); mir++) {
- mirror::ArtMethod* mir_method = miranda_list[mir];
- MethodHelper vtable_mh(mir_method);
+ for (mirror::ArtMethod* mir_method : miranda_list) {
+ vtable_mh.ChangeMethod(mir_method);
if (interface_mh.HasSameNameAndSignature(&vtable_mh)) {
- miranda_method.Assign(miranda_list[mir]);
+ miranda_method.Assign(mir_method);
break;
}
}
@@ -3762,7 +3769,7 @@
}
if (imtable_changed) {
// Fill in empty entries in interface method table with conflict.
- mirror::ArtMethod* imt_conflict_method = Runtime::Current()->GetImtConflictMethod();
+ mirror::ArtMethod* imt_conflict_method = runtime->GetImtConflictMethod();
for (size_t i = 0; i < kImtSize; i++) {
if (imtable->Get(i) == NULL) {
imtable->Set<false>(i, imt_conflict_method);
diff --git a/runtime/class_linker.h b/runtime/class_linker.h
index ccf0558..a1d7bc6 100644
--- a/runtime/class_linker.h
+++ b/runtime/class_linker.h
@@ -499,11 +499,11 @@
bool LoadSuperAndInterfaces(Handle<mirror::Class> klass, const DexFile& dex_file)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- bool LinkMethods(Handle<mirror::Class> klass,
+ bool LinkMethods(Thread* self, Handle<mirror::Class> klass,
Handle<mirror::ObjectArray<mirror::Class>> interfaces)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- bool LinkVirtualMethods(Handle<mirror::Class> klass)
+ bool LinkVirtualMethods(Thread* self, Handle<mirror::Class> klass)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
bool LinkInterfaceMethods(Handle<mirror::Class> klass,
diff --git a/runtime/class_linker_test.cc b/runtime/class_linker_test.cc
index 45ab33a..04f6946 100644
--- a/runtime/class_linker_test.cc
+++ b/runtime/class_linker_test.cc
@@ -152,11 +152,10 @@
}
void AssertMethod(mirror::ArtMethod* method) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- MethodHelper mh(method);
EXPECT_TRUE(method != NULL);
EXPECT_TRUE(method->GetClass() != NULL);
- EXPECT_TRUE(mh.GetName() != NULL);
- EXPECT_TRUE(mh.GetSignature() != Signature::NoSignature());
+ EXPECT_TRUE(method->GetName() != NULL);
+ EXPECT_TRUE(method->GetSignature() != Signature::NoSignature());
EXPECT_TRUE(method->GetDexCacheStrings() != NULL);
EXPECT_TRUE(method->GetDexCacheResolvedMethods() != NULL);
@@ -203,8 +202,7 @@
if (klass->IsInterface()) {
EXPECT_TRUE(klass->IsAbstract());
if (klass->NumDirectMethods() == 1) {
- MethodHelper mh(klass->GetDirectMethod(0));
- EXPECT_TRUE(mh.IsClassInitializer());
+ EXPECT_TRUE(klass->GetDirectMethod(0)->IsClassInitializer());
EXPECT_TRUE(klass->GetDirectMethod(0)->IsDirect());
} else {
EXPECT_EQ(0U, klass->NumDirectMethods());
diff --git a/runtime/common_throws.cc b/runtime/common_throws.cc
index a3e3cfa..8de3068 100644
--- a/runtime/common_throws.cc
+++ b/runtime/common_throws.cc
@@ -363,7 +363,7 @@
}
void ThrowNullPointerExceptionFromDexPC(const ThrowLocation& throw_location) {
- const DexFile::CodeItem* code = MethodHelper(throw_location.GetMethod()).GetCodeItem();
+ const DexFile::CodeItem* code = throw_location.GetMethod()->GetCodeItem();
uint32_t throw_dex_pc = throw_location.GetDexPc();
CHECK_LT(throw_dex_pc, code->insns_size_in_code_units_);
const Instruction* instr = Instruction::At(&code->insns_[throw_dex_pc]);
diff --git a/runtime/debugger.cc b/runtime/debugger.cc
index 8e2340c..73ed590 100644
--- a/runtime/debugger.cc
+++ b/runtime/debugger.cc
@@ -70,7 +70,7 @@
}
int32_t LineNumber() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return MethodHelper(method).GetLineNumFromDexPC(dex_pc);
+ return method->GetLineNumFromDexPC(dex_pc);
}
};
@@ -1373,7 +1373,7 @@
std::string Dbg::GetMethodName(JDWP::MethodId method_id)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
mirror::ArtMethod* m = FromMethodId(method_id);
- return MethodHelper(m).GetName();
+ return m->GetName();
}
std::string Dbg::GetFieldName(JDWP::FieldId field_id)
@@ -1401,7 +1401,7 @@
*/
static uint16_t MangleSlot(uint16_t slot, mirror::ArtMethod* m)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- const DexFile::CodeItem* code_item = MethodHelper(m).GetCodeItem();
+ const DexFile::CodeItem* code_item = m->GetCodeItem();
if (code_item == nullptr) {
// We should not get here for a method without code (native, proxy or abstract). Log it and
// return the slot as is since all registers are arguments.
@@ -1423,7 +1423,7 @@
*/
static uint16_t DemangleSlot(uint16_t slot, mirror::ArtMethod* m)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- const DexFile::CodeItem* code_item = MethodHelper(m).GetCodeItem();
+ const DexFile::CodeItem* code_item = m->GetCodeItem();
if (code_item == nullptr) {
// We should not get here for a method without code (native, proxy or abstract). Log it and
// return the slot as is since all registers are arguments.
@@ -1480,10 +1480,9 @@
for (size_t i = 0; i < direct_method_count + virtual_method_count; ++i) {
mirror::ArtMethod* m = (i < direct_method_count) ? c->GetDirectMethod(i) : c->GetVirtualMethod(i - direct_method_count);
- MethodHelper mh(m);
expandBufAddMethodId(pReply, ToMethodId(m));
- expandBufAddUtf8String(pReply, mh.GetName());
- expandBufAddUtf8String(pReply, mh.GetSignature().ToString());
+ expandBufAddUtf8String(pReply, m->GetName());
+ expandBufAddUtf8String(pReply, m->GetSignature().ToString());
if (with_generic) {
static const char genericSignature[1] = "";
expandBufAddUtf8String(pReply, genericSignature);
@@ -1525,8 +1524,7 @@
}
};
mirror::ArtMethod* m = FromMethodId(method_id);
- MethodHelper mh(m);
- const DexFile::CodeItem* code_item = mh.GetCodeItem();
+ const DexFile::CodeItem* code_item = m->GetCodeItem();
uint64_t start, end;
if (code_item == nullptr) {
DCHECK(m->IsNative() || m->IsProxyMethod());
@@ -1550,25 +1548,30 @@
context.pReply = pReply;
if (code_item != nullptr) {
- mh.GetDexFile().DecodeDebugInfo(code_item, m->IsStatic(), m->GetDexMethodIndex(),
- DebugCallbackContext::Callback, NULL, &context);
+ m->GetDexFile()->DecodeDebugInfo(code_item, m->IsStatic(), m->GetDexMethodIndex(),
+ DebugCallbackContext::Callback, NULL, &context);
}
JDWP::Set4BE(expandBufGetBuffer(pReply) + numLinesOffset, context.numItems);
}
-void Dbg::OutputVariableTable(JDWP::RefTypeId, JDWP::MethodId method_id, bool with_generic, JDWP::ExpandBuf* pReply) {
+void Dbg::OutputVariableTable(JDWP::RefTypeId, JDWP::MethodId method_id, bool with_generic,
+ JDWP::ExpandBuf* pReply) {
struct DebugCallbackContext {
mirror::ArtMethod* method;
JDWP::ExpandBuf* pReply;
size_t variable_count;
bool with_generic;
- static void Callback(void* context, uint16_t slot, uint32_t startAddress, uint32_t endAddress, const char* name, const char* descriptor, const char* signature)
+ static void Callback(void* context, uint16_t slot, uint32_t startAddress, uint32_t endAddress,
+ const char* name, const char* descriptor, const char* signature)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
DebugCallbackContext* pContext = reinterpret_cast<DebugCallbackContext*>(context);
- VLOG(jdwp) << StringPrintf(" %2zd: %d(%d) '%s' '%s' '%s' actual slot=%d mangled slot=%d", pContext->variable_count, startAddress, endAddress - startAddress, name, descriptor, signature, slot, MangleSlot(slot, pContext->method));
+ VLOG(jdwp) << StringPrintf(" %2zd: %d(%d) '%s' '%s' '%s' actual slot=%d mangled slot=%d",
+ pContext->variable_count, startAddress, endAddress - startAddress,
+ name, descriptor, signature, slot,
+ MangleSlot(slot, pContext->method));
slot = MangleSlot(slot, pContext->method);
@@ -1585,11 +1588,10 @@
}
};
mirror::ArtMethod* m = FromMethodId(method_id);
- MethodHelper mh(m);
// arg_count considers doubles and longs to take 2 units.
// variable_count considers everything to take 1 unit.
- std::string shorty(mh.GetShorty());
+ std::string shorty(m->GetShorty());
expandBufAdd4BE(pReply, mirror::ArtMethod::NumArgRegisters(shorty));
// We don't know the total number of variables yet, so leave a blank and update it later.
@@ -1602,10 +1604,11 @@
context.variable_count = 0;
context.with_generic = with_generic;
- const DexFile::CodeItem* code_item = mh.GetCodeItem();
+ const DexFile::CodeItem* code_item = m->GetCodeItem();
if (code_item != nullptr) {
- mh.GetDexFile().DecodeDebugInfo(code_item, m->IsStatic(), m->GetDexMethodIndex(), NULL,
- DebugCallbackContext::Callback, &context);
+ m->GetDexFile()->DecodeDebugInfo(
+ code_item, m->IsStatic(), m->GetDexMethodIndex(), NULL, DebugCallbackContext::Callback,
+ &context);
}
JDWP::Set4BE(expandBufGetBuffer(pReply) + variable_count_offset, context.variable_count);
@@ -1614,7 +1617,7 @@
void Dbg::OutputMethodReturnValue(JDWP::MethodId method_id, const JValue* return_value,
JDWP::ExpandBuf* pReply) {
mirror::ArtMethod* m = FromMethodId(method_id);
- JDWP::JdwpTag tag = BasicTagFromDescriptor(MethodHelper(m).GetShorty());
+ JDWP::JdwpTag tag = BasicTagFromDescriptor(m->GetShorty());
OutputJValue(tag, return_value, pReply);
}
@@ -1632,8 +1635,7 @@
if (m == NULL) {
return JDWP::ERR_INVALID_METHODID;
}
- MethodHelper mh(m);
- const DexFile::CodeItem* code_item = mh.GetCodeItem();
+ const DexFile::CodeItem* code_item = m->GetCodeItem();
size_t byte_count = code_item->insns_size_in_code_units_ * 2;
const uint8_t* begin = reinterpret_cast<const uint8_t*>(code_item->insns_);
const uint8_t* end = begin + byte_count;
@@ -2875,18 +2877,18 @@
static bool IsMethodPossiblyInlined(Thread* self, mirror::ArtMethod* m)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- MethodHelper mh(m);
- const DexFile::CodeItem* code_item = mh.GetCodeItem();
+ const DexFile::CodeItem* code_item = m->GetCodeItem();
if (code_item == nullptr) {
// TODO We should not be asked to watch location in a native or abstract method so the code item
// should never be null. We could just check we never encounter this case.
return false;
}
StackHandleScope<2> hs(self);
- Handle<mirror::DexCache> dex_cache(hs.NewHandle(mh.GetDexCache()));
- Handle<mirror::ClassLoader> class_loader(hs.NewHandle(mh.GetClassLoader()));
- verifier::MethodVerifier verifier(&mh.GetDexFile(), &dex_cache, &class_loader,
- &mh.GetClassDef(), code_item, m->GetDexMethodIndex(), m,
+ mirror::Class* declaring_class = m->GetDeclaringClass();
+ Handle<mirror::DexCache> dex_cache(hs.NewHandle(declaring_class->GetDexCache()));
+ Handle<mirror::ClassLoader> class_loader(hs.NewHandle(declaring_class->GetClassLoader()));
+ verifier::MethodVerifier verifier(dex_cache->GetDexFile(), &dex_cache, &class_loader,
+ &m->GetClassDef(), code_item, m->GetDexMethodIndex(), m,
m->GetAccessFlags(), false, true, false);
// Note: we don't need to verify the method.
return InlineMethodAnalyser::AnalyseMethodCode(&verifier, nullptr);
@@ -3156,11 +3158,10 @@
single_step_control->dex_pcs.clear();
mirror::ArtMethod* m = single_step_control->method;
if (!m->IsNative()) {
- MethodHelper mh(m);
- const DexFile::CodeItem* const code_item = mh.GetCodeItem();
+ const DexFile::CodeItem* const code_item = m->GetCodeItem();
DebugCallbackContext context(single_step_control, line_number, code_item);
- mh.GetDexFile().DecodeDebugInfo(code_item, m->IsStatic(), m->GetDexMethodIndex(),
- DebugCallbackContext::Callback, NULL, &context);
+ m->GetDexFile()->DecodeDebugInfo(code_item, m->IsStatic(), m->GetDexMethodIndex(),
+ DebugCallbackContext::Callback, NULL, &context);
}
//
@@ -3308,32 +3309,41 @@
}
// Check the argument list matches the method.
- MethodHelper mh(m);
- if (mh.GetShortyLength() - 1 != arg_count) {
+ uint32_t shorty_len = 0;
+ const char* shorty = m->GetShorty(&shorty_len);
+ if (shorty_len - 1 != arg_count) {
return JDWP::ERR_ILLEGAL_ARGUMENT;
}
- const char* shorty = mh.GetShorty();
- const DexFile::TypeList* types = mh.GetParameterTypeList();
- for (size_t i = 0; i < arg_count; ++i) {
- if (shorty[i + 1] != JdwpTagToShortyChar(arg_types[i])) {
- return JDWP::ERR_ILLEGAL_ARGUMENT;
- }
- if (shorty[i + 1] == 'L') {
- // Did we really get an argument of an appropriate reference type?
- mirror::Class* parameter_type = mh.GetClassFromTypeIdx(types->GetTypeItem(i).type_idx_);
- mirror::Object* argument = gRegistry->Get<mirror::Object*>(arg_values[i]);
- if (argument == ObjectRegistry::kInvalidObject) {
- return JDWP::ERR_INVALID_OBJECT;
- }
- if (argument != NULL && !argument->InstanceOf(parameter_type)) {
+ {
+ StackHandleScope<3> hs(soa.Self());
+ MethodHelper mh(hs.NewHandle(m));
+ HandleWrapper<mirror::Object> h_obj(hs.NewHandleWrapper(&receiver));
+ HandleWrapper<mirror::Class> h_klass(hs.NewHandleWrapper(&c));
+ const DexFile::TypeList* types = m->GetParameterTypeList();
+ for (size_t i = 0; i < arg_count; ++i) {
+ if (shorty[i + 1] != JdwpTagToShortyChar(arg_types[i])) {
return JDWP::ERR_ILLEGAL_ARGUMENT;
}
- // Turn the on-the-wire ObjectId into a jobject.
- jvalue& v = reinterpret_cast<jvalue&>(arg_values[i]);
- v.l = gRegistry->GetJObject(arg_values[i]);
+ if (shorty[i + 1] == 'L') {
+ // Did we really get an argument of an appropriate reference type?
+ mirror::Class* parameter_type = mh.GetClassFromTypeIdx(types->GetTypeItem(i).type_idx_);
+ mirror::Object* argument = gRegistry->Get<mirror::Object*>(arg_values[i]);
+ if (argument == ObjectRegistry::kInvalidObject) {
+ return JDWP::ERR_INVALID_OBJECT;
+ }
+ if (argument != NULL && !argument->InstanceOf(parameter_type)) {
+ return JDWP::ERR_ILLEGAL_ARGUMENT;
+ }
+
+ // Turn the on-the-wire ObjectId into a jobject.
+ jvalue& v = reinterpret_cast<jvalue&>(arg_values[i]);
+ v.l = gRegistry->GetJObject(arg_values[i]);
+ }
}
+ // Update in case it moved.
+ m = mh.GetMethod();
}
req->receiver = receiver;
@@ -3452,7 +3462,7 @@
mirror::Throwable* exception = soa.Self()->GetException(NULL);
soa.Self()->ClearException();
pReq->exception = gRegistry->Add(exception);
- pReq->result_tag = BasicTagFromDescriptor(MethodHelper(m.Get()).GetShorty());
+ pReq->result_tag = BasicTagFromDescriptor(m.Get()->GetShorty());
if (pReq->exception != 0) {
VLOG(jdwp) << " JDWP invocation returning with exception=" << exception
<< " " << exception->Dump();
@@ -4296,10 +4306,10 @@
DISALLOW_COPY_AND_ASSIGN(StringTable);
};
-static const char* GetMethodSourceFile(MethodHelper* mh)
+static const char* GetMethodSourceFile(mirror::ArtMethod* method)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- DCHECK(mh != nullptr);
- const char* source_file = mh->GetDeclaringClassSourceFile();
+ DCHECK(method != nullptr);
+ const char* source_file = method->GetDeclaringClassSourceFile();
return (source_file != nullptr) ? source_file : "";
}
@@ -4368,14 +4378,12 @@
class_names.Add(record->type->GetDescriptor().c_str());
- MethodHelper mh;
for (size_t i = 0; i < kMaxAllocRecordStackDepth; i++) {
mirror::ArtMethod* m = record->stack[i].method;
if (m != NULL) {
- mh.ChangeMethod(m);
- class_names.Add(mh.GetDeclaringClassDescriptor());
- method_names.Add(mh.GetName());
- filenames.Add(GetMethodSourceFile(&mh));
+ class_names.Add(m->GetDeclaringClassDescriptor());
+ method_names.Add(m->GetName());
+ filenames.Add(GetMethodSourceFile(m));
}
}
@@ -4427,17 +4435,16 @@
JDWP::Append2BE(bytes, allocated_object_class_name_index);
JDWP::Append1BE(bytes, stack_depth);
- MethodHelper mh;
for (size_t stack_frame = 0; stack_frame < stack_depth; ++stack_frame) {
// For each stack frame:
// (2b) method's class name
// (2b) method name
// (2b) method source file
// (2b) line number, clipped to 32767; -2 if native; -1 if no source
- mh.ChangeMethod(record->stack[stack_frame].method);
- size_t class_name_index = class_names.IndexOf(mh.GetDeclaringClassDescriptor());
- size_t method_name_index = method_names.IndexOf(mh.GetName());
- size_t file_name_index = filenames.IndexOf(GetMethodSourceFile(&mh));
+ mirror::ArtMethod* m = record->stack[stack_frame].method;
+ size_t class_name_index = class_names.IndexOf(m->GetDeclaringClassDescriptor());
+ size_t method_name_index = method_names.IndexOf(m->GetName());
+ size_t file_name_index = filenames.IndexOf(GetMethodSourceFile(m));
JDWP::Append2BE(bytes, class_name_index);
JDWP::Append2BE(bytes, method_name_index);
JDWP::Append2BE(bytes, file_name_index);
diff --git a/runtime/entrypoints/entrypoint_utils.cc b/runtime/entrypoints/entrypoint_utils.cc
index 320273d..a0e32f5 100644
--- a/runtime/entrypoints/entrypoint_utils.cc
+++ b/runtime/entrypoints/entrypoint_utils.cc
@@ -189,18 +189,21 @@
// Do nothing.
return zero;
} else {
+ StackHandleScope<1> hs(soa.Self());
+ MethodHelper mh_interface_method(
+ hs.NewHandle(soa.Decode<mirror::ArtMethod*>(interface_method_jobj)));
+ // This can cause thread suspension.
+ mirror::Class* result_type = mh_interface_method.GetReturnType();
mirror::Object* result_ref = soa.Decode<mirror::Object*>(result);
mirror::Object* rcvr = soa.Decode<mirror::Object*>(rcvr_jobj);
- mirror::ArtMethod* interface_method =
- soa.Decode<mirror::ArtMethod*>(interface_method_jobj);
- mirror::Class* result_type = MethodHelper(interface_method).GetReturnType();
mirror::ArtMethod* proxy_method;
- if (interface_method->GetDeclaringClass()->IsInterface()) {
- proxy_method = rcvr->GetClass()->FindVirtualMethodForInterface(interface_method);
+ if (mh_interface_method.GetMethod()->GetDeclaringClass()->IsInterface()) {
+ proxy_method = rcvr->GetClass()->FindVirtualMethodForInterface(
+ mh_interface_method.GetMethod());
} else {
// Proxy dispatch to a method defined in Object.
- DCHECK(interface_method->GetDeclaringClass()->IsObjectClass());
- proxy_method = interface_method;
+ DCHECK(mh_interface_method.GetMethod()->GetDeclaringClass()->IsObjectClass());
+ proxy_method = mh_interface_method.GetMethod();
}
ThrowLocation throw_location(rcvr, proxy_method, -1);
JValue result_unboxed;
diff --git a/runtime/entrypoints/entrypoint_utils.h b/runtime/entrypoints/entrypoint_utils.h
index d0ae746..09899c0 100644
--- a/runtime/entrypoints/entrypoint_utils.h
+++ b/runtime/entrypoints/entrypoint_utils.h
@@ -433,9 +433,8 @@
if (access_check &&
(vtable == nullptr || vtable_index >= static_cast<uint32_t>(vtable->GetLength()))) {
// Behavior to agree with that of the verifier.
- MethodHelper mh(resolved_method);
- ThrowNoSuchMethodError(type, resolved_method->GetDeclaringClass(), mh.GetName(),
- mh.GetSignature());
+ ThrowNoSuchMethodError(type, resolved_method->GetDeclaringClass(),
+ resolved_method->GetName(), resolved_method->GetSignature());
return nullptr; // Failure.
}
DCHECK(vtable != nullptr);
@@ -450,9 +449,8 @@
vtable = (super_class != nullptr) ? super_class->GetVTable() : nullptr;
if (vtable == nullptr || vtable_index >= static_cast<uint32_t>(vtable->GetLength())) {
// Behavior to agree with that of the verifier.
- MethodHelper mh(resolved_method);
- ThrowNoSuchMethodError(type, resolved_method->GetDeclaringClass(), mh.GetName(),
- mh.GetSignature());
+ ThrowNoSuchMethodError(type, resolved_method->GetDeclaringClass(),
+ resolved_method->GetName(), resolved_method->GetSignature());
return nullptr; // Failure.
}
} else {
@@ -682,11 +680,13 @@
JniAbortF(NULL, "invalid reference returned from %s", PrettyMethod(m).c_str());
}
// Make sure that the result is an instance of the type this method was expected to return.
- mirror::Class* return_type = MethodHelper(m).GetReturnType();
+ StackHandleScope<1> hs(self);
+ Handle<mirror::ArtMethod> h_m(hs.NewHandle(m));
+ mirror::Class* return_type = MethodHelper(h_m).GetReturnType();
if (!o->InstanceOf(return_type)) {
- JniAbortF(NULL, "attempt to return an instance of %s from %s",
- PrettyTypeOf(o).c_str(), PrettyMethod(m).c_str());
+ JniAbortF(NULL, "attempt to return an instance of %s from %s", PrettyTypeOf(o).c_str(),
+ PrettyMethod(h_m.Get()).c_str());
}
}
diff --git a/runtime/entrypoints/portable/portable_fillarray_entrypoints.cc b/runtime/entrypoints/portable/portable_fillarray_entrypoints.cc
index 1005d0e..335a617 100644
--- a/runtime/entrypoints/portable/portable_fillarray_entrypoints.cc
+++ b/runtime/entrypoints/portable/portable_fillarray_entrypoints.cc
@@ -26,7 +26,7 @@
mirror::Array* array,
uint32_t payload_offset)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- const DexFile::CodeItem* code_item = MethodHelper(method).GetCodeItem();
+ const DexFile::CodeItem* code_item = method->GetCodeItem();
const Instruction::ArrayDataPayload* payload =
reinterpret_cast<const Instruction::ArrayDataPayload*>(code_item->insns_ + payload_offset);
DCHECK_EQ(payload->ident, static_cast<uint16_t>(Instruction::kArrayDataSignature));
diff --git a/runtime/entrypoints/portable/portable_invoke_entrypoints.cc b/runtime/entrypoints/portable/portable_invoke_entrypoints.cc
index 3a898e8..eb50ec3 100644
--- a/runtime/entrypoints/portable/portable_invoke_entrypoints.cc
+++ b/runtime/entrypoints/portable/portable_invoke_entrypoints.cc
@@ -41,9 +41,8 @@
// When we return, the caller will branch to this address, so it had better not be 0!
if (UNLIKELY(code == NULL)) {
- MethodHelper mh(method);
LOG(FATAL) << "Code was NULL in method: " << PrettyMethod(method)
- << " location: " << mh.GetDexFile().GetLocation();
+ << " location: " << method->GetDexFile()->GetLocation();
}
return method;
}
diff --git a/runtime/entrypoints/portable/portable_throw_entrypoints.cc b/runtime/entrypoints/portable/portable_throw_entrypoints.cc
index 1fdb832..189e6b5 100644
--- a/runtime/entrypoints/portable/portable_throw_entrypoints.cc
+++ b/runtime/entrypoints/portable/portable_throw_entrypoints.cc
@@ -79,8 +79,9 @@
return -1;
}
mirror::Class* exception_type = exception->GetClass();
- MethodHelper mh(current_method);
- const DexFile::CodeItem* code_item = mh.GetCodeItem();
+ StackHandleScope<1> hs(self);
+ MethodHelper mh(hs.NewHandle(current_method));
+ const DexFile::CodeItem* code_item = current_method->GetCodeItem();
DCHECK_LT(ti_offset, code_item->tries_size_);
const DexFile::TryItem* try_item = DexFile::GetTryItems(*code_item, ti_offset);
@@ -102,7 +103,7 @@
// TODO: check, the verifier (class linker?) should take care of resolving all exception
// classes early.
LOG(WARNING) << "Unresolved exception class when finding catch block: "
- << mh.GetTypeDescriptorFromTypeIdx(iter_type_idx);
+ << current_method->GetTypeDescriptorFromTypeIdx(iter_type_idx);
} else if (iter_exception_type->IsAssignableFrom(exception_type)) {
catch_dex_pc = it.GetHandlerAddress();
result = iter_index;
@@ -112,13 +113,11 @@
}
if (result != -1) {
// Handler found.
- Runtime::Current()->GetInstrumentation()->ExceptionCaughtEvent(self,
- throw_location,
- current_method,
- catch_dex_pc,
- exception);
+ Runtime::Current()->GetInstrumentation()->ExceptionCaughtEvent(
+ self, throw_location, current_method, catch_dex_pc, exception);
// If the catch block has no move-exception then clear the exception for it.
- const Instruction* first_catch_instr = Instruction::At(&mh.GetCodeItem()->insns_[catch_dex_pc]);
+ const Instruction* first_catch_instr = Instruction::At(
+ ¤t_method->GetCodeItem()->insns_[catch_dex_pc]);
if (first_catch_instr->Opcode() != Instruction::MOVE_EXCEPTION) {
self->ClearException();
}
diff --git a/runtime/entrypoints/portable/portable_trampoline_entrypoints.cc b/runtime/entrypoints/portable/portable_trampoline_entrypoints.cc
index 3756f47..6825e78 100644
--- a/runtime/entrypoints/portable/portable_trampoline_entrypoints.cc
+++ b/runtime/entrypoints/portable/portable_trampoline_entrypoints.cc
@@ -196,8 +196,9 @@
return 0;
} else {
const char* old_cause = self->StartAssertNoThreadSuspension("Building interpreter shadow frame");
- MethodHelper mh(method);
- const DexFile::CodeItem* code_item = mh.GetCodeItem();
+ StackHandleScope<2> hs(self);
+ MethodHelper mh(hs.NewHandle(method));
+ const DexFile::CodeItem* code_item = method->GetCodeItem();
uint16_t num_regs = code_item->registers_size_;
void* memory = alloca(ShadowFrame::ComputeSize(num_regs));
ShadowFrame* shadow_frame(ShadowFrame::Create(num_regs, NULL, // No last shadow coming from quick.
@@ -214,7 +215,6 @@
if (method->IsStatic() && !method->GetDeclaringClass()->IsInitializing()) {
// Ensure static method's class is initialized.
- StackHandleScope<1> hs(self);
Handle<mirror::Class> h_class(hs.NewHandle(method->GetDeclaringClass()));
if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(h_class, true, true)) {
DCHECK(Thread::Current()->IsExceptionPending());
@@ -294,7 +294,8 @@
jobject rcvr_jobj = soa.AddLocalReference<jobject>(receiver);
// Placing arguments into args vector and remove the receiver.
- MethodHelper proxy_mh(proxy_method);
+ StackHandleScope<1> hs(self);
+ MethodHelper proxy_mh(hs.NewHandle(proxy_method));
std::vector<jvalue> args;
BuildPortableArgumentVisitor local_ref_visitor(proxy_mh, sp, soa, args);
local_ref_visitor.VisitArguments();
@@ -327,7 +328,7 @@
InvokeType invoke_type;
bool is_range;
if (called->IsRuntimeMethod()) {
- const DexFile::CodeItem* code = MethodHelper(caller).GetCodeItem();
+ const DexFile::CodeItem* code = caller->GetCodeItem();
CHECK_LT(dex_pc, code->insns_size_in_code_units_);
const Instruction* instr = Instruction::At(&code->insns_[dex_pc]);
Instruction::Code instr_code = instr->Opcode();
diff --git a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
index 63010cf..514d1aa 100644
--- a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
+++ b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
@@ -466,16 +466,16 @@
} else {
DCHECK(!method->IsNative()) << PrettyMethod(method);
const char* old_cause = self->StartAssertNoThreadSuspension("Building interpreter shadow frame");
- MethodHelper mh(method);
- const DexFile::CodeItem* code_item = mh.GetCodeItem();
+ const DexFile::CodeItem* code_item = method->GetCodeItem();
DCHECK(code_item != nullptr) << PrettyMethod(method);
uint16_t num_regs = code_item->registers_size_;
void* memory = alloca(ShadowFrame::ComputeSize(num_regs));
ShadowFrame* shadow_frame(ShadowFrame::Create(num_regs, NULL, // No last shadow coming from quick.
method, 0, memory));
size_t first_arg_reg = code_item->registers_size_ - code_item->ins_size_;
- BuildQuickShadowFrameVisitor shadow_frame_builder(sp, mh.IsStatic(), mh.GetShorty(),
- mh.GetShortyLength(),
+ uint32_t shorty_len = 0;
+ const char* shorty = method->GetShorty(&shorty_len);
+ BuildQuickShadowFrameVisitor shadow_frame_builder(sp, method->IsStatic(), shorty, shorty_len,
shadow_frame, first_arg_reg);
shadow_frame_builder.VisitArguments();
// Push a transition back into managed code onto the linked list in thread.
@@ -495,6 +495,8 @@
}
}
+ StackHandleScope<1> hs(self);
+ MethodHelper mh(hs.NewHandle(method));
JValue result = interpreter::EnterInterpreterFromStub(self, mh, code_item, *shadow_frame);
// Pop transition.
self->PopManagedStackFragment(fragment);
@@ -596,11 +598,13 @@
jobject rcvr_jobj = soa.AddLocalReference<jobject>(receiver);
// Placing arguments into args vector and remove the receiver.
- MethodHelper proxy_mh(proxy_method);
- DCHECK(!proxy_mh.IsStatic()) << PrettyMethod(proxy_method);
+ mirror::ArtMethod* non_proxy_method = proxy_method->GetInterfaceMethodIfProxy();
+ CHECK(!non_proxy_method->IsStatic()) << PrettyMethod(proxy_method) << " "
+ << PrettyMethod(non_proxy_method);
std::vector<jvalue> args;
- BuildQuickArgumentVisitor local_ref_visitor(sp, proxy_mh.IsStatic(), proxy_mh.GetShorty(),
- proxy_mh.GetShortyLength(), &soa, &args);
+ uint32_t shorty_len = 0;
+ const char* shorty = proxy_method->GetShorty(&shorty_len);
+ BuildQuickArgumentVisitor local_ref_visitor(sp, false, shorty, shorty_len, &soa, &args);
local_ref_visitor.VisitArguments();
DCHECK_GT(args.size(), 0U) << PrettyMethod(proxy_method);
@@ -615,8 +619,7 @@
// All naked Object*s should now be in jobjects, so its safe to go into the main invoke code
// that performs allocations.
self->EndAssertNoThreadSuspension(old_cause);
- JValue result = InvokeProxyInvocationHandler(soa, proxy_mh.GetShorty(),
- rcvr_jobj, interface_method_jobj, args);
+ JValue result = InvokeProxyInvocationHandler(soa, shorty, rcvr_jobj, interface_method_jobj, args);
// Restore references which might have moved.
local_ref_visitor.FixupReferences();
return result.GetJ();
@@ -683,11 +686,8 @@
if (called->IsRuntimeMethod()) {
uint32_t dex_pc = caller->ToDexPc(QuickArgumentVisitor::GetCallingPc(sp));
const DexFile::CodeItem* code;
- {
- MethodHelper mh(caller);
- dex_file = &mh.GetDexFile();
- code = mh.GetCodeItem();
- }
+ dex_file = caller->GetDexFile();
+ code = caller->GetCodeItem();
CHECK_LT(dex_pc, code->insns_size_in_code_units_);
const Instruction* instr = Instruction::At(&code->insns_[dex_pc]);
Instruction::Code instr_code = instr->Opcode();
@@ -743,7 +743,7 @@
} else {
invoke_type = kStatic;
- dex_file = &MethodHelper(called).GetDexFile();
+ dex_file = called->GetDexFile();
dex_method_idx = called->GetDexMethodIndex();
}
uint32_t shorty_len;
@@ -789,9 +789,10 @@
// Calling from one dex file to another, need to compute the method index appropriate to
// the caller's dex file. Since we get here only if the original called was a runtime
// method, we've got the correct dex_file and a dex_method_idx from above.
- DCHECK(&MethodHelper(caller).GetDexFile() == dex_file);
- uint32_t method_index =
- MethodHelper(called).FindDexMethodIndexInOtherDexFile(*dex_file, dex_method_idx);
+ DCHECK_EQ(caller->GetDexFile(), dex_file);
+ StackHandleScope<1> hs(self);
+ MethodHelper mh(hs.NewHandle(called));
+ uint32_t method_index = mh.FindDexMethodIndexInOtherDexFile(*dex_file, dex_method_idx);
if (method_index != DexFile::kDexNoIndex) {
caller->GetDexCacheResolvedMethods()->Set<false>(method_index, called);
}
@@ -1500,10 +1501,9 @@
DCHECK(called->IsNative()) << PrettyMethod(called, true);
// run the visitor
- MethodHelper mh(called);
-
- BuildGenericJniFrameVisitor visitor(&sp, called->IsStatic(), mh.GetShorty(), mh.GetShortyLength(),
- self);
+ uint32_t shorty_len = 0;
+ const char* shorty = called->GetShorty(&shorty_len);
+ BuildGenericJniFrameVisitor visitor(&sp, called->IsStatic(), shorty, shorty_len, self);
visitor.VisitArguments();
visitor.FinalizeHandleScope(self);
@@ -1544,7 +1544,7 @@
// End JNI, as the assembly will move to deliver the exception.
jobject lock = called->IsSynchronized() ? visitor.GetFirstHandleScopeJObject() : nullptr;
- if (mh.GetShorty()[0] == 'L') {
+ if (shorty[0] == 'L') {
artQuickGenericJniEndJNIRef(self, cookie, nullptr, lock);
} else {
artQuickGenericJniEndJNINonRef(self, cookie, lock);
@@ -1583,8 +1583,7 @@
lock = table->GetHandle(0).ToJObject();
}
- MethodHelper mh(called);
- char return_shorty_char = mh.GetShorty()[0];
+ char return_shorty_char = called->GetShorty()[0];
if (return_shorty_char == 'L') {
return artQuickGenericJniEndJNIRef(self, cookie, result.l, lock);
@@ -1659,7 +1658,7 @@
// When we return, the caller will branch to this address, so it had better not be 0!
DCHECK(code != nullptr) << "Code was NULL in method: " << PrettyMethod(method) << " location: "
- << MethodHelper(method).GetDexFile().GetLocation();
+ << method->GetDexFile()->GetLocation();
return GetTwoWordSuccessValue(reinterpret_cast<uintptr_t>(code),
reinterpret_cast<uintptr_t>(method));
@@ -1755,7 +1754,7 @@
// Map the caller PC to a dex PC.
uint32_t dex_pc = caller_method->ToDexPc(caller_pc);
- const DexFile::CodeItem* code = MethodHelper(caller_method).GetCodeItem();
+ const DexFile::CodeItem* code = caller_method->GetCodeItem();
CHECK_LT(dex_pc, code->insns_size_in_code_units_);
const Instruction* instr = Instruction::At(&code->insns_[dex_pc]);
Instruction::Code instr_code = instr->Opcode();
@@ -1793,7 +1792,7 @@
// When we return, the caller will branch to this address, so it had better not be 0!
DCHECK(code != nullptr) << "Code was NULL in method: " << PrettyMethod(method) << " location: "
- << MethodHelper(method).GetDexFile().GetLocation();
+ << method->GetDexFile()->GetLocation();
return GetTwoWordSuccessValue(reinterpret_cast<uintptr_t>(code),
reinterpret_cast<uintptr_t>(method));
diff --git a/runtime/handle.h b/runtime/handle.h
index b70f651..7e13601 100644
--- a/runtime/handle.h
+++ b/runtime/handle.h
@@ -26,18 +26,20 @@
class Thread;
+template<class T> class Handle;
+
template<class T>
-class Handle {
+class ConstHandle {
public:
- Handle() : reference_(nullptr) {
+ ConstHandle() : reference_(nullptr) {
}
- Handle(const Handle<T>& handle) ALWAYS_INLINE : reference_(handle.reference_) {
+ ConstHandle(const ConstHandle<T>& handle) ALWAYS_INLINE : reference_(handle.reference_) {
}
- Handle<T>& operator=(const Handle<T>& handle) ALWAYS_INLINE {
+ ConstHandle<T>& operator=(const ConstHandle<T>& handle) ALWAYS_INLINE {
reference_ = handle.reference_;
return *this;
}
- explicit Handle(StackReference<T>* reference) ALWAYS_INLINE : reference_(reference) {
+ explicit ConstHandle(StackReference<T>* reference) ALWAYS_INLINE : reference_(reference) {
}
T& operator*() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) ALWAYS_INLINE {
return *Get();
@@ -48,11 +50,6 @@
T* Get() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) ALWAYS_INLINE {
return reference_->AsMirrorPtr();
}
- T* Assign(T* reference) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) ALWAYS_INLINE {
- T* old = reference_->AsMirrorPtr();
- reference_->Assign(reference);
- return old;
- }
jobject ToJObject() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) ALWAYS_INLINE {
if (UNLIKELY(reference_->AsMirrorPtr() == nullptr)) {
// Special case so that we work with NullHandles.
@@ -65,17 +62,62 @@
StackReference<T>* reference_;
template<typename S>
- explicit Handle(StackReference<S>* reference)
+ explicit ConstHandle(StackReference<S>* reference)
: reference_(reinterpret_cast<StackReference<T>*>(reference)) {
}
template<typename S>
- explicit Handle(const Handle<S>& handle)
+ explicit ConstHandle(const ConstHandle<S>& handle)
: reference_(reinterpret_cast<StackReference<T>*>(handle.reference_)) {
}
StackReference<T>* GetReference() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) ALWAYS_INLINE {
return reference_;
}
+ const StackReference<T>* GetReference() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
+ ALWAYS_INLINE {
+ return reference_;
+ }
+
+ private:
+ friend class BuildGenericJniFrameVisitor;
+ template<class S> friend class ConstHandle;
+ friend class HandleScope;
+ template<class S> friend class HandleWrapper;
+ template<size_t kNumReferences> friend class StackHandleScope;
+};
+
+template<class T>
+class Handle : public ConstHandle<T> {
+ public:
+ Handle() {
+ }
+ Handle(const Handle<T>& handle) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) ALWAYS_INLINE
+ : ConstHandle<T>(handle.reference_) {
+ }
+ Handle<T>& operator=(const Handle<T>& handle) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
+ ALWAYS_INLINE {
+ ConstHandle<T>::operator=(handle);
+ return *this;
+ }
+ explicit Handle(StackReference<T>* reference) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
+ ALWAYS_INLINE : ConstHandle<T>(reference) {
+ }
+ T* Assign(T* reference) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) ALWAYS_INLINE {
+ StackReference<T>* ref = ConstHandle<T>::GetReference();
+ T* const old = ref->AsMirrorPtr();
+ ref->Assign(reference);
+ return old;
+ }
+
+ protected:
+ template<typename S>
+ explicit Handle(StackReference<S>* reference) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
+ : ConstHandle<T>(reference) {
+ }
+ template<typename S>
+ explicit Handle(const Handle<S>& handle) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
+ : ConstHandle<T>(handle) {
+ }
private:
friend class BuildGenericJniFrameVisitor;
diff --git a/runtime/instrumentation.cc b/runtime/instrumentation.cc
index a407c55..261c241 100644
--- a/runtime/instrumentation.cc
+++ b/runtime/instrumentation.cc
@@ -860,7 +860,8 @@
CheckStackDepth(self, instrumentation_frame, 0);
mirror::ArtMethod* method = instrumentation_frame.method_;
- char return_shorty = MethodHelper(method).GetShorty()[0];
+ uint32_t length;
+ char return_shorty = method->GetShorty(&length)[0];
JValue return_value;
if (return_shorty == 'V') {
return_value.SetJ(0);
diff --git a/runtime/interpreter/interpreter.cc b/runtime/interpreter/interpreter.cc
index 9cfba8d..6dbc6a0 100644
--- a/runtime/interpreter/interpreter.cc
+++ b/runtime/interpreter/interpreter.cc
@@ -400,8 +400,7 @@
}
const char* old_cause = self->StartAssertNoThreadSuspension("EnterInterpreterFromInvoke");
- MethodHelper mh(method);
- const DexFile::CodeItem* code_item = mh.GetCodeItem();
+ const DexFile::CodeItem* code_item = method->GetCodeItem();
uint16_t num_regs;
uint16_t num_ins;
if (code_item != NULL) {
@@ -413,7 +412,7 @@
return;
} else {
DCHECK(method->IsNative());
- num_regs = num_ins = ArtMethod::NumArgRegisters(mh.GetShorty());
+ num_regs = num_ins = ArtMethod::NumArgRegisters(method->GetShorty());
if (!method->IsStatic()) {
num_regs++;
num_ins++;
@@ -431,9 +430,10 @@
shadow_frame->SetVRegReference(cur_reg, receiver);
++cur_reg;
}
- const char* shorty = mh.GetShorty();
+ uint32_t shorty_len = 0;
+ const char* shorty = method->GetShorty(&shorty_len);
for (size_t shorty_pos = 0, arg_pos = 0; cur_reg < num_regs; ++shorty_pos, ++arg_pos, cur_reg++) {
- DCHECK_LT(shorty_pos + 1, mh.GetShortyLength());
+ DCHECK_LT(shorty_pos + 1, shorty_len);
switch (shorty[shorty_pos + 1]) {
case 'L': {
Object* o = reinterpret_cast<StackReference<Object>*>(&args[arg_pos])->AsMirrorPtr();
@@ -465,6 +465,8 @@
}
}
if (LIKELY(!method->IsNative())) {
+ StackHandleScope<1> hs(self);
+ MethodHelper mh(hs.NewHandle(method));
JValue r = Execute(self, mh, code_item, *shadow_frame, JValue());
if (result != NULL) {
*result = r;
@@ -488,11 +490,11 @@
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
JValue value;
value.SetJ(ret_val->GetJ()); // Set value to last known result in case the shadow frame chain is empty.
- MethodHelper mh;
while (shadow_frame != NULL) {
self->SetTopOfShadowStack(shadow_frame);
- mh.ChangeMethod(shadow_frame->GetMethod());
- const DexFile::CodeItem* code_item = mh.GetCodeItem();
+ StackHandleScope<1> hs(self);
+ MethodHelper mh(hs.NewHandle(shadow_frame->GetMethod()));
+ const DexFile::CodeItem* code_item = mh.GetMethod()->GetCodeItem();
value = Execute(self, mh, code_item, *shadow_frame, value);
ShadowFrame* old_frame = shadow_frame;
shadow_frame = shadow_frame->GetLink();
diff --git a/runtime/interpreter/interpreter_common.cc b/runtime/interpreter/interpreter_common.cc
index a66bd94..c6e05ae 100644
--- a/runtime/interpreter/interpreter_common.cc
+++ b/runtime/interpreter/interpreter_common.cc
@@ -54,8 +54,7 @@
bool DoCall(ArtMethod* method, Thread* self, ShadowFrame& shadow_frame,
const Instruction* inst, uint16_t inst_data, JValue* result) {
// Compute method information.
- MethodHelper mh(method);
- const DexFile::CodeItem* code_item = mh.GetCodeItem();
+ const DexFile::CodeItem* code_item = method->GetCodeItem();
const uint16_t num_ins = (is_range) ? inst->VRegA_3rc(inst_data) : inst->VRegA_35c(inst_data);
uint16_t num_regs;
if (LIKELY(code_item != NULL)) {
@@ -73,6 +72,8 @@
// Initialize new shadow frame.
const size_t first_dest_reg = num_regs - num_ins;
+ StackHandleScope<1> hs(self);
+ MethodHelper mh(hs.NewHandle(method));
if (do_assignability_check) {
// Slow path.
// We might need to do class loading, which incurs a thread state change to kNative. So
@@ -82,8 +83,9 @@
// We need to do runtime check on reference assignment. We need to load the shorty
// to get the exact type of each reference argument.
- const DexFile::TypeList* params = mh.GetParameterTypeList();
- const char* shorty = mh.GetShorty();
+ const DexFile::TypeList* params = method->GetParameterTypeList();
+ uint32_t shorty_len = 0;
+ const char* shorty = method->GetShorty(&shorty_len);
// TODO: find a cleaner way to separate non-range and range information without duplicating code.
uint32_t arg[5]; // only used in invoke-XXX.
@@ -98,13 +100,13 @@
size_t dest_reg = first_dest_reg;
size_t arg_offset = 0;
if (!method->IsStatic()) {
- size_t receiver_reg = (is_range) ? vregC : arg[0];
+ size_t receiver_reg = is_range ? vregC : arg[0];
new_shadow_frame->SetVRegReference(dest_reg, shadow_frame.GetVRegReference(receiver_reg));
++dest_reg;
++arg_offset;
}
for (uint32_t shorty_pos = 0; dest_reg < num_regs; ++shorty_pos, ++dest_reg, ++arg_offset) {
- DCHECK_LT(shorty_pos + 1, mh.GetShortyLength());
+ DCHECK_LT(shorty_pos + 1, shorty_len);
const size_t src_reg = (is_range) ? vregC + arg_offset : arg[arg_offset];
switch (shorty[shorty_pos + 1]) {
case 'L': {
@@ -120,7 +122,7 @@
self->ThrowNewExceptionF(self->GetCurrentLocationForThrow(),
"Ljava/lang/VirtualMachineError;",
"Invoking %s with bad arg %d, type '%s' not instance of '%s'",
- mh.GetName(), shorty_pos,
+ method->GetName(), shorty_pos,
o->GetClass()->GetDescriptor().c_str(),
arg_type->GetDescriptor().c_str());
return false;
@@ -368,8 +370,9 @@
Object* obj = shadow_frame->GetVRegReference(arg_offset);
result->SetI(obj->IdentityHashCode());
} else if (name == "java.lang.String java.lang.reflect.ArtMethod.getMethodName(java.lang.reflect.ArtMethod)") {
- ArtMethod* method = shadow_frame->GetVRegReference(arg_offset)->AsArtMethod();
- result->SetL(MethodHelper(method).GetNameAsString());
+ StackHandleScope<1> hs(self);
+ MethodHelper mh(hs.NewHandle(shadow_frame->GetVRegReference(arg_offset)->AsArtMethod()));
+ result->SetL(mh.GetNameAsString(self));
} else if (name == "void java.lang.System.arraycopy(java.lang.Object, int, java.lang.Object, int, int)" ||
name == "void java.lang.System.arraycopy(char[], int, char[], int, int)") {
// Special case array copying without initializing System.
diff --git a/runtime/interpreter/interpreter_common.h b/runtime/interpreter/interpreter_common.h
index 6e136d6..88a8468 100644
--- a/runtime/interpreter/interpreter_common.h
+++ b/runtime/interpreter/interpreter_common.h
@@ -604,10 +604,15 @@
ThrowLocation throw_location;
mirror::Throwable* exception = self->GetException(&throw_location);
bool clear_exception = false;
- StackHandleScope<3> hs(self);
- Handle<mirror::Class> exception_class(hs.NewHandle(exception->GetClass()));
- uint32_t found_dex_pc = shadow_frame.GetMethod()->FindCatchBlock(exception_class, dex_pc,
- &clear_exception);
+ uint32_t found_dex_pc;
+ {
+ StackHandleScope<3> hs(self);
+ Handle<mirror::Class> exception_class(hs.NewHandle(exception->GetClass()));
+ Handle<mirror::ArtMethod> h_method(hs.NewHandle(shadow_frame.GetMethod()));
+ HandleWrapper<mirror::Object> h(hs.NewHandleWrapper(&this_object));
+ found_dex_pc = mirror::ArtMethod::FindCatchBlock(h_method, exception_class, dex_pc,
+ &clear_exception);
+ }
if (found_dex_pc == DexFile::kDexNoIndex) {
instrumentation->MethodUnwindEvent(self, this_object,
shadow_frame.GetMethod(), dex_pc);
@@ -627,7 +632,7 @@
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
static inline void UnexpectedOpcode(const Instruction* inst, MethodHelper& mh) {
- LOG(FATAL) << "Unexpected instruction: " << inst->DumpString(&mh.GetDexFile());
+ LOG(FATAL) << "Unexpected instruction: " << inst->DumpString(mh.GetMethod()->GetDexFile());
exit(0); // Unreachable, keep GCC happy.
}
@@ -640,7 +645,7 @@
std::ostringstream oss;
oss << PrettyMethod(shadow_frame.GetMethod())
<< StringPrintf("\n0x%x: ", dex_pc)
- << inst->DumpString(&mh.GetDexFile()) << "\n";
+ << inst->DumpString(mh.GetMethod()->GetDexFile()) << "\n";
for (uint32_t i = 0; i < shadow_frame.NumberOfVRegs(); ++i) {
uint32_t raw_value = shadow_frame.GetVReg(i);
Object* ref_value = shadow_frame.GetVRegReference(i);
diff --git a/runtime/interpreter/interpreter_goto_table_impl.cc b/runtime/interpreter/interpreter_goto_table_impl.cc
index 623d9c3..19673ac 100644
--- a/runtime/interpreter/interpreter_goto_table_impl.cc
+++ b/runtime/interpreter/interpreter_goto_table_impl.cc
@@ -328,11 +328,13 @@
if (UNLIKELY(self->TestAllFlags())) {
CheckSuspend(self);
}
- Object* obj_result = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
- result.SetJ(0);
- result.SetL(obj_result);
+ const uint8_t vreg_index = inst->VRegA_11x(inst_data);
+ Object* obj_result = shadow_frame.GetVRegReference(vreg_index);
if (do_assignability_check && obj_result != NULL) {
- Class* return_type = MethodHelper(shadow_frame.GetMethod()).GetReturnType();
+ StackHandleScope<1> hs(self);
+ MethodHelper mh(hs.NewHandle(shadow_frame.GetMethod()));
+ Class* return_type = mh.GetReturnType();
+ obj_result = shadow_frame.GetVRegReference(vreg_index);
if (return_type == NULL) {
// Return the pending exception.
HANDLE_PENDING_EXCEPTION();
@@ -347,6 +349,7 @@
HANDLE_PENDING_EXCEPTION();
}
}
+ result.SetL(obj_result);
instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
diff --git a/runtime/interpreter/interpreter_switch_impl.cc b/runtime/interpreter/interpreter_switch_impl.cc
index d592a53..a43fad3 100644
--- a/runtime/interpreter/interpreter_switch_impl.cc
+++ b/runtime/interpreter/interpreter_switch_impl.cc
@@ -244,11 +244,14 @@
if (UNLIKELY(self->TestAllFlags())) {
CheckSuspend(self);
}
- Object* obj_result = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
- result.SetJ(0);
- result.SetL(obj_result);
+ const size_t ref_idx = inst->VRegA_11x(inst_data);
+ Object* obj_result = shadow_frame.GetVRegReference(ref_idx);
if (do_assignability_check && obj_result != NULL) {
- Class* return_type = MethodHelper(shadow_frame.GetMethod()).GetReturnType();
+ StackHandleScope<1> hs(self);
+ MethodHelper mhs(hs.NewHandle(shadow_frame.GetMethod()));
+ Class* return_type = mhs.GetReturnType();
+ // Re-load since it might have moved.
+ obj_result = shadow_frame.GetVRegReference(ref_idx);
if (return_type == NULL) {
// Return the pending exception.
HANDLE_PENDING_EXCEPTION();
@@ -263,6 +266,7 @@
HANDLE_PENDING_EXCEPTION();
}
}
+ result.SetL(obj_result);
if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
shadow_frame.GetMethod(), inst->GetDexPc(insns),
diff --git a/runtime/mirror/art_method-inl.h b/runtime/mirror/art_method-inl.h
index 5f4619b..8fcacc2 100644
--- a/runtime/mirror/art_method-inl.h
+++ b/runtime/mirror/art_method-inl.h
@@ -295,7 +295,9 @@
if (UNLIKELY(entry_point == runtime->GetClassLinker()->GetQuickGenericJniTrampoline())) {
// Generic JNI frame.
DCHECK(IsNative());
- uint32_t handle_refs = MethodHelper(this).GetNumberOfReferenceArgsWithoutReceiver() + 1;
+ StackHandleScope<1> hs(Thread::Current());
+ uint32_t handle_refs =
+ MethodHelper(hs.NewHandle(this)).GetNumberOfReferenceArgsWithoutReceiver() + 1;
size_t scope_size = HandleScope::SizeOf(handle_refs);
QuickMethodFrameInfo callee_info = runtime->GetCalleeSaveMethodFrameInfo(Runtime::kRefsAndArgs);
@@ -314,10 +316,143 @@
inline QuickMethodFrameInfo ArtMethod::GetQuickFrameInfo(const void* code_pointer) {
DCHECK(code_pointer != nullptr);
- DCHECK(code_pointer == GetQuickOatCodePointer());
+ DCHECK_EQ(code_pointer, GetQuickOatCodePointer());
return reinterpret_cast<const OatQuickMethodHeader*>(code_pointer)[-1].frame_info_;
}
+inline const DexFile* ArtMethod::GetDexFile() {
+ return GetInterfaceMethodIfProxy()->GetDeclaringClass()->GetDexCache()->GetDexFile();
+}
+
+inline const char* ArtMethod::GetDeclaringClassDescriptor() {
+ mirror::ArtMethod* method = GetInterfaceMethodIfProxy();
+ uint32_t dex_method_idx = method->GetDexMethodIndex();
+ if (UNLIKELY(dex_method_idx == DexFile::kDexNoIndex)) {
+ return "<runtime method>";
+ }
+ const DexFile* dex_file = method->GetDexFile();
+ return dex_file->GetMethodDeclaringClassDescriptor(dex_file->GetMethodId(dex_method_idx));
+}
+
+inline const char* ArtMethod::GetShorty(uint32_t* out_length) {
+ mirror::ArtMethod* method = GetInterfaceMethodIfProxy();
+ const DexFile* dex_file = method->GetDexFile();
+ return dex_file->GetMethodShorty(dex_file->GetMethodId(method->GetDexMethodIndex()), out_length);
+}
+
+inline const Signature ArtMethod::GetSignature() {
+ mirror::ArtMethod* method = GetInterfaceMethodIfProxy();
+ uint32_t dex_method_idx = method->GetDexMethodIndex();
+ if (dex_method_idx != DexFile::kDexNoIndex) {
+ const DexFile* dex_file = method->GetDexFile();
+ return dex_file->GetMethodSignature(dex_file->GetMethodId(dex_method_idx));
+ }
+ return Signature::NoSignature();
+}
+
+inline const char* ArtMethod::GetName() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ mirror::ArtMethod* method = GetInterfaceMethodIfProxy();
+ uint32_t dex_method_idx = method->GetDexMethodIndex();
+ if (LIKELY(dex_method_idx != DexFile::kDexNoIndex)) {
+ const DexFile* dex_file = method->GetDexFile();
+ return dex_file->GetMethodName(dex_file->GetMethodId(dex_method_idx));
+ }
+ Runtime* runtime = Runtime::Current();
+ if (method == runtime->GetResolutionMethod()) {
+ return "<runtime internal resolution method>";
+ } else if (method == runtime->GetImtConflictMethod()) {
+ return "<runtime internal imt conflict method>";
+ } else if (method == runtime->GetCalleeSaveMethod(Runtime::kSaveAll)) {
+ return "<runtime internal callee-save all registers method>";
+ } else if (method == runtime->GetCalleeSaveMethod(Runtime::kRefsOnly)) {
+ return "<runtime internal callee-save reference registers method>";
+ } else if (method == runtime->GetCalleeSaveMethod(Runtime::kRefsAndArgs)) {
+ return "<runtime internal callee-save reference and argument registers method>";
+ } else {
+ return "<unknown runtime internal method>";
+ }
+}
+
+inline const DexFile::CodeItem* ArtMethod::GetCodeItem() {
+ mirror::ArtMethod* method = GetInterfaceMethodIfProxy();
+ return method->GetDexFile()->GetCodeItem(method->GetCodeItemOffset());
+}
+
+inline bool ArtMethod::IsResolvedTypeIdx(uint16_t type_idx) {
+ mirror::ArtMethod* method = GetInterfaceMethodIfProxy();
+ return method->GetDexCacheResolvedTypes()->Get(type_idx) != nullptr;
+}
+
+inline int32_t ArtMethod::GetLineNumFromDexPC(uint32_t dex_pc) {
+ mirror::ArtMethod* method = GetInterfaceMethodIfProxy();
+ if (dex_pc == DexFile::kDexNoIndex) {
+ return method->IsNative() ? -2 : -1;
+ }
+ return method->GetDexFile()->GetLineNumFromPC(method, dex_pc);
+}
+
+inline const DexFile::ProtoId& ArtMethod::GetPrototype() {
+ mirror::ArtMethod* method = GetInterfaceMethodIfProxy();
+ const DexFile* dex_file = method->GetDexFile();
+ return dex_file->GetMethodPrototype(dex_file->GetMethodId(method->GetDexMethodIndex()));
+}
+
+inline const DexFile::TypeList* ArtMethod::GetParameterTypeList() {
+ mirror::ArtMethod* method = GetInterfaceMethodIfProxy();
+ const DexFile* dex_file = method->GetDexFile();
+ const DexFile::ProtoId& proto = dex_file->GetMethodPrototype(
+ dex_file->GetMethodId(method->GetDexMethodIndex()));
+ return dex_file->GetProtoParameters(proto);
+}
+
+inline const char* ArtMethod::GetDeclaringClassSourceFile() {
+ return GetInterfaceMethodIfProxy()->GetDeclaringClass()->GetSourceFile();
+}
+
+inline uint16_t ArtMethod::GetClassDefIndex() {
+ return GetInterfaceMethodIfProxy()->GetDeclaringClass()->GetDexClassDefIndex();
+}
+
+inline const DexFile::ClassDef& ArtMethod::GetClassDef() {
+ mirror::ArtMethod* method = GetInterfaceMethodIfProxy();
+ return method->GetDexFile()->GetClassDef(GetClassDefIndex());
+}
+
+inline const char* ArtMethod::GetReturnTypeDescriptor() {
+ mirror::ArtMethod* method = GetInterfaceMethodIfProxy();
+ const DexFile* dex_file = method->GetDexFile();
+ const DexFile::MethodId& method_id = dex_file->GetMethodId(method->GetDexMethodIndex());
+ const DexFile::ProtoId& proto_id = dex_file->GetMethodPrototype(method_id);
+ uint16_t return_type_idx = proto_id.return_type_idx_;
+ return dex_file->GetTypeDescriptor(dex_file->GetTypeId(return_type_idx));
+}
+
+inline const char* ArtMethod::GetTypeDescriptorFromTypeIdx(uint16_t type_idx) {
+ mirror::ArtMethod* method = GetInterfaceMethodIfProxy();
+ const DexFile* dex_file = method->GetDexFile();
+ return dex_file->GetTypeDescriptor(dex_file->GetTypeId(type_idx));
+}
+
+inline mirror::ClassLoader* ArtMethod::GetClassLoader() {
+ return GetInterfaceMethodIfProxy()->GetDeclaringClass()->GetClassLoader();
+}
+
+inline mirror::DexCache* ArtMethod::GetDexCache() {
+ return GetInterfaceMethodIfProxy()->GetDeclaringClass()->GetDexCache();
+}
+
+inline ArtMethod* ArtMethod::GetInterfaceMethodIfProxy() {
+ mirror::Class* klass = GetDeclaringClass();
+ if (LIKELY(!klass->IsProxyClass())) {
+ return this;
+ }
+ mirror::ArtMethod* interface_method = GetDexCacheResolvedMethods()->Get(GetDexMethodIndex());
+ DCHECK(interface_method != nullptr);
+ DCHECK_EQ(interface_method,
+ Runtime::Current()->GetClassLinker()->FindMethodForProxy(klass, this));
+ return interface_method;
+}
+
} // namespace mirror
} // namespace art
diff --git a/runtime/mirror/art_method.cc b/runtime/mirror/art_method.cc
index c01fc72..3db4be3 100644
--- a/runtime/mirror/art_method.cc
+++ b/runtime/mirror/art_method.cc
@@ -142,16 +142,16 @@
CHECK_EQ(result,
Runtime::Current()->GetClassLinker()->FindMethodForProxy(GetDeclaringClass(), this));
} else {
- MethodHelper mh(this);
- MethodHelper interface_mh;
+ StackHandleScope<2> hs(Thread::Current());
+ MethodHelper mh(hs.NewHandle(this));
+ MethodHelper interface_mh(hs.NewHandle<mirror::ArtMethod>(nullptr));
IfTable* iftable = GetDeclaringClass()->GetIfTable();
for (size_t i = 0; i < iftable->Count() && result == NULL; i++) {
Class* interface = iftable->GetInterface(i);
for (size_t j = 0; j < interface->NumVirtualMethods(); ++j) {
- ArtMethod* interface_method = interface->GetVirtualMethod(j);
- interface_mh.ChangeMethod(interface_method);
+ interface_mh.ChangeMethod(interface->GetVirtualMethod(j));
if (mh.HasSameNameAndSignature(&interface_mh)) {
- result = interface_method;
+ result = interface_mh.GetMethod();
break;
}
}
@@ -159,8 +159,10 @@
}
}
#ifndef NDEBUG
- MethodHelper result_mh(result);
- DCHECK(result == NULL || MethodHelper(this).HasSameNameAndSignature(&result_mh));
+ StackHandleScope<2> hs(Thread::Current());
+ MethodHelper result_mh(hs.NewHandle(result));
+ MethodHelper this_mh(hs.NewHandle(this));
+ DCHECK(result == NULL || this_mh.HasSameNameAndSignature(&result_mh));
#endif
return result;
}
@@ -229,10 +231,10 @@
return 0;
}
-uint32_t ArtMethod::FindCatchBlock(Handle<Class> exception_type, uint32_t dex_pc,
- bool* has_no_move_exception) {
- MethodHelper mh(this);
- const DexFile::CodeItem* code_item = mh.GetCodeItem();
+uint32_t ArtMethod::FindCatchBlock(Handle<ArtMethod> h_this, Handle<Class> exception_type,
+ uint32_t dex_pc, bool* has_no_move_exception) {
+ MethodHelper mh(h_this);
+ const DexFile::CodeItem* code_item = h_this->GetCodeItem();
// Set aside the exception while we resolve its type.
Thread* self = Thread::Current();
ThrowLocation throw_location;
@@ -260,7 +262,7 @@
// release its in use context at the end.
delete self->GetLongJumpContext();
LOG(WARNING) << "Unresolved exception class when finding catch block: "
- << DescriptorToDot(mh.GetTypeDescriptorFromTypeIdx(iter_type_idx));
+ << DescriptorToDot(h_this->GetTypeDescriptorFromTypeIdx(iter_type_idx));
} else if (iter_exception_type->IsAssignableFrom(exception_type.Get())) {
found_dex_pc = it.GetHandlerAddress();
break;
@@ -283,7 +285,7 @@
if (kIsDebugBuild) {
self->AssertThreadSuspensionIsAllowable();
CHECK_EQ(kRunnable, self->GetState());
- CHECK_STREQ(MethodHelper(this).GetShorty(), shorty);
+ CHECK_STREQ(GetShorty(), shorty);
}
// Push a transition back into managed code onto the linked list in thread.
diff --git a/runtime/mirror/art_method.h b/runtime/mirror/art_method.h
index f901512..1c21b81 100644
--- a/runtime/mirror/art_method.h
+++ b/runtime/mirror/art_method.h
@@ -88,6 +88,11 @@
return (GetAccessFlags() & kAccConstructor) != 0;
}
+ // Returns true if the method is a class initializer.
+ bool IsClassInitializer() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ return IsConstructor() && IsStatic();
+ }
+
// Returns true if the method is static, private, or a constructor.
bool IsDirect() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
return IsDirect(GetAccessFlags());
@@ -216,14 +221,14 @@
// Find the method that this method overrides
ArtMethod* FindOverriddenMethod() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- void Invoke(Thread* self, uint32_t* args, uint32_t args_size, JValue* result,
- const char* shorty) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ void Invoke(Thread* self, uint32_t* args, uint32_t args_size, JValue* result, const char* shorty)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
EntryPointFromInterpreter* GetEntryPointFromInterpreter()
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
return GetFieldPtr<EntryPointFromInterpreter*, kVerifyFlags>(
- OFFSET_OF_OBJECT_MEMBER(ArtMethod, entry_point_from_interpreter_));
+ OFFSET_OF_OBJECT_MEMBER(ArtMethod, entry_point_from_interpreter_));
}
template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
@@ -281,7 +286,7 @@
*
* NOTE: For Thumb both pc and code are offset by 1 indicating the Thumb state.
*/
- return (code <= pc && pc <= code + GetCodeSize());
+ return code <= pc && pc <= code + GetCodeSize();
}
void AssertPcIsWithinQuickCode(uintptr_t pc) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
@@ -398,8 +403,8 @@
// Find the catch block for the given exception type and dex_pc. When a catch block is found,
// indicates whether the found catch block is responsible for clearing the exception or whether
// a move-exception instruction is present.
- uint32_t FindCatchBlock(Handle<Class> exception_type, uint32_t dex_pc,
- bool* has_no_move_exception)
+ static uint32_t FindCatchBlock(Handle<ArtMethod> h_this, Handle<Class> exception_type,
+ uint32_t dex_pc, bool* has_no_move_exception)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
static void SetClass(Class* java_lang_reflect_ArtMethod);
@@ -414,6 +419,30 @@
static void VisitRoots(RootCallback* callback, void* arg)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ const DexFile* GetDexFile() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ const char* GetDeclaringClassDescriptor() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ const char* GetShorty() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ uint32_t unused_length;
+ return GetShorty(&unused_length);
+ }
+ const char* GetShorty(uint32_t* out_length) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ const Signature GetSignature() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ const char* GetName() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ const DexFile::CodeItem* GetCodeItem() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ bool IsResolvedTypeIdx(uint16_t type_idx) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ int32_t GetLineNumFromDexPC(uint32_t dex_pc) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ const DexFile::ProtoId& GetPrototype() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ const DexFile::TypeList* GetParameterTypeList() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ const char* GetDeclaringClassSourceFile() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ uint16_t GetClassDefIndex() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ const DexFile::ClassDef& GetClassDef() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ const char* GetReturnTypeDescriptor() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ const char* GetTypeDescriptorFromTypeIdx(uint16_t type_idx)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ mirror::ClassLoader* GetClassLoader() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ mirror::DexCache* GetDexCache() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ ArtMethod* GetInterfaceMethodIfProxy() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
protected:
// Field order required by test "ValidateFieldOrderOfJavaCppUnionClasses".
// The class we are a part of.
diff --git a/runtime/mirror/class.cc b/runtime/mirror/class.cc
index a409093..7b31a82 100644
--- a/runtime/mirror/class.cc
+++ b/runtime/mirror/class.cc
@@ -366,11 +366,9 @@
}
ArtMethod* Class::FindDeclaredDirectMethod(const StringPiece& name, const StringPiece& signature) {
- MethodHelper mh;
for (size_t i = 0; i < NumDirectMethods(); ++i) {
ArtMethod* method = GetDirectMethod(i);
- mh.ChangeMethod(method);
- if (name == mh.GetName() && mh.GetSignature() == signature) {
+ if (name == method->GetName() && method->GetSignature() == signature) {
return method;
}
}
@@ -378,11 +376,9 @@
}
ArtMethod* Class::FindDeclaredDirectMethod(const StringPiece& name, const Signature& signature) {
- MethodHelper mh;
for (size_t i = 0; i < NumDirectMethods(); ++i) {
ArtMethod* method = GetDirectMethod(i);
- mh.ChangeMethod(method);
- if (name == mh.GetName() && signature == mh.GetSignature()) {
+ if (name == method->GetName() && signature == method->GetSignature()) {
return method;
}
}
@@ -432,24 +428,19 @@
}
ArtMethod* Class::FindDeclaredVirtualMethod(const StringPiece& name, const StringPiece& signature) {
- MethodHelper mh;
for (size_t i = 0; i < NumVirtualMethods(); ++i) {
ArtMethod* method = GetVirtualMethod(i);
- mh.ChangeMethod(method);
- if (name == mh.GetName() && mh.GetSignature() == signature) {
+ if (name == method->GetName() && method->GetSignature() == signature) {
return method;
}
}
return NULL;
}
-ArtMethod* Class::FindDeclaredVirtualMethod(const StringPiece& name,
- const Signature& signature) {
- MethodHelper mh;
+ArtMethod* Class::FindDeclaredVirtualMethod(const StringPiece& name, const Signature& signature) {
for (size_t i = 0; i < NumVirtualMethods(); ++i) {
ArtMethod* method = GetVirtualMethod(i);
- mh.ChangeMethod(method);
- if (name == mh.GetName() && signature == mh.GetSignature()) {
+ if (name == method->GetName() && signature == method->GetSignature()) {
return method;
}
}
@@ -501,13 +492,9 @@
ArtMethod* Class::FindClassInitializer() {
for (size_t i = 0; i < NumDirectMethods(); ++i) {
ArtMethod* method = GetDirectMethod(i);
- if (method->IsConstructor() && method->IsStatic()) {
- if (kIsDebugBuild) {
- MethodHelper mh(method);
- CHECK(mh.IsClassInitializer());
- CHECK_STREQ(mh.GetName(), "<clinit>");
- CHECK_STREQ(mh.GetSignature().ToString().c_str(), "()V");
- }
+ if (method->IsClassInitializer()) {
+ DCHECK_STREQ(method->GetName(), "<clinit>");
+ DCHECK_STREQ(method->GetSignature().ToString().c_str(), "()V");
return method;
}
}
diff --git a/runtime/mirror/object_test.cc b/runtime/mirror/object_test.cc
index 18e50ce..f85fb27 100644
--- a/runtime/mirror/object_test.cc
+++ b/runtime/mirror/object_test.cc
@@ -451,7 +451,7 @@
jobject jclass_loader_1 = LoadDex("ProtoCompare");
jobject jclass_loader_2 = LoadDex("ProtoCompare2");
- StackHandleScope<2> hs(soa.Self());
+ StackHandleScope<4> hs(soa.Self());
Handle<ClassLoader> class_loader_1(hs.NewHandle(soa.Decode<ClassLoader*>(jclass_loader_1)));
Handle<ClassLoader> class_loader_2(hs.NewHandle(soa.Decode<ClassLoader*>(jclass_loader_2)));
@@ -461,33 +461,25 @@
ASSERT_TRUE(klass2 != NULL);
ArtMethod* m1_1 = klass1->GetVirtualMethod(0);
- MethodHelper mh(m1_1);
- EXPECT_STREQ(mh.GetName(), "m1");
+ EXPECT_STREQ(m1_1->GetName(), "m1");
ArtMethod* m2_1 = klass1->GetVirtualMethod(1);
- mh.ChangeMethod(m2_1);
- EXPECT_STREQ(mh.GetName(), "m2");
+ EXPECT_STREQ(m2_1->GetName(), "m2");
ArtMethod* m3_1 = klass1->GetVirtualMethod(2);
- mh.ChangeMethod(m3_1);
- EXPECT_STREQ(mh.GetName(), "m3");
+ EXPECT_STREQ(m3_1->GetName(), "m3");
ArtMethod* m4_1 = klass1->GetVirtualMethod(3);
- mh.ChangeMethod(m4_1);
- EXPECT_STREQ(mh.GetName(), "m4");
+ EXPECT_STREQ(m4_1->GetName(), "m4");
ArtMethod* m1_2 = klass2->GetVirtualMethod(0);
- mh.ChangeMethod(m1_2);
- EXPECT_STREQ(mh.GetName(), "m1");
+ EXPECT_STREQ(m1_2->GetName(), "m1");
ArtMethod* m2_2 = klass2->GetVirtualMethod(1);
- mh.ChangeMethod(m2_2);
- EXPECT_STREQ(mh.GetName(), "m2");
+ EXPECT_STREQ(m2_2->GetName(), "m2");
ArtMethod* m3_2 = klass2->GetVirtualMethod(2);
- mh.ChangeMethod(m3_2);
- EXPECT_STREQ(mh.GetName(), "m3");
+ EXPECT_STREQ(m3_2->GetName(), "m3");
ArtMethod* m4_2 = klass2->GetVirtualMethod(3);
- mh.ChangeMethod(m4_2);
- EXPECT_STREQ(mh.GetName(), "m4");
+ EXPECT_STREQ(m4_2->GetName(), "m4");
- mh.ChangeMethod(m1_1);
- MethodHelper mh2(m1_2);
+ MethodHelper mh(hs.NewHandle(m1_1));
+ MethodHelper mh2(hs.NewHandle(m1_2));
EXPECT_TRUE(mh.HasSameNameAndSignature(&mh2));
EXPECT_TRUE(mh2.HasSameNameAndSignature(&mh));
diff --git a/runtime/mirror/throwable.cc b/runtime/mirror/throwable.cc
index 6874fe5..6efc9e2 100644
--- a/runtime/mirror/throwable.cc
+++ b/runtime/mirror/throwable.cc
@@ -85,16 +85,14 @@
ObjectArray<Object>* method_trace = down_cast<ObjectArray<Object>*>(stack_state);
int32_t depth = method_trace->GetLength() - 1;
IntArray* pc_trace = down_cast<IntArray*>(method_trace->Get(depth));
- MethodHelper mh;
if (depth == 0) {
result += "(Throwable with empty stack trace)";
} else {
for (int32_t i = 0; i < depth; ++i) {
- ArtMethod* method = down_cast<ArtMethod*>(method_trace->Get(i));
- mh.ChangeMethod(method);
+ mirror::ArtMethod* method = down_cast<ArtMethod*>(method_trace->Get(i));
uint32_t dex_pc = pc_trace->Get(i);
- int32_t line_number = mh.GetLineNumFromDexPC(dex_pc);
- const char* source_file = mh.GetDeclaringClassSourceFile();
+ int32_t line_number = method->GetLineNumFromDexPC(dex_pc);
+ const char* source_file = method->GetDeclaringClassSourceFile();
result += StringPrintf(" at %s (%s:%d)\n", PrettyMethod(method, true).c_str(),
source_file, line_number);
}
diff --git a/runtime/monitor.cc b/runtime/monitor.cc
index f73ef1e..a19445b 100644
--- a/runtime/monitor.cc
+++ b/runtime/monitor.cc
@@ -967,14 +967,13 @@
}
// <clinit> is another special case. The runtime holds the class lock while calling <clinit>.
- MethodHelper mh(m);
- if (mh.IsClassInitializer()) {
+ if (m->IsClassInitializer()) {
callback(m->GetDeclaringClass(), callback_context);
// Fall through because there might be synchronization in the user code too.
}
// Is there any reason to believe there's any synchronization in this method?
- const DexFile::CodeItem* code_item = mh.GetCodeItem();
+ const DexFile::CodeItem* code_item = m->GetCodeItem();
CHECK(code_item != NULL) << PrettyMethod(m);
if (code_item->tries_size_ == 0) {
return; // No "tries" implies no synchronization, so no held locks to report.
@@ -1048,12 +1047,11 @@
*line_number = 0;
return;
}
- MethodHelper mh(method);
- *source_file = mh.GetDeclaringClassSourceFile();
+ *source_file = method->GetDeclaringClassSourceFile();
if (*source_file == NULL) {
*source_file = "";
}
- *line_number = mh.GetLineNumFromDexPC(dex_pc);
+ *line_number = method->GetLineNumFromDexPC(dex_pc);
}
uint32_t Monitor::GetOwnerThreadId() {
diff --git a/runtime/object_utils.h b/runtime/object_utils.h
index a05ebe6..28ce8f3 100644
--- a/runtime/object_utils.h
+++ b/runtime/object_utils.h
@@ -121,12 +121,9 @@
class MethodHelper {
public:
- MethodHelper() : method_(nullptr), shorty_(nullptr), shorty_len_(0) {}
-
- explicit MethodHelper(mirror::ArtMethod* m)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
- : method_(nullptr), shorty_(nullptr), shorty_len_(0) {
- SetMethod(m);
+ explicit MethodHelper(Handle<mirror::ArtMethod> m) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
+ : method_(m), shorty_(nullptr), shorty_len_(0) {
+ SetMethod(m.Get());
}
void ChangeMethod(mirror::ArtMethod* new_m) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
@@ -135,48 +132,25 @@
shorty_ = nullptr;
}
- mirror::ArtMethod* GetMethod() const {
- return method_;
+ mirror::ArtMethod* GetMethod() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ return method_->GetInterfaceMethodIfProxy();
}
- const char* GetName() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- const DexFile& dex_file = GetDexFile();
- uint32_t dex_method_idx = method_->GetDexMethodIndex();
- if (LIKELY(dex_method_idx != DexFile::kDexNoIndex)) {
- return dex_file.GetMethodName(dex_file.GetMethodId(dex_method_idx));
- } else {
- Runtime* runtime = Runtime::Current();
- if (method_ == runtime->GetResolutionMethod()) {
- return "<runtime internal resolution method>";
- } else if (method_ == runtime->GetImtConflictMethod()) {
- return "<runtime internal imt conflict method>";
- } else if (method_ == runtime->GetCalleeSaveMethod(Runtime::kSaveAll)) {
- return "<runtime internal callee-save all registers method>";
- } else if (method_ == runtime->GetCalleeSaveMethod(Runtime::kRefsOnly)) {
- return "<runtime internal callee-save reference registers method>";
- } else if (method_ == runtime->GetCalleeSaveMethod(Runtime::kRefsAndArgs)) {
- return "<runtime internal callee-save reference and argument registers method>";
- } else {
- return "<unknown runtime internal method>";
- }
- }
- }
-
- mirror::String* GetNameAsString() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- const DexFile& dex_file = GetDexFile();
- uint32_t dex_method_idx = method_->GetDexMethodIndex();
- const DexFile::MethodId& method_id = dex_file.GetMethodId(dex_method_idx);
- StackHandleScope<1> hs(Thread::Current());
- Handle<mirror::DexCache> dex_cache(hs.NewHandle(GetDexCache()));
- return GetClassLinker()->ResolveString(dex_file, method_id.name_idx_, dex_cache);
+ mirror::String* GetNameAsString(Thread* self) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ const DexFile* dex_file = method_->GetDexFile();
+ mirror::ArtMethod* method = method_->GetInterfaceMethodIfProxy();
+ uint32_t dex_method_idx = method->GetDexMethodIndex();
+ const DexFile::MethodId& method_id = dex_file->GetMethodId(dex_method_idx);
+ StackHandleScope<1> hs(self);
+ Handle<mirror::DexCache> dex_cache(hs.NewHandle(method->GetDexCache()));
+ return Runtime::Current()->GetClassLinker()->ResolveString(*dex_file, method_id.name_idx_,
+ dex_cache);
}
const char* GetShorty() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
const char* result = shorty_;
if (result == nullptr) {
- const DexFile& dex_file = GetDexFile();
- result = dex_file.GetMethodShorty(dex_file.GetMethodId(method_->GetDexMethodIndex()),
- &shorty_len_);
+ result = method_->GetShorty(&shorty_len_);
shorty_ = result;
}
return result;
@@ -203,94 +177,27 @@
return refs;
}
- const Signature GetSignature() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- const DexFile& dex_file = GetDexFile();
- uint32_t dex_method_idx = method_->GetDexMethodIndex();
- if (dex_method_idx != DexFile::kDexNoIndex) {
- return dex_file.GetMethodSignature(dex_file.GetMethodId(dex_method_idx));
- } else {
- return Signature::NoSignature();
- }
- }
-
- const DexFile::ProtoId& GetPrototype() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- const DexFile& dex_file = GetDexFile();
- return dex_file.GetMethodPrototype(dex_file.GetMethodId(method_->GetDexMethodIndex()));
- }
-
- const DexFile::TypeList* GetParameterTypeList() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- const DexFile::ProtoId& proto = GetPrototype();
- return GetDexFile().GetProtoParameters(proto);
- }
-
+ // May cause thread suspension due to GetClassFromTypeIdx calling ResolveType this caused a large
+ // number of bugs at call sites.
mirror::Class* GetReturnType(bool resolve = true) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- const DexFile& dex_file = GetDexFile();
- const DexFile::MethodId& method_id = dex_file.GetMethodId(method_->GetDexMethodIndex());
- const DexFile::ProtoId& proto_id = dex_file.GetMethodPrototype(method_id);
+ mirror::ArtMethod* method = GetMethod();
+ const DexFile* dex_file = method->GetDexFile();
+ const DexFile::MethodId& method_id = dex_file->GetMethodId(method->GetDexMethodIndex());
+ const DexFile::ProtoId& proto_id = dex_file->GetMethodPrototype(method_id);
uint16_t return_type_idx = proto_id.return_type_idx_;
return GetClassFromTypeIdx(return_type_idx, resolve);
}
- const char* GetReturnTypeDescriptor() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- const DexFile& dex_file = GetDexFile();
- const DexFile::MethodId& method_id = dex_file.GetMethodId(method_->GetDexMethodIndex());
- const DexFile::ProtoId& proto_id = dex_file.GetMethodPrototype(method_id);
- uint16_t return_type_idx = proto_id.return_type_idx_;
- return dex_file.GetTypeDescriptor(dex_file.GetTypeId(return_type_idx));
- }
-
- int32_t GetLineNumFromDexPC(uint32_t dex_pc) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- if (dex_pc == DexFile::kDexNoIndex) {
- return method_->IsNative() ? -2 : -1;
- } else {
- const DexFile& dex_file = GetDexFile();
- return dex_file.GetLineNumFromPC(method_, dex_pc);
- }
- }
-
- const char* GetDeclaringClassDescriptor() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- const DexFile& dex_file = GetDexFile();
- uint32_t dex_method_idx = method_->GetDexMethodIndex();
- if (UNLIKELY(dex_method_idx == DexFile::kDexNoIndex)) {
- return "<runtime method>";
- }
- return dex_file.GetMethodDeclaringClassDescriptor(dex_file.GetMethodId(dex_method_idx));
- }
-
- const char* GetDeclaringClassSourceFile() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return method_->GetDeclaringClass()->GetSourceFile();
- }
-
- uint16_t GetClassDefIndex() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return method_->GetDeclaringClass()->GetDexClassDefIndex();
- }
-
- const DexFile::ClassDef& GetClassDef() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return GetDexFile().GetClassDef(GetClassDefIndex());
- }
-
- mirror::ClassLoader* GetClassLoader() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return method_->GetDeclaringClass()->GetClassLoader();
- }
-
- bool IsStatic() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return method_->IsStatic();
- }
-
- bool IsClassInitializer() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return method_->IsConstructor() && IsStatic();
- }
-
size_t NumArgs() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
// "1 +" because the first in Args is the receiver.
// "- 1" because we don't count the return type.
- return (IsStatic() ? 0 : 1) + GetShortyLength() - 1;
+ return (method_->IsStatic() ? 0 : 1) + GetShortyLength() - 1;
}
// Get the primitive type associated with the given parameter.
Primitive::Type GetParamPrimitiveType(size_t param) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
CHECK_LT(param, NumArgs());
- if (IsStatic()) {
+ if (GetMethod()->IsStatic()) {
param++; // 0th argument must skip return value at start of the shorty
} else if (param == 0) {
return Primitive::kPrimNot;
@@ -310,21 +217,20 @@
}
bool HasSameNameAndSignature(MethodHelper* other) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- const DexFile& dex_file = GetDexFile();
- const DexFile::MethodId& mid = dex_file.GetMethodId(method_->GetDexMethodIndex());
- if (GetDexCache() == other->GetDexCache()) {
+ const DexFile* dex_file = method_->GetDexFile();
+ const DexFile::MethodId& mid = dex_file->GetMethodId(GetMethod()->GetDexMethodIndex());
+ if (method_->GetDexCache() == other->method_->GetDexCache()) {
const DexFile::MethodId& other_mid =
- dex_file.GetMethodId(other->method_->GetDexMethodIndex());
+ dex_file->GetMethodId(other->GetMethod()->GetDexMethodIndex());
return mid.name_idx_ == other_mid.name_idx_ && mid.proto_idx_ == other_mid.proto_idx_;
}
- const DexFile& other_dex_file = other->GetDexFile();
+ const DexFile* other_dex_file = other->method_->GetDexFile();
const DexFile::MethodId& other_mid =
- other_dex_file.GetMethodId(other->method_->GetDexMethodIndex());
- if (!DexFileStringEquals(&dex_file, mid.name_idx_,
- &other_dex_file, other_mid.name_idx_)) {
+ other_dex_file->GetMethodId(other->GetMethod()->GetDexMethodIndex());
+ if (!DexFileStringEquals(dex_file, mid.name_idx_, other_dex_file, other_mid.name_idx_)) {
return false; // Name mismatch.
}
- return dex_file.GetMethodSignature(mid) == other_dex_file.GetMethodSignature(other_mid);
+ return dex_file->GetMethodSignature(mid) == other_dex_file->GetMethodSignature(other_mid);
}
bool HasSameSignatureWithDifferentClassLoaders(MethodHelper* other)
@@ -332,8 +238,8 @@
if (UNLIKELY(GetReturnType() != other->GetReturnType())) {
return false;
}
- const DexFile::TypeList* types = GetParameterTypeList();
- const DexFile::TypeList* other_types = other->GetParameterTypeList();
+ const DexFile::TypeList* types = method_->GetParameterTypeList();
+ const DexFile::TypeList* other_types = other->method_->GetParameterTypeList();
if (types == nullptr) {
return (other_types == nullptr) || (other_types->Size() == 0);
} else if (UNLIKELY(other_types == nullptr)) {
@@ -354,84 +260,63 @@
return true;
}
- const DexFile::CodeItem* GetCodeItem()
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return GetDexFile().GetCodeItem(method_->GetCodeItemOffset());
- }
-
- bool IsResolvedTypeIdx(uint16_t type_idx) const
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return method_->GetDexCacheResolvedTypes()->Get(type_idx) != nullptr;
- }
-
mirror::Class* GetClassFromTypeIdx(uint16_t type_idx, bool resolve = true)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- mirror::Class* type = method_->GetDexCacheResolvedTypes()->Get(type_idx);
+ mirror::ArtMethod* method = GetMethod();
+ mirror::Class* type = method->GetDexCacheResolvedTypes()->Get(type_idx);
if (type == nullptr && resolve) {
- type = GetClassLinker()->ResolveType(type_idx, method_);
+ type = Runtime::Current()->GetClassLinker()->ResolveType(type_idx, method);
CHECK(type != nullptr || Thread::Current()->IsExceptionPending());
}
return type;
}
- const char* GetTypeDescriptorFromTypeIdx(uint16_t type_idx)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- const DexFile& dex_file = GetDexFile();
- return dex_file.GetTypeDescriptor(dex_file.GetTypeId(type_idx));
- }
-
mirror::Class* GetDexCacheResolvedType(uint16_t type_idx)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return method_->GetDexCacheResolvedTypes()->Get(type_idx);
- }
-
- const DexFile& GetDexFile() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return *GetDexCache()->GetDexFile();
- }
-
- mirror::DexCache* GetDexCache() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return method_->GetDeclaringClass()->GetDexCache();
+ return GetMethod()->GetDexCacheResolvedTypes()->Get(type_idx);
}
mirror::String* ResolveString(uint32_t string_idx) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- mirror::String* s = method_->GetDexCacheStrings()->Get(string_idx);
+ mirror::ArtMethod* method = GetMethod();
+ mirror::String* s = method->GetDexCacheStrings()->Get(string_idx);
if (UNLIKELY(s == nullptr)) {
StackHandleScope<1> hs(Thread::Current());
- Handle<mirror::DexCache> dex_cache(hs.NewHandle(GetDexCache()));
- s = GetClassLinker()->ResolveString(GetDexFile(), string_idx, dex_cache);
+ Handle<mirror::DexCache> dex_cache(hs.NewHandle(method->GetDexCache()));
+ s = Runtime::Current()->GetClassLinker()->ResolveString(*method->GetDexFile(), string_idx,
+ dex_cache);
}
return s;
}
uint32_t FindDexMethodIndexInOtherDexFile(const DexFile& other_dexfile)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- const DexFile& dexfile = GetDexFile();
- if (&dexfile == &other_dexfile) {
- return method_->GetDexMethodIndex();
+ mirror::ArtMethod* method = GetMethod();
+ const DexFile* dexfile = method->GetDexFile();
+ if (dexfile == &other_dexfile) {
+ return method->GetDexMethodIndex();
}
- const DexFile::MethodId& mid = dexfile.GetMethodId(method_->GetDexMethodIndex());
- const char* mid_declaring_class_descriptor = dexfile.StringByTypeIdx(mid.class_idx_);
+ const DexFile::MethodId& mid = dexfile->GetMethodId(method->GetDexMethodIndex());
+ const char* mid_declaring_class_descriptor = dexfile->StringByTypeIdx(mid.class_idx_);
const DexFile::StringId* other_descriptor =
other_dexfile.FindStringId(mid_declaring_class_descriptor);
if (other_descriptor != nullptr) {
const DexFile::TypeId* other_type_id =
other_dexfile.FindTypeId(other_dexfile.GetIndexForStringId(*other_descriptor));
if (other_type_id != nullptr) {
- const char* mid_name = dexfile.GetMethodName(mid);
+ const char* mid_name = dexfile->GetMethodName(mid);
const DexFile::StringId* other_name = other_dexfile.FindStringId(mid_name);
if (other_name != nullptr) {
uint16_t other_return_type_idx;
std::vector<uint16_t> other_param_type_idxs;
- bool success = other_dexfile.CreateTypeList(dexfile.GetMethodSignature(mid).ToString(),
- &other_return_type_idx,
- &other_param_type_idxs);
+ bool success = other_dexfile.CreateTypeList(
+ dexfile->GetMethodSignature(mid).ToString(), &other_return_type_idx,
+ &other_param_type_idxs);
if (success) {
const DexFile::ProtoId* other_sig =
other_dexfile.FindProtoId(other_return_type_idx, other_param_type_idxs);
if (other_sig != nullptr) {
- const DexFile::MethodId* other_mid = other_dexfile.FindMethodId(*other_type_id,
- *other_name,
- *other_sig);
+ const DexFile::MethodId* other_mid = other_dexfile.FindMethodId(
+ *other_type_id, *other_name, *other_sig);
if (other_mid != nullptr) {
return other_dexfile.GetIndexForMethodId(*other_mid);
}
@@ -448,15 +333,17 @@
uint32_t FindDexMethodIndexInOtherDexFile(const DexFile& other_dexfile,
uint32_t name_and_signature_idx)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- const DexFile& dexfile = GetDexFile();
- const DexFile::MethodId& mid = dexfile.GetMethodId(method_->GetDexMethodIndex());
+ mirror::ArtMethod* method = GetMethod();
+ const DexFile* dexfile = method->GetDexFile();
+ const uint32_t dex_method_idx = method->GetDexMethodIndex();
+ const DexFile::MethodId& mid = dexfile->GetMethodId(dex_method_idx);
const DexFile::MethodId& name_and_sig_mid = other_dexfile.GetMethodId(name_and_signature_idx);
- DCHECK_STREQ(dexfile.GetMethodName(mid), other_dexfile.GetMethodName(name_and_sig_mid));
- DCHECK_EQ(dexfile.GetMethodSignature(mid), other_dexfile.GetMethodSignature(name_and_sig_mid));
- if (&dexfile == &other_dexfile) {
- return method_->GetDexMethodIndex();
+ DCHECK_STREQ(dexfile->GetMethodName(mid), other_dexfile.GetMethodName(name_and_sig_mid));
+ DCHECK_EQ(dexfile->GetMethodSignature(mid), other_dexfile.GetMethodSignature(name_and_sig_mid));
+ if (dexfile == &other_dexfile) {
+ return dex_method_idx;
}
- const char* mid_declaring_class_descriptor = dexfile.StringByTypeIdx(mid.class_idx_);
+ const char* mid_declaring_class_descriptor = dexfile->StringByTypeIdx(mid.class_idx_);
const DexFile::StringId* other_descriptor =
other_dexfile.FindStringId(mid_declaring_class_descriptor);
if (other_descriptor != nullptr) {
@@ -478,24 +365,10 @@
// Set the method_ field, for proxy methods looking up the interface method via the resolved
// methods table.
void SetMethod(mirror::ArtMethod* method) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- if (method != nullptr) {
- mirror::Class* klass = method->GetDeclaringClass();
- if (UNLIKELY(klass->IsProxyClass())) {
- mirror::ArtMethod* interface_method =
- method->GetDexCacheResolvedMethods()->Get(method->GetDexMethodIndex());
- DCHECK(interface_method != nullptr);
- DCHECK(interface_method == GetClassLinker()->FindMethodForProxy(klass, method));
- method = interface_method;
- }
- }
- method_ = method;
+ method_.Assign(method);
}
- ClassLinker* GetClassLinker() ALWAYS_INLINE {
- return Runtime::Current()->GetClassLinker();
- }
-
- mirror::ArtMethod* method_;
+ Handle<mirror::ArtMethod> method_;
const char* shorty_;
uint32_t shorty_len_;
diff --git a/runtime/profiler.cc b/runtime/profiler.cc
index bad79b3..00bb501 100644
--- a/runtime/profiler.cc
+++ b/runtime/profiler.cc
@@ -378,8 +378,7 @@
bool is_filtered = false;
- MethodHelper mh(method);
- if (strcmp(mh.GetName(), "<clinit>") == 0) {
+ if (strcmp(method->GetName(), "<clinit>") == 0) {
// always filter out class init
is_filtered = true;
}
@@ -460,8 +459,7 @@
mirror::ArtMethod *method = meth_iter.first;
std::string method_name = PrettyMethod(method);
- MethodHelper mh(method);
- const DexFile::CodeItem* codeitem = mh.GetCodeItem();
+ const DexFile::CodeItem* codeitem = method->GetCodeItem();
uint32_t method_size = 0;
if (codeitem != nullptr) {
method_size = codeitem->insns_size_in_code_units_;
diff --git a/runtime/quick_exception_handler.cc b/runtime/quick_exception_handler.cc
index b9cec40..e3f9afc 100644
--- a/runtime/quick_exception_handler.cc
+++ b/runtime/quick_exception_handler.cc
@@ -71,11 +71,13 @@
DCHECK(method->IsCalleeSaveMethod());
return true;
}
- return HandleTryItems(method);
+ StackHandleScope<1> hs(self_);
+ return HandleTryItems(hs.NewHandle(method));
}
private:
- bool HandleTryItems(mirror::ArtMethod* method) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ bool HandleTryItems(Handle<mirror::ArtMethod> method)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
uint32_t dex_pc = DexFile::kDexNoIndex;
if (!method->IsNative()) {
dex_pc = GetDexPc();
@@ -84,10 +86,11 @@
bool clear_exception = false;
StackHandleScope<1> hs(Thread::Current());
Handle<mirror::Class> to_find(hs.NewHandle((*exception_)->GetClass()));
- uint32_t found_dex_pc = method->FindCatchBlock(to_find, dex_pc, &clear_exception);
+ uint32_t found_dex_pc = mirror::ArtMethod::FindCatchBlock(method, to_find, dex_pc,
+ &clear_exception);
exception_handler_->SetClearException(clear_exception);
if (found_dex_pc != DexFile::kDexNoIndex) {
- exception_handler_->SetHandlerMethod(method);
+ exception_handler_->SetHandlerMethod(method.Get());
exception_handler_->SetHandlerDexPc(found_dex_pc);
exception_handler_->SetHandlerQuickFramePc(method->ToNativePc(found_dex_pc));
exception_handler_->SetHandlerQuickFrame(GetCurrentQuickFrame());
@@ -175,8 +178,7 @@
private:
bool HandleDeoptimization(mirror::ArtMethod* m) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- MethodHelper mh(m);
- const DexFile::CodeItem* code_item = mh.GetCodeItem();
+ const DexFile::CodeItem* code_item = m->GetCodeItem();
CHECK(code_item != nullptr);
uint16_t num_regs = code_item->registers_size_;
uint32_t dex_pc = GetDexPc();
@@ -184,10 +186,11 @@
uint32_t new_dex_pc = dex_pc + inst->SizeInCodeUnits();
ShadowFrame* new_frame = ShadowFrame::Create(num_regs, nullptr, m, new_dex_pc);
StackHandleScope<2> hs(self_);
- Handle<mirror::DexCache> dex_cache(hs.NewHandle(mh.GetDexCache()));
- Handle<mirror::ClassLoader> class_loader(hs.NewHandle(mh.GetClassLoader()));
- verifier::MethodVerifier verifier(&mh.GetDexFile(), &dex_cache, &class_loader,
- &mh.GetClassDef(), code_item, m->GetDexMethodIndex(), m,
+ mirror::Class* declaring_class = m->GetDeclaringClass();
+ Handle<mirror::DexCache> h_dex_cache(hs.NewHandle(declaring_class->GetDexCache()));
+ Handle<mirror::ClassLoader> h_class_loader(hs.NewHandle(declaring_class->GetClassLoader()));
+ verifier::MethodVerifier verifier(h_dex_cache->GetDexFile(), &h_dex_cache, &h_class_loader,
+ &m->GetClassDef(), code_item, m->GetDexMethodIndex(), m,
m->GetAccessFlags(), false, true, true);
verifier.Verify();
std::vector<int32_t> kinds = verifier.DescribeVRegs(dex_pc);
diff --git a/runtime/reflection.cc b/runtime/reflection.cc
index c08cc30..89cdb4d 100644
--- a/runtime/reflection.cc
+++ b/runtime/reflection.cc
@@ -222,7 +222,7 @@
mirror::Object* receiver,
mirror::ObjectArray<mirror::Object>* args, MethodHelper& mh)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- const DexFile::TypeList* classes = mh.GetParameterTypeList();
+ const DexFile::TypeList* classes = mh.GetMethod()->GetParameterTypeList();
// Set receiver if non-null (method is not static)
if (receiver != nullptr) {
Append(receiver);
@@ -349,7 +349,7 @@
static void CheckMethodArguments(mirror::ArtMethod* m, uint32_t* args)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- const DexFile::TypeList* params = MethodHelper(m).GetParameterTypeList();
+ const DexFile::TypeList* params = m->GetParameterTypeList();
if (params == nullptr) {
return; // No arguments so nothing to check.
}
@@ -359,24 +359,31 @@
if (!m->IsStatic()) {
offset = 1;
}
+ // TODO: If args contain object references, it may cause problems
+ Thread* self = Thread::Current();
+ StackHandleScope<1> hs(self);
+ Handle<mirror::ArtMethod> h_m(hs.NewHandle(m));
+ MethodHelper mh(h_m);
for (uint32_t i = 0; i < num_params; i++) {
uint16_t type_idx = params->GetTypeItem(i).type_idx_;
- mirror::Class* param_type = MethodHelper(m).GetClassFromTypeIdx(type_idx);
+ mirror::Class* param_type = mh.GetClassFromTypeIdx(type_idx);
if (param_type == nullptr) {
- Thread* self = Thread::Current();
CHECK(self->IsExceptionPending());
LOG(ERROR) << "Internal error: unresolvable type for argument type in JNI invoke: "
- << MethodHelper(m).GetTypeDescriptorFromTypeIdx(type_idx) << "\n"
+ << h_m->GetTypeDescriptorFromTypeIdx(type_idx) << "\n"
<< self->GetException(nullptr)->Dump();
self->ClearException();
++error_count;
} else if (!param_type->IsPrimitive()) {
// TODO: check primitives are in range.
+ // TODO: There is a compaction bug here since GetClassFromTypeIdx can cause thread suspension,
+ // this is a hard to fix problem since the args can contain Object*, we need to save and
+ // restore them by using a visitor similar to the ones used in the trampoline entrypoints.
mirror::Object* argument = reinterpret_cast<mirror::Object*>(args[i + offset]);
if (argument != nullptr && !argument->InstanceOf(param_type)) {
LOG(ERROR) << "JNI ERROR (app bug): attempt to pass an instance of "
<< PrettyTypeOf(argument) << " as argument " << (i + 1)
- << " to " << PrettyMethod(m);
+ << " to " << PrettyMethod(h_m.Get());
++error_count;
}
} else if (param_type->IsPrimitiveLong() || param_type->IsPrimitiveDouble()) {
@@ -387,7 +394,7 @@
// TODO: pass the JNI function name (such as "CallVoidMethodV") through so we can call JniAbort
// with an argument.
JniAbortF(nullptr, "bad arguments passed to %s (see above for details)",
- PrettyMethod(m).c_str());
+ PrettyMethod(h_m.Get()).c_str());
}
}
@@ -414,33 +421,36 @@
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
mirror::ArtMethod* method = soa.DecodeMethod(mid);
mirror::Object* receiver = method->IsStatic() ? nullptr : soa.Decode<mirror::Object*>(obj);
- MethodHelper mh(method);
+ uint32_t shorty_len = 0;
+ const char* shorty = method->GetShorty(&shorty_len);
JValue result;
- ArgArray arg_array(mh.GetShorty(), mh.GetShortyLength());
+ ArgArray arg_array(shorty, shorty_len);
arg_array.BuildArgArrayFromVarArgs(soa, receiver, args);
- InvokeWithArgArray(soa, method, &arg_array, &result, mh.GetShorty());
+ InvokeWithArgArray(soa, method, &arg_array, &result, shorty);
return result;
}
JValue InvokeWithJValues(const ScopedObjectAccessAlreadyRunnable& soa, mirror::Object* receiver,
jmethodID mid, jvalue* args) {
mirror::ArtMethod* method = soa.DecodeMethod(mid);
- MethodHelper mh(method);
+ uint32_t shorty_len = 0;
+ const char* shorty = method->GetShorty(&shorty_len);
JValue result;
- ArgArray arg_array(mh.GetShorty(), mh.GetShortyLength());
+ ArgArray arg_array(shorty, shorty_len);
arg_array.BuildArgArrayFromJValues(soa, receiver, args);
- InvokeWithArgArray(soa, method, &arg_array, &result, mh.GetShorty());
+ InvokeWithArgArray(soa, method, &arg_array, &result, shorty);
return result;
}
JValue InvokeVirtualOrInterfaceWithJValues(const ScopedObjectAccessAlreadyRunnable& soa,
mirror::Object* receiver, jmethodID mid, jvalue* args) {
mirror::ArtMethod* method = FindVirtualMethod(receiver, soa.DecodeMethod(mid));
- MethodHelper mh(method);
+ uint32_t shorty_len = 0;
+ const char* shorty = method->GetShorty(&shorty_len);
JValue result;
- ArgArray arg_array(mh.GetShorty(), mh.GetShortyLength());
+ ArgArray arg_array(shorty, shorty_len);
arg_array.BuildArgArrayFromJValues(soa, receiver, args);
- InvokeWithArgArray(soa, method, &arg_array, &result, mh.GetShorty());
+ InvokeWithArgArray(soa, method, &arg_array, &result, shorty);
return result;
}
@@ -448,11 +458,12 @@
jobject obj, jmethodID mid, va_list args) {
mirror::Object* receiver = soa.Decode<mirror::Object*>(obj);
mirror::ArtMethod* method = FindVirtualMethod(receiver, soa.DecodeMethod(mid));
- MethodHelper mh(method);
+ uint32_t shorty_len = 0;
+ const char* shorty = method->GetShorty(&shorty_len);
JValue result;
- ArgArray arg_array(mh.GetShorty(), mh.GetShortyLength());
+ ArgArray arg_array(shorty, shorty_len);
arg_array.BuildArgArrayFromVarArgs(soa, receiver, args);
- InvokeWithArgArray(soa, method, &arg_array, &result, mh.GetShorty());
+ InvokeWithArgArray(soa, method, &arg_array, &result, shorty);
return result;
}
@@ -493,8 +504,7 @@
// Get our arrays of arguments and their types, and check they're the same size.
mirror::ObjectArray<mirror::Object>* objects =
soa.Decode<mirror::ObjectArray<mirror::Object>*>(javaArgs);
- MethodHelper mh(m);
- const DexFile::TypeList* classes = mh.GetParameterTypeList();
+ const DexFile::TypeList* classes = m->GetParameterTypeList();
uint32_t classes_size = (classes == nullptr) ? 0 : classes->Size();
uint32_t arg_count = (objects != nullptr) ? objects->GetLength() : 0;
if (arg_count != classes_size) {
@@ -513,13 +523,17 @@
// Invoke the method.
JValue result;
- ArgArray arg_array(mh.GetShorty(), mh.GetShortyLength());
+ uint32_t shorty_len = 0;
+ const char* shorty = m->GetShorty(&shorty_len);
+ ArgArray arg_array(shorty, shorty_len);
+ StackHandleScope<1> hs(soa.Self());
+ MethodHelper mh(hs.NewHandle(m));
if (!arg_array.BuildArgArrayFromObjectArray(soa, receiver, objects, mh)) {
CHECK(soa.Self()->IsExceptionPending());
return nullptr;
}
- InvokeWithArgArray(soa, m, &arg_array, &result, mh.GetShorty());
+ InvokeWithArgArray(soa, m, &arg_array, &result, shorty);
// Wrap any exception with "Ljava/lang/reflect/InvocationTargetException;" and return early.
if (soa.Self()->IsExceptionPending()) {
diff --git a/runtime/stack.cc b/runtime/stack.cc
index ef09816..7e922c5 100644
--- a/runtime/stack.cc
+++ b/runtime/stack.cc
@@ -40,7 +40,7 @@
} else if (m->IsNative()) {
return GetVRegReference(0);
} else {
- const DexFile::CodeItem* code_item = MethodHelper(m).GetCodeItem();
+ const DexFile::CodeItem* code_item = m->GetCodeItem();
CHECK(code_item != NULL) << PrettyMethod(m);
uint16_t reg = code_item->registers_size_ - code_item->ins_size_;
return GetVRegReference(reg);
@@ -125,7 +125,7 @@
return cur_shadow_frame_->GetVRegReference(0);
}
} else {
- const DexFile::CodeItem* code_item = MethodHelper(m).GetCodeItem();
+ const DexFile::CodeItem* code_item = m->GetCodeItem();
if (code_item == NULL) {
UNIMPLEMENTED(ERROR) << "Failed to determine this object of abstract or proxy method: "
<< PrettyMethod(m);
@@ -157,7 +157,7 @@
uint32_t spill_mask = is_float ? frame_info.FpSpillMask() : frame_info.CoreSpillMask();
return GetGPR(vmap_table.ComputeRegister(spill_mask, vmap_offset, kind));
} else {
- const DexFile::CodeItem* code_item = MethodHelper(m).GetCodeItem();
+ const DexFile::CodeItem* code_item = m->GetCodeItem();
DCHECK(code_item != NULL) << PrettyMethod(m); // Can't be NULL or how would we compile its instructions?
return *GetVRegAddr(cur_quick_frame_, code_item, frame_info.CoreSpillMask(),
frame_info.FpSpillMask(), frame_info.FrameSizeInBytes(), vreg);
@@ -184,7 +184,7 @@
const uint32_t reg = vmap_table.ComputeRegister(spill_mask, vmap_offset, kReferenceVReg);
SetGPR(reg, new_value);
} else {
- const DexFile::CodeItem* code_item = MethodHelper(m).GetCodeItem();
+ const DexFile::CodeItem* code_item = m->GetCodeItem();
DCHECK(code_item != NULL) << PrettyMethod(m); // Can't be NULL or how would we compile its instructions?
int offset = GetVRegOffset(code_item, frame_info.CoreSpillMask(), frame_info.FpSpillMask(),
frame_info.FrameSizeInBytes(), vreg, kRuntimeISA);
diff --git a/runtime/thread.cc b/runtime/thread.cc
index 3bfdc3f..22f0e80 100644
--- a/runtime/thread.cc
+++ b/runtime/thread.cc
@@ -892,8 +892,7 @@
if (m->IsNative()) {
os << "(Native method)";
} else {
- mh.ChangeMethod(m);
- const char* source_file(mh.GetDeclaringClassSourceFile());
+ const char* source_file(m->GetDeclaringClassSourceFile());
os << "(" << (source_file != nullptr ? source_file : "unavailable")
<< ":" << line_number << ")";
}
@@ -933,7 +932,7 @@
std::ostream& os;
const Thread* thread;
const bool can_allocate;
- MethodHelper mh;
+ mirror::ArtMethod* method;
mirror::ArtMethod* last_method;
int last_line_number;
int repetition_count;
@@ -1530,7 +1529,6 @@
soa.Decode<mirror::ObjectArray<mirror::Object>*>(internal);
// Prepare parameters for StackTraceElement(String cls, String method, String file, int line)
mirror::ArtMethod* method = down_cast<mirror::ArtMethod*>(method_trace->Get(i));
- MethodHelper mh(method);
int32_t line_number;
StackHandleScope<3> hs(soa.Self());
auto class_name_object(hs.NewHandle<mirror::String>(nullptr));
@@ -1542,17 +1540,17 @@
} else {
mirror::IntArray* pc_trace = down_cast<mirror::IntArray*>(method_trace->Get(depth));
uint32_t dex_pc = pc_trace->Get(i);
- line_number = mh.GetLineNumFromDexPC(dex_pc);
+ line_number = method->GetLineNumFromDexPC(dex_pc);
// Allocate element, potentially triggering GC
// TODO: reuse class_name_object via Class::name_?
- const char* descriptor = mh.GetDeclaringClassDescriptor();
+ const char* descriptor = method->GetDeclaringClassDescriptor();
CHECK(descriptor != nullptr);
std::string class_name(PrettyDescriptor(descriptor));
class_name_object.Assign(mirror::String::AllocFromModifiedUtf8(soa.Self(), class_name.c_str()));
if (class_name_object.Get() == nullptr) {
return nullptr;
}
- const char* source_file = mh.GetDeclaringClassSourceFile();
+ const char* source_file = method->GetDeclaringClassSourceFile();
if (source_file != nullptr) {
source_name_object.Assign(mirror::String::AllocFromModifiedUtf8(soa.Self(), source_file));
if (source_name_object.Get() == nullptr) {
@@ -1560,7 +1558,7 @@
}
}
}
- const char* method_name = mh.GetName();
+ const char* method_name = method->GetName();
CHECK(method_name != nullptr);
Handle<mirror::String> method_name_object(
hs.NewHandle(mirror::String::AllocFromModifiedUtf8(soa.Self(), method_name)));
@@ -2044,8 +2042,7 @@
if (!m->IsNative() && !m->IsRuntimeMethod() && !m->IsProxyMethod()) {
const uint8_t* native_gc_map = m->GetNativeGcMap();
CHECK(native_gc_map != nullptr) << PrettyMethod(m);
- mh_.ChangeMethod(m);
- const DexFile::CodeItem* code_item = mh_.GetCodeItem();
+ const DexFile::CodeItem* code_item = m->GetCodeItem();
DCHECK(code_item != nullptr) << PrettyMethod(m); // Can't be nullptr or how would we compile its instructions?
NativePcOffsetToReferenceMap map(native_gc_map);
size_t num_regs = std::min(map.RegWidth() * 8,
@@ -2100,9 +2097,6 @@
// Visitor for when we visit a root.
const RootVisitor& visitor_;
-
- // A method helper we keep around to avoid dex file/cache re-computations.
- MethodHelper mh_;
};
class RootCallbackVisitor {
diff --git a/runtime/throw_location.cc b/runtime/throw_location.cc
index 06b6e8d..a1347a4 100644
--- a/runtime/throw_location.cc
+++ b/runtime/throw_location.cc
@@ -27,7 +27,7 @@
std::string ThrowLocation::Dump() const {
if (method_ != nullptr) {
return StringPrintf("%s:%d", PrettyMethod(method_).c_str(),
- MethodHelper(method_).GetLineNumFromDexPC(dex_pc_));
+ method_->GetLineNumFromDexPC(dex_pc_));
} else {
return "unknown throw location";
}
diff --git a/runtime/trace.cc b/runtime/trace.cc
index d53b369..032a566 100644
--- a/runtime/trace.cc
+++ b/runtime/trace.cc
@@ -677,12 +677,10 @@
}
void Trace::DumpMethodList(std::ostream& os, const std::set<mirror::ArtMethod*>& visited_methods) {
- MethodHelper mh;
for (const auto& method : visited_methods) {
- mh.ChangeMethod(method);
os << StringPrintf("%p\t%s\t%s\t%s\t%s\n", method,
- PrettyDescriptor(mh.GetDeclaringClassDescriptor()).c_str(), mh.GetName(),
- mh.GetSignature().ToString().c_str(), mh.GetDeclaringClassSourceFile());
+ PrettyDescriptor(method->GetDeclaringClassDescriptor()).c_str(), method->GetName(),
+ method->GetSignature().ToString().c_str(), method->GetDeclaringClassSourceFile());
}
}
diff --git a/runtime/utils.cc b/runtime/utils.cc
index ef2047b..7700658 100644
--- a/runtime/utils.cc
+++ b/runtime/utils.cc
@@ -365,15 +365,14 @@
if (m == nullptr) {
return "null";
}
- MethodHelper mh(m);
- std::string result(PrettyDescriptor(mh.GetDeclaringClassDescriptor()));
+ std::string result(PrettyDescriptor(m->GetDeclaringClassDescriptor()));
result += '.';
- result += mh.GetName();
+ result += m->GetName();
if (UNLIKELY(m->IsFastNative())) {
result += "!";
}
if (with_signature) {
- const Signature signature = mh.GetSignature();
+ const Signature signature = m->GetSignature();
std::string sig_as_string(signature.ToString());
if (signature == Signature::NoSignature()) {
return result + sig_as_string;
@@ -642,15 +641,14 @@
}
std::string JniShortName(mirror::ArtMethod* m) {
- MethodHelper mh(m);
- std::string class_name(mh.GetDeclaringClassDescriptor());
+ std::string class_name(m->GetDeclaringClassDescriptor());
// Remove the leading 'L' and trailing ';'...
CHECK_EQ(class_name[0], 'L') << class_name;
CHECK_EQ(class_name[class_name.size() - 1], ';') << class_name;
class_name.erase(0, 1);
class_name.erase(class_name.size() - 1, 1);
- std::string method_name(mh.GetName());
+ std::string method_name(m->GetName());
std::string short_name;
short_name += "Java_";
@@ -665,7 +663,7 @@
long_name += JniShortName(m);
long_name += "__";
- std::string signature(MethodHelper(m).GetSignature().ToString());
+ std::string signature(m->GetSignature().ToString());
signature.erase(0, 1);
signature.erase(signature.begin() + signature.find(')'), signature.end());
diff --git a/runtime/verifier/method_verifier.cc b/runtime/verifier/method_verifier.cc
index c7bb20c..e5dcbb0 100644
--- a/runtime/verifier/method_verifier.cc
+++ b/runtime/verifier/method_verifier.cc
@@ -338,12 +338,11 @@
void MethodVerifier::FindLocksAtDexPc(mirror::ArtMethod* m, uint32_t dex_pc,
std::vector<uint32_t>* monitor_enter_dex_pcs) {
- MethodHelper mh(m);
StackHandleScope<2> hs(Thread::Current());
- Handle<mirror::DexCache> dex_cache(hs.NewHandle(mh.GetDexCache()));
- Handle<mirror::ClassLoader> class_loader(hs.NewHandle(mh.GetClassLoader()));
- MethodVerifier verifier(&mh.GetDexFile(), &dex_cache, &class_loader, &mh.GetClassDef(),
- mh.GetCodeItem(), m->GetDexMethodIndex(), m, m->GetAccessFlags(), false,
+ Handle<mirror::DexCache> dex_cache(hs.NewHandle(m->GetDexCache()));
+ Handle<mirror::ClassLoader> class_loader(hs.NewHandle(m->GetClassLoader()));
+ MethodVerifier verifier(m->GetDexFile(), &dex_cache, &class_loader, &m->GetClassDef(),
+ m->GetCodeItem(), m->GetDexMethodIndex(), m, m->GetAccessFlags(), false,
true, false);
verifier.interesting_dex_pc_ = dex_pc;
verifier.monitor_enter_dex_pcs_ = monitor_enter_dex_pcs;
@@ -363,12 +362,11 @@
mirror::ArtField* MethodVerifier::FindAccessedFieldAtDexPc(mirror::ArtMethod* m,
uint32_t dex_pc) {
- MethodHelper mh(m);
StackHandleScope<2> hs(Thread::Current());
- Handle<mirror::DexCache> dex_cache(hs.NewHandle(mh.GetDexCache()));
- Handle<mirror::ClassLoader> class_loader(hs.NewHandle(mh.GetClassLoader()));
- MethodVerifier verifier(&mh.GetDexFile(), &dex_cache, &class_loader, &mh.GetClassDef(),
- mh.GetCodeItem(), m->GetDexMethodIndex(), m, m->GetAccessFlags(), true,
+ Handle<mirror::DexCache> dex_cache(hs.NewHandle(m->GetDexCache()));
+ Handle<mirror::ClassLoader> class_loader(hs.NewHandle(m->GetClassLoader()));
+ MethodVerifier verifier(m->GetDexFile(), &dex_cache, &class_loader, &m->GetClassDef(),
+ m->GetCodeItem(), m->GetDexMethodIndex(), m, m->GetAccessFlags(), true,
true, false);
return verifier.FindAccessedFieldAtDexPc(dex_pc);
}
@@ -394,12 +392,11 @@
mirror::ArtMethod* MethodVerifier::FindInvokedMethodAtDexPc(mirror::ArtMethod* m,
uint32_t dex_pc) {
- MethodHelper mh(m);
StackHandleScope<2> hs(Thread::Current());
- Handle<mirror::DexCache> dex_cache(hs.NewHandle(mh.GetDexCache()));
- Handle<mirror::ClassLoader> class_loader(hs.NewHandle(mh.GetClassLoader()));
- MethodVerifier verifier(&mh.GetDexFile(), &dex_cache, &class_loader, &mh.GetClassDef(),
- mh.GetCodeItem(), m->GetDexMethodIndex(), m, m->GetAccessFlags(), true,
+ Handle<mirror::DexCache> dex_cache(hs.NewHandle(m->GetDexCache()));
+ Handle<mirror::ClassLoader> class_loader(hs.NewHandle(m->GetClassLoader()));
+ MethodVerifier verifier(m->GetDexFile(), &dex_cache, &class_loader, &m->GetClassDef(),
+ m->GetCodeItem(), m->GetDexMethodIndex(), m, m->GetAccessFlags(), true,
true, false);
return verifier.FindInvokedMethodAtDexPc(dex_pc);
}
@@ -2136,19 +2133,22 @@
case Instruction::INVOKE_SUPER_RANGE: {
bool is_range = (inst->Opcode() == Instruction::INVOKE_VIRTUAL_RANGE ||
inst->Opcode() == Instruction::INVOKE_SUPER_RANGE);
- bool is_super = (inst->Opcode() == Instruction::INVOKE_SUPER ||
- inst->Opcode() == Instruction::INVOKE_SUPER_RANGE);
+ bool is_super = (inst->Opcode() == Instruction::INVOKE_SUPER ||
+ inst->Opcode() == Instruction::INVOKE_SUPER_RANGE);
mirror::ArtMethod* called_method = VerifyInvocationArgs(inst, METHOD_VIRTUAL,
is_range, is_super);
const RegType* return_type = nullptr;
if (called_method != nullptr) {
- MethodHelper mh(called_method);
+ Thread* self = Thread::Current();
+ StackHandleScope<1> hs(self);
+ Handle<mirror::ArtMethod> h_called_method(hs.NewHandle(called_method));
+ MethodHelper mh(h_called_method);
mirror::Class* return_type_class = mh.GetReturnType(can_load_classes_);
if (return_type_class != nullptr) {
- return_type = ®_types_.FromClass(mh.GetReturnTypeDescriptor(), return_type_class,
+ return_type = ®_types_.FromClass(h_called_method->GetReturnTypeDescriptor(),
+ return_type_class,
return_type_class->CannotBeAssignedFromOtherTypes());
} else {
- Thread* self = Thread::Current();
DCHECK(!can_load_classes_ || self->IsExceptionPending());
self->ClearException();
}
@@ -2183,7 +2183,7 @@
return_type_descriptor = dex_file_->StringByTypeIdx(return_type_idx);
} else {
is_constructor = called_method->IsConstructor();
- return_type_descriptor = MethodHelper(called_method).GetReturnTypeDescriptor();
+ return_type_descriptor = called_method->GetReturnTypeDescriptor();
}
if (is_constructor) {
/*
@@ -2249,10 +2249,10 @@
uint32_t return_type_idx = dex_file_->GetProtoId(method_id.proto_idx_).return_type_idx_;
descriptor = dex_file_->StringByTypeIdx(return_type_idx);
} else {
- descriptor = MethodHelper(called_method).GetReturnTypeDescriptor();
+ descriptor = called_method->GetReturnTypeDescriptor();
}
- const RegType& return_type = reg_types_.FromDescriptor(class_loader_->Get(), descriptor,
- false);
+ const RegType& return_type = reg_types_.FromDescriptor(class_loader_->Get(), descriptor,
+ false);
if (!return_type.IsLowHalf()) {
work_line_->SetResultRegisterType(return_type);
} else {
@@ -2307,7 +2307,7 @@
uint32_t return_type_idx = dex_file_->GetProtoId(method_id.proto_idx_).return_type_idx_;
descriptor = dex_file_->StringByTypeIdx(return_type_idx);
} else {
- descriptor = MethodHelper(abs_method).GetReturnTypeDescriptor();
+ descriptor = abs_method->GetReturnTypeDescriptor();
}
const RegType& return_type = reg_types_.FromDescriptor(class_loader_->Get(), descriptor,
false);
@@ -2574,7 +2574,7 @@
bool is_range = (inst->Opcode() == Instruction::INVOKE_VIRTUAL_RANGE_QUICK);
mirror::ArtMethod* called_method = VerifyInvokeVirtualQuickArgs(inst, is_range);
if (called_method != NULL) {
- const char* descriptor = MethodHelper(called_method).GetReturnTypeDescriptor();
+ const char* descriptor = called_method->GetReturnTypeDescriptor();
const RegType& return_type = reg_types_.FromDescriptor(class_loader_->Get(), descriptor,
false);
if (!return_type.IsLowHalf()) {
@@ -2962,7 +2962,7 @@
return NULL;
}
// Disallow any calls to class initializers.
- if (MethodHelper(res_method).IsClassInitializer()) {
+ if (res_method->IsClassInitializer()) {
Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "rejecting call to class initializer "
<< PrettyMethod(res_method);
return NULL;
@@ -3027,12 +3027,11 @@
}
mirror::Class* super_klass = super.GetClass();
if (res_method->GetMethodIndex() >= super_klass->GetVTable()->GetLength()) {
- MethodHelper mh(res_method);
Fail(VERIFY_ERROR_NO_METHOD) << "invalid invoke-super from "
<< PrettyMethod(dex_method_idx_, *dex_file_)
<< " to super " << super
- << "." << mh.GetName()
- << mh.GetSignature();
+ << "." << res_method->GetName()
+ << res_method->GetSignature();
return NULL;
}
}
@@ -3081,8 +3080,7 @@
* Process the target method's signature. This signature may or may not
* have been verified, so we can't assume it's properly formed.
*/
- MethodHelper mh(res_method);
- const DexFile::TypeList* params = mh.GetParameterTypeList();
+ const DexFile::TypeList* params = res_method->GetParameterTypeList();
size_t params_size = params == NULL ? 0 : params->Size();
uint32_t arg[5];
if (!is_range) {
@@ -3096,7 +3094,7 @@
return NULL;
}
const char* descriptor =
- mh.GetTypeDescriptorFromTypeIdx(params->GetTypeItem(param_index).type_idx_);
+ res_method->GetTypeDescriptorFromTypeIdx(params->GetTypeItem(param_index).type_idx_);
if (descriptor == NULL) {
Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Rejecting invocation of " << PrettyMethod(res_method)
<< " missing signature component";
@@ -3204,8 +3202,7 @@
* Process the target method's signature. This signature may or may not
* have been verified, so we can't assume it's properly formed.
*/
- MethodHelper mh(res_method);
- const DexFile::TypeList* params = mh.GetParameterTypeList();
+ const DexFile::TypeList* params = res_method->GetParameterTypeList();
size_t params_size = params == NULL ? 0 : params->Size();
uint32_t arg[5];
if (!is_range) {
@@ -3221,7 +3218,7 @@
return NULL;
}
const char* descriptor =
- mh.GetTypeDescriptorFromTypeIdx(params->GetTypeItem(param_index).type_idx_);
+ res_method->GetTypeDescriptorFromTypeIdx(params->GetTypeItem(param_index).type_idx_);
if (descriptor == NULL) {
Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Rejecting invocation of " << PrettyMethod(res_method)
<< " missing signature component";
@@ -3849,13 +3846,18 @@
const RegType& MethodVerifier::GetMethodReturnType() {
if (return_type_ == nullptr) {
if (mirror_method_ != NULL) {
- MethodHelper mh(mirror_method_);
- mirror::Class* return_type_class = mh.GetReturnType(can_load_classes_);
+ Thread* self = Thread::Current();
+ StackHandleScope<1> hs(self);
+ mirror::Class* return_type_class;
+ {
+ HandleWrapper<mirror::ArtMethod> h_mirror_method(hs.NewHandleWrapper(&mirror_method_));
+ return_type_class = MethodHelper(h_mirror_method).GetReturnType(can_load_classes_);
+ }
if (return_type_class != nullptr) {
- return_type_ = ®_types_.FromClass(mh.GetReturnTypeDescriptor(), return_type_class,
+ return_type_ = ®_types_.FromClass(mirror_method_->GetReturnTypeDescriptor(),
+ return_type_class,
return_type_class->CannotBeAssignedFromOtherTypes());
} else {
- Thread* self = Thread::Current();
DCHECK(!can_load_classes_ || self->IsExceptionPending());
self->ClearException();
}
diff --git a/test/ReferenceMap/stack_walk_refmap_jni.cc b/test/ReferenceMap/stack_walk_refmap_jni.cc
index 48a6c61..87187ed 100644
--- a/test/ReferenceMap/stack_walk_refmap_jni.cc
+++ b/test/ReferenceMap/stack_walk_refmap_jni.cc
@@ -33,8 +33,8 @@
namespace art {
-#define IS_IN_REF_BITMAP(mh, ref_bitmap, reg) \
- (((reg) < mh.GetCodeItem()->registers_size_) && \
+#define IS_IN_REF_BITMAP(ref_bitmap, reg) \
+ (((reg) < m->GetCodeItem()->registers_size_) && \
((*((ref_bitmap) + (reg)/8) >> ((reg) % 8) ) & 0x01))
#define CHECK_REGS_CONTAIN_REFS(...) \
@@ -42,7 +42,7 @@
int t[] = {__VA_ARGS__}; \
int t_size = sizeof(t) / sizeof(*t); \
for (int i = 0; i < t_size; ++i) \
- CHECK(IS_IN_REF_BITMAP(mh, ref_bitmap, t[i])) \
+ CHECK(IS_IN_REF_BITMAP(ref_bitmap, t[i])) \
<< "Error: Reg @ " << i << "-th argument is not in GC map"; \
} while (false)
@@ -67,8 +67,7 @@
}
const uint8_t* ref_bitmap = NULL;
- MethodHelper mh(m);
- std::string m_name(mh.GetName());
+ std::string m_name(m->GetName());
// Given the method name and the number of times the method has been called,
// we know the Dex registers with live reference values. Assert that what we
diff --git a/test/StackWalk/stack_walk_jni.cc b/test/StackWalk/stack_walk_jni.cc
index 3cf2d0b..c849c54 100644
--- a/test/StackWalk/stack_walk_jni.cc
+++ b/test/StackWalk/stack_walk_jni.cc
@@ -30,15 +30,15 @@
namespace art {
-#define REG(mh, reg_bitmap, reg) \
- (((reg) < mh.GetCodeItem()->registers_size_) && \
+#define REG(reg_bitmap, reg) \
+ (((reg) < m->GetCodeItem()->registers_size_) && \
((*((reg_bitmap) + (reg)/8) >> ((reg) % 8) ) & 0x01))
#define CHECK_REGS(...) if (!IsShadowFrame()) { \
int t[] = {__VA_ARGS__}; \
int t_size = sizeof(t) / sizeof(*t); \
for (int i = 0; i < t_size; ++i) \
- CHECK(REG(mh, reg_bitmap, t[i])) << "Error: Reg " << i << " is not in RegisterMap"; \
+ CHECK(REG(reg_bitmap, t[i])) << "Error: Reg " << i << " is not in RegisterMap"; \
}
static int gJava_StackWalk_refmap_calls = 0;
@@ -64,8 +64,7 @@
NativePcOffsetToReferenceMap map(m->GetNativeGcMap());
reg_bitmap = map.FindBitMap(GetNativePcOffset());
}
- MethodHelper mh(m);
- StringPiece m_name(mh.GetName());
+ StringPiece m_name(m->GetName());
// Given the method name and the number of times the method has been called,
// we know the Dex registers with live reference values. Assert that what we