Merge "ART: Fix RegTypeCache::FromUnresolvedMerge()."
diff --git a/compiler/utils/swap_space.cc b/compiler/utils/swap_space.cc
index 244a5fe..1a8f567 100644
--- a/compiler/utils/swap_space.cc
+++ b/compiler/utils/swap_space.cc
@@ -152,7 +152,6 @@
}
size_ += next_part;
SpaceChunk new_chunk = {ptr, next_part};
- maps_.push_back(new_chunk);
return new_chunk;
#else
UNUSED(min_size, kMininumMapSize);
diff --git a/compiler/utils/swap_space.h b/compiler/utils/swap_space.h
index b659f1d..bf06675 100644
--- a/compiler/utils/swap_space.h
+++ b/compiler/utils/swap_space.h
@@ -85,7 +85,6 @@
int fd_;
size_t size_;
- std::list<SpaceChunk> maps_;
// NOTE: Boost.Bimap would be useful for the two following members.
diff --git a/runtime/art_method.cc b/runtime/art_method.cc
index a60f31e..f97ad51 100644
--- a/runtime/art_method.cc
+++ b/runtime/art_method.cc
@@ -377,7 +377,7 @@
Runtime* runtime = Runtime::Current();
const void* existing_entry_point = GetEntryPointFromQuickCompiledCode();
- DCHECK(existing_entry_point != nullptr);
+ CHECK(existing_entry_point != nullptr) << PrettyMethod(this) << "@" << this;
ClassLinker* class_linker = runtime->GetClassLinker();
if (class_linker->IsQuickGenericJniStub(existing_entry_point)) {
diff --git a/runtime/interpreter/mterp/mips/binop.S b/runtime/interpreter/mterp/mips/binop.S
index ce09da45..66627e2 100644
--- a/runtime/interpreter/mterp/mips/binop.S
+++ b/runtime/interpreter/mterp/mips/binop.S
@@ -7,8 +7,8 @@
*
* If "chkzero" is set to 1, we perform a divide-by-zero check on
* vCC (a1). Useful for integer division and modulus. Note that we
- * *don't* check for (INT_MIN / -1) here, because the ARM math lib
- * handles it correctly.
+ * *don't* check for (INT_MIN / -1) here, because the CPU handles it
+ * correctly.
*
* For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
* xor-int, shl-int, shr-int, ushr-int
diff --git a/runtime/interpreter/mterp/mips64/bincmp.S b/runtime/interpreter/mterp/mips64/bincmp.S
index d39c900..aa5e74b 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 1a2e22b..14d5fe0 100644
--- a/runtime/interpreter/mterp/mips64/footer.S
+++ b/runtime/interpreter/mterp/mips64/footer.S
@@ -49,6 +49,7 @@
*
*/
.extern MterpHandleException
+ .extern MterpShouldSwitchInterpreters
MterpException:
move a0, rSELF
daddu a1, rFP, OFF_FP_SHADOWFRAME
@@ -59,8 +60,11 @@
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 @@
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 4c3ca9e..dd0fbe0 100644
--- a/runtime/interpreter/mterp/mips64/header.S
+++ b/runtime/interpreter/mterp/mips64/header.S
@@ -82,14 +82,7 @@
#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 4ae4fb1..be647b6 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 f2df3e4..7c7d0ec 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 cbf8cf2..566e3a7 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 4a1feac..b260083 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 cdbdf75..2c6eb2f 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 d7ad894..0e0477f 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 ca727f4..10b19c5 100644
--- a/runtime/interpreter/mterp/mterp.cc
+++ b/runtime/interpreter/mterp/mterp.cc
@@ -147,16 +147,7 @@
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 7cef823..a17252b 100644
--- a/runtime/interpreter/mterp/out/mterp_mips64.S
+++ b/runtime/interpreter/mterp/out/mterp_mips64.S
@@ -89,14 +89,7 @@
#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 @@
* 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 @@
* 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 @@
* 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 @@
*/
/* 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 @@
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 @@
*/
/* 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 @@
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 @@
* 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 @@
* 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 @@
* 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 @@
* 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 @@
* 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 @@
* 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 @@
* 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 @@
* 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 @@
* 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 @@
* 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 @@
* 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 @@
* 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 @@
/* 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 @@
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 @@
/* 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 @@
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 @@
/* 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 @@
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 @@
/* 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 @@
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 @@
/* 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 @@
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 @@
/* 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 @@
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 @@
/* 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 @@
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 @@
/* 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 @@
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 @@
/* 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 @@
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 @@
/* 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 @@
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 @@
/* 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 @@
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 @@
/* 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 @@
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 @@
*
*/
.extern MterpHandleException
+ .extern MterpShouldSwitchInterpreters
MterpException:
move a0, rSELF
daddu a1, rFP, OFF_FP_SHADOWFRAME
@@ -12266,8 +12312,11 @@
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 @@
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/test/462-checker-inlining-across-dex-files/multidex.jpp b/test/462-checker-inlining-across-dex-files/multidex.jpp
new file mode 100644
index 0000000..ae55456
--- /dev/null
+++ b/test/462-checker-inlining-across-dex-files/multidex.jpp
@@ -0,0 +1,8 @@
+Main:
+ @@com.android.jack.annotations.ForceInMainDex
+ class Main
+
+AAA:
+ @@com.android.jack.annotations.ForceInMainDex
+ class AAA
+
diff --git a/test/556-invoke-super/multidex.jpp b/test/556-invoke-super/multidex.jpp
new file mode 100644
index 0000000..fe01801
--- /dev/null
+++ b/test/556-invoke-super/multidex.jpp
@@ -0,0 +1,4 @@
+Main:
+ @@com.android.jack.annotations.ForceInMainDex
+ class Main*
+
diff --git a/test/569-checker-pattern-replacement/multidex.jpp b/test/569-checker-pattern-replacement/multidex.jpp
new file mode 100644
index 0000000..cfc8ad1
--- /dev/null
+++ b/test/569-checker-pattern-replacement/multidex.jpp
@@ -0,0 +1,8 @@
+Main:
+ @@com.android.jack.annotations.ForceInMainDex
+ class Main
+
+BaseInMainDex:
+ @@com.android.jack.annotations.ForceInMainDex
+ class BaseInMainDex
+
diff --git a/test/etc/default-build b/test/etc/default-build
index 6e855ec..5f78496 100755
--- a/test/etc/default-build
+++ b/test/etc/default-build
@@ -116,28 +116,33 @@
SKIP_DX_MERGER="true"
fi
-if [ "${HAS_SRC_MULTIDEX}" = "true" ]; then
- # Jack does not support this configuration unless we specify how to partition the DEX file
- # with a .jpp file.
- USE_JACK="false"
-fi
-
if [ ${USE_JACK} = "true" ]; then
# Jack toolchain
if [ "${HAS_SRC}" = "true" ]; then
- ${JACK} ${JACK_ARGS} --output-jack src.jack src
- imported_jack_files="--import src.jack"
+ if [ "${HAS_SRC_MULTIDEX}" = "true" ]; then
+ # Compile src and src-multidex in the same .jack file. We will apply multidex partitioning
+ # when creating the output .dex file.
+ ${JACK} ${JACK_ARGS} --output-jack src.jack src src src-multidex
+ jack_extra_args="${jack_extra_args} -D jack.dex.output.policy=minimal-multidex"
+ jack_extra_args="${jack_extra_args} -D jack.preprocessor=true"
+ jack_extra_args="${jack_extra_args} -D jack.preprocessor.file=multidex.jpp"
+ else
+ ${JACK} ${JACK_ARGS} --output-jack src.jack src
+ fi
+ jack_extra_args="${jack_extra_args} --import src.jack"
fi
if [ "${HAS_SRC2}" = "true" ]; then
${JACK} ${JACK_ARGS} --output-jack src2.jack src2
- imported_jack_files="--import src2.jack ${imported_jack_files}"
+ # In case of duplicate classes, we want to take into account the classes from src2. Therefore
+ # we apply the 'keep-first' policy and import src2.jack file *before* the src.jack file.
+ jack_extra_args="${jack_extra_args} -D jack.import.type.policy=keep-first"
+ jack_extra_args="--import src2.jack ${jack_extra_args}"
fi
- # Compile jack files into a DEX file. We set jack.import.type.policy=keep-first to consider
- # class definitions from src2 first.
+ # Compile jack files into a DEX file.
if [ "${HAS_SRC}" = "true" ] || [ "${HAS_SRC2}" = "true" ]; then
- ${JACK} ${JACK_ARGS} ${imported_jack_files} -D jack.import.type.policy=keep-first --output-dex .
+ ${JACK} ${JACK_ARGS} ${jack_extra_args} --output-dex .
fi
else
# Legacy toolchain with javac+dx
diff --git a/tools/setup-buildbot-device.sh b/tools/setup-buildbot-device.sh
index 9e085b5..1e9c763 100755
--- a/tools/setup-buildbot-device.sh
+++ b/tools/setup-buildbot-device.sh
@@ -46,5 +46,13 @@
adb logcat -p
echo -e "${green}Kill stalled dalvikvm processes${nc}"
-processes=$(adb shell "ps" | grep dalvikvm | awk '{print $2}')
-for i in $processes; do adb shell kill -9 $i; done
+# 'ps' on M can sometimes hang.
+timeout 2s adb shell "ps"
+if [ $? = 124 ]; then
+ echo -e "${green}Rebooting device to fix 'ps'${nc}"
+ adb reboot
+ adb wait-for-device root
+else
+ processes=$(adb shell "ps" | grep dalvikvm | awk '{print $2}')
+ for i in $processes; do adb shell kill -9 $i; done
+fi