diff options
| author | 2020-05-12 15:36:52 +0100 | |
|---|---|---|
| committer | 2020-05-12 16:54:30 +0000 | |
| commit | 85af16e673c58cef1eb6d764468b7218bc343dae (patch) | |
| tree | ef52df17437ac4db52b450199d6406e9875f1987 | |
| parent | 5b0bbf33180bbf9e7fbe8c952eda16096c637f8c (diff) | |
Fix two bugs around aput-object.
- Fix LSE by not removing stores that may throw.
- Fix nterp to export the PC before calling the aput-object helper.
Test: 726-array-store
Change-Id: I4fa6c608fc657433dc62ef72a4e94260281db660
| -rw-r--r-- | compiler/optimizing/load_store_elimination.cc | 2 | ||||
| -rw-r--r-- | runtime/interpreter/mterp/x86_64ng/array.S | 1 | ||||
| -rw-r--r-- | test/726-array-store/expected.txt | 0 | ||||
| -rw-r--r-- | test/726-array-store/info.txt | 1 | ||||
| -rw-r--r-- | test/726-array-store/src/Main.java | 64 |
5 files changed, 67 insertions, 1 deletions
diff --git a/compiler/optimizing/load_store_elimination.cc b/compiler/optimizing/load_store_elimination.cc index 4c150dacea..24041e9181 100644 --- a/compiler/optimizing/load_store_elimination.cc +++ b/compiler/optimizing/load_store_elimination.cc @@ -668,7 +668,7 @@ class LSEVisitor : public HGraphDelegateVisitor { // Keep the store inside irreducible loops. } } - if (possibly_redundant) { + if (possibly_redundant && !instruction->CanThrow()) { possibly_removed_stores_.push_back(instruction); } diff --git a/runtime/interpreter/mterp/x86_64ng/array.S b/runtime/interpreter/mterp/x86_64ng/array.S index baf5f304b1..c8dd8b092f 100644 --- a/runtime/interpreter/mterp/x86_64ng/array.S +++ b/runtime/interpreter/mterp/x86_64ng/array.S @@ -93,6 +93,7 @@ % op_aput(rINST_reg="rINSTq", store="movq", shift="8", data_offset="MIRROR_WIDE_ARRAY_DATA_OFFSET", wide="1") %def op_aput_object(): + EXPORT_PC # for the art_quick_aput_obj call movzbq 2(rPC), %rax # rax <- BB movzbq 3(rPC), %rcx # rcx <- CC GET_VREG %edi, %rax # edi <- vBB (array object) diff --git a/test/726-array-store/expected.txt b/test/726-array-store/expected.txt new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/726-array-store/expected.txt diff --git a/test/726-array-store/info.txt b/test/726-array-store/info.txt new file mode 100644 index 0000000000..623d923f18 --- /dev/null +++ b/test/726-array-store/info.txt @@ -0,0 +1 @@ +Regression test on storing an invalid type into an array. diff --git a/test/726-array-store/src/Main.java b/test/726-array-store/src/Main.java new file mode 100644 index 0000000000..349e272728 --- /dev/null +++ b/test/726-array-store/src/Main.java @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2020 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 main(String[] args) { + try { + $noinline$doTest(args); + throw new Error("Expected ArrayStoreException"); + } catch (ArrayStoreException e) { + // expected + check(e, mainLine, methodLine, "$noinline$doTest"); + } + } + + public static void $noinline$doTest(String[] args) { + Object[] o = new String[2]; + o[0] = args; + } + + public static int mainLine = 21; + public static int methodLine = 31; + + static void check(ArrayStoreException ase, int mainLine, int methodLine, String methodName) { + StackTraceElement[] trace = ase.getStackTrace(); + checkElement(trace[0], "Main", methodName, "Main.java", methodLine); + checkElement(trace[1], "Main", "main", "Main.java", mainLine); + } + + static void checkElement(StackTraceElement element, + String declaringClass, String methodName, + String fileName, int lineNumber) { + assertEquals(declaringClass, element.getClassName()); + assertEquals(methodName, element.getMethodName()); + assertEquals(fileName, element.getFileName()); + assertEquals(lineNumber, element.getLineNumber()); + } + + static void assertEquals(Object expected, Object actual) { + if (!expected.equals(actual)) { + String msg = "Expected \"" + expected + "\" but got \"" + actual + "\""; + throw new AssertionError(msg); + } + } + + static void assertEquals(int expected, int actual) { + if (expected != actual) { + throw new AssertionError("Expected " + expected + " got " + actual); + } + } +} |