summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author buzbee <buzbee@google.com> 2016-01-25 15:41:24 -0800
committer Serguei Katkov <serguei.i.katkov@intel.com> 2016-01-26 10:46:54 +0600
commita2c97a94ee9379b23204bfef87afacd4b60cae37 (patch)
tree5756c6bf6fd5321c9ead15edfa88e147ff45ac8f
parent1af0204dddc1d99dc17a13eca135c1b57023c1c3 (diff)
[WIP] ART Mterp: fix for hidden gc roots
To support moving gc, we must not hold onto any references solely in registers across potential gc points. This was happening during returns, instance-of and check-cast. [testing in progress] Change-Id: I367750658c5716960737f0666e46800240fd392d
-rw-r--r--runtime/interpreter/mterp/arm/footer.S4
-rw-r--r--runtime/interpreter/mterp/arm/op_check_cast.S4
-rw-r--r--runtime/interpreter/mterp/arm/op_instance_of.S4
-rw-r--r--runtime/interpreter/mterp/arm/op_return.S4
-rw-r--r--runtime/interpreter/mterp/arm/op_return_void.S4
-rw-r--r--runtime/interpreter/mterp/arm/op_return_void_no_barrier.S4
-rw-r--r--runtime/interpreter/mterp/arm/op_return_wide.S4
-rw-r--r--runtime/interpreter/mterp/mterp.cc20
-rw-r--r--runtime/interpreter/mterp/out/mterp_arm.S32
-rw-r--r--runtime/interpreter/mterp/out/mterp_x86.S44
-rw-r--r--runtime/interpreter/mterp/x86/footer.S6
-rw-r--r--runtime/interpreter/mterp/x86/op_check_cast.S4
-rw-r--r--runtime/interpreter/mterp/x86/op_instance_of.S4
-rw-r--r--runtime/interpreter/mterp/x86/op_return.S6
-rw-r--r--runtime/interpreter/mterp/x86/op_return_void.S6
-rw-r--r--runtime/interpreter/mterp/x86/op_return_void_no_barrier.S6
-rw-r--r--runtime/interpreter/mterp/x86/op_return_wide.S6
17 files changed, 117 insertions, 45 deletions
diff --git a/runtime/interpreter/mterp/arm/footer.S b/runtime/interpreter/mterp/arm/footer.S
index 617f572c0f..1dba856ecb 100644
--- a/runtime/interpreter/mterp/arm/footer.S
+++ b/runtime/interpreter/mterp/arm/footer.S
@@ -150,12 +150,8 @@ MterpExceptionReturn:
b MterpDone
MterpReturn:
ldr r2, [rFP, #OFF_FP_RESULT_REGISTER]
- ldr lr, [rSELF, #THREAD_FLAGS_OFFSET]
str r0, [r2]
str r1, [r2, #4]
- mov r0, rSELF
- ands lr, #(THREAD_SUSPEND_REQUEST | THREAD_CHECKPOINT_REQUEST)
- blne MterpSuspendCheck @ (self)
mov r0, #1 @ signal return to caller.
MterpDone:
add sp, sp, #4 @ un-align 64
diff --git a/runtime/interpreter/mterp/arm/op_check_cast.S b/runtime/interpreter/mterp/arm/op_check_cast.S
index 3e3ac707c4..24eba45a69 100644
--- a/runtime/interpreter/mterp/arm/op_check_cast.S
+++ b/runtime/interpreter/mterp/arm/op_check_cast.S
@@ -5,10 +5,10 @@
EXPORT_PC
FETCH r0, 1 @ r0<- BBBB
mov r1, rINST, lsr #8 @ r1<- AA
- GET_VREG r1, r1 @ r1<- object
+ VREG_INDEX_TO_ADDR r1, r1 @ r1<- &object
ldr r2, [rFP, #OFF_FP_METHOD] @ r2<- method
mov r3, rSELF @ r3<- self
- bl MterpCheckCast @ (index, obj, method, self)
+ bl MterpCheckCast @ (index, &obj, method, self)
PREFETCH_INST 2
cmp r0, #0
bne MterpPossibleException
diff --git a/runtime/interpreter/mterp/arm/op_instance_of.S b/runtime/interpreter/mterp/arm/op_instance_of.S
index e94108ca06..d76f0b09fe 100644
--- a/runtime/interpreter/mterp/arm/op_instance_of.S
+++ b/runtime/interpreter/mterp/arm/op_instance_of.S
@@ -8,12 +8,12 @@
EXPORT_PC
FETCH r0, 1 @ r0<- CCCC
mov r1, rINST, lsr #12 @ r1<- B
- GET_VREG r1, r1 @ r1<- vB (object)
+ VREG_INDEX_TO_ADDR r1, r1 @ r1<- &object
ldr r2, [rFP, #OFF_FP_METHOD] @ r2<- method
mov r3, rSELF @ r3<- self
mov r9, rINST, lsr #8 @ r9<- A+
and r9, r9, #15 @ r9<- A
- bl MterpInstanceOf @ (index, obj, method, self)
+ bl MterpInstanceOf @ (index, &obj, method, self)
ldr r1, [rSELF, #THREAD_EXCEPTION_OFFSET]
PREFETCH_INST 2
cmp r1, #0 @ exception pending?
diff --git a/runtime/interpreter/mterp/arm/op_return.S b/runtime/interpreter/mterp/arm/op_return.S
index a4ffd04ea6..1888373256 100644
--- a/runtime/interpreter/mterp/arm/op_return.S
+++ b/runtime/interpreter/mterp/arm/op_return.S
@@ -6,6 +6,10 @@
/* op vAA */
.extern MterpThreadFenceForConstructor
bl MterpThreadFenceForConstructor
+ ldr lr, [rSELF, #THREAD_FLAGS_OFFSET]
+ mov r0, rSELF
+ ands lr, #(THREAD_SUSPEND_REQUEST | THREAD_CHECKPOINT_REQUEST)
+ blne MterpSuspendCheck @ (self)
mov r2, rINST, lsr #8 @ r2<- AA
GET_VREG r0, r2 @ r0<- vAA
mov r1, #0
diff --git a/runtime/interpreter/mterp/arm/op_return_void.S b/runtime/interpreter/mterp/arm/op_return_void.S
index f6dfd99309..cbea2bf6a0 100644
--- a/runtime/interpreter/mterp/arm/op_return_void.S
+++ b/runtime/interpreter/mterp/arm/op_return_void.S
@@ -1,5 +1,9 @@
.extern MterpThreadFenceForConstructor
bl MterpThreadFenceForConstructor
+ ldr lr, [rSELF, #THREAD_FLAGS_OFFSET]
+ mov r0, rSELF
+ ands lr, #(THREAD_SUSPEND_REQUEST | THREAD_CHECKPOINT_REQUEST)
+ blne MterpSuspendCheck @ (self)
mov r0, #0
mov r1, #0
b MterpReturn
diff --git a/runtime/interpreter/mterp/arm/op_return_void_no_barrier.S b/runtime/interpreter/mterp/arm/op_return_void_no_barrier.S
index 7322940a74..2dde7aeefc 100644
--- a/runtime/interpreter/mterp/arm/op_return_void_no_barrier.S
+++ b/runtime/interpreter/mterp/arm/op_return_void_no_barrier.S
@@ -1,3 +1,7 @@
+ ldr lr, [rSELF, #THREAD_FLAGS_OFFSET]
+ mov r0, rSELF
+ ands lr, #(THREAD_SUSPEND_REQUEST | THREAD_CHECKPOINT_REQUEST)
+ blne MterpSuspendCheck @ (self)
mov r0, #0
mov r1, #0
b MterpReturn
diff --git a/runtime/interpreter/mterp/arm/op_return_wide.S b/runtime/interpreter/mterp/arm/op_return_wide.S
index 2881c87e58..cfab5301e5 100644
--- a/runtime/interpreter/mterp/arm/op_return_wide.S
+++ b/runtime/interpreter/mterp/arm/op_return_wide.S
@@ -4,6 +4,10 @@
/* return-wide vAA */
.extern MterpThreadFenceForConstructor
bl MterpThreadFenceForConstructor
+ ldr lr, [rSELF, #THREAD_FLAGS_OFFSET]
+ mov r0, rSELF
+ ands lr, #(THREAD_SUSPEND_REQUEST | THREAD_CHECKPOINT_REQUEST)
+ blne MterpSuspendCheck @ (self)
mov r2, rINST, lsr #8 @ r2<- AA
add r2, rFP, r2, lsl #2 @ r2<- &fp[AA]
ldmia r2, {r0-r1} @ r0/r1 <- vAA/vAA+1
diff --git a/runtime/interpreter/mterp/mterp.cc b/runtime/interpreter/mterp/mterp.cc
index 9975458b85..0afd2765db 100644
--- a/runtime/interpreter/mterp/mterp.cc
+++ b/runtime/interpreter/mterp/mterp.cc
@@ -274,13 +274,15 @@ extern "C" bool MterpConstClass(uint32_t index, uint32_t tgt_vreg, ShadowFrame*
return false;
}
-extern "C" bool MterpCheckCast(uint32_t index, Object* obj, art::ArtMethod* method,
- Thread* self)
+extern "C" bool MterpCheckCast(uint32_t index, StackReference<mirror::Object>* vreg_addr,
+ art::ArtMethod* method, Thread* self)
SHARED_REQUIRES(Locks::mutator_lock_) {
Class* c = ResolveVerifyAndClinit(index, method, self, false, false);
if (UNLIKELY(c == nullptr)) {
return true;
}
+ // Must load obj from vreg following ResolveVerifyAndClinit due to moving gc.
+ Object* obj = vreg_addr->AsMirrorPtr();
if (UNLIKELY(obj != nullptr && !obj->InstanceOf(c))) {
ThrowClassCastException(c, obj->GetClass());
return true;
@@ -288,13 +290,15 @@ extern "C" bool MterpCheckCast(uint32_t index, Object* obj, art::ArtMethod* meth
return false;
}
-extern "C" bool MterpInstanceOf(uint32_t index, Object* obj, art::ArtMethod* method,
- Thread* self)
+extern "C" bool MterpInstanceOf(uint32_t index, StackReference<mirror::Object>* vreg_addr,
+ art::ArtMethod* method, Thread* self)
SHARED_REQUIRES(Locks::mutator_lock_) {
Class* c = ResolveVerifyAndClinit(index, method, self, false, false);
if (UNLIKELY(c == nullptr)) {
return false; // Caller will check for pending exception. Return value unimportant.
}
+ // Must load obj from vreg following ResolveVerifyAndClinit due to moving gc.
+ Object* obj = vreg_addr->AsMirrorPtr();
return (obj != nullptr) && obj->InstanceOf(c);
}
@@ -505,8 +509,7 @@ extern "C" int artSet64IndirectStaticFromMterp(uint32_t field_idx, ArtMethod* re
uint64_t* new_value, Thread* self)
SHARED_REQUIRES(Locks::mutator_lock_) {
ScopedQuickEntrypointChecks sqec(self);
- ArtField* field = FindFieldFast(field_idx, referrer, StaticPrimitiveWrite,
- sizeof(int64_t));
+ ArtField* field = FindFieldFast(field_idx, referrer, StaticPrimitiveWrite, sizeof(int64_t));
if (LIKELY(field != nullptr)) {
// Compiled code can't use transactional mode.
field->Set64<false>(field->GetDeclaringClass(), *new_value);
@@ -524,8 +527,7 @@ extern "C" int artSet64IndirectStaticFromMterp(uint32_t field_idx, ArtMethod* re
extern "C" int artSet8InstanceFromMterp(uint32_t field_idx, mirror::Object* obj, uint8_t new_value,
ArtMethod* referrer)
SHARED_REQUIRES(Locks::mutator_lock_) {
- ArtField* field = FindFieldFast(field_idx, referrer, InstancePrimitiveWrite,
- sizeof(int8_t));
+ ArtField* field = FindFieldFast(field_idx, referrer, InstancePrimitiveWrite, sizeof(int8_t));
if (LIKELY(field != nullptr && obj != nullptr)) {
Primitive::Type type = field->GetTypeAsPrimitiveType();
if (type == Primitive::kPrimBoolean) {
@@ -582,7 +584,7 @@ extern "C" int artSet64InstanceFromMterp(uint32_t field_idx, mirror::Object* obj
}
extern "C" int artSetObjInstanceFromMterp(uint32_t field_idx, mirror::Object* obj,
- mirror::Object* new_value, ArtMethod* referrer)
+ mirror::Object* new_value, ArtMethod* referrer)
SHARED_REQUIRES(Locks::mutator_lock_) {
ArtField* field = FindFieldFast(field_idx, referrer, InstanceObjectWrite,
sizeof(mirror::HeapReference<mirror::Object>));
diff --git a/runtime/interpreter/mterp/out/mterp_arm.S b/runtime/interpreter/mterp/out/mterp_arm.S
index 9ae98a2bbe..78c784b773 100644
--- a/runtime/interpreter/mterp/out/mterp_arm.S
+++ b/runtime/interpreter/mterp/out/mterp_arm.S
@@ -599,6 +599,10 @@ artMterpAsmInstructionStart = .L_op_nop
/* File: arm/op_return_void.S */
.extern MterpThreadFenceForConstructor
bl MterpThreadFenceForConstructor
+ ldr lr, [rSELF, #THREAD_FLAGS_OFFSET]
+ mov r0, rSELF
+ ands lr, #(THREAD_SUSPEND_REQUEST | THREAD_CHECKPOINT_REQUEST)
+ blne MterpSuspendCheck @ (self)
mov r0, #0
mov r1, #0
b MterpReturn
@@ -615,6 +619,10 @@ artMterpAsmInstructionStart = .L_op_nop
/* op vAA */
.extern MterpThreadFenceForConstructor
bl MterpThreadFenceForConstructor
+ ldr lr, [rSELF, #THREAD_FLAGS_OFFSET]
+ mov r0, rSELF
+ ands lr, #(THREAD_SUSPEND_REQUEST | THREAD_CHECKPOINT_REQUEST)
+ blne MterpSuspendCheck @ (self)
mov r2, rINST, lsr #8 @ r2<- AA
GET_VREG r0, r2 @ r0<- vAA
mov r1, #0
@@ -630,6 +638,10 @@ artMterpAsmInstructionStart = .L_op_nop
/* return-wide vAA */
.extern MterpThreadFenceForConstructor
bl MterpThreadFenceForConstructor
+ ldr lr, [rSELF, #THREAD_FLAGS_OFFSET]
+ mov r0, rSELF
+ ands lr, #(THREAD_SUSPEND_REQUEST | THREAD_CHECKPOINT_REQUEST)
+ blne MterpSuspendCheck @ (self)
mov r2, rINST, lsr #8 @ r2<- AA
add r2, rFP, r2, lsl #2 @ r2<- &fp[AA]
ldmia r2, {r0-r1} @ r0/r1 <- vAA/vAA+1
@@ -648,6 +660,10 @@ artMterpAsmInstructionStart = .L_op_nop
/* op vAA */
.extern MterpThreadFenceForConstructor
bl MterpThreadFenceForConstructor
+ ldr lr, [rSELF, #THREAD_FLAGS_OFFSET]
+ mov r0, rSELF
+ ands lr, #(THREAD_SUSPEND_REQUEST | THREAD_CHECKPOINT_REQUEST)
+ blne MterpSuspendCheck @ (self)
mov r2, rINST, lsr #8 @ r2<- AA
GET_VREG r0, r2 @ r0<- vAA
mov r1, #0
@@ -878,10 +894,10 @@ artMterpAsmInstructionStart = .L_op_nop
EXPORT_PC
FETCH r0, 1 @ r0<- BBBB
mov r1, rINST, lsr #8 @ r1<- AA
- GET_VREG r1, r1 @ r1<- object
+ VREG_INDEX_TO_ADDR r1, r1 @ r1<- &object
ldr r2, [rFP, #OFF_FP_METHOD] @ r2<- method
mov r3, rSELF @ r3<- self
- bl MterpCheckCast @ (index, obj, method, self)
+ bl MterpCheckCast @ (index, &obj, method, self)
PREFETCH_INST 2
cmp r0, #0
bne MterpPossibleException
@@ -903,12 +919,12 @@ artMterpAsmInstructionStart = .L_op_nop
EXPORT_PC
FETCH r0, 1 @ r0<- CCCC
mov r1, rINST, lsr #12 @ r1<- B
- GET_VREG r1, r1 @ r1<- vB (object)
+ VREG_INDEX_TO_ADDR r1, r1 @ r1<- &object
ldr r2, [rFP, #OFF_FP_METHOD] @ r2<- method
mov r3, rSELF @ r3<- self
mov r9, rINST, lsr #8 @ r9<- A+
and r9, r9, #15 @ r9<- A
- bl MterpInstanceOf @ (index, obj, method, self)
+ bl MterpInstanceOf @ (index, &obj, method, self)
ldr r1, [rSELF, #THREAD_EXCEPTION_OFFSET]
PREFETCH_INST 2
cmp r1, #0 @ exception pending?
@@ -3385,6 +3401,10 @@ artMterpAsmInstructionStart = .L_op_nop
.balign 128
.L_op_return_void_no_barrier: /* 0x73 */
/* File: arm/op_return_void_no_barrier.S */
+ ldr lr, [rSELF, #THREAD_FLAGS_OFFSET]
+ mov r0, rSELF
+ ands lr, #(THREAD_SUSPEND_REQUEST | THREAD_CHECKPOINT_REQUEST)
+ blne MterpSuspendCheck @ (self)
mov r0, #0
mov r1, #0
b MterpReturn
@@ -12183,12 +12203,8 @@ MterpExceptionReturn:
b MterpDone
MterpReturn:
ldr r2, [rFP, #OFF_FP_RESULT_REGISTER]
- ldr lr, [rSELF, #THREAD_FLAGS_OFFSET]
str r0, [r2]
str r1, [r2, #4]
- mov r0, rSELF
- ands lr, #(THREAD_SUSPEND_REQUEST | THREAD_CHECKPOINT_REQUEST)
- blne MterpSuspendCheck @ (self)
mov r0, #1 @ signal return to caller.
MterpDone:
add sp, sp, #4 @ un-align 64
diff --git a/runtime/interpreter/mterp/out/mterp_x86.S b/runtime/interpreter/mterp/out/mterp_x86.S
index 923d502543..e2918dcfb2 100644
--- a/runtime/interpreter/mterp/out/mterp_x86.S
+++ b/runtime/interpreter/mterp/out/mterp_x86.S
@@ -575,6 +575,12 @@ artMterpAsmInstructionStart = .L_op_nop
/* File: x86/op_return_void.S */
.extern MterpThreadFenceForConstructor
call MterpThreadFenceForConstructor
+ movl rSELF, %eax
+ testl $(THREAD_SUSPEND_REQUEST | THREAD_CHECKPOINT_REQUEST), THREAD_FLAGS_OFFSET(%eax)
+ jz 1f
+ movl %eax, OUT_ARG0(%esp)
+ call MterpSuspendCheck
+1:
xorl %eax, %eax
xorl %ecx, %ecx
jmp MterpReturn
@@ -591,6 +597,12 @@ artMterpAsmInstructionStart = .L_op_nop
/* op vAA */
.extern MterpThreadFenceForConstructor
call MterpThreadFenceForConstructor
+ movl rSELF, %eax
+ testl $(THREAD_SUSPEND_REQUEST | THREAD_CHECKPOINT_REQUEST), THREAD_FLAGS_OFFSET(%eax)
+ jz 1f
+ movl %eax, OUT_ARG0(%esp)
+ call MterpSuspendCheck
+1:
GET_VREG %eax rINST # eax <- vAA
xorl %ecx, %ecx
jmp MterpReturn
@@ -605,6 +617,12 @@ artMterpAsmInstructionStart = .L_op_nop
/* return-wide vAA */
.extern MterpThreadFenceForConstructor
call MterpThreadFenceForConstructor
+ movl rSELF, %eax
+ testl $(THREAD_SUSPEND_REQUEST | THREAD_CHECKPOINT_REQUEST), THREAD_FLAGS_OFFSET(%eax)
+ jz 1f
+ movl %eax, OUT_ARG0(%esp)
+ call MterpSuspendCheck
+1:
GET_VREG %eax rINST # eax <- v[AA+0]
GET_VREG_HIGH %ecx rINST # ecx <- v[AA+1]
jmp MterpReturn
@@ -622,6 +640,12 @@ artMterpAsmInstructionStart = .L_op_nop
/* op vAA */
.extern MterpThreadFenceForConstructor
call MterpThreadFenceForConstructor
+ movl rSELF, %eax
+ testl $(THREAD_SUSPEND_REQUEST | THREAD_CHECKPOINT_REQUEST), THREAD_FLAGS_OFFSET(%eax)
+ jz 1f
+ movl %eax, OUT_ARG0(%esp)
+ call MterpSuspendCheck
+1:
GET_VREG %eax rINST # eax <- vAA
xorl %ecx, %ecx
jmp MterpReturn
@@ -827,13 +851,13 @@ artMterpAsmInstructionStart = .L_op_nop
EXPORT_PC
movzwl 2(rPC), %eax # eax <- BBBB
movl %eax, OUT_ARG0(%esp)
- GET_VREG %ecx rINST
+ leal VREG_ADDRESS(rINST), %ecx
movl %ecx, OUT_ARG1(%esp)
movl OFF_FP_METHOD(rFP),%eax
movl %eax, OUT_ARG2(%esp)
movl rSELF, %ecx
movl %ecx, OUT_ARG3(%esp)
- call MterpCheckCast # (index, obj, method, self)
+ call MterpCheckCast # (index, &obj, method, self)
REFRESH_IBASE
testl %eax, %eax
jnz MterpPossibleException
@@ -855,13 +879,13 @@ artMterpAsmInstructionStart = .L_op_nop
movl %eax, OUT_ARG0(%esp)
movl rINST, %eax # eax <- BA
sarl $4, %eax # eax <- B
- GET_VREG %ecx %eax # Get object
+ leal VREG_ADDRESS(%eax), %ecx # Get object address
movl %ecx, OUT_ARG1(%esp)
movl OFF_FP_METHOD(rFP),%eax
movl %eax, OUT_ARG2(%esp)
movl rSELF, %ecx
movl %ecx, OUT_ARG3(%esp)
- call MterpInstanceOf # (index, obj, method, self)
+ call MterpInstanceOf # (index, &obj, method, self)
movl rSELF, %ecx
REFRESH_IBASE_FROM_SELF %ecx
cmpl $0, THREAD_EXCEPTION_OFFSET(%ecx)
@@ -3145,6 +3169,12 @@ artMterpAsmInstructionStart = .L_op_nop
.balign 128
.L_op_return_void_no_barrier: /* 0x73 */
/* File: x86/op_return_void_no_barrier.S */
+ movl rSELF, %eax
+ testl $(THREAD_SUSPEND_REQUEST | THREAD_CHECKPOINT_REQUEST), THREAD_FLAGS_OFFSET(%eax)
+ jz 1f
+ movl %eax, OUT_ARG0(%esp)
+ call MterpSuspendCheck
+1:
xorl %eax, %eax
xorl %ecx, %ecx
jmp MterpReturn
@@ -12921,12 +12951,6 @@ MterpReturn:
movl OFF_FP_RESULT_REGISTER(rFP), %edx
movl %eax, (%edx)
movl %ecx, 4(%edx)
- movl rSELF, %eax
- testl $(THREAD_SUSPEND_REQUEST | THREAD_CHECKPOINT_REQUEST), THREAD_FLAGS_OFFSET(%eax)
- jz 1f
- movl %eax, OUT_ARG0(%esp)
- call MterpSuspendCheck
-1:
mov $1, %eax
MterpDone:
/* Restore callee save register */
diff --git a/runtime/interpreter/mterp/x86/footer.S b/runtime/interpreter/mterp/x86/footer.S
index 8f79b37681..a2a36c4f64 100644
--- a/runtime/interpreter/mterp/x86/footer.S
+++ b/runtime/interpreter/mterp/x86/footer.S
@@ -169,12 +169,6 @@ MterpReturn:
movl OFF_FP_RESULT_REGISTER(rFP), %edx
movl %eax, (%edx)
movl %ecx, 4(%edx)
- movl rSELF, %eax
- testl $$(THREAD_SUSPEND_REQUEST | THREAD_CHECKPOINT_REQUEST), THREAD_FLAGS_OFFSET(%eax)
- jz 1f
- movl %eax, OUT_ARG0(%esp)
- call MterpSuspendCheck
-1:
mov $$1, %eax
MterpDone:
/* Restore callee save register */
diff --git a/runtime/interpreter/mterp/x86/op_check_cast.S b/runtime/interpreter/mterp/x86/op_check_cast.S
index 3d85f5e404..018432a92a 100644
--- a/runtime/interpreter/mterp/x86/op_check_cast.S
+++ b/runtime/interpreter/mterp/x86/op_check_cast.S
@@ -5,13 +5,13 @@
EXPORT_PC
movzwl 2(rPC), %eax # eax <- BBBB
movl %eax, OUT_ARG0(%esp)
- GET_VREG %ecx rINST
+ leal VREG_ADDRESS(rINST), %ecx
movl %ecx, OUT_ARG1(%esp)
movl OFF_FP_METHOD(rFP),%eax
movl %eax, OUT_ARG2(%esp)
movl rSELF, %ecx
movl %ecx, OUT_ARG3(%esp)
- call MterpCheckCast # (index, obj, method, self)
+ call MterpCheckCast # (index, &obj, method, self)
REFRESH_IBASE
testl %eax, %eax
jnz MterpPossibleException
diff --git a/runtime/interpreter/mterp/x86/op_instance_of.S b/runtime/interpreter/mterp/x86/op_instance_of.S
index cfbd4a0353..c9bfba5c36 100644
--- a/runtime/interpreter/mterp/x86/op_instance_of.S
+++ b/runtime/interpreter/mterp/x86/op_instance_of.S
@@ -10,13 +10,13 @@
movl %eax, OUT_ARG0(%esp)
movl rINST, %eax # eax <- BA
sarl $$4, %eax # eax <- B
- GET_VREG %ecx %eax # Get object
+ leal VREG_ADDRESS(%eax), %ecx # Get object address
movl %ecx, OUT_ARG1(%esp)
movl OFF_FP_METHOD(rFP),%eax
movl %eax, OUT_ARG2(%esp)
movl rSELF, %ecx
movl %ecx, OUT_ARG3(%esp)
- call MterpInstanceOf # (index, obj, method, self)
+ call MterpInstanceOf # (index, &obj, method, self)
movl rSELF, %ecx
REFRESH_IBASE_FROM_SELF %ecx
cmpl $$0, THREAD_EXCEPTION_OFFSET(%ecx)
diff --git a/runtime/interpreter/mterp/x86/op_return.S b/runtime/interpreter/mterp/x86/op_return.S
index 1658322e52..183b3bfdd5 100644
--- a/runtime/interpreter/mterp/x86/op_return.S
+++ b/runtime/interpreter/mterp/x86/op_return.S
@@ -6,6 +6,12 @@
/* op vAA */
.extern MterpThreadFenceForConstructor
call MterpThreadFenceForConstructor
+ movl rSELF, %eax
+ testl $$(THREAD_SUSPEND_REQUEST | THREAD_CHECKPOINT_REQUEST), THREAD_FLAGS_OFFSET(%eax)
+ jz 1f
+ movl %eax, OUT_ARG0(%esp)
+ call MterpSuspendCheck
+1:
GET_VREG %eax rINST # eax <- vAA
xorl %ecx, %ecx
jmp MterpReturn
diff --git a/runtime/interpreter/mterp/x86/op_return_void.S b/runtime/interpreter/mterp/x86/op_return_void.S
index b74446e1c2..f3e24c7990 100644
--- a/runtime/interpreter/mterp/x86/op_return_void.S
+++ b/runtime/interpreter/mterp/x86/op_return_void.S
@@ -1,5 +1,11 @@
.extern MterpThreadFenceForConstructor
call MterpThreadFenceForConstructor
+ movl rSELF, %eax
+ testl $$(THREAD_SUSPEND_REQUEST | THREAD_CHECKPOINT_REQUEST), THREAD_FLAGS_OFFSET(%eax)
+ jz 1f
+ movl %eax, OUT_ARG0(%esp)
+ call MterpSuspendCheck
+1:
xorl %eax, %eax
xorl %ecx, %ecx
jmp MterpReturn
diff --git a/runtime/interpreter/mterp/x86/op_return_void_no_barrier.S b/runtime/interpreter/mterp/x86/op_return_void_no_barrier.S
index abc7c4d745..add4e203fb 100644
--- a/runtime/interpreter/mterp/x86/op_return_void_no_barrier.S
+++ b/runtime/interpreter/mterp/x86/op_return_void_no_barrier.S
@@ -1,3 +1,9 @@
+ movl rSELF, %eax
+ testl $$(THREAD_SUSPEND_REQUEST | THREAD_CHECKPOINT_REQUEST), THREAD_FLAGS_OFFSET(%eax)
+ jz 1f
+ movl %eax, OUT_ARG0(%esp)
+ call MterpSuspendCheck
+1:
xorl %eax, %eax
xorl %ecx, %ecx
jmp MterpReturn
diff --git a/runtime/interpreter/mterp/x86/op_return_wide.S b/runtime/interpreter/mterp/x86/op_return_wide.S
index 00effd66cd..34a3380326 100644
--- a/runtime/interpreter/mterp/x86/op_return_wide.S
+++ b/runtime/interpreter/mterp/x86/op_return_wide.S
@@ -4,6 +4,12 @@
/* return-wide vAA */
.extern MterpThreadFenceForConstructor
call MterpThreadFenceForConstructor
+ movl rSELF, %eax
+ testl $$(THREAD_SUSPEND_REQUEST | THREAD_CHECKPOINT_REQUEST), THREAD_FLAGS_OFFSET(%eax)
+ jz 1f
+ movl %eax, OUT_ARG0(%esp)
+ call MterpSuspendCheck
+1:
GET_VREG %eax rINST # eax <- v[AA+0]
GET_VREG_HIGH %ecx rINST # ecx <- v[AA+1]
jmp MterpReturn