diff options
Diffstat (limited to 'test')
47 files changed, 3402 insertions, 562 deletions
diff --git a/test/004-ThreadStress/check b/test/004-ThreadStress/check index ffbb8cf17e..77e4cdbda0 100755 --- a/test/004-ThreadStress/check +++ b/test/004-ThreadStress/check @@ -14,5 +14,5 @@ # See the License for the specific language governing permissions and # limitations under the License. -# Only compare the last line. -tail -n 1 "$2" | diff --strip-trailing-cr -q "$1" - >/dev/null
\ No newline at end of file +# Do not compare numbers, so replace numbers with 'N'. +sed '-es/[0-9][0-9]*/N/g' "$2" | diff --strip-trailing-cr -q "$1" - >/dev/null
\ No newline at end of file diff --git a/test/004-ThreadStress/expected.txt b/test/004-ThreadStress/expected.txt index a26fb4f191..772faf6e9f 100644 --- a/test/004-ThreadStress/expected.txt +++ b/test/004-ThreadStress/expected.txt @@ -1 +1,11 @@ +JNI_OnLoad called +Starting worker for N +Starting worker for N +Starting worker for N +Starting worker for N +Starting worker for N +Finishing worker +Finishing worker +Finishing worker +Finishing worker Finishing worker diff --git a/test/004-ThreadStress/src/Main.java b/test/004-ThreadStress/src/Main.java index b9a46deba8..5cae3983bf 100644 --- a/test/004-ThreadStress/src/Main.java +++ b/test/004-ThreadStress/src/Main.java @@ -93,9 +93,7 @@ public class Main implements Runnable { killTemp = osClass.getDeclaredMethod("kill", int.class, int.class); } catch (Exception e) { - if (!e.getClass().getName().equals("ErrnoException")) { - e.printStackTrace(System.out); - } + Main.printThrowable(e); } pid = pidTemp; @@ -107,9 +105,10 @@ public class Main implements Runnable { public boolean perform() { try { kill.invoke(null, pid, sigquit); + } catch (OutOfMemoryError e) { } catch (Exception e) { - if (!e.getClass().getName().equals("ErrnoException")) { - e.printStackTrace(System.out); + if (!e.getClass().getName().equals(Main.errnoExceptionName)) { + Main.printThrowable(e); } } return true; @@ -154,7 +153,10 @@ public class Main implements Runnable { private final static class StackTrace extends Operation { @Override public boolean perform() { - Thread.currentThread().getStackTrace(); + try { + Thread.currentThread().getStackTrace(); + } catch (OutOfMemoryError e) { + } return true; } } @@ -264,6 +266,7 @@ public class Main implements Runnable { } public static void main(String[] args) throws Exception { + System.loadLibrary(args[0]); parseAndRun(args); } @@ -395,12 +398,21 @@ public class Main implements Runnable { System.out.println(frequencyMap); } - runTest(numberOfThreads, numberOfDaemons, operationsPerThread, lock, frequencyMap); + try { + runTest(numberOfThreads, numberOfDaemons, operationsPerThread, lock, frequencyMap); + } catch (Throwable t) { + // In this case, the output should not contain all the required + // "Finishing worker" lines. + Main.printThrowable(t); + } } public static void runTest(final int numberOfThreads, final int numberOfDaemons, final int operationsPerThread, final Object lock, Map<Operation, Double> frequencyMap) throws Exception { + final Thread mainThread = Thread.currentThread(); + final Barrier startBarrier = new Barrier(numberOfThreads + numberOfDaemons + 1); + // Each normal thread is going to do operationsPerThread // operations. Each daemon thread will loop over all // the operations and will not stop. @@ -434,8 +446,9 @@ public class Main implements Runnable { } // Randomize the operation order Collections.shuffle(Arrays.asList(operations)); - threadStresses[t] = t < numberOfThreads ? new Main(lock, t, operations) : - new Daemon(lock, t, operations); + threadStresses[t] = (t < numberOfThreads) + ? new Main(lock, t, operations) + : new Daemon(lock, t, operations, mainThread, startBarrier); } // Enable to dump operation counts per thread to make sure its @@ -470,32 +483,41 @@ public class Main implements Runnable { runners[r] = new Thread("Runner thread " + r) { final Main threadStress = ts; public void run() { - int id = threadStress.id; - System.out.println("Starting worker for " + id); - while (threadStress.nextOperation < operationsPerThread) { - try { - Thread thread = new Thread(ts, "Worker thread " + id); - thread.start(); + try { + int id = threadStress.id; + // No memory hungry task are running yet, so println() should succeed. + System.out.println("Starting worker for " + id); + // Wait until all runners and daemons reach the starting point. + startBarrier.await(); + // Run the stress tasks. + while (threadStress.nextOperation < operationsPerThread) { try { + Thread thread = new Thread(ts, "Worker thread " + id); + thread.start(); thread.join(); - } catch (InterruptedException e) { - } - System.out.println("Thread exited for " + id + " with " - + (operationsPerThread - threadStress.nextOperation) - + " operations remaining."); - } catch (OutOfMemoryError e) { - // Ignore OOME since we need to print "Finishing worker" for the test - // to pass. - } - } - // Keep trying to print "Finishing worker" until it succeeds. - while (true) { - try { - System.out.println("Finishing worker"); - break; - } catch (OutOfMemoryError e) { + if (DEBUG) { + System.out.println( + "Thread exited for " + id + " with " + + (operationsPerThread - threadStress.nextOperation) + + " operations remaining."); + } + } catch (OutOfMemoryError e) { + // Ignore OOME since we need to print "Finishing worker" + // for the test to pass. This OOM can come from creating + // the Thread or from the DEBUG output. + // Note that the Thread creation may fail repeatedly, + // preventing the runner from making any progress, + // especially if the number of daemons is too high. + } } + // Print "Finishing worker" through JNI to avoid OOME. + Main.printString(Main.finishingWorkerMessage); + } catch (Throwable t) { + Main.printThrowable(t); + // Interrupt the main thread, so that it can orderly shut down + // instead of waiting indefinitely for some Barrier. + mainThread.interrupt(); } } }; @@ -528,6 +550,9 @@ public class Main implements Runnable { for (int r = 0; r < runners.length; r++) { runners[r].start(); } + // Wait for all threads to reach the starting point. + startBarrier.await(); + // Wait for runners to finish. for (int r = 0; r < runners.length; r++) { runners[r].join(); } @@ -570,8 +595,14 @@ public class Main implements Runnable { } private static class Daemon extends Main { - private Daemon(Object lock, int id, Operation[] operations) { + private Daemon(Object lock, + int id, + Operation[] operations, + Thread mainThread, + Barrier startBarrier) { super(lock, id, operations); + this.mainThread = mainThread; + this.startBarrier = startBarrier; } public void run() { @@ -579,26 +610,74 @@ public class Main implements Runnable { if (DEBUG) { System.out.println("Starting ThreadStress Daemon " + id); } - int i = 0; - while (true) { - Operation operation = operations[i]; - if (DEBUG) { - System.out.println("ThreadStress Daemon " + id - + " operation " + i - + " is " + operation); + startBarrier.await(); + try { + int i = 0; + while (true) { + Operation operation = operations[i]; + if (DEBUG) { + System.out.println("ThreadStress Daemon " + id + + " operation " + i + + " is " + operation); + } + operation.perform(); + i = (i + 1) % operations.length; } - operation.perform(); - i = (i + 1) % operations.length; + } catch (OutOfMemoryError e) { + // Catch OutOfMemoryErrors since these can cause the test to fail it they print + // the stack trace after "Finishing worker". Note that operations should catch + // their own OOME, this guards only agains OOME in the DEBUG output. } - } catch (OutOfMemoryError e) { - // Catch OutOfMemoryErrors since these can cause the test to fail it they print - // the stack trace after "Finishing worker". - } finally { if (DEBUG) { System.out.println("Finishing ThreadStress Daemon for " + id); } + } catch (Throwable t) { + Main.printThrowable(t); + // Interrupt the main thread, so that it can orderly shut down + // instead of waiting indefinitely for some Barrier. + mainThread.interrupt(); + } + } + + final Thread mainThread; + final Barrier startBarrier; + } + + // Note: java.util.concurrent.CyclicBarrier.await() allocates memory and may throw OOM. + // That is highly undesirable in this test, so we use our own simple barrier class. + // The only memory allocation that can happen here is the lock inflation which uses + // a native allocation. As such, it should succeed even if the Java heap is full. + // If the native allocation surprisingly fails, the program shall abort(). + private static class Barrier { + public Barrier(int initialCount) { + count = initialCount; + } + + public synchronized void await() throws InterruptedException { + --count; + if (count != 0) { + do { + wait(); + } while (count != 0); // Check for spurious wakeup. + } else { + notifyAll(); } } + + private int count; } + // Printing a String/Throwable through JNI requires only native memory and space + // in the local reference table, so it should succeed even if the Java heap is full. + private static native void printString(String s); + private static native void printThrowable(Throwable t); + + static final String finishingWorkerMessage; + static final String errnoExceptionName; + static { + // We pre-allocate the strings in class initializer to avoid const-string + // instructions in code using these strings later as they may throw OOME. + finishingWorkerMessage = "Finishing worker\n"; + errnoExceptionName = "ErrnoException"; + } } diff --git a/test/004-ThreadStress/thread_stress.cc b/test/004-ThreadStress/thread_stress.cc new file mode 100644 index 0000000000..573c352423 --- /dev/null +++ b/test/004-ThreadStress/thread_stress.cc @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2016 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. + */ + +#include <iostream> + +#include "jni.h" +#include "mirror/string.h" +#include "mirror/throwable.h" +#include "scoped_thread_state_change.h" + +namespace art { + +extern "C" JNIEXPORT void JNICALL Java_Main_printString(JNIEnv*, jclass, jstring s) { + ScopedObjectAccess soa(Thread::Current()); + std::cout << soa.Decode<mirror::String*>(s)->ToModifiedUtf8(); +} + +extern "C" JNIEXPORT void JNICALL Java_Main_printThrowable(JNIEnv*, jclass, jthrowable t) { + ScopedObjectAccess soa(Thread::Current()); + std::cout << soa.Decode<mirror::Throwable*>(t)->Dump(); +} + +} // namespace art diff --git a/test/004-UnsafeTest/src/Main.java b/test/004-UnsafeTest/src/Main.java index b2f905e0ee..9d4618a07c 100644 --- a/test/004-UnsafeTest/src/Main.java +++ b/test/004-UnsafeTest/src/Main.java @@ -39,16 +39,24 @@ public class Main { } } - private static Unsafe getUnsafe() throws Exception { + private static Unsafe getUnsafe() throws NoSuchFieldException, IllegalAccessException { Class<?> unsafeClass = Unsafe.class; Field f = unsafeClass.getDeclaredField("theUnsafe"); f.setAccessible(true); return (Unsafe) f.get(null); } - public static void main(String[] args) throws Exception { + public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException { System.loadLibrary(args[0]); Unsafe unsafe = getUnsafe(); + + testArrayBaseOffset(unsafe); + testArrayIndexScale(unsafe); + testGetAndPutAndCAS(unsafe); + testGetAndPutVolatile(unsafe); + } + + private static void testArrayBaseOffset(Unsafe unsafe) { check(unsafe.arrayBaseOffset(boolean[].class), vmArrayBaseOffset(boolean[].class), "Unsafe.arrayBaseOffset(boolean[])"); check(unsafe.arrayBaseOffset(byte[].class), vmArrayBaseOffset(byte[].class), @@ -65,7 +73,9 @@ public class Main { "Unsafe.arrayBaseOffset(long[])"); check(unsafe.arrayBaseOffset(Object[].class), vmArrayBaseOffset(Object[].class), "Unsafe.arrayBaseOffset(Object[])"); + } + private static void testArrayIndexScale(Unsafe unsafe) { check(unsafe.arrayIndexScale(boolean[].class), vmArrayIndexScale(boolean[].class), "Unsafe.arrayIndexScale(boolean[])"); check(unsafe.arrayIndexScale(byte[].class), vmArrayIndexScale(byte[].class), @@ -82,7 +92,9 @@ public class Main { "Unsafe.arrayIndexScale(long[])"); check(unsafe.arrayIndexScale(Object[].class), vmArrayIndexScale(Object[].class), "Unsafe.arrayIndexScale(Object[])"); + } + private static void testGetAndPutAndCAS(Unsafe unsafe) throws NoSuchFieldException { TestClass t = new TestClass(); int intValue = 12345678; @@ -185,12 +197,58 @@ public class Main { } } + private static void testGetAndPutVolatile(Unsafe unsafe) throws NoSuchFieldException { + TestVolatileClass tv = new TestVolatileClass(); + + int intValue = 12345678; + Field volatileIntField = TestVolatileClass.class.getDeclaredField("volatileIntVar"); + long volatileIntOffset = unsafe.objectFieldOffset(volatileIntField); + check(unsafe.getIntVolatile(tv, volatileIntOffset), + 0, + "Unsafe.getIntVolatile(Object, long) - initial"); + unsafe.putIntVolatile(tv, volatileIntOffset, intValue); + check(tv.volatileIntVar, intValue, "Unsafe.putIntVolatile(Object, long, int)"); + check(unsafe.getIntVolatile(tv, volatileIntOffset), + intValue, + "Unsafe.getIntVolatile(Object, long)"); + + long longValue = 1234567887654321L; + Field volatileLongField = TestVolatileClass.class.getDeclaredField("volatileLongVar"); + long volatileLongOffset = unsafe.objectFieldOffset(volatileLongField); + check(unsafe.getLongVolatile(tv, volatileLongOffset), + 0, + "Unsafe.getLongVolatile(Object, long) - initial"); + unsafe.putLongVolatile(tv, volatileLongOffset, longValue); + check(tv.volatileLongVar, longValue, "Unsafe.putLongVolatile(Object, long, long)"); + check(unsafe.getLongVolatile(tv, volatileLongOffset), + longValue, + "Unsafe.getLongVolatile(Object, long)"); + + Object objectValue = new Object(); + Field volatileObjectField = TestVolatileClass.class.getDeclaredField("volatileObjectVar"); + long volatileObjectOffset = unsafe.objectFieldOffset(volatileObjectField); + check(unsafe.getObjectVolatile(tv, volatileObjectOffset), + null, + "Unsafe.getObjectVolatile(Object, long) - initial"); + unsafe.putObjectVolatile(tv, volatileObjectOffset, objectValue); + check(tv.volatileObjectVar, objectValue, "Unsafe.putObjectVolatile(Object, long, Object)"); + check(unsafe.getObjectVolatile(tv, volatileObjectOffset), + objectValue, + "Unsafe.getObjectVolatile(Object, long)"); + } + private static class TestClass { public int intVar = 0; public long longVar = 0; public Object objectVar = null; } + private static class TestVolatileClass { + public volatile int volatileIntVar = 0; + public volatile long volatileLongVar = 0; + public volatile Object volatileObjectVar = null; + } + private static native int vmArrayBaseOffset(Class clazz); private static native int vmArrayIndexScale(Class clazz); } diff --git a/test/033-class-init-deadlock/expected.txt b/test/033-class-init-deadlock/expected.txt index 182d0da00d..9e843a06f6 100644 --- a/test/033-class-init-deadlock/expected.txt +++ b/test/033-class-init-deadlock/expected.txt @@ -1,6 +1,4 @@ Deadlock test starting. -A initializing... -B initializing... Deadlock test interrupting threads. Deadlock test main thread bailing. A initialized: false diff --git a/test/033-class-init-deadlock/src/Main.java b/test/033-class-init-deadlock/src/Main.java index 32332307f5..bd4d4ab7b5 100644 --- a/test/033-class-init-deadlock/src/Main.java +++ b/test/033-class-init-deadlock/src/Main.java @@ -14,6 +14,8 @@ * limitations under the License. */ +import java.util.concurrent.CyclicBarrier; + /** * This causes most VMs to lock up. * @@ -23,6 +25,8 @@ public class Main { public static boolean aInitialized = false; public static boolean bInitialized = false; + public static CyclicBarrier barrier = new CyclicBarrier(3); + static public void main(String[] args) { Thread thread1, thread2; @@ -30,10 +34,10 @@ public class Main { thread1 = new Thread() { public void run() { new A(); } }; thread2 = new Thread() { public void run() { new B(); } }; thread1.start(); - // Give thread1 a chance to start before starting thread2. - try { Thread.sleep(1000); } catch (InterruptedException ie) { } thread2.start(); + // Not expecting any exceptions, so print them out if we get them. + try { barrier.await(); } catch (Exception e) { System.out.println(e); } try { Thread.sleep(6000); } catch (InterruptedException ie) { } System.out.println("Deadlock test interrupting threads."); @@ -48,8 +52,8 @@ public class Main { class A { static { - System.out.println("A initializing..."); - try { Thread.sleep(3000); } catch (InterruptedException ie) { } + // Not expecting any exceptions, so print them out if we get them. + try { Main.barrier.await(); } catch (Exception e) { System.out.println(e); } new B(); System.out.println("A initialized"); Main.aInitialized = true; @@ -58,8 +62,8 @@ class A { class B { static { - System.out.println("B initializing..."); - try { Thread.sleep(3000); } catch (InterruptedException ie) { } + // Not expecting any exceptions, so print them out if we get them. + try { Main.barrier.await(); } catch (Exception e) { System.out.println(e); } new A(); System.out.println("B initialized"); Main.bInitialized = true; diff --git a/test/100-reflect2/expected.txt b/test/100-reflect2/expected.txt index d878e69aed..dd89d644a8 100644 --- a/test/100-reflect2/expected.txt +++ b/test/100-reflect2/expected.txt @@ -33,7 +33,7 @@ z (class java.lang.Character) 14 (class java.lang.Short) [java.lang.String(int,int,char[]), public java.lang.String(), public java.lang.String(byte[]), public java.lang.String(byte[],int), public java.lang.String(byte[],int,int), public java.lang.String(byte[],int,int,int), public java.lang.String(byte[],int,int,java.lang.String) throws java.io.UnsupportedEncodingException, public java.lang.String(byte[],int,int,java.nio.charset.Charset), public java.lang.String(byte[],java.lang.String) throws java.io.UnsupportedEncodingException, public java.lang.String(byte[],java.nio.charset.Charset), public java.lang.String(char[]), public java.lang.String(char[],int,int), public java.lang.String(int[],int,int), public java.lang.String(java.lang.String), public java.lang.String(java.lang.StringBuffer), public java.lang.String(java.lang.StringBuilder)] [private final int java.lang.String.count, private int java.lang.String.hash, private static final java.io.ObjectStreamField[] java.lang.String.serialPersistentFields, private static final long java.lang.String.serialVersionUID, public static final java.util.Comparator java.lang.String.CASE_INSENSITIVE_ORDER] -[native void java.lang.String.getCharsNoCheck(int,int,char[],int), native void java.lang.String.setCharAt(int,char), private int java.lang.String.indexOfSupplementary(int,int), private int java.lang.String.lastIndexOfSupplementary(int,int), private native int java.lang.String.fastIndexOf(int,int), private native java.lang.String java.lang.String.fastSubstring(int,int), public boolean java.lang.String.contains(java.lang.CharSequence), public boolean java.lang.String.contentEquals(java.lang.CharSequence), public boolean java.lang.String.contentEquals(java.lang.StringBuffer), public boolean java.lang.String.endsWith(java.lang.String), public boolean java.lang.String.equals(java.lang.Object), public boolean java.lang.String.equalsIgnoreCase(java.lang.String), public boolean java.lang.String.isEmpty(), public boolean java.lang.String.matches(java.lang.String), public boolean java.lang.String.regionMatches(boolean,int,java.lang.String,int,int), public boolean java.lang.String.regionMatches(int,java.lang.String,int,int), public boolean java.lang.String.startsWith(java.lang.String), public boolean java.lang.String.startsWith(java.lang.String,int), public byte[] java.lang.String.getBytes(), public byte[] java.lang.String.getBytes(java.lang.String) throws java.io.UnsupportedEncodingException, public byte[] java.lang.String.getBytes(java.nio.charset.Charset), public int java.lang.String.codePointAt(int), public int java.lang.String.codePointBefore(int), public int java.lang.String.codePointCount(int,int), public int java.lang.String.compareTo(java.lang.Object), public int java.lang.String.compareToIgnoreCase(java.lang.String), public int java.lang.String.hashCode(), public int java.lang.String.indexOf(int), public int java.lang.String.indexOf(int,int), public int java.lang.String.indexOf(java.lang.String), public int java.lang.String.indexOf(java.lang.String,int), public int java.lang.String.lastIndexOf(int), public int java.lang.String.lastIndexOf(int,int), public int java.lang.String.lastIndexOf(java.lang.String), public int java.lang.String.lastIndexOf(java.lang.String,int), public int java.lang.String.length(), public int java.lang.String.offsetByCodePoints(int,int), public java.lang.CharSequence java.lang.String.subSequence(int,int), public java.lang.String java.lang.String.replace(char,char), public java.lang.String java.lang.String.replace(java.lang.CharSequence,java.lang.CharSequence), public java.lang.String java.lang.String.replaceAll(java.lang.String,java.lang.String), public java.lang.String java.lang.String.replaceFirst(java.lang.String,java.lang.String), public java.lang.String java.lang.String.substring(int), public java.lang.String java.lang.String.substring(int,int), public java.lang.String java.lang.String.toLowerCase(), public java.lang.String java.lang.String.toLowerCase(java.util.Locale), public java.lang.String java.lang.String.toString(), public java.lang.String java.lang.String.toUpperCase(), public java.lang.String java.lang.String.toUpperCase(java.util.Locale), public java.lang.String java.lang.String.trim(), public java.lang.String[] java.lang.String.split(java.lang.String), public java.lang.String[] java.lang.String.split(java.lang.String,int), public native char java.lang.String.charAt(int), public native char[] java.lang.String.toCharArray(), public native int java.lang.String.compareTo(java.lang.String), public native java.lang.String java.lang.String.concat(java.lang.String), public native java.lang.String java.lang.String.intern(), public static java.lang.String java.lang.String.copyValueOf(char[]), public static java.lang.String java.lang.String.copyValueOf(char[],int,int), public static java.lang.String java.lang.String.format(java.lang.String,java.lang.Object[]), public static java.lang.String java.lang.String.format(java.util.Locale,java.lang.String,java.lang.Object[]), public static java.lang.String java.lang.String.valueOf(boolean), public static java.lang.String java.lang.String.valueOf(char), public static java.lang.String java.lang.String.valueOf(char[]), public static java.lang.String java.lang.String.valueOf(char[],int,int), public static java.lang.String java.lang.String.valueOf(double), public static java.lang.String java.lang.String.valueOf(float), public static java.lang.String java.lang.String.valueOf(int), public static java.lang.String java.lang.String.valueOf(java.lang.Object), public static java.lang.String java.lang.String.valueOf(long), public void java.lang.String.getBytes(int,int,byte[],int), public void java.lang.String.getChars(int,int,char[],int), static int java.lang.String.indexOf(char[],int,int,char[],int,int,int), static int java.lang.String.indexOf(java.lang.String,java.lang.String,int), static int java.lang.String.lastIndexOf(char[],int,int,char[],int,int,int), static int java.lang.String.lastIndexOf(java.lang.String,java.lang.String,int)] +[native void java.lang.String.getCharsNoCheck(int,int,char[],int), native void java.lang.String.setCharAt(int,char), private boolean java.lang.String.nonSyncContentEquals(java.lang.AbstractStringBuilder), private int java.lang.String.indexOfSupplementary(int,int), private int java.lang.String.lastIndexOfSupplementary(int,int), private native int java.lang.String.fastIndexOf(int,int), private native java.lang.String java.lang.String.fastSubstring(int,int), public boolean java.lang.String.contains(java.lang.CharSequence), public boolean java.lang.String.contentEquals(java.lang.CharSequence), public boolean java.lang.String.contentEquals(java.lang.StringBuffer), public boolean java.lang.String.endsWith(java.lang.String), public boolean java.lang.String.equals(java.lang.Object), public boolean java.lang.String.equalsIgnoreCase(java.lang.String), public boolean java.lang.String.isEmpty(), public boolean java.lang.String.matches(java.lang.String), public boolean java.lang.String.regionMatches(boolean,int,java.lang.String,int,int), public boolean java.lang.String.regionMatches(int,java.lang.String,int,int), public boolean java.lang.String.startsWith(java.lang.String), public boolean java.lang.String.startsWith(java.lang.String,int), public byte[] java.lang.String.getBytes(), public byte[] java.lang.String.getBytes(java.lang.String) throws java.io.UnsupportedEncodingException, public byte[] java.lang.String.getBytes(java.nio.charset.Charset), public int java.lang.String.codePointAt(int), public int java.lang.String.codePointBefore(int), public int java.lang.String.codePointCount(int,int), public int java.lang.String.compareTo(java.lang.Object), public int java.lang.String.compareToIgnoreCase(java.lang.String), public int java.lang.String.hashCode(), public int java.lang.String.indexOf(int), public int java.lang.String.indexOf(int,int), public int java.lang.String.indexOf(java.lang.String), public int java.lang.String.indexOf(java.lang.String,int), public int java.lang.String.lastIndexOf(int), public int java.lang.String.lastIndexOf(int,int), public int java.lang.String.lastIndexOf(java.lang.String), public int java.lang.String.lastIndexOf(java.lang.String,int), public int java.lang.String.length(), public int java.lang.String.offsetByCodePoints(int,int), public java.lang.CharSequence java.lang.String.subSequence(int,int), public java.lang.String java.lang.String.replace(char,char), public java.lang.String java.lang.String.replace(java.lang.CharSequence,java.lang.CharSequence), public java.lang.String java.lang.String.replaceAll(java.lang.String,java.lang.String), public java.lang.String java.lang.String.replaceFirst(java.lang.String,java.lang.String), public java.lang.String java.lang.String.substring(int), public java.lang.String java.lang.String.substring(int,int), public java.lang.String java.lang.String.toLowerCase(), public java.lang.String java.lang.String.toLowerCase(java.util.Locale), public java.lang.String java.lang.String.toString(), public java.lang.String java.lang.String.toUpperCase(), public java.lang.String java.lang.String.toUpperCase(java.util.Locale), public java.lang.String java.lang.String.trim(), public java.lang.String[] java.lang.String.split(java.lang.String), public java.lang.String[] java.lang.String.split(java.lang.String,int), public native char java.lang.String.charAt(int), public native char[] java.lang.String.toCharArray(), public native int java.lang.String.compareTo(java.lang.String), public native java.lang.String java.lang.String.concat(java.lang.String), public native java.lang.String java.lang.String.intern(), public static java.lang.String java.lang.String.copyValueOf(char[]), public static java.lang.String java.lang.String.copyValueOf(char[],int,int), public static java.lang.String java.lang.String.format(java.lang.String,java.lang.Object[]), public static java.lang.String java.lang.String.format(java.util.Locale,java.lang.String,java.lang.Object[]), public static java.lang.String java.lang.String.join(java.lang.CharSequence,java.lang.CharSequence[]), public static java.lang.String java.lang.String.join(java.lang.CharSequence,java.lang.Iterable), public static java.lang.String java.lang.String.valueOf(boolean), public static java.lang.String java.lang.String.valueOf(char), public static java.lang.String java.lang.String.valueOf(char[]), public static java.lang.String java.lang.String.valueOf(char[],int,int), public static java.lang.String java.lang.String.valueOf(double), public static java.lang.String java.lang.String.valueOf(float), public static java.lang.String java.lang.String.valueOf(int), public static java.lang.String java.lang.String.valueOf(java.lang.Object), public static java.lang.String java.lang.String.valueOf(long), public void java.lang.String.getBytes(int,int,byte[],int), public void java.lang.String.getChars(int,int,char[],int), static int java.lang.String.indexOf(char[],int,int,char[],int,int,int), static int java.lang.String.indexOf(java.lang.String,java.lang.String,int), static int java.lang.String.lastIndexOf(char[],int,int,char[],int,int,int), static int java.lang.String.lastIndexOf(java.lang.String,java.lang.String,int), void java.lang.String.getChars(char[],int)] [] [interface java.io.Serializable, interface java.lang.Comparable, interface java.lang.CharSequence] 0 diff --git a/test/136-daemon-jni-shutdown/daemon_jni_shutdown.cc b/test/136-daemon-jni-shutdown/daemon_jni_shutdown.cc index c9110a905d..b7293015cf 100644 --- a/test/136-daemon-jni-shutdown/daemon_jni_shutdown.cc +++ b/test/136-daemon-jni-shutdown/daemon_jni_shutdown.cc @@ -27,8 +27,20 @@ namespace art { namespace { static volatile std::atomic<bool> vm_was_shutdown(false); +static const int kThreadCount = 4; + +static std::atomic<int> barrier_count(kThreadCount + 1); + +static void JniThreadBarrierWait() { + barrier_count--; + while (barrier_count.load() != 0) { + usleep(1000); + } +} extern "C" JNIEXPORT void JNICALL Java_Main_waitAndCallIntoJniEnv(JNIEnv* env, jclass) { + // Wait for all threads to enter JNI together. + JniThreadBarrierWait(); // Wait until the runtime is shutdown. while (!vm_was_shutdown.load()) { usleep(1000); @@ -40,6 +52,8 @@ extern "C" JNIEXPORT void JNICALL Java_Main_waitAndCallIntoJniEnv(JNIEnv* env, j // NO_RETURN does not work with extern "C" for target builds. extern "C" JNIEXPORT void JNICALL Java_Main_destroyJavaVMAndExit(JNIEnv* env, jclass) { + // Wait for all threads to enter JNI together. + JniThreadBarrierWait(); // Fake up the managed stack so we can detach. Thread* const self = Thread::Current(); self->SetTopOfStack(nullptr); diff --git a/test/149-suspend-all-stress/check b/test/149-suspend-all-stress/check new file mode 100755 index 0000000000..d30b8888ca --- /dev/null +++ b/test/149-suspend-all-stress/check @@ -0,0 +1,18 @@ +#!/bin/bash +# +# Copyright (C) 2016 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. + +# Only compare the last line. +tail -n 1 "$2" | diff --strip-trailing-cr -q "$1" - >/dev/null
\ No newline at end of file diff --git a/test/149-suspend-all-stress/expected.txt b/test/149-suspend-all-stress/expected.txt index f993efcdad..134d8d0b47 100644 --- a/test/149-suspend-all-stress/expected.txt +++ b/test/149-suspend-all-stress/expected.txt @@ -1,2 +1 @@ -JNI_OnLoad called Finishing diff --git a/test/149-suspend-all-stress/src/Main.java b/test/149-suspend-all-stress/src/Main.java index aa94fc9f1a..6a27c4b12d 100644 --- a/test/149-suspend-all-stress/src/Main.java +++ b/test/149-suspend-all-stress/src/Main.java @@ -17,7 +17,7 @@ import java.util.Map; public class Main implements Runnable { - static final int numberOfThreads = 4; + static final int numberOfThreads = 8; public static void main(String[] args) throws Exception { System.loadLibrary(args[0]); diff --git a/test/149-suspend-all-stress/suspend_all.cc b/test/149-suspend-all-stress/suspend_all.cc index de479a50bb..dfd944a267 100644 --- a/test/149-suspend-all-stress/suspend_all.cc +++ b/test/149-suspend-all-stress/suspend_all.cc @@ -14,6 +14,7 @@ * limitations under the License. */ +#include "base/time_utils.h" #include "jni.h" #include "runtime.h" #include "thread_list.h" @@ -22,7 +23,6 @@ namespace art { extern "C" JNIEXPORT void JNICALL Java_Main_suspendAndResume(JNIEnv*, jclass) { static constexpr size_t kInitialSleepUS = 100 * 1000; // 100ms. - static constexpr size_t kIterations = 500; usleep(kInitialSleepUS); // Leave some time for threads to get in here before we start suspending. enum Operation { kOPSuspendAll, @@ -31,8 +31,11 @@ extern "C" JNIEXPORT void JNICALL Java_Main_suspendAndResume(JNIEnv*, jclass) { // Total number of operations. kOPNumber, }; - for (size_t i = 0; i < kIterations; ++i) { - switch (static_cast<Operation>(i % kOPNumber)) { + const uint64_t start_time = NanoTime(); + size_t iterations = 0; + // Run for a fixed period of 10 seconds. + while (NanoTime() - start_time < MsToNs(10 * 1000)) { + switch (static_cast<Operation>(iterations % kOPNumber)) { case kOPSuspendAll: { ScopedSuspendAll ssa(__FUNCTION__); usleep(500); @@ -52,7 +55,9 @@ extern "C" JNIEXPORT void JNICALL Java_Main_suspendAndResume(JNIEnv*, jclass) { case kOPNumber: break; } + ++iterations; } + LOG(INFO) << "Did " << iterations << " iterations"; } } // namespace art diff --git a/test/150-loadlibrary/expected.txt b/test/150-loadlibrary/expected.txt new file mode 100644 index 0000000000..41feacf298 --- /dev/null +++ b/test/150-loadlibrary/expected.txt @@ -0,0 +1,2 @@ +JNI_OnLoad called +Success. diff --git a/test/150-loadlibrary/info.txt b/test/150-loadlibrary/info.txt new file mode 100644 index 0000000000..089d04414b --- /dev/null +++ b/test/150-loadlibrary/info.txt @@ -0,0 +1 @@ +Check that passing the BootClassLoader to loadLibrary works. diff --git a/test/150-loadlibrary/src/Main.java b/test/150-loadlibrary/src/Main.java new file mode 100644 index 0000000000..908693760f --- /dev/null +++ b/test/150-loadlibrary/src/Main.java @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2016 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. + */ + +import java.io.File; +import java.lang.reflect.Method; +import java.util.Arrays; + +public class Main { + public static void main(String[] args) throws Exception { + // Check whether we get the BootClassLoader (not null). + ClassLoader bootClassLoader = Object.class.getClassLoader(); + if (bootClassLoader == null) { + throw new IllegalStateException("Expected non-null classloader for Object"); + } + + // Try to load libarttest(d) with the BootClassLoader. First construct the filename. + String libName = System.mapLibraryName(args[0]); + Method libPathsMethod = Runtime.class.getDeclaredMethod("getLibPaths"); + libPathsMethod.setAccessible(true); + String[] libPaths = (String[])libPathsMethod.invoke(Runtime.getRuntime()); + String fileName = null; + for (String p : libPaths) { + String candidate = p + libName; + if (new File(candidate).exists()) { + fileName = candidate; + break; + } + } + if (fileName == null) { + throw new IllegalStateException("Didn't find " + libName + " in " + + Arrays.toString(libPaths)); + } + + // Then call an internal function that accepts the classloader. Do not use load(), as it + // is deprecated and only there for backwards compatibility, and prints a warning to the + // log that we'd have to strip (it contains the pid). + Method m = Runtime.class.getDeclaredMethod("doLoad", String.class, ClassLoader.class); + m.setAccessible(true); + Object result = m.invoke(Runtime.getRuntime(), fileName, bootClassLoader); + if (result != null) { + throw new IllegalStateException(result.toString()); + } + + System.out.println("Success."); + } +} diff --git a/test/201-built-in-exception-detail-messages/src/Main.java b/test/201-built-in-exception-detail-messages/src/Main.java index 52d4259330..f0bb6ddd4f 100644 --- a/test/201-built-in-exception-detail-messages/src/Main.java +++ b/test/201-built-in-exception-detail-messages/src/Main.java @@ -461,7 +461,7 @@ public class Main { "hello there".substring(9,14); fail(); } catch (StringIndexOutOfBoundsException ex) { - assertEquals("length=11; regionStart=9; regionLength=5", ex.getMessage()); + assertEquals("length=11; index=14", ex.getMessage()); } } } diff --git a/test/450-checker-types/src/Main.java b/test/450-checker-types/src/Main.java index 08b6cec35f..36f14d8779 100644 --- a/test/450-checker-types/src/Main.java +++ b/test/450-checker-types/src/Main.java @@ -30,6 +30,11 @@ class Super implements Interface { public void $noinline$f() { throw new RuntimeException(); } + + public int $inline$h(boolean cond) { + Super obj = (cond ? this : null); + return obj.hashCode(); + } } class SubclassA extends Super { @@ -620,6 +625,46 @@ public class Main { o.mainField = 0; } + /// CHECK-START: void Main.testThisArgumentMoreSpecific(boolean) inliner (before) + /// CHECK-DAG: <<Arg:l\d+>> NewInstance + /// CHECK-DAG: InvokeVirtual [<<Arg>>,{{z\d+}}] method_name:Super.$inline$h + + /// CHECK-START: void Main.testThisArgumentMoreSpecific(boolean) inliner (after) + /// CHECK-DAG: <<Arg:l\d+>> NewInstance + /// CHECK-DAG: <<Null:l\d+>> NullConstant + /// CHECK-DAG: <<Phi:l\d+>> Phi [<<Arg>>,<<Null>>] klass:SubclassA + /// CHECK-DAG: <<NCPhi:l\d+>> NullCheck [<<Phi>>] + /// CHECK-DAG: InvokeVirtual [<<NCPhi>>] method_name:Super.hashCode + + public void testThisArgumentMoreSpecific(boolean cond) { + // Inlining method from Super will build it with `this` typed as Super. + // Running RTP will sharpen it to SubclassA. + SubclassA obj = new SubclassA(); + ((Super) obj).$inline$h(cond); + } + + public static int $inline$hashCode(Super obj) { + return obj.hashCode(); + } + + /// CHECK-START: void Main.testExplicitArgumentMoreSpecific(SubclassA) inliner (before) + /// CHECK-DAG: <<Arg:l\d+>> ParameterValue klass:SubclassA + // Note: The ArtMethod* (typed as int or long) is optional after sharpening. + /// CHECK-DAG: InvokeStaticOrDirect [<<Arg>>{{(,[ij]\d+)?}}] method_name:Main.$inline$hashCode + + /// CHECK-START: void Main.testExplicitArgumentMoreSpecific(SubclassA) inliner (after) + /// CHECK-DAG: <<Arg:l\d+>> ParameterValue klass:SubclassA + /// CHECK-DAG: <<NCArg:l\d+>> NullCheck [<<Arg>>] klass:SubclassA + /// CHECK-DAG: InvokeVirtual [<<NCArg>>] method_name:Super.hashCode + + public void testExplicitArgumentMoreSpecific(SubclassA obj) { + // Inlining a method will build it with reference types from its signature, + // here the callee graph is built with Super as the type of its only argument. + // Running RTP after its ParameterValue instructions are replaced with actual + // arguments will type the inner graph more precisely. + $inline$hashCode(obj); + } + /// CHECK-START: void Main.testPhiHasOnlyNullInputs(boolean) inliner (before) /// CHECK: <<Int:i\d+>> IntConstant 0 /// CHECK: <<Phi:l\d+>> Phi klass:Main exact:false diff --git a/test/458-checker-instruction-simplification/src/Main.java b/test/458-checker-instruction-simplification/src/Main.java index 53c2e0b820..ffce49d2e1 100644 --- a/test/458-checker-instruction-simplification/src/Main.java +++ b/test/458-checker-instruction-simplification/src/Main.java @@ -18,6 +18,8 @@ import java.lang.reflect.Method; public class Main { + static boolean doThrow = false; + public static void assertBooleanEquals(boolean expected, boolean result) { if (expected != result) { throw new Error("Expected: " + expected + ", found: " + result); @@ -58,41 +60,43 @@ public class Main { * Tiny programs exercising optimizations of arithmetic identities. */ - /// CHECK-START: long Main.Add0(long) instruction_simplifier (before) + /// CHECK-START: long Main.$noinline$Add0(long) instruction_simplifier (before) /// CHECK-DAG: <<Arg:j\d+>> ParameterValue /// CHECK-DAG: <<Const0:j\d+>> LongConstant 0 /// CHECK-DAG: <<Add:j\d+>> Add [<<Const0>>,<<Arg>>] /// CHECK-DAG: Return [<<Add>>] - /// CHECK-START: long Main.Add0(long) instruction_simplifier (after) + /// CHECK-START: long Main.$noinline$Add0(long) instruction_simplifier (after) /// CHECK-DAG: <<Arg:j\d+>> ParameterValue /// CHECK-DAG: Return [<<Arg>>] - /// CHECK-START: long Main.Add0(long) instruction_simplifier (after) + /// CHECK-START: long Main.$noinline$Add0(long) instruction_simplifier (after) /// CHECK-NOT: Add - public static long Add0(long arg) { + public static long $noinline$Add0(long arg) { + if (doThrow) { throw new Error(); } return 0 + arg; } - /// CHECK-START: int Main.AndAllOnes(int) instruction_simplifier (before) + /// CHECK-START: int Main.$noinline$AndAllOnes(int) instruction_simplifier (before) /// CHECK-DAG: <<Arg:i\d+>> ParameterValue /// CHECK-DAG: <<ConstF:i\d+>> IntConstant -1 /// CHECK-DAG: <<And:i\d+>> And [<<Arg>>,<<ConstF>>] /// CHECK-DAG: Return [<<And>>] - /// CHECK-START: int Main.AndAllOnes(int) instruction_simplifier (after) + /// CHECK-START: int Main.$noinline$AndAllOnes(int) instruction_simplifier (after) /// CHECK-DAG: <<Arg:i\d+>> ParameterValue /// CHECK-DAG: Return [<<Arg>>] - /// CHECK-START: int Main.AndAllOnes(int) instruction_simplifier (after) + /// CHECK-START: int Main.$noinline$AndAllOnes(int) instruction_simplifier (after) /// CHECK-NOT: And - public static int AndAllOnes(int arg) { + public static int $noinline$AndAllOnes(int arg) { + if (doThrow) { throw new Error(); } return arg & -1; } - /// CHECK-START: int Main.UShr28And15(int) instruction_simplifier (before) + /// CHECK-START: int Main.$noinline$UShr28And15(int) instruction_simplifier (before) /// CHECK-DAG: <<Arg:i\d+>> ParameterValue /// CHECK-DAG: <<Const28:i\d+>> IntConstant 28 /// CHECK-DAG: <<Const15:i\d+>> IntConstant 15 @@ -100,20 +104,21 @@ public class Main { /// CHECK-DAG: <<And:i\d+>> And [<<UShr>>,<<Const15>>] /// CHECK-DAG: Return [<<And>>] - /// CHECK-START: int Main.UShr28And15(int) instruction_simplifier (after) + /// CHECK-START: int Main.$noinline$UShr28And15(int) instruction_simplifier (after) /// CHECK-DAG: <<Arg:i\d+>> ParameterValue /// CHECK-DAG: <<Const28:i\d+>> IntConstant 28 /// CHECK-DAG: <<UShr:i\d+>> UShr [<<Arg>>,<<Const28>>] /// CHECK-DAG: Return [<<UShr>>] - /// CHECK-START: int Main.UShr28And15(int) instruction_simplifier (after) + /// CHECK-START: int Main.$noinline$UShr28And15(int) instruction_simplifier (after) /// CHECK-NOT: And - public static int UShr28And15(int arg) { + public static int $noinline$UShr28And15(int arg) { + if (doThrow) { throw new Error(); } return (arg >>> 28) & 15; } - /// CHECK-START: long Main.UShr60And15(long) instruction_simplifier (before) + /// CHECK-START: long Main.$noinline$UShr60And15(long) instruction_simplifier (before) /// CHECK-DAG: <<Arg:j\d+>> ParameterValue /// CHECK-DAG: <<Const60:i\d+>> IntConstant 60 /// CHECK-DAG: <<Const15:j\d+>> LongConstant 15 @@ -121,20 +126,21 @@ public class Main { /// CHECK-DAG: <<And:j\d+>> And [<<UShr>>,<<Const15>>] /// CHECK-DAG: Return [<<And>>] - /// CHECK-START: long Main.UShr60And15(long) instruction_simplifier (after) + /// CHECK-START: long Main.$noinline$UShr60And15(long) instruction_simplifier (after) /// CHECK-DAG: <<Arg:j\d+>> ParameterValue /// CHECK-DAG: <<Const60:i\d+>> IntConstant 60 /// CHECK-DAG: <<UShr:j\d+>> UShr [<<Arg>>,<<Const60>>] /// CHECK-DAG: Return [<<UShr>>] - /// CHECK-START: long Main.UShr60And15(long) instruction_simplifier (after) + /// CHECK-START: long Main.$noinline$UShr60And15(long) instruction_simplifier (after) /// CHECK-NOT: And - public static long UShr60And15(long arg) { + public static long $noinline$UShr60And15(long arg) { + if (doThrow) { throw new Error(); } return (arg >>> 60) & 15; } - /// CHECK-START: int Main.UShr28And7(int) instruction_simplifier (before) + /// CHECK-START: int Main.$noinline$UShr28And7(int) instruction_simplifier (before) /// CHECK-DAG: <<Arg:i\d+>> ParameterValue /// CHECK-DAG: <<Const28:i\d+>> IntConstant 28 /// CHECK-DAG: <<Const7:i\d+>> IntConstant 7 @@ -142,7 +148,7 @@ public class Main { /// CHECK-DAG: <<And:i\d+>> And [<<UShr>>,<<Const7>>] /// CHECK-DAG: Return [<<And>>] - /// CHECK-START: int Main.UShr28And7(int) instruction_simplifier (after) + /// CHECK-START: int Main.$noinline$UShr28And7(int) instruction_simplifier (after) /// CHECK-DAG: <<Arg:i\d+>> ParameterValue /// CHECK-DAG: <<Const28:i\d+>> IntConstant 28 /// CHECK-DAG: <<Const7:i\d+>> IntConstant 7 @@ -150,11 +156,12 @@ public class Main { /// CHECK-DAG: <<And:i\d+>> And [<<UShr>>,<<Const7>>] /// CHECK-DAG: Return [<<And>>] - public static int UShr28And7(int arg) { + public static int $noinline$UShr28And7(int arg) { + if (doThrow) { throw new Error(); } return (arg >>> 28) & 7; } - /// CHECK-START: long Main.UShr60And7(long) instruction_simplifier (before) + /// CHECK-START: long Main.$noinline$UShr60And7(long) instruction_simplifier (before) /// CHECK-DAG: <<Arg:j\d+>> ParameterValue /// CHECK-DAG: <<Const60:i\d+>> IntConstant 60 /// CHECK-DAG: <<Const7:j\d+>> LongConstant 7 @@ -162,7 +169,7 @@ public class Main { /// CHECK-DAG: <<And:j\d+>> And [<<UShr>>,<<Const7>>] /// CHECK-DAG: Return [<<And>>] - /// CHECK-START: long Main.UShr60And7(long) instruction_simplifier (after) + /// CHECK-START: long Main.$noinline$UShr60And7(long) instruction_simplifier (after) /// CHECK-DAG: <<Arg:j\d+>> ParameterValue /// CHECK-DAG: <<Const60:i\d+>> IntConstant 60 /// CHECK-DAG: <<Const7:j\d+>> LongConstant 7 @@ -170,11 +177,12 @@ public class Main { /// CHECK-DAG: <<And:j\d+>> And [<<UShr>>,<<Const7>>] /// CHECK-DAG: Return [<<And>>] - public static long UShr60And7(long arg) { + public static long $noinline$UShr60And7(long arg) { + if (doThrow) { throw new Error(); } return (arg >>> 60) & 7; } - /// CHECK-START: int Main.Shr24And255(int) instruction_simplifier (before) + /// CHECK-START: int Main.$noinline$Shr24And255(int) instruction_simplifier (before) /// CHECK-DAG: <<Arg:i\d+>> ParameterValue /// CHECK-DAG: <<Const24:i\d+>> IntConstant 24 /// CHECK-DAG: <<Const255:i\d+>> IntConstant 255 @@ -182,21 +190,22 @@ public class Main { /// CHECK-DAG: <<And:i\d+>> And [<<Shr>>,<<Const255>>] /// CHECK-DAG: Return [<<And>>] - /// CHECK-START: int Main.Shr24And255(int) instruction_simplifier (after) + /// CHECK-START: int Main.$noinline$Shr24And255(int) instruction_simplifier (after) /// CHECK-DAG: <<Arg:i\d+>> ParameterValue /// CHECK-DAG: <<Const24:i\d+>> IntConstant 24 /// CHECK-DAG: <<UShr:i\d+>> UShr [<<Arg>>,<<Const24>>] /// CHECK-DAG: Return [<<UShr>>] - /// CHECK-START: int Main.Shr24And255(int) instruction_simplifier (after) + /// CHECK-START: int Main.$noinline$Shr24And255(int) instruction_simplifier (after) /// CHECK-NOT: Shr /// CHECK-NOT: And - public static int Shr24And255(int arg) { + public static int $noinline$Shr24And255(int arg) { + if (doThrow) { throw new Error(); } return (arg >> 24) & 255; } - /// CHECK-START: long Main.Shr56And255(long) instruction_simplifier (before) + /// CHECK-START: long Main.$noinline$Shr56And255(long) instruction_simplifier (before) /// CHECK-DAG: <<Arg:j\d+>> ParameterValue /// CHECK-DAG: <<Const56:i\d+>> IntConstant 56 /// CHECK-DAG: <<Const255:j\d+>> LongConstant 255 @@ -204,21 +213,22 @@ public class Main { /// CHECK-DAG: <<And:j\d+>> And [<<Shr>>,<<Const255>>] /// CHECK-DAG: Return [<<And>>] - /// CHECK-START: long Main.Shr56And255(long) instruction_simplifier (after) + /// CHECK-START: long Main.$noinline$Shr56And255(long) instruction_simplifier (after) /// CHECK-DAG: <<Arg:j\d+>> ParameterValue /// CHECK-DAG: <<Const56:i\d+>> IntConstant 56 /// CHECK-DAG: <<UShr:j\d+>> UShr [<<Arg>>,<<Const56>>] /// CHECK-DAG: Return [<<UShr>>] - /// CHECK-START: long Main.Shr56And255(long) instruction_simplifier (after) + /// CHECK-START: long Main.$noinline$Shr56And255(long) instruction_simplifier (after) /// CHECK-NOT: Shr /// CHECK-NOT: And - public static long Shr56And255(long arg) { + public static long $noinline$Shr56And255(long arg) { + if (doThrow) { throw new Error(); } return (arg >> 56) & 255; } - /// CHECK-START: int Main.Shr24And127(int) instruction_simplifier (before) + /// CHECK-START: int Main.$noinline$Shr24And127(int) instruction_simplifier (before) /// CHECK-DAG: <<Arg:i\d+>> ParameterValue /// CHECK-DAG: <<Const24:i\d+>> IntConstant 24 /// CHECK-DAG: <<Const127:i\d+>> IntConstant 127 @@ -226,7 +236,7 @@ public class Main { /// CHECK-DAG: <<And:i\d+>> And [<<Shr>>,<<Const127>>] /// CHECK-DAG: Return [<<And>>] - /// CHECK-START: int Main.Shr24And127(int) instruction_simplifier (after) + /// CHECK-START: int Main.$noinline$Shr24And127(int) instruction_simplifier (after) /// CHECK-DAG: <<Arg:i\d+>> ParameterValue /// CHECK-DAG: <<Const24:i\d+>> IntConstant 24 /// CHECK-DAG: <<Const127:i\d+>> IntConstant 127 @@ -234,11 +244,12 @@ public class Main { /// CHECK-DAG: <<And:i\d+>> And [<<Shr>>,<<Const127>>] /// CHECK-DAG: Return [<<And>>] - public static int Shr24And127(int arg) { + public static int $noinline$Shr24And127(int arg) { + if (doThrow) { throw new Error(); } return (arg >> 24) & 127; } - /// CHECK-START: long Main.Shr56And127(long) instruction_simplifier (before) + /// CHECK-START: long Main.$noinline$Shr56And127(long) instruction_simplifier (before) /// CHECK-DAG: <<Arg:j\d+>> ParameterValue /// CHECK-DAG: <<Const56:i\d+>> IntConstant 56 /// CHECK-DAG: <<Const127:j\d+>> LongConstant 127 @@ -246,7 +257,7 @@ public class Main { /// CHECK-DAG: <<And:j\d+>> And [<<Shr>>,<<Const127>>] /// CHECK-DAG: Return [<<And>>] - /// CHECK-START: long Main.Shr56And127(long) instruction_simplifier (after) + /// CHECK-START: long Main.$noinline$Shr56And127(long) instruction_simplifier (after) /// CHECK-DAG: <<Arg:j\d+>> ParameterValue /// CHECK-DAG: <<Const56:i\d+>> IntConstant 56 /// CHECK-DAG: <<Const127:j\d+>> LongConstant 127 @@ -254,267 +265,283 @@ public class Main { /// CHECK-DAG: <<And:j\d+>> And [<<Shr>>,<<Const127>>] /// CHECK-DAG: Return [<<And>>] - public static long Shr56And127(long arg) { + public static long $noinline$Shr56And127(long arg) { + if (doThrow) { throw new Error(); } return (arg >> 56) & 127; } - /// CHECK-START: long Main.Div1(long) instruction_simplifier (before) + /// CHECK-START: long Main.$noinline$Div1(long) instruction_simplifier (before) /// CHECK-DAG: <<Arg:j\d+>> ParameterValue /// CHECK-DAG: <<Const1:j\d+>> LongConstant 1 /// CHECK-DAG: <<Div:j\d+>> Div [<<Arg>>,<<Const1>>] /// CHECK-DAG: Return [<<Div>>] - /// CHECK-START: long Main.Div1(long) instruction_simplifier (after) + /// CHECK-START: long Main.$noinline$Div1(long) instruction_simplifier (after) /// CHECK-DAG: <<Arg:j\d+>> ParameterValue /// CHECK-DAG: Return [<<Arg>>] - /// CHECK-START: long Main.Div1(long) instruction_simplifier (after) + /// CHECK-START: long Main.$noinline$Div1(long) instruction_simplifier (after) /// CHECK-NOT: Div - public static long Div1(long arg) { + public static long $noinline$Div1(long arg) { + if (doThrow) { throw new Error(); } return arg / 1; } - /// CHECK-START: int Main.DivN1(int) instruction_simplifier (before) + /// CHECK-START: int Main.$noinline$DivN1(int) instruction_simplifier (before) /// CHECK-DAG: <<Arg:i\d+>> ParameterValue /// CHECK-DAG: <<ConstN1:i\d+>> IntConstant -1 /// CHECK-DAG: <<Div:i\d+>> Div [<<Arg>>,<<ConstN1>>] /// CHECK-DAG: Return [<<Div>>] - /// CHECK-START: int Main.DivN1(int) instruction_simplifier (after) + /// CHECK-START: int Main.$noinline$DivN1(int) instruction_simplifier (after) /// CHECK-DAG: <<Arg:i\d+>> ParameterValue /// CHECK-DAG: <<Neg:i\d+>> Neg [<<Arg>>] /// CHECK-DAG: Return [<<Neg>>] - /// CHECK-START: int Main.DivN1(int) instruction_simplifier (after) + /// CHECK-START: int Main.$noinline$DivN1(int) instruction_simplifier (after) /// CHECK-NOT: Div - public static int DivN1(int arg) { + public static int $noinline$DivN1(int arg) { + if (doThrow) { throw new Error(); } return arg / -1; } - /// CHECK-START: long Main.Mul1(long) instruction_simplifier (before) + /// CHECK-START: long Main.$noinline$Mul1(long) instruction_simplifier (before) /// CHECK-DAG: <<Arg:j\d+>> ParameterValue /// CHECK-DAG: <<Const1:j\d+>> LongConstant 1 /// CHECK-DAG: <<Mul:j\d+>> Mul [<<Const1>>,<<Arg>>] /// CHECK-DAG: Return [<<Mul>>] - /// CHECK-START: long Main.Mul1(long) instruction_simplifier (after) + /// CHECK-START: long Main.$noinline$Mul1(long) instruction_simplifier (after) /// CHECK-DAG: <<Arg:j\d+>> ParameterValue /// CHECK-DAG: Return [<<Arg>>] - /// CHECK-START: long Main.Mul1(long) instruction_simplifier (after) + /// CHECK-START: long Main.$noinline$Mul1(long) instruction_simplifier (after) /// CHECK-NOT: Mul - public static long Mul1(long arg) { + public static long $noinline$Mul1(long arg) { + if (doThrow) { throw new Error(); } return arg * 1; } - /// CHECK-START: int Main.MulN1(int) instruction_simplifier (before) + /// CHECK-START: int Main.$noinline$MulN1(int) instruction_simplifier (before) /// CHECK-DAG: <<Arg:i\d+>> ParameterValue /// CHECK-DAG: <<ConstN1:i\d+>> IntConstant -1 /// CHECK-DAG: <<Mul:i\d+>> Mul [<<Arg>>,<<ConstN1>>] /// CHECK-DAG: Return [<<Mul>>] - /// CHECK-START: int Main.MulN1(int) instruction_simplifier (after) + /// CHECK-START: int Main.$noinline$MulN1(int) instruction_simplifier (after) /// CHECK-DAG: <<Arg:i\d+>> ParameterValue /// CHECK-DAG: <<Neg:i\d+>> Neg [<<Arg>>] /// CHECK-DAG: Return [<<Neg>>] - /// CHECK-START: int Main.MulN1(int) instruction_simplifier (after) + /// CHECK-START: int Main.$noinline$MulN1(int) instruction_simplifier (after) /// CHECK-NOT: Mul - public static int MulN1(int arg) { + public static int $noinline$MulN1(int arg) { + if (doThrow) { throw new Error(); } return arg * -1; } - /// CHECK-START: long Main.MulPowerOfTwo128(long) instruction_simplifier (before) + /// CHECK-START: long Main.$noinline$MulPowerOfTwo128(long) instruction_simplifier (before) /// CHECK-DAG: <<Arg:j\d+>> ParameterValue /// CHECK-DAG: <<Const128:j\d+>> LongConstant 128 /// CHECK-DAG: <<Mul:j\d+>> Mul [<<Const128>>,<<Arg>>] /// CHECK-DAG: Return [<<Mul>>] - /// CHECK-START: long Main.MulPowerOfTwo128(long) instruction_simplifier (after) + /// CHECK-START: long Main.$noinline$MulPowerOfTwo128(long) instruction_simplifier (after) /// CHECK-DAG: <<Arg:j\d+>> ParameterValue /// CHECK-DAG: <<Const7:i\d+>> IntConstant 7 /// CHECK-DAG: <<Shl:j\d+>> Shl [<<Arg>>,<<Const7>>] /// CHECK-DAG: Return [<<Shl>>] - /// CHECK-START: long Main.MulPowerOfTwo128(long) instruction_simplifier (after) + /// CHECK-START: long Main.$noinline$MulPowerOfTwo128(long) instruction_simplifier (after) /// CHECK-NOT: Mul - public static long MulPowerOfTwo128(long arg) { + public static long $noinline$MulPowerOfTwo128(long arg) { + if (doThrow) { throw new Error(); } return arg * 128; } - /// CHECK-START: int Main.Or0(int) instruction_simplifier (before) + /// CHECK-START: int Main.$noinline$Or0(int) instruction_simplifier (before) /// CHECK-DAG: <<Arg:i\d+>> ParameterValue /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 /// CHECK-DAG: <<Or:i\d+>> Or [<<Arg>>,<<Const0>>] /// CHECK-DAG: Return [<<Or>>] - /// CHECK-START: int Main.Or0(int) instruction_simplifier (after) + /// CHECK-START: int Main.$noinline$Or0(int) instruction_simplifier (after) /// CHECK-DAG: <<Arg:i\d+>> ParameterValue /// CHECK-DAG: Return [<<Arg>>] - /// CHECK-START: int Main.Or0(int) instruction_simplifier (after) + /// CHECK-START: int Main.$noinline$Or0(int) instruction_simplifier (after) /// CHECK-NOT: Or - public static int Or0(int arg) { + public static int $noinline$Or0(int arg) { + if (doThrow) { throw new Error(); } return arg | 0; } - /// CHECK-START: long Main.OrSame(long) instruction_simplifier (before) + /// CHECK-START: long Main.$noinline$OrSame(long) instruction_simplifier (before) /// CHECK-DAG: <<Arg:j\d+>> ParameterValue /// CHECK-DAG: <<Or:j\d+>> Or [<<Arg>>,<<Arg>>] /// CHECK-DAG: Return [<<Or>>] - /// CHECK-START: long Main.OrSame(long) instruction_simplifier (after) + /// CHECK-START: long Main.$noinline$OrSame(long) instruction_simplifier (after) /// CHECK-DAG: <<Arg:j\d+>> ParameterValue /// CHECK-DAG: Return [<<Arg>>] - /// CHECK-START: long Main.OrSame(long) instruction_simplifier (after) + /// CHECK-START: long Main.$noinline$OrSame(long) instruction_simplifier (after) /// CHECK-NOT: Or - public static long OrSame(long arg) { + public static long $noinline$OrSame(long arg) { + if (doThrow) { throw new Error(); } return arg | arg; } - /// CHECK-START: int Main.Shl0(int) instruction_simplifier (before) + /// CHECK-START: int Main.$noinline$Shl0(int) instruction_simplifier (before) /// CHECK-DAG: <<Arg:i\d+>> ParameterValue /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 /// CHECK-DAG: <<Shl:i\d+>> Shl [<<Arg>>,<<Const0>>] /// CHECK-DAG: Return [<<Shl>>] - /// CHECK-START: int Main.Shl0(int) instruction_simplifier (after) + /// CHECK-START: int Main.$noinline$Shl0(int) instruction_simplifier (after) /// CHECK-DAG: <<Arg:i\d+>> ParameterValue /// CHECK-DAG: Return [<<Arg>>] - /// CHECK-START: int Main.Shl0(int) instruction_simplifier (after) + /// CHECK-START: int Main.$noinline$Shl0(int) instruction_simplifier (after) /// CHECK-NOT: Shl - public static int Shl0(int arg) { + public static int $noinline$Shl0(int arg) { + if (doThrow) { throw new Error(); } return arg << 0; } - /// CHECK-START: long Main.Shr0(long) instruction_simplifier (before) + /// CHECK-START: long Main.$noinline$Shr0(long) instruction_simplifier (before) /// CHECK-DAG: <<Arg:j\d+>> ParameterValue /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 /// CHECK-DAG: <<Shr:j\d+>> Shr [<<Arg>>,<<Const0>>] /// CHECK-DAG: Return [<<Shr>>] - /// CHECK-START: long Main.Shr0(long) instruction_simplifier (after) + /// CHECK-START: long Main.$noinline$Shr0(long) instruction_simplifier (after) /// CHECK-DAG: <<Arg:j\d+>> ParameterValue /// CHECK-DAG: Return [<<Arg>>] - /// CHECK-START: long Main.Shr0(long) instruction_simplifier (after) + /// CHECK-START: long Main.$noinline$Shr0(long) instruction_simplifier (after) /// CHECK-NOT: Shr - public static long Shr0(long arg) { + public static long $noinline$Shr0(long arg) { + if (doThrow) { throw new Error(); } return arg >> 0; } - /// CHECK-START: long Main.Shr64(long) instruction_simplifier (before) + /// CHECK-START: long Main.$noinline$Shr64(long) instruction_simplifier (before) /// CHECK-DAG: <<Arg:j\d+>> ParameterValue /// CHECK-DAG: <<Const64:i\d+>> IntConstant 64 /// CHECK-DAG: <<Shr:j\d+>> Shr [<<Arg>>,<<Const64>>] /// CHECK-DAG: Return [<<Shr>>] - /// CHECK-START: long Main.Shr64(long) instruction_simplifier (after) + /// CHECK-START: long Main.$noinline$Shr64(long) instruction_simplifier (after) /// CHECK-DAG: <<Arg:j\d+>> ParameterValue /// CHECK-DAG: Return [<<Arg>>] - /// CHECK-START: long Main.Shr64(long) instruction_simplifier (after) + /// CHECK-START: long Main.$noinline$Shr64(long) instruction_simplifier (after) /// CHECK-NOT: Shr - public static long Shr64(long arg) { + public static long $noinline$Shr64(long arg) { + if (doThrow) { throw new Error(); } return arg >> 64; } - /// CHECK-START: long Main.Sub0(long) instruction_simplifier (before) + /// CHECK-START: long Main.$noinline$Sub0(long) instruction_simplifier (before) /// CHECK-DAG: <<Arg:j\d+>> ParameterValue /// CHECK-DAG: <<Const0:j\d+>> LongConstant 0 /// CHECK-DAG: <<Sub:j\d+>> Sub [<<Arg>>,<<Const0>>] /// CHECK-DAG: Return [<<Sub>>] - /// CHECK-START: long Main.Sub0(long) instruction_simplifier (after) + /// CHECK-START: long Main.$noinline$Sub0(long) instruction_simplifier (after) /// CHECK-DAG: <<Arg:j\d+>> ParameterValue /// CHECK-DAG: Return [<<Arg>>] - /// CHECK-START: long Main.Sub0(long) instruction_simplifier (after) + /// CHECK-START: long Main.$noinline$Sub0(long) instruction_simplifier (after) /// CHECK-NOT: Sub - public static long Sub0(long arg) { + public static long $noinline$Sub0(long arg) { + if (doThrow) { throw new Error(); } return arg - 0; } - /// CHECK-START: int Main.SubAliasNeg(int) instruction_simplifier (before) + /// CHECK-START: int Main.$noinline$SubAliasNeg(int) instruction_simplifier (before) /// CHECK-DAG: <<Arg:i\d+>> ParameterValue /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 /// CHECK-DAG: <<Sub:i\d+>> Sub [<<Const0>>,<<Arg>>] /// CHECK-DAG: Return [<<Sub>>] - /// CHECK-START: int Main.SubAliasNeg(int) instruction_simplifier (after) + /// CHECK-START: int Main.$noinline$SubAliasNeg(int) instruction_simplifier (after) /// CHECK-DAG: <<Arg:i\d+>> ParameterValue /// CHECK-DAG: <<Neg:i\d+>> Neg [<<Arg>>] /// CHECK-DAG: Return [<<Neg>>] - /// CHECK-START: int Main.SubAliasNeg(int) instruction_simplifier (after) + /// CHECK-START: int Main.$noinline$SubAliasNeg(int) instruction_simplifier (after) /// CHECK-NOT: Sub - public static int SubAliasNeg(int arg) { + public static int $noinline$SubAliasNeg(int arg) { + if (doThrow) { throw new Error(); } return 0 - arg; } - /// CHECK-START: long Main.UShr0(long) instruction_simplifier (before) + /// CHECK-START: long Main.$noinline$UShr0(long) instruction_simplifier (before) /// CHECK-DAG: <<Arg:j\d+>> ParameterValue /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 /// CHECK-DAG: <<UShr:j\d+>> UShr [<<Arg>>,<<Const0>>] /// CHECK-DAG: Return [<<UShr>>] - /// CHECK-START: long Main.UShr0(long) instruction_simplifier (after) + /// CHECK-START: long Main.$noinline$UShr0(long) instruction_simplifier (after) /// CHECK-DAG: <<Arg:j\d+>> ParameterValue /// CHECK-DAG: Return [<<Arg>>] - /// CHECK-START: long Main.UShr0(long) instruction_simplifier (after) + /// CHECK-START: long Main.$noinline$UShr0(long) instruction_simplifier (after) /// CHECK-NOT: UShr - public static long UShr0(long arg) { + public static long $noinline$UShr0(long arg) { + if (doThrow) { throw new Error(); } return arg >>> 0; } - /// CHECK-START: int Main.Xor0(int) instruction_simplifier (before) + /// CHECK-START: int Main.$noinline$Xor0(int) instruction_simplifier (before) /// CHECK-DAG: <<Arg:i\d+>> ParameterValue /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 /// CHECK-DAG: <<Xor:i\d+>> Xor [<<Arg>>,<<Const0>>] /// CHECK-DAG: Return [<<Xor>>] - /// CHECK-START: int Main.Xor0(int) instruction_simplifier (after) + /// CHECK-START: int Main.$noinline$Xor0(int) instruction_simplifier (after) /// CHECK-DAG: <<Arg:i\d+>> ParameterValue /// CHECK-DAG: Return [<<Arg>>] - /// CHECK-START: int Main.Xor0(int) instruction_simplifier (after) + /// CHECK-START: int Main.$noinline$Xor0(int) instruction_simplifier (after) /// CHECK-NOT: Xor - public static int Xor0(int arg) { + public static int $noinline$Xor0(int arg) { + if (doThrow) { throw new Error(); } return arg ^ 0; } - /// CHECK-START: int Main.XorAllOnes(int) instruction_simplifier (before) + /// CHECK-START: int Main.$noinline$XorAllOnes(int) instruction_simplifier (before) /// CHECK-DAG: <<Arg:i\d+>> ParameterValue /// CHECK-DAG: <<ConstF:i\d+>> IntConstant -1 /// CHECK-DAG: <<Xor:i\d+>> Xor [<<Arg>>,<<ConstF>>] /// CHECK-DAG: Return [<<Xor>>] - /// CHECK-START: int Main.XorAllOnes(int) instruction_simplifier (after) + /// CHECK-START: int Main.$noinline$XorAllOnes(int) instruction_simplifier (after) /// CHECK-DAG: <<Arg:i\d+>> ParameterValue /// CHECK-DAG: <<Not:i\d+>> Not [<<Arg>>] /// CHECK-DAG: Return [<<Not>>] - /// CHECK-START: int Main.XorAllOnes(int) instruction_simplifier (after) + /// CHECK-START: int Main.$noinline$XorAllOnes(int) instruction_simplifier (after) /// CHECK-NOT: Xor - public static int XorAllOnes(int arg) { + public static int $noinline$XorAllOnes(int arg) { + if (doThrow) { throw new Error(); } return arg ^ -1; } @@ -525,7 +552,7 @@ public class Main { * `InstructionSimplifierVisitor::TryMoveNegOnInputsAfterBinop`. */ - /// CHECK-START: int Main.AddNegs1(int, int) instruction_simplifier (before) + /// CHECK-START: int Main.$noinline$AddNegs1(int, int) instruction_simplifier (before) /// CHECK-DAG: <<Arg1:i\d+>> ParameterValue /// CHECK-DAG: <<Arg2:i\d+>> ParameterValue /// CHECK-DAG: <<Neg1:i\d+>> Neg [<<Arg1>>] @@ -533,7 +560,7 @@ public class Main { /// CHECK-DAG: <<Add:i\d+>> Add [<<Neg1>>,<<Neg2>>] /// CHECK-DAG: Return [<<Add>>] - /// CHECK-START: int Main.AddNegs1(int, int) instruction_simplifier (after) + /// CHECK-START: int Main.$noinline$AddNegs1(int, int) instruction_simplifier (after) /// CHECK-DAG: <<Arg1:i\d+>> ParameterValue /// CHECK-DAG: <<Arg2:i\d+>> ParameterValue /// CHECK-NOT: Neg @@ -541,7 +568,8 @@ public class Main { /// CHECK-DAG: <<Neg:i\d+>> Neg [<<Add>>] /// CHECK-DAG: Return [<<Neg>>] - public static int AddNegs1(int arg1, int arg2) { + public static int $noinline$AddNegs1(int arg1, int arg2) { + if (doThrow) { throw new Error(); } return -arg1 + -arg2; } @@ -556,7 +584,7 @@ public class Main { * increasing the register pressure by creating or extending live ranges. */ - /// CHECK-START: int Main.AddNegs2(int, int) instruction_simplifier (before) + /// CHECK-START: int Main.$noinline$AddNegs2(int, int) instruction_simplifier (before) /// CHECK-DAG: <<Arg1:i\d+>> ParameterValue /// CHECK-DAG: <<Arg2:i\d+>> ParameterValue /// CHECK-DAG: <<Neg1:i\d+>> Neg [<<Arg1>>] @@ -566,7 +594,7 @@ public class Main { /// CHECK-DAG: <<Or:i\d+>> Or [<<Add1>>,<<Add2>>] /// CHECK-DAG: Return [<<Or>>] - /// CHECK-START: int Main.AddNegs2(int, int) instruction_simplifier (after) + /// CHECK-START: int Main.$noinline$AddNegs2(int, int) instruction_simplifier (after) /// CHECK-DAG: <<Arg1:i\d+>> ParameterValue /// CHECK-DAG: <<Arg2:i\d+>> ParameterValue /// CHECK-DAG: <<Neg1:i\d+>> Neg [<<Arg1>>] @@ -577,7 +605,7 @@ public class Main { /// CHECK-DAG: <<Or:i\d+>> Or [<<Add1>>,<<Add2>>] /// CHECK-DAG: Return [<<Or>>] - /// CHECK-START: int Main.AddNegs2(int, int) GVN (after) + /// CHECK-START: int Main.$noinline$AddNegs2(int, int) GVN (after) /// CHECK-DAG: <<Arg1:i\d+>> ParameterValue /// CHECK-DAG: <<Arg2:i\d+>> ParameterValue /// CHECK-DAG: <<Neg1:i\d+>> Neg [<<Arg1>>] @@ -586,7 +614,8 @@ public class Main { /// CHECK-DAG: <<Or:i\d+>> Or [<<Add>>,<<Add>>] /// CHECK-DAG: Return [<<Or>>] - public static int AddNegs2(int arg1, int arg2) { + public static int $noinline$AddNegs2(int arg1, int arg2) { + if (doThrow) { throw new Error(); } int temp1 = -arg1; int temp2 = -arg2; return (temp1 + temp2) | (temp1 + temp2); @@ -600,7 +629,7 @@ public class Main { * the loop. */ - /// CHECK-START: long Main.AddNegs3(long, long) instruction_simplifier (before) + /// CHECK-START: long Main.$noinline$AddNegs3(long, long) instruction_simplifier (before) // -------------- Arguments and initial negation operations. /// CHECK-DAG: <<Arg1:j\d+>> ParameterValue /// CHECK-DAG: <<Arg2:j\d+>> ParameterValue @@ -612,7 +641,7 @@ public class Main { /// CHECK: <<Add:j\d+>> Add [<<Neg1>>,<<Neg2>>] /// CHECK: Goto - /// CHECK-START: long Main.AddNegs3(long, long) instruction_simplifier (after) + /// CHECK-START: long Main.$noinline$AddNegs3(long, long) instruction_simplifier (after) // -------------- Arguments and initial negation operations. /// CHECK-DAG: <<Arg1:j\d+>> ParameterValue /// CHECK-DAG: <<Arg2:j\d+>> ParameterValue @@ -625,7 +654,8 @@ public class Main { /// CHECK-NOT: Neg /// CHECK: Goto - public static long AddNegs3(long arg1, long arg2) { + public static long $noinline$AddNegs3(long arg1, long arg2) { + if (doThrow) { throw new Error(); } long res = 0; long n_arg1 = -arg1; long n_arg2 = -arg2; @@ -641,24 +671,25 @@ public class Main { * The transformation tested is implemented in `InstructionSimplifierVisitor::VisitAdd`. */ - /// CHECK-START: long Main.AddNeg1(long, long) instruction_simplifier (before) + /// CHECK-START: long Main.$noinline$AddNeg1(long, long) instruction_simplifier (before) /// CHECK-DAG: <<Arg1:j\d+>> ParameterValue /// CHECK-DAG: <<Arg2:j\d+>> ParameterValue /// CHECK-DAG: <<Neg:j\d+>> Neg [<<Arg1>>] /// CHECK-DAG: <<Add:j\d+>> Add [<<Neg>>,<<Arg2>>] /// CHECK-DAG: Return [<<Add>>] - /// CHECK-START: long Main.AddNeg1(long, long) instruction_simplifier (after) + /// CHECK-START: long Main.$noinline$AddNeg1(long, long) instruction_simplifier (after) /// CHECK-DAG: <<Arg1:j\d+>> ParameterValue /// CHECK-DAG: <<Arg2:j\d+>> ParameterValue /// CHECK-DAG: <<Sub:j\d+>> Sub [<<Arg2>>,<<Arg1>>] /// CHECK-DAG: Return [<<Sub>>] - /// CHECK-START: long Main.AddNeg1(long, long) instruction_simplifier (after) + /// CHECK-START: long Main.$noinline$AddNeg1(long, long) instruction_simplifier (after) /// CHECK-NOT: Neg /// CHECK-NOT: Add - public static long AddNeg1(long arg1, long arg2) { + public static long $noinline$AddNeg1(long arg1, long arg2) { + if (doThrow) { throw new Error(); } return -arg1 + arg2; } @@ -671,7 +702,7 @@ public class Main { * increasing the register pressure by creating or extending live ranges. */ - /// CHECK-START: long Main.AddNeg2(long, long) instruction_simplifier (before) + /// CHECK-START: long Main.$noinline$AddNeg2(long, long) instruction_simplifier (before) /// CHECK-DAG: <<Arg1:j\d+>> ParameterValue /// CHECK-DAG: <<Arg2:j\d+>> ParameterValue /// CHECK-DAG: <<Neg:j\d+>> Neg [<<Arg2>>] @@ -680,7 +711,7 @@ public class Main { /// CHECK-DAG: <<Res:j\d+>> Or [<<Add1>>,<<Add2>>] /// CHECK-DAG: Return [<<Res>>] - /// CHECK-START: long Main.AddNeg2(long, long) instruction_simplifier (after) + /// CHECK-START: long Main.$noinline$AddNeg2(long, long) instruction_simplifier (after) /// CHECK-DAG: <<Arg1:j\d+>> ParameterValue /// CHECK-DAG: <<Arg2:j\d+>> ParameterValue /// CHECK-DAG: <<Neg:j\d+>> Neg [<<Arg2>>] @@ -689,10 +720,11 @@ public class Main { /// CHECK-DAG: <<Res:j\d+>> Or [<<Add1>>,<<Add2>>] /// CHECK-DAG: Return [<<Res>>] - /// CHECK-START: long Main.AddNeg2(long, long) instruction_simplifier (after) + /// CHECK-START: long Main.$noinline$AddNeg2(long, long) instruction_simplifier (after) /// CHECK-NOT: Sub - public static long AddNeg2(long arg1, long arg2) { + public static long $noinline$AddNeg2(long arg1, long arg2) { + if (doThrow) { throw new Error(); } long temp = -arg2; return (arg1 + temp) | (arg1 + temp); } @@ -702,20 +734,21 @@ public class Main { * The transformation tested is implemented in `InstructionSimplifierVisitor::VisitNeg`. */ - /// CHECK-START: long Main.NegNeg1(long) instruction_simplifier (before) + /// CHECK-START: long Main.$noinline$NegNeg1(long) instruction_simplifier (before) /// CHECK-DAG: <<Arg:j\d+>> ParameterValue /// CHECK-DAG: <<Neg1:j\d+>> Neg [<<Arg>>] /// CHECK-DAG: <<Neg2:j\d+>> Neg [<<Neg1>>] /// CHECK-DAG: Return [<<Neg2>>] - /// CHECK-START: long Main.NegNeg1(long) instruction_simplifier (after) + /// CHECK-START: long Main.$noinline$NegNeg1(long) instruction_simplifier (after) /// CHECK-DAG: <<Arg:j\d+>> ParameterValue /// CHECK-DAG: Return [<<Arg>>] - /// CHECK-START: long Main.NegNeg1(long) instruction_simplifier (after) + /// CHECK-START: long Main.$noinline$NegNeg1(long) instruction_simplifier (after) /// CHECK-NOT: Neg - public static long NegNeg1(long arg) { + public static long $noinline$NegNeg1(long arg) { + if (doThrow) { throw new Error(); } return -(-arg); } @@ -726,29 +759,30 @@ public class Main { * and in `InstructionSimplifierVisitor::VisitAdd`. */ - /// CHECK-START: int Main.NegNeg2(int) instruction_simplifier (before) + /// CHECK-START: int Main.$noinline$NegNeg2(int) instruction_simplifier (before) /// CHECK-DAG: <<Arg:i\d+>> ParameterValue /// CHECK-DAG: <<Neg1:i\d+>> Neg [<<Arg>>] /// CHECK-DAG: <<Neg2:i\d+>> Neg [<<Neg1>>] /// CHECK-DAG: <<Add:i\d+>> Add [<<Neg2>>,<<Neg1>>] /// CHECK-DAG: Return [<<Add>>] - /// CHECK-START: int Main.NegNeg2(int) instruction_simplifier (after) + /// CHECK-START: int Main.$noinline$NegNeg2(int) instruction_simplifier (after) /// CHECK-DAG: <<Arg:i\d+>> ParameterValue /// CHECK-DAG: <<Sub:i\d+>> Sub [<<Arg>>,<<Arg>>] /// CHECK-DAG: Return [<<Sub>>] - /// CHECK-START: int Main.NegNeg2(int) instruction_simplifier (after) + /// CHECK-START: int Main.$noinline$NegNeg2(int) instruction_simplifier (after) /// CHECK-NOT: Neg /// CHECK-NOT: Add - /// CHECK-START: int Main.NegNeg2(int) constant_folding_after_inlining (after) + /// CHECK-START: int Main.$noinline$NegNeg2(int) constant_folding_after_inlining (after) /// CHECK: <<Const0:i\d+>> IntConstant 0 /// CHECK-NOT: Neg /// CHECK-NOT: Add /// CHECK: Return [<<Const0>>] - public static int NegNeg2(int arg) { + public static int $noinline$NegNeg2(int arg) { + if (doThrow) { throw new Error(); } int temp = -arg; return temp + -temp; } @@ -760,22 +794,23 @@ public class Main { * and in `InstructionSimplifierVisitor::VisitSub`. */ - /// CHECK-START: long Main.NegNeg3(long) instruction_simplifier (before) + /// CHECK-START: long Main.$noinline$NegNeg3(long) instruction_simplifier (before) /// CHECK-DAG: <<Arg:j\d+>> ParameterValue /// CHECK-DAG: <<Const0:j\d+>> LongConstant 0 /// CHECK-DAG: <<Neg:j\d+>> Neg [<<Arg>>] /// CHECK-DAG: <<Sub:j\d+>> Sub [<<Const0>>,<<Neg>>] /// CHECK-DAG: Return [<<Sub>>] - /// CHECK-START: long Main.NegNeg3(long) instruction_simplifier (after) + /// CHECK-START: long Main.$noinline$NegNeg3(long) instruction_simplifier (after) /// CHECK-DAG: <<Arg:j\d+>> ParameterValue /// CHECK-DAG: Return [<<Arg>>] - /// CHECK-START: long Main.NegNeg3(long) instruction_simplifier (after) + /// CHECK-START: long Main.$noinline$NegNeg3(long) instruction_simplifier (after) /// CHECK-NOT: Neg /// CHECK-NOT: Sub - public static long NegNeg3(long arg) { + public static long $noinline$NegNeg3(long arg) { + if (doThrow) { throw new Error(); } return 0 - -arg; } @@ -785,23 +820,24 @@ public class Main { * The transformation tested is implemented in `InstructionSimplifierVisitor::VisitNeg`. */ - /// CHECK-START: int Main.NegSub1(int, int) instruction_simplifier (before) + /// CHECK-START: int Main.$noinline$NegSub1(int, int) instruction_simplifier (before) /// CHECK-DAG: <<Arg1:i\d+>> ParameterValue /// CHECK-DAG: <<Arg2:i\d+>> ParameterValue /// CHECK-DAG: <<Sub:i\d+>> Sub [<<Arg1>>,<<Arg2>>] /// CHECK-DAG: <<Neg:i\d+>> Neg [<<Sub>>] /// CHECK-DAG: Return [<<Neg>>] - /// CHECK-START: int Main.NegSub1(int, int) instruction_simplifier (after) + /// CHECK-START: int Main.$noinline$NegSub1(int, int) instruction_simplifier (after) /// CHECK-DAG: <<Arg1:i\d+>> ParameterValue /// CHECK-DAG: <<Arg2:i\d+>> ParameterValue /// CHECK-DAG: <<Sub:i\d+>> Sub [<<Arg2>>,<<Arg1>>] /// CHECK-DAG: Return [<<Sub>>] - /// CHECK-START: int Main.NegSub1(int, int) instruction_simplifier (after) + /// CHECK-START: int Main.$noinline$NegSub1(int, int) instruction_simplifier (after) /// CHECK-NOT: Neg - public static int NegSub1(int arg1, int arg2) { + public static int $noinline$NegSub1(int arg1, int arg2) { + if (doThrow) { throw new Error(); } return -(arg1 - arg2); } @@ -815,7 +851,7 @@ public class Main { * increasing the register pressure by creating or extending live ranges. */ - /// CHECK-START: int Main.NegSub2(int, int) instruction_simplifier (before) + /// CHECK-START: int Main.$noinline$NegSub2(int, int) instruction_simplifier (before) /// CHECK-DAG: <<Arg1:i\d+>> ParameterValue /// CHECK-DAG: <<Arg2:i\d+>> ParameterValue /// CHECK-DAG: <<Sub:i\d+>> Sub [<<Arg1>>,<<Arg2>>] @@ -824,7 +860,7 @@ public class Main { /// CHECK-DAG: <<Or:i\d+>> Or [<<Neg1>>,<<Neg2>>] /// CHECK-DAG: Return [<<Or>>] - /// CHECK-START: int Main.NegSub2(int, int) instruction_simplifier (after) + /// CHECK-START: int Main.$noinline$NegSub2(int, int) instruction_simplifier (after) /// CHECK-DAG: <<Arg1:i\d+>> ParameterValue /// CHECK-DAG: <<Arg2:i\d+>> ParameterValue /// CHECK-DAG: <<Sub:i\d+>> Sub [<<Arg1>>,<<Arg2>>] @@ -833,7 +869,8 @@ public class Main { /// CHECK-DAG: <<Or:i\d+>> Or [<<Neg1>>,<<Neg2>>] /// CHECK-DAG: Return [<<Or>>] - public static int NegSub2(int arg1, int arg2) { + public static int $noinline$NegSub2(int arg1, int arg2) { + if (doThrow) { throw new Error(); } int temp = arg1 - arg2; return -temp | -temp; } @@ -843,41 +880,43 @@ public class Main { * The transformation tested is implemented in `InstructionSimplifierVisitor::VisitNot`. */ - /// CHECK-START: long Main.NotNot1(long) instruction_simplifier (before) + /// CHECK-START: long Main.$noinline$NotNot1(long) instruction_simplifier (before) /// CHECK-DAG: <<Arg:j\d+>> ParameterValue /// CHECK-DAG: <<Not1:j\d+>> Not [<<Arg>>] /// CHECK-DAG: <<Not2:j\d+>> Not [<<Not1>>] /// CHECK-DAG: Return [<<Not2>>] - /// CHECK-START: long Main.NotNot1(long) instruction_simplifier (after) + /// CHECK-START: long Main.$noinline$NotNot1(long) instruction_simplifier (after) /// CHECK-DAG: <<Arg:j\d+>> ParameterValue /// CHECK-DAG: Return [<<Arg>>] - /// CHECK-START: long Main.NotNot1(long) instruction_simplifier (after) + /// CHECK-START: long Main.$noinline$NotNot1(long) instruction_simplifier (after) /// CHECK-NOT: Not - public static long NotNot1(long arg) { + public static long $noinline$NotNot1(long arg) { + if (doThrow) { throw new Error(); } return ~~arg; } - /// CHECK-START: int Main.NotNot2(int) instruction_simplifier (before) + /// CHECK-START: int Main.$noinline$NotNot2(int) instruction_simplifier (before) /// CHECK-DAG: <<Arg:i\d+>> ParameterValue /// CHECK-DAG: <<Not1:i\d+>> Not [<<Arg>>] /// CHECK-DAG: <<Not2:i\d+>> Not [<<Not1>>] /// CHECK-DAG: <<Add:i\d+>> Add [<<Not2>>,<<Not1>>] /// CHECK-DAG: Return [<<Add>>] - /// CHECK-START: int Main.NotNot2(int) instruction_simplifier (after) + /// CHECK-START: int Main.$noinline$NotNot2(int) instruction_simplifier (after) /// CHECK-DAG: <<Arg:i\d+>> ParameterValue /// CHECK-DAG: <<Not:i\d+>> Not [<<Arg>>] /// CHECK-DAG: <<Add:i\d+>> Add [<<Arg>>,<<Not>>] /// CHECK-DAG: Return [<<Add>>] - /// CHECK-START: int Main.NotNot2(int) instruction_simplifier (after) + /// CHECK-START: int Main.$noinline$NotNot2(int) instruction_simplifier (after) /// CHECK: Not /// CHECK-NOT: Not - public static int NotNot2(int arg) { + public static int $noinline$NotNot2(int arg) { + if (doThrow) { throw new Error(); } int temp = ~arg; return temp + ~temp; } @@ -887,24 +926,25 @@ public class Main { * The transformation tested is implemented in `InstructionSimplifierVisitor::VisitSub`. */ - /// CHECK-START: int Main.SubNeg1(int, int) instruction_simplifier (before) + /// CHECK-START: int Main.$noinline$SubNeg1(int, int) instruction_simplifier (before) /// CHECK-DAG: <<Arg1:i\d+>> ParameterValue /// CHECK-DAG: <<Arg2:i\d+>> ParameterValue /// CHECK-DAG: <<Neg:i\d+>> Neg [<<Arg1>>] /// CHECK-DAG: <<Sub:i\d+>> Sub [<<Neg>>,<<Arg2>>] /// CHECK-DAG: Return [<<Sub>>] - /// CHECK-START: int Main.SubNeg1(int, int) instruction_simplifier (after) + /// CHECK-START: int Main.$noinline$SubNeg1(int, int) instruction_simplifier (after) /// CHECK-DAG: <<Arg1:i\d+>> ParameterValue /// CHECK-DAG: <<Arg2:i\d+>> ParameterValue /// CHECK-DAG: <<Add:i\d+>> Add [<<Arg1>>,<<Arg2>>] /// CHECK-DAG: <<Neg:i\d+>> Neg [<<Add>>] /// CHECK-DAG: Return [<<Neg>>] - /// CHECK-START: int Main.SubNeg1(int, int) instruction_simplifier (after) + /// CHECK-START: int Main.$noinline$SubNeg1(int, int) instruction_simplifier (after) /// CHECK-NOT: Sub - public static int SubNeg1(int arg1, int arg2) { + public static int $noinline$SubNeg1(int arg1, int arg2) { + if (doThrow) { throw new Error(); } return -arg1 - arg2; } @@ -918,7 +958,7 @@ public class Main { * increasing the register pressure by creating or extending live ranges. */ - /// CHECK-START: int Main.SubNeg2(int, int) instruction_simplifier (before) + /// CHECK-START: int Main.$noinline$SubNeg2(int, int) instruction_simplifier (before) /// CHECK-DAG: <<Arg1:i\d+>> ParameterValue /// CHECK-DAG: <<Arg2:i\d+>> ParameterValue /// CHECK-DAG: <<Neg:i\d+>> Neg [<<Arg1>>] @@ -927,7 +967,7 @@ public class Main { /// CHECK-DAG: <<Or:i\d+>> Or [<<Sub1>>,<<Sub2>>] /// CHECK-DAG: Return [<<Or>>] - /// CHECK-START: int Main.SubNeg2(int, int) instruction_simplifier (after) + /// CHECK-START: int Main.$noinline$SubNeg2(int, int) instruction_simplifier (after) /// CHECK-DAG: <<Arg1:i\d+>> ParameterValue /// CHECK-DAG: <<Arg2:i\d+>> ParameterValue /// CHECK-DAG: <<Neg:i\d+>> Neg [<<Arg1>>] @@ -936,10 +976,11 @@ public class Main { /// CHECK-DAG: <<Or:i\d+>> Or [<<Sub1>>,<<Sub2>>] /// CHECK-DAG: Return [<<Or>>] - /// CHECK-START: int Main.SubNeg2(int, int) instruction_simplifier (after) + /// CHECK-START: int Main.$noinline$SubNeg2(int, int) instruction_simplifier (after) /// CHECK-NOT: Add - public static int SubNeg2(int arg1, int arg2) { + public static int $noinline$SubNeg2(int arg1, int arg2) { + if (doThrow) { throw new Error(); } int temp = -arg1; return (temp - arg2) | (temp - arg2); } @@ -951,7 +992,7 @@ public class Main { * the loop. */ - /// CHECK-START: long Main.SubNeg3(long, long) instruction_simplifier (before) + /// CHECK-START: long Main.$noinline$SubNeg3(long, long) instruction_simplifier (before) // -------------- Arguments and initial negation operation. /// CHECK-DAG: <<Arg1:j\d+>> ParameterValue /// CHECK-DAG: <<Arg2:j\d+>> ParameterValue @@ -962,7 +1003,7 @@ public class Main { /// CHECK: <<Sub:j\d+>> Sub [<<Neg>>,<<Arg2>>] /// CHECK: Goto - /// CHECK-START: long Main.SubNeg3(long, long) instruction_simplifier (after) + /// CHECK-START: long Main.$noinline$SubNeg3(long, long) instruction_simplifier (after) // -------------- Arguments and initial negation operation. /// CHECK-DAG: <<Arg1:j\d+>> ParameterValue /// CHECK-DAG: <<Arg2:j\d+>> ParameterValue @@ -974,7 +1015,8 @@ public class Main { /// CHECK-NOT: Neg /// CHECK: Goto - public static long SubNeg3(long arg1, long arg2) { + public static long $noinline$SubNeg3(long arg1, long arg2) { + if (doThrow) { throw new Error(); } long res = 0; long temp = -arg1; for (long i = 0; i < 1; i++) { @@ -983,7 +1025,7 @@ public class Main { return res; } - /// CHECK-START: boolean Main.EqualBoolVsIntConst(boolean) instruction_simplifier_after_bce (before) + /// CHECK-START: boolean Main.$noinline$EqualBoolVsIntConst(boolean) instruction_simplifier_after_bce (before) /// CHECK-DAG: <<Arg:z\d+>> ParameterValue /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 @@ -993,15 +1035,16 @@ public class Main { /// CHECK-DAG: <<NotCond:i\d+>> Select [<<Const1>>,<<Const0>>,<<Cond>>] /// CHECK-DAG: Return [<<NotCond>>] - /// CHECK-START: boolean Main.EqualBoolVsIntConst(boolean) instruction_simplifier_after_bce (after) + /// CHECK-START: boolean Main.$noinline$EqualBoolVsIntConst(boolean) instruction_simplifier_after_bce (after) /// CHECK-DAG: <<True:i\d+>> IntConstant 1 /// CHECK-DAG: Return [<<True>>] - public static boolean EqualBoolVsIntConst(boolean arg) { + public static boolean $noinline$EqualBoolVsIntConst(boolean arg) { + if (doThrow) { throw new Error(); } return (arg ? 0 : 1) != 2; } - /// CHECK-START: boolean Main.NotEqualBoolVsIntConst(boolean) instruction_simplifier_after_bce (before) + /// CHECK-START: boolean Main.$noinline$NotEqualBoolVsIntConst(boolean) instruction_simplifier_after_bce (before) /// CHECK-DAG: <<Arg:z\d+>> ParameterValue /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 @@ -1011,11 +1054,12 @@ public class Main { /// CHECK-DAG: <<NotCond:i\d+>> Select [<<Const1>>,<<Const0>>,<<Cond>>] /// CHECK-DAG: Return [<<NotCond>>] - /// CHECK-START: boolean Main.NotEqualBoolVsIntConst(boolean) instruction_simplifier_after_bce (after) + /// CHECK-START: boolean Main.$noinline$NotEqualBoolVsIntConst(boolean) instruction_simplifier_after_bce (after) /// CHECK-DAG: <<False:i\d+>> IntConstant 0 /// CHECK-DAG: Return [<<False>>] - public static boolean NotEqualBoolVsIntConst(boolean arg) { + public static boolean $noinline$NotEqualBoolVsIntConst(boolean arg) { + if (doThrow) { throw new Error(); } return (arg ? 0 : 1) == 2; } @@ -1025,7 +1069,7 @@ public class Main { * remove the second. */ - /// CHECK-START: boolean Main.NotNotBool(boolean) instruction_simplifier_after_bce (before) + /// CHECK-START: boolean Main.$noinline$NotNotBool(boolean) instruction_simplifier_after_bce (before) /// CHECK-DAG: <<Arg:z\d+>> ParameterValue /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 @@ -1033,7 +1077,7 @@ public class Main { /// CHECK-DAG: <<NotNotArg:i\d+>> Select [<<Const1>>,<<Const0>>,<<NotArg>>] /// CHECK-DAG: Return [<<NotNotArg>>] - /// CHECK-START: boolean Main.NotNotBool(boolean) instruction_simplifier_after_bce (after) + /// CHECK-START: boolean Main.$noinline$NotNotBool(boolean) instruction_simplifier_after_bce (after) /// CHECK-DAG: <<Arg:z\d+>> ParameterValue /// CHECK-DAG: Return [<<Arg>>] @@ -1041,81 +1085,86 @@ public class Main { return !arg; } - public static boolean NotNotBool(boolean arg) { + public static boolean $noinline$NotNotBool(boolean arg) { + if (doThrow) { throw new Error(); } return !(NegateValue(arg)); } - /// CHECK-START: float Main.Div2(float) instruction_simplifier (before) + /// CHECK-START: float Main.$noinline$Div2(float) instruction_simplifier (before) /// CHECK-DAG: <<Arg:f\d+>> ParameterValue /// CHECK-DAG: <<Const2:f\d+>> FloatConstant 2 /// CHECK-DAG: <<Div:f\d+>> Div [<<Arg>>,<<Const2>>] /// CHECK-DAG: Return [<<Div>>] - /// CHECK-START: float Main.Div2(float) instruction_simplifier (after) + /// CHECK-START: float Main.$noinline$Div2(float) instruction_simplifier (after) /// CHECK-DAG: <<Arg:f\d+>> ParameterValue /// CHECK-DAG: <<ConstP5:f\d+>> FloatConstant 0.5 /// CHECK-DAG: <<Mul:f\d+>> Mul [<<Arg>>,<<ConstP5>>] /// CHECK-DAG: Return [<<Mul>>] - /// CHECK-START: float Main.Div2(float) instruction_simplifier (after) + /// CHECK-START: float Main.$noinline$Div2(float) instruction_simplifier (after) /// CHECK-NOT: Div - public static float Div2(float arg) { + public static float $noinline$Div2(float arg) { + if (doThrow) { throw new Error(); } return arg / 2.0f; } - /// CHECK-START: double Main.Div2(double) instruction_simplifier (before) + /// CHECK-START: double Main.$noinline$Div2(double) instruction_simplifier (before) /// CHECK-DAG: <<Arg:d\d+>> ParameterValue /// CHECK-DAG: <<Const2:d\d+>> DoubleConstant 2 /// CHECK-DAG: <<Div:d\d+>> Div [<<Arg>>,<<Const2>>] /// CHECK-DAG: Return [<<Div>>] - /// CHECK-START: double Main.Div2(double) instruction_simplifier (after) + /// CHECK-START: double Main.$noinline$Div2(double) instruction_simplifier (after) /// CHECK-DAG: <<Arg:d\d+>> ParameterValue /// CHECK-DAG: <<ConstP5:d\d+>> DoubleConstant 0.5 /// CHECK-DAG: <<Mul:d\d+>> Mul [<<Arg>>,<<ConstP5>>] /// CHECK-DAG: Return [<<Mul>>] - /// CHECK-START: double Main.Div2(double) instruction_simplifier (after) + /// CHECK-START: double Main.$noinline$Div2(double) instruction_simplifier (after) /// CHECK-NOT: Div - public static double Div2(double arg) { + public static double $noinline$Div2(double arg) { + if (doThrow) { throw new Error(); } return arg / 2.0; } - /// CHECK-START: float Main.DivMP25(float) instruction_simplifier (before) + /// CHECK-START: float Main.$noinline$DivMP25(float) instruction_simplifier (before) /// CHECK-DAG: <<Arg:f\d+>> ParameterValue /// CHECK-DAG: <<ConstMP25:f\d+>> FloatConstant -0.25 /// CHECK-DAG: <<Div:f\d+>> Div [<<Arg>>,<<ConstMP25>>] /// CHECK-DAG: Return [<<Div>>] - /// CHECK-START: float Main.DivMP25(float) instruction_simplifier (after) + /// CHECK-START: float Main.$noinline$DivMP25(float) instruction_simplifier (after) /// CHECK-DAG: <<Arg:f\d+>> ParameterValue /// CHECK-DAG: <<ConstM4:f\d+>> FloatConstant -4 /// CHECK-DAG: <<Mul:f\d+>> Mul [<<Arg>>,<<ConstM4>>] /// CHECK-DAG: Return [<<Mul>>] - /// CHECK-START: float Main.DivMP25(float) instruction_simplifier (after) + /// CHECK-START: float Main.$noinline$DivMP25(float) instruction_simplifier (after) /// CHECK-NOT: Div - public static float DivMP25(float arg) { + public static float $noinline$DivMP25(float arg) { + if (doThrow) { throw new Error(); } return arg / -0.25f; } - /// CHECK-START: double Main.DivMP25(double) instruction_simplifier (before) + /// CHECK-START: double Main.$noinline$DivMP25(double) instruction_simplifier (before) /// CHECK-DAG: <<Arg:d\d+>> ParameterValue /// CHECK-DAG: <<ConstMP25:d\d+>> DoubleConstant -0.25 /// CHECK-DAG: <<Div:d\d+>> Div [<<Arg>>,<<ConstMP25>>] /// CHECK-DAG: Return [<<Div>>] - /// CHECK-START: double Main.DivMP25(double) instruction_simplifier (after) + /// CHECK-START: double Main.$noinline$DivMP25(double) instruction_simplifier (after) /// CHECK-DAG: <<Arg:d\d+>> ParameterValue /// CHECK-DAG: <<ConstM4:d\d+>> DoubleConstant -4 /// CHECK-DAG: <<Mul:d\d+>> Mul [<<Arg>>,<<ConstM4>>] /// CHECK-DAG: Return [<<Mul>>] - /// CHECK-START: double Main.DivMP25(double) instruction_simplifier (after) + /// CHECK-START: double Main.$noinline$DivMP25(double) instruction_simplifier (after) /// CHECK-NOT: Div - public static double DivMP25(double arg) { + public static double $noinline$DivMP25(double arg) { + if (doThrow) { throw new Error(); } return arg / -0.25f; } @@ -1123,18 +1172,19 @@ public class Main { * Test strength reduction of factors of the form (2^n + 1). */ - /// CHECK-START: int Main.mulPow2Plus1(int) instruction_simplifier (before) + /// CHECK-START: int Main.$noinline$mulPow2Plus1(int) instruction_simplifier (before) /// CHECK-DAG: <<Arg:i\d+>> ParameterValue /// CHECK-DAG: <<Const9:i\d+>> IntConstant 9 /// CHECK: Mul [<<Arg>>,<<Const9>>] - /// CHECK-START: int Main.mulPow2Plus1(int) instruction_simplifier (after) + /// CHECK-START: int Main.$noinline$mulPow2Plus1(int) instruction_simplifier (after) /// CHECK-DAG: <<Arg:i\d+>> ParameterValue /// CHECK-DAG: <<Const3:i\d+>> IntConstant 3 /// CHECK: <<Shift:i\d+>> Shl [<<Arg>>,<<Const3>>] /// CHECK-NEXT: Add [<<Arg>>,<<Shift>>] - public static int mulPow2Plus1(int arg) { + public static int $noinline$mulPow2Plus1(int arg) { + if (doThrow) { throw new Error(); } return arg * 9; } @@ -1142,62 +1192,69 @@ public class Main { * Test strength reduction of factors of the form (2^n - 1). */ - /// CHECK-START: long Main.mulPow2Minus1(long) instruction_simplifier (before) + /// CHECK-START: long Main.$noinline$mulPow2Minus1(long) instruction_simplifier (before) /// CHECK-DAG: <<Arg:j\d+>> ParameterValue /// CHECK-DAG: <<Const31:j\d+>> LongConstant 31 /// CHECK: Mul [<<Const31>>,<<Arg>>] - /// CHECK-START: long Main.mulPow2Minus1(long) instruction_simplifier (after) + /// CHECK-START: long Main.$noinline$mulPow2Minus1(long) instruction_simplifier (after) /// CHECK-DAG: <<Arg:j\d+>> ParameterValue /// CHECK-DAG: <<Const5:i\d+>> IntConstant 5 /// CHECK: <<Shift:j\d+>> Shl [<<Arg>>,<<Const5>>] /// CHECK-NEXT: Sub [<<Shift>>,<<Arg>>] - public static long mulPow2Minus1(long arg) { + public static long $noinline$mulPow2Minus1(long arg) { + if (doThrow) { throw new Error(); } return arg * 31; } - /// CHECK-START: int Main.booleanFieldNotEqualOne() instruction_simplifier_after_bce (before) + /// CHECK-START: int Main.$noinline$booleanFieldNotEqualOne() instruction_simplifier_after_bce (before) /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 /// CHECK-DAG: <<Const13:i\d+>> IntConstant 13 /// CHECK-DAG: <<Const54:i\d+>> IntConstant 54 + /// CHECK-DAG: <<doThrow:z\d+>> StaticFieldGet /// CHECK-DAG: <<Field:z\d+>> StaticFieldGet /// CHECK-DAG: <<NE:z\d+>> NotEqual [<<Field>>,<<Const1>>] /// CHECK-DAG: <<Select:i\d+>> Select [<<Const13>>,<<Const54>>,<<NE>>] /// CHECK-DAG: Return [<<Select>>] - /// CHECK-START: int Main.booleanFieldNotEqualOne() instruction_simplifier_after_bce (after) + /// CHECK-START: int Main.$noinline$booleanFieldNotEqualOne() instruction_simplifier_after_bce (after) + /// CHECK-DAG: <<doThrow:z\d+>> StaticFieldGet /// CHECK-DAG: <<Field:z\d+>> StaticFieldGet /// CHECK-DAG: <<Const13:i\d+>> IntConstant 13 /// CHECK-DAG: <<Const54:i\d+>> IntConstant 54 /// CHECK-DAG: <<Select:i\d+>> Select [<<Const54>>,<<Const13>>,<<Field>>] /// CHECK-DAG: Return [<<Select>>] - public static int booleanFieldNotEqualOne() { + public static int $noinline$booleanFieldNotEqualOne() { + if (doThrow) { throw new Error(); } return (booleanField == $inline$true()) ? 13 : 54; } - /// CHECK-START: int Main.booleanFieldEqualZero() instruction_simplifier_after_bce (before) + /// CHECK-START: int Main.$noinline$booleanFieldEqualZero() instruction_simplifier_after_bce (before) /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 /// CHECK-DAG: <<Const13:i\d+>> IntConstant 13 /// CHECK-DAG: <<Const54:i\d+>> IntConstant 54 + /// CHECK-DAG: <<doThrow:z\d+>> StaticFieldGet /// CHECK-DAG: <<Field:z\d+>> StaticFieldGet /// CHECK-DAG: <<NE:z\d+>> Equal [<<Field>>,<<Const0>>] /// CHECK-DAG: <<Select:i\d+>> Select [<<Const13>>,<<Const54>>,<<NE>>] /// CHECK-DAG: Return [<<Select>>] - /// CHECK-START: int Main.booleanFieldEqualZero() instruction_simplifier_after_bce (after) + /// CHECK-START: int Main.$noinline$booleanFieldEqualZero() instruction_simplifier_after_bce (after) + /// CHECK-DAG: <<doThrow:z\d+>> StaticFieldGet /// CHECK-DAG: <<Field:z\d+>> StaticFieldGet /// CHECK-DAG: <<Const13:i\d+>> IntConstant 13 /// CHECK-DAG: <<Const54:i\d+>> IntConstant 54 /// CHECK-DAG: <<Select:i\d+>> Select [<<Const54>>,<<Const13>>,<<Field>>] /// CHECK-DAG: Return [<<Select>>] - public static int booleanFieldEqualZero() { + public static int $noinline$booleanFieldEqualZero() { + if (doThrow) { throw new Error(); } return (booleanField != $inline$false()) ? 13 : 54; } - /// CHECK-START: int Main.intConditionNotEqualOne(int) instruction_simplifier_after_bce (before) + /// CHECK-START: int Main.$noinline$intConditionNotEqualOne(int) instruction_simplifier_after_bce (before) /// CHECK-DAG: <<Arg:i\d+>> ParameterValue /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 @@ -1210,7 +1267,7 @@ public class Main { /// CHECK-DAG: <<Result:i\d+>> Select [<<Const13>>,<<Const54>>,<<NE>>] /// CHECK-DAG: Return [<<Result>>] - /// CHECK-START: int Main.intConditionNotEqualOne(int) instruction_simplifier_after_bce (after) + /// CHECK-START: int Main.$noinline$intConditionNotEqualOne(int) instruction_simplifier_after_bce (after) /// CHECK-DAG: <<Arg:i\d+>> ParameterValue /// CHECK-DAG: <<Const13:i\d+>> IntConstant 13 /// CHECK-DAG: <<Const42:i\d+>> IntConstant 42 @@ -1221,11 +1278,12 @@ public class Main { // Note that we match `LE` from Select because there are two identical // LessThanOrEqual instructions. - public static int intConditionNotEqualOne(int i) { + public static int $noinline$intConditionNotEqualOne(int i) { + if (doThrow) { throw new Error(); } return ((i > 42) == $inline$true()) ? 13 : 54; } - /// CHECK-START: int Main.intConditionEqualZero(int) instruction_simplifier_after_bce (before) + /// CHECK-START: int Main.$noinline$intConditionEqualZero(int) instruction_simplifier_after_bce (before) /// CHECK-DAG: <<Arg:i\d+>> ParameterValue /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 @@ -1238,7 +1296,7 @@ public class Main { /// CHECK-DAG: <<Result:i\d+>> Select [<<Const13>>,<<Const54>>,<<NE>>] /// CHECK-DAG: Return [<<Result>>] - /// CHECK-START: int Main.intConditionEqualZero(int) instruction_simplifier_after_bce (after) + /// CHECK-START: int Main.$noinline$intConditionEqualZero(int) instruction_simplifier_after_bce (after) /// CHECK-DAG: <<Arg:i\d+>> ParameterValue /// CHECK-DAG: <<Const13:i\d+>> IntConstant 13 /// CHECK-DAG: <<Const42:i\d+>> IntConstant 42 @@ -1249,16 +1307,17 @@ public class Main { // Note that we match `LE` from Select because there are two identical // LessThanOrEqual instructions. - public static int intConditionEqualZero(int i) { + public static int $noinline$intConditionEqualZero(int i) { + if (doThrow) { throw new Error(); } return ((i > 42) != $inline$false()) ? 13 : 54; } // Test that conditions on float/double are not flipped. - /// CHECK-START: int Main.floatConditionNotEqualOne(float) builder (after) + /// CHECK-START: int Main.$noinline$floatConditionNotEqualOne(float) builder (after) /// CHECK: LessThanOrEqual - /// CHECK-START: int Main.floatConditionNotEqualOne(float) instruction_simplifier_before_codegen (after) + /// CHECK-START: int Main.$noinline$floatConditionNotEqualOne(float) instruction_simplifier_before_codegen (after) /// CHECK-DAG: <<Arg:f\d+>> ParameterValue /// CHECK-DAG: <<Const13:i\d+>> IntConstant 13 /// CHECK-DAG: <<Const54:i\d+>> IntConstant 54 @@ -1267,14 +1326,15 @@ public class Main { /// CHECK-DAG: <<Select:i\d+>> Select [<<Const13>>,<<Const54>>,<<LE>>] /// CHECK-DAG: Return [<<Select>>] - public static int floatConditionNotEqualOne(float f) { + public static int $noinline$floatConditionNotEqualOne(float f) { + if (doThrow) { throw new Error(); } return ((f > 42.0f) == true) ? 13 : 54; } - /// CHECK-START: int Main.doubleConditionEqualZero(double) builder (after) + /// CHECK-START: int Main.$noinline$doubleConditionEqualZero(double) builder (after) /// CHECK: LessThanOrEqual - /// CHECK-START: int Main.doubleConditionEqualZero(double) instruction_simplifier_before_codegen (after) + /// CHECK-START: int Main.$noinline$doubleConditionEqualZero(double) instruction_simplifier_before_codegen (after) /// CHECK-DAG: <<Arg:d\d+>> ParameterValue /// CHECK-DAG: <<Const13:i\d+>> IntConstant 13 /// CHECK-DAG: <<Const54:i\d+>> IntConstant 54 @@ -1283,42 +1343,45 @@ public class Main { /// CHECK-DAG: <<Select:i\d+>> Select [<<Const13>>,<<Const54>>,<<LE>>] /// CHECK-DAG: Return [<<Select>>] - public static int doubleConditionEqualZero(double d) { + public static int $noinline$doubleConditionEqualZero(double d) { + if (doThrow) { throw new Error(); } return ((d > 42.0) != false) ? 13 : 54; } - /// CHECK-START: int Main.intToDoubleToInt(int) instruction_simplifier (before) + /// CHECK-START: int Main.$noinline$intToDoubleToInt(int) instruction_simplifier (before) /// CHECK-DAG: <<Arg:i\d+>> ParameterValue /// CHECK-DAG: <<Double:d\d+>> TypeConversion [<<Arg>>] /// CHECK-DAG: <<Int:i\d+>> TypeConversion [<<Double>>] /// CHECK-DAG: Return [<<Int>>] - /// CHECK-START: int Main.intToDoubleToInt(int) instruction_simplifier (after) + /// CHECK-START: int Main.$noinline$intToDoubleToInt(int) instruction_simplifier (after) /// CHECK-DAG: <<Arg:i\d+>> ParameterValue /// CHECK-DAG: Return [<<Arg>>] - /// CHECK-START: int Main.intToDoubleToInt(int) instruction_simplifier (after) + /// CHECK-START: int Main.$noinline$intToDoubleToInt(int) instruction_simplifier (after) /// CHECK-NOT: TypeConversion - public static int intToDoubleToInt(int value) { + public static int $noinline$intToDoubleToInt(int value) { + if (doThrow) { throw new Error(); } // Lossless conversion followed by a conversion back. return (int) (double) value; } - /// CHECK-START: java.lang.String Main.intToDoubleToIntPrint(int) instruction_simplifier (before) + /// CHECK-START: java.lang.String Main.$noinline$intToDoubleToIntPrint(int) instruction_simplifier (before) /// CHECK-DAG: <<Arg:i\d+>> ParameterValue /// CHECK-DAG: <<Double:d\d+>> TypeConversion [<<Arg>>] /// CHECK-DAG: {{i\d+}} TypeConversion [<<Double>>] - /// CHECK-START: java.lang.String Main.intToDoubleToIntPrint(int) instruction_simplifier (after) + /// CHECK-START: java.lang.String Main.$noinline$intToDoubleToIntPrint(int) instruction_simplifier (after) /// CHECK-DAG: <<Arg:i\d+>> ParameterValue /// CHECK-DAG: {{d\d+}} TypeConversion [<<Arg>>] - /// CHECK-START: java.lang.String Main.intToDoubleToIntPrint(int) instruction_simplifier (after) + /// CHECK-START: java.lang.String Main.$noinline$intToDoubleToIntPrint(int) instruction_simplifier (after) /// CHECK-DAG: TypeConversion /// CHECK-NOT: TypeConversion - public static String intToDoubleToIntPrint(int value) { + public static String $noinline$intToDoubleToIntPrint(int value) { + if (doThrow) { throw new Error(); } // Lossless conversion followed by a conversion back // with another use of the intermediate result. double d = (double) value; @@ -1326,55 +1389,58 @@ public class Main { return "d=" + d + ", i=" + i; } - /// CHECK-START: int Main.byteToDoubleToInt(byte) instruction_simplifier (before) + /// CHECK-START: int Main.$noinline$byteToDoubleToInt(byte) instruction_simplifier (before) /// CHECK-DAG: <<Arg:b\d+>> ParameterValue /// CHECK-DAG: <<Double:d\d+>> TypeConversion [<<Arg>>] /// CHECK-DAG: <<Int:i\d+>> TypeConversion [<<Double>>] /// CHECK-DAG: Return [<<Int>>] - /// CHECK-START: int Main.byteToDoubleToInt(byte) instruction_simplifier (after) + /// CHECK-START: int Main.$noinline$byteToDoubleToInt(byte) instruction_simplifier (after) /// CHECK-DAG: <<Arg:b\d+>> ParameterValue /// CHECK-DAG: Return [<<Arg>>] - /// CHECK-START: int Main.byteToDoubleToInt(byte) instruction_simplifier (after) + /// CHECK-START: int Main.$noinline$byteToDoubleToInt(byte) instruction_simplifier (after) /// CHECK-NOT: TypeConversion - public static int byteToDoubleToInt(byte value) { + public static int $noinline$byteToDoubleToInt(byte value) { + if (doThrow) { throw new Error(); } // Lossless conversion followed by another conversion, use implicit conversion. return (int) (double) value; } - /// CHECK-START: int Main.floatToDoubleToInt(float) instruction_simplifier (before) + /// CHECK-START: int Main.$noinline$floatToDoubleToInt(float) instruction_simplifier (before) /// CHECK-DAG: <<Arg:f\d+>> ParameterValue /// CHECK-DAG: <<Double:d\d+>> TypeConversion [<<Arg>>] /// CHECK-DAG: <<Int:i\d+>> TypeConversion [<<Double>>] /// CHECK-DAG: Return [<<Int>>] - /// CHECK-START: int Main.floatToDoubleToInt(float) instruction_simplifier (after) + /// CHECK-START: int Main.$noinline$floatToDoubleToInt(float) instruction_simplifier (after) /// CHECK-DAG: <<Arg:f\d+>> ParameterValue /// CHECK-DAG: <<Int:i\d+>> TypeConversion [<<Arg>>] /// CHECK-DAG: Return [<<Int>>] - /// CHECK-START: int Main.floatToDoubleToInt(float) instruction_simplifier (after) + /// CHECK-START: int Main.$noinline$floatToDoubleToInt(float) instruction_simplifier (after) /// CHECK-DAG: TypeConversion /// CHECK-NOT: TypeConversion - public static int floatToDoubleToInt(float value) { + public static int $noinline$floatToDoubleToInt(float value) { + if (doThrow) { throw new Error(); } // Lossless conversion followed by another conversion. return (int) (double) value; } - /// CHECK-START: java.lang.String Main.floatToDoubleToIntPrint(float) instruction_simplifier (before) + /// CHECK-START: java.lang.String Main.$noinline$floatToDoubleToIntPrint(float) instruction_simplifier (before) /// CHECK-DAG: <<Arg:f\d+>> ParameterValue /// CHECK-DAG: <<Double:d\d+>> TypeConversion [<<Arg>>] /// CHECK-DAG: {{i\d+}} TypeConversion [<<Double>>] - /// CHECK-START: java.lang.String Main.floatToDoubleToIntPrint(float) instruction_simplifier (after) + /// CHECK-START: java.lang.String Main.$noinline$floatToDoubleToIntPrint(float) instruction_simplifier (after) /// CHECK-DAG: <<Arg:f\d+>> ParameterValue /// CHECK-DAG: <<Double:d\d+>> TypeConversion [<<Arg>>] /// CHECK-DAG: {{i\d+}} TypeConversion [<<Double>>] - public static String floatToDoubleToIntPrint(float value) { + public static String $noinline$floatToDoubleToIntPrint(float value) { + if (doThrow) { throw new Error(); } // Lossless conversion followed by another conversion with // an extra use of the intermediate result. double d = (double) value; @@ -1382,176 +1448,186 @@ public class Main { return "d=" + d + ", i=" + i; } - /// CHECK-START: short Main.byteToDoubleToShort(byte) instruction_simplifier (before) + /// CHECK-START: short Main.$noinline$byteToDoubleToShort(byte) instruction_simplifier (before) /// CHECK-DAG: <<Arg:b\d+>> ParameterValue /// CHECK-DAG: <<Double:d\d+>> TypeConversion [<<Arg>>] /// CHECK-DAG: <<Int:i\d+>> TypeConversion [<<Double>>] /// CHECK-DAG: <<Short:s\d+>> TypeConversion [<<Int>>] /// CHECK-DAG: Return [<<Short>>] - /// CHECK-START: short Main.byteToDoubleToShort(byte) instruction_simplifier (after) + /// CHECK-START: short Main.$noinline$byteToDoubleToShort(byte) instruction_simplifier (after) /// CHECK-DAG: <<Arg:b\d+>> ParameterValue /// CHECK-DAG: Return [<<Arg>>] - /// CHECK-START: short Main.byteToDoubleToShort(byte) instruction_simplifier (after) + /// CHECK-START: short Main.$noinline$byteToDoubleToShort(byte) instruction_simplifier (after) /// CHECK-NOT: TypeConversion - public static short byteToDoubleToShort(byte value) { + public static short $noinline$byteToDoubleToShort(byte value) { + if (doThrow) { throw new Error(); } // Originally, this is byte->double->int->short. The first conversion is lossless, // so we merge this with the second one to byte->int which we omit as it's an implicit // conversion. Then we eliminate the resulting byte->short as an implicit conversion. return (short) (double) value; } - /// CHECK-START: short Main.charToDoubleToShort(char) instruction_simplifier (before) + /// CHECK-START: short Main.$noinline$charToDoubleToShort(char) instruction_simplifier (before) /// CHECK-DAG: <<Arg:c\d+>> ParameterValue /// CHECK-DAG: <<Double:d\d+>> TypeConversion [<<Arg>>] /// CHECK-DAG: <<Int:i\d+>> TypeConversion [<<Double>>] /// CHECK-DAG: <<Short:s\d+>> TypeConversion [<<Int>>] /// CHECK-DAG: Return [<<Short>>] - /// CHECK-START: short Main.charToDoubleToShort(char) instruction_simplifier (after) + /// CHECK-START: short Main.$noinline$charToDoubleToShort(char) instruction_simplifier (after) /// CHECK-DAG: <<Arg:c\d+>> ParameterValue /// CHECK-DAG: <<Short:s\d+>> TypeConversion [<<Arg>>] /// CHECK-DAG: Return [<<Short>>] - /// CHECK-START: short Main.charToDoubleToShort(char) instruction_simplifier (after) + /// CHECK-START: short Main.$noinline$charToDoubleToShort(char) instruction_simplifier (after) /// CHECK-DAG: TypeConversion /// CHECK-NOT: TypeConversion - public static short charToDoubleToShort(char value) { + public static short $noinline$charToDoubleToShort(char value) { + if (doThrow) { throw new Error(); } // Originally, this is char->double->int->short. The first conversion is lossless, // so we merge this with the second one to char->int which we omit as it's an implicit // conversion. Then we are left with the resulting char->short conversion. return (short) (double) value; } - /// CHECK-START: short Main.floatToIntToShort(float) instruction_simplifier (before) + /// CHECK-START: short Main.$noinline$floatToIntToShort(float) instruction_simplifier (before) /// CHECK-DAG: <<Arg:f\d+>> ParameterValue /// CHECK-DAG: <<Int:i\d+>> TypeConversion [<<Arg>>] /// CHECK-DAG: <<Short:s\d+>> TypeConversion [<<Int>>] /// CHECK-DAG: Return [<<Short>>] - /// CHECK-START: short Main.floatToIntToShort(float) instruction_simplifier (after) + /// CHECK-START: short Main.$noinline$floatToIntToShort(float) instruction_simplifier (after) /// CHECK-DAG: <<Arg:f\d+>> ParameterValue /// CHECK-DAG: <<Int:i\d+>> TypeConversion [<<Arg>>] /// CHECK-DAG: <<Short:s\d+>> TypeConversion [<<Int>>] /// CHECK-DAG: Return [<<Short>>] - public static short floatToIntToShort(float value) { + public static short $noinline$floatToIntToShort(float value) { + if (doThrow) { throw new Error(); } // Lossy FP to integral conversion followed by another conversion: no simplification. return (short) value; } - /// CHECK-START: int Main.intToFloatToInt(int) instruction_simplifier (before) + /// CHECK-START: int Main.$noinline$intToFloatToInt(int) instruction_simplifier (before) /// CHECK-DAG: <<Arg:i\d+>> ParameterValue /// CHECK-DAG: <<Float:f\d+>> TypeConversion [<<Arg>>] /// CHECK-DAG: <<Int:i\d+>> TypeConversion [<<Float>>] /// CHECK-DAG: Return [<<Int>>] - /// CHECK-START: int Main.intToFloatToInt(int) instruction_simplifier (after) + /// CHECK-START: int Main.$noinline$intToFloatToInt(int) instruction_simplifier (after) /// CHECK-DAG: <<Arg:i\d+>> ParameterValue /// CHECK-DAG: <<Float:f\d+>> TypeConversion [<<Arg>>] /// CHECK-DAG: <<Int:i\d+>> TypeConversion [<<Float>>] /// CHECK-DAG: Return [<<Int>>] - public static int intToFloatToInt(int value) { + public static int $noinline$intToFloatToInt(int value) { + if (doThrow) { throw new Error(); } // Lossy integral to FP conversion followed another conversion: no simplification. return (int) (float) value; } - /// CHECK-START: double Main.longToIntToDouble(long) instruction_simplifier (before) + /// CHECK-START: double Main.$noinline$longToIntToDouble(long) instruction_simplifier (before) /// CHECK-DAG: <<Arg:j\d+>> ParameterValue /// CHECK-DAG: <<Int:i\d+>> TypeConversion [<<Arg>>] /// CHECK-DAG: <<Double:d\d+>> TypeConversion [<<Int>>] /// CHECK-DAG: Return [<<Double>>] - /// CHECK-START: double Main.longToIntToDouble(long) instruction_simplifier (after) + /// CHECK-START: double Main.$noinline$longToIntToDouble(long) instruction_simplifier (after) /// CHECK-DAG: <<Arg:j\d+>> ParameterValue /// CHECK-DAG: <<Int:i\d+>> TypeConversion [<<Arg>>] /// CHECK-DAG: <<Double:d\d+>> TypeConversion [<<Int>>] /// CHECK-DAG: Return [<<Double>>] - public static double longToIntToDouble(long value) { + public static double $noinline$longToIntToDouble(long value) { + if (doThrow) { throw new Error(); } // Lossy long-to-int conversion followed an integral to FP conversion: no simplification. return (double) (int) value; } - /// CHECK-START: long Main.longToIntToLong(long) instruction_simplifier (before) + /// CHECK-START: long Main.$noinline$longToIntToLong(long) instruction_simplifier (before) /// CHECK-DAG: <<Arg:j\d+>> ParameterValue /// CHECK-DAG: <<Int:i\d+>> TypeConversion [<<Arg>>] /// CHECK-DAG: <<Long:j\d+>> TypeConversion [<<Int>>] /// CHECK-DAG: Return [<<Long>>] - /// CHECK-START: long Main.longToIntToLong(long) instruction_simplifier (after) + /// CHECK-START: long Main.$noinline$longToIntToLong(long) instruction_simplifier (after) /// CHECK-DAG: <<Arg:j\d+>> ParameterValue /// CHECK-DAG: <<Int:i\d+>> TypeConversion [<<Arg>>] /// CHECK-DAG: <<Long:j\d+>> TypeConversion [<<Int>>] /// CHECK-DAG: Return [<<Long>>] - public static long longToIntToLong(long value) { + public static long $noinline$longToIntToLong(long value) { + if (doThrow) { throw new Error(); } // Lossy long-to-int conversion followed an int-to-long conversion: no simplification. return (long) (int) value; } - /// CHECK-START: short Main.shortToCharToShort(short) instruction_simplifier (before) + /// CHECK-START: short Main.$noinline$shortToCharToShort(short) instruction_simplifier (before) /// CHECK-DAG: <<Arg:s\d+>> ParameterValue /// CHECK-DAG: <<Char:c\d+>> TypeConversion [<<Arg>>] /// CHECK-DAG: <<Short:s\d+>> TypeConversion [<<Char>>] /// CHECK-DAG: Return [<<Short>>] - /// CHECK-START: short Main.shortToCharToShort(short) instruction_simplifier (after) + /// CHECK-START: short Main.$noinline$shortToCharToShort(short) instruction_simplifier (after) /// CHECK-DAG: <<Arg:s\d+>> ParameterValue /// CHECK-DAG: Return [<<Arg>>] - public static short shortToCharToShort(short value) { + public static short $noinline$shortToCharToShort(short value) { + if (doThrow) { throw new Error(); } // Integral conversion followed by non-widening integral conversion to original type. return (short) (char) value; } - /// CHECK-START: int Main.shortToLongToInt(short) instruction_simplifier (before) + /// CHECK-START: int Main.$noinline$shortToLongToInt(short) instruction_simplifier (before) /// CHECK-DAG: <<Arg:s\d+>> ParameterValue /// CHECK-DAG: <<Long:j\d+>> TypeConversion [<<Arg>>] /// CHECK-DAG: <<Int:i\d+>> TypeConversion [<<Long>>] /// CHECK-DAG: Return [<<Int>>] - /// CHECK-START: int Main.shortToLongToInt(short) instruction_simplifier (after) + /// CHECK-START: int Main.$noinline$shortToLongToInt(short) instruction_simplifier (after) /// CHECK-DAG: <<Arg:s\d+>> ParameterValue /// CHECK-DAG: Return [<<Arg>>] - public static int shortToLongToInt(short value) { + public static int $noinline$shortToLongToInt(short value) { + if (doThrow) { throw new Error(); } // Integral conversion followed by non-widening integral conversion, use implicit conversion. return (int) (long) value; } - /// CHECK-START: byte Main.shortToCharToByte(short) instruction_simplifier (before) + /// CHECK-START: byte Main.$noinline$shortToCharToByte(short) instruction_simplifier (before) /// CHECK-DAG: <<Arg:s\d+>> ParameterValue /// CHECK-DAG: <<Char:c\d+>> TypeConversion [<<Arg>>] /// CHECK-DAG: <<Byte:b\d+>> TypeConversion [<<Char>>] /// CHECK-DAG: Return [<<Byte>>] - /// CHECK-START: byte Main.shortToCharToByte(short) instruction_simplifier (after) + /// CHECK-START: byte Main.$noinline$shortToCharToByte(short) instruction_simplifier (after) /// CHECK-DAG: <<Arg:s\d+>> ParameterValue /// CHECK-DAG: <<Byte:b\d+>> TypeConversion [<<Arg>>] /// CHECK-DAG: Return [<<Byte>>] - public static byte shortToCharToByte(short value) { + public static byte $noinline$shortToCharToByte(short value) { + if (doThrow) { throw new Error(); } // Integral conversion followed by non-widening integral conversion losing bits // from the original type. Simplify to use only one conversion. return (byte) (char) value; } - /// CHECK-START: java.lang.String Main.shortToCharToBytePrint(short) instruction_simplifier (before) + /// CHECK-START: java.lang.String Main.$noinline$shortToCharToBytePrint(short) instruction_simplifier (before) /// CHECK-DAG: <<Arg:s\d+>> ParameterValue /// CHECK-DAG: <<Char:c\d+>> TypeConversion [<<Arg>>] /// CHECK-DAG: {{b\d+}} TypeConversion [<<Char>>] - /// CHECK-START: java.lang.String Main.shortToCharToBytePrint(short) instruction_simplifier (after) + /// CHECK-START: java.lang.String Main.$noinline$shortToCharToBytePrint(short) instruction_simplifier (after) /// CHECK-DAG: <<Arg:s\d+>> ParameterValue /// CHECK-DAG: <<Char:c\d+>> TypeConversion [<<Arg>>] /// CHECK-DAG: {{b\d+}} TypeConversion [<<Char>>] - public static String shortToCharToBytePrint(short value) { + public static String $noinline$shortToCharToBytePrint(short value) { + if (doThrow) { throw new Error(); } // Integral conversion followed by non-widening integral conversion losing bits // from the original type with an extra use of the intermediate result. char c = (char) value; @@ -1559,7 +1635,7 @@ public class Main { return "c=" + ((int) c) + ", b=" + ((int) b); // implicit conversions. } - /// CHECK-START: byte Main.longAnd0xffToByte(long) instruction_simplifier (before) + /// CHECK-START: byte Main.$noinline$longAnd0xffToByte(long) instruction_simplifier (before) /// CHECK-DAG: <<Arg:j\d+>> ParameterValue /// CHECK-DAG: <<Mask:j\d+>> LongConstant 255 /// CHECK-DAG: <<And:j\d+>> And [<<Mask>>,<<Arg>>] @@ -1567,58 +1643,61 @@ public class Main { /// CHECK-DAG: <<Byte:b\d+>> TypeConversion [<<Int>>] /// CHECK-DAG: Return [<<Byte>>] - /// CHECK-START: byte Main.longAnd0xffToByte(long) instruction_simplifier (after) + /// CHECK-START: byte Main.$noinline$longAnd0xffToByte(long) instruction_simplifier (after) /// CHECK-DAG: <<Arg:j\d+>> ParameterValue /// CHECK-DAG: <<Byte:b\d+>> TypeConversion [<<Arg>>] /// CHECK-DAG: Return [<<Byte>>] - /// CHECK-START: byte Main.longAnd0xffToByte(long) instruction_simplifier (after) + /// CHECK-START: byte Main.$noinline$longAnd0xffToByte(long) instruction_simplifier (after) /// CHECK-NOT: And - public static byte longAnd0xffToByte(long value) { + public static byte $noinline$longAnd0xffToByte(long value) { + if (doThrow) { throw new Error(); } return (byte) (value & 0xff); } - /// CHECK-START: char Main.intAnd0x1ffffToChar(int) instruction_simplifier (before) + /// CHECK-START: char Main.$noinline$intAnd0x1ffffToChar(int) instruction_simplifier (before) /// CHECK-DAG: <<Arg:i\d+>> ParameterValue /// CHECK-DAG: <<Mask:i\d+>> IntConstant 131071 /// CHECK-DAG: <<And:i\d+>> And [<<Mask>>,<<Arg>>] /// CHECK-DAG: <<Char:c\d+>> TypeConversion [<<And>>] /// CHECK-DAG: Return [<<Char>>] - /// CHECK-START: char Main.intAnd0x1ffffToChar(int) instruction_simplifier (after) + /// CHECK-START: char Main.$noinline$intAnd0x1ffffToChar(int) instruction_simplifier (after) /// CHECK-DAG: <<Arg:i\d+>> ParameterValue /// CHECK-DAG: <<Char:c\d+>> TypeConversion [<<Arg>>] /// CHECK-DAG: Return [<<Char>>] - /// CHECK-START: char Main.intAnd0x1ffffToChar(int) instruction_simplifier (after) + /// CHECK-START: char Main.$noinline$intAnd0x1ffffToChar(int) instruction_simplifier (after) /// CHECK-NOT: And - public static char intAnd0x1ffffToChar(int value) { + public static char $noinline$intAnd0x1ffffToChar(int value) { + if (doThrow) { throw new Error(); } // Keeping all significant bits and one more. return (char) (value & 0x1ffff); } - /// CHECK-START: short Main.intAnd0x17fffToShort(int) instruction_simplifier (before) + /// CHECK-START: short Main.$noinline$intAnd0x17fffToShort(int) instruction_simplifier (before) /// CHECK-DAG: <<Arg:i\d+>> ParameterValue /// CHECK-DAG: <<Mask:i\d+>> IntConstant 98303 /// CHECK-DAG: <<And:i\d+>> And [<<Mask>>,<<Arg>>] /// CHECK-DAG: <<Short:s\d+>> TypeConversion [<<And>>] /// CHECK-DAG: Return [<<Short>>] - /// CHECK-START: short Main.intAnd0x17fffToShort(int) instruction_simplifier (after) + /// CHECK-START: short Main.$noinline$intAnd0x17fffToShort(int) instruction_simplifier (after) /// CHECK-DAG: <<Arg:i\d+>> ParameterValue /// CHECK-DAG: <<Mask:i\d+>> IntConstant 98303 /// CHECK-DAG: <<And:i\d+>> And [<<Mask>>,<<Arg>>] /// CHECK-DAG: <<Short:s\d+>> TypeConversion [<<And>>] /// CHECK-DAG: Return [<<Short>>] - public static short intAnd0x17fffToShort(int value) { + public static short $noinline$intAnd0x17fffToShort(int value) { + if (doThrow) { throw new Error(); } // No simplification: clearing a significant bit. return (short) (value & 0x17fff); } - /// CHECK-START: double Main.shortAnd0xffffToShortToDouble(short) instruction_simplifier (before) + /// CHECK-START: double Main.$noinline$shortAnd0xffffToShortToDouble(short) instruction_simplifier (before) /// CHECK-DAG: <<Arg:s\d+>> ParameterValue /// CHECK-DAG: <<Mask:i\d+>> IntConstant 65535 /// CHECK-DAG: <<And:i\d+>> And [<<Mask>>,<<Arg>>] @@ -1626,45 +1705,49 @@ public class Main { /// CHECK-DAG: <<Double:d\d+>> TypeConversion [<<Same>>] /// CHECK-DAG: Return [<<Double>>] - /// CHECK-START: double Main.shortAnd0xffffToShortToDouble(short) instruction_simplifier (after) + /// CHECK-START: double Main.$noinline$shortAnd0xffffToShortToDouble(short) instruction_simplifier (after) /// CHECK-DAG: <<Arg:s\d+>> ParameterValue /// CHECK-DAG: <<Double:d\d+>> TypeConversion [<<Arg>>] /// CHECK-DAG: Return [<<Double>>] - public static double shortAnd0xffffToShortToDouble(short value) { + public static double $noinline$shortAnd0xffffToShortToDouble(short value) { + if (doThrow) { throw new Error(); } short same = (short) (value & 0xffff); return (double) same; } - /// CHECK-START: int Main.intReverseCondition(int) instruction_simplifier (before) + /// CHECK-START: int Main.$noinline$intReverseCondition(int) instruction_simplifier (before) /// CHECK-DAG: <<Arg:i\d+>> ParameterValue /// CHECK-DAG: <<Const42:i\d+>> IntConstant 42 /// CHECK-DAG: <<LE:z\d+>> LessThanOrEqual [<<Const42>>,<<Arg>>] - /// CHECK-START: int Main.intReverseCondition(int) instruction_simplifier (after) + /// CHECK-START: int Main.$noinline$intReverseCondition(int) instruction_simplifier (after) /// CHECK-DAG: <<Arg:i\d+>> ParameterValue /// CHECK-DAG: <<Const42:i\d+>> IntConstant 42 /// CHECK-DAG: <<GE:z\d+>> GreaterThanOrEqual [<<Arg>>,<<Const42>>] - public static int intReverseCondition(int i) { + public static int $noinline$intReverseCondition(int i) { + if (doThrow) { throw new Error(); } return (42 > i) ? 13 : 54; } - /// CHECK-START: int Main.intReverseConditionNaN(int) instruction_simplifier (before) + /// CHECK-START: int Main.$noinline$intReverseConditionNaN(int) instruction_simplifier (before) /// CHECK-DAG: <<Const42:d\d+>> DoubleConstant 42 /// CHECK-DAG: <<Result:d\d+>> InvokeStaticOrDirect /// CHECK-DAG: <<CMP:i\d+>> Compare [<<Const42>>,<<Result>>] - /// CHECK-START: int Main.intReverseConditionNaN(int) instruction_simplifier (after) + /// CHECK-START: int Main.$noinline$intReverseConditionNaN(int) instruction_simplifier (after) /// CHECK-DAG: <<Const42:d\d+>> DoubleConstant 42 /// CHECK-DAG: <<Result:d\d+>> InvokeStaticOrDirect /// CHECK-DAG: <<EQ:z\d+>> Equal [<<Result>>,<<Const42>>] - public static int intReverseConditionNaN(int i) { + public static int $noinline$intReverseConditionNaN(int i) { + if (doThrow) { throw new Error(); } return (42 != Math.sqrt(i)) ? 13 : 54; } - public static int runSmaliTest(String name, boolean input) { + public static int $noinline$runSmaliTest(String name, boolean input) { + if (doThrow) { throw new Error(); } try { Class<?> c = Class.forName("SmaliTests"); Method m = c.getMethod(name, new Class[] { boolean.class }); @@ -1674,155 +1757,270 @@ public class Main { } } + /// CHECK-START: int Main.$noinline$intUnnecessaryShiftMasking(int, int) instruction_simplifier (before) + /// CHECK: <<Value:i\d+>> ParameterValue + /// CHECK: <<Shift:i\d+>> ParameterValue + /// CHECK-DAG: <<Const31:i\d+>> IntConstant 31 + /// CHECK-DAG: <<And:i\d+>> And [<<Shift>>,<<Const31>>] + /// CHECK-DAG: <<Shl:i\d+>> Shl [<<Value>>,<<And>>] + /// CHECK-DAG: Return [<<Shl>>] + + /// CHECK-START: int Main.$noinline$intUnnecessaryShiftMasking(int, int) instruction_simplifier (after) + /// CHECK: <<Value:i\d+>> ParameterValue + /// CHECK: <<Shift:i\d+>> ParameterValue + /// CHECK-DAG: <<Shl:i\d+>> Shl [<<Value>>,<<Shift>>] + /// CHECK-DAG: Return [<<Shl>>] + + public static int $noinline$intUnnecessaryShiftMasking(int value, int shift) { + if (doThrow) { throw new Error(); } + return value << (shift & 31); + } + + /// CHECK-START: long Main.$noinline$longUnnecessaryShiftMasking(long, int) instruction_simplifier (before) + /// CHECK: <<Value:j\d+>> ParameterValue + /// CHECK: <<Shift:i\d+>> ParameterValue + /// CHECK-DAG: <<Const63:i\d+>> IntConstant 63 + /// CHECK-DAG: <<And:i\d+>> And [<<Shift>>,<<Const63>>] + /// CHECK-DAG: <<Shr:j\d+>> Shr [<<Value>>,<<And>>] + /// CHECK-DAG: Return [<<Shr>>] + + /// CHECK-START: long Main.$noinline$longUnnecessaryShiftMasking(long, int) instruction_simplifier (after) + /// CHECK: <<Value:j\d+>> ParameterValue + /// CHECK: <<Shift:i\d+>> ParameterValue + /// CHECK-DAG: <<Shr:j\d+>> Shr [<<Value>>,<<Shift>>] + /// CHECK-DAG: Return [<<Shr>>] + + public static long $noinline$longUnnecessaryShiftMasking(long value, int shift) { + if (doThrow) { throw new Error(); } + return value >> (shift & 63); + } + + /// CHECK-START: int Main.$noinline$intUnnecessaryWiderShiftMasking(int, int) instruction_simplifier (before) + /// CHECK: <<Value:i\d+>> ParameterValue + /// CHECK: <<Shift:i\d+>> ParameterValue + /// CHECK-DAG: <<Const255:i\d+>> IntConstant 255 + /// CHECK-DAG: <<And:i\d+>> And [<<Shift>>,<<Const255>>] + /// CHECK-DAG: <<UShr:i\d+>> UShr [<<Value>>,<<And>>] + /// CHECK-DAG: Return [<<UShr>>] + + /// CHECK-START: int Main.$noinline$intUnnecessaryWiderShiftMasking(int, int) instruction_simplifier (after) + /// CHECK: <<Value:i\d+>> ParameterValue + /// CHECK: <<Shift:i\d+>> ParameterValue + /// CHECK-DAG: <<UShr:i\d+>> UShr [<<Value>>,<<Shift>>] + /// CHECK-DAG: Return [<<UShr>>] + + public static int $noinline$intUnnecessaryWiderShiftMasking(int value, int shift) { + if (doThrow) { throw new Error(); } + return value >>> (shift & 0xff); + } + + /// CHECK-START: long Main.$noinline$longSmallerShiftMasking(long, int) instruction_simplifier (before) + /// CHECK: <<Value:j\d+>> ParameterValue + /// CHECK: <<Shift:i\d+>> ParameterValue + /// CHECK-DAG: <<Const3:i\d+>> IntConstant 3 + /// CHECK-DAG: <<And:i\d+>> And [<<Shift>>,<<Const3>>] + /// CHECK-DAG: <<Shl:j\d+>> Shl [<<Value>>,<<And>>] + /// CHECK-DAG: Return [<<Shl>>] + + /// CHECK-START: long Main.$noinline$longSmallerShiftMasking(long, int) instruction_simplifier (after) + /// CHECK: <<Value:j\d+>> ParameterValue + /// CHECK: <<Shift:i\d+>> ParameterValue + /// CHECK-DAG: <<Const3:i\d+>> IntConstant 3 + /// CHECK-DAG: <<And:i\d+>> And [<<Shift>>,<<Const3>>] + /// CHECK-DAG: <<Shl:j\d+>> Shl [<<Value>>,<<And>>] + /// CHECK-DAG: Return [<<Shl>>] + + public static long $noinline$longSmallerShiftMasking(long value, int shift) { + if (doThrow) { throw new Error(); } + return value << (shift & 3); + } + + /// CHECK-START: int Main.$noinline$otherUseOfUnnecessaryShiftMasking(int, int) instruction_simplifier (before) + /// CHECK: <<Value:i\d+>> ParameterValue + /// CHECK: <<Shift:i\d+>> ParameterValue + /// CHECK-DAG: <<Const31:i\d+>> IntConstant 31 + /// CHECK-DAG: <<And:i\d+>> And [<<Shift>>,<<Const31>>] + /// CHECK-DAG: <<Shr:i\d+>> Shr [<<Value>>,<<And>>] + /// CHECK-DAG: <<Add:i\d+>> Add [<<Shr>>,<<And>>] + /// CHECK-DAG: Return [<<Add>>] + + /// CHECK-START: int Main.$noinline$otherUseOfUnnecessaryShiftMasking(int, int) instruction_simplifier (after) + /// CHECK: <<Value:i\d+>> ParameterValue + /// CHECK: <<Shift:i\d+>> ParameterValue + /// CHECK-DAG: <<Const31:i\d+>> IntConstant 31 + /// CHECK-DAG: <<And:i\d+>> And [<<Shift>>,<<Const31>>] + /// CHECK-DAG: <<Shr:i\d+>> Shr [<<Value>>,<<Shift>>] + /// CHECK-DAG: <<Add:i\d+>> Add [<<Shr>>,<<And>>] + /// CHECK-DAG: Return [<<Add>>] + + public static int $noinline$otherUseOfUnnecessaryShiftMasking(int value, int shift) { + if (doThrow) { throw new Error(); } + int temp = shift & 31; + return (value >> temp) + temp; + } + public static void main(String[] args) { int arg = 123456; - assertLongEquals(Add0(arg), arg); - assertIntEquals(AndAllOnes(arg), arg); - assertLongEquals(Div1(arg), arg); - assertIntEquals(DivN1(arg), -arg); - assertLongEquals(Mul1(arg), arg); - assertIntEquals(MulN1(arg), -arg); - assertLongEquals(MulPowerOfTwo128(arg), (128 * arg)); - assertIntEquals(Or0(arg), arg); - assertLongEquals(OrSame(arg), arg); - assertIntEquals(Shl0(arg), arg); - assertLongEquals(Shr0(arg), arg); - assertLongEquals(Shr64(arg), arg); - assertLongEquals(Sub0(arg), arg); - assertIntEquals(SubAliasNeg(arg), -arg); - assertLongEquals(UShr0(arg), arg); - assertIntEquals(Xor0(arg), arg); - assertIntEquals(XorAllOnes(arg), ~arg); - assertIntEquals(AddNegs1(arg, arg + 1), -(arg + arg + 1)); - assertIntEquals(AddNegs2(arg, arg + 1), -(arg + arg + 1)); - assertLongEquals(AddNegs3(arg, arg + 1), -(2 * arg + 1)); - assertLongEquals(AddNeg1(arg, arg + 1), 1); - assertLongEquals(AddNeg2(arg, arg + 1), -1); - assertLongEquals(NegNeg1(arg), arg); - assertIntEquals(NegNeg2(arg), 0); - assertLongEquals(NegNeg3(arg), arg); - assertIntEquals(NegSub1(arg, arg + 1), 1); - assertIntEquals(NegSub2(arg, arg + 1), 1); - assertLongEquals(NotNot1(arg), arg); - assertIntEquals(NotNot2(arg), -1); - assertIntEquals(SubNeg1(arg, arg + 1), -(arg + arg + 1)); - assertIntEquals(SubNeg2(arg, arg + 1), -(arg + arg + 1)); - assertLongEquals(SubNeg3(arg, arg + 1), -(2 * arg + 1)); - assertBooleanEquals(EqualBoolVsIntConst(true), true); - assertBooleanEquals(EqualBoolVsIntConst(true), true); - assertBooleanEquals(NotEqualBoolVsIntConst(false), false); - assertBooleanEquals(NotEqualBoolVsIntConst(false), false); - assertBooleanEquals(NotNotBool(true), true); - assertBooleanEquals(NotNotBool(false), false); - assertFloatEquals(Div2(100.0f), 50.0f); - assertDoubleEquals(Div2(150.0), 75.0); - assertFloatEquals(DivMP25(100.0f), -400.0f); - assertDoubleEquals(DivMP25(150.0), -600.0); - assertIntEquals(UShr28And15(0xc1234567), 0xc); - assertLongEquals(UShr60And15(0xc123456787654321L), 0xcL); - assertIntEquals(UShr28And7(0xc1234567), 0x4); - assertLongEquals(UShr60And7(0xc123456787654321L), 0x4L); - assertIntEquals(Shr24And255(0xc1234567), 0xc1); - assertLongEquals(Shr56And255(0xc123456787654321L), 0xc1L); - assertIntEquals(Shr24And127(0xc1234567), 0x41); - assertLongEquals(Shr56And127(0xc123456787654321L), 0x41L); - assertIntEquals(0, mulPow2Plus1(0)); - assertIntEquals(9, mulPow2Plus1(1)); - assertIntEquals(18, mulPow2Plus1(2)); - assertIntEquals(900, mulPow2Plus1(100)); - assertIntEquals(111105, mulPow2Plus1(12345)); - assertLongEquals(0, mulPow2Minus1(0)); - assertLongEquals(31, mulPow2Minus1(1)); - assertLongEquals(62, mulPow2Minus1(2)); - assertLongEquals(3100, mulPow2Minus1(100)); - assertLongEquals(382695, mulPow2Minus1(12345)); + assertLongEquals(arg, $noinline$Add0(arg)); + assertIntEquals(arg, $noinline$AndAllOnes(arg)); + assertLongEquals(arg, $noinline$Div1(arg)); + assertIntEquals(-arg, $noinline$DivN1(arg)); + assertLongEquals(arg, $noinline$Mul1(arg)); + assertIntEquals(-arg, $noinline$MulN1(arg)); + assertLongEquals((128 * arg), $noinline$MulPowerOfTwo128(arg)); + assertIntEquals(arg, $noinline$Or0(arg)); + assertLongEquals(arg, $noinline$OrSame(arg)); + assertIntEquals(arg, $noinline$Shl0(arg)); + assertLongEquals(arg, $noinline$Shr0(arg)); + assertLongEquals(arg, $noinline$Shr64(arg)); + assertLongEquals(arg, $noinline$Sub0(arg)); + assertIntEquals(-arg, $noinline$SubAliasNeg(arg)); + assertLongEquals(arg, $noinline$UShr0(arg)); + assertIntEquals(arg, $noinline$Xor0(arg)); + assertIntEquals(~arg, $noinline$XorAllOnes(arg)); + assertIntEquals(-(arg + arg + 1), $noinline$AddNegs1(arg, arg + 1)); + assertIntEquals(-(arg + arg + 1), $noinline$AddNegs2(arg, arg + 1)); + assertLongEquals(-(2 * arg + 1), $noinline$AddNegs3(arg, arg + 1)); + assertLongEquals(1, $noinline$AddNeg1(arg, arg + 1)); + assertLongEquals(-1, $noinline$AddNeg2(arg, arg + 1)); + assertLongEquals(arg, $noinline$NegNeg1(arg)); + assertIntEquals(0, $noinline$NegNeg2(arg)); + assertLongEquals(arg, $noinline$NegNeg3(arg)); + assertIntEquals(1, $noinline$NegSub1(arg, arg + 1)); + assertIntEquals(1, $noinline$NegSub2(arg, arg + 1)); + assertLongEquals(arg, $noinline$NotNot1(arg)); + assertIntEquals(-1, $noinline$NotNot2(arg)); + assertIntEquals(-(arg + arg + 1), $noinline$SubNeg1(arg, arg + 1)); + assertIntEquals(-(arg + arg + 1), $noinline$SubNeg2(arg, arg + 1)); + assertLongEquals(-(2 * arg + 1), $noinline$SubNeg3(arg, arg + 1)); + assertBooleanEquals(true, $noinline$EqualBoolVsIntConst(true)); + assertBooleanEquals(true, $noinline$EqualBoolVsIntConst(true)); + assertBooleanEquals(false, $noinline$NotEqualBoolVsIntConst(false)); + assertBooleanEquals(false, $noinline$NotEqualBoolVsIntConst(false)); + assertBooleanEquals(true, $noinline$NotNotBool(true)); + assertBooleanEquals(false, $noinline$NotNotBool(false)); + assertFloatEquals(50.0f, $noinline$Div2(100.0f)); + assertDoubleEquals(75.0, $noinline$Div2(150.0)); + assertFloatEquals(-400.0f, $noinline$DivMP25(100.0f)); + assertDoubleEquals(-600.0, $noinline$DivMP25(150.0)); + assertIntEquals(0xc, $noinline$UShr28And15(0xc1234567)); + assertLongEquals(0xcL, $noinline$UShr60And15(0xc123456787654321L)); + assertIntEquals(0x4, $noinline$UShr28And7(0xc1234567)); + assertLongEquals(0x4L, $noinline$UShr60And7(0xc123456787654321L)); + assertIntEquals(0xc1, $noinline$Shr24And255(0xc1234567)); + assertLongEquals(0xc1L, $noinline$Shr56And255(0xc123456787654321L)); + assertIntEquals(0x41, $noinline$Shr24And127(0xc1234567)); + assertLongEquals(0x41L, $noinline$Shr56And127(0xc123456787654321L)); + assertIntEquals(0, $noinline$mulPow2Plus1(0)); + assertIntEquals(9, $noinline$mulPow2Plus1(1)); + assertIntEquals(18, $noinline$mulPow2Plus1(2)); + assertIntEquals(900, $noinline$mulPow2Plus1(100)); + assertIntEquals(111105, $noinline$mulPow2Plus1(12345)); + assertLongEquals(0, $noinline$mulPow2Minus1(0)); + assertLongEquals(31, $noinline$mulPow2Minus1(1)); + assertLongEquals(62, $noinline$mulPow2Minus1(2)); + assertLongEquals(3100, $noinline$mulPow2Minus1(100)); + assertLongEquals(382695, $noinline$mulPow2Minus1(12345)); booleanField = false; - assertIntEquals(booleanFieldNotEqualOne(), 54); - assertIntEquals(booleanFieldEqualZero(), 54); + assertIntEquals($noinline$booleanFieldNotEqualOne(), 54); + assertIntEquals($noinline$booleanFieldEqualZero(), 54); booleanField = true; - assertIntEquals(booleanFieldNotEqualOne(), 13); - assertIntEquals(booleanFieldEqualZero(), 13); - assertIntEquals(intConditionNotEqualOne(6), 54); - assertIntEquals(intConditionNotEqualOne(43), 13); - assertIntEquals(intConditionEqualZero(6), 54); - assertIntEquals(intConditionEqualZero(43), 13); - assertIntEquals(floatConditionNotEqualOne(6.0f), 54); - assertIntEquals(floatConditionNotEqualOne(43.0f), 13); - assertIntEquals(doubleConditionEqualZero(6.0), 54); - assertIntEquals(doubleConditionEqualZero(43.0), 13); - - assertIntEquals(1234567, intToDoubleToInt(1234567)); - assertIntEquals(Integer.MIN_VALUE, intToDoubleToInt(Integer.MIN_VALUE)); - assertIntEquals(Integer.MAX_VALUE, intToDoubleToInt(Integer.MAX_VALUE)); - assertStringEquals("d=7654321.0, i=7654321", intToDoubleToIntPrint(7654321)); - assertIntEquals(12, byteToDoubleToInt((byte) 12)); - assertIntEquals(Byte.MIN_VALUE, byteToDoubleToInt(Byte.MIN_VALUE)); - assertIntEquals(Byte.MAX_VALUE, byteToDoubleToInt(Byte.MAX_VALUE)); - assertIntEquals(11, floatToDoubleToInt(11.3f)); - assertStringEquals("d=12.25, i=12", floatToDoubleToIntPrint(12.25f)); - assertIntEquals(123, byteToDoubleToShort((byte) 123)); - assertIntEquals(Byte.MIN_VALUE, byteToDoubleToShort(Byte.MIN_VALUE)); - assertIntEquals(Byte.MAX_VALUE, byteToDoubleToShort(Byte.MAX_VALUE)); - assertIntEquals(1234, charToDoubleToShort((char) 1234)); - assertIntEquals(Character.MIN_VALUE, charToDoubleToShort(Character.MIN_VALUE)); - assertIntEquals(/* sign-extended */ -1, charToDoubleToShort(Character.MAX_VALUE)); - assertIntEquals(12345, floatToIntToShort(12345.75f)); - assertIntEquals(Short.MAX_VALUE, floatToIntToShort((float)(Short.MIN_VALUE - 1))); - assertIntEquals(Short.MIN_VALUE, floatToIntToShort((float)(Short.MAX_VALUE + 1))); - assertIntEquals(-54321, intToFloatToInt(-54321)); - assertDoubleEquals((double) 0x12345678, longToIntToDouble(0x1234567812345678L)); - assertDoubleEquals(0.0, longToIntToDouble(Long.MIN_VALUE)); - assertDoubleEquals(-1.0, longToIntToDouble(Long.MAX_VALUE)); - assertLongEquals(0x0000000012345678L, longToIntToLong(0x1234567812345678L)); - assertLongEquals(0xffffffff87654321L, longToIntToLong(0x1234567887654321L)); - assertLongEquals(0L, longToIntToLong(Long.MIN_VALUE)); - assertLongEquals(-1L, longToIntToLong(Long.MAX_VALUE)); - assertIntEquals((short) -5678, shortToCharToShort((short) -5678)); - assertIntEquals(Short.MIN_VALUE, shortToCharToShort(Short.MIN_VALUE)); - assertIntEquals(Short.MAX_VALUE, shortToCharToShort(Short.MAX_VALUE)); - assertIntEquals(5678, shortToLongToInt((short) 5678)); - assertIntEquals(Short.MIN_VALUE, shortToLongToInt(Short.MIN_VALUE)); - assertIntEquals(Short.MAX_VALUE, shortToLongToInt(Short.MAX_VALUE)); - assertIntEquals(0x34, shortToCharToByte((short) 0x1234)); - assertIntEquals(-0x10, shortToCharToByte((short) 0x12f0)); - assertIntEquals(0, shortToCharToByte(Short.MIN_VALUE)); - assertIntEquals(-1, shortToCharToByte(Short.MAX_VALUE)); - assertStringEquals("c=1025, b=1", shortToCharToBytePrint((short) 1025)); - assertStringEquals("c=1023, b=-1", shortToCharToBytePrint((short) 1023)); - assertStringEquals("c=65535, b=-1", shortToCharToBytePrint((short) -1)); - - assertIntEquals(0x21, longAnd0xffToByte(0x1234432112344321L)); - assertIntEquals(0, longAnd0xffToByte(Long.MIN_VALUE)); - assertIntEquals(-1, longAnd0xffToByte(Long.MAX_VALUE)); - assertIntEquals(0x1234, intAnd0x1ffffToChar(0x43211234)); - assertIntEquals(0, intAnd0x1ffffToChar(Integer.MIN_VALUE)); - assertIntEquals(Character.MAX_VALUE, intAnd0x1ffffToChar(Integer.MAX_VALUE)); - assertIntEquals(0x4321, intAnd0x17fffToShort(0x87654321)); - assertIntEquals(0x0888, intAnd0x17fffToShort(0x88888888)); - assertIntEquals(0, intAnd0x17fffToShort(Integer.MIN_VALUE)); - assertIntEquals(Short.MAX_VALUE, intAnd0x17fffToShort(Integer.MAX_VALUE)); - - assertDoubleEquals(0.0, shortAnd0xffffToShortToDouble((short) 0)); - assertDoubleEquals(1.0, shortAnd0xffffToShortToDouble((short) 1)); - assertDoubleEquals(-2.0, shortAnd0xffffToShortToDouble((short) -2)); - assertDoubleEquals(12345.0, shortAnd0xffffToShortToDouble((short) 12345)); - assertDoubleEquals((double)Short.MAX_VALUE, shortAnd0xffffToShortToDouble(Short.MAX_VALUE)); - assertDoubleEquals((double)Short.MIN_VALUE, shortAnd0xffffToShortToDouble(Short.MIN_VALUE)); - - assertIntEquals(intReverseCondition(41), 13); - assertIntEquals(intReverseConditionNaN(-5), 13); + assertIntEquals(13, $noinline$booleanFieldNotEqualOne()); + assertIntEquals(13, $noinline$booleanFieldEqualZero()); + assertIntEquals(54, $noinline$intConditionNotEqualOne(6)); + assertIntEquals(13, $noinline$intConditionNotEqualOne(43)); + assertIntEquals(54, $noinline$intConditionEqualZero(6)); + assertIntEquals(13, $noinline$intConditionEqualZero(43)); + assertIntEquals(54, $noinline$floatConditionNotEqualOne(6.0f)); + assertIntEquals(13, $noinline$floatConditionNotEqualOne(43.0f)); + assertIntEquals(54, $noinline$doubleConditionEqualZero(6.0)); + assertIntEquals(13, $noinline$doubleConditionEqualZero(43.0)); + + assertIntEquals(1234567, $noinline$intToDoubleToInt(1234567)); + assertIntEquals(Integer.MIN_VALUE, $noinline$intToDoubleToInt(Integer.MIN_VALUE)); + assertIntEquals(Integer.MAX_VALUE, $noinline$intToDoubleToInt(Integer.MAX_VALUE)); + assertStringEquals("d=7654321.0, i=7654321", $noinline$intToDoubleToIntPrint(7654321)); + assertIntEquals(12, $noinline$byteToDoubleToInt((byte) 12)); + assertIntEquals(Byte.MIN_VALUE, $noinline$byteToDoubleToInt(Byte.MIN_VALUE)); + assertIntEquals(Byte.MAX_VALUE, $noinline$byteToDoubleToInt(Byte.MAX_VALUE)); + assertIntEquals(11, $noinline$floatToDoubleToInt(11.3f)); + assertStringEquals("d=12.25, i=12", $noinline$floatToDoubleToIntPrint(12.25f)); + assertIntEquals(123, $noinline$byteToDoubleToShort((byte) 123)); + assertIntEquals(Byte.MIN_VALUE, $noinline$byteToDoubleToShort(Byte.MIN_VALUE)); + assertIntEquals(Byte.MAX_VALUE, $noinline$byteToDoubleToShort(Byte.MAX_VALUE)); + assertIntEquals(1234, $noinline$charToDoubleToShort((char) 1234)); + assertIntEquals(Character.MIN_VALUE, $noinline$charToDoubleToShort(Character.MIN_VALUE)); + assertIntEquals(/* sign-extended */ -1, $noinline$charToDoubleToShort(Character.MAX_VALUE)); + assertIntEquals(12345, $noinline$floatToIntToShort(12345.75f)); + assertIntEquals(Short.MAX_VALUE, $noinline$floatToIntToShort((float)(Short.MIN_VALUE - 1))); + assertIntEquals(Short.MIN_VALUE, $noinline$floatToIntToShort((float)(Short.MAX_VALUE + 1))); + assertIntEquals(-54321, $noinline$intToFloatToInt(-54321)); + assertDoubleEquals((double) 0x12345678, $noinline$longToIntToDouble(0x1234567812345678L)); + assertDoubleEquals(0.0, $noinline$longToIntToDouble(Long.MIN_VALUE)); + assertDoubleEquals(-1.0, $noinline$longToIntToDouble(Long.MAX_VALUE)); + assertLongEquals(0x0000000012345678L, $noinline$longToIntToLong(0x1234567812345678L)); + assertLongEquals(0xffffffff87654321L, $noinline$longToIntToLong(0x1234567887654321L)); + assertLongEquals(0L, $noinline$longToIntToLong(Long.MIN_VALUE)); + assertLongEquals(-1L, $noinline$longToIntToLong(Long.MAX_VALUE)); + assertIntEquals((short) -5678, $noinline$shortToCharToShort((short) -5678)); + assertIntEquals(Short.MIN_VALUE, $noinline$shortToCharToShort(Short.MIN_VALUE)); + assertIntEquals(Short.MAX_VALUE, $noinline$shortToCharToShort(Short.MAX_VALUE)); + assertIntEquals(5678, $noinline$shortToLongToInt((short) 5678)); + assertIntEquals(Short.MIN_VALUE, $noinline$shortToLongToInt(Short.MIN_VALUE)); + assertIntEquals(Short.MAX_VALUE, $noinline$shortToLongToInt(Short.MAX_VALUE)); + assertIntEquals(0x34, $noinline$shortToCharToByte((short) 0x1234)); + assertIntEquals(-0x10, $noinline$shortToCharToByte((short) 0x12f0)); + assertIntEquals(0, $noinline$shortToCharToByte(Short.MIN_VALUE)); + assertIntEquals(-1, $noinline$shortToCharToByte(Short.MAX_VALUE)); + assertStringEquals("c=1025, b=1", $noinline$shortToCharToBytePrint((short) 1025)); + assertStringEquals("c=1023, b=-1", $noinline$shortToCharToBytePrint((short) 1023)); + assertStringEquals("c=65535, b=-1", $noinline$shortToCharToBytePrint((short) -1)); + + assertIntEquals(0x21, $noinline$longAnd0xffToByte(0x1234432112344321L)); + assertIntEquals(0, $noinline$longAnd0xffToByte(Long.MIN_VALUE)); + assertIntEquals(-1, $noinline$longAnd0xffToByte(Long.MAX_VALUE)); + assertIntEquals(0x1234, $noinline$intAnd0x1ffffToChar(0x43211234)); + assertIntEquals(0, $noinline$intAnd0x1ffffToChar(Integer.MIN_VALUE)); + assertIntEquals(Character.MAX_VALUE, $noinline$intAnd0x1ffffToChar(Integer.MAX_VALUE)); + assertIntEquals(0x4321, $noinline$intAnd0x17fffToShort(0x87654321)); + assertIntEquals(0x0888, $noinline$intAnd0x17fffToShort(0x88888888)); + assertIntEquals(0, $noinline$intAnd0x17fffToShort(Integer.MIN_VALUE)); + assertIntEquals(Short.MAX_VALUE, $noinline$intAnd0x17fffToShort(Integer.MAX_VALUE)); + + assertDoubleEquals(0.0, $noinline$shortAnd0xffffToShortToDouble((short) 0)); + assertDoubleEquals(1.0, $noinline$shortAnd0xffffToShortToDouble((short) 1)); + assertDoubleEquals(-2.0, $noinline$shortAnd0xffffToShortToDouble((short) -2)); + assertDoubleEquals(12345.0, $noinline$shortAnd0xffffToShortToDouble((short) 12345)); + assertDoubleEquals((double)Short.MAX_VALUE, + $noinline$shortAnd0xffffToShortToDouble(Short.MAX_VALUE)); + assertDoubleEquals((double)Short.MIN_VALUE, + $noinline$shortAnd0xffffToShortToDouble(Short.MIN_VALUE)); + + assertIntEquals(13, $noinline$intReverseCondition(41)); + assertIntEquals(13, $noinline$intReverseConditionNaN(-5)); for (String condition : new String[] { "Equal", "NotEqual" }) { for (String constant : new String[] { "True", "False" }) { for (String side : new String[] { "Rhs", "Lhs" }) { String name = condition + constant + side; - assertIntEquals(runSmaliTest(name, true), 5); - assertIntEquals(runSmaliTest(name, false), 3); + assertIntEquals(5, $noinline$runSmaliTest(name, true)); + assertIntEquals(3, $noinline$runSmaliTest(name, false)); } } } + + assertIntEquals(0x5e6f7808, $noinline$intUnnecessaryShiftMasking(0xabcdef01, 3)); + assertIntEquals(0x5e6f7808, $noinline$intUnnecessaryShiftMasking(0xabcdef01, 3 + 32)); + assertLongEquals(0xffffffffffffeaf3L, $noinline$longUnnecessaryShiftMasking(0xabcdef0123456789L, 50)); + assertLongEquals(0xffffffffffffeaf3L, $noinline$longUnnecessaryShiftMasking(0xabcdef0123456789L, 50 + 64)); + assertIntEquals(0x2af37b, $noinline$intUnnecessaryWiderShiftMasking(0xabcdef01, 10)); + assertIntEquals(0x2af37b, $noinline$intUnnecessaryWiderShiftMasking(0xabcdef01, 10 + 128)); + assertLongEquals(0xaf37bc048d159e24L, $noinline$longSmallerShiftMasking(0xabcdef0123456789L, 2)); + assertLongEquals(0xaf37bc048d159e24L, $noinline$longSmallerShiftMasking(0xabcdef0123456789L, 2 + 256)); + assertIntEquals(0xfffd5e7c, $noinline$otherUseOfUnnecessaryShiftMasking(0xabcdef01, 13)); + assertIntEquals(0xfffd5e7c, $noinline$otherUseOfUnnecessaryShiftMasking(0xabcdef01, 13 + 512)); } private static boolean $inline$true() { return true; } diff --git a/test/536-checker-intrinsic-optimization/src/Main.java b/test/536-checker-intrinsic-optimization/src/Main.java index 24ed2feff7..26475ae55c 100644 --- a/test/536-checker-intrinsic-optimization/src/Main.java +++ b/test/536-checker-intrinsic-optimization/src/Main.java @@ -30,6 +30,18 @@ public class Main { } } + public static void assertCharEquals(char expected, char result) { + if (expected != result) { + throw new Error("Expected: " + expected + ", found: " + result); + } + } + + public static void assertStringContains(String searchTerm, String result) { + if (result == null || !result.contains(searchTerm)) { + throw new Error("Search term: " + searchTerm + ", not found in: " + result); + } + } + public static void main(String[] args) { stringEqualsSame(); stringArgumentNotNull("Foo"); @@ -41,6 +53,57 @@ public class Main { assertBooleanEquals(true, $opt$noinline$isStringEmpty("")); assertBooleanEquals(false, $opt$noinline$isStringEmpty("abc")); assertBooleanEquals(false, $opt$noinline$isStringEmpty("0123456789")); + + assertCharEquals('a', $opt$noinline$stringCharAt("a", 0)); + assertCharEquals('a', $opt$noinline$stringCharAt("abc", 0)); + assertCharEquals('b', $opt$noinline$stringCharAt("abc", 1)); + assertCharEquals('c', $opt$noinline$stringCharAt("abc", 2)); + assertCharEquals('7', $opt$noinline$stringCharAt("0123456789", 7)); + + try { + $opt$noinline$stringCharAt("abc", -1); + throw new Error("Should throw SIOOB."); + } catch (StringIndexOutOfBoundsException sioob) { + assertStringContains("java.lang.String.charAt", sioob.getStackTrace()[0].toString()); + assertStringContains("Main.$opt$noinline$stringCharAt", sioob.getStackTrace()[1].toString()); + } + try { + $opt$noinline$stringCharAt("abc", 3); + throw new Error("Should throw SIOOB."); + } catch (StringIndexOutOfBoundsException sioob) { + assertStringContains("java.lang.String.charAt", sioob.getStackTrace()[0].toString()); + assertStringContains("Main.$opt$noinline$stringCharAt", sioob.getStackTrace()[1].toString()); + } + try { + $opt$noinline$stringCharAt("abc", Integer.MAX_VALUE); + throw new Error("Should throw SIOOB."); + } catch (StringIndexOutOfBoundsException sioob) { + assertStringContains("java.lang.String.charAt", sioob.getStackTrace()[0].toString()); + assertStringContains("Main.$opt$noinline$stringCharAt", sioob.getStackTrace()[1].toString()); + } + + assertCharEquals('7', $opt$noinline$stringCharAtCatch("0123456789", 7)); + assertCharEquals('\0', $opt$noinline$stringCharAtCatch("0123456789", 10)); + + assertIntEquals('a' + 'b' + 'c', $opt$noinline$stringSumChars("abc")); + assertIntEquals('a' + 'b' + 'c', $opt$noinline$stringSumLeadingChars("abcdef", 3)); + try { + $opt$noinline$stringSumLeadingChars("abcdef", 7); + throw new Error("Should throw SIOOB."); + } catch (StringIndexOutOfBoundsException sioob) { + assertStringContains("java.lang.String.charAt", sioob.getStackTrace()[0].toString()); + assertStringContains("Main.$opt$noinline$stringSumLeadingChars", + sioob.getStackTrace()[1].toString()); + } + assertIntEquals('a' + 'b' + 'c' + 'd', $opt$noinline$stringSum4LeadingChars("abcdef")); + try { + $opt$noinline$stringSum4LeadingChars("abc"); + throw new Error("Should throw SIOOB."); + } catch (StringIndexOutOfBoundsException sioob) { + assertStringContains("java.lang.String.charAt", sioob.getStackTrace()[0].toString()); + assertStringContains("Main.$opt$noinline$stringSum4LeadingChars", + sioob.getStackTrace()[1].toString()); + } } /// CHECK-START: int Main.$opt$noinline$getStringLength(java.lang.String) instruction_simplifier (before) @@ -81,6 +144,144 @@ public class Main { return s.isEmpty(); } + /// CHECK-START: char Main.$opt$noinline$stringCharAt(java.lang.String, int) instruction_simplifier (before) + /// CHECK-DAG: <<Char:c\d+>> InvokeVirtual intrinsic:StringCharAt + /// CHECK-DAG: Return [<<Char>>] + + /// CHECK-START: char Main.$opt$noinline$stringCharAt(java.lang.String, int) instruction_simplifier (after) + /// CHECK-DAG: <<String:l\d+>> ParameterValue + /// CHECK-DAG: <<Pos:i\d+>> ParameterValue + /// CHECK-DAG: <<NullCk:l\d+>> NullCheck [<<String>>] + /// CHECK-DAG: <<Length:i\d+>> ArrayLength [<<NullCk>>] is_string_length:true + /// CHECK-DAG: BoundsCheck [<<Pos>>,<<Length>>] is_string_char_at:true + /// CHECK-DAG: <<Char:c\d+>> ArrayGet [<<NullCk>>,<<Pos>>] is_string_char_at:true + /// CHECK-DAG: Return [<<Char>>] + + /// CHECK-START: char Main.$opt$noinline$stringCharAt(java.lang.String, int) instruction_simplifier (after) + /// CHECK-NOT: InvokeVirtual intrinsic:StringCharAt + + static public char $opt$noinline$stringCharAt(String s, int pos) { + if (doThrow) { throw new Error(); } + return s.charAt(pos); + } + + /// CHECK-START: char Main.$opt$noinline$stringCharAtCatch(java.lang.String, int) instruction_simplifier (before) + /// CHECK-DAG: <<Char:c\d+>> InvokeVirtual intrinsic:StringCharAt + /// CHECK-DAG: Return [<<Char>>] + + /// CHECK-START: char Main.$opt$noinline$stringCharAtCatch(java.lang.String, int) instruction_simplifier (after) + /// CHECK-DAG: <<String:l\d+>> ParameterValue + /// CHECK-DAG: <<Pos:i\d+>> ParameterValue + /// CHECK-DAG: <<NullCk:l\d+>> NullCheck [<<String>>] + /// CHECK-DAG: <<Length:i\d+>> ArrayLength [<<NullCk>>] is_string_length:true + /// CHECK-DAG: BoundsCheck [<<Pos>>,<<Length>>] is_string_char_at:true + /// CHECK-DAG: <<Char:c\d+>> ArrayGet [<<NullCk>>,<<Pos>>] is_string_char_at:true + /// CHECK-DAG: Return [<<Char>>] + + /// CHECK-START: char Main.$opt$noinline$stringCharAtCatch(java.lang.String, int) instruction_simplifier (after) + /// CHECK-NOT: InvokeVirtual intrinsic:StringCharAt + + static public char $opt$noinline$stringCharAtCatch(String s, int pos) { + if (doThrow) { throw new Error(); } + try { + return s.charAt(pos); + } catch (StringIndexOutOfBoundsException ignored) { + return '\0'; + } + } + + /// CHECK-START: int Main.$opt$noinline$stringSumChars(java.lang.String) instruction_simplifier (before) + /// CHECK-DAG: InvokeVirtual intrinsic:StringLength + /// CHECK-DAG: InvokeVirtual intrinsic:StringCharAt + + /// CHECK-START: int Main.$opt$noinline$stringSumChars(java.lang.String) instruction_simplifier (after) + /// CHECK-DAG: ArrayLength is_string_length:true + /// CHECK-DAG: ArrayLength is_string_length:true + /// CHECK-DAG: BoundsCheck is_string_char_at:true + /// CHECK-DAG: ArrayGet is_string_char_at:true + + /// CHECK-START: int Main.$opt$noinline$stringSumChars(java.lang.String) instruction_simplifier (after) + /// CHECK-NOT: InvokeVirtual intrinsic:StringLength + /// CHECK-NOT: InvokeVirtual intrinsic:StringCharAt + + /// CHECK-START: int Main.$opt$noinline$stringSumChars(java.lang.String) GVN (after) + /// CHECK-DAG: ArrayLength is_string_length:true + /// CHECK-NOT: ArrayLength is_string_length:true + + /// CHECK-START: int Main.$opt$noinline$stringSumChars(java.lang.String) BCE (after) + /// CHECK-NOT: BoundsCheck + + static public int $opt$noinline$stringSumChars(String s) { + if (doThrow) { throw new Error(); } + int sum = 0; + int len = s.length(); + for (int i = 0; i < len; ++i) { + sum += s.charAt(i); + } + return sum; + } + + /// CHECK-START: int Main.$opt$noinline$stringSumLeadingChars(java.lang.String, int) instruction_simplifier (before) + /// CHECK-DAG: InvokeVirtual intrinsic:StringCharAt + + /// CHECK-START: int Main.$opt$noinline$stringSumLeadingChars(java.lang.String, int) instruction_simplifier (after) + /// CHECK-DAG: ArrayLength is_string_length:true + /// CHECK-DAG: BoundsCheck is_string_char_at:true + /// CHECK-DAG: ArrayGet is_string_char_at:true + + /// CHECK-START: int Main.$opt$noinline$stringSumLeadingChars(java.lang.String, int) instruction_simplifier (after) + /// CHECK-NOT: InvokeVirtual intrinsic:StringCharAt + + /// CHECK-START: int Main.$opt$noinline$stringSumLeadingChars(java.lang.String, int) BCE (after) + /// CHECK-DAG: Deoptimize env:[[{{[^\]]*}}]] + + /// CHECK-START: int Main.$opt$noinline$stringSumLeadingChars(java.lang.String, int) BCE (after) + /// CHECK-NOT: BoundsCheck is_string_char_at:true + + static public int $opt$noinline$stringSumLeadingChars(String s, int n) { + if (doThrow) { throw new Error(); } + int sum = 0; + for (int i = 0; i < n; ++i) { + sum += s.charAt(i); + } + return sum; + } + + /// CHECK-START: int Main.$opt$noinline$stringSum4LeadingChars(java.lang.String) instruction_simplifier (before) + /// CHECK-DAG: InvokeVirtual intrinsic:StringCharAt + /// CHECK-DAG: InvokeVirtual intrinsic:StringCharAt + /// CHECK-DAG: InvokeVirtual intrinsic:StringCharAt + /// CHECK-DAG: InvokeVirtual intrinsic:StringCharAt + + /// CHECK-START: int Main.$opt$noinline$stringSum4LeadingChars(java.lang.String) instruction_simplifier (after) + /// CHECK-DAG: ArrayLength is_string_length:true + /// CHECK-DAG: BoundsCheck is_string_char_at:true + /// CHECK-DAG: ArrayGet is_string_char_at:true + /// CHECK-DAG: ArrayLength is_string_length:true + /// CHECK-DAG: BoundsCheck is_string_char_at:true + /// CHECK-DAG: ArrayGet is_string_char_at:true + /// CHECK-DAG: ArrayLength is_string_length:true + /// CHECK-DAG: BoundsCheck is_string_char_at:true + /// CHECK-DAG: ArrayGet is_string_char_at:true + /// CHECK-DAG: ArrayLength is_string_length:true + /// CHECK-DAG: BoundsCheck is_string_char_at:true + /// CHECK-DAG: ArrayGet is_string_char_at:true + + /// CHECK-START: int Main.$opt$noinline$stringSum4LeadingChars(java.lang.String) instruction_simplifier (after) + /// CHECK-NOT: InvokeVirtual intrinsic:StringCharAt + + /// CHECK-START: int Main.$opt$noinline$stringSum4LeadingChars(java.lang.String) BCE (after) + /// CHECK-DAG: Deoptimize env:[[{{[^\]]*}}]] + + /// CHECK-START: int Main.$opt$noinline$stringSum4LeadingChars(java.lang.String) BCE (after) + /// CHECK-NOT: BoundsCheck is_string_char_at:true + + static public int $opt$noinline$stringSum4LeadingChars(String s) { + if (doThrow) { throw new Error(); } + int sum = s.charAt(0) + s.charAt(1) + s.charAt(2) + s.charAt(3); + return sum; + } + /// CHECK-START: boolean Main.stringEqualsSame() instruction_simplifier (before) /// CHECK: InvokeStaticOrDirect diff --git a/test/552-checker-sharpening/src/Main.java b/test/552-checker-sharpening/src/Main.java index 3d985bfaf0..09a77ed285 100644 --- a/test/552-checker-sharpening/src/Main.java +++ b/test/552-checker-sharpening/src/Main.java @@ -28,6 +28,12 @@ public class Main { } } + public static void assertClassEquals(Class<?> expected, Class<?> result) { + if (expected != result) { + throw new Error("Expected: " + expected + ", found: " + result); + } + } + public static boolean doThrow = false; private static int $noinline$foo(int x) { @@ -251,6 +257,66 @@ public class Main { return "non-boot-image-string"; } + /// CHECK-START: java.lang.Class Main.$noinline$getStringClass() sharpening (before) + /// CHECK: LoadClass load_kind:DexCacheViaMethod class_name:java.lang.String + + /// CHECK-START-X86: java.lang.Class Main.$noinline$getStringClass() sharpening (after) + // Note: load kind depends on PIC/non-PIC + // TODO: Remove DexCacheViaMethod when read barrier config supports BootImageAddress. + /// CHECK: LoadClass load_kind:{{BootImageAddress|DexCachePcRelative|DexCacheViaMethod}} class_name:java.lang.String + + /// CHECK-START-X86_64: java.lang.Class Main.$noinline$getStringClass() sharpening (after) + // Note: load kind depends on PIC/non-PIC + // TODO: Remove DexCacheViaMethod when read barrier config supports BootImageAddress. + /// CHECK: LoadClass load_kind:{{BootImageAddress|DexCachePcRelative|DexCacheViaMethod}} class_name:java.lang.String + + /// CHECK-START-ARM: java.lang.Class Main.$noinline$getStringClass() sharpening (after) + // Note: load kind depends on PIC/non-PIC + // TODO: Remove DexCacheViaMethod when read barrier config supports BootImageAddress. + /// CHECK: LoadClass load_kind:{{BootImageAddress|DexCachePcRelative|DexCacheViaMethod}} class_name:java.lang.String + + /// CHECK-START-ARM64: java.lang.Class Main.$noinline$getStringClass() sharpening (after) + // Note: load kind depends on PIC/non-PIC + // TODO: Remove DexCacheViaMethod when read barrier config supports BootImageAddress. + /// CHECK: LoadClass load_kind:{{BootImageAddress|DexCachePcRelative|DexCacheViaMethod}} class_name:java.lang.String + + public static Class<?> $noinline$getStringClass() { + // Prevent inlining to avoid the string comparison being optimized away. + if (doThrow) { throw new Error(); } + // String class is known to be in the boot image. + return String.class; + } + + /// CHECK-START: java.lang.Class Main.$noinline$getOtherClass() sharpening (before) + /// CHECK: LoadClass load_kind:DexCacheViaMethod class_name:Other + + /// CHECK-START-X86: java.lang.Class Main.$noinline$getOtherClass() sharpening (after) + /// CHECK: LoadClass load_kind:DexCachePcRelative class_name:Other + + /// CHECK-START-X86: java.lang.Class Main.$noinline$getOtherClass() pc_relative_fixups_x86 (after) + /// CHECK-DAG: X86ComputeBaseMethodAddress + /// CHECK-DAG: LoadClass load_kind:DexCachePcRelative class_name:Other + + /// CHECK-START-X86_64: java.lang.Class Main.$noinline$getOtherClass() sharpening (after) + /// CHECK: LoadClass load_kind:DexCachePcRelative class_name:Other + + /// CHECK-START-ARM: java.lang.Class Main.$noinline$getOtherClass() sharpening (after) + /// CHECK: LoadClass load_kind:DexCachePcRelative class_name:Other + + /// CHECK-START-ARM: java.lang.Class Main.$noinline$getOtherClass() dex_cache_array_fixups_arm (after) + /// CHECK-DAG: ArmDexCacheArraysBase + /// CHECK-DAG: LoadClass load_kind:DexCachePcRelative class_name:Other + + /// CHECK-START-ARM64: java.lang.Class Main.$noinline$getOtherClass() sharpening (after) + /// CHECK: LoadClass load_kind:DexCachePcRelative class_name:Other + + public static Class<?> $noinline$getOtherClass() { + // Prevent inlining to avoid the string comparison being optimized away. + if (doThrow) { throw new Error(); } + // Other class is not in the boot image. + return Other.class; + } + public static void main(String[] args) { assertIntEquals(1, testSimple(1)); assertIntEquals(1, testDiamond(false, 1)); @@ -262,5 +328,10 @@ public class Main { assertIntEquals(-6, testLoopWithDiamond(new int[]{ 3, 4 }, true, 1)); assertStringEquals("", $noinline$getBootImageString()); assertStringEquals("non-boot-image-string", $noinline$getNonBootImageString()); + assertClassEquals(String.class, $noinline$getStringClass()); + assertClassEquals(Other.class, $noinline$getOtherClass()); } } + +class Other { +} diff --git a/test/566-polymorphic-inlining/polymorphic_inline.cc b/test/566-polymorphic-inlining/polymorphic_inline.cc index 7b2c6cbcd5..c0d93dd8a1 100644 --- a/test/566-polymorphic-inlining/polymorphic_inline.cc +++ b/test/566-polymorphic-inlining/polymorphic_inline.cc @@ -17,6 +17,7 @@ #include "art_method.h" #include "jit/jit.h" #include "jit/jit_code_cache.h" +#include "jit/profiling_info.h" #include "oat_quick_method_header.h" #include "scoped_thread_state_change.h" #include "stack_map.h" @@ -37,8 +38,10 @@ static void do_checks(jclass cls, const char* method_name) { if (code_cache->ContainsPc(header->GetCode())) { break; } else { - // sleep one second to give time to the JIT compiler. - sleep(1); + // Sleep to yield to the compiler thread. + usleep(1000); + // Will either ensure it's compiled or do the compilation itself. + jit->CompileMethod(method, soa.Self(), /* osr */ false); } } @@ -47,7 +50,25 @@ static void do_checks(jclass cls, const char* method_name) { CHECK(info.HasInlineInfo(encoding)); } -extern "C" JNIEXPORT void JNICALL Java_Main_ensureJittedAndPolymorphicInline(JNIEnv*, jclass cls) { +static void allocate_profiling_info(jclass cls, const char* method_name) { + ScopedObjectAccess soa(Thread::Current()); + mirror::Class* klass = soa.Decode<mirror::Class*>(cls); + ArtMethod* method = klass->FindDeclaredDirectMethodByName(method_name, sizeof(void*)); + ProfilingInfo::Create(soa.Self(), method, /* retry_allocation */ true); +} + +extern "C" JNIEXPORT void JNICALL Java_Main_ensureProfilingInfo566(JNIEnv*, jclass cls) { + jit::Jit* jit = Runtime::Current()->GetJit(); + if (jit == nullptr) { + return; + } + + allocate_profiling_info(cls, "testInvokeVirtual"); + allocate_profiling_info(cls, "testInvokeInterface"); + allocate_profiling_info(cls, "$noinline$testInlineToSameTarget"); +} + +extern "C" JNIEXPORT void JNICALL Java_Main_ensureJittedAndPolymorphicInline566(JNIEnv*, jclass cls) { jit::Jit* jit = Runtime::Current()->GetJit(); if (jit == nullptr) { return; diff --git a/test/566-polymorphic-inlining/src/Main.java b/test/566-polymorphic-inlining/src/Main.java index a59ce5b344..d39e6ed57b 100644 --- a/test/566-polymorphic-inlining/src/Main.java +++ b/test/566-polymorphic-inlining/src/Main.java @@ -39,6 +39,9 @@ public class Main implements Itf { itfs[1] = mains[1] = new Subclass(); itfs[2] = mains[2] = new OtherSubclass(); + // Create the profiling info eagerly to make sure they are filled. + ensureProfilingInfo566(); + // Make testInvokeVirtual and testInvokeInterface hot to get them jitted. // We pass Main and Subclass to get polymorphic inlining based on calling // the same method. @@ -51,7 +54,7 @@ public class Main implements Itf { $noinline$testInlineToSameTarget(mains[1]); } - ensureJittedAndPolymorphicInline(); + ensureJittedAndPolymorphicInline566(); // At this point, the JIT should have compiled both methods, and inline // sameInvokeVirtual and sameInvokeInterface. @@ -71,12 +74,12 @@ public class Main implements Itf { } public Class sameInvokeVirtual() { - field.getClass(); // null check to ensure we get an inlined frame in the CodeInfo + field.getClass(); // null check to ensure we get an inlined frame in the CodeInfo. return Main.class; } public Class sameInvokeInterface() { - field.getClass(); // null check to ensure we get an inlined frame in the CodeInfo + field.getClass(); // null check to ensure we get an inlined frame in the CodeInfo. return Itf.class; } @@ -95,7 +98,8 @@ public class Main implements Itf { public Object field = new Object(); - public static native void ensureJittedAndPolymorphicInline(); + public static native void ensureJittedAndPolymorphicInline566(); + public static native void ensureProfilingInfo566(); public void increment() { field.getClass(); // null check to ensure we get an inlined frame in the CodeInfo diff --git a/test/607-daemon-stress/expected.txt b/test/607-daemon-stress/expected.txt new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/607-daemon-stress/expected.txt diff --git a/test/607-daemon-stress/info.txt b/test/607-daemon-stress/info.txt new file mode 100644 index 0000000000..1047b767fa --- /dev/null +++ b/test/607-daemon-stress/info.txt @@ -0,0 +1,3 @@ +Stress test for daemon threads stuck in a method that requires the thread list lock. +(for example Thread.isInterrupted). The shutdown thread used to block those daemons +from making progress. diff --git a/test/607-daemon-stress/src/Main.java b/test/607-daemon-stress/src/Main.java new file mode 100644 index 0000000000..56ef4102b1 --- /dev/null +++ b/test/607-daemon-stress/src/Main.java @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2016 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 extends Thread { + public static void main(String[] args) throws Exception { + for (int i = 0; i < 5; i++) { + Main m = new Main(); + m.setDaemon(true); + m.start(); + } + // Sleep a while to give some time for the threads to start. + Thread.sleep(1000); + } + + public void run() { + while (!isInterrupted()); + } +} diff --git a/test/608-checker-unresolved-lse/expected.txt b/test/608-checker-unresolved-lse/expected.txt new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/608-checker-unresolved-lse/expected.txt diff --git a/test/608-checker-unresolved-lse/info.txt b/test/608-checker-unresolved-lse/info.txt new file mode 100644 index 0000000000..466d5f44ec --- /dev/null +++ b/test/608-checker-unresolved-lse/info.txt @@ -0,0 +1,3 @@ +Regression test for the load store elimination optimization, +which used to wrongly remove field stores in the presence of +unresolved accesses. diff --git a/test/608-checker-unresolved-lse/run b/test/608-checker-unresolved-lse/run new file mode 100644 index 0000000000..226891f65a --- /dev/null +++ b/test/608-checker-unresolved-lse/run @@ -0,0 +1,18 @@ +#!/bin/bash +# +# Copyright (C) 2016 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. + +# Use secondary switch to add secondary dex file to class path. +exec ${RUN} "${@}" --secondary diff --git a/test/608-checker-unresolved-lse/src-dex2oat-unresolved/MissingSuperClass.java b/test/608-checker-unresolved-lse/src-dex2oat-unresolved/MissingSuperClass.java new file mode 100644 index 0000000000..b11b9be78e --- /dev/null +++ b/test/608-checker-unresolved-lse/src-dex2oat-unresolved/MissingSuperClass.java @@ -0,0 +1,18 @@ +/* + * Copyright (C) 2016 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 MissingSuperClass { +} diff --git a/test/608-checker-unresolved-lse/src/Main.java b/test/608-checker-unresolved-lse/src/Main.java new file mode 100644 index 0000000000..c6f8854b49 --- /dev/null +++ b/test/608-checker-unresolved-lse/src/Main.java @@ -0,0 +1,127 @@ +/* + * Copyright (C) 2016 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. + */ + +// We make Main extend an unresolved super class. This will lead to an +// unresolved access to Foo.field, as we won't know if Main can access +// a package private field. +public class Main extends MissingSuperClass { + + public static void main(String[] args) { + instanceFieldTest(); + staticFieldTest(); + instanceFieldTest2(); + } + + /// CHECK-START: void Main.instanceFieldTest() inliner (before) + /// CHECK-NOT: InstanceFieldSet + + /// CHECK-START: void Main.instanceFieldTest() inliner (after) + /// CHECK: InstanceFieldSet + /// CHECK: UnresolvedInstanceFieldGet + + // Load store elimination used to remove the InstanceFieldSet, thinking + // that the UnresolvedInstanceFieldGet was not related. However inlining + // can put you in a situation where the UnresolvedInstanceFieldGet resolves + // to the same field as the one in InstanceFieldSet. So the InstanceFieldSet + // must be preserved. + + /// CHECK-START: void Main.instanceFieldTest() load_store_elimination (after) + /// CHECK: InstanceFieldSet + /// CHECK: UnresolvedInstanceFieldGet + public static void instanceFieldTest() { + Foo f = new Foo(); + if (f.iField != 42) { + throw new Error("Expected 42, got " + f.iField); + } + } + + /// CHECK-START: void Main.instanceFieldTest2() inliner (before) + /// CHECK-NOT: InstanceFieldSet + /// CHECK-NOT: InstanceFieldGet + + /// CHECK-START: void Main.instanceFieldTest2() inliner (after) + /// CHECK: InstanceFieldSet + /// CHECK: InstanceFieldGet + /// CHECK: UnresolvedInstanceFieldSet + /// CHECK: InstanceFieldGet + + // Load store elimination will eliminate the first InstanceFieldGet because + // it simply follows an InstanceFieldSet. It must however not eliminate the second + // InstanceFieldGet, as the UnresolvedInstanceFieldSet might resolve to the same + // field. + + /// CHECK-START: void Main.instanceFieldTest2() load_store_elimination (after) + /// CHECK: InstanceFieldSet + /// CHECK-NOT: InstanceFieldGet + /// CHECK: UnresolvedInstanceFieldSet + /// CHECK: InstanceFieldGet + public static void instanceFieldTest2() { + Foo f = new Foo(); + int a = f.$inline$GetInstanceField(); + f.iField = 43; + a = f.$inline$GetInstanceField(); + if (a != 43) { + throw new Error("Expected 43, got " + a); + } + } + + /// CHECK-START: void Main.staticFieldTest() inliner (before) + /// CHECK-NOT: StaticFieldSet + + /// CHECK-START: void Main.staticFieldTest() inliner (after) + /// CHECK: StaticFieldSet + /// CHECK: StaticFieldSet + /// CHECK: UnresolvedStaticFieldGet + + /// CHECK-START: void Main.staticFieldTest() load_store_elimination (after) + /// CHECK: StaticFieldSet + /// CHECK: StaticFieldSet + /// CHECK: UnresolvedStaticFieldGet + public static void staticFieldTest() { + // Ensure Foo is initialized. + Foo f = new Foo(); + f.$inline$StaticSet42(); + f.$inline$StaticSet43(); + if (Foo.sField != 43) { + throw new Error("Expected 43, got " + Foo.sField); + } + } +} + +class Foo { + // field needs to be package-private to make the access in Main.main + // unresolved. + int iField; + static int sField; + + public void $inline$StaticSet42() { + sField = 42; + } + + public void $inline$StaticSet43() { + sField = 43; + } + + public int $inline$GetInstanceField() { + return iField; + } + + // Constructor needs to be public to get it resolved in Main.main + // and therefore inlined. + public Foo() { + iField = 42; + } +} diff --git a/test/Android.libarttest.mk b/test/Android.libarttest.mk index feee7c2c3d..01790aea12 100644 --- a/test/Android.libarttest.mk +++ b/test/Android.libarttest.mk @@ -25,6 +25,7 @@ LIBARTTEST_COMMON_SRC_FILES := \ 004-SignalTest/signaltest.cc \ 004-ReferenceMap/stack_walk_refmap_jni.cc \ 004-StackWalk/stack_walk_jni.cc \ + 004-ThreadStress/thread_stress.cc \ 004-UnsafeTest/unsafe_test.cc \ 044-proxy/native_proxy.cc \ 051-thread/thread_test.cc \ @@ -87,7 +88,11 @@ define build-libarttest LOCAL_ADDITIONAL_DEPENDENCIES += $(LOCAL_PATH)/Android.libarttest.mk ifeq ($$(art_target_or_host),target) $(call set-target-local-clang-vars) - $(call set-target-local-cflags-vars,debug) + ifeq ($$(suffix),d) + $(call set-target-local-cflags-vars,debug) + else + $(call set-target-local-cflags-vars,ndebug) + endif LOCAL_SHARED_LIBRARIES += libdl LOCAL_MULTILIB := both LOCAL_MODULE_PATH_32 := $(ART_TARGET_TEST_OUT)/$(ART_TARGET_ARCH_32) diff --git a/test/Android.run-test.mk b/test/Android.run-test.mk index f118a7625a..dd6b6f3fbc 100644 --- a/test/Android.run-test.mk +++ b/test/Android.run-test.mk @@ -294,7 +294,8 @@ TEST_ART_BROKEN_NO_PREBUILD_TESTS := \ 147-stripped-dex-fallback \ 554-jit-profile-file \ 529-checker-unresolved \ - 555-checker-regression-x86const + 555-checker-regression-x86const \ + 608-checker-unresolved-lse ifneq (,$(filter no-prebuild,$(PREBUILD_TYPES))) ART_TEST_KNOWN_BROKEN += $(call all-run-test-names,$(TARGET_TYPES),$(RUN_TYPES),no-prebuild, \ diff --git a/test/dexdump/all.dex b/test/dexdump/all.dex Binary files differnew file mode 100644 index 0000000000..caf678da4a --- /dev/null +++ b/test/dexdump/all.dex diff --git a/test/dexdump/all.lst b/test/dexdump/all.lst new file mode 100644 index 0000000000..17ab9cacdd --- /dev/null +++ b/test/dexdump/all.lst @@ -0,0 +1,21 @@ +#all.dex +0x0000043c 8 A <init> ()V (none) -1 +0x00000454 58 A arrays ()V (none) -1 +0x000004a0 130 A binary_ops ()V (none) -1 +0x00000534 66 A binary_ops_2addr ()V (none) -1 +0x00000588 34 A binary_ops_lit16 ()V (none) -1 +0x000005bc 46 A binary_ops_lit8 ()V (none) -1 +0x000005fc 22 A compares ()V (none) -1 +0x00000624 50 A conditionals ()V (none) -1 +0x00000668 56 A constants ()V (none) -1 +0x000006b0 108 A misc ()V (none) -1 +0x0000072c 46 A moves ()V (none) -1 +0x0000076c 32 A packed_switch ()V (none) -1 +0x0000079c 2 A return32 ()I (none) -1 +0x000007b0 2 A return64 ()I (none) -1 +0x000007c4 2 A return_object ()Ljava/lang/Object; (none) -1 +0x000007d8 44 A sparse_switch ()V (none) -1 +0x00000814 58 A static_fields ()V (none) -1 +0x00000860 44 A unary_ops ()V (none) -1 +0x0000089c 58 A instance_fields ()V (none) -1 +0x000008e8 30 A invokes ()V (none) -1 diff --git a/test/dexdump/all.txt b/test/dexdump/all.txt new file mode 100644 index 0000000000..af4fb4c12c --- /dev/null +++ b/test/dexdump/all.txt @@ -0,0 +1,622 @@ +Processing 'all.dex'... +Opened 'all.dex', DEX version '035' +DEX file header: +magic : 'dex\n035\0' +checksum : d5134208 +signature : 7af6...100f +file_size : 2572 +header_size : 112 +link_size : 0 +link_off : 0 (0x000000) +string_ids_size : 46 +string_ids_off : 112 (0x000070) +type_ids_size : 10 +type_ids_off : 296 (0x000128) +proto_ids_size : 3 +proto_ids_off : 336 (0x000150) +field_ids_size : 14 +field_ids_off : 372 (0x000174) +method_ids_size : 21 +method_ids_off : 484 (0x0001e4) +class_defs_size : 1 +class_defs_off : 652 (0x00028c) +data_size : 1888 +data_off : 684 (0x0002ac) + +Class #0 header: +class_idx : 4 +access_flags : 1 (0x0001) +superclass_idx : 5 +interfaces_off : 0 (0x000000) +source_file_idx : -1 +annotations_off : 0 (0x000000) +class_data_off : 2310 (0x000906) +static_fields_size : 7 +instance_fields_size: 7 +direct_methods_size : 18 +virtual_methods_size: 2 + +Class #0 - + Class descriptor : 'LA;' + Access flags : 0x0001 (PUBLIC) + Superclass : 'Ljava/lang/Object;' + Interfaces - + Static fields - + #0 : (in LA;) + name : 'sB' + type : 'B' + access : 0x000a (PRIVATE STATIC) + #1 : (in LA;) + name : 'sC' + type : 'C' + access : 0x000a (PRIVATE STATIC) + #2 : (in LA;) + name : 'sI' + type : 'I' + access : 0x000a (PRIVATE STATIC) + #3 : (in LA;) + name : 'sJ' + type : 'J' + access : 0x000a (PRIVATE STATIC) + #4 : (in LA;) + name : 'sO' + type : 'LA;' + access : 0x000a (PRIVATE STATIC) + #5 : (in LA;) + name : 'sS' + type : 'S' + access : 0x000a (PRIVATE STATIC) + #6 : (in LA;) + name : 'sZ' + type : 'Z' + access : 0x000a (PRIVATE STATIC) + Instance fields - + #0 : (in LA;) + name : 'mB' + type : 'B' + access : 0x0002 (PRIVATE) + #1 : (in LA;) + name : 'mC' + type : 'C' + access : 0x0002 (PRIVATE) + #2 : (in LA;) + name : 'mI' + type : 'I' + access : 0x0002 (PRIVATE) + #3 : (in LA;) + name : 'mJ' + type : 'J' + access : 0x0002 (PRIVATE) + #4 : (in LA;) + name : 'mO' + type : 'LA;' + access : 0x0002 (PRIVATE) + #5 : (in LA;) + name : 'mS' + type : 'S' + access : 0x0002 (PRIVATE) + #6 : (in LA;) + name : 'mZ' + type : 'Z' + access : 0x0002 (PRIVATE) + Direct methods - + #0 : (in LA;) + name : '<init>' + type : '()V' + access : 0x10001 (PUBLIC CONSTRUCTOR) + code - + registers : 1 + ins : 1 + outs : 1 + insns size : 4 16-bit code units +00042c: |[00042c] A.<init>:()V +00043c: 7010 1400 0000 |0000: invoke-direct {v0}, Ljava/lang/Object;.<init>:()V // method@0014 +000442: 0e00 |0003: return-void + catches : (none) + positions : + locals : + + #1 : (in LA;) + name : 'arrays' + type : '()V' + access : 0x0009 (PUBLIC STATIC) + code - + registers : 3 + ins : 0 + outs : 0 + insns size : 29 16-bit code units +000444: |[000444] A.arrays:()V +000454: 4400 0102 |0000: aget v0, v1, v2 +000458: 4500 0102 |0002: aget-wide v0, v1, v2 +00045c: 4600 0102 |0004: aget-object v0, v1, v2 +000460: 4700 0102 |0006: aget-boolean v0, v1, v2 +000464: 4800 0102 |0008: aget-byte v0, v1, v2 +000468: 4900 0102 |000a: aget-char v0, v1, v2 +00046c: 4a00 0102 |000c: aget-short v0, v1, v2 +000470: 4b00 0102 |000e: aput v0, v1, v2 +000474: 4c00 0102 |0010: aput-wide v0, v1, v2 +000478: 4d00 0102 |0012: aput-object v0, v1, v2 +00047c: 4e00 0102 |0014: aput-boolean v0, v1, v2 +000480: 4f00 0102 |0016: aput-byte v0, v1, v2 +000484: 5000 0102 |0018: aput-char v0, v1, v2 +000488: 5100 0102 |001a: aput-short v0, v1, v2 +00048c: 0e00 |001c: return-void + catches : (none) + positions : + locals : + + #2 : (in LA;) + name : 'binary_ops' + type : '()V' + access : 0x0009 (PUBLIC STATIC) + code - + registers : 3 + ins : 0 + outs : 0 + insns size : 65 16-bit code units +000490: |[000490] A.binary_ops:()V +0004a0: 9000 0102 |0000: add-int v0, v1, v2 +0004a4: 9100 0102 |0002: sub-int v0, v1, v2 +0004a8: 9200 0102 |0004: mul-int v0, v1, v2 +0004ac: 9300 0102 |0006: div-int v0, v1, v2 +0004b0: 9400 0102 |0008: rem-int v0, v1, v2 +0004b4: 9500 0102 |000a: and-int v0, v1, v2 +0004b8: 9600 0102 |000c: or-int v0, v1, v2 +0004bc: 9700 0102 |000e: xor-int v0, v1, v2 +0004c0: 9800 0102 |0010: shl-int v0, v1, v2 +0004c4: 9900 0102 |0012: shr-int v0, v1, v2 +0004c8: 9a00 0102 |0014: ushr-int v0, v1, v2 +0004cc: 9b00 0102 |0016: add-long v0, v1, v2 +0004d0: 9c00 0102 |0018: sub-long v0, v1, v2 +0004d4: 9d00 0102 |001a: mul-long v0, v1, v2 +0004d8: 9e00 0102 |001c: div-long v0, v1, v2 +0004dc: 9f00 0102 |001e: rem-long v0, v1, v2 +0004e0: a000 0102 |0020: and-long v0, v1, v2 +0004e4: a100 0102 |0022: or-long v0, v1, v2 +0004e8: a200 0102 |0024: xor-long v0, v1, v2 +0004ec: a300 0102 |0026: shl-long v0, v1, v2 +0004f0: a400 0102 |0028: shr-long v0, v1, v2 +0004f4: a500 0102 |002a: ushr-long v0, v1, v2 +0004f8: a600 0102 |002c: add-float v0, v1, v2 +0004fc: a700 0102 |002e: sub-float v0, v1, v2 +000500: a800 0102 |0030: mul-float v0, v1, v2 +000504: a900 0102 |0032: div-float v0, v1, v2 +000508: aa00 0102 |0034: rem-float v0, v1, v2 +00050c: ab00 0102 |0036: add-double v0, v1, v2 +000510: ac00 0102 |0038: sub-double v0, v1, v2 +000514: ad00 0102 |003a: mul-double v0, v1, v2 +000518: ae00 0102 |003c: div-double v0, v1, v2 +00051c: af00 0102 |003e: rem-double v0, v1, v2 +000520: 0e00 |0040: return-void + catches : (none) + positions : + locals : + + #3 : (in LA;) + name : 'binary_ops_2addr' + type : '()V' + access : 0x0009 (PUBLIC STATIC) + code - + registers : 2 + ins : 0 + outs : 0 + insns size : 33 16-bit code units +000524: |[000524] A.binary_ops_2addr:()V +000534: b010 |0000: add-int/2addr v0, v1 +000536: b110 |0001: sub-int/2addr v0, v1 +000538: b210 |0002: mul-int/2addr v0, v1 +00053a: b310 |0003: div-int/2addr v0, v1 +00053c: b410 |0004: rem-int/2addr v0, v1 +00053e: b510 |0005: and-int/2addr v0, v1 +000540: b610 |0006: or-int/2addr v0, v1 +000542: b710 |0007: xor-int/2addr v0, v1 +000544: b810 |0008: shl-int/2addr v0, v1 +000546: b910 |0009: shr-int/2addr v0, v1 +000548: ba10 |000a: ushr-int/2addr v0, v1 +00054a: bb10 |000b: add-long/2addr v0, v1 +00054c: bc10 |000c: sub-long/2addr v0, v1 +00054e: bd10 |000d: mul-long/2addr v0, v1 +000550: be10 |000e: div-long/2addr v0, v1 +000552: bf10 |000f: rem-long/2addr v0, v1 +000554: c010 |0010: and-long/2addr v0, v1 +000556: c110 |0011: or-long/2addr v0, v1 +000558: c210 |0012: xor-long/2addr v0, v1 +00055a: c310 |0013: shl-long/2addr v0, v1 +00055c: c410 |0014: shr-long/2addr v0, v1 +00055e: c510 |0015: ushr-long/2addr v0, v1 +000560: c610 |0016: add-float/2addr v0, v1 +000562: c710 |0017: sub-float/2addr v0, v1 +000564: c810 |0018: mul-float/2addr v0, v1 +000566: c910 |0019: div-float/2addr v0, v1 +000568: ca10 |001a: rem-float/2addr v0, v1 +00056a: cb10 |001b: add-double/2addr v0, v1 +00056c: cc10 |001c: sub-double/2addr v0, v1 +00056e: cd10 |001d: mul-double/2addr v0, v1 +000570: ce10 |001e: div-double/2addr v0, v1 +000572: cf10 |001f: rem-double/2addr v0, v1 +000574: 0e00 |0020: return-void + catches : (none) + positions : + locals : + + #4 : (in LA;) + name : 'binary_ops_lit16' + type : '()V' + access : 0x0009 (PUBLIC STATIC) + code - + registers : 2 + ins : 0 + outs : 0 + insns size : 17 16-bit code units +000578: |[000578] A.binary_ops_lit16:()V +000588: d010 3412 |0000: add-int/lit16 v0, v1, #int 4660 // #1234 +00058c: d110 3412 |0002: rsub-int v0, v1, #int 4660 // #1234 +000590: d210 3412 |0004: mul-int/lit16 v0, v1, #int 4660 // #1234 +000594: d310 3412 |0006: div-int/lit16 v0, v1, #int 4660 // #1234 +000598: d410 3412 |0008: rem-int/lit16 v0, v1, #int 4660 // #1234 +00059c: d510 3412 |000a: and-int/lit16 v0, v1, #int 4660 // #1234 +0005a0: d610 3412 |000c: or-int/lit16 v0, v1, #int 4660 // #1234 +0005a4: d710 3412 |000e: xor-int/lit16 v0, v1, #int 4660 // #1234 +0005a8: 0e00 |0010: return-void + catches : (none) + positions : + locals : + + #5 : (in LA;) + name : 'binary_ops_lit8' + type : '()V' + access : 0x0009 (PUBLIC STATIC) + code - + registers : 2 + ins : 0 + outs : 0 + insns size : 23 16-bit code units +0005ac: |[0005ac] A.binary_ops_lit8:()V +0005bc: d800 0112 |0000: add-int/lit8 v0, v1, #int 18 // #12 +0005c0: d900 0112 |0002: rsub-int/lit8 v0, v1, #int 18 // #12 +0005c4: da00 0112 |0004: mul-int/lit8 v0, v1, #int 18 // #12 +0005c8: db00 0112 |0006: div-int/lit8 v0, v1, #int 18 // #12 +0005cc: dc00 0112 |0008: rem-int/lit8 v0, v1, #int 18 // #12 +0005d0: dd00 0112 |000a: and-int/lit8 v0, v1, #int 18 // #12 +0005d4: de00 0112 |000c: or-int/lit8 v0, v1, #int 18 // #12 +0005d8: df00 0112 |000e: xor-int/lit8 v0, v1, #int 18 // #12 +0005dc: e000 0112 |0010: shl-int/lit8 v0, v1, #int 18 // #12 +0005e0: e100 0112 |0012: shr-int/lit8 v0, v1, #int 18 // #12 +0005e4: e200 0112 |0014: ushr-int/lit8 v0, v1, #int 18 // #12 +0005e8: 0e00 |0016: return-void + catches : (none) + positions : + locals : + + #6 : (in LA;) + name : 'compares' + type : '()V' + access : 0x0009 (PUBLIC STATIC) + code - + registers : 3 + ins : 0 + outs : 0 + insns size : 11 16-bit code units +0005ec: |[0005ec] A.compares:()V +0005fc: 2d00 0102 |0000: cmpl-float v0, v1, v2 +000600: 2e00 0102 |0002: cmpg-float v0, v1, v2 +000604: 2f00 0102 |0004: cmpl-double v0, v1, v2 +000608: 3000 0102 |0006: cmpg-double v0, v1, v2 +00060c: 3100 0102 |0008: cmp-long v0, v1, v2 +000610: 0e00 |000a: return-void + catches : (none) + positions : + locals : + + #7 : (in LA;) + name : 'conditionals' + type : '()V' + access : 0x0009 (PUBLIC STATIC) + code - + registers : 2 + ins : 0 + outs : 0 + insns size : 25 16-bit code units +000614: |[000614] A.conditionals:()V +000624: 3210 1800 |0000: if-eq v0, v1, 0018 // +0018 +000628: 3310 1600 |0002: if-ne v0, v1, 0018 // +0016 +00062c: 3410 1400 |0004: if-lt v0, v1, 0018 // +0014 +000630: 3510 1200 |0006: if-ge v0, v1, 0018 // +0012 +000634: 3610 1000 |0008: if-gt v0, v1, 0018 // +0010 +000638: 3710 0e00 |000a: if-le v0, v1, 0018 // +000e +00063c: 3800 0c00 |000c: if-eqz v0, 0018 // +000c +000640: 3900 0a00 |000e: if-nez v0, 0018 // +000a +000644: 3a00 0800 |0010: if-ltz v0, 0018 // +0008 +000648: 3b00 0600 |0012: if-gez v0, 0018 // +0006 +00064c: 3c00 0400 |0014: if-gtz v0, 0018 // +0004 +000650: 3d00 0200 |0016: if-lez v0, 0018 // +0002 +000654: 0e00 |0018: return-void + catches : (none) + positions : + locals : + + #8 : (in LA;) + name : 'constants' + type : '()V' + access : 0x0009 (PUBLIC STATIC) + code - + registers : 1 + ins : 0 + outs : 0 + insns size : 28 16-bit code units +000658: |[000658] A.constants:()V +000668: 1210 |0000: const/4 v0, #int 1 // #1 +00066a: 1300 3412 |0001: const/16 v0, #int 4660 // #1234 +00066e: 1400 7856 3412 |0003: const v0, #float 5.69046e-28 // #12345678 +000674: 1500 3412 |0006: const/high16 v0, #int 305397760 // #1234 +000678: 1600 3412 |0008: const-wide/16 v0, #int 4660 // #1234 +00067c: 1700 7856 3412 |000a: const-wide/32 v0, #float 5.69046e-28 // #12345678 +000682: 1800 efcd ab90 7856 3412 |000d: const-wide v0, #double 5.62635e-221 // #1234567890abcdef +00068c: 1900 3412 |0012: const-wide/high16 v0, #long 1311673391471656960 // #1234 +000690: 1a00 2c00 |0014: const-string v0, "string" // string@002c +000694: 1b00 2c00 0000 |0016: const-string/jumbo v0, "string" // string@0000002c +00069a: 1c00 0500 |0019: const-class v0, Ljava/lang/Object; // type@0005 +00069e: 0e00 |001b: return-void + catches : (none) + positions : + locals : + + #9 : (in LA;) + name : 'misc' + type : '()V' + access : 0x0009 (PUBLIC STATIC) + code - + registers : 5 + ins : 0 + outs : 0 + insns size : 54 16-bit code units +0006a0: |[0006a0] A.misc:()V +0006b0: 0000 |0000: nop // spacer +0006b2: 1d00 |0001: monitor-enter v0 +0006b4: 1e00 |0002: monitor-exit v0 +0006b6: 1f00 0500 |0003: check-cast v0, Ljava/lang/Object; // type@0005 +0006ba: 2010 0500 |0005: instance-of v0, v1, Ljava/lang/Object; // type@0005 +0006be: 2110 |0007: array-length v0, v1 +0006c0: 2200 0500 |0008: new-instance v0, Ljava/lang/Object; // type@0005 +0006c4: 2310 0500 |000a: new-array v0, v1, Ljava/lang/Object; // type@0005 +0006c8: 2454 0900 1032 |000c: filled-new-array {v0, v1, v2, v3, v4}, [Ljava/lang/Object; // type@0009 +0006ce: 2505 0900 0000 |000f: filled-new-array/range {v0, v1, v2, v3, v4}, [Ljava/lang/Object; // type@0009 +0006d4: 2600 0c00 0000 |0012: fill-array-data v0, 0000001e // +0000000c +0006da: 2700 |0015: throw v0 +0006dc: 2806 |0016: goto 001c // +0006 +0006de: 2900 0500 |0017: goto/16 001c // +0005 +0006e2: 2a00 0300 0000 |0019: goto/32 #00000003 +0006e8: 0e00 |001c: return-void +0006ea: 0000 |001d: nop // spacer +0006ec: 0003 0400 0a00 0000 0100 0000 0200 ... |001e: array-data (24 units) + catches : (none) + positions : + locals : + + #10 : (in LA;) + name : 'moves' + type : '()V' + access : 0x0009 (PUBLIC STATIC) + code - + registers : 2 + ins : 0 + outs : 0 + insns size : 23 16-bit code units +00071c: |[00071c] A.moves:()V +00072c: 0110 |0000: move v0, v1 +00072e: 0200 0100 |0001: move/from16 v0, v1 +000732: 0300 0000 0100 |0003: move/16 v0, v1 +000738: 0410 |0006: move-wide v0, v1 +00073a: 0500 0100 |0007: move-wide/from16 v0, v1 +00073e: 0600 0000 0100 |0009: move-wide/16 v0, v1 +000744: 0710 |000c: move-object v0, v1 +000746: 0800 0100 |000d: move-object/from16 v0, v1 +00074a: 0900 0000 0100 |000f: move-object/16 v0, v1 +000750: 0a00 |0012: move-result v0 +000752: 0b00 |0013: move-result-wide v0 +000754: 0c00 |0014: move-result-object v0 +000756: 0d00 |0015: move-exception v0 +000758: 0e00 |0016: return-void + catches : (none) + positions : + locals : + + #11 : (in LA;) + name : 'packed_switch' + type : '()V' + access : 0x0009 (PUBLIC STATIC) + code - + registers : 1 + ins : 0 + outs : 0 + insns size : 16 16-bit code units +00075c: |[00075c] A.packed_switch:()V +00076c: 2b00 0800 0000 |0000: packed-switch v0, 00000008 // +00000008 +000772: 0e00 |0003: return-void +000774: 28ff |0004: goto 0003 // -0001 +000776: 28fe |0005: goto 0003 // -0002 +000778: 28fd |0006: goto 0003 // -0003 +00077a: 0000 |0007: nop // spacer +00077c: 0001 0200 feff ff7f 0500 0000 0600 ... |0008: packed-switch-data (8 units) + catches : (none) + positions : + locals : + + #12 : (in LA;) + name : 'return32' + type : '()I' + access : 0x0009 (PUBLIC STATIC) + code - + registers : 1 + ins : 0 + outs : 0 + insns size : 1 16-bit code units +00078c: |[00078c] A.return32:()I +00079c: 0f00 |0000: return v0 + catches : (none) + positions : + locals : + + #13 : (in LA;) + name : 'return64' + type : '()I' + access : 0x0009 (PUBLIC STATIC) + code - + registers : 2 + ins : 0 + outs : 0 + insns size : 1 16-bit code units +0007a0: |[0007a0] A.return64:()I +0007b0: 1000 |0000: return-wide v0 + catches : (none) + positions : + locals : + + #14 : (in LA;) + name : 'return_object' + type : '()Ljava/lang/Object;' + access : 0x0009 (PUBLIC STATIC) + code - + registers : 1 + ins : 0 + outs : 0 + insns size : 1 16-bit code units +0007b4: |[0007b4] A.return_object:()Ljava/lang/Object; +0007c4: 1100 |0000: return-object v0 + catches : (none) + positions : + locals : + + #15 : (in LA;) + name : 'sparse_switch' + type : '()V' + access : 0x0009 (PUBLIC STATIC) + code - + registers : 2 + ins : 0 + outs : 0 + insns size : 22 16-bit code units +0007c8: |[0007c8] A.sparse_switch:()V +0007d8: 2c00 0400 0000 |0000: sparse-switch v0, 00000004 // +00000004 +0007de: 0e00 |0003: return-void +0007e0: 0002 0400 1111 0000 2222 0000 3333 ... |0004: sparse-switch-data (18 units) + catches : (none) + positions : + locals : + + #16 : (in LA;) + name : 'static_fields' + type : '()V' + access : 0x0009 (PUBLIC STATIC) + code - + registers : 1 + ins : 0 + outs : 0 + insns size : 29 16-bit code units +000804: |[000804] A.static_fields:()V +000814: 6000 0900 |0000: sget v0, LA;.sI:I // field@0009 +000818: 6100 0a00 |0002: sget-wide v0, LA;.sJ:J // field@000a +00081c: 6200 0b00 |0004: sget-object v0, LA;.sO:LA; // field@000b +000820: 6300 0d00 |0006: sget-boolean v0, LA;.sZ:Z // field@000d +000824: 6400 0700 |0008: sget-byte v0, LA;.sB:B // field@0007 +000828: 6500 0800 |000a: sget-char v0, LA;.sC:C // field@0008 +00082c: 6600 0c00 |000c: sget-short v0, LA;.sS:S // field@000c +000830: 6700 0900 |000e: sput v0, LA;.sI:I // field@0009 +000834: 6800 0a00 |0010: sput-wide v0, LA;.sJ:J // field@000a +000838: 6900 0b00 |0012: sput-object v0, LA;.sO:LA; // field@000b +00083c: 6a00 0d00 |0014: sput-boolean v0, LA;.sZ:Z // field@000d +000840: 6b00 0700 |0016: sput-byte v0, LA;.sB:B // field@0007 +000844: 6c00 0800 |0018: sput-char v0, LA;.sC:C // field@0008 +000848: 6d00 0500 |001a: sput-short v0, LA;.mS:S // field@0005 +00084c: 0e00 |001c: return-void + catches : (none) + positions : + locals : + + #17 : (in LA;) + name : 'unary_ops' + type : '()V' + access : 0x0009 (PUBLIC STATIC) + code - + registers : 2 + ins : 0 + outs : 0 + insns size : 22 16-bit code units +000850: |[000850] A.unary_ops:()V +000860: 7b10 |0000: neg-int v0, v1 +000862: 7c10 |0001: not-int v0, v1 +000864: 7d10 |0002: neg-long v0, v1 +000866: 7e10 |0003: not-long v0, v1 +000868: 7f10 |0004: neg-float v0, v1 +00086a: 8010 |0005: neg-double v0, v1 +00086c: 8110 |0006: int-to-long v0, v1 +00086e: 8210 |0007: int-to-float v0, v1 +000870: 8310 |0008: int-to-double v0, v1 +000872: 8410 |0009: long-to-int v0, v1 +000874: 8510 |000a: long-to-float v0, v1 +000876: 8610 |000b: long-to-double v0, v1 +000878: 8710 |000c: float-to-int v0, v1 +00087a: 8810 |000d: float-to-long v0, v1 +00087c: 8910 |000e: float-to-double v0, v1 +00087e: 8a10 |000f: double-to-int v0, v1 +000880: 8b10 |0010: double-to-long v0, v1 +000882: 8c10 |0011: double-to-float v0, v1 +000884: 8d10 |0012: int-to-byte v0, v1 +000886: 8e10 |0013: int-to-char v0, v1 +000888: 8f10 |0014: int-to-short v0, v1 +00088a: 0e00 |0015: return-void + catches : (none) + positions : + locals : + + Virtual methods - + #0 : (in LA;) + name : 'instance_fields' + type : '()V' + access : 0x0001 (PUBLIC) + code - + registers : 2 + ins : 1 + outs : 0 + insns size : 29 16-bit code units +00088c: |[00088c] A.instance_fields:()V +00089c: 5210 0900 |0000: iget v0, v1, LA;.sI:I // field@0009 +0008a0: 5310 0a00 |0002: iget-wide v0, v1, LA;.sJ:J // field@000a +0008a4: 5410 0b00 |0004: iget-object v0, v1, LA;.sO:LA; // field@000b +0008a8: 5510 0d00 |0006: iget-boolean v0, v1, LA;.sZ:Z // field@000d +0008ac: 5610 0700 |0008: iget-byte v0, v1, LA;.sB:B // field@0007 +0008b0: 5710 0800 |000a: iget-char v0, v1, LA;.sC:C // field@0008 +0008b4: 5810 0c00 |000c: iget-short v0, v1, LA;.sS:S // field@000c +0008b8: 5910 0900 |000e: iput v0, v1, LA;.sI:I // field@0009 +0008bc: 5a10 0a00 |0010: iput-wide v0, v1, LA;.sJ:J // field@000a +0008c0: 5b10 0b00 |0012: iput-object v0, v1, LA;.sO:LA; // field@000b +0008c4: 5c10 0d00 |0014: iput-boolean v0, v1, LA;.sZ:Z // field@000d +0008c8: 5d10 0700 |0016: iput-byte v0, v1, LA;.sB:B // field@0007 +0008cc: 5e10 0800 |0018: iput-char v0, v1, LA;.sC:C // field@0008 +0008d0: 5f10 0c00 |001a: iput-short v0, v1, LA;.sS:S // field@000c +0008d4: 0e00 |001c: return-void + catches : (none) + positions : + locals : + + #1 : (in LA;) + name : 'invokes' + type : '()V' + access : 0x0001 (PUBLIC) + code - + registers : 5 + ins : 1 + outs : 1 + insns size : 15 16-bit code units +0008d8: |[0008d8] A.invokes:()V +0008e8: 6e54 0a00 1032 |0000: invoke-virtual {v0, v1, v2, v3, v4}, LA;.invokes:()V // method@000a +0008ee: 6f54 0a00 1032 |0003: invoke-super {v0, v1, v2, v3, v4}, LA;.invokes:()V // method@000a +0008f4: 7054 0a00 1032 |0006: invoke-direct {v0, v1, v2, v3, v4}, LA;.invokes:()V // method@000a +0008fa: 7154 0a00 1032 |0009: invoke-static {v0, v1, v2, v3, v4}, LA;.invokes:()V // method@000a +000900: 7254 0a00 1032 |000c: invoke-interface {v0, v1, v2, v3, v4}, LA;.invokes:()V // method@000a + catches : (none) + positions : + locals : + + source_file_idx : -1 (unknown) + diff --git a/test/dexdump/all.xml b/test/dexdump/all.xml new file mode 100644 index 0000000000..b623ecb2c1 --- /dev/null +++ b/test/dexdump/all.xml @@ -0,0 +1,211 @@ +<api> +<package name="" +> +<class name="A" + extends="java.lang.Object" + interface="false" + abstract="false" + static="false" + final="false" + visibility="public" +> +<constructor name="A" + type="A" + static="false" + final="false" + visibility="public" +> +</constructor> +<method name="arrays" + return="void" + abstract="false" + native="false" + synchronized="false" + static="true" + final="false" + visibility="public" +> +</method> +<method name="binary_ops" + return="void" + abstract="false" + native="false" + synchronized="false" + static="true" + final="false" + visibility="public" +> +</method> +<method name="binary_ops_2addr" + return="void" + abstract="false" + native="false" + synchronized="false" + static="true" + final="false" + visibility="public" +> +</method> +<method name="binary_ops_lit16" + return="void" + abstract="false" + native="false" + synchronized="false" + static="true" + final="false" + visibility="public" +> +</method> +<method name="binary_ops_lit8" + return="void" + abstract="false" + native="false" + synchronized="false" + static="true" + final="false" + visibility="public" +> +</method> +<method name="compares" + return="void" + abstract="false" + native="false" + synchronized="false" + static="true" + final="false" + visibility="public" +> +</method> +<method name="conditionals" + return="void" + abstract="false" + native="false" + synchronized="false" + static="true" + final="false" + visibility="public" +> +</method> +<method name="constants" + return="void" + abstract="false" + native="false" + synchronized="false" + static="true" + final="false" + visibility="public" +> +</method> +<method name="misc" + return="void" + abstract="false" + native="false" + synchronized="false" + static="true" + final="false" + visibility="public" +> +</method> +<method name="moves" + return="void" + abstract="false" + native="false" + synchronized="false" + static="true" + final="false" + visibility="public" +> +</method> +<method name="packed_switch" + return="void" + abstract="false" + native="false" + synchronized="false" + static="true" + final="false" + visibility="public" +> +</method> +<method name="return32" + return="int" + abstract="false" + native="false" + synchronized="false" + static="true" + final="false" + visibility="public" +> +</method> +<method name="return64" + return="int" + abstract="false" + native="false" + synchronized="false" + static="true" + final="false" + visibility="public" +> +</method> +<method name="return_object" + return="java.lang.Object" + abstract="false" + native="false" + synchronized="false" + static="true" + final="false" + visibility="public" +> +</method> +<method name="sparse_switch" + return="void" + abstract="false" + native="false" + synchronized="false" + static="true" + final="false" + visibility="public" +> +</method> +<method name="static_fields" + return="void" + abstract="false" + native="false" + synchronized="false" + static="true" + final="false" + visibility="public" +> +</method> +<method name="unary_ops" + return="void" + abstract="false" + native="false" + synchronized="false" + static="true" + final="false" + visibility="public" +> +</method> +<method name="instance_fields" + return="void" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + visibility="public" +> +</method> +<method name="invokes" + return="void" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + visibility="public" +> +</method> +</class> +</package> +</api> diff --git a/test/dexdump/bytecodes.txt b/test/dexdump/bytecodes.txt index 4c8b79b7dd..e1a381ec09 100755..100644 --- a/test/dexdump/bytecodes.txt +++ b/test/dexdump/bytecodes.txt @@ -12,8 +12,8 @@ string_ids_size : 153 string_ids_off : 112 (0x000070) type_ids_size : 42 type_ids_off : 724 (0x0002d4) -proto_ids_size : 12 -proto_ids_off : 892 (0x00037c) +proto_ids_size : 12 +proto_ids_off : 892 (0x00037c) field_ids_size : 40 field_ids_off : 1036 (0x00040c) method_ids_size : 28 @@ -36,6 +36,11 @@ instance_fields_size: 0 direct_methods_size : 0 virtual_methods_size: 1 +Class #0 annotations: +Annotations on class + VISIBILITY_RUNTIME Ljava/lang/annotation/Retention; value=CLASS + VISIBILITY_RUNTIME Ljava/lang/annotation/Target; value={ TYPE FIELD METHOD PARAMETER CONSTRUCTOR LOCAL_VARIABLE } + Class #0 - Class descriptor : 'Landroid/annotation/SuppressLint;' Access flags : 0x2601 (PUBLIC INTERFACE ABSTRACT ANNOTATION) @@ -67,6 +72,11 @@ instance_fields_size: 0 direct_methods_size : 0 virtual_methods_size: 1 +Class #1 annotations: +Annotations on class + VISIBILITY_RUNTIME Ljava/lang/annotation/Retention; value=CLASS + VISIBILITY_RUNTIME Ljava/lang/annotation/Target; value={ TYPE METHOD CONSTRUCTOR } + Class #1 - Class descriptor : 'Landroid/annotation/TargetApi;' Access flags : 0x2601 (PUBLIC INTERFACE ABSTRACT ANNOTATION) @@ -144,6 +154,11 @@ instance_fields_size: 0 direct_methods_size : 1 virtual_methods_size: 0 +Class #3 annotations: +Annotations on class + VISIBILITY_SYSTEM Ldalvik/annotation/EnclosingClass; value=Lcom/google/android/test/R; + VISIBILITY_SYSTEM Ldalvik/annotation/InnerClass; accessFlags=25 name="attr" + Class #3 - Class descriptor : 'Lcom/google/android/test/R$attr;' Access flags : 0x0011 (PUBLIC FINAL) @@ -186,6 +201,11 @@ instance_fields_size: 0 direct_methods_size : 1 virtual_methods_size: 0 +Class #4 annotations: +Annotations on class + VISIBILITY_SYSTEM Ldalvik/annotation/EnclosingClass; value=Lcom/google/android/test/R; + VISIBILITY_SYSTEM Ldalvik/annotation/InnerClass; accessFlags=25 name="drawable" + Class #4 - Class descriptor : 'Lcom/google/android/test/R$drawable;' Access flags : 0x0011 (PUBLIC FINAL) @@ -233,6 +253,10 @@ instance_fields_size: 0 direct_methods_size : 1 virtual_methods_size: 0 +Class #5 annotations: +Annotations on class + VISIBILITY_SYSTEM Ldalvik/annotation/MemberClasses; value={ Lcom/google/android/test/R$attr; Lcom/google/android/test/R$drawable; } + Class #5 - Class descriptor : 'Lcom/google/android/test/R;' Access flags : 0x0011 (PUBLIC FINAL) @@ -275,6 +299,10 @@ instance_fields_size: 20 direct_methods_size : 13 virtual_methods_size: 2 +Class #6 annotations: +Annotations on method #13 'doit' + VISIBILITY_SYSTEM Ldalvik/annotation/Throws; value={ Ljava/lang/Exception; } + Class #6 - Class descriptor : 'Lcom/google/android/test/Test;' Access flags : 0x0001 (PUBLIC) @@ -418,17 +446,17 @@ Class #6 - 000a02: 6a00 1800 |0001: sput-boolean v0, Lcom/google/android/test/Test;.sBool:Z // field@0018 000a06: 1300 1f00 |0003: const/16 v0, #int 31 // #1f 000a0a: 6b00 1700 |0005: sput-byte v0, Lcom/google/android/test/Test;.sB:B // field@0017 -000a0e: 1400 ffff 0000 |0007: const v0, #float 0.000000 // #0000ffff +000a0e: 1400 ffff 0000 |0007: const v0, #float 9.18341e-41 // #0000ffff 000a14: 6c00 1900 |000a: sput-char v0, Lcom/google/android/test/Test;.sC:C // field@0019 000a18: 1300 3412 |000c: const/16 v0, #int 4660 // #1234 000a1c: 6d00 1f00 |000e: sput-short v0, Lcom/google/android/test/Test;.sS:S // field@001f -000a20: 1400 7856 3412 |0010: const v0, #float 0.000000 // #12345678 +000a20: 1400 7856 3412 |0010: const v0, #float 5.69046e-28 // #12345678 000a26: 6700 1c00 |0013: sput v0, Lcom/google/android/test/Test;.sI:I // field@001c -000a2a: 1800 ffff cdab 7956 3412 |0015: const-wide v0, #double 0.000000 // #12345679abcdffff +000a2a: 1800 ffff cdab 7956 3412 |0015: const-wide v0, #double 5.62635e-221 // #12345679abcdffff 000a34: 6800 1d00 |001a: sput-wide v0, Lcom/google/android/test/Test;.sL:J // field@001d -000a38: 1400 00e4 4046 |001c: const v0, #float 12345.000000 // #4640e400 +000a38: 1400 00e4 4046 |001c: const v0, #float 12345 // #4640e400 000a3e: 6700 1b00 |001f: sput v0, Lcom/google/android/test/Test;.sF:F // field@001b -000a42: 1800 0000 0000 801c c840 |0021: const-wide v0, #double 12345.000000 // #40c81c8000000000 +000a42: 1800 0000 0000 801c c840 |0021: const-wide v0, #double 12345 // #40c81c8000000000 000a4c: 6800 1a00 |0026: sput-wide v0, Lcom/google/android/test/Test;.sD:D // field@001a 000a50: 1200 |0028: const/4 v0, #int 0 // #0 000a52: 6900 1e00 |0029: sput-object v0, Lcom/google/android/test/Test;.sO:Ljava/lang/Object; // field@001e @@ -471,17 +499,17 @@ Class #6 - 000ab4: 5c81 0d00 |0008: iput-boolean v1, v8, Lcom/google/android/test/Test;.mBool:Z // field@000d 000ab8: 1301 1f00 |000a: const/16 v1, #int 31 // #1f 000abc: 5d81 0c00 |000c: iput-byte v1, v8, Lcom/google/android/test/Test;.mB:B // field@000c -000ac0: 1401 ffff 0000 |000e: const v1, #float 0.000000 // #0000ffff +000ac0: 1401 ffff 0000 |000e: const v1, #float 9.18341e-41 // #0000ffff 000ac6: 5e81 0e00 |0011: iput-char v1, v8, Lcom/google/android/test/Test;.mC:C // field@000e 000aca: 1301 3412 |0013: const/16 v1, #int 4660 // #1234 000ace: 5f81 1500 |0015: iput-short v1, v8, Lcom/google/android/test/Test;.mS:S // field@0015 -000ad2: 1401 7856 3412 |0017: const v1, #float 0.000000 // #12345678 +000ad2: 1401 7856 3412 |0017: const v1, #float 5.69046e-28 // #12345678 000ad8: 5981 1100 |001a: iput v1, v8, Lcom/google/android/test/Test;.mI:I // field@0011 -000adc: 1802 ffff cdab 7956 3412 |001c: const-wide v2, #double 0.000000 // #12345679abcdffff +000adc: 1802 ffff cdab 7956 3412 |001c: const-wide v2, #double 5.62635e-221 // #12345679abcdffff 000ae6: 5a82 1200 |0021: iput-wide v2, v8, Lcom/google/android/test/Test;.mL:J // field@0012 -000aea: 1401 00e4 4046 |0023: const v1, #float 12345.000000 // #4640e400 +000aea: 1401 00e4 4046 |0023: const v1, #float 12345 // #4640e400 000af0: 5981 1000 |0026: iput v1, v8, Lcom/google/android/test/Test;.mF:F // field@0010 -000af4: 1802 0000 0000 801c c840 |0028: const-wide v2, #double 12345.000000 // #40c81c8000000000 +000af4: 1802 0000 0000 801c c840 |0028: const-wide v2, #double 12345 // #40c81c8000000000 000afe: 5a82 0f00 |002d: iput-wide v2, v8, Lcom/google/android/test/Test;.mD:D // field@000f 000b02: 1201 |002f: const/4 v1, #int 0 // #0 000b04: 5b81 1300 |0030: iput-object v1, v8, Lcom/google/android/test/Test;.mO:Ljava/lang/Object; // field@0013 @@ -626,7 +654,7 @@ Class #6 - 000cc6: 8d00 |0011: int-to-byte v0, v0 000cc8: 5db0 0c00 |0012: iput-byte v0, v11, Lcom/google/android/test/Test;.mB:B // field@000c 000ccc: 57b0 0e00 |0014: iget-char v0, v11, Lcom/google/android/test/Test;.mC:C // field@000e -000cd0: 1401 ffff 0000 |0016: const v1, #float 0.000000 // #0000ffff +000cd0: 1401 ffff 0000 |0016: const v1, #float 9.18341e-41 // #0000ffff 000cd6: b010 |0019: add-int/2addr v0, v1 000cd8: 8e00 |001a: int-to-char v0, v0 000cda: 5eb0 0e00 |001b: iput-char v0, v11, Lcom/google/android/test/Test;.mC:C // field@000e @@ -635,7 +663,7 @@ Class #6 - 000ce6: 8f00 |0021: int-to-short v0, v0 000ce8: 5fb0 1500 |0022: iput-short v0, v11, Lcom/google/android/test/Test;.mS:S // field@0015 000cec: 52b0 1100 |0024: iget v0, v11, Lcom/google/android/test/Test;.mI:I // field@0011 -000cf0: 1401 7856 3412 |0026: const v1, #float 0.000000 // #12345678 +000cf0: 1401 7856 3412 |0026: const v1, #float 5.69046e-28 // #12345678 000cf6: b010 |0029: add-int/2addr v0, v1 000cf8: 59b0 1100 |002a: iput v0, v11, Lcom/google/android/test/Test;.mI:I // field@0011 000cfc: 52b0 1100 |002c: iget v0, v11, Lcom/google/android/test/Test;.mI:I // field@0011 @@ -643,7 +671,7 @@ Class #6 - 000d04: b010 |0030: add-int/2addr v0, v1 000d06: 59b0 1100 |0031: iput v0, v11, Lcom/google/android/test/Test;.mI:I // field@0011 000d0a: 53b0 1200 |0033: iget-wide v0, v11, Lcom/google/android/test/Test;.mL:J // field@0012 -000d0e: 1802 ffff cdab 7956 3412 |0035: const-wide v2, #double 0.000000 // #12345679abcdffff +000d0e: 1802 ffff cdab 7956 3412 |0035: const-wide v2, #double 5.62635e-221 // #12345679abcdffff 000d18: bb20 |003a: add-long/2addr v0, v2 000d1a: 5ab0 1200 |003b: iput-wide v0, v11, Lcom/google/android/test/Test;.mL:J // field@0012 000d1e: 53b0 1200 |003d: iget-wide v0, v11, Lcom/google/android/test/Test;.mL:J // field@0012 @@ -651,7 +679,7 @@ Class #6 - 000d26: bb20 |0041: add-long/2addr v0, v2 000d28: 5ab0 1200 |0042: iput-wide v0, v11, Lcom/google/android/test/Test;.mL:J // field@0012 000d2c: 52b0 1000 |0044: iget v0, v11, Lcom/google/android/test/Test;.mF:F // field@0010 -000d30: 1401 00e4 4046 |0046: const v1, #float 12345.000000 // #4640e400 +000d30: 1401 00e4 4046 |0046: const v1, #float 12345 // #4640e400 000d36: 52b2 1000 |0049: iget v2, v11, Lcom/google/android/test/Test;.mF:F // field@0010 000d3a: 1503 803f |004b: const/high16 v3, #int 1065353216 // #3f80 000d3e: c732 |004d: sub-float/2addr v2, v3 @@ -664,7 +692,7 @@ Class #6 - 000d50: c610 |0056: add-float/2addr v0, v1 000d52: 59b0 1000 |0057: iput v0, v11, Lcom/google/android/test/Test;.mF:F // field@0010 000d56: 53b0 0f00 |0059: iget-wide v0, v11, Lcom/google/android/test/Test;.mD:D // field@000f -000d5a: 1802 0000 0000 801c c840 |005b: const-wide v2, #double 12345.000000 // #40c81c8000000000 +000d5a: 1802 0000 0000 801c c840 |005b: const-wide v2, #double 12345 // #40c81c8000000000 000d64: 53b4 0f00 |0060: iget-wide v4, v11, Lcom/google/android/test/Test;.mD:D // field@000f 000d68: 1906 f03f |0062: const-wide/high16 v6, #long 4607182418800017408 // #3ff0 000d6c: cc64 |0064: sub-double/2addr v4, v6 @@ -681,7 +709,7 @@ Class #6 - 000d8a: 2d00 0001 |0073: cmpl-float v0, v0, v1 000d8e: 3800 2900 |0075: if-eqz v0, 009e // +0029 000d92: 52b0 1000 |0077: iget v0, v11, Lcom/google/android/test/Test;.mF:F // field@0010 -000d96: 1401 9a99 993e |0079: const v1, #float 0.300000 // #3e99999a +000d96: 1401 9a99 993e |0079: const v1, #float 0.3 // #3e99999a 000d9c: 2d00 0001 |007c: cmpl-float v0, v0, v1 000da0: 3900 2000 |007e: if-nez v0, 009e // +0020 000da4: 52b0 1000 |0080: iget v0, v11, Lcom/google/android/test/Test;.mF:F // field@0010 @@ -707,7 +735,7 @@ Class #6 - 000df2: 2f00 0002 |00a7: cmpl-double v0, v0, v2 000df6: 3800 2b00 |00a9: if-eqz v0, 00d4 // +002b 000dfa: 53b0 0f00 |00ab: iget-wide v0, v11, Lcom/google/android/test/Test;.mD:D // field@000f -000dfe: 1802 3333 3333 3333 d33f |00ad: const-wide v2, #double 0.300000 // #3fd3333333333333 +000dfe: 1802 3333 3333 3333 d33f |00ad: const-wide v2, #double 0.3 // #3fd3333333333333 000e08: 2f00 0002 |00b2: cmpl-double v0, v0, v2 000e0c: 3900 2000 |00b4: if-nez v0, 00d4 // +0020 000e10: 53b0 0f00 |00b6: iget-wide v0, v11, Lcom/google/android/test/Test;.mD:D // field@000f @@ -790,7 +818,7 @@ Class #6 - 000eb8: 8d00 |000c: int-to-byte v0, v0 000eba: 6b00 1700 |000d: sput-byte v0, Lcom/google/android/test/Test;.sB:B // field@0017 000ebe: 6500 1900 |000f: sget-char v0, Lcom/google/android/test/Test;.sC:C // field@0019 -000ec2: 1401 ffff 0000 |0011: const v1, #float 0.000000 // #0000ffff +000ec2: 1401 ffff 0000 |0011: const v1, #float 9.18341e-41 // #0000ffff 000ec8: b010 |0014: add-int/2addr v0, v1 000eca: 8e00 |0015: int-to-char v0, v0 000ecc: 6c00 1900 |0016: sput-char v0, Lcom/google/android/test/Test;.sC:C // field@0019 @@ -799,7 +827,7 @@ Class #6 - 000ed8: 8f00 |001c: int-to-short v0, v0 000eda: 6d00 1f00 |001d: sput-short v0, Lcom/google/android/test/Test;.sS:S // field@001f 000ede: 6000 1c00 |001f: sget v0, Lcom/google/android/test/Test;.sI:I // field@001c -000ee2: 1401 7856 3412 |0021: const v1, #float 0.000000 // #12345678 +000ee2: 1401 7856 3412 |0021: const v1, #float 5.69046e-28 // #12345678 000ee8: b010 |0024: add-int/2addr v0, v1 000eea: 6700 1c00 |0025: sput v0, Lcom/google/android/test/Test;.sI:I // field@001c 000eee: 6000 1c00 |0027: sget v0, Lcom/google/android/test/Test;.sI:I // field@001c @@ -807,7 +835,7 @@ Class #6 - 000ef6: b010 |002b: add-int/2addr v0, v1 000ef8: 6700 1c00 |002c: sput v0, Lcom/google/android/test/Test;.sI:I // field@001c 000efc: 6100 1d00 |002e: sget-wide v0, Lcom/google/android/test/Test;.sL:J // field@001d -000f00: 1802 ffff cdab 7956 3412 |0030: const-wide v2, #double 0.000000 // #12345679abcdffff +000f00: 1802 ffff cdab 7956 3412 |0030: const-wide v2, #double 5.62635e-221 // #12345679abcdffff 000f0a: bb20 |0035: add-long/2addr v0, v2 000f0c: 6800 1d00 |0036: sput-wide v0, Lcom/google/android/test/Test;.sL:J // field@001d 000f10: 6100 1d00 |0038: sget-wide v0, Lcom/google/android/test/Test;.sL:J // field@001d @@ -815,7 +843,7 @@ Class #6 - 000f18: bb20 |003c: add-long/2addr v0, v2 000f1a: 6800 1d00 |003d: sput-wide v0, Lcom/google/android/test/Test;.sL:J // field@001d 000f1e: 6000 1b00 |003f: sget v0, Lcom/google/android/test/Test;.sF:F // field@001b -000f22: 1401 00e4 4046 |0041: const v1, #float 12345.000000 // #4640e400 +000f22: 1401 00e4 4046 |0041: const v1, #float 12345 // #4640e400 000f28: 6002 1b00 |0044: sget v2, Lcom/google/android/test/Test;.sF:F // field@001b 000f2c: 7f22 |0046: neg-float v2, v2 000f2e: 1503 803f |0047: const/high16 v3, #int 1065353216 // #3f80 @@ -830,7 +858,7 @@ Class #6 - 000f48: c610 |0054: add-float/2addr v0, v1 000f4a: 6700 1b00 |0055: sput v0, Lcom/google/android/test/Test;.sF:F // field@001b 000f4e: 6100 1a00 |0057: sget-wide v0, Lcom/google/android/test/Test;.sD:D // field@001a -000f52: 1802 0000 0000 801c c840 |0059: const-wide v2, #double 12345.000000 // #40c81c8000000000 +000f52: 1802 0000 0000 801c c840 |0059: const-wide v2, #double 12345 // #40c81c8000000000 000f5c: 6104 1a00 |005e: sget-wide v4, Lcom/google/android/test/Test;.sD:D // field@001a 000f60: 8044 |0060: neg-double v4, v4 000f62: 1906 f03f |0061: const-wide/high16 v6, #long 4607182418800017408 // #3ff0 diff --git a/test/dexdump/checkers.txt b/test/dexdump/checkers.txt index 5c8336f94c..aee6e647f7 100755..100644 --- a/test/dexdump/checkers.txt +++ b/test/dexdump/checkers.txt @@ -12,8 +12,8 @@ string_ids_size : 323 string_ids_off : 112 (0x000070) type_ids_size : 58 type_ids_off : 1404 (0x00057c) -proto_ids_size : 88 -proto_ids_off : 1636 (0x000664) +proto_ids_size : 88 +proto_ids_off : 1636 (0x000664) field_ids_size : 108 field_ids_off : 2692 (0x000a84) method_ids_size : 177 @@ -836,7 +836,7 @@ Class #1 - 001c8a: 1300 5829 |0147: const/16 v0, #int 10584 // #2958 001c8e: 2300 3600 |0149: new-array v0, v0, [B // type@0036 001c92: 6900 6800 |014b: sput-object v0, Lcom/google/android/checkers/g;.p:[B // field@0068 -001c96: 1400 00c1 0300 |014d: const v0, #float 0.000000 // #0003c100 +001c96: 1400 00c1 0300 |014d: const v0, #float 3.44742e-40 // #0003c100 001c9c: 2300 3600 |0150: new-array v0, v0, [B // type@0036 001ca0: 6900 6900 |0152: sput-object v0, Lcom/google/android/checkers/g;.q:[B // field@0069 001ca4: 6e10 1100 0a00 |0154: invoke-virtual {v10}, Landroid/content/Context;.getResources:()Landroid/content/res/Resources; // method@0011 @@ -2044,7 +2044,7 @@ goto options to rotate board" // string@00c2 002bd0: 5433 3b00 |004c: iget-object v3, v3, Lcom/google/android/checkers/a;.b:[I // field@003b 002bd4: 4403 0309 |004e: aget v3, v3, v9 002bd8: 5983 2a00 |0050: iput v3, v8, Lcom/google/android/checkers/CheckersView;.x:I // field@002a -002bdc: 1403 6666 663f |0052: const v3, #float 0.900000 // #3f666666 +002bdc: 1403 6666 663f |0052: const v3, #float 0.9 // #3f666666 002be2: 5983 1e00 |0055: iput v3, v8, Lcom/google/android/checkers/CheckersView;.l:F // field@001e 002be6: 3800 4500 |0057: if-eqz v0, 009c // +0045 002bea: 5483 2200 |0059: iget-object v3, v8, Lcom/google/android/checkers/CheckersView;.p:Lcom/google/android/checkers/a; // field@0022 @@ -2943,7 +2943,7 @@ goto options to rotate board" // string@00c2 0036f2: 0800 1c00 |0197: move-object/from16 v0, v28 0036f6: 5202 1e00 |0199: iget v2, v0, Lcom/google/android/checkers/CheckersView;.l:F // field@001e 0036fa: 8922 |019b: float-to-double v2, v2 -0036fc: 1804 9a99 9999 9999 a93f |019c: const-wide v4, #double 0.050000 // #3fa999999999999a +0036fc: 1804 9a99 9999 9999 a93f |019c: const-wide v4, #double 0.05 // #3fa999999999999a 003706: cc42 |01a1: sub-double/2addr v2, v4 003708: 8c22 |01a2: double-to-float v2, v2 00370a: 0800 1c00 |01a3: move-object/from16 v0, v28 @@ -3568,7 +3568,7 @@ goto options to rotate board" // string@00c2 003f38: 28e9 |001e: goto 0007 // -0017 003f3a: 1300 3075 |001f: const/16 v0, #int 30000 // #7530 003f3e: 28e6 |0021: goto 0007 // -001a -003f40: 1400 60ea 0000 |0022: const v0, #float 0.000000 // #0000ea60 +003f40: 1400 60ea 0000 |0022: const v0, #float 8.40779e-41 // #0000ea60 003f46: 28e2 |0025: goto 0007 // -001e 003f48: 0d00 |0026: move-exception v0 003f4a: 1e02 |0027: monitor-exit v2 @@ -3811,7 +3811,7 @@ Class #2 - 004024: 1302 0040 |0046: const/16 v2, #int 16384 // #4000 004028: 4b02 0001 |0048: aput v2, v0, v1 00402c: 1301 1300 |004a: const/16 v1, #int 19 // #13 -004030: 1402 0080 0000 |004c: const v2, #float 0.000000 // #00008000 +004030: 1402 0080 0000 |004c: const v2, #float 4.59177e-41 // #00008000 004036: 4b02 0001 |004f: aput v2, v0, v1 00403a: 1501 0100 |0051: const/high16 v1, #int 65536 // #1 00403e: 4b01 0006 |0053: aput v1, v0, v6 @@ -3931,7 +3931,7 @@ Class #2 - 0041f6: 1302 0040 |012f: const/16 v2, #int 16384 // #4000 0041fa: 4b02 0001 |0131: aput v2, v0, v1 0041fe: 1301 1200 |0133: const/16 v1, #int 18 // #12 -004202: 1402 0080 0000 |0135: const v2, #float 0.000000 // #00008000 +004202: 1402 0080 0000 |0135: const v2, #float 4.59177e-41 // #00008000 004208: 4b02 0001 |0138: aput v2, v0, v1 00420c: 1301 1400 |013a: const/16 v1, #int 20 // #14 004210: 1502 0100 |013c: const/high16 v2, #int 65536 // #1 @@ -3996,7 +3996,7 @@ Class #2 - 0042fa: 1301 0040 |01b1: const/16 v1, #int 16384 // #4000 0042fe: 4b01 0006 |01b3: aput v1, v0, v6 004302: 1301 1600 |01b5: const/16 v1, #int 22 // #16 -004306: 1402 0080 0000 |01b7: const v2, #float 0.000000 // #00008000 +004306: 1402 0080 0000 |01b7: const v2, #float 4.59177e-41 // #00008000 00430c: 4b02 0001 |01ba: aput v2, v0, v1 004310: 1301 1800 |01bc: const/16 v1, #int 24 // #18 004314: 1502 0200 |01be: const/high16 v2, #int 131072 // #2 @@ -4045,7 +4045,7 @@ Class #2 - 0043b4: 1301 0040 |020e: const/16 v1, #int 16384 // #4000 0043b8: 4b01 0004 |0210: aput v1, v0, v4 0043bc: 1301 0b00 |0212: const/16 v1, #int 11 // #b -0043c0: 1402 0080 0000 |0214: const v2, #float 0.000000 // #00008000 +0043c0: 1402 0080 0000 |0214: const v2, #float 4.59177e-41 // #00008000 0043c6: 4b02 0001 |0217: aput v2, v0, v1 0043ca: 1301 0d00 |0219: const/16 v1, #int 13 // #d 0043ce: 1502 0100 |021b: const/high16 v2, #int 65536 // #1 @@ -4167,7 +4167,7 @@ Class #2 - 004588: 1301 0900 |02f8: const/16 v1, #int 9 // #9 00458c: 1302 0040 |02fa: const/16 v2, #int 16384 // #4000 004590: 4b02 0001 |02fc: aput v2, v0, v1 -004594: 1401 0080 0000 |02fe: const v1, #float 0.000000 // #00008000 +004594: 1401 0080 0000 |02fe: const v1, #float 4.59177e-41 // #00008000 00459a: 4b01 0004 |0301: aput v1, v0, v4 00459e: 1301 0c00 |0303: const/16 v1, #int 12 // #c 0045a2: 1502 0100 |0305: const/high16 v2, #int 65536 // #1 @@ -4226,7 +4226,7 @@ Class #2 - 00466e: 1302 0040 |036b: const/16 v2, #int 16384 // #4000 004672: 4b02 0001 |036d: aput v2, v0, v1 004676: 1261 |036f: const/4 v1, #int 6 // #6 -004678: 1402 0080 0000 |0370: const v2, #float 0.000000 // #00008000 +004678: 1402 0080 0000 |0370: const v2, #float 4.59177e-41 // #00008000 00467e: 4b02 0001 |0373: aput v2, v0, v1 004682: 1301 0800 |0375: const/16 v1, #int 8 // #8 004686: 1502 0200 |0377: const/high16 v2, #int 131072 // #2 @@ -4496,7 +4496,7 @@ Class #2 - 004c16: 3803 3400 |0047: if-eqz v3, 007b // +0034 004c1a: 0800 1800 |0049: move-object/from16 v0, v24 004c1e: 5203 5100 |004b: iget v3, v0, Lcom/google/android/checkers/a;.x:I // field@0051 -004c22: 1404 ffff 0f00 |004d: const v4, #float 0.000000 // #000fffff +004c22: 1404 ffff 0f00 |004d: const v4, #float 1.46937e-39 // #000fffff 004c28: b534 |0050: and-int/2addr v4, v3 004c2a: 0800 1800 |0051: move-object/from16 v0, v24 004c2e: 5405 5200 |0053: iget-object v5, v0, Lcom/google/android/checkers/a;.y:[I // field@0052 @@ -4516,7 +4516,7 @@ Class #2 - 004c66: 5405 5300 |006f: iget-object v5, v0, Lcom/google/android/checkers/a;.z:[S // field@0053 004c6a: 4a04 0504 |0071: aget-short v4, v5, v4 004c6e: 2c03 8104 0000 |0073: sparse-switch v3, 000004f4 // +00000481 -004c74: 1403 3f42 0f00 |0076: const v3, #float 0.000000 // #000f423f +004c74: 1403 3f42 0f00 |0076: const v3, #float 1.4013e-39 // #000f423f 004c7a: 3334 a1ff |0079: if-ne v4, v3, 001a // -005f 004c7e: 0800 1800 |007b: move-object/from16 v0, v24 004c82: 0201 1b00 |007d: move/from16 v1, v27 @@ -4897,7 +4897,7 @@ Class #2 - 0051da: 28c4 |0329: goto 02ed // -003c 0051dc: 0200 1900 |032a: move/from16 v0, v25 0051e0: 3704 4afd |032c: if-le v4, v0, 0076 // -02b6 -0051e4: 1404 3f42 0f00 |032e: const v4, #float 0.000000 // #000f423f +0051e4: 1404 3f42 0f00 |032e: const v4, #float 1.4013e-39 // #000f423f 0051ea: 2900 45fd |0331: goto/16 0076 // -02bb 0051ee: 0200 1a00 |0333: move/from16 v0, v26 0051f2: 3404 f9ff |0335: if-lt v4, v0, 032e // -0007 @@ -5020,7 +5020,7 @@ Class #2 - 0053a2: 3545 bd00 |040d: if-ge v5, v4, 04ca // +00bd 0053a6: 0800 1800 |040f: move-object/from16 v0, v24 0053aa: 5204 3e00 |0411: iget v4, v0, Lcom/google/android/checkers/a;.e:I // field@003e -0053ae: 1405 1100 0088 |0413: const v5, #float -0.000000 // #88000011 +0053ae: 1405 1100 0088 |0413: const v5, #float -3.85187e-34 // #88000011 0053b4: b554 |0416: and-int/2addr v4, v5 0053b6: 3804 0900 |0417: if-eqz v4, 0420 // +0009 0053ba: 7110 9e00 0400 |0419: invoke-static {v4}, Ljava/lang/Integer;.bitCount:(I)I // method@009e @@ -5052,11 +5052,11 @@ Class #2 - 005418: 1507 00a0 |0448: const/high16 v7, #int -1610612736 // #a000 00541c: 3376 0400 |044a: if-ne v6, v7, 044e // +0004 005420: d803 03f4 |044c: add-int/lit8 v3, v3, #int -12 // #f4 -005424: 1406 0066 6600 |044e: const v6, #float 0.000000 // #00666600 +005424: 1406 0066 6600 |044e: const v6, #float 9.40381e-39 // #00666600 00542a: b564 |0451: and-int/2addr v4, v6 00542c: 7110 9e00 0400 |0452: invoke-static {v4}, Ljava/lang/Integer;.bitCount:(I)I // method@009e 005432: 0a04 |0455: move-result v4 -005434: 1406 0066 6600 |0456: const v6, #float 0.000000 // #00666600 +005434: 1406 0066 6600 |0456: const v6, #float 9.40381e-39 // #00666600 00543a: b565 |0459: and-int/2addr v5, v6 00543c: 7110 9e00 0500 |045a: invoke-static {v5}, Ljava/lang/Integer;.bitCount:(I)I // method@009e 005442: 0a05 |045d: move-result v5 @@ -5064,13 +5064,13 @@ Class #2 - 005446: b043 |045f: add-int/2addr v3, v4 005448: 0800 1800 |0460: move-object/from16 v0, v24 00544c: 5204 3d00 |0462: iget v4, v0, Lcom/google/android/checkers/a;.d:I // field@003d -005450: 1405 1818 1818 |0464: const v5, #float 0.000000 // #18181818 +005450: 1405 1818 1818 |0464: const v5, #float 1.96577e-24 // #18181818 005456: b554 |0467: and-int/2addr v4, v5 005458: 7110 9e00 0400 |0468: invoke-static {v4}, Ljava/lang/Integer;.bitCount:(I)I // method@009e 00545e: 0a04 |046b: move-result v4 005460: 0800 1800 |046c: move-object/from16 v0, v24 005464: 5205 3f00 |046e: iget v5, v0, Lcom/google/android/checkers/a;.f:I // field@003f -005468: 1406 1818 1818 |0470: const v6, #float 0.000000 // #18181818 +005468: 1406 1818 1818 |0470: const v6, #float 1.96577e-24 // #18181818 00546e: b565 |0473: and-int/2addr v5, v6 005470: 7110 9e00 0500 |0474: invoke-static {v5}, Ljava/lang/Integer;.bitCount:(I)I // method@009e 005476: 0a05 |0477: move-result v5 @@ -5078,7 +5078,7 @@ Class #2 - 00547a: b143 |0479: sub-int/2addr v3, v4 00547c: 0800 1800 |047a: move-object/from16 v0, v24 005480: 5204 3e00 |047c: iget v4, v0, Lcom/google/android/checkers/a;.e:I // field@003e -005484: 1405 0800 0010 |047e: const v5, #float 0.000000 // #10000008 +005484: 1405 0800 0010 |047e: const v5, #float 2.52436e-29 // #10000008 00548a: b554 |0481: and-int/2addr v4, v5 00548c: 3804 0900 |0482: if-eqz v4, 048b // +0009 005490: 7110 9e00 0400 |0484: invoke-static {v4}, Ljava/lang/Integer;.bitCount:(I)I // method@009e @@ -5087,7 +5087,7 @@ Class #2 - 00549c: b143 |048a: sub-int/2addr v3, v4 00549e: 0800 1800 |048b: move-object/from16 v0, v24 0054a2: 5204 4000 |048d: iget v4, v0, Lcom/google/android/checkers/a;.g:I // field@0040 -0054a6: 1405 0800 0010 |048f: const v5, #float 0.000000 // #10000008 +0054a6: 1405 0800 0010 |048f: const v5, #float 2.52436e-29 // #10000008 0054ac: b554 |0492: and-int/2addr v4, v5 0054ae: 3804 4c00 |0493: if-eqz v4, 04df // +004c 0054b2: 7110 9e00 0400 |0495: invoke-static {v4}, Ljava/lang/Integer;.bitCount:(I)I // method@009e @@ -5124,7 +5124,7 @@ Class #2 - 00551c: 3745 56ff |04ca: if-le v5, v4, 0420 // -00aa 005520: 0800 1800 |04cc: move-object/from16 v0, v24 005524: 5204 4000 |04ce: iget v4, v0, Lcom/google/android/checkers/a;.g:I // field@0040 -005528: 1405 1100 0088 |04d0: const v5, #float -0.000000 // #88000011 +005528: 1405 1100 0088 |04d0: const v5, #float -3.85187e-34 // #88000011 00552e: b554 |04d3: and-int/2addr v4, v5 005530: 3804 4cff |04d4: if-eqz v4, 0420 // -00b4 005534: 7110 9e00 0400 |04d6: invoke-static {v4}, Ljava/lang/Integer;.bitCount:(I)I // method@009e @@ -5407,7 +5407,7 @@ Class #2 - 005868: 0126 |0010: move v6, v2 00586a: 0135 |0011: move v5, v3 00586c: 5240 5100 |0012: iget v0, v4, Lcom/google/android/checkers/a;.x:I // field@0051 -005870: 1401 ffff 0f00 |0014: const v1, #float 0.000000 // #000fffff +005870: 1401 ffff 0f00 |0014: const v1, #float 1.46937e-39 // #000fffff 005876: b501 |0017: and-int/2addr v1, v0 005878: 5442 5200 |0018: iget-object v2, v4, Lcom/google/android/checkers/a;.y:[I // field@0052 00587c: 4b00 0201 |001a: aput v0, v2, v1 @@ -5568,19 +5568,19 @@ Class #2 - 005a54: e203 1404 |0016: ushr-int/lit8 v3, v20, #int 4 // #04 005a58: b543 |0018: and-int/2addr v3, v4 005a5a: 3803 1200 |0019: if-eqz v3, 002b // +0012 -005a5e: 1401 e0e0 e0e0 |001b: const v1, #float -129633581999069331456.000000 // #e0e0e0e0 +005a5e: 1401 e0e0 e0e0 |001b: const v1, #float -1.29634e+20 // #e0e0e0e0 005a64: b531 |001e: and-int/2addr v1, v3 005a66: e201 0105 |001f: ushr-int/lit8 v1, v1, #int 5 // #05 -005a6a: 1405 0007 0707 |0021: const v5, #float 0.000000 // #07070700 +005a6a: 1405 0007 0707 |0021: const v5, #float 1.01583e-34 // #07070700 005a70: b553 |0024: and-int/2addr v3, v5 005a72: e203 0303 |0025: ushr-int/lit8 v3, v3, #int 3 // #03 005a76: b631 |0027: or-int/2addr v1, v3 005a78: b521 |0028: and-int/2addr v1, v2 005a7a: de01 0100 |0029: or-int/lit8 v1, v1, #int 0 // #00 -005a7e: 1403 e0e0 e0e0 |002b: const v3, #float -129633581999069331456.000000 // #e0e0e0e0 +005a7e: 1403 e0e0 e0e0 |002b: const v3, #float -1.29634e+20 // #e0e0e0e0 005a84: 9503 0314 |002e: and-int v3, v3, v20 005a88: e203 0305 |0030: ushr-int/lit8 v3, v3, #int 5 // #05 -005a8c: 1405 0007 0707 |0032: const v5, #float 0.000000 // #07070700 +005a8c: 1405 0007 0707 |0032: const v5, #float 1.01583e-34 // #07070700 005a92: 9505 0514 |0035: and-int v5, v5, v20 005a96: e205 0503 |0037: ushr-int/lit8 v5, v5, #int 3 // #03 005a9a: b653 |0039: or-int/2addr v3, v5 @@ -5597,19 +5597,19 @@ Class #2 - 005abc: 3802 1500 |004a: if-eqz v2, 005f // +0015 005ac0: 0800 1100 |004c: move-object/from16 v0, v17 005ac4: 5203 3e00 |004e: iget v3, v0, Lcom/google/android/checkers/a;.e:I // field@003e -005ac8: 1405 0707 0707 |0050: const v5, #float 0.000000 // #07070707 +005ac8: 1405 0707 0707 |0050: const v5, #float 1.01583e-34 // #07070707 005ace: b525 |0053: and-int/2addr v5, v2 005ad0: e005 0505 |0054: shl-int/lit8 v5, v5, #int 5 // #05 -005ad4: 1406 e0e0 e000 |0056: const v6, #float 0.000000 // #00e0e0e0 +005ad4: 1406 e0e0 e000 |0056: const v6, #float 2.06518e-38 // #00e0e0e0 005ada: b562 |0059: and-int/2addr v2, v6 005adc: e002 0203 |005a: shl-int/lit8 v2, v2, #int 3 // #03 005ae0: b652 |005c: or-int/2addr v2, v5 005ae2: b532 |005d: and-int/2addr v2, v3 005ae4: b621 |005e: or-int/2addr v1, v2 -005ae6: 1402 0707 0707 |005f: const v2, #float 0.000000 // #07070707 +005ae6: 1402 0707 0707 |005f: const v2, #float 1.01583e-34 // #07070707 005aec: 9502 0214 |0062: and-int v2, v2, v20 005af0: e002 0205 |0064: shl-int/lit8 v2, v2, #int 5 // #05 -005af4: 1403 e0e0 e000 |0066: const v3, #float 0.000000 // #00e0e0e0 +005af4: 1403 e0e0 e000 |0066: const v3, #float 2.06518e-38 // #00e0e0e0 005afa: 9503 0314 |0069: and-int v3, v3, v20 005afe: e003 0303 |006b: shl-int/lit8 v3, v3, #int 3 // #03 005b02: b632 |006d: or-int/2addr v2, v3 @@ -5802,19 +5802,19 @@ Class #2 - 005dd4: 3803 1600 |01d6: if-eqz v3, 01ec // +0016 005dd8: 0800 1100 |01d8: move-object/from16 v0, v17 005ddc: 5201 4000 |01da: iget v1, v0, Lcom/google/android/checkers/a;.g:I // field@0040 -005de0: 1405 e0e0 e0e0 |01dc: const v5, #float -129633581999069331456.000000 // #e0e0e0e0 +005de0: 1405 e0e0 e0e0 |01dc: const v5, #float -1.29634e+20 // #e0e0e0e0 005de6: b535 |01df: and-int/2addr v5, v3 005de8: e205 0505 |01e0: ushr-int/lit8 v5, v5, #int 5 // #05 -005dec: 1406 0007 0707 |01e2: const v6, #float 0.000000 // #07070700 +005dec: 1406 0007 0707 |01e2: const v6, #float 1.01583e-34 // #07070700 005df2: b563 |01e5: and-int/2addr v3, v6 005df4: e203 0303 |01e6: ushr-int/lit8 v3, v3, #int 3 // #03 005df8: b653 |01e8: or-int/2addr v3, v5 005dfa: b531 |01e9: and-int/2addr v1, v3 005dfc: de01 0100 |01ea: or-int/lit8 v1, v1, #int 0 // #00 -005e00: 1403 e0e0 e0e0 |01ec: const v3, #float -129633581999069331456.000000 // #e0e0e0e0 +005e00: 1403 e0e0 e0e0 |01ec: const v3, #float -1.29634e+20 // #e0e0e0e0 005e06: 9503 0314 |01ef: and-int v3, v3, v20 005e0a: e203 0305 |01f1: ushr-int/lit8 v3, v3, #int 5 // #05 -005e0e: 1405 0007 0707 |01f3: const v5, #float 0.000000 // #07070700 +005e0e: 1405 0007 0707 |01f3: const v5, #float 1.01583e-34 // #07070700 005e14: 9505 0514 |01f6: and-int v5, v5, v20 005e18: e205 0503 |01f8: ushr-int/lit8 v5, v5, #int 3 // #03 005e1c: b653 |01fa: or-int/2addr v3, v5 @@ -5828,19 +5828,19 @@ Class #2 - 005e34: e003 1404 |0206: shl-int/lit8 v3, v20, #int 4 // #04 005e38: b543 |0208: and-int/2addr v3, v4 005e3a: 3803 1100 |0209: if-eqz v3, 021a // +0011 -005e3e: 1405 0707 0707 |020b: const v5, #float 0.000000 // #07070707 +005e3e: 1405 0707 0707 |020b: const v5, #float 1.01583e-34 // #07070707 005e44: b535 |020e: and-int/2addr v5, v3 005e46: e005 0505 |020f: shl-int/lit8 v5, v5, #int 5 // #05 -005e4a: 1406 e0e0 e000 |0211: const v6, #float 0.000000 // #00e0e0e0 +005e4a: 1406 e0e0 e000 |0211: const v6, #float 2.06518e-38 // #00e0e0e0 005e50: b563 |0214: and-int/2addr v3, v6 005e52: e003 0303 |0215: shl-int/lit8 v3, v3, #int 3 // #03 005e56: b653 |0217: or-int/2addr v3, v5 005e58: b523 |0218: and-int/2addr v3, v2 005e5a: b631 |0219: or-int/2addr v1, v3 -005e5c: 1403 0707 0707 |021a: const v3, #float 0.000000 // #07070707 +005e5c: 1403 0707 0707 |021a: const v3, #float 1.01583e-34 // #07070707 005e62: 9503 0314 |021d: and-int v3, v3, v20 005e66: e003 0305 |021f: shl-int/lit8 v3, v3, #int 5 // #05 -005e6a: 1405 e0e0 e000 |0221: const v5, #float 0.000000 // #00e0e0e0 +005e6a: 1405 e0e0 e000 |0221: const v5, #float 2.06518e-38 // #00e0e0e0 005e70: 9505 0514 |0224: and-int v5, v5, v20 005e74: e005 0503 |0226: shl-int/lit8 v5, v5, #int 3 // #03 005e78: b653 |0228: or-int/2addr v3, v5 @@ -6423,9 +6423,9 @@ Class #2 - outs : 6 insns size : 461 16-bit code units 006604: |[006604] com.google.android.checkers.a.b:(IZI)Z -006614: 1404 e0e0 e000 |0000: const v4, #float 0.000000 // #00e0e0e0 +006614: 1404 e0e0 e000 |0000: const v4, #float 2.06518e-38 // #00e0e0e0 00661a: 1216 |0003: const/4 v6, #int 1 // #1 -00661c: 1403 e0e0 e0e0 |0004: const v3, #float -129633581999069331456.000000 // #e0e0e0e0 +00661c: 1403 e0e0 e0e0 |0004: const v3, #float -1.29634e+20 // #e0e0e0e0 006622: 130a 0008 |0007: const/16 v10, #int 2048 // #800 006626: 1309 0002 |0009: const/16 v9, #int 512 // #200 00662a: 380d e400 |000b: if-eqz v13, 00ef // +00e4 @@ -6436,7 +6436,7 @@ Class #2 - 00663e: 9502 0e03 |0015: and-int v2, v14, v3 006642: e202 0205 |0017: ushr-int/lit8 v2, v2, #int 5 // #05 006646: b621 |0019: or-int/2addr v1, v2 -006648: 1402 0007 0707 |001a: const v2, #float 0.000000 // #07070700 +006648: 1402 0007 0707 |001a: const v2, #float 1.01583e-34 // #07070700 00664e: b5e2 |001d: and-int/2addr v2, v14 006650: e202 0203 |001e: ushr-int/lit8 v2, v2, #int 3 // #03 006654: b621 |0020: or-int/2addr v1, v2 @@ -6453,14 +6453,14 @@ Class #2 - 006676: 9502 0e03 |0031: and-int v2, v14, v3 00667a: e202 0205 |0033: ushr-int/lit8 v2, v2, #int 5 // #05 00667e: b621 |0035: or-int/2addr v1, v2 -006680: 1402 0007 0707 |0036: const v2, #float 0.000000 // #07070700 +006680: 1402 0007 0707 |0036: const v2, #float 1.01583e-34 // #07070700 006686: b5e2 |0039: and-int/2addr v2, v14 006688: e202 0203 |003a: ushr-int/lit8 v2, v2, #int 3 // #03 00668c: b621 |003c: or-int/2addr v1, v2 00668e: b510 |003d: and-int/2addr v0, v1 006690: 52b1 3e00 |003e: iget v1, v11, Lcom/google/android/checkers/a;.e:I // field@003e 006694: e002 0e04 |0040: shl-int/lit8 v2, v14, #int 4 // #04 -006698: 1403 0707 0707 |0042: const v3, #float 0.000000 // #07070707 +006698: 1403 0707 0707 |0042: const v3, #float 1.01583e-34 // #07070707 00669e: b5e3 |0045: and-int/2addr v3, v14 0066a0: e003 0305 |0046: shl-int/lit8 v3, v3, #int 5 // #05 0066a4: b632 |0048: or-int/2addr v2, v3 @@ -6563,7 +6563,7 @@ Class #2 - 0067f6: 3900 5400 |00f1: if-nez v0, 0145 // +0054 0067fa: 52b0 3f00 |00f3: iget v0, v11, Lcom/google/android/checkers/a;.f:I // field@003f 0067fe: e001 0e04 |00f5: shl-int/lit8 v1, v14, #int 4 // #04 -006802: 1402 0707 0707 |00f7: const v2, #float 0.000000 // #07070707 +006802: 1402 0707 0707 |00f7: const v2, #float 1.01583e-34 // #07070707 006808: b5e2 |00fa: and-int/2addr v2, v14 00680a: e002 0205 |00fb: shl-int/lit8 v2, v2, #int 5 // #05 00680e: b621 |00fd: or-int/2addr v1, v2 @@ -6611,7 +6611,7 @@ Class #2 - 0068a2: 52b1 3f00 |0147: iget v1, v11, Lcom/google/android/checkers/a;.f:I // field@003f 0068a6: b610 |0149: or-int/2addr v0, v1 0068a8: e001 0e04 |014a: shl-int/lit8 v1, v14, #int 4 // #04 -0068ac: 1402 0707 0707 |014c: const v2, #float 0.000000 // #07070707 +0068ac: 1402 0707 0707 |014c: const v2, #float 1.01583e-34 // #07070707 0068b2: b5e2 |014f: and-int/2addr v2, v14 0068b4: e002 0205 |0150: shl-int/lit8 v2, v2, #int 5 // #05 0068b8: b621 |0152: or-int/2addr v1, v2 @@ -6624,7 +6624,7 @@ Class #2 - 0068ce: b5e3 |015d: and-int/2addr v3, v14 0068d0: e203 0305 |015e: ushr-int/lit8 v3, v3, #int 5 // #05 0068d4: b632 |0160: or-int/2addr v2, v3 -0068d6: 1403 0007 0707 |0161: const v3, #float 0.000000 // #07070700 +0068d6: 1403 0007 0707 |0161: const v3, #float 1.01583e-34 // #07070700 0068dc: b5e3 |0164: and-int/2addr v3, v14 0068de: e203 0303 |0165: ushr-int/lit8 v3, v3, #int 3 // #03 0068e2: b632 |0167: or-int/2addr v2, v3 diff --git a/test/dexdump/run-all-tests b/test/dexdump/run-all-tests index 11ab55ae30..c9976cd090 100755 --- a/test/dexdump/run-all-tests +++ b/test/dexdump/run-all-tests @@ -39,7 +39,7 @@ mkdir ${tmpdir} # Set up dexdump binary and flags to test. DEXD="${ANDROID_HOST_OUT}/bin/dexdump2" -DEXDFLAGS1="-dfh" +DEXDFLAGS1="-adfh" DEXDFLAGS2="-e -l xml" # Set up dexlist binary and flags to test. diff --git a/test/dexdump/staticfields.txt b/test/dexdump/staticfields.txt index 022605f90d..f6d8f1924f 100644 --- a/test/dexdump/staticfields.txt +++ b/test/dexdump/staticfields.txt @@ -12,8 +12,8 @@ string_ids_size : 28 string_ids_off : 112 (0x000070) type_ids_size : 12 type_ids_off : 224 (0x0000e0) -proto_ids_size : 1 -proto_ids_off : 272 (0x000110) +proto_ids_size : 1 +proto_ids_off : 272 (0x000110) field_ids_size : 12 field_ids_off : 284 (0x00011c) method_ids_size : 2 @@ -71,12 +71,12 @@ Class #0 - name : 'test05_public_static_final_float_46_47' type : 'F' access : 0x0019 (PUBLIC STATIC FINAL) - value : 46.470001 + value : 46.47 #6 : (in LStaticFields;) name : 'test06_public_static_final_double_48_49' type : 'D' access : 0x0019 (PUBLIC STATIC FINAL) - value : 48.490000 + value : 48.49 #7 : (in LStaticFields;) name : 'test07_public_static_final_string' type : 'Ljava/lang/String;' diff --git a/test/dexdump/staticfields.xml b/test/dexdump/staticfields.xml index c906f0a3dd..9082f0ef4d 100644 --- a/test/dexdump/staticfields.xml +++ b/test/dexdump/staticfields.xml @@ -66,7 +66,7 @@ static="true" final="true" visibility="public" - value="46.470001" + value="46.47" > </field> <field name="test06_public_static_final_double_48_49" @@ -76,7 +76,7 @@ static="true" final="true" visibility="public" - value="48.490000" + value="48.49" > </field> <field name="test07_public_static_final_string" @@ -86,7 +86,7 @@ static="true" final="true" visibility="public" - value="abc \><"'&	
" + value="abc \><"'&	
" > </field> <field name="test08_public_static_final_object_null" diff --git a/test/dexdump/values.dex b/test/dexdump/values.dex Binary files differnew file mode 100644 index 0000000000..84602d03c2 --- /dev/null +++ b/test/dexdump/values.dex diff --git a/test/dexdump/values.lst b/test/dexdump/values.lst new file mode 100644 index 0000000000..0dbe3a9ae9 --- /dev/null +++ b/test/dexdump/values.lst @@ -0,0 +1,3 @@ +#values.dex +0x000003bc 8 Test <clinit> ()V Test.java 66 +0x000003d4 8 Test <init> ()V Test.java 1 diff --git a/test/dexdump/values.txt b/test/dexdump/values.txt new file mode 100644 index 0000000000..7f831b17b8 --- /dev/null +++ b/test/dexdump/values.txt @@ -0,0 +1,355 @@ +Processing 'values.dex'... +Opened 'values.dex', DEX version '035' +DEX file header: +magic : 'dex\n035\0' +checksum : 7605eec0 +signature : c197...a065 +file_size : 1864 +header_size : 112 +link_size : 0 +link_off : 0 (0x000000) +string_ids_size : 70 +string_ids_off : 112 (0x000070) +type_ids_size : 12 +type_ids_off : 392 (0x000188) +proto_ids_size : 1 +proto_ids_off : 440 (0x0001b8) +field_ids_size : 54 +field_ids_off : 452 (0x0001c4) +method_ids_size : 3 +method_ids_off : 884 (0x000374) +class_defs_size : 1 +class_defs_off : 908 (0x00038c) +data_size : 924 +data_off : 940 (0x0003ac) + +Class #0 header: +class_idx : 6 +access_flags : 1 (0x0001) +superclass_idx : 7 +interfaces_off : 0 (0x000000) +source_file_idx : 13 +annotations_off : 0 (0x000000) +class_data_off : 1578 (0x00062a) +static_fields_size : 54 +instance_fields_size: 0 +direct_methods_size : 2 +virtual_methods_size: 0 + +Class #0 - + Class descriptor : 'LTest;' + Access flags : 0x0001 (PUBLIC) + Superclass : 'Ljava/lang/Object;' + Interfaces - + Static fields - + #0 : (in LTest;) + name : 'mB0' + type : 'B' + access : 0x0019 (PUBLIC STATIC FINAL) + value : 0 + #1 : (in LTest;) + name : 'mB1' + type : 'B' + access : 0x0019 (PUBLIC STATIC FINAL) + value : 127 + #2 : (in LTest;) + name : 'mB2' + type : 'B' + access : 0x0019 (PUBLIC STATIC FINAL) + value : -128 + #3 : (in LTest;) + name : 'mB3' + type : 'B' + access : 0x0019 (PUBLIC STATIC FINAL) + value : -1 + #4 : (in LTest;) + name : 'mC0' + type : 'C' + access : 0x0019 (PUBLIC STATIC FINAL) + value : 0 + #5 : (in LTest;) + name : 'mC1' + type : 'C' + access : 0x0019 (PUBLIC STATIC FINAL) + value : 32767 + #6 : (in LTest;) + name : 'mC2' + type : 'C' + access : 0x0019 (PUBLIC STATIC FINAL) + value : 32768 + #7 : (in LTest;) + name : 'mC3' + type : 'C' + access : 0x0019 (PUBLIC STATIC FINAL) + value : 255 + #8 : (in LTest;) + name : 'mC4' + type : 'C' + access : 0x0019 (PUBLIC STATIC FINAL) + value : 65520 + #9 : (in LTest;) + name : 'mC5' + type : 'C' + access : 0x0019 (PUBLIC STATIC FINAL) + value : 65535 + #10 : (in LTest;) + name : 'mD0' + type : 'D' + access : 0x0019 (PUBLIC STATIC FINAL) + value : -inf + #11 : (in LTest;) + name : 'mD1' + type : 'D' + access : 0x0019 (PUBLIC STATIC FINAL) + value : 4.94066e-324 + #12 : (in LTest;) + name : 'mD2' + type : 'D' + access : 0x0019 (PUBLIC STATIC FINAL) + value : -0 + #13 : (in LTest;) + name : 'mD3' + type : 'D' + access : 0x0019 (PUBLIC STATIC FINAL) + value : 0 + #14 : (in LTest;) + name : 'mD4' + type : 'D' + access : 0x0019 (PUBLIC STATIC FINAL) + value : 1.79769e+308 + #15 : (in LTest;) + name : 'mD5' + type : 'D' + access : 0x0019 (PUBLIC STATIC FINAL) + value : inf + #16 : (in LTest;) + name : 'mD6' + type : 'D' + access : 0x0019 (PUBLIC STATIC FINAL) + value : nan + #17 : (in LTest;) + name : 'mF0' + type : 'F' + access : 0x0019 (PUBLIC STATIC FINAL) + value : -inf + #18 : (in LTest;) + name : 'mF1' + type : 'F' + access : 0x0019 (PUBLIC STATIC FINAL) + value : 1.4013e-45 + #19 : (in LTest;) + name : 'mF2' + type : 'F' + access : 0x0019 (PUBLIC STATIC FINAL) + value : -0 + #20 : (in LTest;) + name : 'mF3' + type : 'F' + access : 0x0019 (PUBLIC STATIC FINAL) + value : 0 + #21 : (in LTest;) + name : 'mF4' + type : 'F' + access : 0x0019 (PUBLIC STATIC FINAL) + value : 3.40282e+38 + #22 : (in LTest;) + name : 'mF5' + type : 'F' + access : 0x0019 (PUBLIC STATIC FINAL) + value : inf + #23 : (in LTest;) + name : 'mF6' + type : 'F' + access : 0x0019 (PUBLIC STATIC FINAL) + value : nan + #24 : (in LTest;) + name : 'mI0' + type : 'I' + access : 0x0019 (PUBLIC STATIC FINAL) + value : 0 + #25 : (in LTest;) + name : 'mI1' + type : 'I' + access : 0x0019 (PUBLIC STATIC FINAL) + value : 2147483647 + #26 : (in LTest;) + name : 'mI2' + type : 'I' + access : 0x0019 (PUBLIC STATIC FINAL) + value : -2147483648 + #27 : (in LTest;) + name : 'mI3' + type : 'I' + access : 0x0019 (PUBLIC STATIC FINAL) + value : 255 + #28 : (in LTest;) + name : 'mI4' + type : 'I' + access : 0x0019 (PUBLIC STATIC FINAL) + value : -16 + #29 : (in LTest;) + name : 'mI5' + type : 'I' + access : 0x0019 (PUBLIC STATIC FINAL) + value : -4096 + #30 : (in LTest;) + name : 'mI6' + type : 'I' + access : 0x0019 (PUBLIC STATIC FINAL) + value : -1048576 + #31 : (in LTest;) + name : 'mI7' + type : 'I' + access : 0x0019 (PUBLIC STATIC FINAL) + value : -1 + #32 : (in LTest;) + name : 'mJ0' + type : 'J' + access : 0x0019 (PUBLIC STATIC FINAL) + value : 0 + #33 : (in LTest;) + name : 'mJ1' + type : 'J' + access : 0x0019 (PUBLIC STATIC FINAL) + value : 9223372036854775807 + #34 : (in LTest;) + name : 'mJ2' + type : 'J' + access : 0x0019 (PUBLIC STATIC FINAL) + value : -9223372036854775808 + #35 : (in LTest;) + name : 'mJ3' + type : 'J' + access : 0x0019 (PUBLIC STATIC FINAL) + value : 255 + #36 : (in LTest;) + name : 'mJ4' + type : 'J' + access : 0x0019 (PUBLIC STATIC FINAL) + value : -16 + #37 : (in LTest;) + name : 'mJ5' + type : 'J' + access : 0x0019 (PUBLIC STATIC FINAL) + value : -4096 + #38 : (in LTest;) + name : 'mJ6' + type : 'J' + access : 0x0019 (PUBLIC STATIC FINAL) + value : -1048576 + #39 : (in LTest;) + name : 'mJ7' + type : 'J' + access : 0x0019 (PUBLIC STATIC FINAL) + value : -268435456 + #40 : (in LTest;) + name : 'mJ8' + type : 'J' + access : 0x0019 (PUBLIC STATIC FINAL) + value : -68719476736 + #41 : (in LTest;) + name : 'mJ9' + type : 'J' + access : 0x0019 (PUBLIC STATIC FINAL) + value : -17592186044416 + #42 : (in LTest;) + name : 'mJa' + type : 'J' + access : 0x0019 (PUBLIC STATIC FINAL) + value : -4503599627370496 + #43 : (in LTest;) + name : 'mJb' + type : 'J' + access : 0x0019 (PUBLIC STATIC FINAL) + value : -1 + #44 : (in LTest;) + name : 'mObject' + type : 'Ljava/lang/Object;' + access : 0x0019 (PUBLIC STATIC FINAL) + value : null + #45 : (in LTest;) + name : 'mS0' + type : 'S' + access : 0x0019 (PUBLIC STATIC FINAL) + value : 0 + #46 : (in LTest;) + name : 'mS1' + type : 'S' + access : 0x0019 (PUBLIC STATIC FINAL) + value : 32767 + #47 : (in LTest;) + name : 'mS2' + type : 'S' + access : 0x0019 (PUBLIC STATIC FINAL) + value : -32768 + #48 : (in LTest;) + name : 'mS3' + type : 'S' + access : 0x0019 (PUBLIC STATIC FINAL) + value : 255 + #49 : (in LTest;) + name : 'mS4' + type : 'S' + access : 0x0019 (PUBLIC STATIC FINAL) + value : -16 + #50 : (in LTest;) + name : 'mS5' + type : 'S' + access : 0x0019 (PUBLIC STATIC FINAL) + value : -1 + #51 : (in LTest;) + name : 'mString' + type : 'Ljava/lang/String;' + access : 0x0019 (PUBLIC STATIC FINAL) + value : "<&\"JOHO\"&>\n" + #52 : (in LTest;) + name : 'mZ0' + type : 'Z' + access : 0x0019 (PUBLIC STATIC FINAL) + value : false + #53 : (in LTest;) + name : 'mZ1' + type : 'Z' + access : 0x0019 (PUBLIC STATIC FINAL) + value : true + Instance fields - + Direct methods - + #0 : (in LTest;) + name : '<clinit>' + type : '()V' + access : 0x10008 (STATIC CONSTRUCTOR) + code - + registers : 1 + ins : 0 + outs : 0 + insns size : 4 16-bit code units +0003ac: |[0003ac] Test.<clinit>:()V +0003bc: 1200 |0000: const/4 v0, #int 0 // #0 +0003be: 6900 2c00 |0001: sput-object v0, LTest;.mObject:Ljava/lang/Object; // field@002c +0003c2: 0e00 |0003: return-void + catches : (none) + positions : + 0x0000 line=66 + locals : + + #1 : (in LTest;) + name : '<init>' + type : '()V' + access : 0x10001 (PUBLIC CONSTRUCTOR) + code - + registers : 1 + ins : 1 + outs : 1 + insns size : 4 16-bit code units +0003c4: |[0003c4] Test.<init>:()V +0003d4: 7010 0200 0000 |0000: invoke-direct {v0}, Ljava/lang/Object;.<init>:()V // method@0002 +0003da: 0e00 |0003: return-void + catches : (none) + positions : + 0x0000 line=1 + locals : + 0x0000 - 0x0004 reg=0 this LTest; + + Virtual methods - + source_file_idx : 13 (Test.java) + diff --git a/test/dexdump/values.xml b/test/dexdump/values.xml new file mode 100644 index 0000000000..d6ba48da79 --- /dev/null +++ b/test/dexdump/values.xml @@ -0,0 +1,561 @@ +<api> +<package name="" +> +<class name="Test" + extends="java.lang.Object" + interface="false" + abstract="false" + static="false" + final="false" + visibility="public" +> +<field name="mB0" + type="byte" + transient="false" + volatile="false" + static="true" + final="true" + visibility="public" + value="0" +> +</field> +<field name="mB1" + type="byte" + transient="false" + volatile="false" + static="true" + final="true" + visibility="public" + value="127" +> +</field> +<field name="mB2" + type="byte" + transient="false" + volatile="false" + static="true" + final="true" + visibility="public" + value="-128" +> +</field> +<field name="mB3" + type="byte" + transient="false" + volatile="false" + static="true" + final="true" + visibility="public" + value="-1" +> +</field> +<field name="mC0" + type="char" + transient="false" + volatile="false" + static="true" + final="true" + visibility="public" + value="0" +> +</field> +<field name="mC1" + type="char" + transient="false" + volatile="false" + static="true" + final="true" + visibility="public" + value="32767" +> +</field> +<field name="mC2" + type="char" + transient="false" + volatile="false" + static="true" + final="true" + visibility="public" + value="32768" +> +</field> +<field name="mC3" + type="char" + transient="false" + volatile="false" + static="true" + final="true" + visibility="public" + value="255" +> +</field> +<field name="mC4" + type="char" + transient="false" + volatile="false" + static="true" + final="true" + visibility="public" + value="65520" +> +</field> +<field name="mC5" + type="char" + transient="false" + volatile="false" + static="true" + final="true" + visibility="public" + value="65535" +> +</field> +<field name="mD0" + type="double" + transient="false" + volatile="false" + static="true" + final="true" + visibility="public" + value="-inf" +> +</field> +<field name="mD1" + type="double" + transient="false" + volatile="false" + static="true" + final="true" + visibility="public" + value="4.94066e-324" +> +</field> +<field name="mD2" + type="double" + transient="false" + volatile="false" + static="true" + final="true" + visibility="public" + value="-0" +> +</field> +<field name="mD3" + type="double" + transient="false" + volatile="false" + static="true" + final="true" + visibility="public" + value="0" +> +</field> +<field name="mD4" + type="double" + transient="false" + volatile="false" + static="true" + final="true" + visibility="public" + value="1.79769e+308" +> +</field> +<field name="mD5" + type="double" + transient="false" + volatile="false" + static="true" + final="true" + visibility="public" + value="inf" +> +</field> +<field name="mD6" + type="double" + transient="false" + volatile="false" + static="true" + final="true" + visibility="public" + value="nan" +> +</field> +<field name="mF0" + type="float" + transient="false" + volatile="false" + static="true" + final="true" + visibility="public" + value="-inf" +> +</field> +<field name="mF1" + type="float" + transient="false" + volatile="false" + static="true" + final="true" + visibility="public" + value="1.4013e-45" +> +</field> +<field name="mF2" + type="float" + transient="false" + volatile="false" + static="true" + final="true" + visibility="public" + value="-0" +> +</field> +<field name="mF3" + type="float" + transient="false" + volatile="false" + static="true" + final="true" + visibility="public" + value="0" +> +</field> +<field name="mF4" + type="float" + transient="false" + volatile="false" + static="true" + final="true" + visibility="public" + value="3.40282e+38" +> +</field> +<field name="mF5" + type="float" + transient="false" + volatile="false" + static="true" + final="true" + visibility="public" + value="inf" +> +</field> +<field name="mF6" + type="float" + transient="false" + volatile="false" + static="true" + final="true" + visibility="public" + value="nan" +> +</field> +<field name="mI0" + type="int" + transient="false" + volatile="false" + static="true" + final="true" + visibility="public" + value="0" +> +</field> +<field name="mI1" + type="int" + transient="false" + volatile="false" + static="true" + final="true" + visibility="public" + value="2147483647" +> +</field> +<field name="mI2" + type="int" + transient="false" + volatile="false" + static="true" + final="true" + visibility="public" + value="-2147483648" +> +</field> +<field name="mI3" + type="int" + transient="false" + volatile="false" + static="true" + final="true" + visibility="public" + value="255" +> +</field> +<field name="mI4" + type="int" + transient="false" + volatile="false" + static="true" + final="true" + visibility="public" + value="-16" +> +</field> +<field name="mI5" + type="int" + transient="false" + volatile="false" + static="true" + final="true" + visibility="public" + value="-4096" +> +</field> +<field name="mI6" + type="int" + transient="false" + volatile="false" + static="true" + final="true" + visibility="public" + value="-1048576" +> +</field> +<field name="mI7" + type="int" + transient="false" + volatile="false" + static="true" + final="true" + visibility="public" + value="-1" +> +</field> +<field name="mJ0" + type="long" + transient="false" + volatile="false" + static="true" + final="true" + visibility="public" + value="0" +> +</field> +<field name="mJ1" + type="long" + transient="false" + volatile="false" + static="true" + final="true" + visibility="public" + value="9223372036854775807" +> +</field> +<field name="mJ2" + type="long" + transient="false" + volatile="false" + static="true" + final="true" + visibility="public" + value="-9223372036854775808" +> +</field> +<field name="mJ3" + type="long" + transient="false" + volatile="false" + static="true" + final="true" + visibility="public" + value="255" +> +</field> +<field name="mJ4" + type="long" + transient="false" + volatile="false" + static="true" + final="true" + visibility="public" + value="-16" +> +</field> +<field name="mJ5" + type="long" + transient="false" + volatile="false" + static="true" + final="true" + visibility="public" + value="-4096" +> +</field> +<field name="mJ6" + type="long" + transient="false" + volatile="false" + static="true" + final="true" + visibility="public" + value="-1048576" +> +</field> +<field name="mJ7" + type="long" + transient="false" + volatile="false" + static="true" + final="true" + visibility="public" + value="-268435456" +> +</field> +<field name="mJ8" + type="long" + transient="false" + volatile="false" + static="true" + final="true" + visibility="public" + value="-68719476736" +> +</field> +<field name="mJ9" + type="long" + transient="false" + volatile="false" + static="true" + final="true" + visibility="public" + value="-17592186044416" +> +</field> +<field name="mJa" + type="long" + transient="false" + volatile="false" + static="true" + final="true" + visibility="public" + value="-4503599627370496" +> +</field> +<field name="mJb" + type="long" + transient="false" + volatile="false" + static="true" + final="true" + visibility="public" + value="-1" +> +</field> +<field name="mObject" + type="java.lang.Object" + transient="false" + volatile="false" + static="true" + final="true" + visibility="public" + value="null" +> +</field> +<field name="mS0" + type="short" + transient="false" + volatile="false" + static="true" + final="true" + visibility="public" + value="0" +> +</field> +<field name="mS1" + type="short" + transient="false" + volatile="false" + static="true" + final="true" + visibility="public" + value="32767" +> +</field> +<field name="mS2" + type="short" + transient="false" + volatile="false" + static="true" + final="true" + visibility="public" + value="-32768" +> +</field> +<field name="mS3" + type="short" + transient="false" + volatile="false" + static="true" + final="true" + visibility="public" + value="255" +> +</field> +<field name="mS4" + type="short" + transient="false" + volatile="false" + static="true" + final="true" + visibility="public" + value="-16" +> +</field> +<field name="mS5" + type="short" + transient="false" + volatile="false" + static="true" + final="true" + visibility="public" + value="-1" +> +</field> +<field name="mString" + type="java.lang.String" + transient="false" + volatile="false" + static="true" + final="true" + visibility="public" + value="<&"JOHO"&>
" +> +</field> +<field name="mZ0" + type="boolean" + transient="false" + volatile="false" + static="true" + final="true" + visibility="public" + value="false" +> +</field> +<field name="mZ1" + type="boolean" + transient="false" + volatile="false" + static="true" + final="true" + visibility="public" + value="true" +> +</field> +<constructor name="Test" + type="Test" + static="false" + final="false" + visibility="public" +> +</constructor> +</class> +</package> +</api> diff --git a/test/valgrind-target-suppressions.txt b/test/valgrind-target-suppressions.txt index 896850c151..7ae6d539f3 100644 --- a/test/valgrind-target-suppressions.txt +++ b/test/valgrind-target-suppressions.txt @@ -40,3 +40,13 @@ fun:je_tsd_fetch fun:je_malloc_tsd_boot0 } + +# Setenv is known-leaking when overwriting mappings. This is triggered by re-initializing +# ANDROID_DATA. Ignore all setenv leaks. +{ + SetenvAndroidDataReinit + Memcheck:Leak + match-leak-kinds: definite + fun:malloc + fun:setenv +} |