diff options
| -rw-r--r-- | runtime/interpreter/interpreter_common.h | 17 | ||||
| -rw-r--r-- | runtime/interpreter/interpreter_switch_impl-inl.h | 6 | ||||
| -rw-r--r-- | runtime/interpreter/mterp/arm64ng/object.S | 2 | ||||
| -rw-r--r-- | runtime/interpreter/mterp/armng/main.S | 15 | ||||
| -rw-r--r-- | runtime/interpreter/mterp/nterp.cc | 35 | ||||
| -rw-r--r-- | runtime/interpreter/mterp/riscv64/object.S | 4 | ||||
| -rw-r--r-- | runtime/interpreter/mterp/x86_64ng/main.S | 4 | ||||
| -rw-r--r-- | runtime/interpreter/mterp/x86ng/main.S | 22 |
8 files changed, 91 insertions, 14 deletions
diff --git a/runtime/interpreter/interpreter_common.h b/runtime/interpreter/interpreter_common.h index ce6c412ba8..89900671b8 100644 --- a/runtime/interpreter/interpreter_common.h +++ b/runtime/interpreter/interpreter_common.h @@ -290,22 +290,29 @@ LIBART_PROTECTED extern "C" uint32_t NterpGetInstanceFieldOffset(Thread* self, ArtMethod* caller, const uint16_t* dex_pc_ptr, - size_t resolve_field_type); + size_t resolve_field_type, + uint32_t* registers); static inline void GetFieldInfo(Thread* self, - ArtMethod* caller, + ShadowFrame& shadow_frame, const uint16_t* dex_pc_ptr, bool is_static, bool resolve_field_type, ArtField** field, bool* is_volatile, - MemberOffset* offset) { + MemberOffset* offset) + REQUIRES_SHARED(Locks::mutator_lock_) { size_t tls_value = 0u; if (!self->GetInterpreterCache()->Get(self, dex_pc_ptr, &tls_value)) { if (is_static) { - tls_value = NterpGetStaticField(self, caller, dex_pc_ptr, resolve_field_type); + tls_value = NterpGetStaticField( + self, shadow_frame.GetMethod(), dex_pc_ptr, resolve_field_type); } else { - tls_value = NterpGetInstanceFieldOffset(self, caller, dex_pc_ptr, resolve_field_type); + tls_value = NterpGetInstanceFieldOffset(self, + shadow_frame.GetMethod(), + dex_pc_ptr, + resolve_field_type, + shadow_frame.GetVRegAddr(0)); } if (self->IsExceptionPending()) { diff --git a/runtime/interpreter/interpreter_switch_impl-inl.h b/runtime/interpreter/interpreter_switch_impl-inl.h index 7915a10094..791e9df04d 100644 --- a/runtime/interpreter/interpreter_switch_impl-inl.h +++ b/runtime/interpreter/interpreter_switch_impl-inl.h @@ -73,7 +73,7 @@ ALWAYS_INLINE bool DoFieldGet(Thread* self, MemberOffset offset(0u); bool is_volatile; GetFieldInfo(self, - shadow_frame.GetMethod(), + shadow_frame, reinterpret_cast<const uint16_t*>(inst), is_static, /*resolve_field_type=*/ false, @@ -157,7 +157,7 @@ ALWAYS_INLINE bool DoFieldGet(Thread* self, // Returns true on success, otherwise throws an exception and returns false. template<FindFieldType find_type, Primitive::Type field_type, bool transaction_active> ALWAYS_INLINE bool DoFieldPut(Thread* self, - const ShadowFrame& shadow_frame, + ShadowFrame& shadow_frame, const Instruction* inst, uint16_t inst_data, const instrumentation::Instrumentation* instrumentation) @@ -172,7 +172,7 @@ ALWAYS_INLINE bool DoFieldPut(Thread* self, MemberOffset offset(0u); bool is_volatile; GetFieldInfo(self, - shadow_frame.GetMethod(), + shadow_frame, reinterpret_cast<const uint16_t*>(inst), is_static, resolve_field_type, diff --git a/runtime/interpreter/mterp/arm64ng/object.S b/runtime/interpreter/mterp/arm64ng/object.S index ade39d5e89..f51ab6026c 100644 --- a/runtime/interpreter/mterp/arm64ng/object.S +++ b/runtime/interpreter/mterp/arm64ng/object.S @@ -193,6 +193,7 @@ ldr x1, [sp] mov x2, xPC mov x3, #0 + mov x4, xFP EXPORT_PC bl nterp_get_instance_field_offset // Zero extension (nterp_get_instance_field_offset returns uint32_t) of the return value is @@ -275,6 +276,7 @@ .else mov x3, #0 .endif + mov x4, xFP EXPORT_PC bl nterp_get_instance_field_offset // Zero extension (nterp_get_instance_field_offset returns uint32_t) of the return value is diff --git a/runtime/interpreter/mterp/armng/main.S b/runtime/interpreter/mterp/armng/main.S index 5298840f92..38f7647dd2 100644 --- a/runtime/interpreter/mterp/armng/main.S +++ b/runtime/interpreter/mterp/armng/main.S @@ -1950,7 +1950,6 @@ END nterp_f2l_doconv // Entrypoints into runtime. NTERP_TRAMPOLINE nterp_get_static_field, NterpGetStaticField -NTERP_TRAMPOLINE nterp_get_instance_field_offset, NterpGetInstanceFieldOffset NTERP_TRAMPOLINE nterp_filled_new_array, NterpFilledNewArray NTERP_TRAMPOLINE nterp_filled_new_array_range, NterpFilledNewArrayRange NTERP_TRAMPOLINE nterp_get_class, NterpGetClass @@ -1959,6 +1958,20 @@ NTERP_TRAMPOLINE nterp_get_method, NterpGetMethod NTERP_TRAMPOLINE nterp_hot_method, NterpHotMethod NTERP_TRAMPOLINE nterp_load_object, NterpLoadObject +ENTRY nterp_get_instance_field_offset + SETUP_SAVE_REFS_ONLY_FRAME ip + INCREASE_FRAME 8 + str rFP, [sp] + bl NterpGetInstanceFieldOffset + DECREASE_FRAME 8 + RESTORE_SAVE_REFS_ONLY_FRAME + REFRESH_MARKING_REGISTER + ldr ip, [rSELF, #THREAD_EXCEPTION_OFFSET] @ Get exception field. + cmp ip, #0 + bne nterp_deliver_pending_exception + bx lr +END nterp_get_instance_field_offset + ENTRY nterp_deliver_pending_exception DELIVER_PENDING_EXCEPTION END nterp_deliver_pending_exception diff --git a/runtime/interpreter/mterp/nterp.cc b/runtime/interpreter/mterp/nterp.cc index 95cfe7fb7d..f08f70143b 100644 --- a/runtime/interpreter/mterp/nterp.cc +++ b/runtime/interpreter/mterp/nterp.cc @@ -391,8 +391,12 @@ extern "C" size_t NterpGetMethod(Thread* self, ArtMethod* caller, const uint16_t } } +template <bool kStatic> ALWAYS_INLINE FLATTEN -static ArtField* FindFieldFast(ArtMethod* caller, uint16_t field_index) +static ArtField* FindFieldFast(ArtMethod* caller, + uint16_t field_index, + uint32_t* registers, + const Instruction* inst) REQUIRES_SHARED(Locks::mutator_lock_) { if (caller->IsObsolete()) { return nullptr; @@ -405,6 +409,28 @@ static ArtField* FindFieldFast(ArtMethod* caller, uint16_t field_index) return cls->FindDeclaredField(field_index); } + if (!kStatic) { + mirror::Object* obj = reinterpret_cast32<mirror::Object*>(registers[inst->VRegB_22c()]); + if (obj != nullptr) { + mirror::Class* obj_cls = obj->GetClass(); + if (obj_cls->GetDexTypeIndex() == field_id.class_idx_ && + obj_cls->GetDexCache() == cls->GetDexCache() && + obj_cls->IsPublic()) { + ArtField* resolved_field = obj_cls->FindDeclaredField(field_index); + if (caller->SkipAccessChecks() || + (resolved_field != nullptr && resolved_field->IsPublic())) { + return resolved_field; + } + } + } + } + + ArtField* field = caller->GetDexCache()->GetResolvedField(field_index); + if (caller->SkipAccessChecks() || + (field != nullptr && field->IsPublic() && field->GetDeclaringClass()->IsPublic())) { + return field; + } + return nullptr; } @@ -435,7 +461,7 @@ extern "C" size_t NterpGetStaticField(Thread* self, uint16_t field_index = inst->VRegB_21c(); Instruction::Code opcode = inst->Opcode(); - ArtField* resolved_field = FindFieldFast(caller, field_index); + ArtField* resolved_field = FindFieldFast</*kStatic=*/true>(caller, field_index, nullptr, inst); if (resolved_field == nullptr || !resolved_field->IsStatic()) { resolved_field = FindFieldSlow( self, caller, field_index, /*is_static=*/ true, IsInstructionSPut(opcode)); @@ -492,13 +518,14 @@ LIBART_PROTECTED extern "C" uint32_t NterpGetInstanceFieldOffset(Thread* self, ArtMethod* caller, const uint16_t* dex_pc_ptr, - size_t resolve_field_type) // Resolve if not zero + size_t resolve_field_type, // Resolve if not zero + uint32_t* registers) REQUIRES_SHARED(Locks::mutator_lock_) { const Instruction* inst = Instruction::At(dex_pc_ptr); uint16_t field_index = inst->VRegC_22c(); Instruction::Code opcode = inst->Opcode(); - ArtField* resolved_field = FindFieldFast(caller, field_index); + ArtField* resolved_field = FindFieldFast</*kStatic=*/false>(caller, field_index, registers, inst); if (resolved_field == nullptr || resolved_field->IsStatic()) { resolved_field = FindFieldSlow( self, caller, field_index, /*is_static=*/ false, IsInstructionIPut(opcode)); diff --git a/runtime/interpreter/mterp/riscv64/object.S b/runtime/interpreter/mterp/riscv64/object.S index 43bb31f1e9..ebaf550932 100644 --- a/runtime/interpreter/mterp/riscv64/object.S +++ b/runtime/interpreter/mterp/riscv64/object.S @@ -290,6 +290,7 @@ ld a1, (sp) // a1 := caller ArtMethod* mv a2, xPC mv a3, zero + mv a4, xFP EXPORT_PC call nterp_get_instance_field_offset // result a0 := field_offset @@ -367,6 +368,7 @@ ld a1, (sp) // a1 := caller ArtMethod* mv a2, xPC mv a3, zero + mv a4, xFP EXPORT_PC call nterp_get_instance_field_offset // result a0 := field_offset @@ -452,6 +454,7 @@ ld a1, (sp) // a1 := caller ArtMethod* mv a2, xPC mv a3, zero + mv a4, xFP EXPORT_PC call nterp_get_instance_field_offset // result a0 := field_offset @@ -535,6 +538,7 @@ ld a1, (sp) // a1 := caller ArtMethod* mv a2, xPC mv a3, $value + mv a4, xFP EXPORT_PC call nterp_get_instance_field_offset // result a0 := field_offset diff --git a/runtime/interpreter/mterp/x86_64ng/main.S b/runtime/interpreter/mterp/x86_64ng/main.S index 80753c4fc2..7126c9f5ae 100644 --- a/runtime/interpreter/mterp/x86_64ng/main.S +++ b/runtime/interpreter/mterp/x86_64ng/main.S @@ -1547,6 +1547,7 @@ END_FUNCTION \name movq 0(%rsp), %rsi movq rPC, %rdx movq $$0, %rcx + movq rFP, %r8 call nterp_get_instance_field_offset testl %eax, %eax jns 1b @@ -1581,6 +1582,7 @@ END_FUNCTION \name movq 0(%rsp), %rsi movq rPC, %rdx movq $$0, %rcx + movq rFP, %r8 call nterp_get_instance_field_offset testl %eax, %eax jns 1b @@ -1944,6 +1946,7 @@ NterpPutObjectInstanceField: movq 0(%rsp), %rsi movq rPC, %rdx // %rcx is already set. + movq rFP, %r8 call nterp_get_instance_field_offset // Reload the value as it may have moved. GET_VREG %ecx, %rbp # ecx <- v[A] @@ -1987,6 +1990,7 @@ NterpGetObjectInstanceField: movq 0(%rsp), %rsi movq rPC, %rdx movq $$0, %rcx + movq rFP, %r8 call nterp_get_instance_field_offset testl %eax, %eax jns 1b diff --git a/runtime/interpreter/mterp/x86ng/main.S b/runtime/interpreter/mterp/x86ng/main.S index d2f4271f99..dabdd4233a 100644 --- a/runtime/interpreter/mterp/x86ng/main.S +++ b/runtime/interpreter/mterp/x86ng/main.S @@ -2321,7 +2321,6 @@ SYMBOL(EndExecuteNterpImpl): // Entrypoints into runtime. NTERP_TRAMPOLINE nterp_get_static_field, NterpGetStaticField -NTERP_TRAMPOLINE nterp_get_instance_field_offset, NterpGetInstanceFieldOffset NTERP_TRAMPOLINE nterp_filled_new_array, NterpFilledNewArray NTERP_TRAMPOLINE nterp_filled_new_array_range, NterpFilledNewArrayRange NTERP_TRAMPOLINE nterp_get_class, NterpGetClass @@ -2330,6 +2329,27 @@ NTERP_TRAMPOLINE nterp_get_method, NterpGetMethod NTERP_TRAMPOLINE nterp_hot_method, NterpHotMethod NTERP_TRAMPOLINE nterp_load_object, NterpLoadObject +// Special case nterp_get_instance_field_offset as it requires 5 arguments. +DEFINE_FUNCTION nterp_get_instance_field_offset + movd %ebx, %xmm0 + SETUP_SAVE_REFS_ONLY_FRAME ebx + movd %xmm0, %ebx + INCREASE_FRAME 12 + PUSH_ARG edi + PUSH_ARG ebx + PUSH_ARG edx + PUSH_ARG ecx + PUSH_ARG eax + call NterpGetInstanceFieldOffset + DECREASE_FRAME 32 + RESTORE_IBASE_WITH_CFA + FETCH_INST_CLEAR_OPCODE + RESTORE_SAVE_REFS_ONLY_FRAME + cmpl LITERAL(0), %fs:THREAD_EXCEPTION_OFFSET + jne nterp_deliver_pending_exception + ret +END_FUNCTION nterp_get_instance_field_offset + DEFINE_FUNCTION nterp_deliver_pending_exception DELIVER_PENDING_EXCEPTION END_FUNCTION nterp_deliver_pending_exception |