summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--compiler/dex/gvn_dead_code_elimination.cc8
-rw-r--r--compiler/dex/gvn_dead_code_elimination_test.cc27
-rw-r--r--test/140-dce-regression/expected.txt1
-rw-r--r--test/140-dce-regression/info.txt1
-rw-r--r--test/140-dce-regression/src/Main.java33
5 files changed, 69 insertions, 1 deletions
diff --git a/compiler/dex/gvn_dead_code_elimination.cc b/compiler/dex/gvn_dead_code_elimination.cc
index b1f5d870d..044989e2a 100644
--- a/compiler/dex/gvn_dead_code_elimination.cc
+++ b/compiler/dex/gvn_dead_code_elimination.cc
@@ -1192,7 +1192,6 @@ bool GvnDeadCodeElimination::RecordMIR(MIR* mir) {
case Instruction::CONST_WIDE_32:
case Instruction::CONST_WIDE:
case Instruction::CONST_WIDE_HIGH16:
- case Instruction::ARRAY_LENGTH:
case Instruction::CMPL_FLOAT:
case Instruction::CMPG_FLOAT:
case Instruction::CMPL_DOUBLE:
@@ -1316,6 +1315,13 @@ bool GvnDeadCodeElimination::RecordMIR(MIR* mir) {
}
break;
+ case Instruction::ARRAY_LENGTH:
+ if ((mir->optimization_flags & MIR_IGNORE_NULL_CHECK) == 0) {
+ must_keep = true;
+ uses_all_vregs = true;
+ }
+ break;
+
case Instruction::AGET_OBJECT:
case Instruction::AGET:
case Instruction::AGET_WIDE:
diff --git a/compiler/dex/gvn_dead_code_elimination_test.cc b/compiler/dex/gvn_dead_code_elimination_test.cc
index 461c844a6..6ba91b64b 100644
--- a/compiler/dex/gvn_dead_code_elimination_test.cc
+++ b/compiler/dex/gvn_dead_code_elimination_test.cc
@@ -2066,4 +2066,31 @@ TEST_F(GvnDeadCodeEliminationTestSimple, UnusedRegs2) {
}
}
+TEST_F(GvnDeadCodeEliminationTestSimple, ArrayLengthThrows) {
+ static const MIRDef mirs[] = {
+ DEF_CONST(3, Instruction::CONST, 0u, 0), // null
+ DEF_UNOP(3, Instruction::ARRAY_LENGTH, 1u, 0u), // null.length
+ DEF_CONST(3, Instruction::CONST, 2u, 1000u), // Overwrite the array-length dest.
+ };
+
+ static const int32_t sreg_to_vreg_map[] = { 0, 1, 1 };
+ PrepareSRegToVRegMap(sreg_to_vreg_map);
+
+ PrepareMIRs(mirs);
+ PerformGVN_DCE();
+
+ ASSERT_EQ(arraysize(mirs), value_names_.size());
+ static const size_t diff_indexes[] = { 0, 1, 2 };
+ ExpectValueNamesNE(diff_indexes);
+
+ static const bool eliminated[] = {
+ false, false, false,
+ };
+ static_assert(arraysize(eliminated) == arraysize(mirs), "array size mismatch");
+ for (size_t i = 0; i != arraysize(eliminated); ++i) {
+ bool actually_eliminated = (static_cast<int>(mirs_[i].dalvikInsn.opcode) == kMirOpNop);
+ EXPECT_EQ(eliminated[i], actually_eliminated) << i;
+ }
+}
+
} // namespace art
diff --git a/test/140-dce-regression/expected.txt b/test/140-dce-regression/expected.txt
new file mode 100644
index 000000000..863339fb8
--- /dev/null
+++ b/test/140-dce-regression/expected.txt
@@ -0,0 +1 @@
+Passed
diff --git a/test/140-dce-regression/info.txt b/test/140-dce-regression/info.txt
new file mode 100644
index 000000000..de6ad34d4
--- /dev/null
+++ b/test/140-dce-regression/info.txt
@@ -0,0 +1 @@
+Regression test for quick dead code elimination.
diff --git a/test/140-dce-regression/src/Main.java b/test/140-dce-regression/src/Main.java
new file mode 100644
index 000000000..f25502980
--- /dev/null
+++ b/test/140-dce-regression/src/Main.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+public class Main {
+
+ public static void testArrayLength() {
+ int[] arr = null;
+ int len = 0;
+ try {
+ len = arr.length;
+ len = 5;
+ } catch (NullPointerException npe) {
+ System.out.println("Passed");
+ }
+ }
+
+ public static void main(String[] args) {
+ testArrayLength();
+ }
+}