summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Mingyao Yang <mingyao@google.com> 2018-02-07 22:26:51 +0000
committer Gerrit Code Review <noreply-gerritcodereview@google.com> 2018-02-07 22:26:51 +0000
commitf12c3092477b824b44bef06777688b80d6754b77 (patch)
treeffaeac5af69ed7ce8969cd4b4fa21a8ca0d6a2e0
parent2e6d97bb6f5dbaa75e0b5700633311d40e880cc2 (diff)
parent7cf9af2ce0bb72c5bd2ff7c5bd82df5c05877355 (diff)
Merge "Do not eliminate array allocation if it may throw NegativeArraySizeException"
-rw-r--r--compiler/optimizing/load_store_elimination.cc9
-rw-r--r--test/530-checker-lse/expected.txt1
-rw-r--r--test/530-checker-lse/src/Main.java23
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);