diff options
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) { |