test: Modify 586-checker-null-array-get for javac/dx
Previously 1 of the methods were failing checker with javac/dx.
Move their old bytecode to a smali file to retain testing of those
optimizations.
Rewrite the checker tests in Main.java to use the javac/dx-generated
bytecode.
Test: art/test/run-test --64 --host --optimizing --build-with-javac-dx 586-checker-null-array-get
Bug: 62950048
Bug: 36902714
Change-Id: Ib320509422a358e116c24bb1b33442c0cf09ba25
diff --git a/test/586-checker-null-array-get/build b/test/586-checker-null-array-get/build
new file mode 100755
index 0000000..49292c9
--- /dev/null
+++ b/test/586-checker-null-array-get/build
@@ -0,0 +1,23 @@
+#!/bin/bash
+#
+# Copyright 2017 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.
+
+# This checker test is incompatible with jack bytecode output,
+# so force it to use javac/dx.
+export USE_JACK=false
+# Also disable desugar because it is missing in jack platform builds.
+export DESUGAR=false
+
+./default-build "$@"
diff --git a/test/586-checker-null-array-get/smali/SmaliTests.smali b/test/586-checker-null-array-get/smali/SmaliTests.smali
new file mode 100644
index 0000000..f58af36
--- /dev/null
+++ b/test/586-checker-null-array-get/smali/SmaliTests.smali
@@ -0,0 +1,96 @@
+# Copyright (C) 2017 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.
+
+.class public LSmaliTests;
+.super Ljava/lang/Object;
+
+## CHECK-START: void SmaliTests.bar() load_store_elimination (after)
+## CHECK-DAG: <<Null:l\d+>> NullConstant
+## CHECK-DAG: <<BoundType:l\d+>> BoundType [<<Null>>]
+## CHECK-DAG: <<CheckL:l\d+>> NullCheck [<<BoundType>>]
+## CHECK-DAG: <<GetL0:l\d+>> ArrayGet [<<CheckL>>,{{i\d+}}]
+## CHECK-DAG: <<GetL1:l\d+>> ArrayGet [<<CheckL>>,{{i\d+}}]
+## CHECK-DAG: <<GetL2:l\d+>> ArrayGet [<<CheckL>>,{{i\d+}}]
+## CHECK-DAG: <<GetL3:l\d+>> ArrayGet [<<CheckL>>,{{i\d+}}]
+## CHECK-DAG: <<CheckJ:l\d+>> NullCheck [<<Null>>]
+## CHECK-DAG: <<GetJ0:j\d+>> ArrayGet [<<CheckJ>>,{{i\d+}}]
+## CHECK-DAG: <<GetJ1:j\d+>> ArrayGet [<<CheckJ>>,{{i\d+}}]
+## CHECK-DAG: <<GetJ2:j\d+>> ArrayGet [<<CheckJ>>,{{i\d+}}]
+## CHECK-DAG: <<GetJ3:j\d+>> ArrayGet [<<CheckJ>>,{{i\d+}}]
+.method public static bar()V
+ .registers 7
+
+ .prologue
+ const/4 v6, 0x3
+ const/4 v5, 0x2
+ const/4 v4, 0x1
+ const/4 v3, 0x0
+
+ # We create multiple accesses that will lead the bounds check
+ # elimination pass to add a HDeoptimize. Not having the bounds check helped
+ # the load store elimination think it could merge two ArrayGet with different
+ # types.
+
+ # String[] array = (String[])getNull();
+ invoke-static {}, LMain;->getNull()Ljava/lang/Object;
+ move-result-object v0
+ check-cast v0, [Ljava/lang/String;
+
+ # objectField = array[0];
+ aget-object v2, v0, v3
+ sput-object v2, LMain;->objectField:Ljava/lang/Object;
+ # objectField = array[1];
+ aget-object v2, v0, v4
+ sput-object v2, LMain;->objectField:Ljava/lang/Object;
+ # objectField = array[2];
+ aget-object v2, v0, v5
+ sput-object v2, LMain;->objectField:Ljava/lang/Object;
+ # objectField = array[3];
+ aget-object v2, v0, v6
+ sput-object v2, LMain;->objectField:Ljava/lang/Object;
+
+ # long[] longArray = getLongArray();
+ invoke-static {}, LMain;->getLongArray()[J
+ move-result-object v1
+
+ # longField = longArray[0];
+ aget-wide v2, v1, v3
+ sput-wide v2, LMain;->longField:J
+ # longField = longArray[1];
+ aget-wide v2, v1, v4
+ sput-wide v2, LMain;->longField:J
+ # longField = longArray[2];
+ aget-wide v2, v1, v5
+ sput-wide v2, LMain;->longField:J
+ # longField = longArray[3];
+ aget-wide v2, v1, v6
+ sput-wide v2, LMain;->longField:J
+
+ return-void
+.end method
+
+
+# static fields
+.field static doThrow:Z # boolean
+
+# direct methods
+.method static constructor <clinit>()V
+ .registers 1
+
+ .prologue
+ # doThrow = false
+ const/4 v0, 0x0
+ sput-boolean v0, LSmaliTests;->doThrow:Z
+ return-void
+.end method
diff --git a/test/586-checker-null-array-get/src/Main.java b/test/586-checker-null-array-get/src/Main.java
index 0ea7d34..09ebff1 100644
--- a/test/586-checker-null-array-get/src/Main.java
+++ b/test/586-checker-null-array-get/src/Main.java
@@ -14,6 +14,9 @@
* limitations under the License.
*/
+import java.lang.reflect.Method;
+import java.lang.reflect.InvocationTargetException;
+
class Test1 {
int[] iarr;
}
@@ -29,6 +32,18 @@
public static Test1 getNullTest1() { return null; }
public static Test2 getNullTest2() { return null; }
+ public static void $noinline$runSmaliTest(String name) throws Throwable {
+ try {
+ Class<?> c = Class.forName("SmaliTests");
+ Method m = c.getMethod(name);
+ m.invoke(null);
+ } catch (InvocationTargetException ex) {
+ throw ex.getCause(); // re-raise expected exception.
+ } catch (Exception ex) {
+ throw new Error(ex);
+ }
+ }
+
public static void main(String[] args) {
try {
foo();
@@ -43,6 +58,15 @@
// Expected.
}
try {
+ $noinline$runSmaliTest("bar");
+ throw new Error("Expected NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected.
+ } catch (Throwable t) {
+ throw new Error("Unexpected Throwable", t);
+ }
+
+ try {
test1();
throw new Error("Expected NullPointerException");
} catch (NullPointerException e) {
@@ -62,7 +86,8 @@
/// CHECK-START: void Main.bar() load_store_elimination (after)
/// CHECK-DAG: <<Null:l\d+>> NullConstant
- /// CHECK-DAG: <<BoundType:l\d+>> BoundType [<<Null>>]
+ /// CHECK-DAG: <<BoundFirst:l\d+>> BoundType [<<Null>>]
+ /// CHECK-DAG: <<BoundType:l\d+>> BoundType [<<BoundFirst>>]
/// CHECK-DAG: <<CheckL:l\d+>> NullCheck [<<BoundType>>]
/// CHECK-DAG: <<GetL0:l\d+>> ArrayGet [<<CheckL>>,{{i\d+}}]
/// CHECK-DAG: <<GetL1:l\d+>> ArrayGet [<<CheckL>>,{{i\d+}}]
diff --git a/test/knownfailures.json b/test/knownfailures.json
index ad6d390..df8fa60 100644
--- a/test/knownfailures.json
+++ b/test/knownfailures.json
@@ -603,7 +603,6 @@
{
"tests": [
"567-checker-compare",
- "586-checker-null-array-get",
"633-checker-rtp-getclass"
],
"description": "Checker tests failing when run with --build-with-javac-dx.",