summaryrefslogtreecommitdiff
path: root/runtime/class_linker.cc
diff options
context:
space:
mode:
author Alex Light <allight@google.com> 2019-11-13 09:33:52 -0800
committer Treehugger Robot <treehugger-gerrit@google.com> 2019-11-26 02:11:19 +0000
commitc47040d31cbcd8cddd5fadb552b4f0f6c94b5bd0 (patch)
tree50df569420cd6746daadf1487933719d1f86d66b /runtime/class_linker.cc
parentdc540dfffb6863177143d024dd6f491775d77585 (diff)
Allow structural redefinition on non-final classes.
This adds support for structurally redefining non-final, non-finalizable classes. The only restriction is that one cannot redefine a class at the same time as any of its supertypes, if a structural redefinition is occurring. The structural redefinition may not remove any fields or methods, change the superclass or change the implemented interfaces. Adding new methods or fields, both static or non-static, public, private, protected, or package-private, is supported. Test: ./test.py --host Bug: 134162467 Bug: 144168550 Change-Id: I32e9e854b3e56270170b10e8f5aba9de8f6bfdfa
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);