diff options
| -rw-r--r-- | runtime/entrypoints/entrypoint_utils-inl.h | 6 | ||||
| -rw-r--r-- | runtime/entrypoints/entrypoint_utils.h | 7 | ||||
| -rw-r--r-- | runtime/entrypoints/quick/quick_field_entrypoints.cc | 358 |
3 files changed, 220 insertions, 151 deletions
diff --git a/runtime/entrypoints/entrypoint_utils-inl.h b/runtime/entrypoints/entrypoint_utils-inl.h index 51611753c8..7e7d904a10 100644 --- a/runtime/entrypoints/entrypoint_utils-inl.h +++ b/runtime/entrypoints/entrypoint_utils-inl.h @@ -299,8 +299,10 @@ inline mirror::Array* AllocArrayFromCodeResolved(mirror::Class* klass, } template<FindFieldType type, bool access_check> -inline ArtField* FindFieldFromCode(uint32_t field_idx, ArtMethod* referrer, - Thread* self, size_t expected_size) { +inline ArtField* FindFieldFromCode(uint32_t field_idx, + ArtMethod* referrer, + Thread* self, + size_t expected_size) REQUIRES(!Roles::uninterruptible_) { bool is_primitive; bool is_set; bool is_static; diff --git a/runtime/entrypoints/entrypoint_utils.h b/runtime/entrypoints/entrypoint_utils.h index a28376fadf..455e53f750 100644 --- a/runtime/entrypoints/entrypoint_utils.h +++ b/runtime/entrypoints/entrypoint_utils.h @@ -133,6 +133,13 @@ enum FindFieldType { StaticPrimitiveWrite, }; +inline constexpr bool FindFieldTypeIsRead(FindFieldType type) { + return type == InstanceObjectRead || + type == InstancePrimitiveRead || + type == StaticObjectRead || + type == StaticPrimitiveRead; +} + template<FindFieldType type, bool access_check> inline ArtField* FindFieldFromCode( uint32_t field_idx, ArtMethod* referrer, Thread* self, size_t expected_size) diff --git a/runtime/entrypoints/quick/quick_field_entrypoints.cc b/runtime/entrypoints/quick/quick_field_entrypoints.cc index 185025412a..bb90667381 100644 --- a/runtime/entrypoints/quick/quick_field_entrypoints.cc +++ b/runtime/entrypoints/quick/quick_field_entrypoints.cc @@ -27,7 +27,26 @@ namespace art { -extern "C" int8_t artGetByteStaticFromCode(uint32_t field_idx, ArtMethod* referrer, +template<FindFieldType type, bool kAccessCheck> +ALWAYS_INLINE static inline ArtField* FindInstanceField(uint32_t field_idx, + ArtMethod* referrer, + Thread* self, + size_t size, + mirror::Object** obj) + REQUIRES(!Roles::uninterruptible_) + SHARED_REQUIRES(Locks::mutator_lock_) { + StackHandleScope<1> hs(self); + HandleWrapper<mirror::Object> h(hs.NewHandleWrapper(obj)); + ArtField* field = FindFieldFromCode<type, kAccessCheck>(field_idx, referrer, self, size); + if (LIKELY(field != nullptr) && UNLIKELY(h.Get() == nullptr)) { + ThrowNullPointerExceptionForFieldAccess(field, /*is_read*/FindFieldTypeIsRead(type)); + return nullptr; + } + return field; +} + +extern "C" int8_t artGetByteStaticFromCode(uint32_t field_idx, + ArtMethod* referrer, Thread* self) SHARED_REQUIRES(Locks::mutator_lock_) { ScopedQuickEntrypointChecks sqec(self); @@ -42,7 +61,8 @@ extern "C" int8_t artGetByteStaticFromCode(uint32_t field_idx, ArtMethod* referr return 0; // Will throw exception by checking with Thread::Current. } -extern "C" uint8_t artGetBooleanStaticFromCode(uint32_t field_idx, ArtMethod* referrer, +extern "C" uint8_t artGetBooleanStaticFromCode(uint32_t field_idx, + ArtMethod* referrer, Thread* self) SHARED_REQUIRES(Locks::mutator_lock_) { ScopedQuickEntrypointChecks sqec(self); @@ -57,7 +77,8 @@ extern "C" uint8_t artGetBooleanStaticFromCode(uint32_t field_idx, ArtMethod* re return 0; // Will throw exception by checking with Thread::Current. } -extern "C" int16_t artGetShortStaticFromCode(uint32_t field_idx, ArtMethod* referrer, +extern "C" int16_t artGetShortStaticFromCode(uint32_t field_idx, + ArtMethod* referrer, Thread* self) SHARED_REQUIRES(Locks::mutator_lock_) { ScopedQuickEntrypointChecks sqec(self); @@ -125,12 +146,16 @@ extern "C" mirror::Object* artGetObjStaticFromCode(uint32_t field_idx, Thread* self) SHARED_REQUIRES(Locks::mutator_lock_) { ScopedQuickEntrypointChecks sqec(self); - ArtField* field = FindFieldFast(field_idx, referrer, StaticObjectRead, + ArtField* field = FindFieldFast(field_idx, + referrer, + StaticObjectRead, sizeof(mirror::HeapReference<mirror::Object>)); if (LIKELY(field != nullptr)) { return field->GetObj(field->GetDeclaringClass()); } - field = FindFieldFromCode<StaticObjectRead, true>(field_idx, referrer, self, + field = FindFieldFromCode<StaticObjectRead, true>(field_idx, + referrer, + self, sizeof(mirror::HeapReference<mirror::Object>)); if (LIKELY(field != nullptr)) { return field->GetObj(field->GetDeclaringClass()); @@ -138,149 +163,159 @@ extern "C" mirror::Object* artGetObjStaticFromCode(uint32_t field_idx, return nullptr; // Will throw exception by checking with Thread::Current. } -extern "C" int8_t artGetByteInstanceFromCode(uint32_t field_idx, mirror::Object* obj, - ArtMethod* referrer, Thread* self) +extern "C" int8_t artGetByteInstanceFromCode(uint32_t field_idx, + mirror::Object* obj, + ArtMethod* referrer, + Thread* self) SHARED_REQUIRES(Locks::mutator_lock_) { ScopedQuickEntrypointChecks sqec(self); ArtField* field = FindFieldFast(field_idx, referrer, InstancePrimitiveRead, sizeof(int8_t)); if (LIKELY(field != nullptr && obj != nullptr)) { return field->GetByte(obj); } - field = FindFieldFromCode<InstancePrimitiveRead, true>(field_idx, referrer, self, - sizeof(int8_t)); + field = FindInstanceField<InstancePrimitiveRead, true>(field_idx, + referrer, + self, + sizeof(int8_t), + &obj); if (LIKELY(field != nullptr)) { - if (UNLIKELY(obj == nullptr)) { - ThrowNullPointerExceptionForFieldAccess(field, true); - } else { - return field->GetByte(obj); - } + return field->GetByte(obj); } return 0; // Will throw exception by checking with Thread::Current. } -extern "C" uint8_t artGetBooleanInstanceFromCode(uint32_t field_idx, mirror::Object* obj, - ArtMethod* referrer, Thread* self) +extern "C" uint8_t artGetBooleanInstanceFromCode(uint32_t field_idx, + mirror::Object* obj, + ArtMethod* referrer, + Thread* self) SHARED_REQUIRES(Locks::mutator_lock_) { ScopedQuickEntrypointChecks sqec(self); ArtField* field = FindFieldFast(field_idx, referrer, InstancePrimitiveRead, sizeof(int8_t)); if (LIKELY(field != nullptr && obj != nullptr)) { return field->GetBoolean(obj); } - field = FindFieldFromCode<InstancePrimitiveRead, true>(field_idx, referrer, self, - sizeof(int8_t)); + field = FindInstanceField<InstancePrimitiveRead, true>(field_idx, + referrer, + self, + sizeof(int8_t), + &obj); if (LIKELY(field != nullptr)) { - if (UNLIKELY(obj == nullptr)) { - ThrowNullPointerExceptionForFieldAccess(field, true); - } else { - return field->GetBoolean(obj); - } + return field->GetBoolean(obj); } return 0; // Will throw exception by checking with Thread::Current. } -extern "C" int16_t artGetShortInstanceFromCode(uint32_t field_idx, mirror::Object* obj, - ArtMethod* referrer, Thread* self) +extern "C" int16_t artGetShortInstanceFromCode(uint32_t field_idx, + mirror::Object* obj, + ArtMethod* referrer, + Thread* self) SHARED_REQUIRES(Locks::mutator_lock_) { ScopedQuickEntrypointChecks sqec(self); ArtField* field = FindFieldFast(field_idx, referrer, InstancePrimitiveRead, sizeof(int16_t)); if (LIKELY(field != nullptr && obj != nullptr)) { return field->GetShort(obj); } - field = FindFieldFromCode<InstancePrimitiveRead, true>(field_idx, referrer, self, - sizeof(int16_t)); + field = FindInstanceField<InstancePrimitiveRead, true>(field_idx, + referrer, + self, + sizeof(int16_t), + &obj); if (LIKELY(field != nullptr)) { - if (UNLIKELY(obj == nullptr)) { - ThrowNullPointerExceptionForFieldAccess(field, true); - } else { - return field->GetShort(obj); - } + return field->GetShort(obj); } return 0; // Will throw exception by checking with Thread::Current. } -extern "C" uint16_t artGetCharInstanceFromCode(uint32_t field_idx, mirror::Object* obj, - ArtMethod* referrer, Thread* self) +extern "C" uint16_t artGetCharInstanceFromCode(uint32_t field_idx, + mirror::Object* obj, + ArtMethod* referrer, + Thread* self) SHARED_REQUIRES(Locks::mutator_lock_) { ScopedQuickEntrypointChecks sqec(self); ArtField* field = FindFieldFast(field_idx, referrer, InstancePrimitiveRead, sizeof(int16_t)); if (LIKELY(field != nullptr && obj != nullptr)) { return field->GetChar(obj); } - field = FindFieldFromCode<InstancePrimitiveRead, true>(field_idx, referrer, self, - sizeof(int16_t)); + field = FindInstanceField<InstancePrimitiveRead, true>(field_idx, + referrer, + self, + sizeof(int16_t), + &obj); if (LIKELY(field != nullptr)) { - if (UNLIKELY(obj == nullptr)) { - ThrowNullPointerExceptionForFieldAccess(field, true); - } else { - return field->GetChar(obj); - } + return field->GetChar(obj); } return 0; // Will throw exception by checking with Thread::Current. } -extern "C" uint32_t artGet32InstanceFromCode(uint32_t field_idx, mirror::Object* obj, - ArtMethod* referrer, Thread* self) +extern "C" uint32_t artGet32InstanceFromCode(uint32_t field_idx, + mirror::Object* obj, + ArtMethod* referrer, + Thread* self) SHARED_REQUIRES(Locks::mutator_lock_) { ScopedQuickEntrypointChecks sqec(self); ArtField* field = FindFieldFast(field_idx, referrer, InstancePrimitiveRead, sizeof(int32_t)); if (LIKELY(field != nullptr && obj != nullptr)) { return field->Get32(obj); } - field = FindFieldFromCode<InstancePrimitiveRead, true>(field_idx, referrer, self, - sizeof(int32_t)); + field = FindInstanceField<InstancePrimitiveRead, true>(field_idx, + referrer, + self, + sizeof(int32_t), + &obj); if (LIKELY(field != nullptr)) { - if (UNLIKELY(obj == nullptr)) { - ThrowNullPointerExceptionForFieldAccess(field, true); - } else { - return field->Get32(obj); - } + return field->Get32(obj); } return 0; // Will throw exception by checking with Thread::Current. } -extern "C" uint64_t artGet64InstanceFromCode(uint32_t field_idx, mirror::Object* obj, - ArtMethod* referrer, Thread* self) +extern "C" uint64_t artGet64InstanceFromCode(uint32_t field_idx, + mirror::Object* obj, + ArtMethod* referrer, + Thread* self) SHARED_REQUIRES(Locks::mutator_lock_) { ScopedQuickEntrypointChecks sqec(self); ArtField* field = FindFieldFast(field_idx, referrer, InstancePrimitiveRead, sizeof(int64_t)); if (LIKELY(field != nullptr && obj != nullptr)) { return field->Get64(obj); } - field = FindFieldFromCode<InstancePrimitiveRead, true>(field_idx, referrer, self, - sizeof(int64_t)); + field = FindInstanceField<InstancePrimitiveRead, true>(field_idx, + referrer, + self, + sizeof(int64_t), + &obj); if (LIKELY(field != nullptr)) { - if (UNLIKELY(obj == nullptr)) { - ThrowNullPointerExceptionForFieldAccess(field, true); - } else { - return field->Get64(obj); - } + return field->Get64(obj); } return 0; // Will throw exception by checking with Thread::Current. } -extern "C" mirror::Object* artGetObjInstanceFromCode(uint32_t field_idx, mirror::Object* obj, +extern "C" mirror::Object* artGetObjInstanceFromCode(uint32_t field_idx, + mirror::Object* obj, ArtMethod* referrer, Thread* self) SHARED_REQUIRES(Locks::mutator_lock_) { ScopedQuickEntrypointChecks sqec(self); - ArtField* field = FindFieldFast(field_idx, referrer, InstanceObjectRead, + ArtField* field = FindFieldFast(field_idx, + referrer, + InstanceObjectRead, sizeof(mirror::HeapReference<mirror::Object>)); if (LIKELY(field != nullptr && obj != nullptr)) { return field->GetObj(obj); } - field = FindFieldFromCode<InstanceObjectRead, true>( - field_idx, referrer, self, sizeof(mirror::HeapReference<mirror::Object>)); + field = FindInstanceField<InstanceObjectRead, true>(field_idx, + referrer, + self, + sizeof(mirror::HeapReference<mirror::Object>), + &obj); if (LIKELY(field != nullptr)) { - if (UNLIKELY(obj == nullptr)) { - ThrowNullPointerExceptionForFieldAccess(field, true); - } else { - return field->GetObj(obj); - } + return field->GetObj(obj); } return nullptr; // Will throw exception by checking with Thread::Current. } -extern "C" int artSet8StaticFromCode(uint32_t field_idx, uint32_t new_value, - ArtMethod* referrer, Thread* self) +extern "C" int artSet8StaticFromCode(uint32_t field_idx, + uint32_t new_value, + ArtMethod* referrer, + Thread* self) SHARED_REQUIRES(Locks::mutator_lock_) { ScopedQuickEntrypointChecks sqec(self); ArtField* field = FindFieldFast(field_idx, referrer, StaticPrimitiveWrite, sizeof(int8_t)); @@ -310,8 +345,10 @@ extern "C" int artSet8StaticFromCode(uint32_t field_idx, uint32_t new_value, return -1; // failure } -extern "C" int artSet16StaticFromCode(uint32_t field_idx, uint16_t new_value, - ArtMethod* referrer, Thread* self) +extern "C" int artSet16StaticFromCode(uint32_t field_idx, + uint16_t new_value, + ArtMethod* referrer, + Thread* self) SHARED_REQUIRES(Locks::mutator_lock_) { ScopedQuickEntrypointChecks sqec(self); ArtField* field = FindFieldFast(field_idx, referrer, StaticPrimitiveWrite, sizeof(int16_t)); @@ -341,8 +378,10 @@ extern "C" int artSet16StaticFromCode(uint32_t field_idx, uint16_t new_value, return -1; // failure } -extern "C" int artSet32StaticFromCode(uint32_t field_idx, uint32_t new_value, - ArtMethod* referrer, Thread* self) +extern "C" int artSet32StaticFromCode(uint32_t field_idx, + uint32_t new_value, + ArtMethod* referrer, + Thread* self) SHARED_REQUIRES(Locks::mutator_lock_) { ScopedQuickEntrypointChecks sqec(self); ArtField* field = FindFieldFast(field_idx, referrer, StaticPrimitiveWrite, sizeof(int32_t)); @@ -360,8 +399,10 @@ extern "C" int artSet32StaticFromCode(uint32_t field_idx, uint32_t new_value, return -1; // failure } -extern "C" int artSet64StaticFromCode(uint32_t field_idx, ArtMethod* referrer, - uint64_t new_value, Thread* self) +extern "C" int artSet64StaticFromCode(uint32_t field_idx, + ArtMethod* referrer, + uint64_t new_value, + Thread* self) SHARED_REQUIRES(Locks::mutator_lock_) { ScopedQuickEntrypointChecks sqec(self); ArtField* field = FindFieldFast(field_idx, referrer, StaticPrimitiveWrite, sizeof(int64_t)); @@ -379,11 +420,15 @@ extern "C" int artSet64StaticFromCode(uint32_t field_idx, ArtMethod* referrer, return -1; // failure } -extern "C" int artSetObjStaticFromCode(uint32_t field_idx, mirror::Object* new_value, - ArtMethod* referrer, Thread* self) +extern "C" int artSetObjStaticFromCode(uint32_t field_idx, + mirror::Object* new_value, + ArtMethod* referrer, + Thread* self) SHARED_REQUIRES(Locks::mutator_lock_) { ScopedQuickEntrypointChecks sqec(self); - ArtField* field = FindFieldFast(field_idx, referrer, StaticObjectWrite, + ArtField* field = FindFieldFast(field_idx, + referrer, + StaticObjectWrite, sizeof(mirror::HeapReference<mirror::Object>)); if (LIKELY(field != nullptr)) { if (LIKELY(!field->IsPrimitiveType())) { @@ -392,8 +437,15 @@ extern "C" int artSetObjStaticFromCode(uint32_t field_idx, mirror::Object* new_v return 0; // success } } - field = FindFieldFromCode<StaticObjectWrite, true>(field_idx, referrer, self, - sizeof(mirror::HeapReference<mirror::Object>)); + { + StackHandleScope<1> hs(self); + HandleWrapper<mirror::Object> h_obj(hs.NewHandleWrapper(&new_value)); + field = FindFieldFromCode<StaticObjectWrite, true>( + field_idx, + referrer, + self, + sizeof(mirror::HeapReference<mirror::Object>)); + } if (LIKELY(field != nullptr)) { // Compiled code can't use transactional mode. field->SetObj<false>(field->GetDeclaringClass(), new_value); @@ -402,8 +454,11 @@ extern "C" int artSetObjStaticFromCode(uint32_t field_idx, mirror::Object* new_v return -1; // failure } -extern "C" int artSet8InstanceFromCode(uint32_t field_idx, mirror::Object* obj, uint8_t new_value, - ArtMethod* referrer, Thread* self) +extern "C" int artSet8InstanceFromCode(uint32_t field_idx, + mirror::Object* obj, + uint8_t new_value, + ArtMethod* referrer, + Thread* self) SHARED_REQUIRES(Locks::mutator_lock_) { ScopedQuickEntrypointChecks sqec(self); ArtField* field = FindFieldFast(field_idx, referrer, InstancePrimitiveWrite, sizeof(int8_t)); @@ -418,31 +473,29 @@ extern "C" int artSet8InstanceFromCode(uint32_t field_idx, mirror::Object* obj, } return 0; // success } - { - StackHandleScope<1> hs(self); - HandleWrapper<mirror::Object> h_obj(hs.NewHandleWrapper(&obj)); - field = FindFieldFromCode<InstancePrimitiveWrite, true>(field_idx, referrer, self, - sizeof(int8_t)); - } + field = FindInstanceField<InstancePrimitiveWrite, true>(field_idx, + referrer, + self, + sizeof(int8_t), + &obj); if (LIKELY(field != nullptr)) { - if (UNLIKELY(obj == nullptr)) { - ThrowNullPointerExceptionForFieldAccess(field, false); + Primitive::Type type = field->GetTypeAsPrimitiveType(); + // Compiled code can't use transactional mode. + if (type == Primitive::kPrimBoolean) { + field->SetBoolean<false>(obj, new_value); } else { - Primitive::Type type = field->GetTypeAsPrimitiveType(); - // Compiled code can't use transactional mode. - if (type == Primitive::kPrimBoolean) { - field->SetBoolean<false>(obj, new_value); - } else { - field->SetByte<false>(obj, new_value); - } - return 0; // success + field->SetByte<false>(obj, new_value); } + return 0; // success } return -1; // failure } -extern "C" int artSet16InstanceFromCode(uint32_t field_idx, mirror::Object* obj, uint16_t new_value, - ArtMethod* referrer, Thread* self) +extern "C" int artSet16InstanceFromCode(uint32_t field_idx, + mirror::Object* obj, + uint16_t new_value, + ArtMethod* referrer, + Thread* self) SHARED_REQUIRES(Locks::mutator_lock_) { ScopedQuickEntrypointChecks sqec(self); ArtField* field = FindFieldFast(field_idx, referrer, InstancePrimitiveWrite, sizeof(int16_t)); @@ -457,32 +510,30 @@ extern "C" int artSet16InstanceFromCode(uint32_t field_idx, mirror::Object* obj, } return 0; // success } - { - StackHandleScope<1> hs(self); - HandleWrapper<mirror::Object> h_obj(hs.NewHandleWrapper(&obj)); - field = FindFieldFromCode<InstancePrimitiveWrite, true>(field_idx, referrer, self, - sizeof(int16_t)); - } + field = FindInstanceField<InstancePrimitiveWrite, true>(field_idx, + referrer, + self, + sizeof(int16_t), + &obj); if (LIKELY(field != nullptr)) { - if (UNLIKELY(obj == nullptr)) { - ThrowNullPointerExceptionForFieldAccess(field, false); + Primitive::Type type = field->GetTypeAsPrimitiveType(); + // Compiled code can't use transactional mode. + if (type == Primitive::kPrimChar) { + field->SetChar<false>(obj, new_value); } else { - Primitive::Type type = field->GetTypeAsPrimitiveType(); - // Compiled code can't use transactional mode. - if (type == Primitive::kPrimChar) { - field->SetChar<false>(obj, new_value); - } else { - DCHECK_EQ(Primitive::kPrimShort, type); - field->SetShort<false>(obj, new_value); - } - return 0; // success + DCHECK_EQ(Primitive::kPrimShort, type); + field->SetShort<false>(obj, new_value); } + return 0; // success } return -1; // failure } -extern "C" int artSet32InstanceFromCode(uint32_t field_idx, mirror::Object* obj, uint32_t new_value, - ArtMethod* referrer, Thread* self) +extern "C" int artSet32InstanceFromCode(uint32_t field_idx, + mirror::Object* obj, + uint32_t new_value, + ArtMethod* referrer, + Thread* self) SHARED_REQUIRES(Locks::mutator_lock_) { ScopedQuickEntrypointChecks sqec(self); ArtField* field = FindFieldFast(field_idx, referrer, InstancePrimitiveWrite, sizeof(int32_t)); @@ -491,26 +542,24 @@ extern "C" int artSet32InstanceFromCode(uint32_t field_idx, mirror::Object* obj, field->Set32<false>(obj, new_value); return 0; // success } - { - StackHandleScope<1> hs(self); - HandleWrapper<mirror::Object> h_obj(hs.NewHandleWrapper(&obj)); - field = FindFieldFromCode<InstancePrimitiveWrite, true>(field_idx, referrer, self, - sizeof(int32_t)); - } + field = FindInstanceField<InstancePrimitiveWrite, true>(field_idx, + referrer, + self, + sizeof(int32_t), + &obj); if (LIKELY(field != nullptr)) { - if (UNLIKELY(obj == nullptr)) { - ThrowNullPointerExceptionForFieldAccess(field, false); - } else { - // Compiled code can't use transactional mode. - field->Set32<false>(obj, new_value); - return 0; // success - } + // Compiled code can't use transactional mode. + field->Set32<false>(obj, new_value); + return 0; // success } return -1; // failure } -extern "C" int artSet64InstanceFromCode(uint32_t field_idx, mirror::Object* obj, uint64_t new_value, - ArtMethod* referrer, Thread* self) +extern "C" int artSet64InstanceFromCode(uint32_t field_idx, + mirror::Object* obj, + uint64_t new_value, + ArtMethod* referrer, + Thread* self) SHARED_REQUIRES(Locks::mutator_lock_) { ScopedQuickEntrypointChecks sqec(self); ArtField* field = FindFieldFast(field_idx, referrer, InstancePrimitiveWrite, sizeof(int64_t)); @@ -519,34 +568,45 @@ extern "C" int artSet64InstanceFromCode(uint32_t field_idx, mirror::Object* obj, field->Set64<false>(obj, new_value); return 0; // success } - field = FindFieldFromCode<InstancePrimitiveWrite, true>(field_idx, referrer, self, - sizeof(int64_t)); + field = FindInstanceField<InstancePrimitiveWrite, true>(field_idx, + referrer, + self, + sizeof(int64_t), + &obj); if (LIKELY(field != nullptr)) { - if (UNLIKELY(obj == nullptr)) { - ThrowNullPointerExceptionForFieldAccess(field, false); - } else { - // Compiled code can't use transactional mode. - field->Set64<false>(obj, new_value); - return 0; // success - } + // Compiled code can't use transactional mode. + field->Set64<false>(obj, new_value); + return 0; } return -1; // failure } -extern "C" int artSetObjInstanceFromCode(uint32_t field_idx, mirror::Object* obj, +extern "C" int artSetObjInstanceFromCode(uint32_t field_idx, + mirror::Object* obj, mirror::Object* new_value, - ArtMethod* referrer, Thread* self) + ArtMethod* referrer, + Thread* self) SHARED_REQUIRES(Locks::mutator_lock_) { ScopedQuickEntrypointChecks sqec(self); - ArtField* field = FindFieldFast(field_idx, referrer, InstanceObjectWrite, + ArtField* field = FindFieldFast(field_idx, + referrer, + InstanceObjectWrite, sizeof(mirror::HeapReference<mirror::Object>)); if (LIKELY(field != nullptr && obj != nullptr)) { // Compiled code can't use transactional mode. field->SetObj<false>(obj, new_value); return 0; // success } - field = FindFieldFromCode<InstanceObjectWrite, true>(field_idx, referrer, self, - sizeof(mirror::HeapReference<mirror::Object>)); + { + StackHandleScope<2> hs(self); + HandleWrapper<mirror::Object> h_obj(hs.NewHandleWrapper(&obj)); + HandleWrapper<mirror::Object> h_new_value(hs.NewHandleWrapper(&new_value)); + field = FindFieldFromCode<InstanceObjectWrite, true>( + field_idx, + referrer, + self, + sizeof(mirror::HeapReference<mirror::Object>)); + } if (LIKELY(field != nullptr)) { if (UNLIKELY(obj == nullptr)) { ThrowNullPointerExceptionForFieldAccess(field, false); |