From e01e3644205c3644546889237c20185391a0092e Mon Sep 17 00:00:00 2001 From: Andreas Gampe Date: Mon, 25 Jul 2016 13:06:04 -0700 Subject: [PATCH] ART: Add pointer-size template to some reflection functions The unstarted runtime may run code for a different pointer size, even when no transaction is active (e.g., during startup). To retain performance when the runtime is up and executing under normal conditions, add a template parameter and use sizeof(void*) in places where it is adequate. For maintainability, it is necessary to drop the default for the transaction template parameter. Implicit conversions from bool to size_t may lead to incorrect code and hard to diagnose problems. So instead ensure that all callers must give all template parameter values. Test: m test-art-host Change-Id: I3076883422c8553ede4de5642409c5684a5a9aa8 --- runtime/dex_file.cc | 38 ++++++++++-- .../quick/quick_trampoline_entrypoints.cc | 4 +- runtime/interpreter/unstarted_runtime.cc | 62 ++++++++++++++++--- runtime/jni_internal.cc | 9 ++- runtime/mirror/abstract_method.cc | 13 ++-- runtime/mirror/abstract_method.h | 2 +- runtime/mirror/class.cc | 70 +++++++++++++--------- runtime/mirror/class.h | 4 +- runtime/mirror/field-inl.h | 8 +-- runtime/mirror/field.h | 2 +- runtime/mirror/method.cc | 22 ++++--- runtime/mirror/method.h | 4 +- runtime/native/java_lang_Class.cc | 33 +++++++--- runtime/proxy_test.cc | 24 +++++--- 14 files changed, 207 insertions(+), 88 deletions(-) diff --git a/runtime/dex_file.cc b/runtime/dex_file.cc index 5d9ae14d1..2a2d2c09b 100644 --- a/runtime/dex_file.cc +++ b/runtime/dex_file.cc @@ -1638,8 +1638,15 @@ mirror::Object* DexFile::CreateAnnotationMember(Handle klass, mirror::Class* annotation_member_class = WellKnownClasses::ToClass(WellKnownClasses::libcore_reflect_AnnotationMember); Handle new_member(hs.NewHandle(annotation_member_class->AllocObject(self))); - Handle method_object( - hs.NewHandle(mirror::Method::CreateFromArtMethod(self, annotation_method))); + mirror::Method* method_obj_ptr; + DCHECK(!Runtime::Current()->IsActiveTransaction()); + if (pointer_size == 8U) { + method_obj_ptr = mirror::Method::CreateFromArtMethod<8U, false>(self, annotation_method); + } else { + DCHECK_EQ(pointer_size, 4U); + method_obj_ptr = mirror::Method::CreateFromArtMethod<4U, false>(self, annotation_method); + } + Handle method_object(hs.NewHandle(method_obj_ptr)); if (new_member.Get() == nullptr || string_name.Get() == nullptr || method_object.Get() == nullptr || method_return.Get() == nullptr) { @@ -1947,16 +1954,29 @@ bool DexFile::ProcessAnnotationValue(Handle klass, const uint8_t* StackHandleScope<2> hs(self); Handle dex_cache(hs.NewHandle(klass->GetDexCache())); Handle class_loader(hs.NewHandle(klass->GetClassLoader())); - ArtMethod* method = Runtime::Current()->GetClassLinker()->ResolveMethodWithoutInvokeType( + ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); + ArtMethod* method = class_linker->ResolveMethodWithoutInvokeType( klass->GetDexFile(), index, dex_cache, class_loader); if (method == nullptr) { return false; } + size_t pointer_size = class_linker->GetImagePointerSize(); set_object = true; + DCHECK(!Runtime::Current()->IsActiveTransaction()); if (method->IsConstructor()) { - element_object = mirror::Constructor::CreateFromArtMethod(self, method); + if (pointer_size == 8U) { + element_object = mirror::Constructor::CreateFromArtMethod<8U, false>(self, method); + } else { + DCHECK_EQ(pointer_size, 4U); + element_object = mirror::Constructor::CreateFromArtMethod<4U, false>(self, method); + } } else { - element_object = mirror::Method::CreateFromArtMethod(self, method); + if (pointer_size == 8U) { + element_object = mirror::Method::CreateFromArtMethod<8U, false>(self, method); + } else { + DCHECK_EQ(pointer_size, 4U); + element_object = mirror::Method::CreateFromArtMethod<4U, false>(self, method); + } } if (element_object == nullptr) { return false; @@ -1978,7 +1998,13 @@ bool DexFile::ProcessAnnotationValue(Handle klass, const uint8_t* return false; } set_object = true; - element_object = mirror::Field::CreateFromArtField(self, field, true); + size_t pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize(); + if (pointer_size == 8) { + element_object = mirror::Field::CreateFromArtField<8U>(self, field, true); + } else { + DCHECK_EQ(pointer_size, 4U); + element_object = mirror::Field::CreateFromArtField<4U>(self, field, true); + } if (element_object == nullptr) { return false; } diff --git a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc index 49043f674..0306bd62e 100644 --- a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc +++ b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc @@ -876,8 +876,10 @@ extern "C" uint64_t artQuickProxyInvokeHandler( DCHECK(interface_method != nullptr) << PrettyMethod(proxy_method); DCHECK(!interface_method->IsProxyMethod()) << PrettyMethod(interface_method); self->EndAssertNoThreadSuspension(old_cause); + DCHECK_EQ(Runtime::Current()->GetClassLinker()->GetImagePointerSize(), sizeof(void*)); + DCHECK(!Runtime::Current()->IsActiveTransaction()); jobject interface_method_jobj = soa.AddLocalReference( - mirror::Method::CreateFromArtMethod(soa.Self(), interface_method)); + mirror::Method::CreateFromArtMethod(soa.Self(), interface_method)); // All naked Object*s should now be in jobjects, so its safe to go into the main invoke code // that performs allocations. diff --git a/runtime/interpreter/unstarted_runtime.cc b/runtime/interpreter/unstarted_runtime.cc index 1f473e404..793260dc5 100644 --- a/runtime/interpreter/unstarted_runtime.cc +++ b/runtime/interpreter/unstarted_runtime.cc @@ -300,11 +300,25 @@ void UnstartedRuntime::UnstartedClassGetDeclaredField( PrettyDescriptor(klass).c_str()); return; } - if (Runtime::Current()->IsActiveTransaction()) { - result->SetL(mirror::Field::CreateFromArtField(self, found, true)); + Runtime* runtime = Runtime::Current(); + size_t pointer_size = runtime->GetClassLinker()->GetImagePointerSize(); + mirror::Field* field; + if (runtime->IsActiveTransaction()) { + if (pointer_size == 8) { + field = mirror::Field::CreateFromArtField<8U, true>(self, found, true); + } else { + DCHECK_EQ(pointer_size, 4U); + field = mirror::Field::CreateFromArtField<4U, true>(self, found, true); + } } else { - result->SetL(mirror::Field::CreateFromArtField(self, found, true)); + if (pointer_size == 8) { + field = mirror::Field::CreateFromArtField<8U, false>(self, found, true); + } else { + DCHECK_EQ(pointer_size, 4U); + field = mirror::Field::CreateFromArtField<4U, false>(self, found, true); + } } + result->SetL(field); } // This is required for Enum(Set) code, as that uses reflection to inspect enum classes. @@ -319,11 +333,26 @@ void UnstartedRuntime::UnstartedClassGetDeclaredMethod( mirror::String* name = shadow_frame->GetVRegReference(arg_offset + 1)->AsString(); mirror::ObjectArray* args = shadow_frame->GetVRegReference(arg_offset + 2)->AsObjectArray(); - if (Runtime::Current()->IsActiveTransaction()) { - result->SetL(mirror::Class::GetDeclaredMethodInternal(self, klass, name, args)); + Runtime* runtime = Runtime::Current(); + bool transaction = runtime->IsActiveTransaction(); + size_t pointer_size = runtime->GetClassLinker()->GetImagePointerSize(); + mirror::Method* method; + if (transaction) { + if (pointer_size == 8U) { + method = mirror::Class::GetDeclaredMethodInternal<8U, true>(self, klass, name, args); + } else { + DCHECK_EQ(pointer_size, 4U); + method = mirror::Class::GetDeclaredMethodInternal<4U, true>(self, klass, name, args); + } } else { - result->SetL(mirror::Class::GetDeclaredMethodInternal(self, klass, name, args)); + if (pointer_size == 8U) { + method = mirror::Class::GetDeclaredMethodInternal<8U, false>(self, klass, name, args); + } else { + DCHECK_EQ(pointer_size, 4U); + method = mirror::Class::GetDeclaredMethodInternal<4U, false>(self, klass, name, args); + } } + result->SetL(method); } // Special managed code cut-out to allow constructor lookup in a un-started runtime. @@ -336,11 +365,26 @@ void UnstartedRuntime::UnstartedClassGetDeclaredConstructor( } mirror::ObjectArray* args = shadow_frame->GetVRegReference(arg_offset + 1)->AsObjectArray(); - if (Runtime::Current()->IsActiveTransaction()) { - result->SetL(mirror::Class::GetDeclaredConstructorInternal(self, klass, args)); + Runtime* runtime = Runtime::Current(); + bool transaction = runtime->IsActiveTransaction(); + size_t pointer_size = runtime->GetClassLinker()->GetImagePointerSize(); + mirror::Constructor* constructor; + if (transaction) { + if (pointer_size == 8U) { + constructor = mirror::Class::GetDeclaredConstructorInternal<8U, true>(self, klass, args); + } else { + DCHECK_EQ(pointer_size, 4U); + constructor = mirror::Class::GetDeclaredConstructorInternal<4U, true>(self, klass, args); + } } else { - result->SetL(mirror::Class::GetDeclaredConstructorInternal(self, klass, args)); + if (pointer_size == 8U) { + constructor = mirror::Class::GetDeclaredConstructorInternal<8U, false>(self, klass, args); + } else { + DCHECK_EQ(pointer_size, 4U); + constructor = mirror::Class::GetDeclaredConstructorInternal<4U, false>(self, klass, args); + } } + result->SetL(constructor); } void UnstartedRuntime::UnstartedClassGetEnclosingClass( diff --git a/runtime/jni_internal.cc b/runtime/jni_internal.cc index 8cdf96de8..6ef399982 100644 --- a/runtime/jni_internal.cc +++ b/runtime/jni_internal.cc @@ -375,10 +375,12 @@ class JNI { ScopedObjectAccess soa(env); ArtMethod* m = soa.DecodeMethod(mid); mirror::AbstractMethod* method; + DCHECK_EQ(Runtime::Current()->GetClassLinker()->GetImagePointerSize(), sizeof(void*)); + DCHECK(!Runtime::Current()->IsActiveTransaction()); if (m->IsConstructor()) { - method = mirror::Constructor::CreateFromArtMethod(soa.Self(), m); + method = mirror::Constructor::CreateFromArtMethod(soa.Self(), m); } else { - method = mirror::Method::CreateFromArtMethod(soa.Self(), m); + method = mirror::Method::CreateFromArtMethod(soa.Self(), m); } return soa.AddLocalReference(method); } @@ -387,7 +389,8 @@ class JNI { CHECK_NON_NULL_ARGUMENT(fid); ScopedObjectAccess soa(env); ArtField* f = soa.DecodeField(fid); - return soa.AddLocalReference(mirror::Field::CreateFromArtField(soa.Self(), f, true)); + return soa.AddLocalReference( + mirror::Field::CreateFromArtField(soa.Self(), f, true)); } static jclass GetObjectClass(JNIEnv* env, jobject java_object) { diff --git a/runtime/mirror/abstract_method.cc b/runtime/mirror/abstract_method.cc index 5a07deee5..ef39132f9 100644 --- a/runtime/mirror/abstract_method.cc +++ b/runtime/mirror/abstract_method.cc @@ -21,12 +21,9 @@ namespace art { namespace mirror { -template +template bool AbstractMethod::CreateFromArtMethod(ArtMethod* method) { - auto* interface_method = method->GetInterfaceMethodIfProxy( - kTransactionActive - ? Runtime::Current()->GetClassLinker()->GetImagePointerSize() - : sizeof(void*)); + auto* interface_method = method->GetInterfaceMethodIfProxy(kPointerSize); SetArtMethod(method); SetFieldObject(DeclaringClassOffset(), method->GetDeclaringClass()); SetFieldObject( @@ -36,8 +33,10 @@ bool AbstractMethod::CreateFromArtMethod(ArtMethod* method) { return true; } -template bool AbstractMethod::CreateFromArtMethod(ArtMethod* method); -template bool AbstractMethod::CreateFromArtMethod(ArtMethod* method); +template bool AbstractMethod::CreateFromArtMethod<4U, false>(ArtMethod* method); +template bool AbstractMethod::CreateFromArtMethod<4U, true>(ArtMethod* method); +template bool AbstractMethod::CreateFromArtMethod<8U, false>(ArtMethod* method); +template bool AbstractMethod::CreateFromArtMethod<8U, true>(ArtMethod* method); ArtMethod* AbstractMethod::GetArtMethod() { return reinterpret_cast(GetField64(ArtMethodOffset())); diff --git a/runtime/mirror/abstract_method.h b/runtime/mirror/abstract_method.h index a39f94d39..936b14c57 100644 --- a/runtime/mirror/abstract_method.h +++ b/runtime/mirror/abstract_method.h @@ -34,7 +34,7 @@ namespace mirror { class MANAGED AbstractMethod : public AccessibleObject { public: // Called from Constructor::CreateFromArtMethod, Method::CreateFromArtMethod. - template + template bool CreateFromArtMethod(ArtMethod* method) SHARED_REQUIRES(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_); diff --git a/runtime/mirror/class.cc b/runtime/mirror/class.cc index 1c31c5764..375cb2f4b 100644 --- a/runtime/mirror/class.cc +++ b/runtime/mirror/class.cc @@ -1053,7 +1053,7 @@ uint32_t Class::FindTypeIndexInOtherDexFile(const DexFile& dex_file) { return (type_id == nullptr) ? DexFile::kDexNoIndex : dex_file.GetIndexForTypeId(*type_id); } -template +template mirror::Method* Class::GetDeclaredMethodInternal(Thread* self, mirror::Class* klass, mirror::String* name, @@ -1074,11 +1074,8 @@ mirror::Method* Class::GetDeclaredMethodInternal(Thread* self, auto h_args = hs.NewHandle(args); Handle h_klass = hs.NewHandle(klass); ArtMethod* result = nullptr; - const size_t pointer_size = kTransactionActive - ? Runtime::Current()->GetClassLinker()->GetImagePointerSize() - : sizeof(void*); - for (auto& m : h_klass->GetDeclaredVirtualMethods(pointer_size)) { - auto* np_method = m.GetInterfaceMethodIfProxy(pointer_size); + for (auto& m : h_klass->GetDeclaredVirtualMethods(kPointerSize)) { + auto* np_method = m.GetInterfaceMethodIfProxy(kPointerSize); // May cause thread suspension. mirror::String* np_name = np_method->GetNameAsString(self); if (!np_name->Equals(h_method_name.Get()) || !np_method->EqualParameters(h_args)) { @@ -1089,19 +1086,19 @@ mirror::Method* Class::GetDeclaredMethodInternal(Thread* self, } auto modifiers = m.GetAccessFlags(); if ((modifiers & kSkipModifiers) == 0) { - return mirror::Method::CreateFromArtMethod(self, &m); + return mirror::Method::CreateFromArtMethod(self, &m); } if ((modifiers & kAccMiranda) == 0) { result = &m; // Remember as potential result if it's not a miranda method. } } if (result == nullptr) { - for (auto& m : h_klass->GetDirectMethods(pointer_size)) { + for (auto& m : h_klass->GetDirectMethods(kPointerSize)) { auto modifiers = m.GetAccessFlags(); if ((modifiers & kAccConstructor) != 0) { continue; } - auto* np_method = m.GetInterfaceMethodIfProxy(pointer_size); + auto* np_method = m.GetInterfaceMethodIfProxy(kPointerSize); // May cause thread suspension. mirror::String* np_name = np_method->GetNameAsString(self); if (np_name == nullptr) { @@ -1115,50 +1112,69 @@ mirror::Method* Class::GetDeclaredMethodInternal(Thread* self, continue; } if ((modifiers & kSkipModifiers) == 0) { - return mirror::Method::CreateFromArtMethod(self, &m); + return mirror::Method::CreateFromArtMethod(self, &m); } // Direct methods cannot be miranda methods, so this potential result must be synthetic. result = &m; } } return result != nullptr - ? mirror::Method::CreateFromArtMethod(self, result) + ? mirror::Method::CreateFromArtMethod(self, result) : nullptr; } template -mirror::Method* Class::GetDeclaredMethodInternal(Thread* self, - mirror::Class* klass, - mirror::String* name, - mirror::ObjectArray* args); +mirror::Method* Class::GetDeclaredMethodInternal<4U, false>( + Thread* self, + mirror::Class* klass, + mirror::String* name, + mirror::ObjectArray* args); +template +mirror::Method* Class::GetDeclaredMethodInternal<4U, true>( + Thread* self, + mirror::Class* klass, + mirror::String* name, + mirror::ObjectArray* args); +template +mirror::Method* Class::GetDeclaredMethodInternal<8U, false>( + Thread* self, + mirror::Class* klass, + mirror::String* name, + mirror::ObjectArray* args); template -mirror::Method* Class::GetDeclaredMethodInternal(Thread* self, - mirror::Class* klass, - mirror::String* name, - mirror::ObjectArray* args); +mirror::Method* Class::GetDeclaredMethodInternal<8U, true>( + Thread* self, + mirror::Class* klass, + mirror::String* name, + mirror::ObjectArray* args); -template +template mirror::Constructor* Class::GetDeclaredConstructorInternal( Thread* self, mirror::Class* klass, mirror::ObjectArray* args) { StackHandleScope<1> hs(self); - const size_t pointer_size = kTransactionActive - ? Runtime::Current()->GetClassLinker()->GetImagePointerSize() - : sizeof(void*); - ArtMethod* result = klass->GetDeclaredConstructor(self, hs.NewHandle(args), pointer_size); + ArtMethod* result = klass->GetDeclaredConstructor(self, hs.NewHandle(args), kPointerSize); return result != nullptr - ? mirror::Constructor::CreateFromArtMethod(self, result) + ? mirror::Constructor::CreateFromArtMethod(self, result) : nullptr; } // mirror::Constructor::CreateFromArtMethod(self, result) -template mirror::Constructor* Class::GetDeclaredConstructorInternal( +template mirror::Constructor* Class::GetDeclaredConstructorInternal<4U, false>( + Thread* self, + mirror::Class* klass, + mirror::ObjectArray* args); +template mirror::Constructor* Class::GetDeclaredConstructorInternal<4U, true>( + Thread* self, + mirror::Class* klass, + mirror::ObjectArray* args); +template mirror::Constructor* Class::GetDeclaredConstructorInternal<8U, false>( Thread* self, mirror::Class* klass, mirror::ObjectArray* args); -template mirror::Constructor* Class::GetDeclaredConstructorInternal( +template mirror::Constructor* Class::GetDeclaredConstructorInternal<8U, true>( Thread* self, mirror::Class* klass, mirror::ObjectArray* args); diff --git a/runtime/mirror/class.h b/runtime/mirror/class.h index 9be9f0107..32ed337cc 100644 --- a/runtime/mirror/class.h +++ b/runtime/mirror/class.h @@ -754,13 +754,13 @@ class MANAGED Class FINAL : public Object { size_t pointer_size) SHARED_REQUIRES(Locks::mutator_lock_); - template + template static Method* GetDeclaredMethodInternal(Thread* self, mirror::Class* klass, mirror::String* name, mirror::ObjectArray* args) SHARED_REQUIRES(Locks::mutator_lock_); - template + template static Constructor* GetDeclaredConstructorInternal(Thread* self, mirror::Class* klass, mirror::ObjectArray* args) diff --git a/runtime/mirror/field-inl.h b/runtime/mirror/field-inl.h index 8a0daec4c..4183476a4 100644 --- a/runtime/mirror/field-inl.h +++ b/runtime/mirror/field-inl.h @@ -27,7 +27,7 @@ namespace art { namespace mirror { -template +template inline mirror::Field* Field::CreateFromArtField(Thread* self, ArtField* field, bool force_resolve) { StackHandleScope<2> hs(self); @@ -54,10 +54,8 @@ inline mirror::Field* Field::CreateFromArtField(Thread* self, ArtField* field, self->AssertPendingOOMException(); return nullptr; } - const auto pointer_size = kTransactionActive ? - Runtime::Current()->GetClassLinker()->GetImagePointerSize() : sizeof(void*); auto dex_field_index = field->GetDexFieldIndex(); - auto* resolved_field = field->GetDexCache()->GetResolvedField(dex_field_index, pointer_size); + auto* resolved_field = field->GetDexCache()->GetResolvedField(dex_field_index, kPointerSize); if (field->GetDeclaringClass()->IsProxyClass()) { DCHECK(field->IsStatic()); DCHECK_LT(dex_field_index, 2U); @@ -70,7 +68,7 @@ inline mirror::Field* Field::CreateFromArtField(Thread* self, ArtField* field, } else { // We rely on the field being resolved so that we can back to the ArtField // (i.e. FromReflectedMethod). - field->GetDexCache()->SetResolvedField(dex_field_index, field, pointer_size); + field->GetDexCache()->SetResolvedField(dex_field_index, field, kPointerSize); } } ret->SetType(type.Get()); diff --git a/runtime/mirror/field.h b/runtime/mirror/field.h index edaddbd2e..2bd613213 100644 --- a/runtime/mirror/field.h +++ b/runtime/mirror/field.h @@ -92,7 +92,7 @@ class MANAGED Field : public AccessibleObject { // Slow, try to use only for PrettyField and such. ArtField* GetArtField() SHARED_REQUIRES(Locks::mutator_lock_); - template + template static mirror::Field* CreateFromArtField(Thread* self, ArtField* field, bool force_resolve) SHARED_REQUIRES(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_); diff --git a/runtime/mirror/method.cc b/runtime/mirror/method.cc index 9838b7168..3cc70e1b8 100644 --- a/runtime/mirror/method.cc +++ b/runtime/mirror/method.cc @@ -51,18 +51,21 @@ void Method::ResetArrayClass() { array_class_ = GcRoot(nullptr); } -template +template Method* Method::CreateFromArtMethod(Thread* self, ArtMethod* method) { DCHECK(!method->IsConstructor()) << PrettyMethod(method); auto* ret = down_cast(StaticClass()->AllocObject(self)); if (LIKELY(ret != nullptr)) { - static_cast(ret)->CreateFromArtMethod(method); + static_cast(ret)-> + CreateFromArtMethod(method); } return ret; } -template Method* Method::CreateFromArtMethod(Thread* self, ArtMethod* method); -template Method* Method::CreateFromArtMethod(Thread* self, ArtMethod* method); +template Method* Method::CreateFromArtMethod<4U, false>(Thread* self, ArtMethod* method); +template Method* Method::CreateFromArtMethod<4U, true>(Thread* self, ArtMethod* method); +template Method* Method::CreateFromArtMethod<8U, false>(Thread* self, ArtMethod* method); +template Method* Method::CreateFromArtMethod<8U, true>(Thread* self, ArtMethod* method); void Method::VisitRoots(RootVisitor* visitor) { static_class_.VisitRootIfNonNull(visitor, RootInfo(kRootStickyClass)); @@ -96,18 +99,21 @@ void Constructor::VisitRoots(RootVisitor* visitor) { array_class_.VisitRootIfNonNull(visitor, RootInfo(kRootStickyClass)); } -template +template Constructor* Constructor::CreateFromArtMethod(Thread* self, ArtMethod* method) { DCHECK(method->IsConstructor()) << PrettyMethod(method); auto* ret = down_cast(StaticClass()->AllocObject(self)); if (LIKELY(ret != nullptr)) { - static_cast(ret)->CreateFromArtMethod(method); + static_cast(ret)-> + CreateFromArtMethod(method); } return ret; } -template Constructor* Constructor::CreateFromArtMethod(Thread* self, ArtMethod* method); -template Constructor* Constructor::CreateFromArtMethod(Thread* self, ArtMethod* method); +template Constructor* Constructor::CreateFromArtMethod<4U, false>(Thread* self, ArtMethod* method); +template Constructor* Constructor::CreateFromArtMethod<4U, true>(Thread* self, ArtMethod* method); +template Constructor* Constructor::CreateFromArtMethod<8U, false>(Thread* self, ArtMethod* method); +template Constructor* Constructor::CreateFromArtMethod<8U, true>(Thread* self, ArtMethod* method); } // namespace mirror } // namespace art diff --git a/runtime/mirror/method.h b/runtime/mirror/method.h index 0b569640e..ecd6a749e 100644 --- a/runtime/mirror/method.h +++ b/runtime/mirror/method.h @@ -28,7 +28,7 @@ class Class; // C++ mirror of java.lang.reflect.Method. class MANAGED Method : public AbstractMethod { public: - template + template static Method* CreateFromArtMethod(Thread* self, ArtMethod* method) SHARED_REQUIRES(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_); @@ -60,7 +60,7 @@ class MANAGED Method : public AbstractMethod { // C++ mirror of java.lang.reflect.Constructor. class MANAGED Constructor: public AbstractMethod { public: - template + template static Constructor* CreateFromArtMethod(Thread* self, ArtMethod* method) SHARED_REQUIRES(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_); diff --git a/runtime/native/java_lang_Class.cc b/runtime/native/java_lang_Class.cc index 0624da38c..02a97f517 100644 --- a/runtime/native/java_lang_Class.cc +++ b/runtime/native/java_lang_Class.cc @@ -136,7 +136,9 @@ static mirror::ObjectArray* GetDeclaredFields( } for (ArtField& field : ifields) { if (!public_only || field.IsPublic()) { - auto* reflect_field = mirror::Field::CreateFromArtField(self, &field, force_resolve); + auto* reflect_field = mirror::Field::CreateFromArtField(self, + &field, + force_resolve); if (reflect_field == nullptr) { if (kIsDebugBuild) { self->AssertPendingException(); @@ -149,7 +151,9 @@ static mirror::ObjectArray* GetDeclaredFields( } for (ArtField& field : sfields) { if (!public_only || field.IsPublic()) { - auto* reflect_field = mirror::Field::CreateFromArtField(self, &field, force_resolve); + auto* reflect_field = mirror::Field::CreateFromArtField(self, + &field, + force_resolve); if (reflect_field == nullptr) { if (kIsDebugBuild) { self->AssertPendingException(); @@ -222,11 +226,15 @@ ALWAYS_INLINE static inline mirror::Field* GetDeclaredField( SHARED_REQUIRES(Locks::mutator_lock_) { ArtField* art_field = FindFieldByName(self, name, c->GetIFieldsPtr()); if (art_field != nullptr) { - return mirror::Field::CreateFromArtField(self, art_field, true); + return mirror::Field::CreateFromArtField(self, + art_field, + true); } art_field = FindFieldByName(self, name, c->GetSFieldsPtr()); if (art_field != nullptr) { - return mirror::Field::CreateFromArtField(self, art_field, true); + return mirror::Field::CreateFromArtField(self, + art_field, + true); } return nullptr; } @@ -323,7 +331,9 @@ static jobject Class_getDeclaredField(JNIEnv* env, jobject javaThis, jstring nam static jobject Class_getDeclaredConstructorInternal( JNIEnv* env, jobject javaThis, jobjectArray args) { ScopedFastNativeObjectAccess soa(env); - mirror::Constructor* result = mirror::Class::GetDeclaredConstructorInternal( + DCHECK_EQ(Runtime::Current()->GetClassLinker()->GetImagePointerSize(), sizeof(void*)); + DCHECK(!Runtime::Current()->IsActiveTransaction()); + mirror::Constructor* result = mirror::Class::GetDeclaredConstructorInternal( soa.Self(), DecodeClass(soa, javaThis), soa.Decode*>(args)); @@ -355,7 +365,10 @@ static jobjectArray Class_getDeclaredConstructorsInternal( constructor_count = 0; for (auto& m : h_klass->GetDirectMethods(sizeof(void*))) { if (MethodMatchesConstructor(&m, publicOnly != JNI_FALSE)) { - auto* constructor = mirror::Constructor::CreateFromArtMethod(soa.Self(), &m); + DCHECK_EQ(Runtime::Current()->GetClassLinker()->GetImagePointerSize(), sizeof(void*)); + DCHECK(!Runtime::Current()->IsActiveTransaction()); + auto* constructor = mirror::Constructor::CreateFromArtMethod( + soa.Self(), &m); if (UNLIKELY(constructor == nullptr)) { soa.Self()->AssertPendingOOMException(); return nullptr; @@ -369,7 +382,9 @@ static jobjectArray Class_getDeclaredConstructorsInternal( static jobject Class_getDeclaredMethodInternal(JNIEnv* env, jobject javaThis, jobject name, jobjectArray args) { ScopedFastNativeObjectAccess soa(env); - mirror::Method* result = mirror::Class::GetDeclaredMethodInternal( + DCHECK_EQ(Runtime::Current()->GetClassLinker()->GetImagePointerSize(), sizeof(void*)); + DCHECK(!Runtime::Current()->IsActiveTransaction()); + mirror::Method* result = mirror::Class::GetDeclaredMethodInternal( soa.Self(), DecodeClass(soa, javaThis), soa.Decode(name), @@ -398,7 +413,9 @@ static jobjectArray Class_getDeclaredMethodsUnchecked(JNIEnv* env, jobject javaT auto modifiers = m.GetAccessFlags(); if ((publicOnly == JNI_FALSE || (modifiers & kAccPublic) != 0) && (modifiers & kAccConstructor) == 0) { - auto* method = mirror::Method::CreateFromArtMethod(soa.Self(), &m); + DCHECK_EQ(Runtime::Current()->GetClassLinker()->GetImagePointerSize(), sizeof(void*)); + DCHECK(!Runtime::Current()->IsActiveTransaction()); + auto* method = mirror::Method::CreateFromArtMethod(soa.Self(), &m); if (method == nullptr) { soa.Self()->AssertPendingException(); return nullptr; diff --git a/runtime/proxy_test.cc b/runtime/proxy_test.cc index 4d9ca6d44..1ce7e483d 100644 --- a/runtime/proxy_test.cc +++ b/runtime/proxy_test.cc @@ -60,29 +60,31 @@ class ProxyTest : public CommonCompilerTest { jsize array_index = 0; // Fill the method array + DCHECK_EQ(Runtime::Current()->GetClassLinker()->GetImagePointerSize(), sizeof(void*)); ArtMethod* method = javaLangObject->FindDeclaredVirtualMethod( "equals", "(Ljava/lang/Object;)Z", sizeof(void*)); CHECK(method != nullptr); + DCHECK(!Runtime::Current()->IsActiveTransaction()); soa.Env()->SetObjectArrayElement( proxyClassMethods, array_index++, soa.AddLocalReference( - mirror::Method::CreateFromArtMethod(soa.Self(), method))); + mirror::Method::CreateFromArtMethod(soa.Self(), method))); method = javaLangObject->FindDeclaredVirtualMethod("hashCode", "()I", sizeof(void*)); CHECK(method != nullptr); soa.Env()->SetObjectArrayElement( proxyClassMethods, array_index++, soa.AddLocalReference( - mirror::Method::CreateFromArtMethod(soa.Self(), method))); + mirror::Method::CreateFromArtMethod(soa.Self(), method))); method = javaLangObject->FindDeclaredVirtualMethod( "toString", "()Ljava/lang/String;", sizeof(void*)); CHECK(method != nullptr); soa.Env()->SetObjectArrayElement( proxyClassMethods, array_index++, soa.AddLocalReference( - mirror::Method::CreateFromArtMethod(soa.Self(), method))); + mirror::Method::CreateFromArtMethod(soa.Self(), method))); // Now adds all interfaces virtual methods. for (mirror::Class* interface : interfaces) { for (auto& m : interface->GetDeclaredVirtualMethods(sizeof(void*))) { soa.Env()->SetObjectArrayElement( proxyClassMethods, array_index++, soa.AddLocalReference( - mirror::Method::CreateFromArtMethod(soa.Self(), &m))); + mirror::Method::CreateFromArtMethod(soa.Self(), &m))); } } CHECK_EQ(array_index, methods_count); @@ -226,14 +228,20 @@ TEST_F(ProxyTest, CheckArtMirrorFieldsOfProxyStaticFields) { EXPECT_EQ(static_fields1->At(0).GetDeclaringClass(), proxyClass1.Get()); EXPECT_EQ(static_fields1->At(1).GetDeclaringClass(), proxyClass1.Get()); + ASSERT_EQ(Runtime::Current()->GetClassLinker()->GetImagePointerSize(), sizeof(void*)); + ASSERT_FALSE(Runtime::Current()->IsActiveTransaction()); Handle field00 = - hs.NewHandle(mirror::Field::CreateFromArtField(soa.Self(), &static_fields0->At(0), true)); + hs.NewHandle(mirror::Field::CreateFromArtField( + soa.Self(), &static_fields0->At(0), true)); Handle field01 = - hs.NewHandle(mirror::Field::CreateFromArtField(soa.Self(), &static_fields0->At(1), true)); + hs.NewHandle(mirror::Field::CreateFromArtField( + soa.Self(), &static_fields0->At(1), true)); Handle field10 = - hs.NewHandle(mirror::Field::CreateFromArtField(soa.Self(), &static_fields1->At(0), true)); + hs.NewHandle(mirror::Field::CreateFromArtField( + soa.Self(), &static_fields1->At(0), true)); Handle field11 = - hs.NewHandle(mirror::Field::CreateFromArtField(soa.Self(), &static_fields1->At(1), true)); + hs.NewHandle(mirror::Field::CreateFromArtField( + soa.Self(), &static_fields1->At(1), true)); EXPECT_EQ(field00->GetArtField(), &static_fields0->At(0)); EXPECT_EQ(field01->GetArtField(), &static_fields0->At(1)); EXPECT_EQ(field10->GetArtField(), &static_fields1->At(0)); -- 2.11.0