summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/interpreter/interpreter_common.h10
-rw-r--r--runtime/interpreter/mterp/arm/arithmetic.S2
-rw-r--r--runtime/interpreter/mterp/arm/floating_point.S11
-rw-r--r--runtime/interpreter/mterp/arm/main.S6
-rw-r--r--runtime/interpreter/shadow_frame.h11
-rw-r--r--runtime/thread-inl.h1
6 files changed, 28 insertions, 13 deletions
diff --git a/runtime/interpreter/interpreter_common.h b/runtime/interpreter/interpreter_common.h
index 96588c8738..ac68a4bc81 100644
--- a/runtime/interpreter/interpreter_common.h
+++ b/runtime/interpreter/interpreter_common.h
@@ -242,6 +242,10 @@ static ALWAYS_INLINE bool DoInvoke(Thread* self,
return false;
}
+ if (jit != nullptr) {
+ jit->AddSamples(self, called_method, 1, /* with_backedges */false);
+ }
+
// Create shadow frame on the stack.
const char* old_cause = self->StartAssertNoThreadSuspension("DoFastInvoke");
ShadowFrameAllocaUniquePtr shadow_frame_unique_ptr =
@@ -261,13 +265,9 @@ static ALWAYS_INLINE bool DoInvoke(Thread* self,
*new_shadow_frame->GetShadowRefAddr(dst) = *shadow_frame.GetShadowRefAddr(arg[i]);
}
}
+ self->PushShadowFrame(new_shadow_frame);
self->EndAssertNoThreadSuspension(old_cause);
- if (jit != nullptr) {
- jit->AddSamples(self, called_method, 1, /* with_backedges */false);
- }
-
- self->PushShadowFrame(new_shadow_frame);
DCheckStaticState(self, called_method);
while (true) {
// Mterp does not support all instrumentation/debugging.
diff --git a/runtime/interpreter/mterp/arm/arithmetic.S b/runtime/interpreter/mterp/arm/arithmetic.S
index 6413b63627..7a373c7e3a 100644
--- a/runtime/interpreter/mterp/arm/arithmetic.S
+++ b/runtime/interpreter/mterp/arm/arithmetic.S
@@ -234,7 +234,7 @@
* that specifies an instruction that performs "result = op r0/r1", where
* "result" is a 32-bit quantity in r0.
*
- * For: long-to-float, double-to-int, double-to-float
+ * For: long-to-float
*
* (This would work for long-to-int, but that instruction is actually
* an exact match for op_move.)
diff --git a/runtime/interpreter/mterp/arm/floating_point.S b/runtime/interpreter/mterp/arm/floating_point.S
index 6bf54e8de0..21c386eb6a 100644
--- a/runtime/interpreter/mterp/arm/floating_point.S
+++ b/runtime/interpreter/mterp/arm/floating_point.S
@@ -19,8 +19,7 @@
FETCH_ADVANCE_INST 2 @ advance rPC, load rINST
$instr @ s2<- op
GET_INST_OPCODE ip @ extract opcode from rINST
- VREG_INDEX_TO_ADDR r9, r9 @ r9<- &vAA
- fsts s2, [r9] @ vAA<- s2
+ SET_VREG_FLOAT s2, r9, lr @ vAA<- s2
GOTO_OPCODE ip @ jump to next instruction
%def fbinop2addr(instr=""):
@@ -41,7 +40,7 @@
flds s0, [r9] @ s0<- vA
$instr @ s2<- op
GET_INST_OPCODE ip @ extract opcode from rINST
- fsts s2, [r9] @ vAA<- s2
+ fsts s2, [r9] @ vAA<- s2 No need to clear as it's 2addr
GOTO_OPCODE ip @ jump to next instruction
%def fbinopWide(instr=""):
@@ -107,8 +106,7 @@
FETCH_ADVANCE_INST 1 @ advance rPC, load rINST
$instr @ s1<- op
GET_INST_OPCODE ip @ extract opcode from rINST
- VREG_INDEX_TO_ADDR r9, r9 @ r9<- &vA
- fsts s1, [r9] @ vA<- s1
+ SET_VREG_FLOAT s1, r9, lr @ vA<- s1
GOTO_OPCODE ip @ jump to next instruction
%def funopNarrower(instr=""):
@@ -126,8 +124,7 @@
FETCH_ADVANCE_INST 1 @ advance rPC, load rINST
$instr @ s0<- op
GET_INST_OPCODE ip @ extract opcode from rINST
- VREG_INDEX_TO_ADDR r9, r9 @ r9<- &vA
- fsts s0, [r9] @ vA<- s0
+ SET_VREG_FLOAT s0, r9, lr @ vA<- s0
GOTO_OPCODE ip @ jump to next instruction
%def funopWider(instr=""):
diff --git a/runtime/interpreter/mterp/arm/main.S b/runtime/interpreter/mterp/arm/main.S
index a9cffe77a7..6d6b1901ef 100644
--- a/runtime/interpreter/mterp/arm/main.S
+++ b/runtime/interpreter/mterp/arm/main.S
@@ -274,6 +274,12 @@ unspecified registers or condition codes.
.macro SET_VREG_SHADOW reg, vreg
str \reg, [rREFS, \vreg, lsl #2]
.endm
+.macro SET_VREG_FLOAT reg, vreg, tmpreg
+ add \tmpreg, rFP, \vreg, lsl #2
+ fsts \reg, [\tmpreg]
+ mov \tmpreg, #0
+ str \tmpreg, [rREFS, \vreg, lsl #2]
+.endm
/*
* Clear the corresponding shadow regs for a vreg pair
diff --git a/runtime/interpreter/shadow_frame.h b/runtime/interpreter/shadow_frame.h
index c0920a8466..660902142b 100644
--- a/runtime/interpreter/shadow_frame.h
+++ b/runtime/interpreter/shadow_frame.h
@@ -375,6 +375,17 @@ class ShadowFrame {
UpdateFrameFlag(enable, FrameFlags::kForceRetryInst);
}
+ void CheckConsistentVRegs() const {
+ if (kIsDebugBuild) {
+ // A shadow frame visible to GC requires the following rule: for a given vreg,
+ // its vreg reference equivalent should be the same, or null.
+ for (uint32_t i = 0; i < NumberOfVRegs(); ++i) {
+ int32_t reference_value = References()[i].AsVRegValue();
+ CHECK((GetVReg(i) == reference_value) || (reference_value == 0));
+ }
+ }
+ }
+
private:
ShadowFrame(uint32_t num_vregs, ShadowFrame* link, ArtMethod* method,
uint32_t dex_pc, bool has_reference_array)
diff --git a/runtime/thread-inl.h b/runtime/thread-inl.h
index 91c27af407..0c00fb93ac 100644
--- a/runtime/thread-inl.h
+++ b/runtime/thread-inl.h
@@ -385,6 +385,7 @@ inline bool Thread::ModifySuspendCount(Thread* self,
}
inline ShadowFrame* Thread::PushShadowFrame(ShadowFrame* new_top_frame) {
+ new_top_frame->CheckConsistentVRegs();
return tlsPtr_.managed_stack.PushShadowFrame(new_top_frame);
}