diff options
| -rw-r--r-- | runtime/interpreter/interpreter_common.h | 10 | ||||
| -rw-r--r-- | runtime/interpreter/mterp/arm/arithmetic.S | 2 | ||||
| -rw-r--r-- | runtime/interpreter/mterp/arm/floating_point.S | 11 | ||||
| -rw-r--r-- | runtime/interpreter/mterp/arm/main.S | 6 | ||||
| -rw-r--r-- | runtime/interpreter/shadow_frame.h | 11 | ||||
| -rw-r--r-- | runtime/thread-inl.h | 1 |
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); } |