From db045bea24d28ce6ad932fec4ce055af7be530e2 Mon Sep 17 00:00:00 2001 From: Alexey Frunze Date: Thu, 3 Mar 2016 17:50:48 -0800 Subject: [PATCH] ART: Enable JitProfiling for MIPS64 Mterp Change-Id: I46bdbfd706569ebbb1d1b08b9060ff01518d0f3a --- runtime/interpreter/mterp/mips64/bincmp.S | 30 +- runtime/interpreter/mterp/mips64/footer.S | 20 +- runtime/interpreter/mterp/mips64/header.S | 9 +- runtime/interpreter/mterp/mips64/invoke.S | 3 + runtime/interpreter/mterp/mips64/op_goto.S | 28 +- runtime/interpreter/mterp/mips64/op_goto_16.S | 26 +- runtime/interpreter/mterp/mips64/op_goto_32.S | 28 +- .../interpreter/mterp/mips64/op_packed_switch.S | 23 +- runtime/interpreter/mterp/mips64/zcmp.S | 30 +- runtime/interpreter/mterp/mterp.cc | 11 +- runtime/interpreter/mterp/out/mterp_mips64.S | 553 ++++++++++++--------- 11 files changed, 420 insertions(+), 341 deletions(-) diff --git a/runtime/interpreter/mterp/mips64/bincmp.S b/runtime/interpreter/mterp/mips64/bincmp.S index d39c9009b..aa5e74b3d 100644 --- a/runtime/interpreter/mterp/mips64/bincmp.S +++ b/runtime/interpreter/mterp/mips64/bincmp.S @@ -6,27 +6,27 @@ * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le */ /* if-cmp vA, vB, +CCCC */ - lh a4, 2(rPC) # a4 <- sign-extended CCCC + .extern MterpProfileBranch ext a2, rINST, 8, 4 # a2 <- A ext a3, rINST, 12, 4 # a3 <- B + lh rINST, 2(rPC) # rINST <- offset (sign-extended CCCC) GET_VREG a0, a2 # a0 <- vA GET_VREG a1, a3 # a1 <- vB - b${condition}c a0, a1, 1f - li a4, 2 # offset if branch not taken + li rINST, 2 # offset if branch not taken 1: - - dlsa rPC, a4, rPC, 1 # rPC <- rPC + CCCC * 2 - FETCH_INST # load rINST - -#if MTERP_SUSPEND - bgez a4, 2f # CCCC * 2 >= 0 => no suspend check - REFRESH_IBASE -2: -#else - lw ra, THREAD_FLAGS_OFFSET(rSELF) # Preload flags for MterpCheckSuspendAndContinue - bltz a4, MterpCheckSuspendAndContinue +#if MTERP_PROFILE_BRANCHES + EXPORT_PC + move a0, rSELF + daddu a1, rFP, OFF_FP_SHADOWFRAME + move a2, rINST + jal MterpProfileBranch # (self, shadow_frame, offset) + bnezc v0, MterpOnStackReplacement # Note: offset must be in rINST #endif - + dlsa rPC, rINST, rPC, 1 # rPC <- rPC + offset * 2 + lw ra, THREAD_FLAGS_OFFSET(rSELF) # Preload flags for MterpCheckSuspendAndContinue + move a0, rINST # a0 <- offset + FETCH_INST # load rINST + bltz a0, MterpCheckSuspendAndContinue # suspend check if backwards branch GET_INST_OPCODE v0 # extract opcode from rINST GOTO_OPCODE v0 # jump to next instruction diff --git a/runtime/interpreter/mterp/mips64/footer.S b/runtime/interpreter/mterp/mips64/footer.S index 1a2e22b67..14d5fe01f 100644 --- a/runtime/interpreter/mterp/mips64/footer.S +++ b/runtime/interpreter/mterp/mips64/footer.S @@ -49,6 +49,7 @@ MterpPossibleException: * */ .extern MterpHandleException + .extern MterpShouldSwitchInterpreters MterpException: move a0, rSELF daddu a1, rFP, OFF_FP_SHADOWFRAME @@ -59,8 +60,11 @@ MterpException: REFRESH_IBASE daddu rPC, a0, CODEITEM_INSNS_OFFSET dlsa rPC, a1, rPC, 1 # generate new dex_pc_ptr - sd rPC, OFF_FP_DEX_PC_PTR(rFP) + /* Do we need to switch interpreters? */ + jal MterpShouldSwitchInterpreters + bnezc v0, MterpFallback /* resume execution at catch block */ + EXPORT_PC FETCH_INST GET_INST_OPCODE v0 GOTO_OPCODE v0 @@ -81,10 +85,24 @@ check1: EXPORT_PC move a0, rSELF jal MterpSuspendCheck # (self) + bnezc v0, MterpFallback # Something in the environment changed, switch interpreters GET_INST_OPCODE v0 # extract opcode from rINST GOTO_OPCODE v0 # jump to next instruction /* + * On-stack replacement has happened, and now we've returned from the compiled method. + */ +MterpOnStackReplacement: +#if MTERP_LOGGING + move a0, rSELF + daddu a1, rFP, OFF_FP_SHADOWFRAME + move a2, rINST # rINST contains offset + jal MterpLogOSR +#endif + li v0, 1 # Signal normal return + b MterpDone + +/* * Bail out to reference interpreter. */ .extern MterpLogFallback diff --git a/runtime/interpreter/mterp/mips64/header.S b/runtime/interpreter/mterp/mips64/header.S index 4c3ca9eff..dd0fbe005 100644 --- a/runtime/interpreter/mterp/mips64/header.S +++ b/runtime/interpreter/mterp/mips64/header.S @@ -82,14 +82,7 @@ The following registers have fixed assignments: #define OFF_FP_CODE_ITEM OFF_FP(SHADOWFRAME_CODE_ITEM_OFFSET) #define OFF_FP_SHADOWFRAME (-SHADOWFRAME_VREGS_OFFSET) -/* - * - * The reference interpreter performs explicit suspect checks, which is somewhat wasteful. - * Dalvik's interpreter folded suspend checks into the jump table mechanism, and eventually - * mterp should do so as well. - */ -#define MTERP_SUSPEND 0 - +#define MTERP_PROFILE_BRANCHES 1 #define MTERP_LOGGING 0 /* diff --git a/runtime/interpreter/mterp/mips64/invoke.S b/runtime/interpreter/mterp/mips64/invoke.S index 4ae4fb1c1..be647b618 100644 --- a/runtime/interpreter/mterp/mips64/invoke.S +++ b/runtime/interpreter/mterp/mips64/invoke.S @@ -5,6 +5,7 @@ /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ .extern $helper + .extern MterpShouldSwitchInterpreters EXPORT_PC move a0, rSELF daddu a1, rFP, OFF_FP_SHADOWFRAME @@ -13,5 +14,7 @@ jal $helper beqzc v0, MterpException FETCH_ADVANCE_INST 3 + jal MterpShouldSwitchInterpreters + bnezc v0, MterpFallback GET_INST_OPCODE v0 GOTO_OPCODE v0 diff --git a/runtime/interpreter/mterp/mips64/op_goto.S b/runtime/interpreter/mterp/mips64/op_goto.S index f2df3e411..7c7d0ecf5 100644 --- a/runtime/interpreter/mterp/mips64/op_goto.S +++ b/runtime/interpreter/mterp/mips64/op_goto.S @@ -5,19 +5,21 @@ * double to get a byte offset. */ /* goto +AA */ - srl a0, rINST, 8 - seb a0, a0 # a0 <- sign-extended AA - dlsa rPC, a0, rPC, 1 # rPC <- rPC + AA * 2 - FETCH_INST # load rINST - -#if MTERP_SUSPEND - bgez a0, 1f # AA * 2 >= 0 => no suspend check - REFRESH_IBASE -1: -#else - lw ra, THREAD_FLAGS_OFFSET(rSELF) # Preload flags for MterpCheckSuspendAndContinue - bltz a0, MterpCheckSuspendAndContinue + .extern MterpProfileBranch + srl rINST, rINST, 8 + seb rINST, rINST # rINST <- offset (sign-extended AA) +#if MTERP_PROFILE_BRANCHES + EXPORT_PC + move a0, rSELF + daddu a1, rFP, OFF_FP_SHADOWFRAME + move a2, rINST + jal MterpProfileBranch # (self, shadow_frame, offset) + bnezc v0, MterpOnStackReplacement # Note: offset must be in rINST #endif - + dlsa rPC, rINST, rPC, 1 # rPC <- rPC + offset * 2 + lw ra, THREAD_FLAGS_OFFSET(rSELF) # Preload flags for MterpCheckSuspendAndContinue + move a0, rINST # a0 <- offset + FETCH_INST # load rINST + bltz a0, MterpCheckSuspendAndContinue # suspend check if backwards branch GET_INST_OPCODE v0 # extract opcode from rINST GOTO_OPCODE v0 # jump to next instruction diff --git a/runtime/interpreter/mterp/mips64/op_goto_16.S b/runtime/interpreter/mterp/mips64/op_goto_16.S index cbf8cf299..566e3a78f 100644 --- a/runtime/interpreter/mterp/mips64/op_goto_16.S +++ b/runtime/interpreter/mterp/mips64/op_goto_16.S @@ -5,18 +5,20 @@ * double to get a byte offset. */ /* goto/16 +AAAA */ - lh a0, 2(rPC) # a0 <- sign-extended AAAA - dlsa rPC, a0, rPC, 1 # rPC <- rPC + AAAA * 2 - FETCH_INST # load rINST - -#if MTERP_SUSPEND - bgez a0, 1f # AA * 2 >= 0 => no suspend check - REFRESH_IBASE -1: -#else - lw ra, THREAD_FLAGS_OFFSET(rSELF) # Preload flags for MterpCheckSuspendAndContinue - bltz a0, MterpCheckSuspendAndContinue + .extern MterpProfileBranch + lh rINST, 2(rPC) # rINST <- offset (sign-extended AAAA) +#if MTERP_PROFILE_BRANCHES + EXPORT_PC + move a0, rSELF + daddu a1, rFP, OFF_FP_SHADOWFRAME + move a2, rINST + jal MterpProfileBranch # (self, shadow_frame, offset) + bnezc v0, MterpOnStackReplacement # Note: offset must be in rINST #endif - + dlsa rPC, rINST, rPC, 1 # rPC <- rPC + offset * 2 + lw ra, THREAD_FLAGS_OFFSET(rSELF) # Preload flags for MterpCheckSuspendAndContinue + move a0, rINST # a0 <- offset + FETCH_INST # load rINST + bltz a0, MterpCheckSuspendAndContinue # suspend check if backwards branch GET_INST_OPCODE v0 # extract opcode from rINST GOTO_OPCODE v0 # jump to next instruction diff --git a/runtime/interpreter/mterp/mips64/op_goto_32.S b/runtime/interpreter/mterp/mips64/op_goto_32.S index 4a1feac1a..b260083ae 100644 --- a/runtime/interpreter/mterp/mips64/op_goto_32.S +++ b/runtime/interpreter/mterp/mips64/op_goto_32.S @@ -8,20 +8,22 @@ * our "backward branch" test must be "<=0" instead of "<0". */ /* goto/32 +AAAAAAAA */ - lh a0, 2(rPC) # a0 <- aaaa (low) + .extern MterpProfileBranch + lh rINST, 2(rPC) # rINST <- aaaa (low) lh a1, 4(rPC) # a1 <- AAAA (high) - ins a0, a1, 16, 16 # a0 = sign-extended AAAAaaaa - dlsa rPC, a0, rPC, 1 # rPC <- rPC + AAAAAAAA * 2 - FETCH_INST # load rINST - -#if MTERP_SUSPEND - bgtz a0, 1f # AA * 2 > 0 => no suspend check - REFRESH_IBASE -1: -#else - lw ra, THREAD_FLAGS_OFFSET(rSELF) # Preload flags for MterpCheckSuspendAndContinue - blez a0, MterpCheckSuspendAndContinue + ins rINST, a1, 16, 16 # rINST <- offset (sign-extended AAAAaaaa) +#if MTERP_PROFILE_BRANCHES + EXPORT_PC + move a0, rSELF + daddu a1, rFP, OFF_FP_SHADOWFRAME + move a2, rINST + jal MterpProfileBranch # (self, shadow_frame, offset) + bnezc v0, MterpOnStackReplacement # Note: offset must be in rINST #endif - + dlsa rPC, rINST, rPC, 1 # rPC <- rPC + offset * 2 + lw ra, THREAD_FLAGS_OFFSET(rSELF) # Preload flags for MterpCheckSuspendAndContinue + move a0, rINST # a0 <- offset + FETCH_INST # load rINST + blez a0, MterpCheckSuspendAndContinue # suspend check if backwards branch GET_INST_OPCODE v0 # extract opcode from rINST GOTO_OPCODE v0 # jump to next instruction diff --git a/runtime/interpreter/mterp/mips64/op_packed_switch.S b/runtime/interpreter/mterp/mips64/op_packed_switch.S index cdbdf7532..2c6eb2f3c 100644 --- a/runtime/interpreter/mterp/mips64/op_packed_switch.S +++ b/runtime/interpreter/mterp/mips64/op_packed_switch.S @@ -10,6 +10,7 @@ */ /* op vAA, +BBBBBBBB */ .extern $func + .extern MterpProfileBranch lh a0, 2(rPC) # a0 <- bbbb (lo) lh a1, 4(rPC) # a1 <- BBBB (hi) srl a3, rINST, 8 # a3 <- AA @@ -17,15 +18,19 @@ GET_VREG a1, a3 # a1 <- vAA dlsa a0, a0, rPC, 1 # a0 <- PC + BBBBbbbb*2 jal $func # v0 <- code-unit branch offset - dlsa rPC, v0, rPC, 1 # rPC <- rPC + offset * 2 - FETCH_INST # load rINST -#if MTERP_SUSPEND - bgtz v0, 1f # offset * 2 > 0 => no suspend check - REFRESH_IBASE -1: -#else - lw ra, THREAD_FLAGS_OFFSET(rSELF) # Preload flags for MterpCheckSuspendAndContinue - blez v0, MterpCheckSuspendAndContinue + move rINST, v0 +#if MTERP_PROFILE_BRANCHES + EXPORT_PC + move a0, rSELF + daddu a1, rFP, OFF_FP_SHADOWFRAME + move a2, rINST + jal MterpProfileBranch # (self, shadow_frame, offset) + bnezc v0, MterpOnStackReplacement # Note: offset must be in rINST #endif + dlsa rPC, rINST, rPC, 1 # rPC <- rPC + offset * 2 + lw ra, THREAD_FLAGS_OFFSET(rSELF) # Preload flags for MterpCheckSuspendAndContinue + move a0, rINST # a0 <- offset + FETCH_INST # load rINST + blez a0, MterpCheckSuspendAndContinue # suspend check if backwards branch GET_INST_OPCODE v0 # extract opcode from rINST GOTO_OPCODE v0 # jump to next instruction diff --git a/runtime/interpreter/mterp/mips64/zcmp.S b/runtime/interpreter/mterp/mips64/zcmp.S index d7ad89448..0e0477fad 100644 --- a/runtime/interpreter/mterp/mips64/zcmp.S +++ b/runtime/interpreter/mterp/mips64/zcmp.S @@ -6,25 +6,25 @@ * For: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez */ /* if-cmp vAA, +BBBB */ - lh a4, 2(rPC) # a4 <- sign-extended BBBB + .extern MterpProfileBranch srl a2, rINST, 8 # a2 <- AA + lh rINST, 2(rPC) # rINST <- offset (sign-extended BBBB) GET_VREG a0, a2 # a0 <- vAA - b${condition}zc a0, 1f - li a4, 2 # offset if branch not taken + li rINST, 2 # offset if branch not taken 1: - - dlsa rPC, a4, rPC, 1 # rPC <- rPC + BBBB * 2 - FETCH_INST # load rINST - -#if MTERP_SUSPEND - bgez a4, 2f # BBBB * 2 >= 0 => no suspend check - REFRESH_IBASE -2: -#else - lw ra, THREAD_FLAGS_OFFSET(rSELF) # Preload flags for MterpCheckSuspendAndContinue - bltz a4, MterpCheckSuspendAndContinue +#if MTERP_PROFILE_BRANCHES + EXPORT_PC + move a0, rSELF + daddu a1, rFP, OFF_FP_SHADOWFRAME + move a2, rINST + jal MterpProfileBranch # (self, shadow_frame, offset) + bnezc v0, MterpOnStackReplacement # Note: offset must be in rINST #endif - + dlsa rPC, rINST, rPC, 1 # rPC <- rPC + offset * 2 + lw ra, THREAD_FLAGS_OFFSET(rSELF) # Preload flags for MterpCheckSuspendAndContinue + move a0, rINST # a0 <- offset + FETCH_INST # load rINST + bltz a0, MterpCheckSuspendAndContinue # suspend check if backwards branch GET_INST_OPCODE v0 # extract opcode from rINST GOTO_OPCODE v0 # jump to next instruction diff --git a/runtime/interpreter/mterp/mterp.cc b/runtime/interpreter/mterp/mterp.cc index ca727f47b..10b19c5f4 100644 --- a/runtime/interpreter/mterp/mterp.cc +++ b/runtime/interpreter/mterp/mterp.cc @@ -147,16 +147,7 @@ extern "C" bool MterpShouldSwitchInterpreters() SHARED_REQUIRES(Locks::mutator_lock_) { const instrumentation::Instrumentation* const instrumentation = Runtime::Current()->GetInstrumentation(); - bool unhandled_instrumentation; - // TODO: enable for other targets after more extensive testing. - if ((kRuntimeISA == kArm64) || (kRuntimeISA == kArm) || - (kRuntimeISA == kX86_64) || (kRuntimeISA == kX86) || - (kRuntimeISA == kMips)) { - unhandled_instrumentation = instrumentation->NonJitProfilingActive(); - } else { - unhandled_instrumentation = instrumentation->IsActive(); - } - return unhandled_instrumentation || Dbg::IsDebuggerActive(); + return instrumentation->NonJitProfilingActive() || Dbg::IsDebuggerActive(); } diff --git a/runtime/interpreter/mterp/out/mterp_mips64.S b/runtime/interpreter/mterp/out/mterp_mips64.S index 7cef823ff..a17252b2f 100644 --- a/runtime/interpreter/mterp/out/mterp_mips64.S +++ b/runtime/interpreter/mterp/out/mterp_mips64.S @@ -89,14 +89,7 @@ The following registers have fixed assignments: #define OFF_FP_CODE_ITEM OFF_FP(SHADOWFRAME_CODE_ITEM_OFFSET) #define OFF_FP_SHADOWFRAME (-SHADOWFRAME_VREGS_OFFSET) -/* - * - * The reference interpreter performs explicit suspect checks, which is somewhat wasteful. - * Dalvik's interpreter folded suspend checks into the jump table mechanism, and eventually - * mterp should do so as well. - */ -#define MTERP_SUSPEND 0 - +#define MTERP_PROFILE_BRANCHES 1 #define MTERP_LOGGING 0 /* @@ -1107,20 +1100,22 @@ artMterpAsmInstructionStart = .L_op_nop * double to get a byte offset. */ /* goto +AA */ - srl a0, rINST, 8 - seb a0, a0 # a0 <- sign-extended AA - dlsa rPC, a0, rPC, 1 # rPC <- rPC + AA * 2 - FETCH_INST # load rINST - -#if MTERP_SUSPEND - bgez a0, 1f # AA * 2 >= 0 => no suspend check - REFRESH_IBASE -1: -#else - lw ra, THREAD_FLAGS_OFFSET(rSELF) # Preload flags for MterpCheckSuspendAndContinue - bltz a0, MterpCheckSuspendAndContinue + .extern MterpProfileBranch + srl rINST, rINST, 8 + seb rINST, rINST # rINST <- offset (sign-extended AA) +#if MTERP_PROFILE_BRANCHES + EXPORT_PC + move a0, rSELF + daddu a1, rFP, OFF_FP_SHADOWFRAME + move a2, rINST + jal MterpProfileBranch # (self, shadow_frame, offset) + bnezc v0, MterpOnStackReplacement # Note: offset must be in rINST #endif - + dlsa rPC, rINST, rPC, 1 # rPC <- rPC + offset * 2 + lw ra, THREAD_FLAGS_OFFSET(rSELF) # Preload flags for MterpCheckSuspendAndContinue + move a0, rINST # a0 <- offset + FETCH_INST # load rINST + bltz a0, MterpCheckSuspendAndContinue # suspend check if backwards branch GET_INST_OPCODE v0 # extract opcode from rINST GOTO_OPCODE v0 # jump to next instruction @@ -1135,19 +1130,21 @@ artMterpAsmInstructionStart = .L_op_nop * double to get a byte offset. */ /* goto/16 +AAAA */ - lh a0, 2(rPC) # a0 <- sign-extended AAAA - dlsa rPC, a0, rPC, 1 # rPC <- rPC + AAAA * 2 - FETCH_INST # load rINST - -#if MTERP_SUSPEND - bgez a0, 1f # AA * 2 >= 0 => no suspend check - REFRESH_IBASE -1: -#else - lw ra, THREAD_FLAGS_OFFSET(rSELF) # Preload flags for MterpCheckSuspendAndContinue - bltz a0, MterpCheckSuspendAndContinue + .extern MterpProfileBranch + lh rINST, 2(rPC) # rINST <- offset (sign-extended AAAA) +#if MTERP_PROFILE_BRANCHES + EXPORT_PC + move a0, rSELF + daddu a1, rFP, OFF_FP_SHADOWFRAME + move a2, rINST + jal MterpProfileBranch # (self, shadow_frame, offset) + bnezc v0, MterpOnStackReplacement # Note: offset must be in rINST #endif - + dlsa rPC, rINST, rPC, 1 # rPC <- rPC + offset * 2 + lw ra, THREAD_FLAGS_OFFSET(rSELF) # Preload flags for MterpCheckSuspendAndContinue + move a0, rINST # a0 <- offset + FETCH_INST # load rINST + bltz a0, MterpCheckSuspendAndContinue # suspend check if backwards branch GET_INST_OPCODE v0 # extract opcode from rINST GOTO_OPCODE v0 # jump to next instruction @@ -1165,21 +1162,23 @@ artMterpAsmInstructionStart = .L_op_nop * our "backward branch" test must be "<=0" instead of "<0". */ /* goto/32 +AAAAAAAA */ - lh a0, 2(rPC) # a0 <- aaaa (low) + .extern MterpProfileBranch + lh rINST, 2(rPC) # rINST <- aaaa (low) lh a1, 4(rPC) # a1 <- AAAA (high) - ins a0, a1, 16, 16 # a0 = sign-extended AAAAaaaa - dlsa rPC, a0, rPC, 1 # rPC <- rPC + AAAAAAAA * 2 - FETCH_INST # load rINST - -#if MTERP_SUSPEND - bgtz a0, 1f # AA * 2 > 0 => no suspend check - REFRESH_IBASE -1: -#else - lw ra, THREAD_FLAGS_OFFSET(rSELF) # Preload flags for MterpCheckSuspendAndContinue - blez a0, MterpCheckSuspendAndContinue + ins rINST, a1, 16, 16 # rINST <- offset (sign-extended AAAAaaaa) +#if MTERP_PROFILE_BRANCHES + EXPORT_PC + move a0, rSELF + daddu a1, rFP, OFF_FP_SHADOWFRAME + move a2, rINST + jal MterpProfileBranch # (self, shadow_frame, offset) + bnezc v0, MterpOnStackReplacement # Note: offset must be in rINST #endif - + dlsa rPC, rINST, rPC, 1 # rPC <- rPC + offset * 2 + lw ra, THREAD_FLAGS_OFFSET(rSELF) # Preload flags for MterpCheckSuspendAndContinue + move a0, rINST # a0 <- offset + FETCH_INST # load rINST + blez a0, MterpCheckSuspendAndContinue # suspend check if backwards branch GET_INST_OPCODE v0 # extract opcode from rINST GOTO_OPCODE v0 # jump to next instruction @@ -1198,6 +1197,7 @@ artMterpAsmInstructionStart = .L_op_nop */ /* op vAA, +BBBBBBBB */ .extern MterpDoPackedSwitch + .extern MterpProfileBranch lh a0, 2(rPC) # a0 <- bbbb (lo) lh a1, 4(rPC) # a1 <- BBBB (hi) srl a3, rINST, 8 # a3 <- AA @@ -1205,16 +1205,20 @@ artMterpAsmInstructionStart = .L_op_nop GET_VREG a1, a3 # a1 <- vAA dlsa a0, a0, rPC, 1 # a0 <- PC + BBBBbbbb*2 jal MterpDoPackedSwitch # v0 <- code-unit branch offset - dlsa rPC, v0, rPC, 1 # rPC <- rPC + offset * 2 - FETCH_INST # load rINST -#if MTERP_SUSPEND - bgtz v0, 1f # offset * 2 > 0 => no suspend check - REFRESH_IBASE -1: -#else - lw ra, THREAD_FLAGS_OFFSET(rSELF) # Preload flags for MterpCheckSuspendAndContinue - blez v0, MterpCheckSuspendAndContinue + move rINST, v0 +#if MTERP_PROFILE_BRANCHES + EXPORT_PC + move a0, rSELF + daddu a1, rFP, OFF_FP_SHADOWFRAME + move a2, rINST + jal MterpProfileBranch # (self, shadow_frame, offset) + bnezc v0, MterpOnStackReplacement # Note: offset must be in rINST #endif + dlsa rPC, rINST, rPC, 1 # rPC <- rPC + offset * 2 + lw ra, THREAD_FLAGS_OFFSET(rSELF) # Preload flags for MterpCheckSuspendAndContinue + move a0, rINST # a0 <- offset + FETCH_INST # load rINST + blez a0, MterpCheckSuspendAndContinue # suspend check if backwards branch GET_INST_OPCODE v0 # extract opcode from rINST GOTO_OPCODE v0 # jump to next instruction @@ -1234,6 +1238,7 @@ artMterpAsmInstructionStart = .L_op_nop */ /* op vAA, +BBBBBBBB */ .extern MterpDoSparseSwitch + .extern MterpProfileBranch lh a0, 2(rPC) # a0 <- bbbb (lo) lh a1, 4(rPC) # a1 <- BBBB (hi) srl a3, rINST, 8 # a3 <- AA @@ -1241,16 +1246,20 @@ artMterpAsmInstructionStart = .L_op_nop GET_VREG a1, a3 # a1 <- vAA dlsa a0, a0, rPC, 1 # a0 <- PC + BBBBbbbb*2 jal MterpDoSparseSwitch # v0 <- code-unit branch offset - dlsa rPC, v0, rPC, 1 # rPC <- rPC + offset * 2 - FETCH_INST # load rINST -#if MTERP_SUSPEND - bgtz v0, 1f # offset * 2 > 0 => no suspend check - REFRESH_IBASE -1: -#else - lw ra, THREAD_FLAGS_OFFSET(rSELF) # Preload flags for MterpCheckSuspendAndContinue - blez v0, MterpCheckSuspendAndContinue + move rINST, v0 +#if MTERP_PROFILE_BRANCHES + EXPORT_PC + move a0, rSELF + daddu a1, rFP, OFF_FP_SHADOWFRAME + move a2, rINST + jal MterpProfileBranch # (self, shadow_frame, offset) + bnezc v0, MterpOnStackReplacement # Note: offset must be in rINST #endif + dlsa rPC, rINST, rPC, 1 # rPC <- rPC + offset * 2 + lw ra, THREAD_FLAGS_OFFSET(rSELF) # Preload flags for MterpCheckSuspendAndContinue + move a0, rINST # a0 <- offset + FETCH_INST # load rINST + blez a0, MterpCheckSuspendAndContinue # suspend check if backwards branch GET_INST_OPCODE v0 # extract opcode from rINST GOTO_OPCODE v0 # jump to next instruction @@ -1438,28 +1447,28 @@ artMterpAsmInstructionStart = .L_op_nop * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le */ /* if-cmp vA, vB, +CCCC */ - lh a4, 2(rPC) # a4 <- sign-extended CCCC + .extern MterpProfileBranch ext a2, rINST, 8, 4 # a2 <- A ext a3, rINST, 12, 4 # a3 <- B + lh rINST, 2(rPC) # rINST <- offset (sign-extended CCCC) GET_VREG a0, a2 # a0 <- vA GET_VREG a1, a3 # a1 <- vB - beqc a0, a1, 1f - li a4, 2 # offset if branch not taken + li rINST, 2 # offset if branch not taken 1: - - dlsa rPC, a4, rPC, 1 # rPC <- rPC + CCCC * 2 - FETCH_INST # load rINST - -#if MTERP_SUSPEND - bgez a4, 2f # CCCC * 2 >= 0 => no suspend check - REFRESH_IBASE -2: -#else - lw ra, THREAD_FLAGS_OFFSET(rSELF) # Preload flags for MterpCheckSuspendAndContinue - bltz a4, MterpCheckSuspendAndContinue +#if MTERP_PROFILE_BRANCHES + EXPORT_PC + move a0, rSELF + daddu a1, rFP, OFF_FP_SHADOWFRAME + move a2, rINST + jal MterpProfileBranch # (self, shadow_frame, offset) + bnezc v0, MterpOnStackReplacement # Note: offset must be in rINST #endif - + dlsa rPC, rINST, rPC, 1 # rPC <- rPC + offset * 2 + lw ra, THREAD_FLAGS_OFFSET(rSELF) # Preload flags for MterpCheckSuspendAndContinue + move a0, rINST # a0 <- offset + FETCH_INST # load rINST + bltz a0, MterpCheckSuspendAndContinue # suspend check if backwards branch GET_INST_OPCODE v0 # extract opcode from rINST GOTO_OPCODE v0 # jump to next instruction @@ -1477,28 +1486,28 @@ artMterpAsmInstructionStart = .L_op_nop * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le */ /* if-cmp vA, vB, +CCCC */ - lh a4, 2(rPC) # a4 <- sign-extended CCCC + .extern MterpProfileBranch ext a2, rINST, 8, 4 # a2 <- A ext a3, rINST, 12, 4 # a3 <- B + lh rINST, 2(rPC) # rINST <- offset (sign-extended CCCC) GET_VREG a0, a2 # a0 <- vA GET_VREG a1, a3 # a1 <- vB - bnec a0, a1, 1f - li a4, 2 # offset if branch not taken + li rINST, 2 # offset if branch not taken 1: - - dlsa rPC, a4, rPC, 1 # rPC <- rPC + CCCC * 2 - FETCH_INST # load rINST - -#if MTERP_SUSPEND - bgez a4, 2f # CCCC * 2 >= 0 => no suspend check - REFRESH_IBASE -2: -#else - lw ra, THREAD_FLAGS_OFFSET(rSELF) # Preload flags for MterpCheckSuspendAndContinue - bltz a4, MterpCheckSuspendAndContinue +#if MTERP_PROFILE_BRANCHES + EXPORT_PC + move a0, rSELF + daddu a1, rFP, OFF_FP_SHADOWFRAME + move a2, rINST + jal MterpProfileBranch # (self, shadow_frame, offset) + bnezc v0, MterpOnStackReplacement # Note: offset must be in rINST #endif - + dlsa rPC, rINST, rPC, 1 # rPC <- rPC + offset * 2 + lw ra, THREAD_FLAGS_OFFSET(rSELF) # Preload flags for MterpCheckSuspendAndContinue + move a0, rINST # a0 <- offset + FETCH_INST # load rINST + bltz a0, MterpCheckSuspendAndContinue # suspend check if backwards branch GET_INST_OPCODE v0 # extract opcode from rINST GOTO_OPCODE v0 # jump to next instruction @@ -1516,28 +1525,28 @@ artMterpAsmInstructionStart = .L_op_nop * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le */ /* if-cmp vA, vB, +CCCC */ - lh a4, 2(rPC) # a4 <- sign-extended CCCC + .extern MterpProfileBranch ext a2, rINST, 8, 4 # a2 <- A ext a3, rINST, 12, 4 # a3 <- B + lh rINST, 2(rPC) # rINST <- offset (sign-extended CCCC) GET_VREG a0, a2 # a0 <- vA GET_VREG a1, a3 # a1 <- vB - bltc a0, a1, 1f - li a4, 2 # offset if branch not taken + li rINST, 2 # offset if branch not taken 1: - - dlsa rPC, a4, rPC, 1 # rPC <- rPC + CCCC * 2 - FETCH_INST # load rINST - -#if MTERP_SUSPEND - bgez a4, 2f # CCCC * 2 >= 0 => no suspend check - REFRESH_IBASE -2: -#else - lw ra, THREAD_FLAGS_OFFSET(rSELF) # Preload flags for MterpCheckSuspendAndContinue - bltz a4, MterpCheckSuspendAndContinue +#if MTERP_PROFILE_BRANCHES + EXPORT_PC + move a0, rSELF + daddu a1, rFP, OFF_FP_SHADOWFRAME + move a2, rINST + jal MterpProfileBranch # (self, shadow_frame, offset) + bnezc v0, MterpOnStackReplacement # Note: offset must be in rINST #endif - + dlsa rPC, rINST, rPC, 1 # rPC <- rPC + offset * 2 + lw ra, THREAD_FLAGS_OFFSET(rSELF) # Preload flags for MterpCheckSuspendAndContinue + move a0, rINST # a0 <- offset + FETCH_INST # load rINST + bltz a0, MterpCheckSuspendAndContinue # suspend check if backwards branch GET_INST_OPCODE v0 # extract opcode from rINST GOTO_OPCODE v0 # jump to next instruction @@ -1555,28 +1564,28 @@ artMterpAsmInstructionStart = .L_op_nop * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le */ /* if-cmp vA, vB, +CCCC */ - lh a4, 2(rPC) # a4 <- sign-extended CCCC + .extern MterpProfileBranch ext a2, rINST, 8, 4 # a2 <- A ext a3, rINST, 12, 4 # a3 <- B + lh rINST, 2(rPC) # rINST <- offset (sign-extended CCCC) GET_VREG a0, a2 # a0 <- vA GET_VREG a1, a3 # a1 <- vB - bgec a0, a1, 1f - li a4, 2 # offset if branch not taken + li rINST, 2 # offset if branch not taken 1: - - dlsa rPC, a4, rPC, 1 # rPC <- rPC + CCCC * 2 - FETCH_INST # load rINST - -#if MTERP_SUSPEND - bgez a4, 2f # CCCC * 2 >= 0 => no suspend check - REFRESH_IBASE -2: -#else - lw ra, THREAD_FLAGS_OFFSET(rSELF) # Preload flags for MterpCheckSuspendAndContinue - bltz a4, MterpCheckSuspendAndContinue +#if MTERP_PROFILE_BRANCHES + EXPORT_PC + move a0, rSELF + daddu a1, rFP, OFF_FP_SHADOWFRAME + move a2, rINST + jal MterpProfileBranch # (self, shadow_frame, offset) + bnezc v0, MterpOnStackReplacement # Note: offset must be in rINST #endif - + dlsa rPC, rINST, rPC, 1 # rPC <- rPC + offset * 2 + lw ra, THREAD_FLAGS_OFFSET(rSELF) # Preload flags for MterpCheckSuspendAndContinue + move a0, rINST # a0 <- offset + FETCH_INST # load rINST + bltz a0, MterpCheckSuspendAndContinue # suspend check if backwards branch GET_INST_OPCODE v0 # extract opcode from rINST GOTO_OPCODE v0 # jump to next instruction @@ -1594,28 +1603,28 @@ artMterpAsmInstructionStart = .L_op_nop * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le */ /* if-cmp vA, vB, +CCCC */ - lh a4, 2(rPC) # a4 <- sign-extended CCCC + .extern MterpProfileBranch ext a2, rINST, 8, 4 # a2 <- A ext a3, rINST, 12, 4 # a3 <- B + lh rINST, 2(rPC) # rINST <- offset (sign-extended CCCC) GET_VREG a0, a2 # a0 <- vA GET_VREG a1, a3 # a1 <- vB - bgtc a0, a1, 1f - li a4, 2 # offset if branch not taken + li rINST, 2 # offset if branch not taken 1: - - dlsa rPC, a4, rPC, 1 # rPC <- rPC + CCCC * 2 - FETCH_INST # load rINST - -#if MTERP_SUSPEND - bgez a4, 2f # CCCC * 2 >= 0 => no suspend check - REFRESH_IBASE -2: -#else - lw ra, THREAD_FLAGS_OFFSET(rSELF) # Preload flags for MterpCheckSuspendAndContinue - bltz a4, MterpCheckSuspendAndContinue +#if MTERP_PROFILE_BRANCHES + EXPORT_PC + move a0, rSELF + daddu a1, rFP, OFF_FP_SHADOWFRAME + move a2, rINST + jal MterpProfileBranch # (self, shadow_frame, offset) + bnezc v0, MterpOnStackReplacement # Note: offset must be in rINST #endif - + dlsa rPC, rINST, rPC, 1 # rPC <- rPC + offset * 2 + lw ra, THREAD_FLAGS_OFFSET(rSELF) # Preload flags for MterpCheckSuspendAndContinue + move a0, rINST # a0 <- offset + FETCH_INST # load rINST + bltz a0, MterpCheckSuspendAndContinue # suspend check if backwards branch GET_INST_OPCODE v0 # extract opcode from rINST GOTO_OPCODE v0 # jump to next instruction @@ -1633,28 +1642,28 @@ artMterpAsmInstructionStart = .L_op_nop * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le */ /* if-cmp vA, vB, +CCCC */ - lh a4, 2(rPC) # a4 <- sign-extended CCCC + .extern MterpProfileBranch ext a2, rINST, 8, 4 # a2 <- A ext a3, rINST, 12, 4 # a3 <- B + lh rINST, 2(rPC) # rINST <- offset (sign-extended CCCC) GET_VREG a0, a2 # a0 <- vA GET_VREG a1, a3 # a1 <- vB - blec a0, a1, 1f - li a4, 2 # offset if branch not taken + li rINST, 2 # offset if branch not taken 1: - - dlsa rPC, a4, rPC, 1 # rPC <- rPC + CCCC * 2 - FETCH_INST # load rINST - -#if MTERP_SUSPEND - bgez a4, 2f # CCCC * 2 >= 0 => no suspend check - REFRESH_IBASE -2: -#else - lw ra, THREAD_FLAGS_OFFSET(rSELF) # Preload flags for MterpCheckSuspendAndContinue - bltz a4, MterpCheckSuspendAndContinue +#if MTERP_PROFILE_BRANCHES + EXPORT_PC + move a0, rSELF + daddu a1, rFP, OFF_FP_SHADOWFRAME + move a2, rINST + jal MterpProfileBranch # (self, shadow_frame, offset) + bnezc v0, MterpOnStackReplacement # Note: offset must be in rINST #endif - + dlsa rPC, rINST, rPC, 1 # rPC <- rPC + offset * 2 + lw ra, THREAD_FLAGS_OFFSET(rSELF) # Preload flags for MterpCheckSuspendAndContinue + move a0, rINST # a0 <- offset + FETCH_INST # load rINST + bltz a0, MterpCheckSuspendAndContinue # suspend check if backwards branch GET_INST_OPCODE v0 # extract opcode from rINST GOTO_OPCODE v0 # jump to next instruction @@ -1672,26 +1681,26 @@ artMterpAsmInstructionStart = .L_op_nop * For: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez */ /* if-cmp vAA, +BBBB */ - lh a4, 2(rPC) # a4 <- sign-extended BBBB + .extern MterpProfileBranch srl a2, rINST, 8 # a2 <- AA + lh rINST, 2(rPC) # rINST <- offset (sign-extended BBBB) GET_VREG a0, a2 # a0 <- vAA - beqzc a0, 1f - li a4, 2 # offset if branch not taken + li rINST, 2 # offset if branch not taken 1: - - dlsa rPC, a4, rPC, 1 # rPC <- rPC + BBBB * 2 - FETCH_INST # load rINST - -#if MTERP_SUSPEND - bgez a4, 2f # BBBB * 2 >= 0 => no suspend check - REFRESH_IBASE -2: -#else - lw ra, THREAD_FLAGS_OFFSET(rSELF) # Preload flags for MterpCheckSuspendAndContinue - bltz a4, MterpCheckSuspendAndContinue +#if MTERP_PROFILE_BRANCHES + EXPORT_PC + move a0, rSELF + daddu a1, rFP, OFF_FP_SHADOWFRAME + move a2, rINST + jal MterpProfileBranch # (self, shadow_frame, offset) + bnezc v0, MterpOnStackReplacement # Note: offset must be in rINST #endif - + dlsa rPC, rINST, rPC, 1 # rPC <- rPC + offset * 2 + lw ra, THREAD_FLAGS_OFFSET(rSELF) # Preload flags for MterpCheckSuspendAndContinue + move a0, rINST # a0 <- offset + FETCH_INST # load rINST + bltz a0, MterpCheckSuspendAndContinue # suspend check if backwards branch GET_INST_OPCODE v0 # extract opcode from rINST GOTO_OPCODE v0 # jump to next instruction @@ -1709,26 +1718,26 @@ artMterpAsmInstructionStart = .L_op_nop * For: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez */ /* if-cmp vAA, +BBBB */ - lh a4, 2(rPC) # a4 <- sign-extended BBBB + .extern MterpProfileBranch srl a2, rINST, 8 # a2 <- AA + lh rINST, 2(rPC) # rINST <- offset (sign-extended BBBB) GET_VREG a0, a2 # a0 <- vAA - bnezc a0, 1f - li a4, 2 # offset if branch not taken + li rINST, 2 # offset if branch not taken 1: - - dlsa rPC, a4, rPC, 1 # rPC <- rPC + BBBB * 2 - FETCH_INST # load rINST - -#if MTERP_SUSPEND - bgez a4, 2f # BBBB * 2 >= 0 => no suspend check - REFRESH_IBASE -2: -#else - lw ra, THREAD_FLAGS_OFFSET(rSELF) # Preload flags for MterpCheckSuspendAndContinue - bltz a4, MterpCheckSuspendAndContinue +#if MTERP_PROFILE_BRANCHES + EXPORT_PC + move a0, rSELF + daddu a1, rFP, OFF_FP_SHADOWFRAME + move a2, rINST + jal MterpProfileBranch # (self, shadow_frame, offset) + bnezc v0, MterpOnStackReplacement # Note: offset must be in rINST #endif - + dlsa rPC, rINST, rPC, 1 # rPC <- rPC + offset * 2 + lw ra, THREAD_FLAGS_OFFSET(rSELF) # Preload flags for MterpCheckSuspendAndContinue + move a0, rINST # a0 <- offset + FETCH_INST # load rINST + bltz a0, MterpCheckSuspendAndContinue # suspend check if backwards branch GET_INST_OPCODE v0 # extract opcode from rINST GOTO_OPCODE v0 # jump to next instruction @@ -1746,26 +1755,26 @@ artMterpAsmInstructionStart = .L_op_nop * For: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez */ /* if-cmp vAA, +BBBB */ - lh a4, 2(rPC) # a4 <- sign-extended BBBB + .extern MterpProfileBranch srl a2, rINST, 8 # a2 <- AA + lh rINST, 2(rPC) # rINST <- offset (sign-extended BBBB) GET_VREG a0, a2 # a0 <- vAA - bltzc a0, 1f - li a4, 2 # offset if branch not taken + li rINST, 2 # offset if branch not taken 1: - - dlsa rPC, a4, rPC, 1 # rPC <- rPC + BBBB * 2 - FETCH_INST # load rINST - -#if MTERP_SUSPEND - bgez a4, 2f # BBBB * 2 >= 0 => no suspend check - REFRESH_IBASE -2: -#else - lw ra, THREAD_FLAGS_OFFSET(rSELF) # Preload flags for MterpCheckSuspendAndContinue - bltz a4, MterpCheckSuspendAndContinue +#if MTERP_PROFILE_BRANCHES + EXPORT_PC + move a0, rSELF + daddu a1, rFP, OFF_FP_SHADOWFRAME + move a2, rINST + jal MterpProfileBranch # (self, shadow_frame, offset) + bnezc v0, MterpOnStackReplacement # Note: offset must be in rINST #endif - + dlsa rPC, rINST, rPC, 1 # rPC <- rPC + offset * 2 + lw ra, THREAD_FLAGS_OFFSET(rSELF) # Preload flags for MterpCheckSuspendAndContinue + move a0, rINST # a0 <- offset + FETCH_INST # load rINST + bltz a0, MterpCheckSuspendAndContinue # suspend check if backwards branch GET_INST_OPCODE v0 # extract opcode from rINST GOTO_OPCODE v0 # jump to next instruction @@ -1783,26 +1792,26 @@ artMterpAsmInstructionStart = .L_op_nop * For: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez */ /* if-cmp vAA, +BBBB */ - lh a4, 2(rPC) # a4 <- sign-extended BBBB + .extern MterpProfileBranch srl a2, rINST, 8 # a2 <- AA + lh rINST, 2(rPC) # rINST <- offset (sign-extended BBBB) GET_VREG a0, a2 # a0 <- vAA - bgezc a0, 1f - li a4, 2 # offset if branch not taken + li rINST, 2 # offset if branch not taken 1: - - dlsa rPC, a4, rPC, 1 # rPC <- rPC + BBBB * 2 - FETCH_INST # load rINST - -#if MTERP_SUSPEND - bgez a4, 2f # BBBB * 2 >= 0 => no suspend check - REFRESH_IBASE -2: -#else - lw ra, THREAD_FLAGS_OFFSET(rSELF) # Preload flags for MterpCheckSuspendAndContinue - bltz a4, MterpCheckSuspendAndContinue +#if MTERP_PROFILE_BRANCHES + EXPORT_PC + move a0, rSELF + daddu a1, rFP, OFF_FP_SHADOWFRAME + move a2, rINST + jal MterpProfileBranch # (self, shadow_frame, offset) + bnezc v0, MterpOnStackReplacement # Note: offset must be in rINST #endif - + dlsa rPC, rINST, rPC, 1 # rPC <- rPC + offset * 2 + lw ra, THREAD_FLAGS_OFFSET(rSELF) # Preload flags for MterpCheckSuspendAndContinue + move a0, rINST # a0 <- offset + FETCH_INST # load rINST + bltz a0, MterpCheckSuspendAndContinue # suspend check if backwards branch GET_INST_OPCODE v0 # extract opcode from rINST GOTO_OPCODE v0 # jump to next instruction @@ -1820,26 +1829,26 @@ artMterpAsmInstructionStart = .L_op_nop * For: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez */ /* if-cmp vAA, +BBBB */ - lh a4, 2(rPC) # a4 <- sign-extended BBBB + .extern MterpProfileBranch srl a2, rINST, 8 # a2 <- AA + lh rINST, 2(rPC) # rINST <- offset (sign-extended BBBB) GET_VREG a0, a2 # a0 <- vAA - bgtzc a0, 1f - li a4, 2 # offset if branch not taken + li rINST, 2 # offset if branch not taken 1: - - dlsa rPC, a4, rPC, 1 # rPC <- rPC + BBBB * 2 - FETCH_INST # load rINST - -#if MTERP_SUSPEND - bgez a4, 2f # BBBB * 2 >= 0 => no suspend check - REFRESH_IBASE -2: -#else - lw ra, THREAD_FLAGS_OFFSET(rSELF) # Preload flags for MterpCheckSuspendAndContinue - bltz a4, MterpCheckSuspendAndContinue +#if MTERP_PROFILE_BRANCHES + EXPORT_PC + move a0, rSELF + daddu a1, rFP, OFF_FP_SHADOWFRAME + move a2, rINST + jal MterpProfileBranch # (self, shadow_frame, offset) + bnezc v0, MterpOnStackReplacement # Note: offset must be in rINST #endif - + dlsa rPC, rINST, rPC, 1 # rPC <- rPC + offset * 2 + lw ra, THREAD_FLAGS_OFFSET(rSELF) # Preload flags for MterpCheckSuspendAndContinue + move a0, rINST # a0 <- offset + FETCH_INST # load rINST + bltz a0, MterpCheckSuspendAndContinue # suspend check if backwards branch GET_INST_OPCODE v0 # extract opcode from rINST GOTO_OPCODE v0 # jump to next instruction @@ -1857,26 +1866,26 @@ artMterpAsmInstructionStart = .L_op_nop * For: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez */ /* if-cmp vAA, +BBBB */ - lh a4, 2(rPC) # a4 <- sign-extended BBBB + .extern MterpProfileBranch srl a2, rINST, 8 # a2 <- AA + lh rINST, 2(rPC) # rINST <- offset (sign-extended BBBB) GET_VREG a0, a2 # a0 <- vAA - blezc a0, 1f - li a4, 2 # offset if branch not taken + li rINST, 2 # offset if branch not taken 1: - - dlsa rPC, a4, rPC, 1 # rPC <- rPC + BBBB * 2 - FETCH_INST # load rINST - -#if MTERP_SUSPEND - bgez a4, 2f # BBBB * 2 >= 0 => no suspend check - REFRESH_IBASE -2: -#else - lw ra, THREAD_FLAGS_OFFSET(rSELF) # Preload flags for MterpCheckSuspendAndContinue - bltz a4, MterpCheckSuspendAndContinue +#if MTERP_PROFILE_BRANCHES + EXPORT_PC + move a0, rSELF + daddu a1, rFP, OFF_FP_SHADOWFRAME + move a2, rINST + jal MterpProfileBranch # (self, shadow_frame, offset) + bnezc v0, MterpOnStackReplacement # Note: offset must be in rINST #endif - + dlsa rPC, rINST, rPC, 1 # rPC <- rPC + offset * 2 + lw ra, THREAD_FLAGS_OFFSET(rSELF) # Preload flags for MterpCheckSuspendAndContinue + move a0, rINST # a0 <- offset + FETCH_INST # load rINST + bltz a0, MterpCheckSuspendAndContinue # suspend check if backwards branch GET_INST_OPCODE v0 # extract opcode from rINST GOTO_OPCODE v0 # jump to next instruction @@ -3166,6 +3175,7 @@ artMterpAsmInstructionStart = .L_op_nop /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ .extern MterpInvokeVirtual + .extern MterpShouldSwitchInterpreters EXPORT_PC move a0, rSELF daddu a1, rFP, OFF_FP_SHADOWFRAME @@ -3174,6 +3184,8 @@ artMterpAsmInstructionStart = .L_op_nop jal MterpInvokeVirtual beqzc v0, MterpException FETCH_ADVANCE_INST 3 + jal MterpShouldSwitchInterpreters + bnezc v0, MterpFallback GET_INST_OPCODE v0 GOTO_OPCODE v0 @@ -3196,6 +3208,7 @@ artMterpAsmInstructionStart = .L_op_nop /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ .extern MterpInvokeSuper + .extern MterpShouldSwitchInterpreters EXPORT_PC move a0, rSELF daddu a1, rFP, OFF_FP_SHADOWFRAME @@ -3204,6 +3217,8 @@ artMterpAsmInstructionStart = .L_op_nop jal MterpInvokeSuper beqzc v0, MterpException FETCH_ADVANCE_INST 3 + jal MterpShouldSwitchInterpreters + bnezc v0, MterpFallback GET_INST_OPCODE v0 GOTO_OPCODE v0 @@ -3226,6 +3241,7 @@ artMterpAsmInstructionStart = .L_op_nop /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ .extern MterpInvokeDirect + .extern MterpShouldSwitchInterpreters EXPORT_PC move a0, rSELF daddu a1, rFP, OFF_FP_SHADOWFRAME @@ -3234,6 +3250,8 @@ artMterpAsmInstructionStart = .L_op_nop jal MterpInvokeDirect beqzc v0, MterpException FETCH_ADVANCE_INST 3 + jal MterpShouldSwitchInterpreters + bnezc v0, MterpFallback GET_INST_OPCODE v0 GOTO_OPCODE v0 @@ -3249,6 +3267,7 @@ artMterpAsmInstructionStart = .L_op_nop /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ .extern MterpInvokeStatic + .extern MterpShouldSwitchInterpreters EXPORT_PC move a0, rSELF daddu a1, rFP, OFF_FP_SHADOWFRAME @@ -3257,6 +3276,8 @@ artMterpAsmInstructionStart = .L_op_nop jal MterpInvokeStatic beqzc v0, MterpException FETCH_ADVANCE_INST 3 + jal MterpShouldSwitchInterpreters + bnezc v0, MterpFallback GET_INST_OPCODE v0 GOTO_OPCODE v0 @@ -3272,6 +3293,7 @@ artMterpAsmInstructionStart = .L_op_nop /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ .extern MterpInvokeInterface + .extern MterpShouldSwitchInterpreters EXPORT_PC move a0, rSELF daddu a1, rFP, OFF_FP_SHADOWFRAME @@ -3280,6 +3302,8 @@ artMterpAsmInstructionStart = .L_op_nop jal MterpInvokeInterface beqzc v0, MterpException FETCH_ADVANCE_INST 3 + jal MterpShouldSwitchInterpreters + bnezc v0, MterpFallback GET_INST_OPCODE v0 GOTO_OPCODE v0 @@ -3316,6 +3340,7 @@ artMterpAsmInstructionStart = .L_op_nop /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ .extern MterpInvokeVirtualRange + .extern MterpShouldSwitchInterpreters EXPORT_PC move a0, rSELF daddu a1, rFP, OFF_FP_SHADOWFRAME @@ -3324,6 +3349,8 @@ artMterpAsmInstructionStart = .L_op_nop jal MterpInvokeVirtualRange beqzc v0, MterpException FETCH_ADVANCE_INST 3 + jal MterpShouldSwitchInterpreters + bnezc v0, MterpFallback GET_INST_OPCODE v0 GOTO_OPCODE v0 @@ -3339,6 +3366,7 @@ artMterpAsmInstructionStart = .L_op_nop /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ .extern MterpInvokeSuperRange + .extern MterpShouldSwitchInterpreters EXPORT_PC move a0, rSELF daddu a1, rFP, OFF_FP_SHADOWFRAME @@ -3347,6 +3375,8 @@ artMterpAsmInstructionStart = .L_op_nop jal MterpInvokeSuperRange beqzc v0, MterpException FETCH_ADVANCE_INST 3 + jal MterpShouldSwitchInterpreters + bnezc v0, MterpFallback GET_INST_OPCODE v0 GOTO_OPCODE v0 @@ -3362,6 +3392,7 @@ artMterpAsmInstructionStart = .L_op_nop /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ .extern MterpInvokeDirectRange + .extern MterpShouldSwitchInterpreters EXPORT_PC move a0, rSELF daddu a1, rFP, OFF_FP_SHADOWFRAME @@ -3370,6 +3401,8 @@ artMterpAsmInstructionStart = .L_op_nop jal MterpInvokeDirectRange beqzc v0, MterpException FETCH_ADVANCE_INST 3 + jal MterpShouldSwitchInterpreters + bnezc v0, MterpFallback GET_INST_OPCODE v0 GOTO_OPCODE v0 @@ -3385,6 +3418,7 @@ artMterpAsmInstructionStart = .L_op_nop /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ .extern MterpInvokeStaticRange + .extern MterpShouldSwitchInterpreters EXPORT_PC move a0, rSELF daddu a1, rFP, OFF_FP_SHADOWFRAME @@ -3393,6 +3427,8 @@ artMterpAsmInstructionStart = .L_op_nop jal MterpInvokeStaticRange beqzc v0, MterpException FETCH_ADVANCE_INST 3 + jal MterpShouldSwitchInterpreters + bnezc v0, MterpFallback GET_INST_OPCODE v0 GOTO_OPCODE v0 @@ -3408,6 +3444,7 @@ artMterpAsmInstructionStart = .L_op_nop /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ .extern MterpInvokeInterfaceRange + .extern MterpShouldSwitchInterpreters EXPORT_PC move a0, rSELF daddu a1, rFP, OFF_FP_SHADOWFRAME @@ -3416,6 +3453,8 @@ artMterpAsmInstructionStart = .L_op_nop jal MterpInvokeInterfaceRange beqzc v0, MterpException FETCH_ADVANCE_INST 3 + jal MterpShouldSwitchInterpreters + bnezc v0, MterpFallback GET_INST_OPCODE v0 GOTO_OPCODE v0 @@ -6962,6 +7001,7 @@ artMterpAsmInstructionStart = .L_op_nop /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ .extern MterpInvokeVirtualQuick + .extern MterpShouldSwitchInterpreters EXPORT_PC move a0, rSELF daddu a1, rFP, OFF_FP_SHADOWFRAME @@ -6970,6 +7010,8 @@ artMterpAsmInstructionStart = .L_op_nop jal MterpInvokeVirtualQuick beqzc v0, MterpException FETCH_ADVANCE_INST 3 + jal MterpShouldSwitchInterpreters + bnezc v0, MterpFallback GET_INST_OPCODE v0 GOTO_OPCODE v0 @@ -6985,6 +7027,7 @@ artMterpAsmInstructionStart = .L_op_nop /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ .extern MterpInvokeVirtualQuickRange + .extern MterpShouldSwitchInterpreters EXPORT_PC move a0, rSELF daddu a1, rFP, OFF_FP_SHADOWFRAME @@ -6993,6 +7036,8 @@ artMterpAsmInstructionStart = .L_op_nop jal MterpInvokeVirtualQuickRange beqzc v0, MterpException FETCH_ADVANCE_INST 3 + jal MterpShouldSwitchInterpreters + bnezc v0, MterpFallback GET_INST_OPCODE v0 GOTO_OPCODE v0 @@ -12256,6 +12301,7 @@ MterpPossibleException: * */ .extern MterpHandleException + .extern MterpShouldSwitchInterpreters MterpException: move a0, rSELF daddu a1, rFP, OFF_FP_SHADOWFRAME @@ -12266,8 +12312,11 @@ MterpException: REFRESH_IBASE daddu rPC, a0, CODEITEM_INSNS_OFFSET dlsa rPC, a1, rPC, 1 # generate new dex_pc_ptr - sd rPC, OFF_FP_DEX_PC_PTR(rFP) + /* Do we need to switch interpreters? */ + jal MterpShouldSwitchInterpreters + bnezc v0, MterpFallback /* resume execution at catch block */ + EXPORT_PC FETCH_INST GET_INST_OPCODE v0 GOTO_OPCODE v0 @@ -12288,10 +12337,24 @@ check1: EXPORT_PC move a0, rSELF jal MterpSuspendCheck # (self) + bnezc v0, MterpFallback # Something in the environment changed, switch interpreters GET_INST_OPCODE v0 # extract opcode from rINST GOTO_OPCODE v0 # jump to next instruction /* + * On-stack replacement has happened, and now we've returned from the compiled method. + */ +MterpOnStackReplacement: +#if MTERP_LOGGING + move a0, rSELF + daddu a1, rFP, OFF_FP_SHADOWFRAME + move a2, rINST # rINST contains offset + jal MterpLogOSR +#endif + li v0, 1 # Signal normal return + b MterpDone + +/* * Bail out to reference interpreter. */ .extern MterpLogFallback -- 2.11.0