ART: Enable Jit Profiling in Mterp for arm/arm64
Adds the hooks for branch profiling to arm and arm64. The
other Jit profiling modes are handled in common code.
Stubbed out support for on-stack replacement.
Change-Id: Ic298a81139108c3d7f1325b59d97e14a9de08de6
diff --git a/runtime/instrumentation.h b/runtime/instrumentation.h
index 56aeefc..e3cbf53 100644
--- a/runtime/instrumentation.h
+++ b/runtime/instrumentation.h
@@ -290,6 +290,14 @@
bool IsActive() const SHARED_REQUIRES(Locks::mutator_lock_) {
return have_dex_pc_listeners_ || have_method_entry_listeners_ || have_method_exit_listeners_ ||
have_field_read_listeners_ || have_field_write_listeners_ ||
+ have_exception_caught_listeners_ || have_method_unwind_listeners_ ||
+ have_branch_listeners_ || have_invoke_virtual_or_interface_listeners_;
+ }
+
+ // Any instrumentation *other* than what is needed for Jit profiling active?
+ bool NonJitProfilingActive() const SHARED_REQUIRES(Locks::mutator_lock_) {
+ return have_dex_pc_listeners_ || have_method_exit_listeners_ ||
+ have_field_read_listeners_ || have_field_write_listeners_ ||
have_exception_caught_listeners_ || have_method_unwind_listeners_;
}
diff --git a/runtime/interpreter/interpreter.cc b/runtime/interpreter/interpreter.cc
index 3eff7fc..903c200 100644
--- a/runtime/interpreter/interpreter.cc
+++ b/runtime/interpreter/interpreter.cc
@@ -322,8 +322,14 @@
const instrumentation::Instrumentation* const instrumentation =
Runtime::Current()->GetInstrumentation();
while (true) {
- if (instrumentation->IsActive() || !Runtime::Current()->IsStarted()) {
- // TODO: allow JIT profiling instrumentation. Now, just punt on all instrumentation.
+ // Mterp does not support all instrumentation.
+ bool unhandled_instrumentation;
+ if ((kRuntimeISA == kArm64) || (kRuntimeISA == kArm)) {
+ unhandled_instrumentation = instrumentation->NonJitProfilingActive();
+ } else {
+ unhandled_instrumentation = instrumentation->IsActive();
+ }
+ if (unhandled_instrumentation || !Runtime::Current()->IsStarted()) {
#if !defined(__clang__)
return ExecuteGotoImpl<false, false>(self, code_item, shadow_frame, result_register);
#else
diff --git a/runtime/interpreter/mterp/arm/bincmp.S b/runtime/interpreter/mterp/arm/bincmp.S
index 474bc3c..dae3b57 100644
--- a/runtime/interpreter/mterp/arm/bincmp.S
+++ b/runtime/interpreter/mterp/arm/bincmp.S
@@ -25,10 +25,18 @@
GET_VREG r3, r1 @ r3<- vB
GET_VREG r2, r0 @ r2<- vA
ldr lr, [rSELF, #THREAD_FLAGS_OFFSET]
- FETCH_S r1, 1 @ r1<- branch offset, in code units
+ FETCH_S rINST, 1 @ rINST<- branch offset, in code units
cmp r2, r3 @ compare (vA, vB)
- mov${revcmp} r1, #2 @ r1<- BYTE branch dist for not-taken
- adds r2, r1, r1 @ convert to bytes, check sign
+ mov${revcmp} rINST, #2 @ rINST<- BYTE branch dist for not-taken
+#if MTERP_PROFILE_BRANCHES
+ mov r0, rSELF
+ add r1, rFP, #OFF_FP_SHADOWFRAME
+ mov r2, rINST
+ bl MterpProfileBranch @ (self, shadow_frame, offset)
+ cmp r0, #0
+ bne MterpOnStackReplacement @ Note: offset must be in rINST
+#endif
+ adds r2, rINST, rINST @ convert to bytes, check sign
FETCH_ADVANCE_INST_RB r2 @ update rPC, load rINST
bmi MterpCheckSuspendAndContinue
GET_INST_OPCODE ip @ extract opcode from rINST
diff --git a/runtime/interpreter/mterp/arm/footer.S b/runtime/interpreter/mterp/arm/footer.S
index 1dba856..a444843 100644
--- a/runtime/interpreter/mterp/arm/footer.S
+++ b/runtime/interpreter/mterp/arm/footer.S
@@ -124,6 +124,18 @@
GOTO_OPCODE ip @ jump to next instruction
/*
+ * On-stack replacement pending.
+ * Branch offset in rINST on entry.
+ */
+MterpOnStackReplacement:
+#if MTERP_LOGGING
+ mov r0, rSELF
+ add r1, rFP, #OFF_FP_SHADOWFRAME
+ mov r2, rINST
+ bl MterpLogOSR
+#endif
+ b MterpFallback @ Let the reference interpreter deal with it.
+/*
* Bail out to reference interpreter.
*/
MterpFallback:
diff --git a/runtime/interpreter/mterp/arm/header.S b/runtime/interpreter/mterp/arm/header.S
index 14319d9..b67bd22 100644
--- a/runtime/interpreter/mterp/arm/header.S
+++ b/runtime/interpreter/mterp/arm/header.S
@@ -85,6 +85,8 @@
*/
#include "asm_support.h"
+#define MTERP_PROFILE_BRANCHES 1
+
/* During bringup, we'll use the shadow frame model instead of rFP */
/* single-purpose registers, given names for clarity */
#define rPC r4
diff --git a/runtime/interpreter/mterp/arm/op_goto.S b/runtime/interpreter/mterp/arm/op_goto.S
index 9b3632a..0f02438 100644
--- a/runtime/interpreter/mterp/arm/op_goto.S
+++ b/runtime/interpreter/mterp/arm/op_goto.S
@@ -16,10 +16,18 @@
GET_INST_OPCODE ip @ extract opcode from rINST
GOTO_OPCODE ip @ jump to next instruction
#else
- ldr lr, [rSELF, #THREAD_FLAGS_OFFSET]
mov r0, rINST, lsl #16 @ r0<- AAxx0000
- movs r1, r0, asr #24 @ r1<- ssssssAA (sign-extended)
- add r2, r1, r1 @ r2<- byte offset, set flags
+ movs rINST, r0, asr #24 @ rINST<- ssssssAA (sign-extended)
+#if MTERP_PROFILE_BRANCHES
+ mov r0, rSELF
+ add r1, rFP, #OFF_FP_SHADOWFRAME
+ mov r2, rINST
+ bl MterpProfileBranch @ (self, shadow_frame, offset)
+ cmp r0, #0
+ bne MterpOnStackReplacement @ Note: offset must be in rINST
+#endif
+ ldr lr, [rSELF, #THREAD_FLAGS_OFFSET]
+ add r2, rINST, rINST @ r2<- byte offset, set flags
FETCH_ADVANCE_INST_RB r2 @ update rPC, load rINST
@ If backwards branch refresh rIBASE
bmi MterpCheckSuspendAndContinue
diff --git a/runtime/interpreter/mterp/arm/op_goto_16.S b/runtime/interpreter/mterp/arm/op_goto_16.S
index 2231acd..8a9acf0 100644
--- a/runtime/interpreter/mterp/arm/op_goto_16.S
+++ b/runtime/interpreter/mterp/arm/op_goto_16.S
@@ -13,9 +13,17 @@
GET_INST_OPCODE ip @ extract opcode from rINST
GOTO_OPCODE ip @ jump to next instruction
#else
- FETCH_S r0, 1 @ r0<- ssssAAAA (sign-extended)
+ FETCH_S rINST, 1 @ rINST<- ssssAAAA (sign-extended)
+#if MTERP_PROFILE_BRANCHES
+ mov r0, rINST
+ add r1, rFP, #OFF_FP_SHADOWFRAME
+ mov r2, rINST
+ bl MterpOnStackReplacement @ (self, shadow_frame, offset)
+ cmp r0, #0
+ bne MterpOnStackReplacement @ Note: offset must be in rINST
+#endif
ldr lr, [rSELF, #THREAD_FLAGS_OFFSET]
- adds r1, r0, r0 @ r1<- byte offset, flags set
+ adds r1, rINST, rINST @ r1<- byte offset, flags set
FETCH_ADVANCE_INST_RB r1 @ update rPC, load rINST
bmi MterpCheckSuspendAndContinue
GET_INST_OPCODE ip @ extract opcode from rINST
diff --git a/runtime/interpreter/mterp/arm/op_goto_32.S b/runtime/interpreter/mterp/arm/op_goto_32.S
index 6b72ff5..51a6f06 100644
--- a/runtime/interpreter/mterp/arm/op_goto_32.S
+++ b/runtime/interpreter/mterp/arm/op_goto_32.S
@@ -22,9 +22,17 @@
#else
FETCH r0, 1 @ r0<- aaaa (lo)
FETCH r1, 2 @ r1<- AAAA (hi)
+ orr rINST, r0, r1, lsl #16 @ rINST<- AAAAaaaa
+#if MTERP_PROFILE_BRANCHES
+ mov r0, rSELF
+ add r1, rFP, #OFF_FP_SHADOWFRAME
+ mov r2, rINST
+ bl MterpOnStackReplacement @ (self, shadow_frame, offset)
+ cmp r0, #0
+ bne MterpOnStackReplacement @ Note: offset must be in rINST
+#endif
ldr lr, [rSELF, #THREAD_FLAGS_OFFSET]
- orr r0, r0, r1, lsl #16 @ r0<- AAAAaaaa
- adds r1, r0, r0 @ r1<- byte offset
+ adds r1, rINST, rINST @ r1<- byte offset
FETCH_ADVANCE_INST_RB r1 @ update rPC, load rINST
ble MterpCheckSuspendAndContinue
GET_INST_OPCODE ip @ extract opcode from rINST
diff --git a/runtime/interpreter/mterp/arm/op_packed_switch.S b/runtime/interpreter/mterp/arm/op_packed_switch.S
index 1e3370e..109b245 100644
--- a/runtime/interpreter/mterp/arm/op_packed_switch.S
+++ b/runtime/interpreter/mterp/arm/op_packed_switch.S
@@ -30,8 +30,17 @@
GET_VREG r1, r3 @ r1<- vAA
add r0, rPC, r0, lsl #1 @ r0<- PC + BBBBbbbb*2
bl $func @ r0<- code-unit branch offset
+ mov rINST, r0
+#if MTERP_PROFILE_BRANCHES
+ mov r0, rSELF
+ add r1, rFP, #OFF_FP_SHADOWFRAME
+ mov r2, rINST
+ bl MterpProfileBranch @ (self, shadow_frame, offset)
+ cmp r0, #0
+ bne MterpOnStackReplacement @ Note: offset must be in rINST
+#endif
ldr lr, [rSELF, #THREAD_FLAGS_OFFSET]
- adds r1, r0, r0 @ r1<- byte offset; clear V
+ adds r1, rINST, rINST @ r1<- byte offset; clear V
FETCH_ADVANCE_INST_RB r1 @ update rPC, load rINST
ble MterpCheckSuspendAndContinue
GET_INST_OPCODE ip @ extract opcode from rINST
diff --git a/runtime/interpreter/mterp/arm/zcmp.S b/runtime/interpreter/mterp/arm/zcmp.S
index 6e9ef55..b2cc18b 100644
--- a/runtime/interpreter/mterp/arm/zcmp.S
+++ b/runtime/interpreter/mterp/arm/zcmp.S
@@ -20,11 +20,19 @@
#else
mov r0, rINST, lsr #8 @ r0<- AA
GET_VREG r2, r0 @ r2<- vAA
- FETCH_S r1, 1 @ r1<- branch offset, in code units
+ FETCH_S rINST, 1 @ rINST<- branch offset, in code units
ldr lr, [rSELF, #THREAD_FLAGS_OFFSET]
cmp r2, #0 @ compare (vA, 0)
- mov${revcmp} r1, #2 @ r1<- inst branch dist for not-taken
- adds r1, r1, r1 @ convert to bytes & set flags
+ mov${revcmp} rINST, #2 @ rINST<- inst branch dist for not-taken
+#if MTERP_PROFILE_BRANCHES
+ mov r0, rSELF
+ add r1, rFP, #OFF_FP_SHADOWFRAME
+ mov r2, rINST
+ bl MterpProfileBranch @ (self, shadow_frame, offset)
+ cmp r0, #0
+ bne MterpOnStackReplacement @ Note: offset must be in rINST
+#endif
+ adds r1, rINST, rINST @ convert to bytes & set flags
FETCH_ADVANCE_INST_RB r1 @ update rPC, load rINST
bmi MterpCheckSuspendAndContinue
GET_INST_OPCODE ip @ extract opcode from rINST
diff --git a/runtime/interpreter/mterp/arm64/bincmp.S b/runtime/interpreter/mterp/arm64/bincmp.S
index ecab2ce..53d4dfa 100644
--- a/runtime/interpreter/mterp/arm64/bincmp.S
+++ b/runtime/interpreter/mterp/arm64/bincmp.S
@@ -25,11 +25,18 @@
GET_VREG w3, w1 // w3<- vB
GET_VREG w2, w0 // w2<- vA
FETCH_S w1, 1 // w1<- branch offset, in code units
- ldr w7, [xSELF, #THREAD_FLAGS_OFFSET]
mov w0, #2 // Offset if branch not taken
cmp w2, w3 // compare (vA, vB)
- csel w1, w1, w0, ${condition} // Branch if true
- adds w2, w1, w1 // convert to bytes, check sign
+ csel wINST, w1, w0, ${condition} // Branch if true, stashing result in callee save reg.
+#if MTERP_PROFILE_BRANCHES
+ mov x0, xSELF
+ add x1, xFP, #OFF_FP_SHADOWFRAME
+ sbfm x2, xINST, 0, 31 // Sign extend branch offset
+ bl MterpProfileBranch // (self, shadow_frame, offset)
+ cbnz w0, MterpOnStackReplacement // Note: offset must be in xINST
+#endif
+ ldr w7, [xSELF, #THREAD_FLAGS_OFFSET]
+ adds w2, wINST, wINST // convert to bytes, check sign
FETCH_ADVANCE_INST_RB w2 // update rPC, load wINST
b.mi MterpCheckSuspendAndContinue
GET_INST_OPCODE ip // extract opcode from wINST
diff --git a/runtime/interpreter/mterp/arm64/footer.S b/runtime/interpreter/mterp/arm64/footer.S
index b360539..d237c51 100644
--- a/runtime/interpreter/mterp/arm64/footer.S
+++ b/runtime/interpreter/mterp/arm64/footer.S
@@ -124,6 +124,19 @@
GOTO_OPCODE ip // jump to next instruction
/*
+ * On-stack replacement pending.
+ * Branch offset in wINST on entry.
+ */
+MterpOnStackReplacement:
+#if MTERP_LOGGING
+ mov x0, xSELF
+ add x1, xFP, #OFF_FP_SHADOWFRAME
+ sbfm x2, xINST, 0, 31
+ bl MterpLogOSR
+#endif
+ b MterpFallback // Let the reference interpreter deal with it.
+
+/*
* Bail out to reference interpreter.
*/
MterpFallback:
diff --git a/runtime/interpreter/mterp/arm64/header.S b/runtime/interpreter/mterp/arm64/header.S
index 351a607..622abc8 100644
--- a/runtime/interpreter/mterp/arm64/header.S
+++ b/runtime/interpreter/mterp/arm64/header.S
@@ -87,6 +87,8 @@
*/
#include "asm_support.h"
+#define MTERP_PROFILE_BRANCHES 1
+
/* During bringup, we'll use the shadow frame model instead of xFP */
/* single-purpose registers, given names for clarity */
#define xPC x20
diff --git a/runtime/interpreter/mterp/arm64/op_goto.S b/runtime/interpreter/mterp/arm64/op_goto.S
index db98a45..803bade 100644
--- a/runtime/interpreter/mterp/arm64/op_goto.S
+++ b/runtime/interpreter/mterp/arm64/op_goto.S
@@ -16,10 +16,17 @@
GET_INST_OPCODE ip // extract opcode from wINST
GOTO_OPCODE ip // jump to next instruction
#else
- ldr w7, [xSELF, #THREAD_FLAGS_OFFSET] // Preload flags for MterpCheckSuspendAndContinue
lsl w0, wINST, #16 // w0<- AAxx0000
- asr w0, w0, #24 // w0<- ssssssAA (sign-extended)
- adds w1, w0, w0 // Convert dalvik offset to byte offset, setting flags
+ asr wINST, w0, #24 // wINST<- ssssssAA (sign-extended)
+#if MTERP_PROFILE_BRANCHES
+ mov x0, xSELF
+ add x1, xFP, #OFF_FP_SHADOWFRAME
+ sbfm x2, xINST, 0, 31
+ bl MterpProfileBranch // (self, shadow_frame, offset)
+ cbnz w0, MterpOnStackReplacement // Note: offset must be in wINST
+#endif
+ ldr w7, [xSELF, #THREAD_FLAGS_OFFSET] // Preload flags for MterpCheckSuspendAndContinue
+ adds w1, wINST, wINST // Convert dalvik offset to byte offset, setting flags
FETCH_ADVANCE_INST_RB w1 // load wINST and advance xPC
// If backwards branch refresh rIBASE
b.mi MterpCheckSuspendAndContinue
diff --git a/runtime/interpreter/mterp/arm64/op_goto_16.S b/runtime/interpreter/mterp/arm64/op_goto_16.S
index ff66a23..ad26b36 100644
--- a/runtime/interpreter/mterp/arm64/op_goto_16.S
+++ b/runtime/interpreter/mterp/arm64/op_goto_16.S
@@ -13,9 +13,16 @@
GET_INST_OPCODE ip // extract opcode from rINST
GOTO_OPCODE ip // jump to next instruction
#else
- FETCH_S w0, 1 // w0<- ssssAAAA (sign-extended)
+ FETCH_S wINST, 1 // wINST<- ssssAAAA (sign-extended)
+#if MTERP_PROFILE_BRANCHES
+ mov x0, xSELF
+ add x1, xFP, #OFF_FP_SHADOWFRAME
+ sbfm x2, xINST, 0, 31
+ bl MterpProfileBranch // (self, shadow_frame, offset)
+ cbnz w0, MterpOnStackReplacement // Note: offset must be in xINST
+#endif
ldr w7, [xSELF, #THREAD_FLAGS_OFFSET]
- adds w1, w0, w0 // w1<- byte offset, flags set
+ adds w1, wINST, wINST // w1<- byte offset, flags set
FETCH_ADVANCE_INST_RB w1 // update rPC, load rINST
b.mi MterpCheckSuspendAndContinue
GET_INST_OPCODE ip // extract opcode from rINST
diff --git a/runtime/interpreter/mterp/arm64/op_goto_32.S b/runtime/interpreter/mterp/arm64/op_goto_32.S
index 8a6980e..3f040e6 100644
--- a/runtime/interpreter/mterp/arm64/op_goto_32.S
+++ b/runtime/interpreter/mterp/arm64/op_goto_32.S
@@ -22,9 +22,16 @@
#else
FETCH w0, 1 // w0<- aaaa (lo)
FETCH w1, 2 // w1<- AAAA (hi)
+ orr wINST, w0, w1, lsl #16 // wINST<- AAAAaaaa
+#if MTERP_PROFILE_BRANCHES
+ mov x0, xSELF
+ add x1, xFP, #OFF_FP_SHADOWFRAME
+ sbfm x2, xINST, 0, 31
+ bl MterpProfileBranch // (self, shadow_frame, offset)
+ cbnz w0, MterpOnStackReplacement // Note: offset must be in xINST
+#endif
ldr w7, [xSELF, #THREAD_FLAGS_OFFSET]
- orr w0, w0, w1, lsl #16 // w0<- AAAAaaaa
- adds w1, w0, w0 // w1<- byte offset
+ adds w1, wINST, wINST // w1<- byte offset
FETCH_ADVANCE_INST_RB w1 // update rPC, load xINST
b.le MterpCheckSuspendAndContinue
GET_INST_OPCODE ip // extract opcode from xINST
diff --git a/runtime/interpreter/mterp/arm64/op_packed_switch.S b/runtime/interpreter/mterp/arm64/op_packed_switch.S
index f087d23..39ab8bf 100644
--- a/runtime/interpreter/mterp/arm64/op_packed_switch.S
+++ b/runtime/interpreter/mterp/arm64/op_packed_switch.S
@@ -30,8 +30,16 @@
GET_VREG w1, w3 // w1<- vAA
add x0, xPC, w0, lsl #1 // w0<- PC + BBBBbbbb*2
bl $func // w0<- code-unit branch offset
+ sbfm xINST, x0, 0, 31
+#if MTERP_PROFILE_BRANCHES
+ mov x0, xSELF
+ add x1, xFP, #OFF_FP_SHADOWFRAME
+ mov x2, xINST
+ bl MterpProfileBranch // (self, shadow_frame, offset)
+ cbnz w0, MterpOnStackReplacement
+#endif
ldr w7, [xSELF, #THREAD_FLAGS_OFFSET]
- adds w1, w0, w0 // w1<- byte offset; clear V
+ adds w1, wINST, wINST // w1<- byte offset; clear V
FETCH_ADVANCE_INST_RB w1 // update rPC, load wINST
b.le MterpCheckSuspendAndContinue
GET_INST_OPCODE ip // extract opcode from wINST
diff --git a/runtime/interpreter/mterp/arm64/zcmp.S b/runtime/interpreter/mterp/arm64/zcmp.S
index d4856d2..e28668b 100644
--- a/runtime/interpreter/mterp/arm64/zcmp.S
+++ b/runtime/interpreter/mterp/arm64/zcmp.S
@@ -21,11 +21,18 @@
lsr w0, wINST, #8 // w0<- AA
GET_VREG w2, w0 // w2<- vAA
FETCH_S w1, 1 // w1<- branch offset, in code units
- ldr w7, [xSELF, #THREAD_FLAGS_OFFSET]
mov w0, #2 // Branch offset if not taken
cmp w2, #0 // compare (vA, 0)
- csel w1, w1, w0, ${condition} // Branch if true
- adds w2, w1, w1 // convert to bytes & set flags
+ csel wINST, w1, w0, ${condition} // Branch if true, stashing result in callee save reg
+#if MTERP_PROFILE_BRANCHES
+ mov x0, xSELF
+ add x1, xFP, #OFF_FP_SHADOWFRAME
+ sbfm x2, xINST, 0, 31
+ bl MterpProfileBranch // (self, shadow_frame, offset)
+ cbnz w0, MterpOnStackReplacement // Note: offset must be in wINST
+#endif
+ ldr w7, [xSELF, #THREAD_FLAGS_OFFSET]
+ adds w2, wINST, wINST // convert to bytes & set flags
FETCH_ADVANCE_INST_RB w2 // update rPC, load wINST
b.mi MterpCheckSuspendAndContinue
GET_INST_OPCODE ip // extract opcode from wINST
diff --git a/runtime/interpreter/mterp/mterp.cc b/runtime/interpreter/mterp/mterp.cc
index 0afd276..3e2a222 100644
--- a/runtime/interpreter/mterp/mterp.cc
+++ b/runtime/interpreter/mterp/mterp.cc
@@ -488,6 +488,14 @@
<< self->IsExceptionPending();
}
+extern "C" void MterpLogOSR(Thread* self, ShadowFrame* shadow_frame, int32_t offset)
+ SHARED_REQUIRES(Locks::mutator_lock_) {
+ UNUSED(self);
+ const Instruction* inst = Instruction::At(shadow_frame->GetDexPCPtr());
+ uint16_t inst_data = inst->Fetch16(0);
+ LOG(INFO) << "OSR: " << inst->Opcode(inst_data) << ", offset = " << offset;
+}
+
extern "C" void MterpLogSuspendFallback(Thread* self, ShadowFrame* shadow_frame, uint32_t flags)
SHARED_REQUIRES(Locks::mutator_lock_) {
UNUSED(self);
@@ -618,5 +626,14 @@
return obj->GetFieldObject<mirror::Object>(MemberOffset(field_offset));
}
+extern "C" bool MterpProfileBranch(Thread* self, ShadowFrame* shadow_frame, int32_t offset)
+ SHARED_REQUIRES(Locks::mutator_lock_) {
+ if (offset <= 0) {
+ const auto* const instrumentation = Runtime::Current()->GetInstrumentation();
+ instrumentation->Branch(self, shadow_frame->GetMethod(), shadow_frame->GetDexPC(), offset);
+ }
+ return false; // TDB - return true if need to trigger on-stack replacement.
+}
+
} // namespace interpreter
} // namespace art
diff --git a/runtime/interpreter/mterp/out/mterp_arm.S b/runtime/interpreter/mterp/out/mterp_arm.S
index 78c784b..9091b6f 100644
--- a/runtime/interpreter/mterp/out/mterp_arm.S
+++ b/runtime/interpreter/mterp/out/mterp_arm.S
@@ -92,6 +92,8 @@
*/
#include "asm_support.h"
+#define MTERP_PROFILE_BRANCHES 1
+
/* During bringup, we'll use the shadow frame model instead of rFP */
/* single-purpose registers, given names for clarity */
#define rPC r4
@@ -1100,10 +1102,18 @@
GET_INST_OPCODE ip @ extract opcode from rINST
GOTO_OPCODE ip @ jump to next instruction
#else
- ldr lr, [rSELF, #THREAD_FLAGS_OFFSET]
mov r0, rINST, lsl #16 @ r0<- AAxx0000
- movs r1, r0, asr #24 @ r1<- ssssssAA (sign-extended)
- add r2, r1, r1 @ r2<- byte offset, set flags
+ movs rINST, r0, asr #24 @ rINST<- ssssssAA (sign-extended)
+#if MTERP_PROFILE_BRANCHES
+ mov r0, rSELF
+ add r1, rFP, #OFF_FP_SHADOWFRAME
+ mov r2, rINST
+ bl MterpProfileBranch @ (self, shadow_frame, offset)
+ cmp r0, #0
+ bne MterpOnStackReplacement @ Note: offset must be in rINST
+#endif
+ ldr lr, [rSELF, #THREAD_FLAGS_OFFSET]
+ add r2, rINST, rINST @ r2<- byte offset, set flags
FETCH_ADVANCE_INST_RB r2 @ update rPC, load rINST
@ If backwards branch refresh rIBASE
bmi MterpCheckSuspendAndContinue
@@ -1130,9 +1140,17 @@
GET_INST_OPCODE ip @ extract opcode from rINST
GOTO_OPCODE ip @ jump to next instruction
#else
- FETCH_S r0, 1 @ r0<- ssssAAAA (sign-extended)
+ FETCH_S rINST, 1 @ rINST<- ssssAAAA (sign-extended)
+#if MTERP_PROFILE_BRANCHES
+ mov r0, rINST
+ add r1, rFP, #OFF_FP_SHADOWFRAME
+ mov r2, rINST
+ bl MterpOnStackReplacement @ (self, shadow_frame, offset)
+ cmp r0, #0
+ bne MterpOnStackReplacement @ Note: offset must be in rINST
+#endif
ldr lr, [rSELF, #THREAD_FLAGS_OFFSET]
- adds r1, r0, r0 @ r1<- byte offset, flags set
+ adds r1, rINST, rINST @ r1<- byte offset, flags set
FETCH_ADVANCE_INST_RB r1 @ update rPC, load rINST
bmi MterpCheckSuspendAndContinue
GET_INST_OPCODE ip @ extract opcode from rINST
@@ -1167,9 +1185,17 @@
#else
FETCH r0, 1 @ r0<- aaaa (lo)
FETCH r1, 2 @ r1<- AAAA (hi)
+ orr rINST, r0, r1, lsl #16 @ rINST<- AAAAaaaa
+#if MTERP_PROFILE_BRANCHES
+ mov r0, rSELF
+ add r1, rFP, #OFF_FP_SHADOWFRAME
+ mov r2, rINST
+ bl MterpOnStackReplacement @ (self, shadow_frame, offset)
+ cmp r0, #0
+ bne MterpOnStackReplacement @ Note: offset must be in rINST
+#endif
ldr lr, [rSELF, #THREAD_FLAGS_OFFSET]
- orr r0, r0, r1, lsl #16 @ r0<- AAAAaaaa
- adds r1, r0, r0 @ r1<- byte offset
+ adds r1, rINST, rINST @ r1<- byte offset
FETCH_ADVANCE_INST_RB r1 @ update rPC, load rINST
ble MterpCheckSuspendAndContinue
GET_INST_OPCODE ip @ extract opcode from rINST
@@ -1211,8 +1237,17 @@
GET_VREG r1, r3 @ r1<- vAA
add r0, rPC, r0, lsl #1 @ r0<- PC + BBBBbbbb*2
bl MterpDoPackedSwitch @ r0<- code-unit branch offset
+ mov rINST, r0
+#if MTERP_PROFILE_BRANCHES
+ mov r0, rSELF
+ add r1, rFP, #OFF_FP_SHADOWFRAME
+ mov r2, rINST
+ bl MterpProfileBranch @ (self, shadow_frame, offset)
+ cmp r0, #0
+ bne MterpOnStackReplacement @ Note: offset must be in rINST
+#endif
ldr lr, [rSELF, #THREAD_FLAGS_OFFSET]
- adds r1, r0, r0 @ r1<- byte offset; clear V
+ adds r1, rINST, rINST @ r1<- byte offset; clear V
FETCH_ADVANCE_INST_RB r1 @ update rPC, load rINST
ble MterpCheckSuspendAndContinue
GET_INST_OPCODE ip @ extract opcode from rINST
@@ -1255,8 +1290,17 @@
GET_VREG r1, r3 @ r1<- vAA
add r0, rPC, r0, lsl #1 @ r0<- PC + BBBBbbbb*2
bl MterpDoSparseSwitch @ r0<- code-unit branch offset
+ mov rINST, r0
+#if MTERP_PROFILE_BRANCHES
+ mov r0, rSELF
+ add r1, rFP, #OFF_FP_SHADOWFRAME
+ mov r2, rINST
+ bl MterpProfileBranch @ (self, shadow_frame, offset)
+ cmp r0, #0
+ bne MterpOnStackReplacement @ Note: offset must be in rINST
+#endif
ldr lr, [rSELF, #THREAD_FLAGS_OFFSET]
- adds r1, r0, r0 @ r1<- byte offset; clear V
+ adds r1, rINST, rINST @ r1<- byte offset; clear V
FETCH_ADVANCE_INST_RB r1 @ update rPC, load rINST
ble MterpCheckSuspendAndContinue
GET_INST_OPCODE ip @ extract opcode from rINST
@@ -1493,10 +1537,18 @@
GET_VREG r3, r1 @ r3<- vB
GET_VREG r2, r0 @ r2<- vA
ldr lr, [rSELF, #THREAD_FLAGS_OFFSET]
- FETCH_S r1, 1 @ r1<- branch offset, in code units
+ FETCH_S rINST, 1 @ rINST<- branch offset, in code units
cmp r2, r3 @ compare (vA, vB)
- movne r1, #2 @ r1<- BYTE branch dist for not-taken
- adds r2, r1, r1 @ convert to bytes, check sign
+ movne rINST, #2 @ rINST<- BYTE branch dist for not-taken
+#if MTERP_PROFILE_BRANCHES
+ mov r0, rSELF
+ add r1, rFP, #OFF_FP_SHADOWFRAME
+ mov r2, rINST
+ bl MterpProfileBranch @ (self, shadow_frame, offset)
+ cmp r0, #0
+ bne MterpOnStackReplacement @ Note: offset must be in rINST
+#endif
+ adds r2, rINST, rINST @ convert to bytes, check sign
FETCH_ADVANCE_INST_RB r2 @ update rPC, load rINST
bmi MterpCheckSuspendAndContinue
GET_INST_OPCODE ip @ extract opcode from rINST
@@ -1536,10 +1588,18 @@
GET_VREG r3, r1 @ r3<- vB
GET_VREG r2, r0 @ r2<- vA
ldr lr, [rSELF, #THREAD_FLAGS_OFFSET]
- FETCH_S r1, 1 @ r1<- branch offset, in code units
+ FETCH_S rINST, 1 @ rINST<- branch offset, in code units
cmp r2, r3 @ compare (vA, vB)
- moveq r1, #2 @ r1<- BYTE branch dist for not-taken
- adds r2, r1, r1 @ convert to bytes, check sign
+ moveq rINST, #2 @ rINST<- BYTE branch dist for not-taken
+#if MTERP_PROFILE_BRANCHES
+ mov r0, rSELF
+ add r1, rFP, #OFF_FP_SHADOWFRAME
+ mov r2, rINST
+ bl MterpProfileBranch @ (self, shadow_frame, offset)
+ cmp r0, #0
+ bne MterpOnStackReplacement @ Note: offset must be in rINST
+#endif
+ adds r2, rINST, rINST @ convert to bytes, check sign
FETCH_ADVANCE_INST_RB r2 @ update rPC, load rINST
bmi MterpCheckSuspendAndContinue
GET_INST_OPCODE ip @ extract opcode from rINST
@@ -1579,10 +1639,18 @@
GET_VREG r3, r1 @ r3<- vB
GET_VREG r2, r0 @ r2<- vA
ldr lr, [rSELF, #THREAD_FLAGS_OFFSET]
- FETCH_S r1, 1 @ r1<- branch offset, in code units
+ FETCH_S rINST, 1 @ rINST<- branch offset, in code units
cmp r2, r3 @ compare (vA, vB)
- movge r1, #2 @ r1<- BYTE branch dist for not-taken
- adds r2, r1, r1 @ convert to bytes, check sign
+ movge rINST, #2 @ rINST<- BYTE branch dist for not-taken
+#if MTERP_PROFILE_BRANCHES
+ mov r0, rSELF
+ add r1, rFP, #OFF_FP_SHADOWFRAME
+ mov r2, rINST
+ bl MterpProfileBranch @ (self, shadow_frame, offset)
+ cmp r0, #0
+ bne MterpOnStackReplacement @ Note: offset must be in rINST
+#endif
+ adds r2, rINST, rINST @ convert to bytes, check sign
FETCH_ADVANCE_INST_RB r2 @ update rPC, load rINST
bmi MterpCheckSuspendAndContinue
GET_INST_OPCODE ip @ extract opcode from rINST
@@ -1622,10 +1690,18 @@
GET_VREG r3, r1 @ r3<- vB
GET_VREG r2, r0 @ r2<- vA
ldr lr, [rSELF, #THREAD_FLAGS_OFFSET]
- FETCH_S r1, 1 @ r1<- branch offset, in code units
+ FETCH_S rINST, 1 @ rINST<- branch offset, in code units
cmp r2, r3 @ compare (vA, vB)
- movlt r1, #2 @ r1<- BYTE branch dist for not-taken
- adds r2, r1, r1 @ convert to bytes, check sign
+ movlt rINST, #2 @ rINST<- BYTE branch dist for not-taken
+#if MTERP_PROFILE_BRANCHES
+ mov r0, rSELF
+ add r1, rFP, #OFF_FP_SHADOWFRAME
+ mov r2, rINST
+ bl MterpProfileBranch @ (self, shadow_frame, offset)
+ cmp r0, #0
+ bne MterpOnStackReplacement @ Note: offset must be in rINST
+#endif
+ adds r2, rINST, rINST @ convert to bytes, check sign
FETCH_ADVANCE_INST_RB r2 @ update rPC, load rINST
bmi MterpCheckSuspendAndContinue
GET_INST_OPCODE ip @ extract opcode from rINST
@@ -1665,10 +1741,18 @@
GET_VREG r3, r1 @ r3<- vB
GET_VREG r2, r0 @ r2<- vA
ldr lr, [rSELF, #THREAD_FLAGS_OFFSET]
- FETCH_S r1, 1 @ r1<- branch offset, in code units
+ FETCH_S rINST, 1 @ rINST<- branch offset, in code units
cmp r2, r3 @ compare (vA, vB)
- movle r1, #2 @ r1<- BYTE branch dist for not-taken
- adds r2, r1, r1 @ convert to bytes, check sign
+ movle rINST, #2 @ rINST<- BYTE branch dist for not-taken
+#if MTERP_PROFILE_BRANCHES
+ mov r0, rSELF
+ add r1, rFP, #OFF_FP_SHADOWFRAME
+ mov r2, rINST
+ bl MterpProfileBranch @ (self, shadow_frame, offset)
+ cmp r0, #0
+ bne MterpOnStackReplacement @ Note: offset must be in rINST
+#endif
+ adds r2, rINST, rINST @ convert to bytes, check sign
FETCH_ADVANCE_INST_RB r2 @ update rPC, load rINST
bmi MterpCheckSuspendAndContinue
GET_INST_OPCODE ip @ extract opcode from rINST
@@ -1708,10 +1792,18 @@
GET_VREG r3, r1 @ r3<- vB
GET_VREG r2, r0 @ r2<- vA
ldr lr, [rSELF, #THREAD_FLAGS_OFFSET]
- FETCH_S r1, 1 @ r1<- branch offset, in code units
+ FETCH_S rINST, 1 @ rINST<- branch offset, in code units
cmp r2, r3 @ compare (vA, vB)
- movgt r1, #2 @ r1<- BYTE branch dist for not-taken
- adds r2, r1, r1 @ convert to bytes, check sign
+ movgt rINST, #2 @ rINST<- BYTE branch dist for not-taken
+#if MTERP_PROFILE_BRANCHES
+ mov r0, rSELF
+ add r1, rFP, #OFF_FP_SHADOWFRAME
+ mov r2, rINST
+ bl MterpProfileBranch @ (self, shadow_frame, offset)
+ cmp r0, #0
+ bne MterpOnStackReplacement @ Note: offset must be in rINST
+#endif
+ adds r2, rINST, rINST @ convert to bytes, check sign
FETCH_ADVANCE_INST_RB r2 @ update rPC, load rINST
bmi MterpCheckSuspendAndContinue
GET_INST_OPCODE ip @ extract opcode from rINST
@@ -1746,11 +1838,19 @@
#else
mov r0, rINST, lsr #8 @ r0<- AA
GET_VREG r2, r0 @ r2<- vAA
- FETCH_S r1, 1 @ r1<- branch offset, in code units
+ FETCH_S rINST, 1 @ rINST<- branch offset, in code units
ldr lr, [rSELF, #THREAD_FLAGS_OFFSET]
cmp r2, #0 @ compare (vA, 0)
- movne r1, #2 @ r1<- inst branch dist for not-taken
- adds r1, r1, r1 @ convert to bytes & set flags
+ movne rINST, #2 @ rINST<- inst branch dist for not-taken
+#if MTERP_PROFILE_BRANCHES
+ mov r0, rSELF
+ add r1, rFP, #OFF_FP_SHADOWFRAME
+ mov r2, rINST
+ bl MterpProfileBranch @ (self, shadow_frame, offset)
+ cmp r0, #0
+ bne MterpOnStackReplacement @ Note: offset must be in rINST
+#endif
+ adds r1, rINST, rINST @ convert to bytes & set flags
FETCH_ADVANCE_INST_RB r1 @ update rPC, load rINST
bmi MterpCheckSuspendAndContinue
GET_INST_OPCODE ip @ extract opcode from rINST
@@ -1785,11 +1885,19 @@
#else
mov r0, rINST, lsr #8 @ r0<- AA
GET_VREG r2, r0 @ r2<- vAA
- FETCH_S r1, 1 @ r1<- branch offset, in code units
+ FETCH_S rINST, 1 @ rINST<- branch offset, in code units
ldr lr, [rSELF, #THREAD_FLAGS_OFFSET]
cmp r2, #0 @ compare (vA, 0)
- moveq r1, #2 @ r1<- inst branch dist for not-taken
- adds r1, r1, r1 @ convert to bytes & set flags
+ moveq rINST, #2 @ rINST<- inst branch dist for not-taken
+#if MTERP_PROFILE_BRANCHES
+ mov r0, rSELF
+ add r1, rFP, #OFF_FP_SHADOWFRAME
+ mov r2, rINST
+ bl MterpProfileBranch @ (self, shadow_frame, offset)
+ cmp r0, #0
+ bne MterpOnStackReplacement @ Note: offset must be in rINST
+#endif
+ adds r1, rINST, rINST @ convert to bytes & set flags
FETCH_ADVANCE_INST_RB r1 @ update rPC, load rINST
bmi MterpCheckSuspendAndContinue
GET_INST_OPCODE ip @ extract opcode from rINST
@@ -1824,11 +1932,19 @@
#else
mov r0, rINST, lsr #8 @ r0<- AA
GET_VREG r2, r0 @ r2<- vAA
- FETCH_S r1, 1 @ r1<- branch offset, in code units
+ FETCH_S rINST, 1 @ rINST<- branch offset, in code units
ldr lr, [rSELF, #THREAD_FLAGS_OFFSET]
cmp r2, #0 @ compare (vA, 0)
- movge r1, #2 @ r1<- inst branch dist for not-taken
- adds r1, r1, r1 @ convert to bytes & set flags
+ movge rINST, #2 @ rINST<- inst branch dist for not-taken
+#if MTERP_PROFILE_BRANCHES
+ mov r0, rSELF
+ add r1, rFP, #OFF_FP_SHADOWFRAME
+ mov r2, rINST
+ bl MterpProfileBranch @ (self, shadow_frame, offset)
+ cmp r0, #0
+ bne MterpOnStackReplacement @ Note: offset must be in rINST
+#endif
+ adds r1, rINST, rINST @ convert to bytes & set flags
FETCH_ADVANCE_INST_RB r1 @ update rPC, load rINST
bmi MterpCheckSuspendAndContinue
GET_INST_OPCODE ip @ extract opcode from rINST
@@ -1863,11 +1979,19 @@
#else
mov r0, rINST, lsr #8 @ r0<- AA
GET_VREG r2, r0 @ r2<- vAA
- FETCH_S r1, 1 @ r1<- branch offset, in code units
+ FETCH_S rINST, 1 @ rINST<- branch offset, in code units
ldr lr, [rSELF, #THREAD_FLAGS_OFFSET]
cmp r2, #0 @ compare (vA, 0)
- movlt r1, #2 @ r1<- inst branch dist for not-taken
- adds r1, r1, r1 @ convert to bytes & set flags
+ movlt rINST, #2 @ rINST<- inst branch dist for not-taken
+#if MTERP_PROFILE_BRANCHES
+ mov r0, rSELF
+ add r1, rFP, #OFF_FP_SHADOWFRAME
+ mov r2, rINST
+ bl MterpProfileBranch @ (self, shadow_frame, offset)
+ cmp r0, #0
+ bne MterpOnStackReplacement @ Note: offset must be in rINST
+#endif
+ adds r1, rINST, rINST @ convert to bytes & set flags
FETCH_ADVANCE_INST_RB r1 @ update rPC, load rINST
bmi MterpCheckSuspendAndContinue
GET_INST_OPCODE ip @ extract opcode from rINST
@@ -1902,11 +2026,19 @@
#else
mov r0, rINST, lsr #8 @ r0<- AA
GET_VREG r2, r0 @ r2<- vAA
- FETCH_S r1, 1 @ r1<- branch offset, in code units
+ FETCH_S rINST, 1 @ rINST<- branch offset, in code units
ldr lr, [rSELF, #THREAD_FLAGS_OFFSET]
cmp r2, #0 @ compare (vA, 0)
- movle r1, #2 @ r1<- inst branch dist for not-taken
- adds r1, r1, r1 @ convert to bytes & set flags
+ movle rINST, #2 @ rINST<- inst branch dist for not-taken
+#if MTERP_PROFILE_BRANCHES
+ mov r0, rSELF
+ add r1, rFP, #OFF_FP_SHADOWFRAME
+ mov r2, rINST
+ bl MterpProfileBranch @ (self, shadow_frame, offset)
+ cmp r0, #0
+ bne MterpOnStackReplacement @ Note: offset must be in rINST
+#endif
+ adds r1, rINST, rINST @ convert to bytes & set flags
FETCH_ADVANCE_INST_RB r1 @ update rPC, load rINST
bmi MterpCheckSuspendAndContinue
GET_INST_OPCODE ip @ extract opcode from rINST
@@ -1941,11 +2073,19 @@
#else
mov r0, rINST, lsr #8 @ r0<- AA
GET_VREG r2, r0 @ r2<- vAA
- FETCH_S r1, 1 @ r1<- branch offset, in code units
+ FETCH_S rINST, 1 @ rINST<- branch offset, in code units
ldr lr, [rSELF, #THREAD_FLAGS_OFFSET]
cmp r2, #0 @ compare (vA, 0)
- movgt r1, #2 @ r1<- inst branch dist for not-taken
- adds r1, r1, r1 @ convert to bytes & set flags
+ movgt rINST, #2 @ rINST<- inst branch dist for not-taken
+#if MTERP_PROFILE_BRANCHES
+ mov r0, rSELF
+ add r1, rFP, #OFF_FP_SHADOWFRAME
+ mov r2, rINST
+ bl MterpProfileBranch @ (self, shadow_frame, offset)
+ cmp r0, #0
+ bne MterpOnStackReplacement @ Note: offset must be in rINST
+#endif
+ adds r1, rINST, rINST @ convert to bytes & set flags
FETCH_ADVANCE_INST_RB r1 @ update rPC, load rINST
bmi MterpCheckSuspendAndContinue
GET_INST_OPCODE ip @ extract opcode from rINST
@@ -12177,6 +12317,18 @@
GOTO_OPCODE ip @ jump to next instruction
/*
+ * On-stack replacement pending.
+ * Branch offset in rINST on entry.
+ */
+MterpOnStackReplacement:
+#if MTERP_LOGGING
+ mov r0, rSELF
+ add r1, rFP, #OFF_FP_SHADOWFRAME
+ mov r2, rINST
+ bl MterpLogOSR
+#endif
+ b MterpFallback @ Let the reference interpreter deal with it.
+/*
* Bail out to reference interpreter.
*/
MterpFallback:
diff --git a/runtime/interpreter/mterp/out/mterp_arm64.S b/runtime/interpreter/mterp/out/mterp_arm64.S
index e9d28ab..220041f 100644
--- a/runtime/interpreter/mterp/out/mterp_arm64.S
+++ b/runtime/interpreter/mterp/out/mterp_arm64.S
@@ -94,6 +94,8 @@
*/
#include "asm_support.h"
+#define MTERP_PROFILE_BRANCHES 1
+
/* During bringup, we'll use the shadow frame model instead of xFP */
/* single-purpose registers, given names for clarity */
#define xPC x20
@@ -1097,10 +1099,17 @@
GET_INST_OPCODE ip // extract opcode from wINST
GOTO_OPCODE ip // jump to next instruction
#else
- ldr w7, [xSELF, #THREAD_FLAGS_OFFSET] // Preload flags for MterpCheckSuspendAndContinue
lsl w0, wINST, #16 // w0<- AAxx0000
- asr w0, w0, #24 // w0<- ssssssAA (sign-extended)
- adds w1, w0, w0 // Convert dalvik offset to byte offset, setting flags
+ asr wINST, w0, #24 // wINST<- ssssssAA (sign-extended)
+#if MTERP_PROFILE_BRANCHES
+ mov x0, xSELF
+ add x1, xFP, #OFF_FP_SHADOWFRAME
+ sbfm x2, xINST, 0, 31
+ bl MterpProfileBranch // (self, shadow_frame, offset)
+ cbnz w0, MterpOnStackReplacement // Note: offset must be in wINST
+#endif
+ ldr w7, [xSELF, #THREAD_FLAGS_OFFSET] // Preload flags for MterpCheckSuspendAndContinue
+ adds w1, wINST, wINST // Convert dalvik offset to byte offset, setting flags
FETCH_ADVANCE_INST_RB w1 // load wINST and advance xPC
// If backwards branch refresh rIBASE
b.mi MterpCheckSuspendAndContinue
@@ -1127,9 +1136,16 @@
GET_INST_OPCODE ip // extract opcode from rINST
GOTO_OPCODE ip // jump to next instruction
#else
- FETCH_S w0, 1 // w0<- ssssAAAA (sign-extended)
+ FETCH_S wINST, 1 // wINST<- ssssAAAA (sign-extended)
+#if MTERP_PROFILE_BRANCHES
+ mov x0, xSELF
+ add x1, xFP, #OFF_FP_SHADOWFRAME
+ sbfm x2, xINST, 0, 31
+ bl MterpProfileBranch // (self, shadow_frame, offset)
+ cbnz w0, MterpOnStackReplacement // Note: offset must be in xINST
+#endif
ldr w7, [xSELF, #THREAD_FLAGS_OFFSET]
- adds w1, w0, w0 // w1<- byte offset, flags set
+ adds w1, wINST, wINST // w1<- byte offset, flags set
FETCH_ADVANCE_INST_RB w1 // update rPC, load rINST
b.mi MterpCheckSuspendAndContinue
GET_INST_OPCODE ip // extract opcode from rINST
@@ -1164,9 +1180,16 @@
#else
FETCH w0, 1 // w0<- aaaa (lo)
FETCH w1, 2 // w1<- AAAA (hi)
+ orr wINST, w0, w1, lsl #16 // wINST<- AAAAaaaa
+#if MTERP_PROFILE_BRANCHES
+ mov x0, xSELF
+ add x1, xFP, #OFF_FP_SHADOWFRAME
+ sbfm x2, xINST, 0, 31
+ bl MterpProfileBranch // (self, shadow_frame, offset)
+ cbnz w0, MterpOnStackReplacement // Note: offset must be in xINST
+#endif
ldr w7, [xSELF, #THREAD_FLAGS_OFFSET]
- orr w0, w0, w1, lsl #16 // w0<- AAAAaaaa
- adds w1, w0, w0 // w1<- byte offset
+ adds w1, wINST, wINST // w1<- byte offset
FETCH_ADVANCE_INST_RB w1 // update rPC, load xINST
b.le MterpCheckSuspendAndContinue
GET_INST_OPCODE ip // extract opcode from xINST
@@ -1208,8 +1231,16 @@
GET_VREG w1, w3 // w1<- vAA
add x0, xPC, w0, lsl #1 // w0<- PC + BBBBbbbb*2
bl MterpDoPackedSwitch // w0<- code-unit branch offset
+ sbfm xINST, x0, 0, 31
+#if MTERP_PROFILE_BRANCHES
+ mov x0, xSELF
+ add x1, xFP, #OFF_FP_SHADOWFRAME
+ mov x2, xINST
+ bl MterpProfileBranch // (self, shadow_frame, offset)
+ cbnz w0, MterpOnStackReplacement
+#endif
ldr w7, [xSELF, #THREAD_FLAGS_OFFSET]
- adds w1, w0, w0 // w1<- byte offset; clear V
+ adds w1, wINST, wINST // w1<- byte offset; clear V
FETCH_ADVANCE_INST_RB w1 // update rPC, load wINST
b.le MterpCheckSuspendAndContinue
GET_INST_OPCODE ip // extract opcode from wINST
@@ -1252,8 +1283,16 @@
GET_VREG w1, w3 // w1<- vAA
add x0, xPC, w0, lsl #1 // w0<- PC + BBBBbbbb*2
bl MterpDoSparseSwitch // w0<- code-unit branch offset
+ sbfm xINST, x0, 0, 31
+#if MTERP_PROFILE_BRANCHES
+ mov x0, xSELF
+ add x1, xFP, #OFF_FP_SHADOWFRAME
+ mov x2, xINST
+ bl MterpProfileBranch // (self, shadow_frame, offset)
+ cbnz w0, MterpOnStackReplacement
+#endif
ldr w7, [xSELF, #THREAD_FLAGS_OFFSET]
- adds w1, w0, w0 // w1<- byte offset; clear V
+ adds w1, wINST, wINST // w1<- byte offset; clear V
FETCH_ADVANCE_INST_RB w1 // update rPC, load wINST
b.le MterpCheckSuspendAndContinue
GET_INST_OPCODE ip // extract opcode from wINST
@@ -1415,11 +1454,18 @@
GET_VREG w3, w1 // w3<- vB
GET_VREG w2, w0 // w2<- vA
FETCH_S w1, 1 // w1<- branch offset, in code units
- ldr w7, [xSELF, #THREAD_FLAGS_OFFSET]
mov w0, #2 // Offset if branch not taken
cmp w2, w3 // compare (vA, vB)
- csel w1, w1, w0, eq // Branch if true
- adds w2, w1, w1 // convert to bytes, check sign
+ csel wINST, w1, w0, eq // Branch if true, stashing result in callee save reg.
+#if MTERP_PROFILE_BRANCHES
+ mov x0, xSELF
+ add x1, xFP, #OFF_FP_SHADOWFRAME
+ sbfm x2, xINST, 0, 31 // Sign extend branch offset
+ bl MterpProfileBranch // (self, shadow_frame, offset)
+ cbnz w0, MterpOnStackReplacement // Note: offset must be in xINST
+#endif
+ ldr w7, [xSELF, #THREAD_FLAGS_OFFSET]
+ adds w2, wINST, wINST // convert to bytes, check sign
FETCH_ADVANCE_INST_RB w2 // update rPC, load wINST
b.mi MterpCheckSuspendAndContinue
GET_INST_OPCODE ip // extract opcode from wINST
@@ -1459,11 +1505,18 @@
GET_VREG w3, w1 // w3<- vB
GET_VREG w2, w0 // w2<- vA
FETCH_S w1, 1 // w1<- branch offset, in code units
- ldr w7, [xSELF, #THREAD_FLAGS_OFFSET]
mov w0, #2 // Offset if branch not taken
cmp w2, w3 // compare (vA, vB)
- csel w1, w1, w0, ne // Branch if true
- adds w2, w1, w1 // convert to bytes, check sign
+ csel wINST, w1, w0, ne // Branch if true, stashing result in callee save reg.
+#if MTERP_PROFILE_BRANCHES
+ mov x0, xSELF
+ add x1, xFP, #OFF_FP_SHADOWFRAME
+ sbfm x2, xINST, 0, 31 // Sign extend branch offset
+ bl MterpProfileBranch // (self, shadow_frame, offset)
+ cbnz w0, MterpOnStackReplacement // Note: offset must be in xINST
+#endif
+ ldr w7, [xSELF, #THREAD_FLAGS_OFFSET]
+ adds w2, wINST, wINST // convert to bytes, check sign
FETCH_ADVANCE_INST_RB w2 // update rPC, load wINST
b.mi MterpCheckSuspendAndContinue
GET_INST_OPCODE ip // extract opcode from wINST
@@ -1503,11 +1556,18 @@
GET_VREG w3, w1 // w3<- vB
GET_VREG w2, w0 // w2<- vA
FETCH_S w1, 1 // w1<- branch offset, in code units
- ldr w7, [xSELF, #THREAD_FLAGS_OFFSET]
mov w0, #2 // Offset if branch not taken
cmp w2, w3 // compare (vA, vB)
- csel w1, w1, w0, lt // Branch if true
- adds w2, w1, w1 // convert to bytes, check sign
+ csel wINST, w1, w0, lt // Branch if true, stashing result in callee save reg.
+#if MTERP_PROFILE_BRANCHES
+ mov x0, xSELF
+ add x1, xFP, #OFF_FP_SHADOWFRAME
+ sbfm x2, xINST, 0, 31 // Sign extend branch offset
+ bl MterpProfileBranch // (self, shadow_frame, offset)
+ cbnz w0, MterpOnStackReplacement // Note: offset must be in xINST
+#endif
+ ldr w7, [xSELF, #THREAD_FLAGS_OFFSET]
+ adds w2, wINST, wINST // convert to bytes, check sign
FETCH_ADVANCE_INST_RB w2 // update rPC, load wINST
b.mi MterpCheckSuspendAndContinue
GET_INST_OPCODE ip // extract opcode from wINST
@@ -1547,11 +1607,18 @@
GET_VREG w3, w1 // w3<- vB
GET_VREG w2, w0 // w2<- vA
FETCH_S w1, 1 // w1<- branch offset, in code units
- ldr w7, [xSELF, #THREAD_FLAGS_OFFSET]
mov w0, #2 // Offset if branch not taken
cmp w2, w3 // compare (vA, vB)
- csel w1, w1, w0, ge // Branch if true
- adds w2, w1, w1 // convert to bytes, check sign
+ csel wINST, w1, w0, ge // Branch if true, stashing result in callee save reg.
+#if MTERP_PROFILE_BRANCHES
+ mov x0, xSELF
+ add x1, xFP, #OFF_FP_SHADOWFRAME
+ sbfm x2, xINST, 0, 31 // Sign extend branch offset
+ bl MterpProfileBranch // (self, shadow_frame, offset)
+ cbnz w0, MterpOnStackReplacement // Note: offset must be in xINST
+#endif
+ ldr w7, [xSELF, #THREAD_FLAGS_OFFSET]
+ adds w2, wINST, wINST // convert to bytes, check sign
FETCH_ADVANCE_INST_RB w2 // update rPC, load wINST
b.mi MterpCheckSuspendAndContinue
GET_INST_OPCODE ip // extract opcode from wINST
@@ -1591,11 +1658,18 @@
GET_VREG w3, w1 // w3<- vB
GET_VREG w2, w0 // w2<- vA
FETCH_S w1, 1 // w1<- branch offset, in code units
- ldr w7, [xSELF, #THREAD_FLAGS_OFFSET]
mov w0, #2 // Offset if branch not taken
cmp w2, w3 // compare (vA, vB)
- csel w1, w1, w0, gt // Branch if true
- adds w2, w1, w1 // convert to bytes, check sign
+ csel wINST, w1, w0, gt // Branch if true, stashing result in callee save reg.
+#if MTERP_PROFILE_BRANCHES
+ mov x0, xSELF
+ add x1, xFP, #OFF_FP_SHADOWFRAME
+ sbfm x2, xINST, 0, 31 // Sign extend branch offset
+ bl MterpProfileBranch // (self, shadow_frame, offset)
+ cbnz w0, MterpOnStackReplacement // Note: offset must be in xINST
+#endif
+ ldr w7, [xSELF, #THREAD_FLAGS_OFFSET]
+ adds w2, wINST, wINST // convert to bytes, check sign
FETCH_ADVANCE_INST_RB w2 // update rPC, load wINST
b.mi MterpCheckSuspendAndContinue
GET_INST_OPCODE ip // extract opcode from wINST
@@ -1635,11 +1709,18 @@
GET_VREG w3, w1 // w3<- vB
GET_VREG w2, w0 // w2<- vA
FETCH_S w1, 1 // w1<- branch offset, in code units
- ldr w7, [xSELF, #THREAD_FLAGS_OFFSET]
mov w0, #2 // Offset if branch not taken
cmp w2, w3 // compare (vA, vB)
- csel w1, w1, w0, le // Branch if true
- adds w2, w1, w1 // convert to bytes, check sign
+ csel wINST, w1, w0, le // Branch if true, stashing result in callee save reg.
+#if MTERP_PROFILE_BRANCHES
+ mov x0, xSELF
+ add x1, xFP, #OFF_FP_SHADOWFRAME
+ sbfm x2, xINST, 0, 31 // Sign extend branch offset
+ bl MterpProfileBranch // (self, shadow_frame, offset)
+ cbnz w0, MterpOnStackReplacement // Note: offset must be in xINST
+#endif
+ ldr w7, [xSELF, #THREAD_FLAGS_OFFSET]
+ adds w2, wINST, wINST // convert to bytes, check sign
FETCH_ADVANCE_INST_RB w2 // update rPC, load wINST
b.mi MterpCheckSuspendAndContinue
GET_INST_OPCODE ip // extract opcode from wINST
@@ -1675,11 +1756,18 @@
lsr w0, wINST, #8 // w0<- AA
GET_VREG w2, w0 // w2<- vAA
FETCH_S w1, 1 // w1<- branch offset, in code units
- ldr w7, [xSELF, #THREAD_FLAGS_OFFSET]
mov w0, #2 // Branch offset if not taken
cmp w2, #0 // compare (vA, 0)
- csel w1, w1, w0, eq // Branch if true
- adds w2, w1, w1 // convert to bytes & set flags
+ csel wINST, w1, w0, eq // Branch if true, stashing result in callee save reg
+#if MTERP_PROFILE_BRANCHES
+ mov x0, xSELF
+ add x1, xFP, #OFF_FP_SHADOWFRAME
+ sbfm x2, xINST, 0, 31
+ bl MterpProfileBranch // (self, shadow_frame, offset)
+ cbnz w0, MterpOnStackReplacement // Note: offset must be in wINST
+#endif
+ ldr w7, [xSELF, #THREAD_FLAGS_OFFSET]
+ adds w2, wINST, wINST // convert to bytes & set flags
FETCH_ADVANCE_INST_RB w2 // update rPC, load wINST
b.mi MterpCheckSuspendAndContinue
GET_INST_OPCODE ip // extract opcode from wINST
@@ -1715,11 +1803,18 @@
lsr w0, wINST, #8 // w0<- AA
GET_VREG w2, w0 // w2<- vAA
FETCH_S w1, 1 // w1<- branch offset, in code units
- ldr w7, [xSELF, #THREAD_FLAGS_OFFSET]
mov w0, #2 // Branch offset if not taken
cmp w2, #0 // compare (vA, 0)
- csel w1, w1, w0, ne // Branch if true
- adds w2, w1, w1 // convert to bytes & set flags
+ csel wINST, w1, w0, ne // Branch if true, stashing result in callee save reg
+#if MTERP_PROFILE_BRANCHES
+ mov x0, xSELF
+ add x1, xFP, #OFF_FP_SHADOWFRAME
+ sbfm x2, xINST, 0, 31
+ bl MterpProfileBranch // (self, shadow_frame, offset)
+ cbnz w0, MterpOnStackReplacement // Note: offset must be in wINST
+#endif
+ ldr w7, [xSELF, #THREAD_FLAGS_OFFSET]
+ adds w2, wINST, wINST // convert to bytes & set flags
FETCH_ADVANCE_INST_RB w2 // update rPC, load wINST
b.mi MterpCheckSuspendAndContinue
GET_INST_OPCODE ip // extract opcode from wINST
@@ -1755,11 +1850,18 @@
lsr w0, wINST, #8 // w0<- AA
GET_VREG w2, w0 // w2<- vAA
FETCH_S w1, 1 // w1<- branch offset, in code units
- ldr w7, [xSELF, #THREAD_FLAGS_OFFSET]
mov w0, #2 // Branch offset if not taken
cmp w2, #0 // compare (vA, 0)
- csel w1, w1, w0, lt // Branch if true
- adds w2, w1, w1 // convert to bytes & set flags
+ csel wINST, w1, w0, lt // Branch if true, stashing result in callee save reg
+#if MTERP_PROFILE_BRANCHES
+ mov x0, xSELF
+ add x1, xFP, #OFF_FP_SHADOWFRAME
+ sbfm x2, xINST, 0, 31
+ bl MterpProfileBranch // (self, shadow_frame, offset)
+ cbnz w0, MterpOnStackReplacement // Note: offset must be in wINST
+#endif
+ ldr w7, [xSELF, #THREAD_FLAGS_OFFSET]
+ adds w2, wINST, wINST // convert to bytes & set flags
FETCH_ADVANCE_INST_RB w2 // update rPC, load wINST
b.mi MterpCheckSuspendAndContinue
GET_INST_OPCODE ip // extract opcode from wINST
@@ -1795,11 +1897,18 @@
lsr w0, wINST, #8 // w0<- AA
GET_VREG w2, w0 // w2<- vAA
FETCH_S w1, 1 // w1<- branch offset, in code units
- ldr w7, [xSELF, #THREAD_FLAGS_OFFSET]
mov w0, #2 // Branch offset if not taken
cmp w2, #0 // compare (vA, 0)
- csel w1, w1, w0, ge // Branch if true
- adds w2, w1, w1 // convert to bytes & set flags
+ csel wINST, w1, w0, ge // Branch if true, stashing result in callee save reg
+#if MTERP_PROFILE_BRANCHES
+ mov x0, xSELF
+ add x1, xFP, #OFF_FP_SHADOWFRAME
+ sbfm x2, xINST, 0, 31
+ bl MterpProfileBranch // (self, shadow_frame, offset)
+ cbnz w0, MterpOnStackReplacement // Note: offset must be in wINST
+#endif
+ ldr w7, [xSELF, #THREAD_FLAGS_OFFSET]
+ adds w2, wINST, wINST // convert to bytes & set flags
FETCH_ADVANCE_INST_RB w2 // update rPC, load wINST
b.mi MterpCheckSuspendAndContinue
GET_INST_OPCODE ip // extract opcode from wINST
@@ -1835,11 +1944,18 @@
lsr w0, wINST, #8 // w0<- AA
GET_VREG w2, w0 // w2<- vAA
FETCH_S w1, 1 // w1<- branch offset, in code units
- ldr w7, [xSELF, #THREAD_FLAGS_OFFSET]
mov w0, #2 // Branch offset if not taken
cmp w2, #0 // compare (vA, 0)
- csel w1, w1, w0, gt // Branch if true
- adds w2, w1, w1 // convert to bytes & set flags
+ csel wINST, w1, w0, gt // Branch if true, stashing result in callee save reg
+#if MTERP_PROFILE_BRANCHES
+ mov x0, xSELF
+ add x1, xFP, #OFF_FP_SHADOWFRAME
+ sbfm x2, xINST, 0, 31
+ bl MterpProfileBranch // (self, shadow_frame, offset)
+ cbnz w0, MterpOnStackReplacement // Note: offset must be in wINST
+#endif
+ ldr w7, [xSELF, #THREAD_FLAGS_OFFSET]
+ adds w2, wINST, wINST // convert to bytes & set flags
FETCH_ADVANCE_INST_RB w2 // update rPC, load wINST
b.mi MterpCheckSuspendAndContinue
GET_INST_OPCODE ip // extract opcode from wINST
@@ -1875,11 +1991,18 @@
lsr w0, wINST, #8 // w0<- AA
GET_VREG w2, w0 // w2<- vAA
FETCH_S w1, 1 // w1<- branch offset, in code units
- ldr w7, [xSELF, #THREAD_FLAGS_OFFSET]
mov w0, #2 // Branch offset if not taken
cmp w2, #0 // compare (vA, 0)
- csel w1, w1, w0, le // Branch if true
- adds w2, w1, w1 // convert to bytes & set flags
+ csel wINST, w1, w0, le // Branch if true, stashing result in callee save reg
+#if MTERP_PROFILE_BRANCHES
+ mov x0, xSELF
+ add x1, xFP, #OFF_FP_SHADOWFRAME
+ sbfm x2, xINST, 0, 31
+ bl MterpProfileBranch // (self, shadow_frame, offset)
+ cbnz w0, MterpOnStackReplacement // Note: offset must be in wINST
+#endif
+ ldr w7, [xSELF, #THREAD_FLAGS_OFFSET]
+ adds w2, wINST, wINST // convert to bytes & set flags
FETCH_ADVANCE_INST_RB w2 // update rPC, load wINST
b.mi MterpCheckSuspendAndContinue
GET_INST_OPCODE ip // extract opcode from wINST
@@ -11679,6 +11802,19 @@
GOTO_OPCODE ip // jump to next instruction
/*
+ * On-stack replacement pending.
+ * Branch offset in wINST on entry.
+ */
+MterpOnStackReplacement:
+#if MTERP_LOGGING
+ mov x0, xSELF
+ add x1, xFP, #OFF_FP_SHADOWFRAME
+ sbfm x2, xINST, 0, 31
+ bl MterpLogOSR
+#endif
+ b MterpFallback // Let the reference interpreter deal with it.
+
+/*
* Bail out to reference interpreter.
*/
MterpFallback: