Merge "Add some more uninterruptible annotations"
diff --git a/compiler/dex/mir_graph.h b/compiler/dex/mir_graph.h
index dbe9062..23b7c42 100644
--- a/compiler/dex/mir_graph.h
+++ b/compiler/dex/mir_graph.h
@@ -173,7 +173,17 @@
typedef uint16_t BasicBlockId;
static const BasicBlockId NullBasicBlockId = 0;
-static constexpr bool kLeafOptimization = false;
+
+// Leaf optimization is basically the removal of suspend checks from leaf methods.
+// This is incompatible with SuspendCheckElimination (SCE) which eliminates suspend
+// checks from loops that call any non-intrinsic method, since a loop that calls
+// only a leaf method would end up without any suspend checks at all. So turning
+// this on automatically disables the SCE in MIRGraph::EliminateSuspendChecksGate().
+//
+// Since the Optimizing compiler is actually applying the same optimization, Quick
+// must not run SCE anyway, so we enable this optimization as a way to disable SCE
+// while keeping a consistent behavior across the backends, b/22657404.
+static constexpr bool kLeafOptimization = true;
/*
* In general, vreg/sreg describe Dalvik registers that originated with dx. However,
diff --git a/compiler/dex/mir_optimization.cc b/compiler/dex/mir_optimization.cc
index 5bb0ce3..80b7ac1 100644
--- a/compiler/dex/mir_optimization.cc
+++ b/compiler/dex/mir_optimization.cc
@@ -1724,7 +1724,8 @@
bool MIRGraph::EliminateSuspendChecksGate() {
- if ((cu_->disable_opt & (1 << kSuspendCheckElimination)) != 0 || // Disabled.
+ if (kLeafOptimization || // Incompatible (could create loops without suspend checks).
+ (cu_->disable_opt & (1 << kSuspendCheckElimination)) != 0 || // Disabled.
GetMaxNestedLoops() == 0u || // Nothing to do.
GetMaxNestedLoops() >= 32u || // Only 32 bits in suspend_checks_in_loops_[.].
// Exclude 32 as well to keep bit shifts well-defined.
diff --git a/compiler/dex/mir_optimization_test.cc b/compiler/dex/mir_optimization_test.cc
index 10a4337..47123ba 100644
--- a/compiler/dex/mir_optimization_test.cc
+++ b/compiler/dex/mir_optimization_test.cc
@@ -467,8 +467,17 @@
cu_.mir_graph->ComputeDominators();
cu_.mir_graph->ComputeTopologicalSortOrder();
cu_.mir_graph->SSATransformationEnd();
+
bool gate_result = cu_.mir_graph->EliminateSuspendChecksGate();
- ASSERT_TRUE(gate_result);
+ ASSERT_NE(gate_result, kLeafOptimization);
+ if (kLeafOptimization) {
+ // Even with kLeafOptimization on and Gate() refusing to allow SCE, we want
+ // to run the SCE test to avoid bitrot, so we need to initialize explicitly.
+ cu_.mir_graph->suspend_checks_in_loops_ =
+ cu_.mir_graph->arena_->AllocArray<uint32_t>(cu_.mir_graph->GetNumBlocks(),
+ kArenaAllocMisc);
+ }
+
TopologicalSortIterator iterator(cu_.mir_graph.get());
bool change = false;
for (BasicBlock* bb = iterator.Next(change); bb != nullptr; bb = iterator.Next(change)) {
diff --git a/runtime/arch/x86_64/quick_entrypoints_x86_64.S b/runtime/arch/x86_64/quick_entrypoints_x86_64.S
index 7e7d789..0eeb03a 100644
--- a/runtime/arch/x86_64/quick_entrypoints_x86_64.S
+++ b/runtime/arch/x86_64/quick_entrypoints_x86_64.S
@@ -1127,19 +1127,23 @@
DEFINE_FUNCTION art_quick_check_cast
PUSH rdi // Save args for exc
PUSH rsi
+ subq LITERAL(8), %rsp // Alignment padding.
+ CFI_ADJUST_CFA_OFFSET(8)
SETUP_FP_CALLEE_SAVE_FRAME
call SYMBOL(artIsAssignableFromCode) // (Class* klass, Class* ref_klass)
testq %rax, %rax
jz 1f // jump forward if not assignable
RESTORE_FP_CALLEE_SAVE_FRAME
- addq LITERAL(16), %rsp // pop arguments
- CFI_ADJUST_CFA_OFFSET(-16)
+ addq LITERAL(24), %rsp // pop arguments
+ CFI_ADJUST_CFA_OFFSET(-24)
ret
- CFI_ADJUST_CFA_OFFSET(16 + 4 * 8) // Reset unwind info so following code unwinds.
+ CFI_ADJUST_CFA_OFFSET(24 + 4 * 8) // Reset unwind info so following code unwinds.
1:
RESTORE_FP_CALLEE_SAVE_FRAME
+ addq LITERAL(8), %rsp // pop padding
+ CFI_ADJUST_CFA_OFFSET(-8)
POP rsi // Pop arguments
POP rdi
SETUP_SAVE_ALL_CALLEE_SAVE_FRAME // save all registers as basis for long jump context
@@ -1226,8 +1230,6 @@
PUSH rdi
PUSH rsi
PUSH rdx
- subq LITERAL(8), %rsp // Alignment padding.
- CFI_ADJUST_CFA_OFFSET(8)
SETUP_FP_CALLEE_SAVE_FRAME
// "Uncompress" = do nothing, as already zero-extended on load.
@@ -1243,8 +1245,6 @@
RESTORE_FP_CALLEE_SAVE_FRAME
// Restore arguments.
- addq LITERAL(8), %rsp
- CFI_ADJUST_CFA_OFFSET(-8)
POP rdx
POP rsi
POP rdi
@@ -1258,12 +1258,10 @@
movb %dl, (%rdx, %rdi) // Note: this assumes that top 32b of %rdi are zero
// movb %dl, (%rdx, %rdi)
ret
- CFI_ADJUST_CFA_OFFSET(32 + 4 * 8) // Reset unwind info so following code unwinds.
+ CFI_ADJUST_CFA_OFFSET(24 + 4 * 8) // Reset unwind info so following code unwinds.
.Lthrow_array_store_exception:
RESTORE_FP_CALLEE_SAVE_FRAME
// Restore arguments.
- addq LITERAL(8), %rsp
- CFI_ADJUST_CFA_OFFSET(-8)
POP rdx
POP rsi
POP rdi
@@ -1717,7 +1715,11 @@
DEFINE_FUNCTION art_quick_assignable_from_code
SETUP_FP_CALLEE_SAVE_FRAME
+ subq LITERAL(8), %rsp // Alignment padding.
+ CFI_ADJUST_CFA_OFFSET(8)
call SYMBOL(artIsAssignableFromCode) // (const mirror::Class*, const mirror::Class*)
+ addq LITERAL(8), %rsp
+ CFI_ADJUST_CFA_OFFSET(-8)
RESTORE_FP_CALLEE_SAVE_FRAME
ret
END_FUNCTION art_quick_assignable_from_code
diff --git a/test/109-suspend-check/src/Main.java b/test/109-suspend-check/src/Main.java
index 8046d75..3c3353b 100644
--- a/test/109-suspend-check/src/Main.java
+++ b/test/109-suspend-check/src/Main.java
@@ -32,6 +32,8 @@
new InfiniteWhileLoopWithSpecialPutOrNop(new SpecialMethods2()),
new InfiniteWhileLoopWithSpecialConstOrIGet(new SpecialMethods1()),
new InfiniteWhileLoopWithSpecialConstOrIGet(new SpecialMethods2()),
+ new InfiniteWhileLoopWithSpecialConstOrIGetInTryCatch(new SpecialMethods1()),
+ new InfiniteWhileLoopWithSpecialConstOrIGetInTryCatch(new SpecialMethods2()),
};
doWhileLoopWithLong.start();
for (SimpleLoopThread loop : simpleLoops) {
@@ -135,6 +137,21 @@
}
}
+class InfiniteWhileLoopWithSpecialConstOrIGetInTryCatch extends SimpleLoopThread {
+ private SpecialMethodInterface smi;
+ public InfiniteWhileLoopWithSpecialConstOrIGetInTryCatch(SpecialMethodInterface smi) {
+ this.smi = smi;
+ }
+ public void run() {
+ try {
+ long i = 0L;
+ while (keepGoing) {
+ i += smi.ConstOrIGet();
+ }
+ } catch (Throwable ignored) { }
+ }
+}
+
class InfiniteWhileLoopWithIntrinsic extends SimpleLoopThread {
private String[] strings = { "a", "b", "c", "d" };
private int sum = 0;