diff options
| -rw-r--r-- | runtime/dex_file_annotations.cc | 92 | ||||
| -rw-r--r-- | runtime/interpreter/unstarted_runtime.cc | 14 | ||||
| -rw-r--r-- | runtime/interpreter/unstarted_runtime_list.h | 1 | ||||
| -rw-r--r-- | runtime/interpreter/unstarted_runtime_test.cc | 45 |
4 files changed, 118 insertions, 34 deletions
diff --git a/runtime/dex_file_annotations.cc b/runtime/dex_file_annotations.cc index a95f94cabb..d39ea35a90 100644 --- a/runtime/dex_file_annotations.cc +++ b/runtime/dex_file_annotations.cc @@ -299,6 +299,7 @@ mirror::Object* ProcessEncodedAnnotation(Handle<mirror::Class> klass, const uint return result.GetL(); } +template <bool kTransactionActive> bool ProcessAnnotationValue(Handle<mirror::Class> klass, const uint8_t** annotation_ptr, DexFile::AnnotationValue* annotation_value, @@ -409,22 +410,21 @@ bool ProcessAnnotationValue(Handle<mirror::Class> klass, } PointerSize pointer_size = class_linker->GetImagePointerSize(); set_object = true; - DCHECK(!Runtime::Current()->IsActiveTransaction()); if (method->IsConstructor()) { if (pointer_size == PointerSize::k64) { element_object = mirror::Constructor::CreateFromArtMethod<PointerSize::k64, - false>(self, method); + kTransactionActive>(self, method); } else { element_object = mirror::Constructor::CreateFromArtMethod<PointerSize::k32, - false>(self, method); + kTransactionActive>(self, method); } } else { if (pointer_size == PointerSize::k64) { element_object = mirror::Method::CreateFromArtMethod<PointerSize::k64, - false>(self, method); + kTransactionActive>(self, method); } else { element_object = mirror::Method::CreateFromArtMethod<PointerSize::k32, - false>(self, method); + kTransactionActive>(self, method); } } if (element_object == nullptr) { @@ -449,9 +449,11 @@ bool ProcessAnnotationValue(Handle<mirror::Class> klass, set_object = true; PointerSize pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize(); if (pointer_size == PointerSize::k64) { - element_object = mirror::Field::CreateFromArtField<PointerSize::k64>(self, field, true); + element_object = mirror::Field::CreateFromArtField<PointerSize::k64, + kTransactionActive>(self, field, true); } else { - element_object = mirror::Field::CreateFromArtField<PointerSize::k32>(self, field, true); + element_object = mirror::Field::CreateFromArtField<PointerSize::k32, + kTransactionActive>(self, field, true); } if (element_object == nullptr) { return false; @@ -497,45 +499,49 @@ bool ProcessAnnotationValue(Handle<mirror::Class> klass, } DexFile::AnnotationValue new_annotation_value; for (uint32_t i = 0; i < size; ++i) { - if (!ProcessAnnotationValue(klass, &annotation, &new_annotation_value, - component_type, DexFile::kPrimitivesOrObjects)) { + if (!ProcessAnnotationValue<kTransactionActive>(klass, + &annotation, + &new_annotation_value, + component_type, + DexFile::kPrimitivesOrObjects)) { return false; } if (!component_type->IsPrimitive()) { mirror::Object* obj = new_annotation_value.value_.GetL(); - new_array->AsObjectArray<mirror::Object>()->SetWithoutChecks<false>(i, obj); + new_array->AsObjectArray<mirror::Object>()-> + SetWithoutChecks<kTransactionActive>(i, obj); } else { switch (new_annotation_value.type_) { case DexFile::kDexAnnotationByte: - new_array->AsByteArray()->SetWithoutChecks<false>( + new_array->AsByteArray()->SetWithoutChecks<kTransactionActive>( i, new_annotation_value.value_.GetB()); break; case DexFile::kDexAnnotationShort: - new_array->AsShortArray()->SetWithoutChecks<false>( + new_array->AsShortArray()->SetWithoutChecks<kTransactionActive>( i, new_annotation_value.value_.GetS()); break; case DexFile::kDexAnnotationChar: - new_array->AsCharArray()->SetWithoutChecks<false>( + new_array->AsCharArray()->SetWithoutChecks<kTransactionActive>( i, new_annotation_value.value_.GetC()); break; case DexFile::kDexAnnotationInt: - new_array->AsIntArray()->SetWithoutChecks<false>( + new_array->AsIntArray()->SetWithoutChecks<kTransactionActive>( i, new_annotation_value.value_.GetI()); break; case DexFile::kDexAnnotationLong: - new_array->AsLongArray()->SetWithoutChecks<false>( + new_array->AsLongArray()->SetWithoutChecks<kTransactionActive>( i, new_annotation_value.value_.GetJ()); break; case DexFile::kDexAnnotationFloat: - new_array->AsFloatArray()->SetWithoutChecks<false>( + new_array->AsFloatArray()->SetWithoutChecks<kTransactionActive>( i, new_annotation_value.value_.GetF()); break; case DexFile::kDexAnnotationDouble: - new_array->AsDoubleArray()->SetWithoutChecks<false>( + new_array->AsDoubleArray()->SetWithoutChecks<kTransactionActive>( i, new_annotation_value.value_.GetD()); break; case DexFile::kDexAnnotationBoolean: - new_array->AsBooleanArray()->SetWithoutChecks<false>( + new_array->AsBooleanArray()->SetWithoutChecks<kTransactionActive>( i, new_annotation_value.value_.GetZ()); break; default: @@ -611,8 +617,11 @@ mirror::Object* CreateAnnotationMember(Handle<mirror::Class> klass, annotation_method->GetReturnType(true /* resolve */))); DexFile::AnnotationValue annotation_value; - if (!ProcessAnnotationValue(klass, annotation, &annotation_value, method_return, - DexFile::kAllObjects)) { + if (!ProcessAnnotationValue<false>(klass, + annotation, + &annotation_value, + method_return, + DexFile::kAllObjects)) { return nullptr; } Handle<mirror::Object> value_object(hs.NewHandle(annotation_value.value_.GetL())); @@ -716,8 +725,18 @@ mirror::Object* GetAnnotationValue(Handle<mirror::Class> klass, return nullptr; } DexFile::AnnotationValue annotation_value; - if (!ProcessAnnotationValue(klass, &annotation, &annotation_value, array_class, - DexFile::kAllObjects)) { + bool result = Runtime::Current()->IsActiveTransaction() + ? ProcessAnnotationValue<true>(klass, + &annotation, + &annotation_value, + array_class, + DexFile::kAllObjects) + : ProcessAnnotationValue<false>(klass, + &annotation, + &annotation_value, + array_class, + DexFile::kAllObjects); + if (!result) { return nullptr; } if (annotation_value.type_ != expected_type) { @@ -949,8 +968,11 @@ mirror::Object* GetAnnotationDefaultValue(ArtMethod* method) { StackHandleScope<2> hs(Thread::Current()); Handle<mirror::Class> h_klass(hs.NewHandle(klass)); Handle<mirror::Class> return_type(hs.NewHandle(method->GetReturnType(true /* resolve */))); - if (!ProcessAnnotationValue(h_klass, &annotation, &annotation_value, return_type, - DexFile::kAllObjects)) { + if (!ProcessAnnotationValue<false>(h_klass, + &annotation, + &annotation_value, + return_type, + DexFile::kAllObjects)) { return nullptr; } return annotation_value.value_.GetL(); @@ -1201,8 +1223,11 @@ mirror::Class* GetEnclosingClass(Handle<mirror::Class> klass) { return nullptr; } DexFile::AnnotationValue annotation_value; - if (!ProcessAnnotationValue(klass, &annotation, &annotation_value, - ScopedNullHandle<mirror::Class>(), DexFile::kAllRaw)) { + if (!ProcessAnnotationValue<false>(klass, + &annotation, + &annotation_value, + ScopedNullHandle<mirror::Class>(), + DexFile::kAllRaw)) { return nullptr; } if (annotation_value.type_ != DexFile::kDexAnnotationMethod) { @@ -1252,9 +1277,11 @@ bool GetInnerClass(Handle<mirror::Class> klass, mirror::String** name) { return false; } DexFile::AnnotationValue annotation_value; - if (!ProcessAnnotationValue(klass, &annotation, &annotation_value, - ScopedNullHandle<mirror::Class>(), - DexFile::kAllObjects)) { + if (!ProcessAnnotationValue<false>(klass, + &annotation, + &annotation_value, + ScopedNullHandle<mirror::Class>(), + DexFile::kAllObjects)) { return false; } if (annotation_value.type_ != DexFile::kDexAnnotationNull && @@ -1283,8 +1310,11 @@ bool GetInnerClassFlags(Handle<mirror::Class> klass, uint32_t* flags) { return false; } DexFile::AnnotationValue annotation_value; - if (!ProcessAnnotationValue(klass, &annotation, &annotation_value, - ScopedNullHandle<mirror::Class>(), DexFile::kAllRaw)) { + if (!ProcessAnnotationValue<false>(klass, + &annotation, + &annotation_value, + ScopedNullHandle<mirror::Class>(), + DexFile::kAllRaw)) { return false; } if (annotation_value.type_ != DexFile::kDexAnnotationInt) { diff --git a/runtime/interpreter/unstarted_runtime.cc b/runtime/interpreter/unstarted_runtime.cc index fc219450df..4a321e6d27 100644 --- a/runtime/interpreter/unstarted_runtime.cc +++ b/runtime/interpreter/unstarted_runtime.cc @@ -445,6 +445,20 @@ void UnstartedRuntime::UnstartedClassGetInnerClassFlags( result->SetI(mirror::Class::GetInnerClassFlags(klass, default_value)); } +void UnstartedRuntime::UnstartedClassGetSignatureAnnotation( + Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) { + StackHandleScope<1> hs(self); + Handle<mirror::Class> klass(hs.NewHandle( + reinterpret_cast<mirror::Class*>(shadow_frame->GetVRegReference(arg_offset)))); + + if (klass->IsProxyClass() || klass->GetDexCache() == nullptr) { + result->SetL(nullptr); + return; + } + + result->SetL(annotations::GetSignatureAnnotationForClass(klass)); +} + void UnstartedRuntime::UnstartedClassIsAnonymousClass( Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) { StackHandleScope<1> hs(self); diff --git a/runtime/interpreter/unstarted_runtime_list.h b/runtime/interpreter/unstarted_runtime_list.h index 929b747840..c6114da037 100644 --- a/runtime/interpreter/unstarted_runtime_list.h +++ b/runtime/interpreter/unstarted_runtime_list.h @@ -31,6 +31,7 @@ V(ClassGetDeclaringClass, "java.lang.Class java.lang.Class.getDeclaringClass()") \ V(ClassGetEnclosingClass, "java.lang.Class java.lang.Class.getEnclosingClass()") \ V(ClassGetInnerClassFlags, "int java.lang.Class.getInnerClassFlags(int)") \ + V(ClassGetSignatureAnnotation, "java.lang.String[] java.lang.Class.getSignatureAnnotation()") \ V(ClassIsAnonymousClass, "boolean java.lang.Class.isAnonymousClass()") \ V(ClassLoaderGetResourceAsStream, "java.io.InputStream java.lang.ClassLoader.getResourceAsStream(java.lang.String)") \ V(VmClassLoaderFindLoadedClass, "java.lang.Class java.lang.VMClassLoader.findLoadedClass(java.lang.ClassLoader, java.lang.String)") \ diff --git a/runtime/interpreter/unstarted_runtime_test.cc b/runtime/interpreter/unstarted_runtime_test.cc index 3a0d0e71c2..4186c37dbc 100644 --- a/runtime/interpreter/unstarted_runtime_test.cc +++ b/runtime/interpreter/unstarted_runtime_test.cc @@ -29,6 +29,8 @@ #include "handle_scope-inl.h" #include "interpreter/interpreter_common.h" #include "mirror/class_loader.h" +#include "mirror/object_array-inl.h" +#include "mirror/object-inl.h" #include "mirror/string-inl.h" #include "runtime.h" #include "scoped_thread_state_change-inl.h" @@ -1077,9 +1079,9 @@ TEST_F(UnstartedRuntimeTest, LogManager) { StackHandleScope<1> hs(self); ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); Handle<mirror::Class> log_manager_class = hs.NewHandle( - class_linker->FindClass(self, - "Ljava/util/logging/LogManager;", - ScopedNullHandle<mirror::ClassLoader>())); + class_linker->FindClass(self, + "Ljava/util/logging/LogManager;", + ScopedNullHandle<mirror::ClassLoader>())); ASSERT_TRUE(log_manager_class.Get() != nullptr); ASSERT_TRUE(class_linker->EnsureInitialized(self, log_manager_class, true, true)); } @@ -1278,5 +1280,42 @@ TEST_F(UnstartedClassForNameTest, ClassForNameLongWithClassLoaderFail) { RunTest(runner, true, false); } +TEST_F(UnstartedRuntimeTest, ClassGetSignatureAnnotation) { + Thread* self = Thread::Current(); + ScopedObjectAccess soa(self); + + StackHandleScope<1> hs(self); + ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); + Handle<mirror::Class> list_class = hs.NewHandle( + class_linker->FindClass(self, + "Ljava/util/List;", + ScopedNullHandle<mirror::ClassLoader>())); + ASSERT_TRUE(list_class.Get() != nullptr); + ASSERT_TRUE(class_linker->EnsureInitialized(self, list_class, true, true)); + + JValue result; + ShadowFrame* shadow_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); + + shadow_frame->SetVRegReference(0, list_class.Get()); + UnstartedClassGetSignatureAnnotation(self, shadow_frame, &result, 0); + ASSERT_TRUE(result.GetL() != nullptr); + ASSERT_FALSE(self->IsExceptionPending()); + + ShadowFrame::DeleteDeoptimizedFrame(shadow_frame); + + ASSERT_TRUE(result.GetL()->IsObjectArray()); + ObjPtr<mirror::ObjectArray<mirror::Object>> array = + result.GetL()->AsObjectArray<mirror::Object>(); + std::ostringstream oss; + for (int32_t i = 0; i != array->GetLength(); ++i) { + ObjPtr<mirror::Object> elem = array->Get(i); + ASSERT_TRUE(elem != nullptr); + ASSERT_TRUE(elem->IsString()); + oss << elem->AsString()->ToModifiedUtf8(); + } + std::string output_string = oss.str(); + ASSERT_EQ(output_string, "<E:Ljava/lang/Object;>Ljava/lang/Object;Ljava/util/Collection<TE;>;"); +} + } // namespace interpreter } // namespace art |