Clean up ZygoteHooks stack walking slightly.
Test: Build and run marlin with libartd.so
Change-Id: I4a67935c5c7270636085c3ee12db0ebc1798a89e
diff --git a/runtime/native/dalvik_system_ZygoteHooks.cc b/runtime/native/dalvik_system_ZygoteHooks.cc
index bb92ca7..836ba81 100644
--- a/runtime/native/dalvik_system_ZygoteHooks.cc
+++ b/runtime/native/dalvik_system_ZygoteHooks.cc
@@ -76,24 +76,29 @@
class ClassSet {
public:
- explicit ClassSet(Thread* const self) : hs_(self) {}
+ // The number of classes we reasonably expect to have to look at. Realistically the number is more
+ // ~10 but there is little harm in having some extra.
+ static constexpr int kClassSetCapacity = 100;
- void AddClass(ObjPtr<mirror::Class> klass) REQUIRES(Locks::mutator_lock_) {
- for (Handle<mirror::Class> k : class_set_) {
- if (k.Get() == klass.Ptr()) {
- return;
- }
- }
- class_set_.push_back(hs_.NewHandle<mirror::Class>(klass));
+ explicit ClassSet(Thread* const self) : self_(self) {
+ self_->GetJniEnv()->PushFrame(kClassSetCapacity);
}
- const std::vector<Handle<mirror::Class>>& GetClasses() const {
+ ~ClassSet() {
+ self_->GetJniEnv()->PopFrame();
+ }
+
+ void AddClass(ObjPtr<mirror::Class> klass) REQUIRES(Locks::mutator_lock_) {
+ class_set_.insert(self_->GetJniEnv()->AddLocalReference<jclass>(klass.Ptr()));
+ }
+
+ const std::unordered_set<jclass>& GetClasses() const {
return class_set_;
}
private:
- VariableSizedHandleScope hs_;
- std::vector<Handle<mirror::Class>> class_set_;
+ Thread* const self_;
+ std::unordered_set<jclass> class_set_;
};
static void DoCollectNonDebuggableCallback(Thread* thread, void* data)
@@ -133,20 +138,15 @@
ScopedObjectAccess soa(self);
ClassSet classes(self);
{
- // Drop the mutator lock.
- self->TransitionFromRunnableToSuspended(art::ThreadState::kNative);
- {
- // Get it back with a suspend all.
- ScopedSuspendAll suspend("Checking stacks for non-obsoletable methods!",
- /*long_suspend*/false);
- MutexLock mu(Thread::Current(), *Locks::thread_list_lock_);
- runtime->GetThreadList()->ForEach(DoCollectNonDebuggableCallback, &classes);
- }
- // Recover the shared lock before we leave this scope.
- self->TransitionFromSuspendedToRunnable();
+ // Drop the shared mutator lock.
+ ScopedThreadSuspension sts(self, art::ThreadState::kNative);
+ // Get exclusive mutator lock with suspend all.
+ ScopedSuspendAll suspend("Checking stacks for non-obsoletable methods!", /*long_suspend*/false);
+ MutexLock mu(Thread::Current(), *Locks::thread_list_lock_);
+ runtime->GetThreadList()->ForEach(DoCollectNonDebuggableCallback, &classes);
}
- for (Handle<mirror::Class> klass : classes.GetClasses()) {
- NonDebuggableClasses::AddNonDebuggableClass(klass.Get());
+ for (jclass klass : classes.GetClasses()) {
+ NonDebuggableClasses::AddNonDebuggableClass(klass);
}
}
diff --git a/runtime/non_debuggable_classes.cc b/runtime/non_debuggable_classes.cc
index db121a9..829ea65 100644
--- a/runtime/non_debuggable_classes.cc
+++ b/runtime/non_debuggable_classes.cc
@@ -27,16 +27,16 @@
std::vector<jclass> NonDebuggableClasses::non_debuggable_classes;
-void NonDebuggableClasses::AddNonDebuggableClass(ObjPtr<mirror::Class> klass) {
+void NonDebuggableClasses::AddNonDebuggableClass(jclass klass) {
Thread* self = Thread::Current();
JNIEnvExt* env = self->GetJniEnv();
+ ObjPtr<mirror::Class> mirror_klass(self->DecodeJObject(klass)->AsClass());
for (jclass c : non_debuggable_classes) {
- if (self->DecodeJObject(c)->AsClass() == klass.Ptr()) {
+ if (self->DecodeJObject(c)->AsClass() == mirror_klass.Ptr()) {
return;
}
}
- ScopedLocalRef<jclass> lr(env, env->AddLocalReference<jclass>(klass));
- non_debuggable_classes.push_back(reinterpret_cast<jclass>(env->NewGlobalRef(lr.get())));
+ non_debuggable_classes.push_back(reinterpret_cast<jclass>(env->NewGlobalRef(klass)));
}
} // namespace art
diff --git a/runtime/non_debuggable_classes.h b/runtime/non_debuggable_classes.h
index 0c94dc0..e1b5633 100644
--- a/runtime/non_debuggable_classes.h
+++ b/runtime/non_debuggable_classes.h
@@ -21,21 +21,16 @@
#include "base/mutex.h"
#include "jni.h"
-#include "obj_ptr.h"
namespace art {
-namespace mirror {
-class Class;
-} // namespace mirror
-
struct NonDebuggableClasses {
public:
static const std::vector<jclass>& GetNonDebuggableClasses() {
return non_debuggable_classes;
}
- static void AddNonDebuggableClass(ObjPtr<mirror::Class> klass)
+ static void AddNonDebuggableClass(jclass klass)
REQUIRES_SHARED(Locks::mutator_lock_);
private: