Revert "Revert^2 "Walk internal ArtField/ArtMethod pointers""
This reverts commit ea2a3d949354c8b054983ba629c81bc5ff7163da.
Bug: 134162467
Reason for revert: Fails redefine stress
Change-Id: If487c0bcacaf3a3f565ff475b6dad8321e3428b9
diff --git a/openjdkjvmti/events.cc b/openjdkjvmti/events.cc
index 3f205eb..77acd56 100644
--- a/openjdkjvmti/events.cc
+++ b/openjdkjvmti/events.cc
@@ -64,8 +64,6 @@
#include "mirror/object-inl.h"
#include "monitor-inl.h"
#include "nativehelper/scoped_local_ref.h"
-#include "reflective_handle.h"
-#include "reflective_handle_scope-inl.h"
#include "runtime.h"
#include "scoped_thread_state_change-inl.h"
#include "scoped_thread_state_change.h"
@@ -802,14 +800,11 @@
// Call-back for when we read from a field.
void FieldRead(art::Thread* self,
art::Handle<art::mirror::Object> this_object,
- art::ArtMethod* method_p,
+ art::ArtMethod* method,
uint32_t dex_pc,
- art::ArtField* field_p)
+ art::ArtField* field)
REQUIRES_SHARED(art::Locks::mutator_lock_) override {
if (event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kFieldAccess)) {
- art::StackReflectiveHandleScope<1, 1> rhs(self);
- art::ReflectiveHandle<art::ArtField> field(rhs.NewHandle(field_p));
- art::ReflectiveHandle<art::ArtMethod> method(rhs.NewHandle(method_p));
art::JNIEnvExt* jnienv = self->GetJniEnv();
// DCHECK(!self->IsExceptionPending());
ScopedLocalRef<jobject> this_ref(jnienv, AddLocalRef<jobject>(jnienv, this_object.Get()));
@@ -829,16 +824,13 @@
void FieldWritten(art::Thread* self,
art::Handle<art::mirror::Object> this_object,
- art::ArtMethod* method_p,
+ art::ArtMethod* method,
uint32_t dex_pc,
- art::ArtField* field_p,
+ art::ArtField* field,
art::Handle<art::mirror::Object> new_val)
REQUIRES_SHARED(art::Locks::mutator_lock_) override {
if (event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kFieldModification)) {
art::JNIEnvExt* jnienv = self->GetJniEnv();
- art::StackReflectiveHandleScope<1, 1> rhs(self);
- art::ReflectiveHandle<art::ArtField> field(rhs.NewHandle(field_p));
- art::ReflectiveHandle<art::ArtMethod> method(rhs.NewHandle(method_p));
// DCHECK(!self->IsExceptionPending());
ScopedLocalRef<jobject> this_ref(jnienv, AddLocalRef<jobject>(jnienv, this_object.Get()));
ScopedLocalRef<jobject> fklass(jnienv,
@@ -864,16 +856,13 @@
// Call-back for when we write into a field.
void FieldWritten(art::Thread* self,
art::Handle<art::mirror::Object> this_object,
- art::ArtMethod* method_p,
+ art::ArtMethod* method,
uint32_t dex_pc,
- art::ArtField* field_p,
+ art::ArtField* field,
const art::JValue& field_value)
REQUIRES_SHARED(art::Locks::mutator_lock_) override {
if (event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kFieldModification)) {
art::JNIEnvExt* jnienv = self->GetJniEnv();
- art::StackReflectiveHandleScope<1, 1> rhs(self);
- art::ReflectiveHandle<art::ArtField> field(rhs.NewHandle(field_p));
- art::ReflectiveHandle<art::ArtMethod> method(rhs.NewHandle(method_p));
DCHECK(!self->IsExceptionPending());
ScopedLocalRef<jobject> this_ref(jnienv, AddLocalRef<jobject>(jnienv, this_object.Get()));
ScopedLocalRef<jobject> fklass(jnienv,
diff --git a/runtime/Android.bp b/runtime/Android.bp
index cfa16f8..81e1ecf 100644
--- a/runtime/Android.bp
+++ b/runtime/Android.bp
@@ -189,7 +189,6 @@
"read_barrier.cc",
"reference_table.cc",
"reflection.cc",
- "reflective_handle_scope.cc",
"reflective_value_visitor.cc",
"runtime.cc",
"runtime_callbacks.cc",
diff --git a/runtime/common_dex_operations.h b/runtime/common_dex_operations.h
index 882e3ce..2f86fbc 100644
--- a/runtime/common_dex_operations.h
+++ b/runtime/common_dex_operations.h
@@ -35,8 +35,6 @@
#include "mirror/class.h"
#include "mirror/object.h"
#include "obj_ptr-inl.h"
-#include "reflective_handle.h"
-#include "reflective_handle_scope.h"
#include "runtime.h"
#include "stack.h"
#include "thread.h"
@@ -102,10 +100,8 @@
instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
if (UNLIKELY(instrumentation->HasFieldReadListeners())) {
StackHandleScope<1> hs(self);
- StackArtFieldHandleScope<1> rhs(self);
// Wrap in handle wrapper in case the listener does thread suspension.
HandleWrapperObjPtr<mirror::Object> h(hs.NewHandleWrapper(&obj));
- ReflectiveHandleWrapper<ArtField> fh(rhs.NewReflectiveHandleWrapper(&field));
ObjPtr<mirror::Object> this_object;
if (!field->IsStatic()) {
this_object = obj;
@@ -163,10 +159,8 @@
instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
if (UNLIKELY(instrumentation->HasFieldWriteListeners())) {
StackHandleScope<2> hs(self);
- StackArtFieldHandleScope<1> rhs(self);
// Save this and return value (if needed) in case the instrumentation causes a suspend.
HandleWrapperObjPtr<mirror::Object> h(hs.NewHandleWrapper(&obj));
- ReflectiveHandleWrapper<ArtField> fh(rhs.NewReflectiveHandleWrapper(&field));
ObjPtr<mirror::Object> this_object = field->IsStatic() ? nullptr : obj;
mirror::Object* fake_root = nullptr;
HandleWrapper<mirror::Object> ret(hs.NewHandleWrapper<mirror::Object>(
@@ -216,10 +210,8 @@
ObjPtr<mirror::Class> field_class;
{
StackHandleScope<2> hs(self);
- StackArtFieldHandleScope<1> rhs(self);
HandleWrapperObjPtr<mirror::Object> h_reg(hs.NewHandleWrapper(®));
HandleWrapperObjPtr<mirror::Object> h_obj(hs.NewHandleWrapper(&obj));
- ReflectiveHandleWrapper<ArtField> fh(rhs.NewReflectiveHandleWrapper(&field));
field_class = field->ResolveType();
}
// ArtField::ResolveType() may fail as evidenced with a dexing bug (b/78788577).
diff --git a/runtime/debugger.cc b/runtime/debugger.cc
index b28868f..4cc3583 100644
--- a/runtime/debugger.cc
+++ b/runtime/debugger.cc
@@ -71,8 +71,6 @@
#include "oat_file.h"
#include "obj_ptr-inl.h"
#include "reflection.h"
-#include "reflective_handle.h"
-#include "reflective_handle_scope-inl.h"
#include "runtime-inl.h"
#include "scoped_thread_state_change-inl.h"
#include "stack.h"
@@ -4058,19 +4056,18 @@
soa.Self()->AssertNoPendingException();
// Translate the method through the vtable, unless the debugger wants to suppress it.
- StackArtMethodHandleScope<2> rhs(soa.Self());
- MutableReflectiveHandle<ArtMethod> m(rhs.NewHandle(pReq->method));
+ ArtMethod* m = pReq->method;
PointerSize image_pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
if ((pReq->options & JDWP::INVOKE_NONVIRTUAL) == 0 && pReq->receiver.Read() != nullptr) {
- MutableReflectiveHandle<ArtMethod> actual_method(rhs.NewHandle(
- pReq->klass.Read()->FindVirtualMethodForVirtualOrInterface(m.Get(), image_pointer_size)));
- if (actual_method.Get() != m.Get()) {
- VLOG(jdwp) << "ExecuteMethod translated " << m->PrettyMethod()
- << " to " << actual_method->PrettyMethod();
+ ArtMethod* actual_method =
+ pReq->klass.Read()->FindVirtualMethodForVirtualOrInterface(m, image_pointer_size);
+ if (actual_method != m) {
+ VLOG(jdwp) << "ExecuteMethod translated " << ArtMethod::PrettyMethod(m)
+ << " to " << ArtMethod::PrettyMethod(actual_method);
m = actual_method;
}
}
- VLOG(jdwp) << "ExecuteMethod " << m->PrettyMethod()
+ VLOG(jdwp) << "ExecuteMethod " << ArtMethod::PrettyMethod(m)
<< " receiver=" << pReq->receiver.Read()
<< " arg_count=" << pReq->arg_count;
CHECK(m != nullptr);
diff --git a/runtime/entrypoints/entrypoint_utils-inl.h b/runtime/entrypoints/entrypoint_utils-inl.h
index fe12a7c..2556079 100644
--- a/runtime/entrypoints/entrypoint_utils-inl.h
+++ b/runtime/entrypoints/entrypoint_utils-inl.h
@@ -39,7 +39,6 @@
#include "mirror/object-inl.h"
#include "mirror/throwable.h"
#include "nth_caller_visitor.h"
-#include "reflective_handle_scope-inl.h"
#include "runtime.h"
#include "stack_map.h"
#include "thread.h"
@@ -382,11 +381,9 @@
return resolved_field;
} else {
StackHandleScope<1> hs(self);
- StackArtFieldHandleScope<1> rhs(self);
- ReflectiveHandle<ArtField> resolved_field_handle(rhs.NewHandle(resolved_field));
if (LIKELY(class_linker->EnsureInitialized(self, hs.NewHandle(fields_class), true, true))) {
// Otherwise let's ensure the class is initialized before resolving the field.
- return resolved_field_handle.Get();
+ return resolved_field;
}
DCHECK(self->IsExceptionPending()); // Throw exception and unwind
return nullptr; // Failure.
diff --git a/runtime/entrypoints_order_test.cc b/runtime/entrypoints_order_test.cc
index 5235f65..5b4275c 100644
--- a/runtime/entrypoints_order_test.cc
+++ b/runtime/entrypoints_order_test.cc
@@ -136,13 +136,10 @@
EXPECT_OFFSET_DIFFP(Thread, tlsPtr_, flip_function, method_verifier, sizeof(void*));
EXPECT_OFFSET_DIFFP(Thread, tlsPtr_, method_verifier, thread_local_mark_stack, sizeof(void*));
EXPECT_OFFSET_DIFFP(Thread, tlsPtr_, thread_local_mark_stack, async_exception, sizeof(void*));
- EXPECT_OFFSET_DIFFP(Thread, tlsPtr_, async_exception, top_reflective_handle_scope,
- sizeof(void*));
// The first field after tlsPtr_ is forced to a 16 byte alignment so it might have some space.
auto offset_tlsptr_end = OFFSETOF_MEMBER(Thread, tlsPtr_) +
sizeof(decltype(reinterpret_cast<Thread*>(16)->tlsPtr_));
- CHECKED(offset_tlsptr_end - OFFSETOF_MEMBER(Thread, tlsPtr_.top_reflective_handle_scope) ==
- sizeof(void*),
+ CHECKED(offset_tlsptr_end - OFFSETOF_MEMBER(Thread, tlsPtr_.async_exception) == sizeof(void*),
"async_exception last field");
}
diff --git a/runtime/jni/jni_id_manager.cc b/runtime/jni/jni_id_manager.cc
index 4b6335b..2553fdf 100644
--- a/runtime/jni/jni_id_manager.cc
+++ b/runtime/jni/jni_id_manager.cc
@@ -16,10 +16,6 @@
#include "jni_id_manager.h"
-#include <algorithm>
-#include <cstdint>
-#include <type_traits>
-
#include "android-base/macros.h"
#include "art_field-inl.h"
#include "art_method-inl.h"
@@ -38,11 +34,12 @@
#include "mirror/class_ext-inl.h"
#include "mirror/object-inl.h"
#include "obj_ptr-inl.h"
-#include "reflective_handle_scope-inl.h"
-#include "reflective_handle_scope.h"
#include "reflective_value_visitor.h"
#include "thread-inl.h"
#include "thread.h"
+#include <algorithm>
+#include <cstdint>
+#include <type_traits>
namespace art {
namespace jni {
@@ -63,63 +60,65 @@
}
template <typename ArtType>
-ObjPtr<mirror::PointerArray> GetIds(ObjPtr<mirror::Class> k, ArtType* t)
- REQUIRES_SHARED(Locks::mutator_lock_) {
- if constexpr (std::is_same_v<ArtType, ArtField>) {
- return t->IsStatic() ? k->GetStaticFieldIds() : k->GetInstanceFieldIds();
- } else {
- return t->IsObsolete() ? nullptr : k->GetMethodIds();
- }
-}
-
-// Forces the appropriate id array to be present if possible. Returns true if allocation was
-// attempted but failed.
-template <typename ArtType>
-bool EnsureIdsArray(Thread* self, ObjPtr<mirror::Class> k, ArtType* t)
+ObjPtr<mirror::PointerArray> GetOrCreateIds(Thread* self,
+ ObjPtr<mirror::Class> k,
+ ArtType* t,
+ /*out*/bool* allocation_failure)
REQUIRES_SHARED(Locks::mutator_lock_);
template <>
-bool EnsureIdsArray(Thread* self, ObjPtr<mirror::Class> k, ArtField* field) {
+ObjPtr<mirror::PointerArray> GetOrCreateIds(Thread* self,
+ ObjPtr<mirror::Class> k,
+ ArtField* field,
+ /*out*/bool* allocation_failure) {
ScopedExceptionStorage ses(self);
StackHandleScope<1> hs(self);
Handle<mirror::Class> h_k(hs.NewHandle(k));
+ ObjPtr<mirror::PointerArray> res;
if (Locks::mutator_lock_->IsExclusiveHeld(self)) {
- return false;
+ res = field->IsStatic() ? h_k->GetStaticFieldIds() : h_k->GetInstanceFieldIds();
} else {
- // NB This modifies the class to allocate the ClassExt and the ids array.
- field->IsStatic() ? mirror::Class::GetOrCreateStaticFieldIds(h_k)
- : mirror::Class::GetOrCreateInstanceFieldIds(h_k);
+ res = field->IsStatic() ? mirror::Class::GetOrCreateStaticFieldIds(h_k)
+ : mirror::Class::GetOrCreateInstanceFieldIds(h_k);
}
if (self->IsExceptionPending()) {
self->AssertPendingOOMException();
ses.SuppressOldException("Failed to allocate maps for jmethodIDs. ");
- return true;
+ *allocation_failure = true;
+ } else {
+ *allocation_failure = false;
}
- return false;
+ return res;
}
template <>
-bool EnsureIdsArray(Thread* self, ObjPtr<mirror::Class> k, ArtMethod* method) {
+ObjPtr<mirror::PointerArray> GetOrCreateIds(Thread* self,
+ ObjPtr<mirror::Class> k,
+ ArtMethod* method,
+ /*out*/bool* allocation_failure) {
if (method->IsObsolete()) {
if (kTraceIds) {
LOG(INFO) << "jmethodID for Obsolete method " << method->PrettyMethod() << " requested!";
}
// No ids array for obsolete methods. Just do a linear scan.
- return false;
+ *allocation_failure = false;
+ return nullptr;
}
StackHandleScope<1> hs(self);
Handle<mirror::Class> h_k(hs.NewHandle(k));
+ ObjPtr<mirror::PointerArray> res;
if (Locks::mutator_lock_->IsExclusiveHeld(self) || !Locks::mutator_lock_->IsSharedHeld(self)) {
- return false;
+ res = h_k->GetMethodIds();
} else {
- // NB This modifies the class to allocate the ClassExt and the ids array.
- mirror::Class::GetOrCreateMethodIds(h_k);
+ res = mirror::Class::GetOrCreateMethodIds(h_k);
}
if (self->IsExceptionPending()) {
self->AssertPendingOOMException();
- return true;
+ *allocation_failure = true;
+ } else {
+ *allocation_failure = false;
}
- return false;
+ return res;
}
template <typename ArtType>
@@ -136,49 +135,33 @@
// Calls the relevant PrettyMethod/PrettyField on the input.
template <typename ArtType>
-std::string PrettyGeneric(ArtType t) REQUIRES_SHARED(Locks::mutator_lock_);
-template <>
-std::string PrettyGeneric(ArtMethod* f) {
+std::string PrettyGeneric(ArtType* t) REQUIRES_SHARED(Locks::mutator_lock_);
+template <> std::string PrettyGeneric(ArtMethod* f) {
return f->PrettyMethod();
}
-template <>
-std::string PrettyGeneric(ReflectiveHandle<ArtMethod> f) {
- return f->PrettyMethod();
-}
-template <>
-std::string PrettyGeneric(ArtField* f) {
- return f->PrettyField();
-}
-template <>
-std::string PrettyGeneric(ReflectiveHandle<ArtField> f) {
+template <> std::string PrettyGeneric(ArtField* f) {
return f->PrettyField();
}
// Checks if the field or method is obsolete.
-template <typename ArtType>
-bool IsObsolete(ReflectiveHandle<ArtType> t) REQUIRES_SHARED(Locks::mutator_lock_);
-template <>
-bool IsObsolete(ReflectiveHandle<ArtField> t ATTRIBUTE_UNUSED) {
+template <typename ArtType> bool IsObsolete(ArtType* t) REQUIRES_SHARED(Locks::mutator_lock_);
+template <> bool IsObsolete(ArtField* t ATTRIBUTE_UNUSED) {
return false;
}
-template <>
-bool IsObsolete(ReflectiveHandle<ArtMethod> t) {
+template <> bool IsObsolete(ArtMethod* t) {
return t->IsObsolete();
}
// Get the canonical (non-copied) version of the field or method. Only relevant for methods.
-template <typename ArtType>
-ArtType* Canonicalize(ReflectiveHandle<ArtType> t) REQUIRES_SHARED(Locks::mutator_lock_);
-template <>
-ArtField* Canonicalize(ReflectiveHandle<ArtField> t) {
- return t.Get();
+template <typename ArtType> ArtType* Canonicalize(ArtType* t) REQUIRES_SHARED(Locks::mutator_lock_);
+template <> ArtField* Canonicalize(ArtField* t) {
+ return t;
}
-template <>
-ArtMethod* Canonicalize(ReflectiveHandle<ArtMethod> t) {
+template <> ArtMethod* Canonicalize(ArtMethod* t) {
if (UNLIKELY(t->IsCopied())) {
- return t->GetCanonicalMethod();
+ t = t->GetCanonicalMethod();
}
- return t.Get();
+ return t;
}
}; // namespace
@@ -186,8 +169,7 @@
// We increment the id by 2 each time to allow us to use the LSB as a flag that the ID is an index
// and not a pointer. This gives us 2**31 unique methods that can be addressed on 32-bit art, which
// should be more than enough.
-template <>
-uintptr_t JniIdManager::GetNextId<ArtField>(JniIdType type, ReflectiveHandle<ArtField> f) {
+template <> uintptr_t JniIdManager::GetNextId<ArtField>(JniIdType type, ArtField* f) {
if (LIKELY(type == JniIdType::kIndices)) {
uintptr_t res = next_field_id_;
next_field_id_ += 2;
@@ -195,12 +177,11 @@
return res;
} else {
DCHECK_EQ(type, JniIdType::kSwapablePointer);
- return reinterpret_cast<uintptr_t>(f.Get());
+ return reinterpret_cast<uintptr_t>(f);
}
}
-template <>
-uintptr_t JniIdManager::GetNextId<ArtMethod>(JniIdType type, ReflectiveHandle<ArtMethod> m) {
+template <> uintptr_t JniIdManager::GetNextId<ArtMethod>(JniIdType type, ArtMethod* m) {
if (LIKELY(type == JniIdType::kIndices)) {
uintptr_t res = next_method_id_;
next_method_id_ += 2;
@@ -208,26 +189,21 @@
return res;
} else {
DCHECK_EQ(type, JniIdType::kSwapablePointer);
- return reinterpret_cast<uintptr_t>(m.Get());
+ return reinterpret_cast<uintptr_t>(m);
}
}
-template <>
-std::vector<ArtField*>& JniIdManager::GetGenericMap<ArtField>() {
+template <> std::vector<ArtField*>& JniIdManager::GetGenericMap<ArtField>() {
return field_id_map_;
}
-template <>
-std::vector<ArtMethod*>& JniIdManager::GetGenericMap<ArtMethod>() {
+template <> std::vector<ArtMethod*>& JniIdManager::GetGenericMap<ArtMethod>() {
return method_id_map_;
}
-template <>
-size_t JniIdManager::GetLinearSearchStartId<ArtField>(
- ReflectiveHandle<ArtField> t ATTRIBUTE_UNUSED) {
+template <> size_t JniIdManager::GetLinearSearchStartId<ArtField>(ArtField* t ATTRIBUTE_UNUSED) {
return deferred_allocation_field_id_start_;
}
-template <>
-size_t JniIdManager::GetLinearSearchStartId<ArtMethod>(ReflectiveHandle<ArtMethod> m) {
+template <> size_t JniIdManager::GetLinearSearchStartId<ArtMethod>(ArtMethod* m) {
if (m->IsObsolete()) {
return 1;
} else {
@@ -236,24 +212,20 @@
}
// TODO need to fix races in here with visitors
-template <typename ArtType>
-uintptr_t JniIdManager::EncodeGenericId(ReflectiveHandle<ArtType> t) {
- static_assert(std::is_same_v<ArtType, ArtField> || std::is_same_v<ArtType, ArtMethod>,
- "Expected ArtField or ArtMethod");
+template <typename ArtType> uintptr_t JniIdManager::EncodeGenericId(ArtType* t) {
Runtime* runtime = Runtime::Current();
JniIdType id_type = runtime->GetJniIdType();
if (id_type == JniIdType::kPointer || t == nullptr) {
- return reinterpret_cast<uintptr_t>(t.Get());
+ return reinterpret_cast<uintptr_t>(t);
}
Thread* self = Thread::Current();
ScopedExceptionStorage ses(self);
+ t = Canonicalize(t);
ObjPtr<mirror::Class> klass = t->GetDeclaringClass();
DCHECK(!klass.IsNull()) << "Null declaring class " << PrettyGeneric(t);
- size_t off = GetIdOffset(klass, Canonicalize(t), kRuntimePointerSize);
- // Here is the earliest point we can suspend.
- bool allocation_failure = EnsureIdsArray(self, klass, t.Get());
- klass = t->GetDeclaringClass();
- ObjPtr<mirror::PointerArray> ids(GetIds(klass, t.Get()));
+ size_t off = GetIdOffset(klass, t, kRuntimePointerSize);
+ bool allocation_failure = false;
+ ObjPtr<mirror::PointerArray> ids(GetOrCreateIds(self, klass, t, &allocation_failure));
if (allocation_failure) {
self->AssertPendingOOMException();
ses.SuppressOldException("OOM exception while trying to allocate JNI ids.");
@@ -262,27 +234,14 @@
uintptr_t cur_id = 0;
if (!ids.IsNull()) {
DCHECK_GT(ids->GetLength(), static_cast<int32_t>(off)) << " is " << PrettyGeneric(t);
- DCHECK_LE(0, static_cast<int32_t>(off)) << " is " << PrettyGeneric(t);
cur_id = ids->GetElementPtrSize<uintptr_t>(off, kRuntimePointerSize);
}
if (cur_id != 0) {
return cur_id;
}
WriterMutexLock mu(self, *Locks::jni_id_lock_);
- ScopedAssertNoThreadSuspension sants("EncodeJniId critical section.");
// Check the ids array for a racing id.
- constexpr std::pair<size_t, size_t> counts {
- std::is_same_v<ArtType, ArtField> ? 1 : 0,
- std::is_same_v<ArtType, ArtField> ? 0 : 1,
- };
- StackReflectiveHandleScope<counts.first, counts.second> hs(self);
- t = hs.NewHandle(Canonicalize(t));
if (!ids.IsNull()) {
- // It's possible we got suspended and structurally redefined during the EnsureIdsArray. We need
- // to get the information again.
- ids = GetIds(klass, t.Get());
- off = GetIdOffset(klass, Canonicalize(t), kRuntimePointerSize);
- CHECK(!ids.IsNull());
cur_id = ids->GetElementPtrSize<uintptr_t>(off, kRuntimePointerSize);
if (cur_id != 0) {
// We were racing some other thread and lost.
@@ -300,18 +259,17 @@
size_t search_start_index = IdToIndex(GetLinearSearchStartId(t));
size_t index = std::count_if(vec.cbegin() + search_start_index,
vec.cend(),
- [&found, &self, t](const ArtType* candidate) {
- Locks::mutator_lock_->AssertSharedHeld(self);
- found = found || candidate == t.Get();
+ [&found, t](const ArtType* candidate) {
+ found = found || candidate == t;
return !found;
}) +
search_start_index;
if (found) {
// We were either racing some other thread and lost or this thread was asked to encode the
// same method multiple times while holding the mutator lock.
- DCHECK_EQ(vec[index], t.Get())
- << "Expected: " << PrettyGeneric(vec[index]) << " got " << PrettyGeneric(t)
- << " at index " << index << " (id: " << IndexToId(index) << ").";
+ DCHECK_EQ(vec[index], t) << "Expected: " << PrettyGeneric(vec[index]) << " got "
+ << PrettyGeneric(t) << " at index " << index
+ << " (id: " << IndexToId(index) << ").";
return IndexToId(index);
}
}
@@ -322,10 +280,10 @@
std::vector<ArtType*>& vec = GetGenericMap<ArtType>();
vec.reserve(cur_index + 1);
vec.resize(std::max(vec.size(), cur_index + 1), nullptr);
- vec[cur_index] = t.Get();
+ vec[cur_index] = t;
} else {
DCHECK_EQ(cur_id % 2, 0u);
- DCHECK_EQ(cur_id, reinterpret_cast<uintptr_t>(t.Get()));
+ DCHECK_EQ(cur_id, reinterpret_cast<uintptr_t>(t));
}
if (ids.IsNull()) {
if (kIsDebugBuild && !IsObsolete(t)) {
@@ -340,24 +298,13 @@
}
jfieldID JniIdManager::EncodeFieldId(ArtField* field) {
- StackArtFieldHandleScope<1> rhs(Thread::Current());
- return EncodeFieldId(rhs.NewHandle(field));
-}
-
-jfieldID JniIdManager::EncodeFieldId(ReflectiveHandle<ArtField> field) {
auto* res = reinterpret_cast<jfieldID>(EncodeGenericId(field));
if (kTraceIds && field != nullptr) {
LOG(INFO) << "Returning " << res << " for field " << field->PrettyField();
}
return res;
}
-
jmethodID JniIdManager::EncodeMethodId(ArtMethod* method) {
- StackArtMethodHandleScope<1> rhs(Thread::Current());
- return EncodeMethodId(rhs.NewHandle(method));
-}
-
-jmethodID JniIdManager::EncodeMethodId(ReflectiveHandle<ArtMethod> method) {
auto* res = reinterpret_cast<jmethodID>(EncodeGenericId(method));
if (kTraceIds && method != nullptr) {
LOG(INFO) << "Returning " << res << " for method " << method->PrettyMethod();
@@ -498,70 +445,17 @@
}
}
-class JniIdDeferStackReflectiveScope : public BaseReflectiveHandleScope {
- public:
- JniIdDeferStackReflectiveScope() REQUIRES_SHARED(art::Locks::mutator_lock_)
- : BaseReflectiveHandleScope(), methods_(), fields_() {
- PushScope(Thread::Current());
- }
-
- void Initialize(const std::vector<ArtMethod*>& methods, const std::vector<ArtField*>& fields)
- REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(Roles::uninterruptible_) {
- methods_ = methods;
- fields_ = fields;
- }
-
- ~JniIdDeferStackReflectiveScope() REQUIRES_SHARED(Locks::mutator_lock_) {
- PopScope();
- }
-
- void VisitTargets(ReflectiveValueVisitor* visitor) override
- REQUIRES_SHARED(Locks::mutator_lock_) {
- for (auto it = methods_.begin(); it != methods_.end(); ++it) {
- if (*it == nullptr) {
- continue;
- }
- *it = visitor->VisitMethod(*it, ReflectiveHandleScopeSourceInfo(this));
- }
- for (auto it = fields_.begin(); it != fields_.end(); ++it) {
- if (*it == nullptr) {
- continue;
- }
- *it = visitor->VisitField(*it, ReflectiveHandleScopeSourceInfo(this));
- }
- }
-
- ArtField** GetFieldPtr(size_t idx) REQUIRES_SHARED(Locks::mutator_lock_) {
- return &fields_[idx];
- }
-
- ArtMethod** GetMethodPtr(size_t idx) REQUIRES_SHARED(Locks::mutator_lock_) {
- return &methods_[idx];
- }
-
- size_t NumFields() const {
- return fields_.size();
- }
- size_t NumMethods() const {
- return methods_.size();
- }
-
- private:
- std::vector<ArtMethod*> methods_;
- std::vector<ArtField*> fields_;
-};
-
void JniIdManager::EndDefer() {
// Fixup the method->id map.
Thread* self = Thread::Current();
- auto set_id = [&](auto** t, uintptr_t id) REQUIRES_SHARED(Locks::mutator_lock_) {
+ auto set_id = [&](auto* t, uintptr_t id) REQUIRES_SHARED(Locks::mutator_lock_) {
if (t == nullptr) {
return;
}
- bool alloc_failure = EnsureIdsArray(self, (*t)->GetDeclaringClass(), *t);
- ObjPtr<mirror::Class> klass((*t)->GetDeclaringClass());
- size_t off = GetIdOffset(klass, (*t), kRuntimePointerSize);
- ObjPtr<mirror::PointerArray> ids = GetIds(klass, (*t));
+ ObjPtr<mirror::Class> klass(t->GetDeclaringClass());
+ size_t off = GetIdOffset(klass, t, kRuntimePointerSize);
+ bool alloc_failure = false;
+ ObjPtr<mirror::PointerArray> ids = GetOrCreateIds(self, klass, t, &alloc_failure);
CHECK(!alloc_failure) << "Could not allocate jni ids array!";
if (ids.IsNull()) {
return;
@@ -588,24 +482,25 @@
// ids when it finishes.
Locks::mutator_lock_->AssertNotExclusiveHeld(self);
Locks::mutator_lock_->AssertSharedHeld(self);
- JniIdDeferStackReflectiveScope jidsrs;
+ std::vector<ArtMethod*> method_id_copy;
+ std::vector<ArtField*> field_id_copy;
uintptr_t method_start_id;
uintptr_t field_start_id;
{
ReaderMutexLock mu(self, *Locks::jni_id_lock_);
- ScopedAssertNoThreadSuspension sants(__FUNCTION__);
- jidsrs.Initialize(method_id_map_, field_id_map_);
+ method_id_copy = method_id_map_;
+ field_id_copy = field_id_map_;
method_start_id = deferred_allocation_method_id_start_;
field_start_id = deferred_allocation_field_id_start_;
}
- for (size_t index = kIsDebugBuild ? 0 : IdToIndex(method_start_id); index < jidsrs.NumMethods();
+ for (size_t index = kIsDebugBuild ? 0 : IdToIndex(method_start_id); index < method_id_copy.size();
++index) {
- set_id(jidsrs.GetMethodPtr(index), IndexToId(index));
+ set_id(method_id_copy[index], IndexToId(index));
}
- for (size_t index = kIsDebugBuild ? 0 : IdToIndex(field_start_id); index < jidsrs.NumFields();
+ for (size_t index = kIsDebugBuild ? 0 : IdToIndex(field_start_id); index < field_id_copy.size();
++index) {
- set_id(jidsrs.GetFieldPtr(index), IndexToId(index));
+ set_id(field_id_copy[index], IndexToId(index));
}
WriterMutexLock mu(self, *Locks::jni_id_lock_);
DCHECK_GE(deferred_allocation_refcount_, 1u);
diff --git a/runtime/jni/jni_id_manager.h b/runtime/jni/jni_id_manager.h
index 1cfcefb..6b43534 100644
--- a/runtime/jni/jni_id_manager.h
+++ b/runtime/jni/jni_id_manager.h
@@ -17,9 +17,8 @@
#ifndef ART_RUNTIME_JNI_JNI_ID_MANAGER_H_
#define ART_RUNTIME_JNI_JNI_ID_MANAGER_H_
-#include <jni.h>
-
#include <atomic>
+#include <jni.h>
#include <vector>
#include "art_field.h"
@@ -29,8 +28,6 @@
#include "reflective_value_visitor.h"
namespace art {
-template<typename RT> class ReflectiveHandle;
-
namespace jni {
class ScopedEnableSuspendAllJniIdQueries;
@@ -45,12 +42,8 @@
ArtMethod* DecodeMethodId(jmethodID method) REQUIRES(!Locks::jni_id_lock_);
ArtField* DecodeFieldId(jfieldID field) REQUIRES(!Locks::jni_id_lock_);
- jmethodID EncodeMethodId(ReflectiveHandle<ArtMethod> method) REQUIRES(!Locks::jni_id_lock_)
- REQUIRES_SHARED(Locks::mutator_lock_);
jmethodID EncodeMethodId(ArtMethod* method) REQUIRES(!Locks::jni_id_lock_)
REQUIRES_SHARED(Locks::mutator_lock_);
- jfieldID EncodeFieldId(ReflectiveHandle<ArtField> field) REQUIRES(!Locks::jni_id_lock_)
- REQUIRES_SHARED(Locks::mutator_lock_);
jfieldID EncodeFieldId(ArtField* field) REQUIRES(!Locks::jni_id_lock_)
REQUIRES_SHARED(Locks::mutator_lock_);
@@ -59,20 +52,15 @@
private:
template <typename ArtType>
- uintptr_t EncodeGenericId(ReflectiveHandle<ArtType> t) REQUIRES(!Locks::jni_id_lock_)
+ uintptr_t EncodeGenericId(ArtType* t) REQUIRES(!Locks::jni_id_lock_)
REQUIRES_SHARED(Locks::mutator_lock_);
template <typename ArtType>
ArtType* DecodeGenericId(uintptr_t input) REQUIRES(!Locks::jni_id_lock_);
- template <typename ArtType> std::vector<ArtType*>& GetGenericMap()
- REQUIRES(Locks::jni_id_lock_);
+ template <typename ArtType> std::vector<ArtType*>& GetGenericMap() REQUIRES(Locks::jni_id_lock_);
template <typename ArtType>
- uintptr_t GetNextId(JniIdType id, ReflectiveHandle<ArtType> t)
- REQUIRES_SHARED(Locks::mutator_lock_)
- REQUIRES(Locks::jni_id_lock_);
+ uintptr_t GetNextId(JniIdType id, ArtType* t) REQUIRES(Locks::jni_id_lock_);
template <typename ArtType>
- size_t GetLinearSearchStartId(ReflectiveHandle<ArtType> t)
- REQUIRES(Locks::jni_id_lock_)
- REQUIRES_SHARED(Locks::mutator_lock_);
+ size_t GetLinearSearchStartId(ArtType* t) REQUIRES(Locks::jni_id_lock_);
void StartDefer() REQUIRES(!Locks::jni_id_lock_) REQUIRES_SHARED(Locks::mutator_lock_);
void EndDefer() REQUIRES(!Locks::jni_id_lock_) REQUIRES_SHARED(Locks::mutator_lock_);
diff --git a/runtime/jni/jni_internal.h b/runtime/jni/jni_internal.h
index 1616ee5..da17922 100644
--- a/runtime/jni/jni_internal.h
+++ b/runtime/jni/jni_internal.h
@@ -22,10 +22,7 @@
#include "base/locks.h"
#include "base/macros.h"
-#include "reflective_handle.h"
-#include "reflective_handle_scope.h"
#include "runtime.h"
-#include "thread.h"
namespace art {
@@ -90,16 +87,6 @@
}
template <bool kEnableIndexIds = true>
-ALWAYS_INLINE static inline jfieldID EncodeArtField(ReflectiveHandle<ArtField> field)
- REQUIRES_SHARED(Locks::mutator_lock_) {
- if (kEnableIndexIds && Runtime::Current()->GetJniIdType() != JniIdType::kPointer) {
- return Runtime::Current()->GetJniIdManager()->EncodeFieldId(field);
- } else {
- return reinterpret_cast<jfieldID>(field.Get());
- }
-}
-
-template <bool kEnableIndexIds = true>
ALWAYS_INLINE
static inline jfieldID EncodeArtField(ArtField* field) REQUIRES_SHARED(Locks::mutator_lock_) {
if (kEnableIndexIds && Runtime::Current()->GetJniIdType() != JniIdType::kPointer) {
@@ -111,17 +98,6 @@
template <bool kEnableIndexIds = true>
ALWAYS_INLINE
-static inline jmethodID EncodeArtMethod(ReflectiveHandle<ArtMethod> art_method)
- REQUIRES_SHARED(Locks::mutator_lock_) {
- if (kEnableIndexIds && Runtime::Current()->GetJniIdType() != JniIdType::kPointer) {
- return Runtime::Current()->GetJniIdManager()->EncodeMethodId(art_method);
- } else {
- return reinterpret_cast<jmethodID>(art_method.Get());
- }
-}
-
-template <bool kEnableIndexIds = true>
-ALWAYS_INLINE
static inline jmethodID EncodeArtMethod(ArtMethod* art_method)
REQUIRES_SHARED(Locks::mutator_lock_) {
if (kEnableIndexIds && Runtime::Current()->GetJniIdType() != JniIdType::kPointer) {
diff --git a/runtime/reflective_handle.h b/runtime/reflective_handle.h
deleted file mode 100644
index 014d976..0000000
--- a/runtime/reflective_handle.h
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Copyright (C) 2014 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.
- */
-
-#ifndef ART_RUNTIME_REFLECTIVE_HANDLE_H_
-#define ART_RUNTIME_REFLECTIVE_HANDLE_H_
-
-#include "base/value_object.h"
-#include "reflective_reference.h"
-
-namespace art {
-
-// This is a holder similar to Handle<T> that is used to hold reflective references to ArtField and
-// ArtMethod structures. A reflective reference is one that must be updated if the underlying class
-// or instances are replaced due to structural redefinition or some other process. In general these
-// don't need to be used. It's only when it's important that a reference to a field not become
-// obsolete and it needs to be held over a suspend point that this should be used.
-template <typename T>
-class ReflectiveHandle : public ValueObject {
- public:
- static_assert(std::is_same_v<T, ArtField> || std::is_same_v<T, ArtMethod>,
- "Expected ArtField or ArtMethod");
-
- ReflectiveHandle() : reference_(nullptr) {}
-
- ALWAYS_INLINE ReflectiveHandle(const ReflectiveHandle<T>& handle) = default;
- ALWAYS_INLINE ReflectiveHandle<T>& operator=(const ReflectiveHandle<T>& handle) = default;
-
- ALWAYS_INLINE explicit ReflectiveHandle(ReflectiveReference<T>* reference)
- : reference_(reference) {}
-
- ALWAYS_INLINE T& operator*() const REQUIRES_SHARED(Locks::mutator_lock_) {
- return *Get();
- }
-
- ALWAYS_INLINE T* operator->() const REQUIRES_SHARED(Locks::mutator_lock_) {
- return Get();
- }
-
- ALWAYS_INLINE T* Get() const REQUIRES_SHARED(Locks::mutator_lock_) {
- return reference_->Ptr();
- }
-
- ALWAYS_INLINE bool IsNull() const {
- // It's safe to null-check it without a read barrier.
- return reference_->IsNull();
- }
-
- ALWAYS_INLINE bool operator!=(std::nullptr_t) const REQUIRES_SHARED(Locks::mutator_lock_) {
- return !IsNull();
- }
-
- ALWAYS_INLINE bool operator==(std::nullptr_t) const REQUIRES_SHARED(Locks::mutator_lock_) {
- return IsNull();
- }
-
- protected:
- ReflectiveReference<T>* reference_;
-
- private:
- friend class BaseReflectiveHandleScope;
- template <size_t kNumFieldReferences, size_t kNumMethodReferences>
- friend class StackReflectiveHandleScope;
-};
-
-// Handles that support assignment.
-template <typename T>
-class MutableReflectiveHandle : public ReflectiveHandle<T> {
- public:
- MutableReflectiveHandle() {}
-
- ALWAYS_INLINE MutableReflectiveHandle(const MutableReflectiveHandle<T>& handle)
- REQUIRES_SHARED(Locks::mutator_lock_) = default;
-
- ALWAYS_INLINE MutableReflectiveHandle<T>& operator=(const MutableReflectiveHandle<T>& handle)
- REQUIRES_SHARED(Locks::mutator_lock_) = default;
-
- ALWAYS_INLINE explicit MutableReflectiveHandle(ReflectiveReference<T>* reference)
- REQUIRES_SHARED(Locks::mutator_lock_)
- : ReflectiveHandle<T>(reference) {}
-
- ALWAYS_INLINE T* Assign(T* reference) REQUIRES_SHARED(Locks::mutator_lock_) {
- ReflectiveReference<T>* ref = ReflectiveHandle<T>::reference_;
- T* old = ref->Ptr();
- ref->Assign(reference);
- return old;
- }
-
- private:
- friend class BaseReflectiveHandleScope;
- template <size_t kNumFieldReferences, size_t kNumMethodReferences>
- friend class StackReflectiveHandleScope;
-};
-
-template<typename T>
-class ReflectiveHandleWrapper : public MutableReflectiveHandle<T> {
- public:
- ReflectiveHandleWrapper(T** obj, const MutableReflectiveHandle<T>& handle)
- : MutableReflectiveHandle<T>(handle), obj_(obj) {
- }
-
- ReflectiveHandleWrapper(const ReflectiveHandleWrapper&) = default;
-
- ~ReflectiveHandleWrapper() {
- *obj_ = MutableReflectiveHandle<T>::Get();
- }
-
- private:
- T** const obj_;
-};
-
-} // namespace art
-
-#endif // ART_RUNTIME_REFLECTIVE_HANDLE_H_
diff --git a/runtime/reflective_handle_scope-inl.h b/runtime/reflective_handle_scope-inl.h
deleted file mode 100644
index 64ea9f9..0000000
--- a/runtime/reflective_handle_scope-inl.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2014 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.
- */
-
-#ifndef ART_RUNTIME_REFLECTIVE_HANDLE_SCOPE_INL_H_
-#define ART_RUNTIME_REFLECTIVE_HANDLE_SCOPE_INL_H_
-
-#include "android-base/thread_annotations.h"
-#include "base/mutex.h"
-#include "reflective_handle.h"
-#include "reflective_handle_scope.h"
-#include "thread-current-inl.h"
-
-namespace art {
-
-template <size_t kNumFields, size_t kNumMethods>
-StackReflectiveHandleScope<kNumFields, kNumMethods>::StackReflectiveHandleScope(Thread* self) : field_pos_(0), method_pos_(0) {
- DCHECK_EQ(self, Thread::Current());
- PushScope(self);
-}
-
-template <size_t kNumFields, size_t kNumMethods>
-void StackReflectiveHandleScope<kNumFields, kNumMethods>::VisitTargets(
- ReflectiveValueVisitor* visitor) {
- Thread* self = Thread::Current();
- DCHECK(GetThread() == self ||
- Locks::mutator_lock_->IsExclusiveHeld(self))
- << *GetThread() << " on thread " << *self;
- auto visit_one = [&](auto& rv) NO_THREAD_SAFETY_ANALYSIS {
- Locks::mutator_lock_->AssertSharedHeld(self);
- if (!rv.IsNull()) {
- rv.Assign((*visitor)(rv.Ptr(), ReflectiveHandleScopeSourceInfo(this)));
- }
- };
- std::for_each(fields_.begin(), fields_.begin() + field_pos_, visit_one);
- std::for_each(methods_.begin(), methods_.begin() + method_pos_, visit_one);
-}
-
-template <size_t kNumFields, size_t kNumMethods>
-StackReflectiveHandleScope<kNumFields, kNumMethods>::~StackReflectiveHandleScope() {
- PopScope();
-}
-
-void BaseReflectiveHandleScope::PushScope(Thread* self) {
- DCHECK_EQ(self, Thread::Current());
- self_ = self;
- link_ = self_->GetTopReflectiveHandleScope();
- self_->PushReflectiveHandleScope(this);
-}
-
-void BaseReflectiveHandleScope::PopScope() {
- auto* prev = self_->PopReflectiveHandleScope();
- CHECK_EQ(prev, this);
- link_ = nullptr;
-}
-
-} // namespace art
-
-#endif // ART_RUNTIME_REFLECTIVE_HANDLE_SCOPE_INL_H_
diff --git a/runtime/reflective_handle_scope.cc b/runtime/reflective_handle_scope.cc
deleted file mode 100644
index 2c3ae5e..0000000
--- a/runtime/reflective_handle_scope.cc
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2019 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 "reflective_handle_scope.h"
-
-#include <ostream>
-
-#include "thread.h"
-
-namespace art {
-
-
-void BaseReflectiveHandleScope::Describe(std::ostream& os) const {
- os << "[BaseReflectiveHandleScope self_=" << *self_ << ", link_=" << link_ << "]";
-}
-
-std::ostream& operator<<(std::ostream& os, const BaseReflectiveHandleScope& brhs) {
- brhs.Describe(os);
- return os;
-}
-
-} // namespace art
diff --git a/runtime/reflective_handle_scope.h b/runtime/reflective_handle_scope.h
deleted file mode 100644
index 46cff8b..0000000
--- a/runtime/reflective_handle_scope.h
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- * Copyright (C) 2019 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.
- */
-
-#ifndef ART_RUNTIME_REFLECTIVE_HANDLE_SCOPE_H_
-#define ART_RUNTIME_REFLECTIVE_HANDLE_SCOPE_H_
-
-#include <android-base/logging.h>
-
-#include <array>
-#include <compare>
-#include <functional>
-#include <stack>
-
-#include "android-base/macros.h"
-#include "base/enums.h"
-#include "base/globals.h"
-#include "base/locks.h"
-#include "base/macros.h"
-#include "base/value_object.h"
-#include "reflective_handle.h"
-#include "reflective_reference.h"
-#include "reflective_value_visitor.h"
-
-namespace art {
-
-class ArtField;
-class ArtMethod;
-class BaseReflectiveHandleScope;
-class Thread;
-
-// This is a holder similar to StackHandleScope that is used to hold reflective references to
-// ArtField and ArtMethod structures. A reflective reference is one that must be updated if the
-// underlying class or instances are replaced due to structural redefinition or some other process.
-// In general these don't need to be used. It's only when it's important that a reference to a field
-// not become obsolete and it needs to be held over a suspend point that this should be used. This
-// takes care of the book-keeping to allow the runtime to visit and update ReflectiveHandles when
-// structural redefinition occurs.
-class BaseReflectiveHandleScope {
- public:
- template <typename Visitor>
- ALWAYS_INLINE void VisitTargets(Visitor& visitor) REQUIRES_SHARED(Locks::mutator_lock_) {
- FunctionReflectiveValueVisitor v(&visitor);
- VisitTargets(&v);
- }
-
- ALWAYS_INLINE virtual ~BaseReflectiveHandleScope() {
- DCHECK(link_ == nullptr);
- }
-
- virtual void VisitTargets(ReflectiveValueVisitor* visitor)
- REQUIRES_SHARED(Locks::mutator_lock_) = 0;
-
- BaseReflectiveHandleScope* GetLink() {
- return link_;
- }
-
- Thread* GetThread() {
- return self_;
- }
-
- void Describe(std::ostream& os) const;
-
- protected:
- ALWAYS_INLINE BaseReflectiveHandleScope() : self_(nullptr), link_(nullptr) {}
-
- ALWAYS_INLINE inline void PushScope(Thread* self) REQUIRES_SHARED(Locks::mutator_lock_);
- ALWAYS_INLINE inline void PopScope() REQUIRES_SHARED(Locks::mutator_lock_);
-
- // Thread this node is rooted in.
- Thread* self_;
- // Next node in the handle-scope linked list. Root is held by Thread.
- BaseReflectiveHandleScope* link_;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(BaseReflectiveHandleScope);
-};
-std::ostream& operator<<(std::ostream& os, const BaseReflectiveHandleScope& brhs);
-
-template <size_t kNumFields, size_t kNumMethods>
-class StackReflectiveHandleScope : public BaseReflectiveHandleScope {
- private:
- static constexpr bool kHasFields = kNumFields > 0;
- static constexpr bool kHasMethods = kNumMethods > 0;
-
- public:
- ALWAYS_INLINE explicit StackReflectiveHandleScope(Thread* self)
- REQUIRES_SHARED(Locks::mutator_lock_);
- ALWAYS_INLINE ~StackReflectiveHandleScope() REQUIRES_SHARED(Locks::mutator_lock_);
-
- void VisitTargets(ReflectiveValueVisitor* visitor) override REQUIRES_SHARED(Locks::mutator_lock_);
-
- template <typename T,
- typename = typename std::enable_if_t<(kHasFields && std::is_same_v<T, ArtField>) ||
- (kHasMethods && std::is_same_v<T, ArtMethod>)>>
- ALWAYS_INLINE MutableReflectiveHandle<T> NewHandle(T* t) REQUIRES_SHARED(Locks::mutator_lock_) {
- if constexpr (std::is_same_v<T, ArtField>) {
- return NewFieldHandle(t);
- } else {
- static_assert(std::is_same_v<T, ArtMethod>, "Expected ArtField or ArtMethod");
- return NewMethodHandle(t);
- }
- }
- template<typename T>
- ALWAYS_INLINE ReflectiveHandleWrapper<T> NewReflectiveHandleWrapper(T** t)
- REQUIRES_SHARED(art::Locks::mutator_lock_) {
- return ReflectiveHandleWrapper<T>(t, NewHandle(*t));
- }
-
- ALWAYS_INLINE MutableReflectiveHandle<ArtField> NewFieldHandle(ArtField* f)
- REQUIRES_SHARED(art::Locks::mutator_lock_) {
- static_assert(kHasFields, "No fields");
- DCHECK_LT(field_pos_, kNumFields);
- MutableReflectiveHandle<ArtField> fh(GetMutableFieldHandle(field_pos_++));
- fh.Assign(f);
- return fh;
- }
- ALWAYS_INLINE ReflectiveHandleWrapper<ArtField> NewReflectiveFieldHandleWrapper(ArtField** f)
- REQUIRES_SHARED(art::Locks::mutator_lock_) {
- return ReflectiveHandleWrapper<ArtField>(f, NewMethodHandle(*f));
- }
-
- ALWAYS_INLINE ArtField* GetField(size_t i) {
- static_assert(kHasFields, "No fields");
- return GetFieldReference(i)->Ptr();
- }
- ALWAYS_INLINE ReflectiveHandle<ArtField> GetFieldHandle(size_t i) {
- static_assert(kHasFields, "No fields");
- return ReflectiveHandle<ArtField>(GetFieldReference(i));
- }
- ALWAYS_INLINE MutableReflectiveHandle<ArtField> GetMutableFieldHandle(size_t i) {
- static_assert(kHasFields, "No fields");
- return MutableReflectiveHandle<ArtField>(GetFieldReference(i));
- }
-
- ALWAYS_INLINE MutableReflectiveHandle<ArtMethod> NewMethodHandle(ArtMethod* m)
- REQUIRES_SHARED(art::Locks::mutator_lock_) {
- static_assert(kHasMethods, "No methods");
- DCHECK_LT(method_pos_, kNumMethods);
- MutableReflectiveHandle<ArtMethod> mh(GetMutableMethodHandle(method_pos_++));
- mh.Assign(m);
- return mh;
- }
- ALWAYS_INLINE ReflectiveHandleWrapper<ArtMethod> NewReflectiveMethodHandleWrapper(ArtMethod** m)
- REQUIRES_SHARED(art::Locks::mutator_lock_) {
- return ReflectiveHandleWrapper<ArtMethod>(m, NewMethodHandle(*m));
- }
-
- ALWAYS_INLINE ArtMethod* GetMethod(size_t i) {
- static_assert(kHasMethods, "No methods");
- return GetMethodReference(i)->Ptr();
- }
- ALWAYS_INLINE ReflectiveHandle<ArtMethod> GetMethodHandle(size_t i) {
- static_assert(kHasMethods, "No methods");
- return ReflectiveHandle<ArtMethod>(GetMethodReference(i));
- }
- ALWAYS_INLINE MutableReflectiveHandle<ArtMethod> GetMutableMethodHandle(size_t i) {
- static_assert(kHasMethods, "No methods");
- return MutableReflectiveHandle<ArtMethod>(GetMethodReference(i));
- }
-
- size_t RemainingFieldSlots() const {
- return kNumFields - field_pos_;
- }
-
- size_t RemainingMethodSlots() const {
- return kNumMethods - method_pos_;
- }
-
- private:
- ReflectiveReference<ArtMethod>* GetMethodReference(size_t i) {
- DCHECK_LT(i, method_pos_);
- return &methods_[i];
- }
-
- ReflectiveReference<ArtField>* GetFieldReference(size_t i) {
- DCHECK_LT(i, field_pos_);
- return &fields_[i];
- }
-
- size_t field_pos_;
- size_t method_pos_;
- std::array<ReflectiveReference<ArtField>, kNumFields> fields_;
- std::array<ReflectiveReference<ArtMethod>, kNumMethods> methods_;
-};
-
-template <size_t kNumMethods>
-using StackArtMethodHandleScope = StackReflectiveHandleScope</*kNumFields=*/0, kNumMethods>;
-
-template <size_t kNumFields>
-using StackArtFieldHandleScope = StackReflectiveHandleScope<kNumFields, /*kNumMethods=*/0>;
-
-} // namespace art
-
-#endif // ART_RUNTIME_REFLECTIVE_HANDLE_SCOPE_H_
diff --git a/runtime/reflective_reference.h b/runtime/reflective_reference.h
deleted file mode 100644
index f57c030..0000000
--- a/runtime/reflective_reference.h
+++ /dev/null
@@ -1,71 +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.
- */
-
-#ifndef ART_RUNTIME_REFLECTIVE_REFERENCE_H_
-#define ART_RUNTIME_REFLECTIVE_REFERENCE_H_
-
-#include "android-base/macros.h"
-#include "base/macros.h"
-#include "mirror/object_reference.h"
-
-namespace art {
-
-class ArtField;
-class ArtMethod;
-// A reference to a ArtField or ArtMethod.
-template <class ReflectiveType>
-class ReflectiveReference {
- public:
- static_assert(std::is_same_v<ReflectiveType, ArtMethod> ||
- std::is_same_v<ReflectiveType, ArtField>,
- "Uknown type!");
- ReflectiveReference() : val_(nullptr) {}
- explicit ReflectiveReference(ReflectiveType* r) : val_(r) {}
- ReflectiveReference<ReflectiveType>& operator=(const ReflectiveReference<ReflectiveType>& t) =
- default;
-
- ReflectiveType* Ptr() {
- return val_;
- }
-
- void Assign(ReflectiveType* r) {
- val_ = r;
- }
-
- bool IsNull() const {
- return val_ == nullptr;
- }
-
- bool operator==(const ReflectiveReference<ReflectiveType>& rr) const {
- return val_ == rr.val_;
- }
- bool operator!=(const ReflectiveReference<ReflectiveType>& rr) const {
- return !operator==(rr);
- }
- bool operator==(std::nullptr_t) const {
- return IsNull();
- }
- bool operator!=(std::nullptr_t) const {
- return !IsNull();
- }
-
- private:
- ReflectiveType* val_;
-};
-
-} // namespace art
-
-#endif // ART_RUNTIME_REFLECTIVE_REFERENCE_H_
diff --git a/runtime/reflective_value_visitor.cc b/runtime/reflective_value_visitor.cc
index 5a288d3..69fd51f 100644
--- a/runtime/reflective_value_visitor.cc
+++ b/runtime/reflective_value_visitor.cc
@@ -42,13 +42,4 @@
os << " jmethodID=" << reinterpret_cast<uintptr_t>(id_);
}
-void ReflectiveHandleScopeSourceInfo::Describe(std::ostream& os) const {
- ReflectionSourceInfo::Describe(os);
- os << " source= (" << source_ << ") ";
- if (source_ == nullptr) {
- os << "nullptr";
- } else {
- os << *source_;
- }
-}
} // namespace art
diff --git a/runtime/reflective_value_visitor.h b/runtime/reflective_value_visitor.h
index 0b09a0b..8823fcb 100644
--- a/runtime/reflective_value_visitor.h
+++ b/runtime/reflective_value_visitor.h
@@ -124,7 +124,10 @@
explicit ReflectiveHandleScopeSourceInfo(BaseReflectiveHandleScope* source)
: ReflectionSourceInfo(kSourceThreadHandleScope), source_(source) {}
- void Describe(std::ostream& os) const override;
+ void Describe(std::ostream& os) const override {
+ ReflectionSourceInfo::Describe(os);
+ os << " source=" << source_;
+ }
private:
BaseReflectiveHandleScope* source_;
diff --git a/runtime/runtime.cc b/runtime/runtime.cc
index 0c9aece..8f68b55 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -2198,7 +2198,6 @@
}
void Runtime::VisitReflectiveTargets(ReflectiveValueVisitor *visitor) {
- thread_list_->VisitReflectiveTargets(visitor);
heap_->VisitReflectiveTargets(visitor);
jni_id_manager_->VisitReflectiveTargets(visitor);
callbacks_->VisitReflectiveTargets(visitor);
diff --git a/runtime/thread.cc b/runtime/thread.cc
index 3aacfcb..088f997 100644
--- a/runtime/thread.cc
+++ b/runtime/thread.cc
@@ -98,7 +98,6 @@
#include "quick_exception_handler.h"
#include "read_barrier-inl.h"
#include "reflection.h"
-#include "reflective_handle_scope-inl.h"
#include "runtime-inl.h"
#include "runtime.h"
#include "runtime_callbacks.h"
@@ -3958,14 +3957,6 @@
const uint32_t tid_;
};
-void Thread::VisitReflectiveTargets(ReflectiveValueVisitor* visitor) {
- for (BaseReflectiveHandleScope* brhs = GetTopReflectiveHandleScope();
- brhs != nullptr;
- brhs = brhs->GetLink()) {
- brhs->VisitTargets(visitor);
- }
-}
-
template <bool kPrecise>
void Thread::VisitRoots(RootVisitor* visitor) {
const pid_t thread_id = GetThreadId();
diff --git a/runtime/thread.h b/runtime/thread.h
index 16ca2aa..22c9d06 100644
--- a/runtime/thread.h
+++ b/runtime/thread.h
@@ -40,7 +40,6 @@
#include "managed_stack.h"
#include "offsets.h"
#include "read_barrier_config.h"
-#include "reflective_handle_scope.h"
#include "runtime_globals.h"
#include "runtime_stats.h"
#include "thread_state.h"
@@ -636,9 +635,6 @@
void VisitRoots(RootVisitor* visitor, VisitRootFlags flags)
REQUIRES_SHARED(Locks::mutator_lock_);
- void VisitReflectiveTargets(ReflectiveValueVisitor* visitor)
- REQUIRES(Locks::mutator_lock_);
-
void VerifyStack() REQUIRES_SHARED(Locks::mutator_lock_) {
if (kVerifyStack) {
VerifyStackImpl();
@@ -896,23 +892,6 @@
top_handle_scope));
}
- BaseReflectiveHandleScope* GetTopReflectiveHandleScope() {
- return tlsPtr_.top_reflective_handle_scope;
- }
-
- void PushReflectiveHandleScope(BaseReflectiveHandleScope* scope) {
- DCHECK_EQ(scope->GetLink(), tlsPtr_.top_reflective_handle_scope);
- DCHECK_EQ(scope->GetThread(), this);
- tlsPtr_.top_reflective_handle_scope = scope;
- }
-
- BaseReflectiveHandleScope* PopReflectiveHandleScope() {
- BaseReflectiveHandleScope* handle_scope = tlsPtr_.top_reflective_handle_scope;
- DCHECK(handle_scope != nullptr);
- tlsPtr_.top_reflective_handle_scope = tlsPtr_.top_reflective_handle_scope->GetLink();
- return handle_scope;
- }
-
DebugInvokeReq* GetInvokeReq() const {
return tlsPtr_.debug_invoke_req;
}
@@ -1660,7 +1639,7 @@
thread_local_objects(0), mterp_current_ibase(nullptr), thread_local_alloc_stack_top(nullptr),
thread_local_alloc_stack_end(nullptr),
flip_function(nullptr), method_verifier(nullptr), thread_local_mark_stack(nullptr),
- async_exception(nullptr), top_reflective_handle_scope(nullptr) {
+ async_exception(nullptr) {
std::fill(held_mutexes, held_mutexes + kLockLevelCount, nullptr);
}
@@ -1818,9 +1797,6 @@
// The pending async-exception or null.
mirror::Throwable* async_exception;
-
- // Top of the linked-list for reflective-handle scopes or null if none.
- BaseReflectiveHandleScope* top_reflective_handle_scope;
} tlsPtr_;
// Small thread-local cache to be used from the interpreter.
diff --git a/runtime/thread_list.cc b/runtime/thread_list.cc
index 4e8f468..28bc184 100644
--- a/runtime/thread_list.cc
+++ b/runtime/thread_list.cc
@@ -1542,13 +1542,6 @@
}
}
-void ThreadList::VisitReflectiveTargets(ReflectiveValueVisitor *visitor) const {
- MutexLock mu(Thread::Current(), *Locks::thread_list_lock_);
- for (const auto& thread : list_) {
- thread->VisitReflectiveTargets(visitor);
- }
-}
-
uint32_t ThreadList::AllocThreadId(Thread* self) {
MutexLock mu(self, *Locks::allocated_thread_ids_lock_);
for (size_t i = 0; i < allocated_ids_.size(); ++i) {
diff --git a/runtime/thread_list.h b/runtime/thread_list.h
index dad896e..b5b4450 100644
--- a/runtime/thread_list.h
+++ b/runtime/thread_list.h
@@ -22,7 +22,6 @@
#include "base/mutex.h"
#include "base/value_object.h"
#include "jni.h"
-#include "reflective_handle_scope.h"
#include "suspend_reason.h"
#include <bitset>
@@ -174,8 +173,6 @@
REQUIRES(!Locks::thread_list_lock_, !Locks::thread_suspend_count_lock_)
REQUIRES_SHARED(Locks::mutator_lock_);
- void VisitReflectiveTargets(ReflectiveValueVisitor* visitor) const REQUIRES(Locks::mutator_lock_);
-
// Return a copy of the thread list.
std::list<Thread*> GetList() REQUIRES(Locks::thread_list_lock_) {
return list_;
diff --git a/test/1985-structural-redefine-stack-scope/expected.txt b/test/1985-structural-redefine-stack-scope/expected.txt
deleted file mode 100644
index 6a5618e..0000000
--- a/test/1985-structural-redefine-stack-scope/expected.txt
+++ /dev/null
@@ -1 +0,0 @@
-JNI_OnLoad called
diff --git a/test/1985-structural-redefine-stack-scope/info.txt b/test/1985-structural-redefine-stack-scope/info.txt
deleted file mode 100644
index a108013..0000000
--- a/test/1985-structural-redefine-stack-scope/info.txt
+++ /dev/null
@@ -1 +0,0 @@
-Tests StackReflectiveHandleScope.
diff --git a/test/1985-structural-redefine-stack-scope/run b/test/1985-structural-redefine-stack-scope/run
deleted file mode 100755
index a36de16..0000000
--- a/test/1985-structural-redefine-stack-scope/run
+++ /dev/null
@@ -1,18 +0,0 @@
-#!/bin/bash
-#
-# Copyright 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.
-
-# Ask for stack traces to be dumped to a file rather than to stdout.
-./default-run "$@" --jvmti --android-runtime-option -Xopaque-jni-ids:true
diff --git a/test/1985-structural-redefine-stack-scope/src/Main.java b/test/1985-structural-redefine-stack-scope/src/Main.java
deleted file mode 100644
index cb86c3d..0000000
--- a/test/1985-structural-redefine-stack-scope/src/Main.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (C) 2019 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 art.Redefinition;
-import java.lang.invoke.*;
-import java.lang.reflect.Field;
-import java.util.Base64;
-
-public class Main {
- public static final class Transform {
- static {
- }
-
- public static Object foo = null;
- }
-
- /**
- * Base64 encoded dex bytes for:
- * public static final class Transform {
- * static {}
- * public static Object bar = null;
- * public static Object foo = null;
- * }
- */
- public static final byte[] DEX_BYTES =
- Base64.getDecoder()
- .decode(
- "ZGV4CjAzNQCjkRjcSr1RJO8FnnCjHV/8h6keJP/+P3WQAwAAcAAAAHhWNBIAAAAAAAAAANgCAAAQ"
- + "AAAAcAAAAAYAAACwAAAAAQAAAMgAAAACAAAA1AAAAAMAAADkAAAAAQAAAPwAAAB0AgAAHAEAAFwB"
- + "AABmAQAAbgEAAIABAACIAQAArAEAAMwBAADgAQAA6wEAAPYBAAD5AQAABgIAAAsCAAAQAgAAFgIA"
- + "AB0CAAACAAAAAwAAAAQAAAAFAAAABgAAAAkAAAAJAAAABQAAAAAAAAAAAAQACwAAAAAABAAMAAAA"
- + "AAAAAAAAAAAAAAAAAQAAAAQAAAABAAAAAAAAABEAAAAEAAAAAAAAAAcAAADIAgAApAIAAAAAAAAB"
- + "AAAAAAAAAFABAAAGAAAAEgBpAAAAaQABAA4AAQABAAEAAABVAQAABAAAAHAQAgAAAA4ABwAOPAAF"
- + "AA4AAAAACDxjbGluaXQ+AAY8aW5pdD4AEExNYWluJFRyYW5zZm9ybTsABkxNYWluOwAiTGRhbHZp"
- + "ay9hbm5vdGF0aW9uL0VuY2xvc2luZ0NsYXNzOwAeTGRhbHZpay9hbm5vdGF0aW9uL0lubmVyQ2xh"
- + "c3M7ABJMamF2YS9sYW5nL09iamVjdDsACU1haW4uamF2YQAJVHJhbnNmb3JtAAFWAAthY2Nlc3NG"
- + "bGFncwADYmFyAANmb28ABG5hbWUABXZhbHVlAHZ+fkQ4eyJjb21waWxhdGlvbi1tb2RlIjoiZGVi"
- + "dWciLCJtaW4tYXBpIjoxLCJzaGEtMSI6IjI4YmNlZjUwYWM4NTk3Y2YyMmU4OTJiMWJjM2EzYjky"
- + "Yjc0ZTcwZTkiLCJ2ZXJzaW9uIjoiMS42LjMyLWRldiJ9AAICAQ4YAQIDAgoEGQ0XCAIAAgAACQEJ"
- + "AIiABJwCAYGABLgCAAAAAAIAAACVAgAAmwIAALwCAAAAAAAAAAAAAAAAAAAPAAAAAAAAAAEAAAAA"
- + "AAAAAQAAABAAAABwAAAAAgAAAAYAAACwAAAAAwAAAAEAAADIAAAABAAAAAIAAADUAAAABQAAAAMA"
- + "AADkAAAABgAAAAEAAAD8AAAAASAAAAIAAAAcAQAAAyAAAAIAAABQAQAAAiAAABAAAABcAQAABCAA"
- + "AAIAAACVAgAAACAAAAEAAACkAgAAAxAAAAIAAAC4AgAABiAAAAEAAADIAgAAABAAAAEAAADYAgAA");
-
- public static void assertEquals(Object a, Object b) {
- if (a != b) {
- throw new Error("Expected " + b + ", got " + a);
- }
- }
-
- public static void main(String[] args) throws Exception, Throwable {
- System.loadLibrary(args[0]);
- Field f = Transform.class.getDeclaredField("foo");
- Transform.foo = "THIS IS A FOO VALUE";
- assertEquals(f.get(null), Transform.foo);
- MethodHandle j =
- NativeFieldScopeCheck(
- f,
- () -> {
- Redefinition.doCommonStructuralClassRedefinition(Transform.class, DEX_BYTES);
- });
- assertEquals(j.invokeExact(), Transform.foo);
- }
-
- // Hold the field as a ArtField, run the 'test' function, turn the ArtField into a MethodHandle
- // directly and return that.
- public static native MethodHandle NativeFieldScopeCheck(Field in, Runnable test);
-}
diff --git a/test/1985-structural-redefine-stack-scope/src/art/Redefinition.java b/test/1985-structural-redefine-stack-scope/src/art/Redefinition.java
deleted file mode 120000
index 81eaf31..0000000
--- a/test/1985-structural-redefine-stack-scope/src/art/Redefinition.java
+++ /dev/null
@@ -1 +0,0 @@
-../../../jvmti-common/Redefinition.java
\ No newline at end of file
diff --git a/test/1985-structural-redefine-stack-scope/stack_scope.cc b/test/1985-structural-redefine-stack-scope/stack_scope.cc
deleted file mode 100644
index 5c5215b..0000000
--- a/test/1985-structural-redefine-stack-scope/stack_scope.cc
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2019 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 <cstdio>
-#include <memory>
-#include <mutex>
-#include <string>
-#include <vector>
-
-#include "class_linker.h"
-#include "class_root.h"
-#include "jni.h"
-#include "jni/jni_internal.h"
-#include "mirror/class.h"
-#include "mirror/method_handle_impl.h"
-#include "mirror/object-inl.h"
-#include "mirror/object_array-alloc-inl.h"
-#include "reflection.h"
-#include "reflective_handle.h"
-#include "reflective_handle_scope-inl.h"
-#include "runtime.h"
-#include "scoped_thread_state_change-inl.h"
-#include "thread-inl.h"
-
-namespace art {
-namespace Test1985StructuralRedefineStackScope {
-
-extern "C" JNICALL jobject JNIEXPORT Java_Main_NativeFieldScopeCheck(JNIEnv* env,
- jclass,
- jobject field,
- jobject runnable) {
- jfieldID fid = env->FromReflectedField(field);
- jclass runnable_klass = env->FindClass("java/lang/Runnable");
- jmethodID run = env->GetMethodID(runnable_klass, "run", "()V");
- ScopedObjectAccess soa(Thread::Current());
- StackHandleScope<4> hs(soa.Self());
- StackArtFieldHandleScope<1> fhs(soa.Self());
- StackArtFieldHandleScope<1> bhs(soa.Self());
- ReflectiveHandle<ArtField> rf(fhs.NewHandle(jni::DecodeArtField(fid)));
- ReflectiveHandle<ArtField> bf(bhs.NewHandle(jni::DecodeArtField(fid)));
- ArtField* pre_ptr = rf.Get();
- {
- ScopedThreadSuspension sts(soa.Self(), ThreadState::kNative);
- // Upcall to perform redefinition.
- env->CallVoidMethod(runnable, run);
- }
- Handle<mirror::ObjectArray<mirror::Class>> mt_arr(
- hs.NewHandle(mirror::ObjectArray<mirror::Class>::Alloc(
- soa.Self(),
- Runtime::Current()->GetClassLinker()->FindArrayClass(soa.Self(),
- GetClassRoot<mirror::Class>()),
- 0)));
- Handle<mirror::MethodType> mt(hs.NewHandle(mirror::MethodType::Create(
- soa.Self(), hs.NewHandle(GetClassRoot<mirror::Object>()), mt_arr)));
- Handle<mirror::MethodHandleImpl> mhi(hs.NewHandle(
- mirror::MethodHandleImpl::Create(soa.Self(),
- reinterpret_cast<uintptr_t>(rf.Get()),
- (rf->IsStatic() ? mirror::MethodHandle::Kind::kStaticGet
- : mirror::MethodHandle::Kind::kInstanceGet),
- mt)));
- CHECK_EQ(rf.Get(), bf.Get()) << "rf: " << rf->PrettyField() << " bf: " << bf->PrettyField();
- // TODO Modify this to work for when run doesn't cause a change.
- CHECK_NE(pre_ptr, rf.Get()) << "pre_ptr: " << pre_ptr->PrettyField()
- << " rf: " << rf->PrettyField();
- CHECK_EQ(fid, jni::EncodeArtField(rf));
- return soa.AddLocalReference<jobject>(mhi.Get());
-}
-
-} // namespace Test1985StructuralRedefineStackScope
-} // namespace art
diff --git a/test/1986-structural-redefine-multi-thread-stack-scope/expected.txt b/test/1986-structural-redefine-multi-thread-stack-scope/expected.txt
deleted file mode 100644
index 6a5618e..0000000
--- a/test/1986-structural-redefine-multi-thread-stack-scope/expected.txt
+++ /dev/null
@@ -1 +0,0 @@
-JNI_OnLoad called
diff --git a/test/1986-structural-redefine-multi-thread-stack-scope/info.txt b/test/1986-structural-redefine-multi-thread-stack-scope/info.txt
deleted file mode 100644
index 184bd72..0000000
--- a/test/1986-structural-redefine-multi-thread-stack-scope/info.txt
+++ /dev/null
@@ -1 +0,0 @@
-Tests StackReflectiveHandleScope works when there are several all in different threads.
diff --git a/test/1986-structural-redefine-multi-thread-stack-scope/run b/test/1986-structural-redefine-multi-thread-stack-scope/run
deleted file mode 100755
index a36de16..0000000
--- a/test/1986-structural-redefine-multi-thread-stack-scope/run
+++ /dev/null
@@ -1,18 +0,0 @@
-#!/bin/bash
-#
-# Copyright 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.
-
-# Ask for stack traces to be dumped to a file rather than to stdout.
-./default-run "$@" --jvmti --android-runtime-option -Xopaque-jni-ids:true
diff --git a/test/1986-structural-redefine-multi-thread-stack-scope/src/Main.java b/test/1986-structural-redefine-multi-thread-stack-scope/src/Main.java
deleted file mode 100644
index 23b1656..0000000
--- a/test/1986-structural-redefine-multi-thread-stack-scope/src/Main.java
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * Copyright (C) 2019 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 art.Redefinition;
-import java.lang.invoke.*;
-import java.lang.reflect.Field;
-import java.util.Base64;
-import java.util.concurrent.CountDownLatch;
-
-public class Main {
- public static final class Transform {
- static {
- }
-
- public static Object foo = null;
- }
-
- /**
- * Base64 encoded dex bytes for:
- *
- * public static final class Transform {
- * static {}
- * public static Object bar = null;
- * public static Object foo = null;
- * }
- */
- public static final byte[] DEX_BYTES =
- Base64.getDecoder()
- .decode(
- "ZGV4CjAzNQCjkRjcSr1RJO8FnnCjHV/8h6keJP/+P3WQAwAAcAAAAHhWNBIAAAAAAAAAANgCAAAQ"
- + "AAAAcAAAAAYAAACwAAAAAQAAAMgAAAACAAAA1AAAAAMAAADkAAAAAQAAAPwAAAB0AgAAHAEAAFwB"
- + "AABmAQAAbgEAAIABAACIAQAArAEAAMwBAADgAQAA6wEAAPYBAAD5AQAABgIAAAsCAAAQAgAAFgIA"
- + "AB0CAAACAAAAAwAAAAQAAAAFAAAABgAAAAkAAAAJAAAABQAAAAAAAAAAAAQACwAAAAAABAAMAAAA"
- + "AAAAAAAAAAAAAAAAAQAAAAQAAAABAAAAAAAAABEAAAAEAAAAAAAAAAcAAADIAgAApAIAAAAAAAAB"
- + "AAAAAAAAAFABAAAGAAAAEgBpAAAAaQABAA4AAQABAAEAAABVAQAABAAAAHAQAgAAAA4ABwAOPAAF"
- + "AA4AAAAACDxjbGluaXQ+AAY8aW5pdD4AEExNYWluJFRyYW5zZm9ybTsABkxNYWluOwAiTGRhbHZp"
- + "ay9hbm5vdGF0aW9uL0VuY2xvc2luZ0NsYXNzOwAeTGRhbHZpay9hbm5vdGF0aW9uL0lubmVyQ2xh"
- + "c3M7ABJMamF2YS9sYW5nL09iamVjdDsACU1haW4uamF2YQAJVHJhbnNmb3JtAAFWAAthY2Nlc3NG"
- + "bGFncwADYmFyAANmb28ABG5hbWUABXZhbHVlAHZ+fkQ4eyJjb21waWxhdGlvbi1tb2RlIjoiZGVi"
- + "dWciLCJtaW4tYXBpIjoxLCJzaGEtMSI6IjI4YmNlZjUwYWM4NTk3Y2YyMmU4OTJiMWJjM2EzYjky"
- + "Yjc0ZTcwZTkiLCJ2ZXJzaW9uIjoiMS42LjMyLWRldiJ9AAICAQ4YAQIDAgoEGQ0XCAIAAgAACQEJ"
- + "AIiABJwCAYGABLgCAAAAAAIAAACVAgAAmwIAALwCAAAAAAAAAAAAAAAAAAAPAAAAAAAAAAEAAAAA"
- + "AAAAAQAAABAAAABwAAAAAgAAAAYAAACwAAAAAwAAAAEAAADIAAAABAAAAAIAAADUAAAABQAAAAMA"
- + "AADkAAAABgAAAAEAAAD8AAAAASAAAAIAAAAcAQAAAyAAAAIAAABQAQAAAiAAABAAAABcAQAABCAA"
- + "AAIAAACVAgAAACAAAAEAAACkAgAAAxAAAAIAAAC4AgAABiAAAAEAAADIAgAAABAAAAEAAADYAgAA");
-
- public static void assertEquals(Object a, Object b) {
- if (a != b) {
- throw new Error("Expected " + b + ", got " + a);
- }
- }
-
- public static void assertAllEquals(Object[] a, Object b) {
- boolean failed = false;
- String msg = "";
- for (int i = 0; i < a.length; i++) {
- if (a[i] != b) {
- failed = true;
- msg += "Expected " + b + ", got a[" + i + "] (" + a[i] + "), ";
- }
- }
- if (failed) {
- throw new Error(msg);
- }
- }
-
- public static void main(String[] args) throws Exception, Throwable {
- System.loadLibrary(args[0]);
- Field f = Transform.class.getDeclaredField("foo");
- Transform.foo = "THIS IS A FOO VALUE";
- assertEquals(f.get(null), Transform.foo);
- final int num_threads = 10;
- Object[] results = new Object[num_threads];
- Thread[] threads = new Thread[num_threads];
- CountDownLatch start_latch = new CountDownLatch(num_threads);
- CountDownLatch continue_latch = new CountDownLatch(1);
- for (int i = 0; i < num_threads; i++) {
- final int id = i;
- threads[id] =
- new Thread(
- () -> {
- try {
- MethodHandle mh =
- NativeFieldScopeCheck(
- f,
- () -> {
- try {
- start_latch.countDown();
- continue_latch.await();
- } catch (Exception e) {
- throw new Error("failed!", e);
- }
- });
- results[id] = mh.invokeExact();
- } catch (Throwable t) {
- throw new Error("Failed", t);
- }
- },
- "Target thread " + id);
- threads[id].start();
- }
- start_latch.await();
- Redefinition.doCommonStructuralClassRedefinition(Transform.class, DEX_BYTES);
- continue_latch.countDown();
- for (Thread t : threads) {
- t.join();
- }
- assertAllEquals(results, Transform.foo);
- }
-
- // Hold the field as a ArtField, run the 'test' function, turn the ArtField into a MethodHandle
- // directly and return that.
- public static native MethodHandle NativeFieldScopeCheck(Field in, Runnable test);
-}
diff --git a/test/1986-structural-redefine-multi-thread-stack-scope/src/art/Redefinition.java b/test/1986-structural-redefine-multi-thread-stack-scope/src/art/Redefinition.java
deleted file mode 120000
index 81eaf31..0000000
--- a/test/1986-structural-redefine-multi-thread-stack-scope/src/art/Redefinition.java
+++ /dev/null
@@ -1 +0,0 @@
-../../../jvmti-common/Redefinition.java
\ No newline at end of file
diff --git a/test/1987-structural-redefine-recurisive-stack-scope/expected.txt b/test/1987-structural-redefine-recurisive-stack-scope/expected.txt
deleted file mode 100644
index 288bed8..0000000
--- a/test/1987-structural-redefine-recurisive-stack-scope/expected.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-JNI_OnLoad called
-Foo value is THIS IS A FOO VALUE
-Result at depth 0: THIS IS A FOO VALUE
-Result at depth 1: THIS IS A FOO VALUE
-Result at depth 2: THIS IS A FOO VALUE
-Result at depth 3: THIS IS A FOO VALUE
-Result at depth 4: THIS IS A FOO VALUE
-Result at depth 5: THIS IS A FOO VALUE
-Result at depth 6: THIS IS A FOO VALUE
-Result at depth 7: THIS IS A FOO VALUE
-Result at depth 8: THIS IS A FOO VALUE
-Result at depth 9: THIS IS A FOO VALUE
diff --git a/test/1987-structural-redefine-recurisive-stack-scope/info.txt b/test/1987-structural-redefine-recurisive-stack-scope/info.txt
deleted file mode 100644
index f841897..0000000
--- a/test/1987-structural-redefine-recurisive-stack-scope/info.txt
+++ /dev/null
@@ -1 +0,0 @@
-Tests StackReflectiveHandleScope works when there are several all in different recursive frames.
diff --git a/test/1987-structural-redefine-recurisive-stack-scope/run b/test/1987-structural-redefine-recurisive-stack-scope/run
deleted file mode 100755
index a36de16..0000000
--- a/test/1987-structural-redefine-recurisive-stack-scope/run
+++ /dev/null
@@ -1,18 +0,0 @@
-#!/bin/bash
-#
-# Copyright 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.
-
-# Ask for stack traces to be dumped to a file rather than to stdout.
-./default-run "$@" --jvmti --android-runtime-option -Xopaque-jni-ids:true
diff --git a/test/1987-structural-redefine-recurisive-stack-scope/src/Main.java b/test/1987-structural-redefine-recurisive-stack-scope/src/Main.java
deleted file mode 100644
index 2c53057..0000000
--- a/test/1987-structural-redefine-recurisive-stack-scope/src/Main.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2019 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 art.Redefinition;
-import java.lang.invoke.*;
-import java.lang.reflect.Field;
-import java.util.Base64;
-
-public class Main {
- public static final class Transform {
- static {
- }
-
- public static Object foo = null;
- }
-
- /* Base64 encoded dex bytes for:
- *
- * public static final class Transform {
- * static {}
- * public static Object bar = null;
- * public static Object foo = null;
- * }
- */
- public static final byte[] DEX_BYTES =
- Base64.getDecoder()
- .decode(
- "ZGV4CjAzNQCjkRjcSr1RJO8FnnCjHV/8h6keJP/+P3WQAwAAcAAAAHhWNBIAAAAAAAAAANgCAAAQ"
- + "AAAAcAAAAAYAAACwAAAAAQAAAMgAAAACAAAA1AAAAAMAAADkAAAAAQAAAPwAAAB0AgAAHAEAAFwB"
- + "AABmAQAAbgEAAIABAACIAQAArAEAAMwBAADgAQAA6wEAAPYBAAD5AQAABgIAAAsCAAAQAgAAFgIA"
- + "AB0CAAACAAAAAwAAAAQAAAAFAAAABgAAAAkAAAAJAAAABQAAAAAAAAAAAAQACwAAAAAABAAMAAAA"
- + "AAAAAAAAAAAAAAAAAQAAAAQAAAABAAAAAAAAABEAAAAEAAAAAAAAAAcAAADIAgAApAIAAAAAAAAB"
- + "AAAAAAAAAFABAAAGAAAAEgBpAAAAaQABAA4AAQABAAEAAABVAQAABAAAAHAQAgAAAA4ABwAOPAAF"
- + "AA4AAAAACDxjbGluaXQ+AAY8aW5pdD4AEExNYWluJFRyYW5zZm9ybTsABkxNYWluOwAiTGRhbHZp"
- + "ay9hbm5vdGF0aW9uL0VuY2xvc2luZ0NsYXNzOwAeTGRhbHZpay9hbm5vdGF0aW9uL0lubmVyQ2xh"
- + "c3M7ABJMamF2YS9sYW5nL09iamVjdDsACU1haW4uamF2YQAJVHJhbnNmb3JtAAFWAAthY2Nlc3NG"
- + "bGFncwADYmFyAANmb28ABG5hbWUABXZhbHVlAHZ+fkQ4eyJjb21waWxhdGlvbi1tb2RlIjoiZGVi"
- + "dWciLCJtaW4tYXBpIjoxLCJzaGEtMSI6IjI4YmNlZjUwYWM4NTk3Y2YyMmU4OTJiMWJjM2EzYjky"
- + "Yjc0ZTcwZTkiLCJ2ZXJzaW9uIjoiMS42LjMyLWRldiJ9AAICAQ4YAQIDAgoEGQ0XCAIAAgAACQEJ"
- + "AIiABJwCAYGABLgCAAAAAAIAAACVAgAAmwIAALwCAAAAAAAAAAAAAAAAAAAPAAAAAAAAAAEAAAAA"
- + "AAAAAQAAABAAAABwAAAAAgAAAAYAAACwAAAAAwAAAAEAAADIAAAABAAAAAIAAADUAAAABQAAAAMA"
- + "AADkAAAABgAAAAEAAAD8AAAAASAAAAIAAAAcAQAAAyAAAAIAAABQAQAAAiAAABAAAABcAQAABCAA"
- + "AAIAAACVAgAAACAAAAEAAACkAgAAAxAAAAIAAAC4AgAABiAAAAEAAADIAgAAABAAAAEAAADYAgAA");
-
- public static void main(String[] args) throws Exception, Throwable {
- System.loadLibrary(args[0]);
- Field f = Transform.class.getDeclaredField("foo");
- Transform.foo = "THIS IS A FOO VALUE";
- System.out.println("Foo value is " + f.get(null));
- final int max_depth = 10;
- Object[] results = new Object[max_depth];
- Runnable res =
- () -> {
- Redefinition.doCommonStructuralClassRedefinition(Transform.class, DEX_BYTES);
- };
- for (int i = 0; i < max_depth; i++) {
- final Runnable next = res;
- final int id = i;
- res =
- () -> {
- try {
- results[id] = NativeFieldScopeCheck(f, next).invokeExact();
- } catch (Throwable t) {
- throw new Error("Failed!", t);
- }
- };
- }
- res.run();
- for (int i = 0; i < max_depth; i++) {
- System.out.println("Result at depth " + i + ": " + results[i]);
- }
- }
-
- // Hold the field as a ArtField, run the 'test' function, turn the ArtField into a MethodHandle
- // directly and return that.
- public static native MethodHandle NativeFieldScopeCheck(Field in, Runnable test);
-}
diff --git a/test/1987-structural-redefine-recurisive-stack-scope/src/art/Redefinition.java b/test/1987-structural-redefine-recurisive-stack-scope/src/art/Redefinition.java
deleted file mode 120000
index 81eaf31..0000000
--- a/test/1987-structural-redefine-recurisive-stack-scope/src/art/Redefinition.java
+++ /dev/null
@@ -1 +0,0 @@
-../../../jvmti-common/Redefinition.java
\ No newline at end of file
diff --git a/test/Android.bp b/test/Android.bp
index ac83a5d..66a08e9 100644
--- a/test/Android.bp
+++ b/test/Android.bp
@@ -518,7 +518,6 @@
"1002-notify-startup/startup_interface.cc",
"1947-breakpoint-redefine-deopt/check_deopt.cc",
"1972-jni-id-swap-indices/jni_id.cc",
- "1985-structural-redefine-stack-scope/stack_scope.cc",
"common/runtime_state.cc",
"common/stack_inspect.cc",
],