Revert "Refactor annotation code for obsolete methods."
Test has flakes.
Bug: 31455788
This reverts commit 672a0b75c91af44749b1e946684e6a65a884d778.
Change-Id: If00ecbd31abe204bcaf8341eceb674e07c0ac8f2
diff --git a/runtime/art_method-inl.h b/runtime/art_method-inl.h
index b47f8f0..685e26c 100644
--- a/runtime/art_method-inl.h
+++ b/runtime/art_method-inl.h
@@ -347,11 +347,7 @@
inline uint16_t ArtMethod::GetClassDefIndex() {
DCHECK(!IsProxyMethod());
- if (LIKELY(!IsObsolete())) {
- return GetDeclaringClass()->GetDexClassDefIndex();
- } else {
- return FindObsoleteDexClassDefIndex();
- }
+ return GetDeclaringClass()->GetDexClassDefIndex();
}
inline const DexFile::ClassDef& ArtMethod::GetClassDef() {
diff --git a/runtime/art_method.cc b/runtime/art_method.cc
index 80a8773..9d74e7c 100644
--- a/runtime/art_method.cc
+++ b/runtime/art_method.cc
@@ -104,16 +104,6 @@
UNREACHABLE();
}
-uint16_t ArtMethod::FindObsoleteDexClassDefIndex() {
- DCHECK(!Runtime::Current()->IsAotCompiler()) << PrettyMethod();
- DCHECK(IsObsolete());
- const DexFile* dex_file = GetDexFile();
- const dex::TypeIndex declaring_class_type = dex_file->GetMethodId(GetDexMethodIndex()).class_idx_;
- const DexFile::ClassDef* class_def = dex_file->FindClassDef(declaring_class_type);
- CHECK(class_def != nullptr);
- return dex_file->GetIndexForClassDef(*class_def);
-}
-
mirror::String* ArtMethod::GetNameAsString(Thread* self) {
CHECK(!IsProxyMethod());
StackHandleScope<1> hs(self);
diff --git a/runtime/art_method.h b/runtime/art_method.h
index 2248c3b..cd1950c 100644
--- a/runtime/art_method.h
+++ b/runtime/art_method.h
@@ -700,8 +700,6 @@
} ptr_sized_fields_;
private:
- uint16_t FindObsoleteDexClassDefIndex() REQUIRES_SHARED(Locks::mutator_lock_);
-
bool IsAnnotatedWith(jclass klass, uint32_t visibility);
static constexpr size_t PtrSizedFieldsOffset(PointerSize pointer_size) {
diff --git a/runtime/dex_file_annotations.cc b/runtime/dex_file_annotations.cc
index 6b9654d..d39ea35 100644
--- a/runtime/dex_file_annotations.cc
+++ b/runtime/dex_file_annotations.cc
@@ -41,80 +41,7 @@
};
namespace {
-
-// A helper class that contains all the data needed to do annotation lookup.
-class ClassData {
- public:
- explicit ClassData(ArtMethod* method) REQUIRES_SHARED(Locks::mutator_lock_)
- : ClassData(ScopedNullHandle<mirror::Class>(), // klass
- method,
- *method->GetDexFile(),
- &method->GetClassDef()) {}
-
- // Requires Scope to be able to create at least 1 handles.
- template <typename Scope>
- ClassData(Scope& hs, ArtField* field) REQUIRES_SHARED(Locks::mutator_lock_)
- : ClassData(hs.NewHandle(field->GetDeclaringClass())) { }
-
- explicit ClassData(Handle<mirror::Class> klass) REQUIRES_SHARED(art::Locks::mutator_lock_)
- : ClassData(klass, // klass
- nullptr, // method
- klass->GetDexFile(),
- klass->GetClassDef()) {}
-
- const DexFile& GetDexFile() const REQUIRES_SHARED(Locks::mutator_lock_) {
- return dex_file_;
- }
-
- const DexFile::ClassDef* GetClassDef() const REQUIRES_SHARED(Locks::mutator_lock_) {
- return class_def_;
- }
-
- ObjPtr<mirror::DexCache> GetDexCache() const REQUIRES_SHARED(Locks::mutator_lock_) {
- if (method_ != nullptr) {
- return method_->GetDexCache();
- } else {
- return real_klass_->GetDexCache();
- }
- }
-
- ObjPtr<mirror::ClassLoader> GetClassLoader() const REQUIRES_SHARED(Locks::mutator_lock_) {
- if (method_ != nullptr) {
- return method_->GetDeclaringClass()->GetClassLoader();
- } else {
- return real_klass_->GetClassLoader();
- }
- }
-
- ObjPtr<mirror::Class> GetRealClass() const REQUIRES_SHARED(Locks::mutator_lock_) {
- if (method_ != nullptr) {
- return method_->GetDeclaringClass();
- } else {
- return real_klass_.Get();
- }
- }
-
- private:
- ClassData(Handle<mirror::Class> klass,
- ArtMethod* method,
- const DexFile& dex_file,
- const DexFile::ClassDef* class_def) REQUIRES_SHARED(Locks::mutator_lock_)
- : real_klass_(klass),
- method_(method),
- dex_file_(dex_file),
- class_def_(class_def) {
- DCHECK((method_ == nullptr) || real_klass_.IsNull());
- }
-
- Handle<mirror::Class> real_klass_;
- ArtMethod* method_;
- const DexFile& dex_file_;
- const DexFile::ClassDef* class_def_;
-
- DISALLOW_COPY_AND_ASSIGN(ClassData);
-};
-
-mirror::Object* CreateAnnotationMember(const ClassData& klass,
+mirror::Object* CreateAnnotationMember(Handle<mirror::Class> klass,
Handle<mirror::Class> annotation_class,
const uint8_t** annotation)
REQUIRES_SHARED(Locks::mutator_lock_);
@@ -258,8 +185,9 @@
const DexFile::AnnotationSetItem* FindAnnotationSetForMethod(ArtMethod* method)
REQUIRES_SHARED(Locks::mutator_lock_) {
const DexFile* dex_file = method->GetDexFile();
+ mirror::Class* klass = method->GetDeclaringClass();
const DexFile::AnnotationsDirectoryItem* annotations_dir =
- dex_file->GetAnnotationsDirectory(method->GetClassDef());
+ dex_file->GetAnnotationsDirectory(*klass->GetClassDef());
if (annotations_dir == nullptr) {
return nullptr;
}
@@ -281,8 +209,9 @@
const DexFile::ParameterAnnotationsItem* FindAnnotationsItemForMethod(ArtMethod* method)
REQUIRES_SHARED(Locks::mutator_lock_) {
const DexFile* dex_file = method->GetDexFile();
+ mirror::Class* klass = method->GetDeclaringClass();
const DexFile::AnnotationsDirectoryItem* annotations_dir =
- dex_file->GetAnnotationsDirectory(method->GetClassDef());
+ dex_file->GetAnnotationsDirectory(*klass->GetClassDef());
if (annotations_dir == nullptr) {
return nullptr;
}
@@ -301,34 +230,30 @@
return nullptr;
}
-const DexFile::AnnotationSetItem* FindAnnotationSetForClass(const ClassData& klass)
+const DexFile::AnnotationSetItem* FindAnnotationSetForClass(Handle<mirror::Class> klass)
REQUIRES_SHARED(Locks::mutator_lock_) {
- const DexFile& dex_file = klass.GetDexFile();
+ const DexFile& dex_file = klass->GetDexFile();
const DexFile::AnnotationsDirectoryItem* annotations_dir =
- dex_file.GetAnnotationsDirectory(*klass.GetClassDef());
+ dex_file.GetAnnotationsDirectory(*klass->GetClassDef());
if (annotations_dir == nullptr) {
return nullptr;
}
return dex_file.GetClassAnnotationSet(annotations_dir);
}
-mirror::Object* ProcessEncodedAnnotation(const ClassData& klass, const uint8_t** annotation)
+mirror::Object* ProcessEncodedAnnotation(Handle<mirror::Class> klass, const uint8_t** annotation)
REQUIRES_SHARED(Locks::mutator_lock_) {
uint32_t type_index = DecodeUnsignedLeb128(annotation);
uint32_t size = DecodeUnsignedLeb128(annotation);
Thread* self = Thread::Current();
ScopedObjectAccessUnchecked soa(self);
- StackHandleScope<4> hs(self);
+ StackHandleScope<2> hs(self);
ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
Handle<mirror::Class> annotation_class(hs.NewHandle(
- class_linker->ResolveType(klass.GetDexFile(),
- dex::TypeIndex(type_index),
- hs.NewHandle(klass.GetDexCache()),
- hs.NewHandle(klass.GetClassLoader()))));
+ class_linker->ResolveType(klass->GetDexFile(), dex::TypeIndex(type_index), klass.Get())));
if (annotation_class == nullptr) {
- LOG(INFO) << "Unable to resolve " << klass.GetRealClass()->PrettyClass()
- << " annotation class " << type_index;
+ LOG(INFO) << "Unable to resolve " << klass->PrettyClass() << " annotation class " << type_index;
DCHECK(Thread::Current()->IsExceptionPending());
Thread::Current()->ClearException();
return nullptr;
@@ -375,13 +300,13 @@
}
template <bool kTransactionActive>
-bool ProcessAnnotationValue(const ClassData& klass,
+bool ProcessAnnotationValue(Handle<mirror::Class> klass,
const uint8_t** annotation_ptr,
DexFile::AnnotationValue* annotation_value,
Handle<mirror::Class> array_class,
DexFile::AnnotationResultStyle result_style)
REQUIRES_SHARED(Locks::mutator_lock_) {
- const DexFile& dex_file = klass.GetDexFile();
+ const DexFile& dex_file = klass->GetDexFile();
Thread* self = Thread::Current();
ObjPtr<mirror::Object> element_object = nullptr;
bool set_object = false;
@@ -436,8 +361,9 @@
annotation_value->value_.SetI(index);
} else {
StackHandleScope<1> hs(self);
+ Handle<mirror::DexCache> dex_cache(hs.NewHandle(klass->GetDexCache()));
element_object = Runtime::Current()->GetClassLinker()->ResolveString(
- klass.GetDexFile(), dex::StringIndex(index), hs.NewHandle(klass.GetDexCache()));
+ klass->GetDexFile(), dex::StringIndex(index), dex_cache);
set_object = true;
if (element_object == nullptr) {
return false;
@@ -451,12 +377,8 @@
annotation_value->value_.SetI(index);
} else {
dex::TypeIndex type_index(index);
- StackHandleScope<2> hs(self);
element_object = Runtime::Current()->GetClassLinker()->ResolveType(
- klass.GetDexFile(),
- type_index,
- hs.NewHandle(klass.GetDexCache()),
- hs.NewHandle(klass.GetClassLoader()));
+ klass->GetDexFile(), type_index, klass.Get());
set_object = true;
if (element_object == nullptr) {
CHECK(self->IsExceptionPending());
@@ -477,13 +399,12 @@
if (result_style == DexFile::kAllRaw) {
annotation_value->value_.SetI(index);
} else {
- ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
StackHandleScope<2> hs(self);
+ Handle<mirror::DexCache> dex_cache(hs.NewHandle(klass->GetDexCache()));
+ Handle<mirror::ClassLoader> class_loader(hs.NewHandle(klass->GetClassLoader()));
+ ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
ArtMethod* method = class_linker->ResolveMethodWithoutInvokeType(
- klass.GetDexFile(),
- index,
- hs.NewHandle(klass.GetDexCache()),
- hs.NewHandle(klass.GetClassLoader()));
+ klass->GetDexFile(), index, dex_cache, class_loader);
if (method == nullptr) {
return false;
}
@@ -518,11 +439,10 @@
annotation_value->value_.SetI(index);
} else {
StackHandleScope<2> hs(self);
+ Handle<mirror::DexCache> dex_cache(hs.NewHandle(klass->GetDexCache()));
+ Handle<mirror::ClassLoader> class_loader(hs.NewHandle(klass->GetClassLoader()));
ArtField* field = Runtime::Current()->GetClassLinker()->ResolveFieldJLS(
- klass.GetDexFile(),
- index,
- hs.NewHandle(klass.GetDexCache()),
- hs.NewHandle(klass.GetClassLoader()));
+ klass->GetDexFile(), index, dex_cache, class_loader);
if (field == nullptr) {
return false;
}
@@ -547,12 +467,10 @@
annotation_value->value_.SetI(index);
} else {
StackHandleScope<3> hs(self);
+ Handle<mirror::DexCache> dex_cache(hs.NewHandle(klass->GetDexCache()));
+ Handle<mirror::ClassLoader> class_loader(hs.NewHandle(klass->GetClassLoader()));
ArtField* enum_field = Runtime::Current()->GetClassLinker()->ResolveField(
- klass.GetDexFile(),
- index,
- hs.NewHandle(klass.GetDexCache()),
- hs.NewHandle(klass.GetClassLoader()),
- true);
+ klass->GetDexFile(), index, dex_cache, class_loader, true);
if (enum_field == nullptr) {
return false;
} else {
@@ -677,10 +595,10 @@
return true;
}
-mirror::Object* CreateAnnotationMember(const ClassData& klass,
+mirror::Object* CreateAnnotationMember(Handle<mirror::Class> klass,
Handle<mirror::Class> annotation_class,
const uint8_t** annotation) {
- const DexFile& dex_file = klass.GetDexFile();
+ const DexFile& dex_file = klass->GetDexFile();
Thread* self = Thread::Current();
ScopedObjectAccessUnchecked soa(self);
StackHandleScope<5> hs(self);
@@ -748,12 +666,12 @@
}
const DexFile::AnnotationItem* GetAnnotationItemFromAnnotationSet(
- const ClassData& klass,
+ Handle<mirror::Class> klass,
const DexFile::AnnotationSetItem* annotation_set,
uint32_t visibility,
Handle<mirror::Class> annotation_class)
REQUIRES_SHARED(Locks::mutator_lock_) {
- const DexFile& dex_file = klass.GetDexFile();
+ const DexFile& dex_file = klass->GetDexFile();
for (uint32_t i = 0; i < annotation_set->size_; ++i) {
const DexFile::AnnotationItem* annotation_item = dex_file.GetAnnotationItem(annotation_set, i);
if (!IsVisibilityCompatible(annotation_item->visibility_, visibility)) {
@@ -761,16 +679,12 @@
}
const uint8_t* annotation = annotation_item->annotation_;
uint32_t type_index = DecodeUnsignedLeb128(&annotation);
- StackHandleScope<2> hs(Thread::Current());
mirror::Class* resolved_class = Runtime::Current()->GetClassLinker()->ResolveType(
- klass.GetDexFile(),
- dex::TypeIndex(type_index),
- hs.NewHandle(klass.GetDexCache()),
- hs.NewHandle(klass.GetClassLoader()));
+ klass->GetDexFile(), dex::TypeIndex(type_index), klass.Get());
if (resolved_class == nullptr) {
std::string temp;
LOG(WARNING) << StringPrintf("Unable to resolve %s annotation class %d",
- klass.GetRealClass()->GetDescriptor(&temp), type_index);
+ klass->GetDescriptor(&temp), type_index);
CHECK(Thread::Current()->IsExceptionPending());
Thread::Current()->ClearException();
continue;
@@ -784,7 +698,7 @@
}
mirror::Object* GetAnnotationObjectFromAnnotationSet(
- const ClassData& klass,
+ Handle<mirror::Class> klass,
const DexFile::AnnotationSetItem* annotation_set,
uint32_t visibility,
Handle<mirror::Class> annotation_class)
@@ -798,13 +712,13 @@
return ProcessEncodedAnnotation(klass, &annotation);
}
-mirror::Object* GetAnnotationValue(const ClassData& klass,
+mirror::Object* GetAnnotationValue(Handle<mirror::Class> klass,
const DexFile::AnnotationItem* annotation_item,
const char* annotation_name,
Handle<mirror::Class> array_class,
uint32_t expected_type)
REQUIRES_SHARED(Locks::mutator_lock_) {
- const DexFile& dex_file = klass.GetDexFile();
+ const DexFile& dex_file = klass->GetDexFile();
const uint8_t* annotation =
SearchEncodedAnnotation(dex_file, annotation_item->annotation_, annotation_name);
if (annotation == nullptr) {
@@ -831,10 +745,10 @@
return annotation_value.value_.GetL();
}
-mirror::ObjectArray<mirror::String>* GetSignatureValue(const ClassData& klass,
+mirror::ObjectArray<mirror::String>* GetSignatureValue(Handle<mirror::Class> klass,
const DexFile::AnnotationSetItem* annotation_set)
REQUIRES_SHARED(Locks::mutator_lock_) {
- const DexFile& dex_file = klass.GetDexFile();
+ const DexFile& dex_file = klass->GetDexFile();
StackHandleScope<1> hs(Thread::Current());
const DexFile::AnnotationItem* annotation_item =
SearchAnnotationSet(dex_file, annotation_set, "Ldalvik/annotation/Signature;",
@@ -857,10 +771,10 @@
return obj->AsObjectArray<mirror::String>();
}
-mirror::ObjectArray<mirror::Class>* GetThrowsValue(const ClassData& klass,
+mirror::ObjectArray<mirror::Class>* GetThrowsValue(Handle<mirror::Class> klass,
const DexFile::AnnotationSetItem* annotation_set)
REQUIRES_SHARED(Locks::mutator_lock_) {
- const DexFile& dex_file = klass.GetDexFile();
+ const DexFile& dex_file = klass->GetDexFile();
StackHandleScope<1> hs(Thread::Current());
const DexFile::AnnotationItem* annotation_item =
SearchAnnotationSet(dex_file, annotation_set, "Ldalvik/annotation/Throws;",
@@ -884,11 +798,11 @@
}
mirror::ObjectArray<mirror::Object>* ProcessAnnotationSet(
- const ClassData& klass,
+ Handle<mirror::Class> klass,
const DexFile::AnnotationSetItem* annotation_set,
uint32_t visibility)
REQUIRES_SHARED(Locks::mutator_lock_) {
- const DexFile& dex_file = klass.GetDexFile();
+ const DexFile& dex_file = klass->GetDexFile();
Thread* self = Thread::Current();
ScopedObjectAccessUnchecked soa(self);
StackHandleScope<2> hs(self);
@@ -942,11 +856,11 @@
}
mirror::ObjectArray<mirror::Object>* ProcessAnnotationSetRefList(
- const ClassData& klass,
+ Handle<mirror::Class> klass,
const DexFile::AnnotationSetRefList* set_ref_list,
uint32_t size)
REQUIRES_SHARED(Locks::mutator_lock_) {
- const DexFile& dex_file = klass.GetDexFile();
+ const DexFile& dex_file = klass->GetDexFile();
Thread* self = Thread::Current();
ScopedObjectAccessUnchecked soa(self);
StackHandleScope<1> hs(self);
@@ -985,17 +899,15 @@
return nullptr;
}
StackHandleScope<1> hs(Thread::Current());
- const ClassData field_class(hs, field);
- return GetAnnotationObjectFromAnnotationSet(field_class,
- annotation_set,
- DexFile::kDexVisibilityRuntime,
- annotation_class);
+ Handle<mirror::Class> field_class(hs.NewHandle(field->GetDeclaringClass()));
+ return GetAnnotationObjectFromAnnotationSet(field_class, annotation_set,
+ DexFile::kDexVisibilityRuntime, annotation_class);
}
mirror::ObjectArray<mirror::Object>* GetAnnotationsForField(ArtField* field) {
const DexFile::AnnotationSetItem* annotation_set = FindAnnotationSetForField(field);
StackHandleScope<1> hs(Thread::Current());
- const ClassData field_class(hs, field);
+ Handle<mirror::Class> field_class(hs.NewHandle(field->GetDeclaringClass()));
return ProcessAnnotationSet(field_class, annotation_set, DexFile::kDexVisibilityRuntime);
}
@@ -1005,7 +917,7 @@
return nullptr;
}
StackHandleScope<1> hs(Thread::Current());
- const ClassData field_class(hs, field);
+ Handle<mirror::Class> field_class(hs.NewHandle(field->GetDeclaringClass()));
return GetSignatureValue(field_class, annotation_set);
}
@@ -1015,17 +927,17 @@
return false;
}
StackHandleScope<1> hs(Thread::Current());
- const ClassData field_class(hs, field);
+ Handle<mirror::Class> field_class(hs.NewHandle(field->GetDeclaringClass()));
const DexFile::AnnotationItem* annotation_item = GetAnnotationItemFromAnnotationSet(
field_class, annotation_set, DexFile::kDexVisibilityRuntime, annotation_class);
return annotation_item != nullptr;
}
mirror::Object* GetAnnotationDefaultValue(ArtMethod* method) {
- const ClassData klass(method);
- const DexFile* dex_file = &klass.GetDexFile();
+ const DexFile* dex_file = method->GetDexFile();
+ mirror::Class* klass = method->GetDeclaringClass();
const DexFile::AnnotationsDirectoryItem* annotations_dir =
- dex_file->GetAnnotationsDirectory(*klass.GetClassDef());
+ dex_file->GetAnnotationsDirectory(*klass->GetClassDef());
if (annotations_dir == nullptr) {
return nullptr;
}
@@ -1053,9 +965,10 @@
return nullptr;
}
DexFile::AnnotationValue annotation_value;
- StackHandleScope<1> hs(Thread::Current());
+ 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<false>(klass,
+ if (!ProcessAnnotationValue<false>(h_klass,
&annotation,
&annotation_value,
return_type,
@@ -1070,15 +983,17 @@
if (annotation_set == nullptr) {
return nullptr;
}
- return GetAnnotationObjectFromAnnotationSet(ClassData(method), annotation_set,
+ StackHandleScope<1> hs(Thread::Current());
+ Handle<mirror::Class> method_class(hs.NewHandle(method->GetDeclaringClass()));
+ return GetAnnotationObjectFromAnnotationSet(method_class, annotation_set,
DexFile::kDexVisibilityRuntime, annotation_class);
}
mirror::ObjectArray<mirror::Object>* GetAnnotationsForMethod(ArtMethod* method) {
const DexFile::AnnotationSetItem* annotation_set = FindAnnotationSetForMethod(method);
- return ProcessAnnotationSet(ClassData(method),
- annotation_set,
- DexFile::kDexVisibilityRuntime);
+ StackHandleScope<1> hs(Thread::Current());
+ Handle<mirror::Class> method_class(hs.NewHandle(method->GetDeclaringClass()));
+ return ProcessAnnotationSet(method_class, annotation_set, DexFile::kDexVisibilityRuntime);
}
mirror::ObjectArray<mirror::Class>* GetExceptionTypesForMethod(ArtMethod* method) {
@@ -1086,7 +1001,9 @@
if (annotation_set == nullptr) {
return nullptr;
}
- return GetThrowsValue(ClassData(method), annotation_set);
+ StackHandleScope<1> hs(Thread::Current());
+ Handle<mirror::Class> method_class(hs.NewHandle(method->GetDeclaringClass()));
+ return GetThrowsValue(method_class, annotation_set);
}
mirror::ObjectArray<mirror::Object>* GetParameterAnnotations(ArtMethod* method) {
@@ -1102,7 +1019,9 @@
return nullptr;
}
uint32_t size = set_ref_list->size_;
- return ProcessAnnotationSetRefList(ClassData(method), set_ref_list, size);
+ StackHandleScope<1> hs(Thread::Current());
+ Handle<mirror::Class> method_class(hs.NewHandle(method->GetDeclaringClass()));
+ return ProcessAnnotationSetRefList(method_class, set_ref_list, size);
}
mirror::Object* GetAnnotationForMethodParameter(ArtMethod* method,
@@ -1126,7 +1045,9 @@
const DexFile::AnnotationSetItem* annotation_set =
dex_file->GetSetRefItemItem(annotation_set_ref);
- return GetAnnotationObjectFromAnnotationSet(ClassData(method),
+ StackHandleScope<1> hs(Thread::Current());
+ Handle<mirror::Class> method_class(hs.NewHandle(method->GetDeclaringClass()));
+ return GetAnnotationObjectFromAnnotationSet(method_class,
annotation_set,
DexFile::kDexVisibilityRuntime,
annotation_class);
@@ -1151,7 +1072,7 @@
return false;
}
- StackHandleScope<4> hs(Thread::Current());
+ StackHandleScope<5> hs(Thread::Current());
// Extract the parameters' names String[].
ObjPtr<mirror::Class> string_class = mirror::String::GetJavaLangString();
@@ -1161,9 +1082,9 @@
return false;
}
- ClassData data(method);
+ Handle<mirror::Class> klass = hs.NewHandle(method->GetDeclaringClass());
Handle<mirror::Object> names_obj =
- hs.NewHandle(GetAnnotationValue(data,
+ hs.NewHandle(GetAnnotationValue(klass,
annotation_item,
"names",
string_array_class,
@@ -1178,7 +1099,7 @@
return false;
}
Handle<mirror::Object> access_flags_obj =
- hs.NewHandle(GetAnnotationValue(data,
+ hs.NewHandle(GetAnnotationValue(klass,
annotation_item,
"accessFlags",
int_array_class,
@@ -1197,7 +1118,9 @@
if (annotation_set == nullptr) {
return nullptr;
}
- return GetSignatureValue(ClassData(method), annotation_set);
+ StackHandleScope<1> hs(Thread::Current());
+ Handle<mirror::Class> method_class(hs.NewHandle(method->GetDeclaringClass()));
+ return GetSignatureValue(method_class, annotation_set);
}
bool IsMethodAnnotationPresent(ArtMethod* method, Handle<mirror::Class> annotation_class,
@@ -1206,39 +1129,37 @@
if (annotation_set == nullptr) {
return false;
}
+ StackHandleScope<1> hs(Thread::Current());
+ Handle<mirror::Class> method_class(hs.NewHandle(method->GetDeclaringClass()));
const DexFile::AnnotationItem* annotation_item =
- GetAnnotationItemFromAnnotationSet(ClassData(method),
- annotation_set, visibility, annotation_class);
+ GetAnnotationItemFromAnnotationSet(method_class, annotation_set, visibility,
+ annotation_class);
return annotation_item != nullptr;
}
mirror::Object* GetAnnotationForClass(Handle<mirror::Class> klass,
Handle<mirror::Class> annotation_class) {
- ClassData data(klass);
- const DexFile::AnnotationSetItem* annotation_set = FindAnnotationSetForClass(data);
+ const DexFile::AnnotationSetItem* annotation_set = FindAnnotationSetForClass(klass);
if (annotation_set == nullptr) {
return nullptr;
}
- return GetAnnotationObjectFromAnnotationSet(data,
- annotation_set,
- DexFile::kDexVisibilityRuntime,
+ return GetAnnotationObjectFromAnnotationSet(klass, annotation_set, DexFile::kDexVisibilityRuntime,
annotation_class);
}
mirror::ObjectArray<mirror::Object>* GetAnnotationsForClass(Handle<mirror::Class> klass) {
- ClassData data(klass);
- const DexFile::AnnotationSetItem* annotation_set = FindAnnotationSetForClass(data);
- return ProcessAnnotationSet(data, annotation_set, DexFile::kDexVisibilityRuntime);
+ const DexFile::AnnotationSetItem* annotation_set = FindAnnotationSetForClass(klass);
+ return ProcessAnnotationSet(klass, annotation_set, DexFile::kDexVisibilityRuntime);
}
mirror::ObjectArray<mirror::Class>* GetDeclaredClasses(Handle<mirror::Class> klass) {
- ClassData data(klass);
- const DexFile::AnnotationSetItem* annotation_set = FindAnnotationSetForClass(data);
+ const DexFile& dex_file = klass->GetDexFile();
+ const DexFile::AnnotationSetItem* annotation_set = FindAnnotationSetForClass(klass);
if (annotation_set == nullptr) {
return nullptr;
}
const DexFile::AnnotationItem* annotation_item =
- SearchAnnotationSet(data.GetDexFile(), annotation_set, "Ldalvik/annotation/MemberClasses;",
+ SearchAnnotationSet(dex_file, annotation_set, "Ldalvik/annotation/MemberClasses;",
DexFile::kDexVisibilitySystem);
if (annotation_item == nullptr) {
return nullptr;
@@ -1251,7 +1172,7 @@
return nullptr;
}
mirror::Object* obj =
- GetAnnotationValue(data, annotation_item, "value", class_array_class,
+ GetAnnotationValue(klass, annotation_item, "value", class_array_class,
DexFile::kDexAnnotationArray);
if (obj == nullptr) {
return nullptr;
@@ -1260,18 +1181,18 @@
}
mirror::Class* GetDeclaringClass(Handle<mirror::Class> klass) {
- ClassData data(klass);
- const DexFile::AnnotationSetItem* annotation_set = FindAnnotationSetForClass(data);
+ const DexFile& dex_file = klass->GetDexFile();
+ const DexFile::AnnotationSetItem* annotation_set = FindAnnotationSetForClass(klass);
if (annotation_set == nullptr) {
return nullptr;
}
const DexFile::AnnotationItem* annotation_item =
- SearchAnnotationSet(data.GetDexFile(), annotation_set, "Ldalvik/annotation/EnclosingClass;",
+ SearchAnnotationSet(dex_file, annotation_set, "Ldalvik/annotation/EnclosingClass;",
DexFile::kDexVisibilitySystem);
if (annotation_item == nullptr) {
return nullptr;
}
- mirror::Object* obj = GetAnnotationValue(data, annotation_item, "value",
+ mirror::Object* obj = GetAnnotationValue(klass, annotation_item, "value",
ScopedNullHandle<mirror::Class>(),
DexFile::kDexAnnotationType);
if (obj == nullptr) {
@@ -1281,30 +1202,28 @@
}
mirror::Class* GetEnclosingClass(Handle<mirror::Class> klass) {
+ const DexFile& dex_file = klass->GetDexFile();
mirror::Class* declaring_class = GetDeclaringClass(klass);
if (declaring_class != nullptr) {
return declaring_class;
}
- ClassData data(klass);
- const DexFile::AnnotationSetItem* annotation_set = FindAnnotationSetForClass(data);
+ const DexFile::AnnotationSetItem* annotation_set = FindAnnotationSetForClass(klass);
if (annotation_set == nullptr) {
return nullptr;
}
const DexFile::AnnotationItem* annotation_item =
- SearchAnnotationSet(data.GetDexFile(),
- annotation_set,
- "Ldalvik/annotation/EnclosingMethod;",
+ SearchAnnotationSet(dex_file, annotation_set, "Ldalvik/annotation/EnclosingMethod;",
DexFile::kDexVisibilitySystem);
if (annotation_item == nullptr) {
return nullptr;
}
const uint8_t* annotation =
- SearchEncodedAnnotation(data.GetDexFile(), annotation_item->annotation_, "value");
+ SearchEncodedAnnotation(dex_file, annotation_item->annotation_, "value");
if (annotation == nullptr) {
return nullptr;
}
DexFile::AnnotationValue annotation_value;
- if (!ProcessAnnotationValue<false>(data,
+ if (!ProcessAnnotationValue<false>(klass,
&annotation,
&annotation_value,
ScopedNullHandle<mirror::Class>(),
@@ -1315,11 +1234,10 @@
return nullptr;
}
StackHandleScope<2> hs(Thread::Current());
+ Handle<mirror::DexCache> dex_cache(hs.NewHandle(klass->GetDexCache()));
+ Handle<mirror::ClassLoader> class_loader(hs.NewHandle(klass->GetClassLoader()));
ArtMethod* method = Runtime::Current()->GetClassLinker()->ResolveMethodWithoutInvokeType(
- data.GetDexFile(),
- annotation_value.value_.GetI(),
- hs.NewHandle(data.GetDexCache()),
- hs.NewHandle(data.GetClassLoader()));
+ klass->GetDexFile(), annotation_value.value_.GetI(), dex_cache, class_loader);
if (method == nullptr) {
return nullptr;
}
@@ -1327,44 +1245,39 @@
}
mirror::Object* GetEnclosingMethod(Handle<mirror::Class> klass) {
- ClassData data(klass);
- const DexFile::AnnotationSetItem* annotation_set = FindAnnotationSetForClass(data);
+ const DexFile& dex_file = klass->GetDexFile();
+ const DexFile::AnnotationSetItem* annotation_set = FindAnnotationSetForClass(klass);
if (annotation_set == nullptr) {
return nullptr;
}
const DexFile::AnnotationItem* annotation_item =
- SearchAnnotationSet(data.GetDexFile(),
- annotation_set,
- "Ldalvik/annotation/EnclosingMethod;",
+ SearchAnnotationSet(dex_file, annotation_set, "Ldalvik/annotation/EnclosingMethod;",
DexFile::kDexVisibilitySystem);
if (annotation_item == nullptr) {
return nullptr;
}
- return GetAnnotationValue(data, annotation_item, "value", ScopedNullHandle<mirror::Class>(),
+ return GetAnnotationValue(klass, annotation_item, "value", ScopedNullHandle<mirror::Class>(),
DexFile::kDexAnnotationMethod);
}
bool GetInnerClass(Handle<mirror::Class> klass, mirror::String** name) {
- ClassData data(klass);
- const DexFile::AnnotationSetItem* annotation_set = FindAnnotationSetForClass(data);
+ const DexFile& dex_file = klass->GetDexFile();
+ const DexFile::AnnotationSetItem* annotation_set = FindAnnotationSetForClass(klass);
if (annotation_set == nullptr) {
return false;
}
const DexFile::AnnotationItem* annotation_item = SearchAnnotationSet(
- data.GetDexFile(),
- annotation_set,
- "Ldalvik/annotation/InnerClass;",
- DexFile::kDexVisibilitySystem);
+ dex_file, annotation_set, "Ldalvik/annotation/InnerClass;", DexFile::kDexVisibilitySystem);
if (annotation_item == nullptr) {
return false;
}
const uint8_t* annotation =
- SearchEncodedAnnotation(data.GetDexFile(), annotation_item->annotation_, "name");
+ SearchEncodedAnnotation(dex_file, annotation_item->annotation_, "name");
if (annotation == nullptr) {
return false;
}
DexFile::AnnotationValue annotation_value;
- if (!ProcessAnnotationValue<false>(data,
+ if (!ProcessAnnotationValue<false>(klass,
&annotation,
&annotation_value,
ScopedNullHandle<mirror::Class>(),
@@ -1380,24 +1293,24 @@
}
bool GetInnerClassFlags(Handle<mirror::Class> klass, uint32_t* flags) {
- ClassData data(klass);
- const DexFile::AnnotationSetItem* annotation_set = FindAnnotationSetForClass(data);
+ const DexFile& dex_file = klass->GetDexFile();
+ const DexFile::AnnotationSetItem* annotation_set = FindAnnotationSetForClass(klass);
if (annotation_set == nullptr) {
return false;
}
const DexFile::AnnotationItem* annotation_item =
- SearchAnnotationSet(data.GetDexFile(), annotation_set, "Ldalvik/annotation/InnerClass;",
+ SearchAnnotationSet(dex_file, annotation_set, "Ldalvik/annotation/InnerClass;",
DexFile::kDexVisibilitySystem);
if (annotation_item == nullptr) {
return false;
}
const uint8_t* annotation =
- SearchEncodedAnnotation(data.GetDexFile(), annotation_item->annotation_, "accessFlags");
+ SearchEncodedAnnotation(dex_file, annotation_item->annotation_, "accessFlags");
if (annotation == nullptr) {
return false;
}
DexFile::AnnotationValue annotation_value;
- if (!ProcessAnnotationValue<false>(data,
+ if (!ProcessAnnotationValue<false>(klass,
&annotation,
&annotation_value,
ScopedNullHandle<mirror::Class>(),
@@ -1412,22 +1325,20 @@
}
mirror::ObjectArray<mirror::String>* GetSignatureAnnotationForClass(Handle<mirror::Class> klass) {
- ClassData data(klass);
- const DexFile::AnnotationSetItem* annotation_set = FindAnnotationSetForClass(data);
+ const DexFile::AnnotationSetItem* annotation_set = FindAnnotationSetForClass(klass);
if (annotation_set == nullptr) {
return nullptr;
}
- return GetSignatureValue(data, annotation_set);
+ return GetSignatureValue(klass, annotation_set);
}
bool IsClassAnnotationPresent(Handle<mirror::Class> klass, Handle<mirror::Class> annotation_class) {
- ClassData data(klass);
- const DexFile::AnnotationSetItem* annotation_set = FindAnnotationSetForClass(data);
+ const DexFile::AnnotationSetItem* annotation_set = FindAnnotationSetForClass(klass);
if (annotation_set == nullptr) {
return false;
}
const DexFile::AnnotationItem* annotation_item = GetAnnotationItemFromAnnotationSet(
- data, annotation_set, DexFile::kDexVisibilityRuntime, annotation_class);
+ klass, annotation_set, DexFile::kDexVisibilityRuntime, annotation_class);
return annotation_item != nullptr;
}
diff --git a/test/980-redefine-object/expected.txt b/test/980-redefine-object/expected.txt
deleted file mode 100644
index 8675329..0000000
--- a/test/980-redefine-object/expected.txt
+++ /dev/null
@@ -1,55 +0,0 @@
- Initializing and loading the TestWatcher class that will (eventually) be notified of object allocations
- Allocating an j.l.Object before redefining Object class
- Allocating a Transform before redefining Object class
- Redefining the Object class to add a hook into the <init> method
-Object allocated of type 'Ljava/lang/StringBuilder;'
-Object allocated of type 'Ljava/nio/HeapCharBuffer;'
- Allocating an j.l.Object after redefining Object class
-Object allocated of type 'Ljava/lang/Object;'
-Object allocated of type 'Ljava/lang/StringBuilder;'
-Object allocated of type 'Ljava/nio/HeapCharBuffer;'
- Allocating a Transform after redefining Object class
-Object allocated of type 'LTransform;'
-Object allocated of type 'Ljava/lang/StringBuilder;'
-Object allocated of type 'Ljava/nio/HeapCharBuffer;'
- Allocating an int[] after redefining Object class
-Object allocated of type 'Ljava/lang/StringBuilder;'
-Object allocated of type 'Ljava/nio/HeapCharBuffer;'
- Allocating an array list
-Object allocated of type 'Ljava/util/ArrayList;'
-Object allocated of type 'Ljava/lang/StringBuilder;'
-Object allocated of type 'Ljava/nio/HeapCharBuffer;'
- Adding a bunch of stuff to the array list
-Object allocated of type 'Ljava/lang/Object;'
-Object allocated of type 'Ljava/lang/Object;'
-Object allocated of type 'LTransform;'
-Object allocated of type 'Ljava/lang/StringBuilder;'
-Object allocated of type 'Ljava/nio/HeapCharBuffer;'
- Allocating a linked list
-Object allocated of type 'Ljava/util/LinkedList;'
-Object allocated of type 'Ljava/lang/StringBuilder;'
-Object allocated of type 'Ljava/nio/HeapCharBuffer;'
- Adding a bunch of stuff to the linked list
-Object allocated of type 'Ljava/lang/Object;'
-Object allocated of type 'Ljava/util/LinkedList$Node;'
-Object allocated of type 'Ljava/lang/Object;'
-Object allocated of type 'Ljava/util/LinkedList$Node;'
-Object allocated of type 'Ljava/util/LinkedList$Node;'
-Object allocated of type 'Ljava/util/LinkedList$Node;'
-Object allocated of type 'Ljava/util/LinkedList$Node;'
-Object allocated of type 'Ljava/util/LinkedList$Node;'
-Object allocated of type 'LTransform;'
-Object allocated of type 'Ljava/util/LinkedList$Node;'
-Object allocated of type 'Ljava/lang/StringBuilder;'
-Object allocated of type 'Ljava/nio/HeapCharBuffer;'
- Throwing from down 4 stack frames
-Object allocated of type 'Ljava/lang/Exception;'
-Object allocated of type 'Ljava/lang/StringBuilder;'
-Object allocated of type 'Ljava/nio/HeapCharBuffer;'
- Exception caught.
-Object allocated of type 'Ljava/lang/StringBuilder;'
-Object allocated of type 'Ljava/nio/HeapCharBuffer;'
- Finishing test!
-Object allocated of type 'Ljava/lang/InterruptedException;'
-Object allocated of type 'Ljava/lang/InterruptedException;'
-Object allocated of type 'Ljava/lang/InterruptedException;'
diff --git a/test/980-redefine-object/info.txt b/test/980-redefine-object/info.txt
deleted file mode 100644
index f3e01b5..0000000
--- a/test/980-redefine-object/info.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-Tests basic functions in the jvmti plugin.
-
-This tests that we are able to redefine methods/constructors on the
-java.lang.Object class at runtime.
-
-This also (indirectly) tests that we correctly handle reading annotations on
-obsolete methods. This is something that is not normally done since there is no
-way to get a reference to an obsolete method outside of the runtime but some
-annotations on the Object class are read by the runtime directly.
-
-NB This test cannot be run on the RI at the moment.
-
-If this test starts failing during the doCommonClassRedefinition call it is
-possible that the definition of Object contained in the base64 DEX_BYTES array
-has become stale and will need to be recreated. The only difference from the
-normal Object dex bytes is that (a) it contains only the bytes of the Object
-class itself, and (b) it adds an
-'invoke-static {p0}, Ljava/lang/Object;->NotifyConstructed(Ljava/lang/Object;)V'
-to the <init> function.
-
-It is also possible it could fail due to the pattern of allocations caused by
-doing string concatenation or printing changing. In this case you should simply
-update the expected.txt file.
diff --git a/test/980-redefine-object/redefine_object.cc b/test/980-redefine-object/redefine_object.cc
deleted file mode 100644
index ff450dd..0000000
--- a/test/980-redefine-object/redefine_object.cc
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <inttypes.h>
-#include <iostream>
-
-#include "android-base/stringprintf.h"
-#include "base/logging.h"
-#include "base/macros.h"
-#include "jni.h"
-#include "openjdkjvmti/jvmti.h"
-#include "ScopedUtfChars.h"
-
-#include "ti-agent/common_helper.h"
-#include "ti-agent/common_load.h"
-
-namespace art {
-namespace Test980RedefineObjects {
-
-extern "C" JNIEXPORT void JNICALL Java_Main_bindFunctionsForClass(
- JNIEnv* env, jclass Main_klass ATTRIBUTE_UNUSED, jclass target) {
- BindFunctionsOnClass(jvmti_env, env, target);
-}
-
-extern "C" JNIEXPORT void JNICALL Java_art_test_TestWatcher_NotifyConstructed(
- JNIEnv* env, jclass TestWatcherClass ATTRIBUTE_UNUSED, jobject constructed) {
- char* sig = nullptr;
- char* generic_sig = nullptr;
- if (JvmtiErrorToException(env, jvmti_env->GetClassSignature(env->GetObjectClass(constructed),
- &sig,
- &generic_sig))) {
- // Exception.
- return;
- }
- std::cout << "Object allocated of type '" << sig << "'" << std::endl;
- jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(sig));
- jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(generic_sig));
-}
-
-} // namespace Test980RedefineObjects
-} // namespace art
diff --git a/test/980-redefine-object/run b/test/980-redefine-object/run
deleted file mode 100755
index c6e62ae..0000000
--- a/test/980-redefine-object/run
+++ /dev/null
@@ -1,17 +0,0 @@
-#!/bin/bash
-#
-# Copyright 2016 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-./default-run "$@" --jvmti
diff --git a/test/980-redefine-object/src-ex/TestWatcher.java b/test/980-redefine-object/src-ex/TestWatcher.java
deleted file mode 100644
index d15e688..0000000
--- a/test/980-redefine-object/src-ex/TestWatcher.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package art.test;
-
-public class TestWatcher {
- // NB This function is native since it is called in the Object.<init> method and so cannot cause
- // any java allocations at all. The normal System.out.print* functions will cause allocations to
- // occur so we cannot use them. This means the easiest way to report the object as being created
- // is to go into native code and do it there.
- public static native void NotifyConstructed(Object o);
-}
diff --git a/test/980-redefine-object/src/Main.java b/test/980-redefine-object/src/Main.java
deleted file mode 100644
index 348951c..0000000
--- a/test/980-redefine-object/src/Main.java
+++ /dev/null
@@ -1,390 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-import java.util.ArrayList;
-import java.util.Base64;
-import java.util.LinkedList;
-
-public class Main {
-
- // TODO We should make this run on the RI.
- /**
- * This test cannot be run on the RI.
- */
- private static final byte[] CLASS_BYTES = new byte[0];
-
- // TODO It might be a good idea to replace this hard-coded Object definition with a
- // retransformation based test.
- /**
- * Base64 encoding of the following smali file.
- *
- * .class public Ljava/lang/Object;
- * .source "Object.java"
- * # instance fields
- * .field private transient shadow$_klass_:Ljava/lang/Class;
- * .annotation system Ldalvik/annotation/Signature;
- * value = {
- * "Ljava/lang/Class",
- * "<*>;"
- * }
- * .end annotation
- * .end field
- *
- * .field private transient shadow$_monitor_:I
- * # direct methods
- * .method public constructor <init>()V
- * .registers 1
- * .prologue
- * invoke-static {p0}, Lart/test/TestWatcher;->NotifyConstructed(Ljava/lang/Object;)V
- * return-void
- * .end method
- *
- * .method static identityHashCode(Ljava/lang/Object;)I
- * .registers 7
- * .prologue
- * iget v0, p0, Ljava/lang/Object;->shadow$_monitor_:I
- * const/high16 v3, -0x40000000 # -2.0f
- * const/high16 v2, -0x80000000
- * const v1, 0xfffffff
- * const/high16 v4, -0x40000000 # -2.0f
- * and-int/2addr v4, v0
- * const/high16 v5, -0x80000000
- * if-ne v4, v5, :cond_15
- * const v4, 0xfffffff
- * and-int/2addr v4, v0
- * return v4
- * :cond_15
- * invoke-static {p0}, Ljava/lang/Object;->identityHashCodeNative(Ljava/lang/Object;)I
- * move-result v4
- * return v4
- * .end method
- *
- * .method private static native identityHashCodeNative(Ljava/lang/Object;)I
- * .annotation build Ldalvik/annotation/optimization/FastNative;
- * .end annotation
- * .end method
- *
- * .method private native internalClone()Ljava/lang/Object;
- * .annotation build Ldalvik/annotation/optimization/FastNative;
- * .end annotation
- * .end method
- *
- *
- * # virtual methods
- * .method protected clone()Ljava/lang/Object;
- * .registers 4
- * .annotation system Ldalvik/annotation/Throws;
- * value = {
- * Ljava/lang/CloneNotSupportedException;
- * }
- * .end annotation
- *
- * .prologue
- * instance-of v0, p0, Ljava/lang/Cloneable;
- * if-nez v0, :cond_2d
- * new-instance v0, Ljava/lang/CloneNotSupportedException;
- * new-instance v1, Ljava/lang/StringBuilder;
- * invoke-direct {v1}, Ljava/lang/StringBuilder;-><init>()V
- * const-string/jumbo v2, "Class "
- * invoke-virtual {v1, v2}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
- * move-result-object v1
- * invoke-virtual {p0}, Ljava/lang/Object;->getClass()Ljava/lang/Class;
- * move-result-object v2
- * invoke-virtual {v2}, Ljava/lang/Class;->getName()Ljava/lang/String;
- * move-result-object v2
- * invoke-virtual {v1, v2}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
- * move-result-object v1
- * const-string/jumbo v2, " doesn\'t implement Cloneable"
- * invoke-virtual {v1, v2}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
- * move-result-object v1
- * invoke-virtual {v1}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;
- * move-result-object v1
- * invoke-direct {v0, v1}, Ljava/lang/CloneNotSupportedException;-><init>(Ljava/lang/String;)V
- * throw v0
- * :cond_2d
- * invoke-direct {p0}, Ljava/lang/Object;->internalClone()Ljava/lang/Object;
- * move-result-object v0
- * return-object v0
- * .end method
- *
- * .method public equals(Ljava/lang/Object;)Z
- * .registers 3
- * .prologue
- * if-ne p0, p1, :cond_4
- * const/4 v0, 0x1
- * :goto_3
- * return v0
- * :cond_4
- * const/4 v0, 0x0
- * goto :goto_3
- * .end method
- *
- * .method protected finalize()V
- * .registers 1
- * .annotation system Ldalvik/annotation/Throws;
- * value = {
- * Ljava/lang/Throwable;
- * }
- * .end annotation
- * .prologue
- * return-void
- * .end method
- *
- * .method public final getClass()Ljava/lang/Class;
- * .registers 2
- * .annotation system Ldalvik/annotation/Signature;
- * value = {
- * "()",
- * "Ljava/lang/Class",
- * "<*>;"
- * }
- * .end annotation
- * .prologue
- * iget-object v0, p0, Ljava/lang/Object;->shadow$_klass_:Ljava/lang/Class;
- * return-object v0
- * .end method
- *
- * .method public hashCode()I
- * .registers 2
- * .prologue
- * invoke-static {p0}, Ljava/lang/Object;->identityHashCode(Ljava/lang/Object;)I
- * move-result v0
- * return v0
- * .end method
- *
- * .method public final native notify()V
- * .annotation build Ldalvik/annotation/optimization/FastNative;
- * .end annotation
- * .end method
- *
- * .method public final native notifyAll()V
- * .annotation build Ldalvik/annotation/optimization/FastNative;
- * .end annotation
- * .end method
- *
- * .method public toString()Ljava/lang/String;
- * .registers 3
- * .prologue
- * new-instance v0, Ljava/lang/StringBuilder;
- * invoke-direct {v0}, Ljava/lang/StringBuilder;-><init>()V
- * invoke-virtual {p0}, Ljava/lang/Object;->getClass()Ljava/lang/Class;
- * move-result-object v1
- * invoke-virtual {v1}, Ljava/lang/Class;->getName()Ljava/lang/String;
- * move-result-object v1
- * invoke-virtual {v0, v1}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
- * move-result-object v0
- * const-string/jumbo v1, "@"
- * invoke-virtual {v0, v1}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
- * move-result-object v0
- * invoke-virtual {p0}, Ljava/lang/Object;->hashCode()I
- * move-result v1
- * invoke-static {v1}, Ljava/lang/Integer;->toHexString(I)Ljava/lang/String;
- * move-result-object v1
- * invoke-virtual {v0, v1}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
- * move-result-object v0
- * invoke-virtual {v0}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;
- * move-result-object v0
- * return-object v0
- * .end method
- *
- * .method public final native wait()V
- * .annotation system Ldalvik/annotation/Throws;
- * value = {
- * Ljava/lang/InterruptedException;
- * }
- * .end annotation
- *
- * .annotation build Ldalvik/annotation/optimization/FastNative;
- * .end annotation
- * .end method
- *
- * .method public final wait(J)V
- * .registers 4
- * .annotation system Ldalvik/annotation/Throws;
- * value = {
- * Ljava/lang/InterruptedException;
- * }
- * .end annotation
- * .prologue
- * const/4 v0, 0x0
- * invoke-virtual {p0, p1, p2, v0}, Ljava/lang/Object;->wait(JI)V
- * return-void
- * .end method
- *
- * .method public final native wait(JI)V
- * .annotation system Ldalvik/annotation/Throws;
- * value = {
- * Ljava/lang/InterruptedException;
- * }
- * .end annotation
- *
- * .annotation build Ldalvik/annotation/optimization/FastNative;
- * .end annotation
- * .end method
- */
- private static final byte[] DEX_BYTES = Base64.getDecoder().decode(
- "ZGV4CjAzNQDUlMR9j03MYuOKekKs2p7zJzu2IfDb7RlMCgAAcAAAAHhWNBIAAAAAAAAAAIgJAAA6" +
- "AAAAcAAAABEAAABYAQAADQAAAJwBAAACAAAAOAIAABYAAABIAgAAAQAAAPgCAAA0BwAAGAMAABgD" +
- "AAA2AwAAOgMAAEADAABIAwAASwMAAFMDAABWAwAAWgMAAF0DAABgAwAAZAMAAGgDAACAAwAAnwMA" +
- "ALsDAADoAwAA+gMAAA0EAAA1BAAATAQAAGEEAACDBAAAlwQAAKsEAADGBAAA3QQAAPAEAAD9BAAA" +
- "AAUAAAQFAAAJBQAADQUAABAFAAAUBQAAHAUAACMFAAArBQAANQUAAD8FAABIBQAAUgUAAGQFAAB8" +
- "BQAAiwUAAJUFAACnBQAAugUAAM0FAADVBQAA3QUAAOgFAADtBQAA/QUAAA8GAAAcBgAAJgYAAC0G" +
- "AAAGAAAACAAAAAwAAAANAAAADgAAAA8AAAARAAAAEgAAABMAAAAUAAAAFQAAABYAAAAXAAAAGAAA" +
- "ABkAAAAcAAAAIAAAAAYAAAAAAAAAAAAAAAcAAAAAAAAAPAYAAAkAAAAGAAAAAAAAAAkAAAALAAAA" +
- "AAAAAAkAAAAMAAAAAAAAAAoAAAAMAAAARAYAAAsAAAANAAAAVAYAABwAAAAPAAAAAAAAAB0AAAAP" +
- "AAAATAYAAB4AAAAPAAAANAYAAB8AAAAPAAAAPAYAAB8AAAAPAAAAVAYAACEAAAAQAAAAPAYAAAsA" +
- "BgA0AAAACwAAADUAAAACAAoAGgAAAAYABAAnAAAABwALAAMAAAAJAAUANgAAAAsABwADAAAACwAD" +
- "ACMAAAALAAwAJAAAAAsABwAlAAAACwACACYAAAALAAAAKAAAAAsAAQApAAAACwABACoAAAALAAMA" +
- "KwAAAAsABwAxAAAACwAHADIAAAALAAQANwAAAAsABwA5AAAACwAIADkAAAALAAkAOQAAAA0ABwAD" +
- "AAAADQAGACIAAAANAAQANwAAAAsAAAABAAAA/////wAAAAAbAAAA0AYAAD4JAAAAAAAAHCBkb2Vz" +
- "bid0IGltcGxlbWVudCBDbG9uZWFibGUAAigpAAQ8Kj47AAY8aW5pdD4AAUAABkNsYXNzIAABSQAC" +
- "SUwAAUoAAUwAAkxJAAJMTAAWTGFydC90ZXN0L1Rlc3RXYXRjaGVyOwAdTGRhbHZpay9hbm5vdGF0" +
- "aW9uL1NpZ25hdHVyZTsAGkxkYWx2aWsvYW5ub3RhdGlvbi9UaHJvd3M7ACtMZGFsdmlrL2Fubm90" +
- "YXRpb24vb3B0aW1pemF0aW9uL0Zhc3ROYXRpdmU7ABBMamF2YS9sYW5nL0NsYXNzABFMamF2YS9s" +
- "YW5nL0NsYXNzOwAmTGphdmEvbGFuZy9DbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbjsAFUxqYXZh" +
- "L2xhbmcvQ2xvbmVhYmxlOwATTGphdmEvbGFuZy9JbnRlZ2VyOwAgTGphdmEvbGFuZy9JbnRlcnJ1" +
- "cHRlZEV4Y2VwdGlvbjsAEkxqYXZhL2xhbmcvT2JqZWN0OwASTGphdmEvbGFuZy9TdHJpbmc7ABlM" +
- "amF2YS9sYW5nL1N0cmluZ0J1aWxkZXI7ABVMamF2YS9sYW5nL1Rocm93YWJsZTsAEU5vdGlmeUNv" +
- "bnN0cnVjdGVkAAtPYmplY3QuamF2YQABVgACVkoAA1ZKSQACVkwAAVoAAlpMAAZhcHBlbmQABWNs" +
- "b25lAAZlcXVhbHMACGZpbmFsaXplAAhnZXRDbGFzcwAHZ2V0TmFtZQAIaGFzaENvZGUAEGlkZW50" +
- "aXR5SGFzaENvZGUAFmlkZW50aXR5SGFzaENvZGVOYXRpdmUADWludGVybmFsQ2xvbmUACGxvY2tX" +
- "b3JkABBsb2NrV29yZEhhc2hNYXNrABFsb2NrV29yZFN0YXRlSGFzaAARbG9ja1dvcmRTdGF0ZU1h" +
- "c2sABm1pbGxpcwAGbm90aWZ5AAlub3RpZnlBbGwAA29iagAOc2hhZG93JF9rbGFzc18AEHNoYWRv" +
- "dyRfbW9uaXRvcl8AC3RvSGV4U3RyaW5nAAh0b1N0cmluZwAFdmFsdWUABHdhaXQAAAIAAAABAAAA" +
- "AQAAAAsAAAABAAAAAAAAAAEAAAABAAAAAQAAAAwAAgQBOBwBGAcCBAE4HAEYCgIDATgcAhcQFwIC" +
- "BAE4HAEYDgAFAAIDATgcAxcBFxAXAgAAAAAAAAAAAAEAAABaBgAAAgAAAGIGAAB8BgAAAQAAAGIG" +
- "AAABAAAAagYAAAEAAAB0BgAAAQAAAHwGAAABAAAAfwYAAAAAAAABAAAACgAAAAAAAAAAAAAAsAYA" +
- "AAUAAACUBgAABwAAALgGAAAIAAAAyAYAAAsAAADABgAADAAAAMAGAAANAAAAwAYAAA4AAADABgAA" +
- "EAAAAJwGAAARAAAAqAYAABIAAACcBgAAKAAHDgBwATQHDi0DAC0BLQMDMAEtAwIvATwDAS4BeFsA" +
- "7AEABw5LARoPOsYArAEBNAcOAMUEAAcOAEEABw4AaAAHDgCRAgAHDgCmAwExBw5LAAAAAQABAAEA" +
- "AAA4BwAABAAAAHEQAAAAAA4ABwABAAEAAAA9BwAAGgAAAFJgAQAVAwDAFQIAgBQB////DxUEAMC1" +
- "BBUFAIAzVAcAFAT///8PtQQPBHEQCwAGAAoEDwQEAAEAAgAAAFkHAAAyAAAAIDAIADkAKwAiAAcA" +
- "IgENAHAQEwABABsCBQAAAG4gFAAhAAwBbhAIAAMADAJuEAEAAgAMAm4gFAAhAAwBGwIAAAAAbiAU" +
- "ACEADAFuEBUAAQAMAXAgAgAQACcAcBAMAAMADAARAAMAAgAAAAAAZQcAAAYAAAAzIQQAEhAPABIA" +
- "KP4BAAEAAAAAAGwHAAABAAAADgAAAAIAAQAAAAAAcgcAAAMAAABUEAAAEQAAAAIAAQABAAAAdwcA" +
- "AAUAAABxEAoAAQAKAA8AAAADAAEAAgAAAHwHAAApAAAAIgANAHAQEwAAAG4QCAACAAwBbhABAAEA" +
- "DAFuIBQAEAAMABsBBAAAAG4gFAAQAAwAbhAJAAIACgFxEAMAAQAMAW4gFAAQAAwAbhAVAAAADAAR" +
- "AAAABAADAAQAAACCBwAABQAAABIAbkASACEDDgAAAgQLAIIBAYIBBIGABIwPBgikDwGKAgABggIA" +
- "BQToDwEB3BABBPgQARGMEQEBpBEEkQIAAZECAAEBwBEBkQIAARGkEgGRAgAAABAAAAAAAAAAAQAA" +
- "AAAAAAABAAAAOgAAAHAAAAACAAAAEQAAAFgBAAADAAAADQAAAJwBAAAEAAAAAgAAADgCAAAFAAAA" +
- "FgAAAEgCAAAGAAAAAQAAAPgCAAACIAAAOgAAABgDAAABEAAABQAAADQGAAAEIAAABgAAAFoGAAAD" +
- "EAAACQAAAIwGAAAGIAAAAQAAANAGAAADIAAACQAAADgHAAABIAAACQAAAIwHAAAAIAAAAQAAAD4J" +
- "AAAAEAAAAQAAAIgJAAA=");
-
- private static final String LISTENER_LOCATION =
- System.getenv("DEX_LOCATION") + "/980-redefine-object-ex.jar";
-
- public static void main(String[] args) {
- doTest();
- }
-
- private static void ensureTestWatcherInitialized() {
- try {
- // Make sure the TestWatcher class can be found from the Object <init> function.
- addToBootClassLoader(LISTENER_LOCATION);
- // Load TestWatcher from the bootclassloader and make sure it is initialized.
- Class<?> testwatcher_class = Class.forName("art.test.TestWatcher", true, null);
- // Bind the native functions of testwatcher_class.
- bindFunctionsForClass(testwatcher_class);
- } catch (Exception e) {
- throw new Error("Exception while making testwatcher", e);
- }
- }
-
- // NB This function will cause 2 objects of type "Ljava/nio/HeapCharBuffer;" and
- // "Ljava/nio/HeapCharBuffer;" to be allocated each time it is called.
- private static void safePrintln(Object o) {
- System.out.flush();
- System.out.print("\t" + o + "\n");
- System.out.flush();
- }
-
- private static void throwFrom(int depth) throws Exception {
- if (depth <= 0) {
- throw new Exception("Throwing the exception");
- } else {
- throwFrom(depth - 1);
- }
- }
-
- public static void doTest() {
- safePrintln("Initializing and loading the TestWatcher class that will (eventually) be " +
- "notified of object allocations");
- // Make sure the TestWatcher class is initialized before we do anything else.
- ensureTestWatcherInitialized();
- safePrintln("Allocating an j.l.Object before redefining Object class");
- // Make sure these aren't shown.
- Object o = new Object();
- safePrintln("Allocating a Transform before redefining Object class");
- Transform t = new Transform();
-
- // Redefine the Object Class.
- safePrintln("Redefining the Object class to add a hook into the <init> method");
- doCommonClassRedefinition(Object.class, CLASS_BYTES, DEX_BYTES);
-
- safePrintln("Allocating an j.l.Object after redefining Object class");
- Object o2 = new Object();
- safePrintln("Allocating a Transform after redefining Object class");
- Transform t2 = new Transform();
-
- // This shouldn't cause the Object constructor to be run.
- safePrintln("Allocating an int[] after redefining Object class");
- int[] abc = new int[12];
-
- // Try adding stuff to an array list.
- safePrintln("Allocating an array list");
- ArrayList<Object> al = new ArrayList<>();
- safePrintln("Adding a bunch of stuff to the array list");
- al.add(new Object());
- al.add(new Object());
- al.add(o2);
- al.add(o);
- al.add(t);
- al.add(t2);
- al.add(new Transform());
-
- // Try adding stuff to a LinkedList
- safePrintln("Allocating a linked list");
- LinkedList<Object> ll = new LinkedList<>();
- safePrintln("Adding a bunch of stuff to the linked list");
- ll.add(new Object());
- ll.add(new Object());
- ll.add(o2);
- ll.add(o);
- ll.add(t);
- ll.add(t2);
- ll.add(new Transform());
-
- // Try making an exception.
- safePrintln("Throwing from down 4 stack frames");
- try {
- throwFrom(4);
- } catch (Exception e) {
- safePrintln("Exception caught.");
- }
-
- safePrintln("Finishing test!");
- }
-
- private static native void addToBootClassLoader(String s);
-
- private static native void bindFunctionsForClass(Class<?> target);
-
- // Transforms the class
- private static native void doCommonClassRedefinition(Class<?> target,
- byte[] class_file,
- byte[] dex_file);
-}
diff --git a/test/980-redefine-object/src/Transform.java b/test/980-redefine-object/src/Transform.java
deleted file mode 100644
index 23f67d9..0000000
--- a/test/980-redefine-object/src/Transform.java
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-class Transform { }
diff --git a/test/Android.bp b/test/Android.bp
index 3bb3ef8..594cce2 100644
--- a/test/Android.bp
+++ b/test/Android.bp
@@ -275,7 +275,6 @@
"936-search-onload/search_onload.cc",
"944-transform-classloaders/classloader.cc",
"945-obsolete-native/obsolete_native.cc",
- "980-redefine-object/redefine_object.cc",
],
shared_libs: [
"libbase",
diff --git a/test/ti-agent/common_helper.cc b/test/ti-agent/common_helper.cc
index 6316a9c..4ddd0aa 100644
--- a/test/ti-agent/common_helper.cc
+++ b/test/ti-agent/common_helper.cc
@@ -520,14 +520,11 @@
LOG(FATAL) << "Could not load " << class_name;
}
}
- BindFunctionsOnClass(jenv, env, klass.get());
-}
-void BindFunctionsOnClass(jvmtiEnv* jenv, JNIEnv* env, jclass klass) {
// Use JVMTI to get the methods.
jint method_count;
jmethodID* methods;
- jvmtiError methods_result = jenv->GetClassMethods(klass, &method_count, &methods);
+ jvmtiError methods_result = jenv->GetClassMethods(klass.get(), &method_count, &methods);
if (methods_result != JVMTI_ERROR_NONE) {
LOG(FATAL) << "Could not get methods";
}
@@ -541,7 +538,7 @@
}
constexpr jint kNative = static_cast<jint>(kAccNative);
if ((modifiers & kNative) != 0) {
- BindMethod(jenv, env, klass, methods[i]);
+ BindMethod(jenv, env, klass.get(), methods[i]);
}
}
diff --git a/test/ti-agent/common_helper.h b/test/ti-agent/common_helper.h
index f10356d..0a316ed 100644
--- a/test/ti-agent/common_helper.h
+++ b/test/ti-agent/common_helper.h
@@ -81,7 +81,6 @@
//
// This will abort on failure.
void BindFunctions(jvmtiEnv* jvmti_env, JNIEnv* env, const char* class_name);
-void BindFunctionsOnClass(jvmtiEnv* jvmti_env, JNIEnv* env, jclass klass);
} // namespace art