diff options
author | 2017-06-16 08:58:34 -0700 | |
---|---|---|
committer | 2017-06-19 10:20:32 -0700 | |
commit | 084fa370a14edc43dcf8ff4e454e04c863e1a130 (patch) | |
tree | d616c178536092d546fcfeb10734df1a1d8bfcc1 /runtime/common_dex_operations.h | |
parent | 8b0673f022711bc725b63517bf338447a00cb45c (diff) |
Add field access & modify JVMTI callbacks
This adds support for the FieldAccess and FieldModification callbacks
in JVMTI and all other functions and behaviors associated with the
can_generate_field_modification_events and
can_generate_field_access_events capabilities.
Tests follow in the next CL.
Bug: 34409228
Test: ./test.py --host -j40
Change-Id: Id18fc53677cc1f96e1460c498ade7607219d5a79
Diffstat (limited to 'runtime/common_dex_operations.h')
-rw-r--r-- | runtime/common_dex_operations.h | 21 |
1 files changed, 16 insertions, 5 deletions
diff --git a/runtime/common_dex_operations.h b/runtime/common_dex_operations.h index 133ddb0721..528db96dd5 100644 --- a/runtime/common_dex_operations.h +++ b/runtime/common_dex_operations.h @@ -62,7 +62,7 @@ inline void PerformCall(Thread* self, } template<Primitive::Type field_type> -static ALWAYS_INLINE void DoFieldGetCommon(Thread* self, +static ALWAYS_INLINE bool DoFieldGetCommon(Thread* self, const ShadowFrame& shadow_frame, ObjPtr<mirror::Object> obj, ArtField* field, @@ -85,6 +85,9 @@ static ALWAYS_INLINE void DoFieldGetCommon(Thread* self, shadow_frame.GetMethod(), shadow_frame.GetDexPC(), field); + if (UNLIKELY(self->IsExceptionPending())) { + return false; + } } switch (field_type) { @@ -113,6 +116,7 @@ static ALWAYS_INLINE void DoFieldGetCommon(Thread* self, LOG(FATAL) << "Unreachable " << field_type; break; } + return true; } template<Primitive::Type field_type, bool do_assignability_check, bool transaction_active> @@ -120,7 +124,7 @@ ALWAYS_INLINE bool DoFieldPutCommon(Thread* self, const ShadowFrame& shadow_frame, ObjPtr<mirror::Object> obj, ArtField* field, - const JValue& value) + JValue& value) REQUIRES_SHARED(Locks::mutator_lock_) { field->GetDeclaringClass()->AssertInitializedOrInitializingInThread(self); @@ -128,15 +132,22 @@ ALWAYS_INLINE bool DoFieldPutCommon(Thread* self, // the field from the base of the object, we need to look for it first. instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation(); if (UNLIKELY(instrumentation->HasFieldWriteListeners())) { - StackHandleScope<1> hs(self); - // Wrap in handle wrapper in case the listener does thread suspension. + StackHandleScope<2> hs(self); + // Save this and return value (if needed) in case the instrumentation causes a suspend. HandleWrapperObjPtr<mirror::Object> h(hs.NewHandleWrapper(&obj)); ObjPtr<mirror::Object> this_object = field->IsStatic() ? nullptr : obj; - instrumentation->FieldWriteEvent(self, this_object.Ptr(), + mirror::Object* fake_root = nullptr; + HandleWrapper<mirror::Object> ret(hs.NewHandleWrapper<mirror::Object>( + field_type == Primitive::kPrimNot ? value.GetGCRoot() : &fake_root)); + instrumentation->FieldWriteEvent(self, + this_object.Ptr(), shadow_frame.GetMethod(), shadow_frame.GetDexPC(), field, value); + if (UNLIKELY(self->IsExceptionPending())) { + return false; + } } switch (field_type) { |