diff options
| -rw-r--r-- | compiler/optimizing/load_store_elimination.cc | 9 | ||||
| -rw-r--r-- | test/530-checker-lse/expected.txt | 1 | ||||
| -rw-r--r-- | test/530-checker-lse/src/Main.java | 23 |
3 files changed, 32 insertions, 1 deletions
diff --git a/compiler/optimizing/load_store_elimination.cc b/compiler/optimizing/load_store_elimination.cc index 8b4eae1780..237ecd3c10 100644 --- a/compiler/optimizing/load_store_elimination.cc +++ b/compiler/optimizing/load_store_elimination.cc @@ -882,6 +882,7 @@ class LSEVisitor : public HGraphDelegateVisitor { } if (ref_info->IsSingletonAndRemovable() && !new_instance->NeedsChecks()) { DCHECK(!new_instance->IsFinalizable()); + // new_instance can potentially be eliminated. singleton_new_instances_.push_back(new_instance); } ScopedArenaVector<HInstruction*>& heap_values = @@ -904,7 +905,13 @@ class LSEVisitor : public HGraphDelegateVisitor { return; } if (ref_info->IsSingletonAndRemovable()) { - singleton_new_instances_.push_back(new_array); + if (new_array->GetLength()->IsIntConstant() && + new_array->GetLength()->AsIntConstant()->GetValue() >= 0) { + // new_array can potentially be eliminated. + singleton_new_instances_.push_back(new_array); + } else { + // new_array may throw NegativeArraySizeException. Keep it. + } } ScopedArenaVector<HInstruction*>& heap_values = heap_values_for_[new_array->GetBlock()->GetBlockId()]; diff --git a/test/530-checker-lse/expected.txt b/test/530-checker-lse/expected.txt index ddae16aff4..fb67e22d0b 100644 --- a/test/530-checker-lse/expected.txt +++ b/test/530-checker-lse/expected.txt @@ -1 +1,2 @@ java.lang.ArrayIndexOutOfBoundsException: length=3; index=3 +Got NegativeArraySizeException. diff --git a/test/530-checker-lse/src/Main.java b/test/530-checker-lse/src/Main.java index 98838c5089..ebde3bf845 100644 --- a/test/530-checker-lse/src/Main.java +++ b/test/530-checker-lse/src/Main.java @@ -1052,6 +1052,23 @@ public class Main { return array[1] + array[i]; } + /// CHECK-START: int Main.testAllocationEliminationOfArray5(int) load_store_elimination (before) + /// CHECK: NewArray + /// CHECK: ArraySet + /// CHECK: ArrayGet + + /// CHECK-START: int Main.testAllocationEliminationOfArray5(int) load_store_elimination (after) + /// CHECK: NewArray + /// CHECK-NOT: ArraySet + /// CHECK-NOT: ArrayGet + private static int testAllocationEliminationOfArray5(int i) { + // Cannot eliminate array allocation due to unknown i that may + // cause NegativeArraySizeException. + int[] array = new int[i]; + array[1] = 12; + return array[1]; + } + /// CHECK-START: int Main.testExitMerge(boolean) load_store_elimination (before) /// CHECK: NewInstance /// CHECK: InstanceFieldSet @@ -1205,6 +1222,12 @@ public class Main { assertIntEquals(testAllocationEliminationOfArray2(), 11); assertIntEquals(testAllocationEliminationOfArray3(2), 4); assertIntEquals(testAllocationEliminationOfArray4(2), 6); + assertIntEquals(testAllocationEliminationOfArray5(2), 12); + try { + testAllocationEliminationOfArray5(-2); + } catch (NegativeArraySizeException e) { + System.out.println("Got NegativeArraySizeException."); + } assertIntEquals(testStoreStore().i, 41); assertIntEquals(testStoreStore().j, 43); |