summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/interpreter/interpreter_common.h17
-rw-r--r--runtime/interpreter/interpreter_switch_impl-inl.h6
-rw-r--r--runtime/interpreter/mterp/arm64ng/object.S2
-rw-r--r--runtime/interpreter/mterp/armng/main.S15
-rw-r--r--runtime/interpreter/mterp/nterp.cc35
-rw-r--r--runtime/interpreter/mterp/riscv64/object.S4
-rw-r--r--runtime/interpreter/mterp/x86_64ng/main.S4
-rw-r--r--runtime/interpreter/mterp/x86ng/main.S22
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