summaryrefslogtreecommitdiff
path: root/runtime/class_linker.cc
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/class_linker.cc')
-rw-r--r--runtime/class_linker.cc19
1 files changed, 19 insertions, 0 deletions
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 438d5cb709..d4f98afe84 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -3359,12 +3359,31 @@ static bool IsReservedBootClassPathDescriptor(const char* descriptor) {
StartsWith(descriptor_sv, "Landroid/media/");
}
+// Helper for maintaining DefineClass counting. We need to notify callbacks when we start/end a
+// define-class and how many recursive DefineClasses we are at in order to allow for doing things
+// like pausing class definition.
+struct ScopedDefiningClass {
+ public:
+ explicit ScopedDefiningClass(Thread* self) REQUIRES_SHARED(Locks::mutator_lock_) : self_(self) {
+ Runtime::Current()->GetRuntimeCallbacks()->BeginDefineClass();
+ self_->IncrDefineClassCount();
+ }
+ ~ScopedDefiningClass() REQUIRES_SHARED(Locks::mutator_lock_) {
+ self_->DecrDefineClassCount();
+ Runtime::Current()->GetRuntimeCallbacks()->EndDefineClass();
+ }
+
+ private:
+ Thread* self_;
+};
+
ObjPtr<mirror::Class> ClassLinker::DefineClass(Thread* self,
const char* descriptor,
size_t hash,
Handle<mirror::ClassLoader> class_loader,
const DexFile& dex_file,
const dex::ClassDef& dex_class_def) {
+ ScopedDefiningClass sdc(self);
StackHandleScope<3> hs(self);
auto klass = hs.NewHandle<mirror::Class>(nullptr);