diff options
| -rw-r--r-- | compiler/optimizing/ssa_liveness_analysis.cc | 2 | ||||
| -rw-r--r-- | compiler/optimizing/ssa_liveness_analysis.h | 8 | ||||
| -rw-r--r-- | test/449-checker-bce/expected.txt | 1 | ||||
| -rw-r--r-- | test/449-checker-bce/src/Main.java | 23 | ||||
| -rw-r--r-- | test/484-checker-register-hints/src/Main.java | 57 |
5 files changed, 66 insertions, 25 deletions
diff --git a/compiler/optimizing/ssa_liveness_analysis.cc b/compiler/optimizing/ssa_liveness_analysis.cc index 701dbb019b..40502c173b 100644 --- a/compiler/optimizing/ssa_liveness_analysis.cc +++ b/compiler/optimizing/ssa_liveness_analysis.cc @@ -225,7 +225,7 @@ void SsaLivenessAnalysis::ComputeLiveRanges() { // SsaLivenessAnalysis. for (size_t i = 0, e = environment->Size(); i < e; ++i) { HInstruction* instruction = environment->GetInstructionAt(i); - bool should_be_live = ShouldBeLiveForEnvironment(instruction); + bool should_be_live = ShouldBeLiveForEnvironment(current, instruction); if (should_be_live) { DCHECK(instruction->HasSsaIndex()); live_in->SetBit(instruction->GetSsaIndex()); diff --git a/compiler/optimizing/ssa_liveness_analysis.h b/compiler/optimizing/ssa_liveness_analysis.h index 220ee6a8d0..a7044de850 100644 --- a/compiler/optimizing/ssa_liveness_analysis.h +++ b/compiler/optimizing/ssa_liveness_analysis.h @@ -1201,8 +1201,14 @@ class SsaLivenessAnalysis : public ValueObject { // Update the live_out set of the block and returns whether it has changed. bool UpdateLiveOut(const HBasicBlock& block); - static bool ShouldBeLiveForEnvironment(HInstruction* instruction) { + // Returns whether `instruction` in an HEnvironment held by `env_holder` + // should be kept live by the HEnvironment. + static bool ShouldBeLiveForEnvironment(HInstruction* env_holder, + HInstruction* instruction) { if (instruction == nullptr) return false; + // A value that's not live in compiled code may still be needed in interpreter, + // due to code motion, etc. + if (env_holder->IsDeoptimize()) return true; if (instruction->GetBlock()->GetGraph()->IsDebuggable()) return true; return instruction->GetType() == Primitive::kPrimNot; } diff --git a/test/449-checker-bce/expected.txt b/test/449-checker-bce/expected.txt index e69de29bb2..e114c50371 100644 --- a/test/449-checker-bce/expected.txt +++ b/test/449-checker-bce/expected.txt @@ -0,0 +1 @@ +java.lang.ArrayIndexOutOfBoundsException: length=5; index=82 diff --git a/test/449-checker-bce/src/Main.java b/test/449-checker-bce/src/Main.java index c4f7ddbeaf..a746664160 100644 --- a/test/449-checker-bce/src/Main.java +++ b/test/449-checker-bce/src/Main.java @@ -1101,6 +1101,28 @@ public class Main { } + public void testExceptionMessage() { + short[] B1 = new short[5]; + int[] B2 = new int[5]; + Exception err = null; + try { + testExceptionMessage1(B1, B2, null, -1, 6); + } catch (Exception e) { + err = e; + } + System.out.println(err); + } + + void testExceptionMessage1(short[] a1, int[] a2, long a3[], int start, int finish) { + int j = finish + 77; + // Bug: 22665511 + // A deoptimization will be triggered here right before the loop. Need to make + // sure the value of j is preserved for the interpreter. + for (int i = start; i <= finish; i++) { + a2[j - 1] = a1[i + 1]; + } + } + // Make sure this method is compiled with optimizing. /// CHECK-START: void Main.main(java.lang.String[]) register (after) /// CHECK: ParallelMove @@ -1141,6 +1163,7 @@ public class Main { }; testUnknownBounds(); + new Main().testExceptionMessage(); } } diff --git a/test/484-checker-register-hints/src/Main.java b/test/484-checker-register-hints/src/Main.java index 3715ca2b14..6e68f7c91e 100644 --- a/test/484-checker-register-hints/src/Main.java +++ b/test/484-checker-register-hints/src/Main.java @@ -16,6 +16,14 @@ public class Main { + static class Foo { + int field0; + int field1; + int field2; + int field3; + int field4; + }; + /// CHECK-START: void Main.test1(boolean, int, int, int, int, int) register (after) /// CHECK: name "B0" /// CHECK-NOT: ParallelMove @@ -25,7 +33,7 @@ public class Main { /// CHECK-NOT: ParallelMove /// CHECK: name "B3" /// CHECK-NOT: end_block - /// CHECK: ArraySet + /// CHECK: InstanceFieldSet // We could check here that there is a parallel move, but it's only valid // for some architectures (for example x86), as other architectures may // not do move at all. @@ -36,19 +44,19 @@ public class Main { int e = live1; int f = live2; int g = live3; + int j = live0; if (z) { } else { // Create enough live instructions to force spilling on x86. int h = live4; int i = live5; - array[2] = e + i + h; - array[3] = f + i + h; - array[4] = g + i + h; - array[0] = h; - array[1] = i + h; - + foo.field2 = e + i + h; + foo.field3 = f + i + h; + foo.field4 = g + i + h; + foo.field0 = h; + foo.field1 = i + h; } - live1 = e + f + g; + live1 = e + f + g + j; } /// CHECK-START: void Main.test2(boolean, int, int, int, int, int) register (after) @@ -60,7 +68,7 @@ public class Main { /// CHECK-NOT: ParallelMove /// CHECK: name "B3" /// CHECK-NOT: end_block - /// CHECK: ArraySet + /// CHECK: InstanceFieldSet // We could check here that there is a parallel move, but it's only valid // for some architectures (for example x86), as other architectures may // not do move at all. @@ -71,18 +79,19 @@ public class Main { int e = live1; int f = live2; int g = live3; + int j = live0; if (z) { if (y) { int h = live4; int i = live5; - array[2] = e + i + h; - array[3] = f + i + h; - array[4] = g + i + h; - array[0] = h; - array[1] = i + h; + foo.field2 = e + i + h; + foo.field3 = f + i + h; + foo.field4 = g + i + h; + foo.field0 = h; + foo.field1 = i + h; } } - live1 = e + f + g; + live1 = e + f + g + j; } /// CHECK-START: void Main.test3(boolean, int, int, int, int, int) register (after) @@ -94,7 +103,7 @@ public class Main { /// CHECK-NOT: ParallelMove /// CHECK: name "B6" /// CHECK-NOT: end_block - /// CHECK: ArraySet + /// CHECK: InstanceFieldSet // We could check here that there is a parallel move, but it's only valid // for some architectures (for example x86), as other architectures may // not do move at all. @@ -107,6 +116,7 @@ public class Main { int e = live1; int f = live2; int g = live3; + int j = live0; if (z) { live1 = e; } else { @@ -115,24 +125,25 @@ public class Main { } else { int h = live4; int i = live5; - array[2] = e + i + h; - array[3] = f + i + h; - array[4] = g + i + h; - array[0] = h; - array[1] = i + h; + foo.field2 = e + i + h; + foo.field3 = f + i + h; + foo.field4 = g + i + h; + foo.field0 = h; + foo.field1 = i + h; } } - live1 = e + f + g; + live1 = e + f + g + j; } public static void main(String[] args) { } static boolean y; + static int live0; static int live1; static int live2; static int live3; static int live4; static int live5; - static int[] array; + static Foo foo; } |