# HG changeset patch # User Christian Haeubl # Date 1370607338 -7200 # Node ID 81b298e0868bd17c5e444d0c55b44290ce7fcdc5 # Parent fe9a97ee352b4204d94387768438771841241f6a# Parent 44fcf49b746f1cb081d19028b945666560868d4d Merge. diff -r fe9a97ee352b -r 81b298e0868b .hgignore --- a/.hgignore Fri Jun 07 13:43:13 2013 +0200 +++ b/.hgignore Fri Jun 07 14:15:38 2013 +0200 @@ -72,3 +72,5 @@ *.jar.* eclipse-build.xml rebuild-launch.out +coverage +jacoco.exec diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/Assumptions.java --- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/Assumptions.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/Assumptions.java Fri Jun 07 14:15:38 2013 +0200 @@ -259,6 +259,7 @@ public Assumptions(boolean useOptimisticAssumptions) { this.useOptimisticAssumptions = useOptimisticAssumptions; + list = new Assumption[4]; } /** @@ -362,6 +363,10 @@ count++; } + public Assumption[] getAssumptions() { + return list; + } + public void record(Assumptions assumptions) { for (int i = 0; i < assumptions.count; i++) { record(assumptions.list[i]); diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/BytecodeFrame.java --- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/BytecodeFrame.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/BytecodeFrame.java Fri Jun 07 14:15:38 2013 +0200 @@ -82,6 +82,13 @@ */ public final int numLocks; + /** + * True if this is a position inside an exception handler before the exception object has been + * consumed. In this case, {@link #numStack == 1} and {@link #getStackValue(int) + * getStackValue(0)} is the location of the exception object. If deoptimization happens at this + * position, the interpreter will rethrow the exception instead of executing the bytecode + * instruction at this position. + */ public final boolean rethrowException; public final boolean duringCall; diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CompilationResult.java --- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CompilationResult.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CompilationResult.java Fri Jun 07 14:15:38 2013 +0200 @@ -492,6 +492,9 @@ * @return the code annotations or {@code null} if there are none */ public List getAnnotations() { + if (annotations == null) { + return Collections.emptyList(); + } return annotations; } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/ForeignCallLinkage.java --- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/ForeignCallLinkage.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/ForeignCallLinkage.java Fri Jun 07 14:15:38 2013 +0200 @@ -55,4 +55,11 @@ * this target */ boolean destroysRegisters(); + + /** + * Determines if this is call to a function that does not deoptimize, and therefore also does + * not lock, GC or throw exceptions. That is, the thread's execution state during the call is + * never inspected by another thread. + */ + boolean canDeoptimize(); } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/Register.java --- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/Register.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/Register.java Fri Jun 07 14:15:38 2013 +0200 @@ -213,7 +213,8 @@ public boolean equals(Object obj) { if (obj instanceof Register) { Register other = (Register) obj; - if (number == other.number && name.equals(other.name)) { + if (number == other.number) { + assert name.equals(other.name); assert encoding == other.encoding; assert registerCategory == other.registerCategory; return true; diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/ValueUtil.java --- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/ValueUtil.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/ValueUtil.java Fri Jun 07 14:15:38 2013 +0200 @@ -120,7 +120,7 @@ } public static boolean sameRegister(Value v1, Value v2) { - return isRegister(v1) && isRegister(v2) && asRegister(v1) == asRegister(v2); + return isRegister(v1) && isRegister(v2) && asRegister(v1).equals(asRegister(v2)); } public static boolean sameRegister(Value v1, Value v2, Value v3) { @@ -128,7 +128,7 @@ } public static boolean differentRegisters(Value v1, Value v2) { - return !isRegister(v1) || !isRegister(v2) || asRegister(v1) != asRegister(v2); + return !isRegister(v1) || !isRegister(v2) || !asRegister(v1).equals(asRegister(v2)); } public static boolean differentRegisters(Value v1, Value v2, Value v3) { diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/VirtualObject.java --- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/VirtualObject.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/VirtualObject.java Fri Jun 07 14:15:38 2013 +0200 @@ -147,7 +147,8 @@ } else { Kind componentKind = type.getComponentType().getKind().getStackKind(); for (int i = 0; i < values.length; i++) { - assert values[i].getKind().getStackKind() == componentKind : values[i].getKind() + " != " + componentKind; + assert values[i].getKind().getStackKind() == componentKind || componentKind.getBitCount() >= values[i].getKind().getStackKind().getBitCount() : values[i].getKind() + " != " + + componentKind; } } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/MethodUniverse.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/MethodUniverse.java Fri Jun 07 14:15:38 2013 +0200 @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.api.meta.test; + +import java.lang.reflect.*; +import java.util.*; + +import com.oracle.graal.api.meta.*; + +/** + * Context for method related api.meta tests. + */ +public class MethodUniverse extends TypeUniverse { + + public final Map methods = new HashMap<>(); + public final Map constructors = new HashMap<>(); + + public MethodUniverse() { + for (Class c : classes) { + for (Method m : c.getDeclaredMethods()) { + ResolvedJavaMethod method = runtime.lookupJavaMethod(m); + methods.put(m, method); + } + for (Constructor m : c.getDeclaredConstructors()) { + constructors.put(m, runtime.lookupJavaConstructor(m)); + } + } + } +} diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestBytecodeDisassemblerProvider.java --- a/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestBytecodeDisassemblerProvider.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestBytecodeDisassemblerProvider.java Fri Jun 07 14:15:38 2013 +0200 @@ -30,7 +30,7 @@ /** * Tests for {@link BytecodeDisassemblerProvider}. */ -public class TestBytecodeDisassemblerProvider { +public class TestBytecodeDisassemblerProvider extends MethodUniverse { public TestBytecodeDisassemblerProvider() { } @@ -43,7 +43,7 @@ BytecodeDisassemblerProvider dis = Graal.getRuntime().getCapability(BytecodeDisassemblerProvider.class); if (dis != null) { int count = 0; - for (ResolvedJavaMethod m : TestJavaMethod.methods.values()) { + for (ResolvedJavaMethod m : methods.values()) { String disasm1 = dis.disassemble(m); String disasm2 = dis.disassemble(m); if (disasm1 == null) { diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestJavaMethod.java --- a/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestJavaMethod.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestJavaMethod.java Fri Jun 07 14:15:38 2013 +0200 @@ -22,7 +22,6 @@ */ package com.oracle.graal.api.meta.test; -import static com.oracle.graal.api.meta.test.TestMetaAccessProvider.*; import static org.junit.Assert.*; import java.lang.reflect.*; @@ -35,24 +34,7 @@ /** * Tests for {@link JavaMethod}. */ -public class TestJavaMethod { - - public TestJavaMethod() { - } - - public static final Map methods = new HashMap<>(); - public static final Map constructors = new HashMap<>(); - static { - for (Class c : classes) { - for (Method m : c.getDeclaredMethods()) { - ResolvedJavaMethod method = runtime.lookupJavaMethod(m); - methods.put(m, method); - } - for (Constructor m : c.getDeclaredConstructors()) { - constructors.put(m, runtime.lookupJavaConstructor(m)); - } - } - } +public class TestJavaMethod extends MethodUniverse { @Test public void getNameTest() { diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestJavaType.java --- a/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestJavaType.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestJavaType.java Fri Jun 07 14:15:38 2013 +0200 @@ -22,7 +22,6 @@ */ package com.oracle.graal.api.meta.test; -import static com.oracle.graal.api.meta.test.TestMetaAccessProvider.*; import static org.junit.Assert.*; import org.junit.*; @@ -32,7 +31,7 @@ /** * Tests for {@link JavaType}. */ -public class TestJavaType { +public class TestJavaType extends TypeUniverse { public TestJavaType() { } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestMetaAccessProvider.java --- a/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestMetaAccessProvider.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestMetaAccessProvider.java Fri Jun 07 14:15:38 2013 +0200 @@ -25,125 +25,16 @@ import static com.oracle.graal.api.meta.MetaUtil.*; import static org.junit.Assert.*; -import java.io.*; import java.lang.reflect.*; -import java.util.*; import org.junit.*; -import sun.misc.Unsafe; - import com.oracle.graal.api.meta.*; -import com.oracle.graal.api.runtime.*; /** * Tests for {@link MetaAccessProvider}. */ -public class TestMetaAccessProvider { - - public static final Unsafe unsafe; - static { - Unsafe theUnsafe = null; - try { - theUnsafe = Unsafe.getUnsafe(); - } catch (Exception e) { - try { - Field theUnsafeField = Unsafe.class.getDeclaredField("theUnsafe"); - theUnsafeField.setAccessible(true); - theUnsafe = (Unsafe) theUnsafeField.get(null); - } catch (Exception e1) { - throw (InternalError) new InternalError("unable to initialize unsafe").initCause(e1); - } - } - unsafe = theUnsafe; - } - - public TestMetaAccessProvider() { - } - - public static final MetaAccessProvider runtime = Graal.getRequiredCapability(MetaAccessProvider.class); - public static final Collection> classes = new HashSet<>(); - public static final Map, Class> arrayClasses = new HashMap<>(); - - public static synchronized Class getArrayClass(Class componentType) { - Class arrayClass = arrayClasses.get(componentType); - if (arrayClass == null) { - arrayClass = Array.newInstance(componentType, 0).getClass(); - arrayClasses.put(componentType, arrayClass); - } - return arrayClass; - } - - public static int dimensions(Class c) { - if (c.getComponentType() != null) { - return 1 + dimensions(c.getComponentType()); - } - return 0; - } - - private static void addClass(Class c) { - if (classes.add(c)) { - if (c.getSuperclass() != null) { - addClass(c.getSuperclass()); - } - for (Class sc : c.getInterfaces()) { - addClass(sc); - } - for (Class dc : c.getDeclaredClasses()) { - addClass(dc); - } - for (Method m : c.getDeclaredMethods()) { - addClass(m.getReturnType()); - for (Class p : m.getParameterTypes()) { - addClass(p); - } - } - - if (c != void.class && dimensions(c) < 2) { - Class arrayClass = Array.newInstance(c, 0).getClass(); - arrayClasses.put(c, arrayClass); - addClass(arrayClass); - } - } - } - - static { - Class[] initialClasses = {void.class, boolean.class, byte.class, short.class, char.class, int.class, float.class, long.class, double.class, Object.class, Class.class, ClassLoader.class, - String.class, Serializable.class, Cloneable.class, Test.class, TestMetaAccessProvider.class, List.class, Collection.class, Map.class, Queue.class, HashMap.class, - LinkedHashMap.class, IdentityHashMap.class, AbstractCollection.class, AbstractList.class, ArrayList.class}; - for (Class c : initialClasses) { - addClass(c); - } - } - - public static final List constants = new ArrayList<>(); - static { - for (Field f : Constant.class.getDeclaredFields()) { - int mods = f.getModifiers(); - if (f.getType() == Constant.class && Modifier.isPublic(mods) && Modifier.isStatic(mods) && Modifier.isFinal(mods)) { - try { - Constant c = (Constant) f.get(null); - if (c != null) { - constants.add(c); - } - } catch (Exception e) { - } - } - } - for (Class c : classes) { - if (c != void.class && !c.isArray()) { - constants.add(Constant.forObject(Array.newInstance(c, 42))); - } - } - constants.add(Constant.forObject(new ArrayList<>())); - constants.add(Constant.forObject(new IdentityHashMap<>())); - constants.add(Constant.forObject(new LinkedHashMap<>())); - constants.add(Constant.forObject(new TreeMap<>())); - constants.add(Constant.forObject(new ArrayDeque<>())); - constants.add(Constant.forObject(new LinkedList<>())); - constants.add(Constant.forObject("a string")); - constants.add(Constant.forObject(42)); - } +public class TestMetaAccessProvider extends TypeUniverse { @Test public void lookupJavaTypeTest() { diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaMethod.java --- a/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaMethod.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaMethod.java Fri Jun 07 14:15:38 2013 +0200 @@ -22,10 +22,10 @@ */ package com.oracle.graal.api.meta.test; -import static com.oracle.graal.api.meta.test.TestJavaMethod.*; import static java.lang.reflect.Modifier.*; import static org.junit.Assert.*; +import java.lang.annotation.*; import java.lang.reflect.*; import java.util.*; @@ -36,7 +36,7 @@ /** * Tests for {@link ResolvedJavaMethod}. */ -public class TestResolvedJavaMethod { +public class TestResolvedJavaMethod extends MethodUniverse { public TestResolvedJavaMethod() { } @@ -94,21 +94,6 @@ } @Test - public void getCompilationComplexityTest() { - // TODO - } - - @Test - public void getMaxLocalsTest() { - // TODO - } - - @Test - public void getMaxStackSizeTest() { - // TODO - } - - @Test public void getModifiersTest() { for (Map.Entry e : methods.entrySet()) { ResolvedJavaMethod m = e.getValue(); @@ -148,52 +133,168 @@ @Test public void canBeStaticallyBoundTest() { - // TODO + for (Map.Entry e : methods.entrySet()) { + ResolvedJavaMethod m = e.getValue(); + assertEquals(m.canBeStaticallyBound(), canBeStaticallyBound(e.getKey().getModifiers())); + } + for (Map.Entry e : constructors.entrySet()) { + ResolvedJavaMethod m = e.getValue(); + assertEquals(m.canBeStaticallyBound(), canBeStaticallyBound(e.getKey().getModifiers())); + } } - @Test - public void getExceptionHandlersTest() { - // TODO + private static boolean canBeStaticallyBound(int modifiers) { + return (Modifier.isFinal(modifiers) || Modifier.isPrivate(modifiers) || Modifier.isStatic(modifiers)) && !Modifier.isAbstract(modifiers); + } + + private static String methodWithExceptionHandlers(String p1, Object o2) { + try { + return p1.substring(100) + o2.toString(); + } catch (IndexOutOfBoundsException e) { + e.printStackTrace(); + } catch (NullPointerException e) { + e.printStackTrace(); + } catch (RuntimeException e) { + e.printStackTrace(); + } + return null; } @Test - public void asStackTraceElementTest() { - // TODO + public void getExceptionHandlersTest() throws NoSuchMethodException { + ResolvedJavaMethod method = runtime.lookupJavaMethod(getClass().getDeclaredMethod("methodWithExceptionHandlers", String.class, Object.class)); + ExceptionHandler[] handlers = method.getExceptionHandlers(); + assertNotNull(handlers); + assertEquals(handlers.length, 3); + handlers[0].getCatchType().equals(runtime.lookupJavaType(IndexOutOfBoundsException.class)); + handlers[1].getCatchType().equals(runtime.lookupJavaType(NullPointerException.class)); + handlers[2].getCatchType().equals(runtime.lookupJavaType(RuntimeException.class)); + } + + private static String nullPointerExceptionOnFirstLine(Object o, String ignored) { + return o.toString() + ignored; } @Test - public void getProfilingInfoTest() { - // TODO - } - - @Test - public void getCompilerStorageTest() { - // TODO + public void asStackTraceElementTest() throws NoSuchMethodException { + try { + nullPointerExceptionOnFirstLine(null, "ignored"); + Assert.fail("should not reach here"); + } catch (NullPointerException e) { + StackTraceElement expected = e.getStackTrace()[0]; + ResolvedJavaMethod method = runtime.lookupJavaMethod(getClass().getDeclaredMethod("nullPointerExceptionOnFirstLine", Object.class, String.class)); + StackTraceElement actual = method.asStackTraceElement(0); + assertEquals(expected, actual); + } } @Test public void getConstantPoolTest() { - // TODO + for (Map.Entry e : methods.entrySet()) { + ResolvedJavaMethod m = e.getValue(); + ConstantPool cp = m.getConstantPool(); + assertTrue(cp.length() > 0); + } + } + + @Test(timeout = 1000L) + public void getAnnotationTest() throws NoSuchMethodException { + ResolvedJavaMethod method = runtime.lookupJavaMethod(getClass().getDeclaredMethod("getAnnotationTest")); + Test annotation = method.getAnnotation(Test.class); + assertNotNull(annotation); + assertEquals(1000L, annotation.timeout()); + } + + @Retention(RetentionPolicy.RUNTIME) + @Target(ElementType.PARAMETER) + @interface NonNull { + } + + @Retention(RetentionPolicy.RUNTIME) + @Target(ElementType.PARAMETER) + @interface Special { + } + + private static native void methodWithAnnotatedParameters(@NonNull HashMap p1, @Special @NonNull Class p2); + + @Test + public void getParameterAnnotationsTest() throws NoSuchMethodException { + ResolvedJavaMethod method = runtime.lookupJavaMethod(getClass().getDeclaredMethod("methodWithAnnotatedParameters", HashMap.class, Class.class)); + Annotation[][] annotations = method.getParameterAnnotations(); + assertEquals(2, annotations.length); + assertEquals(1, annotations[0].length); + assertEquals(NonNull.class, annotations[0][0].annotationType()); + assertEquals(2, annotations[1].length); + assertEquals(Special.class, annotations[1][0].annotationType()); + assertEquals(NonNull.class, annotations[1][1].annotationType()); } @Test - public void getAnnotationTest() { - // TODO + public void getGenericParameterTypesTest() throws NoSuchMethodException { + ResolvedJavaMethod method = runtime.lookupJavaMethod(getClass().getDeclaredMethod("methodWithAnnotatedParameters", HashMap.class, Class.class)); + Type[] genericParameterTypes = method.getGenericParameterTypes(); + assertEquals(2, genericParameterTypes.length); + assertEquals("java.util.HashMap", genericParameterTypes[0].toString()); + assertEquals("java.lang.Class", genericParameterTypes[1].toString()); } @Test - public void getParameterAnnotationsTest() { - // TODO - } - - @Test - public void getGenericParameterTypesTest() { - // TODO + public void getMaxLocalsTest() throws NoSuchMethodException { + ResolvedJavaMethod method1 = runtime.lookupJavaMethod(getClass().getDeclaredMethod("methodWithAnnotatedParameters", HashMap.class, Class.class)); + ResolvedJavaMethod method2 = runtime.lookupJavaMethod(getClass().getDeclaredMethod("nullPointerExceptionOnFirstLine", Object.class, String.class)); + assertEquals(0, method1.getMaxLocals()); + assertEquals(2, method2.getMaxLocals()); } @Test - public void canBeInlinedTest() { - // TODO + public void getMaxStackSizeTest() throws NoSuchMethodException { + ResolvedJavaMethod method1 = runtime.lookupJavaMethod(getClass().getDeclaredMethod("methodWithAnnotatedParameters", HashMap.class, Class.class)); + ResolvedJavaMethod method2 = runtime.lookupJavaMethod(getClass().getDeclaredMethod("nullPointerExceptionOnFirstLine", Object.class, String.class)); + assertEquals(0, method1.getMaxStackSize()); + // some versions of javac produce bytecode with a stacksize of 2 for this method + assertTrue(3 == method2.getMaxStackSize() || 2 == method2.getMaxStackSize()); + } + + private Method findTestMethod(Method apiMethod) { + String testName = apiMethod.getName() + "Test"; + for (Method m : getClass().getDeclaredMethods()) { + if (m.getName().equals(testName) && m.getAnnotation(Test.class) != null) { + return m; + } + } + return null; + } + + // @formatter:off + private static final String[] untestedApiMethods = { + "invoke", + "newInstance", + "getDeclaringClass", + "getEncoding", + "getProfilingInfo", + "reprofile", + "getCompilerStorage", + "canBeInlined", + "getLineNumberTable", + "getLocalVariableTable", + "isInVirtualMethodTable" + }; + // @formatter:on + + /** + * Ensures that any new methods added to {@link ResolvedJavaMethod} either have a test written + * for them or are added to {@link #untestedApiMethods}. + */ + @Test + public void testCoverage() { + Set known = new HashSet<>(Arrays.asList(untestedApiMethods)); + for (Method m : ResolvedJavaMethod.class.getDeclaredMethods()) { + if (findTestMethod(m) == null) { + assertTrue("test missing for " + m, known.contains(m.getName())); + } else { + assertFalse("test should be removed from untestedApiMethods" + m, known.contains(m.getName())); + } + } } } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaType.java --- a/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaType.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaType.java Fri Jun 07 14:15:38 2013 +0200 @@ -22,7 +22,6 @@ */ package com.oracle.graal.api.meta.test; -import static com.oracle.graal.api.meta.test.TestMetaAccessProvider.*; import static java.lang.Integer.*; import static java.lang.reflect.Modifier.*; import static org.junit.Assert.*; @@ -41,7 +40,7 @@ /** * Tests for {@link ResolvedJavaType}. */ -public class TestResolvedJavaType { +public class TestResolvedJavaType extends TypeUniverse { public TestResolvedJavaType() { } @@ -83,7 +82,7 @@ } @Test - public void isArrayClassTest() { + public void isArrayTest() { for (Class c : classes) { ResolvedJavaType type = runtime.lookupJavaType(c); boolean expected = c.isArray(); @@ -103,7 +102,7 @@ } @Test - public void isAssignableToTest() { + public void isAssignableFromTest() { Class[] all = classes.toArray(new Class[classes.size()]); for (int i = 0; i < all.length; i++) { Class c1 = all[i]; @@ -194,7 +193,7 @@ } } - public static Class getSupertype(Class c) { + public Class getSupertype(Class c) { assert !c.isPrimitive(); if (c.isArray()) { Class componentType = c.getComponentType(); @@ -209,7 +208,7 @@ return c.getSuperclass(); } - public static Class findLeastCommonAncestor(Class c1Initial, Class c2Initial) { + public Class findLeastCommonAncestor(Class c1Initial, Class c2Initial) { if (c1Initial.isPrimitive() || c2Initial.isPrimitive()) { return null; } else { @@ -270,7 +269,7 @@ abstract static class Abstract4 extends Concrete3 { } - static void checkConcreteSubtype(ResolvedJavaType type, Class expected) { + void checkConcreteSubtype(ResolvedJavaType type, Class expected) { ResolvedJavaType subtype = type.findUniqueConcreteSubtype(); if (subtype == null) { // findUniqueConcreteSubtype() is conservative @@ -455,8 +454,10 @@ } @Test - public void findUniqueConcreteMethodTest() { - // TODO + public void findUniqueConcreteMethodTest() throws NoSuchMethodException { + ResolvedJavaMethod thisMethod = runtime.lookupJavaMethod(getClass().getDeclaredMethod("findUniqueConcreteMethodTest")); + ResolvedJavaMethod ucm = runtime.lookupJavaType(getClass()).findUniqueConcreteMethod(thisMethod); + assertEquals(thisMethod, ucm); } public static Set getInstanceFields(Class c, boolean includeSuperclasses) { @@ -475,12 +476,12 @@ return result; } - public static boolean fieldsEqual(Field f, ResolvedJavaField rjf) { + public boolean fieldsEqual(Field f, ResolvedJavaField rjf) { return rjf.getDeclaringClass().equals(runtime.lookupJavaType(f.getDeclaringClass())) && rjf.getName().equals(f.getName()) && rjf.getType().resolve(rjf.getDeclaringClass()).equals(runtime.lookupJavaType(f.getType())); } - public static ResolvedJavaField lookupField(ResolvedJavaField[] fields, Field key) { + public ResolvedJavaField lookupField(ResolvedJavaField[] fields, Field key) { for (ResolvedJavaField rf : fields) { if (fieldsEqual(key, rf)) { assert (fieldModifiers() & key.getModifiers()) == rf.getModifiers() : key + ": " + toHexString(key.getModifiers()) + " != " + toHexString(rf.getModifiers()); @@ -490,7 +491,7 @@ return null; } - public static Field lookupField(Set fields, ResolvedJavaField key) { + public Field lookupField(Set fields, ResolvedJavaField key) { for (Field f : fields) { if (fieldsEqual(f, key)) { assert key.getModifiers() == (fieldModifiers() & f.getModifiers()) : key + ": " + toHexString(key.getModifiers()) + " != " + toHexString(f.getModifiers()); @@ -500,7 +501,7 @@ return null; } - private static boolean isHiddenFromReflection(ResolvedJavaField f) { + private boolean isHiddenFromReflection(ResolvedJavaField f) { if (f.getDeclaringClass().equals(runtime.lookupJavaType(Throwable.class)) && f.getName().equals("backtrace")) { return true; } @@ -574,4 +575,50 @@ } } } + + private Method findTestMethod(Method apiMethod) { + String testName = apiMethod.getName() + "Test"; + for (Method m : getClass().getDeclaredMethods()) { + if (m.getName().equals(testName) && m.getAnnotation(Test.class) != null) { + return m; + } + } + return null; + } + + // @formatter:off + private static final String[] untestedApiMethods = { + "initialize", + "isPrimitive", + "newArray", + "getDeclaredMethods", + "getDeclaredConstructors", + "isInitialized", + "getEncoding", + "hasFinalizableSubclass", + "hasFinalizer", + "getSourceFileName", + "getClassFilePath", + "isLocal", + "isMember", + "getEnclosingType" + }; + // @formatter:on + + /** + * Ensures that any new methods added to {@link ResolvedJavaMethod} either have a test written + * for them or are added to {@link #untestedApiMethods}. + */ + @Test + public void testCoverage() { + Set known = new HashSet<>(Arrays.asList(untestedApiMethods)); + for (Method m : ResolvedJavaType.class.getDeclaredMethods()) { + if (findTestMethod(m) == null) { + assertTrue("test missing for " + m, known.contains(m.getName())); + } else { + assertFalse("test should be removed from untestedApiMethods" + m, known.contains(m.getName())); + } + } + } + } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TypeUniverse.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TypeUniverse.java Fri Jun 07 14:15:38 2013 +0200 @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.api.meta.test; + +import java.io.*; +import java.lang.reflect.*; +import java.util.*; +import java.util.Queue; + +import org.junit.*; + +import sun.misc.*; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.api.runtime.*; + +/** + * Context for type related api.meta tests. + */ +public class TypeUniverse { + + public final Unsafe unsafe; + public final MetaAccessProvider runtime = Graal.getRequiredCapability(MetaAccessProvider.class); + public final Collection> classes = new HashSet<>(); + public final Map, Class> arrayClasses = new HashMap<>(); + public final List constants = new ArrayList<>(); + + public TypeUniverse() { + Unsafe theUnsafe = null; + try { + theUnsafe = Unsafe.getUnsafe(); + } catch (Exception e) { + try { + Field theUnsafeField = Unsafe.class.getDeclaredField("theUnsafe"); + theUnsafeField.setAccessible(true); + theUnsafe = (Unsafe) theUnsafeField.get(null); + } catch (Exception e1) { + throw (InternalError) new InternalError("unable to initialize unsafe").initCause(e1); + } + } + unsafe = theUnsafe; + + Class[] initialClasses = {void.class, boolean.class, byte.class, short.class, char.class, int.class, float.class, long.class, double.class, Object.class, Class.class, ClassLoader.class, + String.class, Serializable.class, Cloneable.class, Test.class, TestMetaAccessProvider.class, List.class, Collection.class, Map.class, Queue.class, HashMap.class, + LinkedHashMap.class, IdentityHashMap.class, AbstractCollection.class, AbstractList.class, ArrayList.class}; + for (Class c : initialClasses) { + addClass(c); + } + for (Field f : Constant.class.getDeclaredFields()) { + int mods = f.getModifiers(); + if (f.getType() == Constant.class && Modifier.isPublic(mods) && Modifier.isStatic(mods) && Modifier.isFinal(mods)) { + try { + Constant c = (Constant) f.get(null); + if (c != null) { + constants.add(c); + } + } catch (Exception e) { + } + } + } + for (Class c : classes) { + if (c != void.class && !c.isArray()) { + constants.add(Constant.forObject(Array.newInstance(c, 42))); + } + } + constants.add(Constant.forObject(new ArrayList<>())); + constants.add(Constant.forObject(new IdentityHashMap<>())); + constants.add(Constant.forObject(new LinkedHashMap<>())); + constants.add(Constant.forObject(new TreeMap<>())); + constants.add(Constant.forObject(new ArrayDeque<>())); + constants.add(Constant.forObject(new LinkedList<>())); + constants.add(Constant.forObject("a string")); + constants.add(Constant.forObject(42)); + } + + public synchronized Class getArrayClass(Class componentType) { + Class arrayClass = arrayClasses.get(componentType); + if (arrayClass == null) { + arrayClass = Array.newInstance(componentType, 0).getClass(); + arrayClasses.put(componentType, arrayClass); + } + return arrayClass; + } + + public static int dimensions(Class c) { + if (c.getComponentType() != null) { + return 1 + dimensions(c.getComponentType()); + } + return 0; + } + + private void addClass(Class c) { + if (classes.add(c)) { + if (c.getSuperclass() != null) { + addClass(c.getSuperclass()); + } + for (Class sc : c.getInterfaces()) { + addClass(sc); + } + for (Class dc : c.getDeclaredClasses()) { + addClass(dc); + } + for (Method m : c.getDeclaredMethods()) { + addClass(m.getReturnType()); + for (Class p : m.getParameterTypes()) { + addClass(p); + } + } + + if (c != void.class && dimensions(c) < 2) { + Class arrayClass = Array.newInstance(c, 0).getClass(); + arrayClasses.put(c, arrayClass); + addClass(arrayClass); + } + } + } +} diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ForeignCallDescriptor.java --- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ForeignCallDescriptor.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ForeignCallDescriptor.java Fri Jun 07 14:15:38 2013 +0200 @@ -33,6 +33,9 @@ *
  • The callee has different register saving semantics. For example, the callee may save all * registers (apart from some specified temporaries) in which case the register allocator doesn't * not need to spill all live registers around the call site.
  • + *
  • The call does not occur at an INVOKE* bytecode. Such a call could be transformed into a + * standard Java call if the foreign routine is a normal Java method and the runtime supports + * linking Java calls at arbitrary bytecodes.
  • * */ public class ForeignCallDescriptor { diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Kind.java --- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Kind.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Kind.java Fri Jun 07 14:15:38 2013 +0200 @@ -362,8 +362,12 @@ case Char: case Short: return 16; + case Float: + return 32; case Int: return 32; + case Double: + return 64; case Long: return 64; default: diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/LocationIdentity.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/LocationIdentity.java Fri Jun 07 14:15:38 2013 +0200 @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.api.meta; + +/** + * Marker interface for location identities. Apart from the special values {@link #ANY_LOCATION} and + * {@link #FINAL_LOCATION}, a different location identity of two memory accesses guarantees that the + * two accesses do not interfere. + */ +public interface LocationIdentity { + + /** + * Denotes any location. A write to such a location kills all values in a memory map during an + * analysis of memory accesses. A read from this location cannot be moved or coalesced with + * other reads because its interaction with other reads is not known. + */ + LocationIdentity ANY_LOCATION = new NamedLocationIdentity("ANY_LOCATION"); + + /** + * Denotes the location of a value that is guaranteed to be final. + */ + LocationIdentity FINAL_LOCATION = new NamedLocationIdentity("FINAL_LOCATION"); + +} diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/MetaAccessProvider.java --- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/MetaAccessProvider.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/MetaAccessProvider.java Fri Jun 07 14:15:38 2013 +0200 @@ -96,8 +96,20 @@ Constant readUnsafeConstant(Kind kind, Object base, long displacement); /** - * Determines if a given foreign call has a side-effect. Deoptimization cannot return execution - * to a point before a foreign call that has a side effect. + * Determines if a given foreign call is side-effect free. Deoptimization cannot return + * execution to a point before a foreign call that has a side effect. */ - boolean hasSideEffect(ForeignCallDescriptor descriptor); + boolean isReexecutable(ForeignCallDescriptor descriptor); + + /** + * Gets the set of memory locations killed by a given foreign call. Returning the special value + * {@link LocationIdentity#ANY_LOCATION} denotes that the call kills all memory locations. + * Returning any empty array denotes that the call does not kill any memory locations. + */ + LocationIdentity[] getKilledLocations(ForeignCallDescriptor descriptor); + + /** + * Determines if deoptimization can occur during a given foreign call. + */ + boolean canDeoptimize(ForeignCallDescriptor descriptor); } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/NamedLocationIdentity.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/NamedLocationIdentity.java Fri Jun 07 14:15:38 2013 +0200 @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.api.meta; + +import java.util.*; + +/** + * A {@link LocationIdentity} with a name. + */ +public class NamedLocationIdentity implements LocationIdentity { + + protected final String name; + + /** + * Creates a named unique location identity for read and write operations. + * + * @param name the name of the new location identity + */ + public NamedLocationIdentity(String name) { + this.name = name; + } + + @Override + public String toString() { + return name; + } + + /** + * Returns the named location identity for an array of the given element kind. Array accesses of + * the same kind must have the same location identity unless an alias analysis guarantees that + * two distinct arrays are accessed. + */ + public static LocationIdentity getArrayLocation(Kind elementKind) { + return ARRAY_LOCATIONS.get(elementKind); + } + + private static final EnumMap ARRAY_LOCATIONS = initArrayLocations(); + + private static EnumMap initArrayLocations() { + EnumMap result = new EnumMap<>(Kind.class); + for (Kind kind : Kind.values()) { + result.put(kind, new NamedLocationIdentity("Array: " + kind.getJavaName())); + } + return result; + } +} diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaType.java --- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaType.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaType.java Fri Jun 07 14:15:38 2013 +0200 @@ -198,7 +198,8 @@ * Resolves the method implementation for virtual dispatches on objects of this dynamic type. * * @param method the method to select the implementation of - * @return the method implementation that would be selected at runtime + * @return the method implementation that would be selected at runtime, or {@code null} if the + * runtime cannot resolve the method at this point in time. */ ResolvedJavaMethod resolveMethod(ResolvedJavaMethod method); diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Address.java --- a/graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Address.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Address.java Fri Jun 07 14:15:38 2013 +0200 @@ -114,11 +114,11 @@ StringBuilder s = new StringBuilder(); s.append("["); String sep = ""; - if (getBase() != Register.None) { + if (!getBase().equals(Register.None)) { s.append(getBase()); sep = " + "; } - if (getIndex() != Register.None) { + if (!getIndex().equals(Register.None)) { s.append(sep).append(getIndex()).append(" * ").append(getScale().value); sep = " + "; } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Assembler.java --- a/graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Assembler.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Assembler.java Fri Jun 07 14:15:38 2013 +0200 @@ -216,7 +216,7 @@ } protected void emitOperandHelper(Register reg, AMD64Address addr) { - assert reg != Register.None; + assert !reg.equals(Register.None); emitOperandHelper(encode(reg), addr); } @@ -230,14 +230,14 @@ AMD64Address.Scale scale = addr.getScale(); int disp = addr.getDisplacement(); - if (base == Register.Frame) { + if (base.equals(Register.Frame)) { assert frameRegister != null : "cannot use register " + Register.Frame + " in assembler with null register configuration"; base = frameRegister; } - if (base == AMD64.rip) { // also matches Placeholder + if (base.equals(AMD64.rip)) { // also matches Placeholder // [00 000 101] disp32 - assert index == Register.None : "cannot use RIP relative addressing with index register"; + assert index.equals(Register.None) : "cannot use RIP relative addressing with index register"; emitByte(0x05 | regenc); emitInt(disp); } else if (base.isValid()) { @@ -245,28 +245,28 @@ if (index.isValid()) { int indexenc = encode(index) << 3; // [base + indexscale + disp] - if (disp == 0 && base != rbp && (base != r13)) { + if (disp == 0 && !base.equals(rbp) && !base.equals(r13)) { // [base + indexscale] // [00 reg 100][ss index base] - assert index != rsp : "illegal addressing mode"; + assert !index.equals(rsp) : "illegal addressing mode"; emitByte(0x04 | regenc); emitByte(scale.log2 << 6 | indexenc | baseenc); } else if (isByte(disp)) { // [base + indexscale + imm8] // [01 reg 100][ss index base] imm8 - assert index != rsp : "illegal addressing mode"; + assert !index.equals(rsp) : "illegal addressing mode"; emitByte(0x44 | regenc); emitByte(scale.log2 << 6 | indexenc | baseenc); emitByte(disp & 0xFF); } else { // [base + indexscale + disp32] // [10 reg 100][ss index base] disp32 - assert index != rsp : "illegal addressing mode"; + assert !index.equals(rsp) : "illegal addressing mode"; emitByte(0x84 | regenc); emitByte(scale.log2 << 6 | indexenc | baseenc); emitInt(disp); } - } else if (base == rsp || (base == r12)) { + } else if (base.equals(rsp) || base.equals(r12)) { // [rsp + disp] if (disp == 0) { // [rsp] @@ -288,8 +288,8 @@ } } else { // [base + disp] - assert base != rsp && (base != r12) : "illegal addressing mode"; - if (disp == 0 && base != rbp && (base != r13)) { + assert !base.equals(rsp) && !base.equals(r12) : "illegal addressing mode"; + if (disp == 0 && !base.equals(rbp) && !base.equals(r13)) { // [base] // [00 reg base] emitByte(0x00 | regenc | baseenc); @@ -310,7 +310,7 @@ int indexenc = encode(index) << 3; // [indexscale + disp] // [00 reg 100][ss index 101] disp32 - assert index != rsp : "illegal addressing mode"; + assert !index.equals(rsp) : "illegal addressing mode"; emitByte(0x04 | regenc); emitByte(scale.log2 << 6 | indexenc | 0x05); emitInt(disp); @@ -531,7 +531,7 @@ // cmpxchg r,[m] is equivalent to X86.rax, = CAS (m, X86.rax, r) cmpl(rax, adr); movl(rax, adr); - if (reg != rax) { + if (reg.equals(rax)) { Label l = new Label(); jccb(ConditionFlag.NotEqual, l); movl(adr, reg); diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/AbstractSPARCAssembler.java --- a/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/AbstractSPARCAssembler.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/AbstractSPARCAssembler.java Fri Jun 07 14:15:38 2013 +0200 @@ -26,10 +26,11 @@ import com.oracle.graal.api.code.Register; import com.oracle.graal.api.code.TargetDescription; import com.oracle.graal.asm.AbstractAssembler; -import com.oracle.graal.asm.Label; public abstract class AbstractSPARCAssembler extends AbstractAssembler { + public static final String UNBOUND_TARGET = "L" + Integer.MAX_VALUE; + public AbstractSPARCAssembler(TargetDescription target) { super(target); } @@ -40,11 +41,6 @@ } @Override - public void jmp(Label l) { - // SPARC: Implement jump. - } - - @Override protected void patchJumpTarget(int branch, int jumpTarget) { // SPARC: Implement patching of jump target. } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAddress.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAddress.java Fri Jun 07 14:15:38 2013 +0200 @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.asm.sparc; + +import com.oracle.graal.api.code.AbstractAddress; +import com.oracle.graal.api.code.Register; + +public class SPARCAddress extends AbstractAddress { + + private final Register base; + private final int displacement; // need Register offset / displacement CompositeValue? + + /** + * Creates an {@link SPARCAddress} with given base register, no scaling and a given + * displacement. + * + * @param base the base register + * @param displacement the displacement + */ + public SPARCAddress(Register base, int displacement) { + this.base = base; + this.displacement = displacement; + } + + @Override + public String toString() { + StringBuilder s = new StringBuilder(); + s.append("["); + if (!getBase().equals(Register.None)) { + s.append(getBase()); + } + // later: displacement CompositeValue? + s.append("]"); + return s.toString(); + } + + /** + * @return Base register that defines the start of the address computation. If not present, is + * denoted by {@link Register#None}. + */ + public Register getBase() { + return base; + } + + /** + * @return Optional additive displacement. + */ + public int getDisplacement() { + return displacement; + } +} diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAssembler.java --- a/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAssembler.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAssembler.java Fri Jun 07 14:15:38 2013 +0200 @@ -22,21 +22,230 @@ */ package com.oracle.graal.asm.sparc; -import com.oracle.graal.api.code.*; -import com.oracle.graal.sparc.*; +import com.oracle.graal.api.code.Register; +import com.oracle.graal.api.code.RegisterConfig; +import com.oracle.graal.api.code.TargetDescription; +import com.oracle.graal.api.meta.Kind; +import com.oracle.graal.asm.*; +import com.oracle.graal.hotspot.HotSpotGraalRuntime; +import com.oracle.graal.sparc.SPARC; /** * This class implements an assembler that can encode most SPARC instructions. */ public class SPARCAssembler extends AbstractSPARCAssembler { + // @formatter:off + + public static class Fmt1 { + public Fmt1(SPARCAssembler masm, int op, int disp30) { + assert op == 1; + assert ((disp30 & 0xc0000000) == 0); + + masm.emitInt(op << 30 | disp30); + } + } + + public static class Fmt2a { + public Fmt2a(SPARCAssembler masm, int op, int rd, int op2, int imm22) { + assert op == 0; + assert rd < 0x40; + assert op2 < 0x8; + + masm.emitInt(op << 30 | rd << 25 | op2 << 22 | (imm22 & 0x003fffff)); + } + } + + public static class Fmt2b { + public Fmt2b(SPARCAssembler masm, int op, int a, int cond, int op2, int disp22) { + assert op == 0; + assert op == 0; + assert cond < 0x10; + assert op2 < 0x8; + + masm.emitInt(op << 30 | a << 29 | cond << 25 | op2 << 22 | (disp22 & 0x003fffff)); + } + } + + public static class Fmt2c { + public Fmt2c(SPARCAssembler masm, int op, int a, int cond, int op2, int cc, int predict, int disp19) { + assert predict < 2; + assert op == 0; + assert cond < 0x10; + assert op2 < 0x8; + + masm.emitInt(op << 30 | a << 29 | cond << 25 | op2 << 22 | cc << 20 | predict | (disp19 & 0x0007ffff)); + } + } + + public static class Fmt2d { + public Fmt2d(SPARCAssembler masm, int op, int a, int rcond, int op2, int d16hi, int predict, int rs1, int d16lo) { + assert predict == 0 || predict == 1; + assert rcond >= 0 && rcond < 0x8; + assert op == 0; + assert op2 >= 0 && op2 < 0x8; + assert rs1 >= 0 && rs1 < 0x20; + + masm.emitInt(op << 30 | a << 29 | rcond << 25 | op2 << 22 | d16hi & 3 | predict << 18 | rs1 << 14 | (d16lo & 0x003fff)); + } + } + + public static class Fmt3a { + public Fmt3a(SPARCAssembler masm, int op, int rd, int op3, int rs1, int rs2) { + assert op == 2 || op == 3; + assert op3 >= 0 && op3 < 0x40; + assert rs1 >= 0 && rs1 < 0x20; + assert rs2 >= 0 && rs2 < 0x20; + assert rd >= 0 && rd < 0x20; + + masm.emitInt(op << 30 | rd << 25 | op3 << 19 | rs1 << 14 | rs2); + } + } + + public static class Fmt3b { + public Fmt3b(SPARCAssembler masm, int op, int op3, int rs1, int regOrImmediate, int rd) { + assert op == 2 || op == 3; + assert op3 >= 0 && op3 < 0x40; + assert rs1 >= 0 && rs1 < 0x20; + assert rd >= 0 && rd < 0x20; + + masm.emitInt(op << 30 | rd << 25 | op3 << 19 | rs1 << 14 | (regOrImmediate & 0x1fff)); + } + } + + public static class Fmt3c { + public Fmt3c(SPARCAssembler masm, int op, int op3, int rs1, int rs2) { + assert op == 2; + assert op3 >= 0 && op3 < 0x40; + assert rs1 >= 0 && rs1 < 0x20; + assert rs2 >= 0 && rs2 < 0x20; + + masm.emitInt(op << 30 | op3 << 19 | rs1 << 14 | rs2); + } + } + + public static class Fmt3d { + public Fmt3d(SPARCAssembler masm, int op, int op3, int rs1, int simm13) { + assert op == 2; + assert op3 >= 0 && op3 < 0x40; + assert rs1 >= 0 && rs1 < 0x20; + + masm.emitInt(op << 30 | op3 << 19 | rs1 << 14 | ImmedTrue | simm13); + } + } + + public static class Fmt3e { + public Fmt3e(SPARCAssembler masm, int op, int op3, int rcond, int rs1, int rs2, int rd) { + assert op == 2 || op == 3; + assert op3 >= 0 && op3 < 0x40; + assert rcond >= 0 && rcond < 0x8; + assert rs1 >= 0 && rs1 < 0x20; + assert rs2 >= 0 && rs2 < 0x20; + assert rd >= 0 && rd < 0x20; + + masm.emitInt(op << 30 | rd << 25 | op3 << 19 | rs1 << 14 | rcond << 10 | rs2); + } + } + + public static class Fmt3f { + public Fmt3f(SPARCAssembler masm, int op, int op3, int rcond, int rs1, int simm10, int rd) { + assert op == 2 || op == 3; + assert op3 >= 0 && op3 < 0x40; + assert rs1 >= 0 && rs1 < 0x20; + assert rd >= 0 && rd < 0x20; + + masm.emitInt(op << 30 | rd << 25 | op3 << 19 | ImmedTrue | rs1 << 14 | rcond << 10 | (simm10 & 0x000003ff)); + } + } + + public static class Fmt3p { + public Fmt3p(SPARCAssembler masm, int op, int op3, int opf, int rs1, int rs2, int rd) { + assert op == 2 || op == 3; + assert op3 >= 0 && op3 < 0x40; + assert opf >= 0 && opf < 0x200; + assert rs1 >= 0 && rs1 < 0x20; + assert rs2 >= 0 && rs2 < 0x20; + assert rd >= 0 && rd < 0x20; + + masm.emitInt(op << 30 | rd << 25 | op3 << 19 | rs1 << 14 | opf << 5 | rs2); + } + } + + public static class Fmt3n { + public Fmt3n(SPARCAssembler masm, int op, int op3, int opf, int rs2, int rd) { + assert op == 2 || op == 3; + assert op3 >= 0 && op3 < 0x40; + assert opf >= 0 && opf < 0x200; + assert rs2 >= 0 && rs2 < 0x20; + assert rd >= 0 && rd < 0x20; + + masm.emitInt(op << 30 | rd << 25 | op3 << 19 | opf << 5 | rs2); + } + } + + public static class Fmt3q { + public Fmt3q(SPARCAssembler masm, int op, int op3, int rs1, int rd) { + assert op == 2 || op == 3; + assert op3 >= 0 && op3 < 0x40; + assert rs1 >= 0 && rs1 < 0x20; + assert rd >= 0 && rd < 0x20; + + masm.emitInt(op << 30 | rd << 25 | op3 << 19 | rs1 << 14); + } + } + + public static class Fmt3r { + public Fmt3r(SPARCAssembler masm, int op, int fcn, int op3) { + assert op == 23; + assert op3 >= 0 && op3 < 0x40; + assert fcn >= 0 && fcn < 0x40; + + masm.emitInt(op << 30 | fcn << 25 | op3 << 19); + } + } + + public static class Fmt4a { + public Fmt4a(SPARCAssembler masm, int op, int op3, int cc, int rs1, int regOrImmediate, int rd) { + assert op == 2; + assert rs1 >= 0 && rs1 < 0x20; + assert rd >= 0 && rd < 0x10; + + masm.emitInt(op << 30 | rd << 25 | op3 << 19 | rs1 << 14 | ((cc << 11) & 0x000001800) | regOrImmediate); + } + } + + public static class Fmt4c { + public Fmt4c(SPARCAssembler masm, int op, int op3, int cond, int cc, int rs2, int rd) { + assert op == 2; + assert op3 >= 0 && op3 < 0x40; + assert cc >= 0 && cc < 0x8; + assert cond >= 0 && cond < 0x10; + assert rs2 >= 0 && rs2 < 0x20; + assert rd >= 0 && rd < 0x20; + + masm.emitInt(op << 30 | rd << 25 | op3 << 19 | ((cc << 15) & 0x00040000) | cond << 14 | ((cc << 11) & 0x3) | rs2); + } + } + + public static class Fmt4d { + public Fmt4d(SPARCAssembler masm, int op, int op3, int cond, int cc, int simm11, int rd) { + assert op == 2; + assert op3 >= 0 && op3 < 0x40; + assert cc >= 0 && cc < 0x8; + assert cond >= 0 && cond < 0x10; + assert rd >= 0 && rd < 0x20; + + masm.emitInt(op << 30 | rd << 25 | op3 << 19 | ImmedTrue | ((cc << 15) & 0x00040000) | cond << 14 | ((cc << 11) & 0x3) | simm11 & 0x00004000); + } + } + public static final int ImmedTrue = 0x00002000; public enum Ops { - CallOp(0x40000000), - BranchOp(0x00000000), - ArithOp(0x80000000), - LdstOp(0xC0000000); + CallOp(1), + BranchOp(0), + ArithOp(2), + LdstOp(3); private final int value; @@ -49,53 +258,119 @@ } } + public enum Op2s { + Bpr(3), + Fb(6), + Fbp(5), + Br(2), + Bp(1), + Cb(7), + Sethi(4); + + private final int value; + + private Op2s(int value) { + this.value = value; + } + + public int getValue() { + return value; + } + } + public enum Op3s { - Add((0x00 << 19) & 0x01F80000, "add"), - And((0x01 << 19) & 0x01F80000, "and"), - Or((0x02 << 19) & 0x01F80000, "or"), - Xor((0x03 << 19) & 0x01F80000, "xor"), - Sub((0x04 << 19) & 0x01F80000, "sub"), - Andn((0x05 << 19) & 0x01F80000, "andn"), - Orn((0x06 << 19) & 0x01F80000, "orn"), - Xnor((0x07 << 19) & 0x01F80000, "xnor"), - Addc((0x08 << 19) & 0x01F80000, "addc"), - Mulx((0x09 << 19) & 0x01F80000, "mulx"), - Umul((0x0A << 19) & 0x01F80000, "umul"), - Smul((0x0B << 19) & 0x01F80000, "smul"), - Subc((0x0C << 19) & 0x01F80000, "subc"), - Udivx((0x0D << 19) & 0x01F80000, "udivx"), - Udiv((0x0E << 19) & 0x01F80000, "udiv"), - Sdiv((0x0F << 19) & 0x01F80000, "sdiv"), + Add(0x00, "add"), + And(0x01, "and"), + Or(0x02, "or"), + Xor(0x03, "xor"), + Sub(0x04, "sub"), + Andn(0x05, "andn"), + Orn(0x06, "orn"), + Xnor(0x07, "xnor"), + Addc(0x08, "addc"), + Mulx(0x09, "mulx"), + Umul(0x0A, "umul"), + Smul(0x0B, "smul"), + Subc(0x0C, "subc"), + Udivx(0x0D, "udivx"), + Udiv(0x0E, "udiv"), + Sdiv(0x0F, "sdiv"), + + Addcc(0x10, "addcc"), + Andcc(0x11, "andcc"), + Orcc(0x12, "orcc"), + Xorcc(0x13, "xorcc"), + Subcc(0x14, "subcc"), + Andncc(0x15, "andncc"), + Orncc(0x16, "orncc"), + Xnorcc(0x17, "xnorcc"), + Addccc(0x18, "addccc"), + Mulxcc(0x19, "mulxcc"), + Umulcc(0x1A, "umulcc"), + Smulcc(0x1B, "smulcc"), + Subccc(0x1C0, "subccc"), + Udivcc(0x1E, "udivcc"), + Sdivcc(0x1F, "sdivcc"), - Addcc((0x10 << 19) & 0x01F80000, "addcc"), - Andcc((0x11 << 19) & 0x01F80000, "andcc"), - Orcc((0x12 << 19) & 0x01F80000, "orcc"), - Xorcc((0x13 << 19) & 0x01F80000, "xorcc"), - Subcc((0x14 << 19) & 0x01F80000, "subcc"), - Andncc((0x15 << 19) & 0x01F80000, "andncc"), - Orncc((0x16 << 19) & 0x01F80000, "orncc"), - Xnorcc((0x17 << 19) & 0x01F80000, "xnorcc"), - Addccc((0x18 << 19) & 0x01F80000, "addccc"), - Mulxcc((0x19 << 19) & 0x01F80000, "mulxcc"), - Umulcc((0x1A << 19) & 0x01F80000, "umulcc"), - Smulcc((0x1B << 19) & 0x01F80000, "smulcc"), - Subccc((0x1C << 19) & 0x01F80000, "subccc"), - Udivcc((0x1E << 19) & 0x01F80000, "udivcc"), - Sdivcc((0x1F << 19) & 0x01F80000, "sdivcc"), + Taddcc(0x20, "taddcc"), + Tsubcc(0x21, "tsubcc"), + Taddcctv(0x22, "taddcctv"), + Tsubcctv(0x23, "tsubcctv"), + Mulscc(0x24, "mulscc"), + Sll(0x25, "sll"), + Sllx(0x25, "sllx"), + Srl(0x26, "srl"), + Srlx(0x26, "srlx"), + Sra(0x27, "srax"), + Srax(0x27, "srax"), + Rdreg(0x28, "rdreg"), + Membar(0x28, "membar"), + + Flushw(0x2B, "flushw"), + Movcc(0x2C, "movcc"), + Sdivx(0x2D, "sdivx"), + Popc(0x2E, "popc"), + Movr(0x2F, "movr"), + + Sir(0x30, "sir"), + Wrreg(0x30, "wrreg"), + Saved(0x31, "saved"), - Taddcc((0x20 << 19) & 0x01F80000, "taddcc"), - Tsubcc((0x21 << 19) & 0x01F80000, "tsubcc"), - Taddcctv((0x22 << 19) & 0x01F80000, "taddcctv"), - Tsubcctv((0x23 << 19) & 0x01F80000, "tsubcctv"), - Mulscc((0x23 << 19) & 0x01F80000, "mulscc"), - Sll((0x25 << 19) & 0x01F80000, "sll"), - Sllx((0x25 << 19) & 0x01F80000, "sllx"), - Srl((0x26 << 19) & 0x01F80000, "srl"), - Srlx((0x26 << 19) & 0x01F80000, "srlx"), - Sra((0x27 << 19) & 0x01F80000, "srax"), - Srax((0x27 << 19) & 0x01F80000, "srax"), - Rdreg((0x27 << 19) & 0x01F80000, "rdreg"), - Membar((0x27 << 19) & 0x01F80000, "membar"); + Fpop1(0x34, "fpop1"), + Fpop2(0x35, "fpop2"), + Impdep1(0x36, "impdep1"), + Impdep2(0x37, "impdep2"), + Jmpl(0x38, "jmpl"), + Rett(0x39, "rett"), + Trap(0x3a, "trap"), + Flush(0x3b, "flush"), + Save(0x3c, "save"), + Restore(0x3d, "restore"), + Done(0x3e, "done"), + Retry(0x3e, "retry"), + + Lduw(0x00, "lduw"), + Ldub(0x01, "ldub"), + Lduh(0x02, "lduh"), + Ldd(0x03, "ldd"), + Stw(0x04, "stw"), + Stb(0x05, "stb"), + Sth(0x06, "sth"), + Std(0x07, "std"), + Ldsw(0x08, "ldsw"), + Ldsb(0x09, "ldsb"), + Ldsh(0x0A, "ldsh"), + Ldx(0x0b, "ldx"), + Stx(0x0e, "stx"), + + Ldf(0x20, "ldf"), + Ldfsr(0x21, "ldfsr"), + Ldaf(0x22, "ldaf"), + Lddf(0x23, "lddf"), + Stf(0x24, "stf"), + Stfsr(0x25, "stfsr"), + Staf(0x26, "staf"), + Stdf(0x27, "stdf"); private final int value; private final String operator; @@ -114,23 +389,214 @@ } } - @SuppressWarnings("unused") - public SPARCAssembler(TargetDescription target) { - super(target); - // TODO Auto-generated constructor stub - SPARC sparc; + public enum Opfs { + Fmovs(0x01, "fmovs"), + Fmovd(0x02, "fmovd"), + Fmovq(0x03, "fmovq"), + Fnegs(0x05, "fnegs"), + Fnegd(0x06, "fnegd"), + Fnegq(0x07, "fnegq"), + Fabss(0x09, "fabss"), + Fabsd(0x0A, "fabsd"), + Fabsq(0x0B, "fabsq"), + Fadds(0x41, "fadds"), + Faddd(0x42, "faddd"), + Faddq(0x43, "faddq"), + Fsubs(0x45, "fsubs"), + Fsubd(0x46, "fsubd"), + Fsubq(0x47, "fsubq"), + Fmuls(0x49, "fmuls"), + Fmuld(0x4A, "fmuld"), + Fdivs(0x4C, "fdivs"), + Fdivd(0x4D, "fdivd"), + Fdivq(0x4E, "fdivq"), + + Fsqrts(0x29, "fsqrts"), + Fsqrtd(0x2A, "fsqrtd"), + Fsqrtq(0x2B, "fsqrtq"), + + Fsmuld(0x69, "fsmuld"), + Fmulq(0x6B, "fmulq"), + Fdmuldq(0x6E, "fdmulq"), + + Fstoi(0xD1, "fstoi"), + Fdtoi(0xD2, "fdtoi"); + + private final int value; + private final String operator; + + private Opfs(int value, String op) { + this.value = value; + this.operator = op; + } + + public int getValue() { + return value; + } + + public String getOperator() { + return operator; + } + } + + public enum MembarMask { + StoreStore(1 << 3, "storestore"), + LoadStore(1 << 2, "loadstore"), + StoreLoad(1 << 1, "storeload"), + LoadLoad(1 << 0, "loadload"), + Sync(1 << 6, "sync"), + MemIssue(1 << 5, "memissue"), + LookAside(1 << 4, "lookaside"); + + private final int value; + private final String operator; + + private MembarMask(int value, String op) { + this.value = value; + this.operator = op; + } + + public int getValue() { + return value | 0x2000; + } + + public String getOperator() { + return operator; + } + } + + public enum CC { + Icc(4, "icc"), + Xcc(6, "xcc"), + Ptrcc(HotSpotGraalRuntime.wordKind() == Kind.Long ? Xcc.getValue() : Icc.getValue(), "ptrcc"), + Fcc0(0, "fcc0"), + Fcc1(1, "fcc1"), + Fcc2(2, "fcc2"), + Fcc3(3, "fcc3"); + + private final int value; + private final String operator; + + private CC(int value, String op) { + this.value = value; + this.operator = op; + } + + public int getValue() { + return value; + } + + public String getOperator() { + return operator; + } } - public static final int rs1(int val) { - return val; + public enum ConditionFlag { + // for FBfcc & FBPfcc instruction + + F_Never(0, "f_never"), + F_NotEqual(1, "f_notEqual"), + F_NotZero(1, "f_notZero"), + F_LessOrGreater(2, "f_lessOrGreater"), + F_UnorderedOrLess(3, "f_unorderedOrLess"), + F_Less(4, "f_less"), + F_UnorderedOrGreater(5, "f_unorderedOrGreater"), + F_Greater(6, "f_greater"), + F_Unordered(7, "f_unordered"), + F_Always(8, "f_always"), + F_Equal(9, "f_equal"), + F_Zero(9, "f_zero"), + F_UnorderedOrEqual(10, "f_unorderedOrEqual"), + F_GreaterOrEqual(11, "f_greaterOrEqual"), + F_UnorderedGreaterOrEqual(12, "f_unorderedGreaterOrEqual"), + F_LessOrEqual(13, "f_lessOrEqual"), + F_UnorderedOrLessOrEqual(14, "f_unorderedOrLessOrEqual"), + F_Ordered(15, "f_ordered"), + + // for integers + Never(0, "never"), + Equal(1, "equal"), + Zero(1, "zero"), + LessEqual(2, "lessEqual"), + Less(3, "less"), + LessEqualUnsigned(4, "lessEqualUnsigned"), + LessUnsigned(5, "lessUnsigned"), + CarrySet(5, "carrySet"), + Negative(6, "negative"), + OverflowSet(7, "overflowSet"), + Always(8, "always"), + NotEqual(9, "notEqual"), + NotZero(9, "notZero"), + Greater(10, "greater"), + GreaterEqual(11, "greaterEqual"), + GreaterUnsigned(12, "greaterUnsigned"), + GreaterEqualUnsigned(13, "greaterEqualUnsigned"), + CarryClear(13, "carryClear"), + Positive(14, "positive"), + OverflowClear(15, "overflowClear"); + + private final int value; + private final String operator; + + private ConditionFlag(int value, String op) { + this.value = value; + this.operator = op; + } + + public int getValue() { + return value; + } + + public String getOperator() { + return operator; + } } - public static final int rs2(int val) { - return val; + public enum RCondition { + Rc_z(1, "rc_z"), + Rc_lez(2, "rc_lez"), + Rc_lz(3, "rc_lz"), + Rc_nz(5, "rc_nz"), + Rc_gz(6, "rc_gz"), + Rc_gez(7, "rc_gez"), + Rc_last(Rc_gez.getValue(), "rc_last"); + + private final int value; + private final String operator; + + private RCondition(int value, String op) { + this.value = value; + this.operator = op; + } + + public int getValue() { + return value; + } + + public String getOperator() { + return operator; + } } - public static final int rd(int val) { - return val; + public static int getFloatEncoding(int reg) { + assert reg < 32; + return reg; + } + + public static int getDoubleEncoding(int reg) { + assert reg < 64 && ((reg & 1) == 0); + // ignore v8 assertion for now + return (reg & 0x1e) | ((reg & 0x20) >> 5); + } + + public static int getQuadEncoding(int reg) { + assert reg < 64 && ((reg & 3) == 0); + // ignore v8 assertion for now + return (reg & 0x1c) | ((reg & 0x20) >> 5); + } + + public SPARCAssembler(TargetDescription target, @SuppressWarnings("unused") RegisterConfig registerConfig) { + super(target); } public static final int sx1 = 0x00001000; @@ -140,372 +606,1004 @@ return x & ((1 << nbits) - 1); } - public final void add(Register src1, Register src2, Register dst) { - emitInt(Ops.ArithOp.getValue() | Op3s.Add.getValue() | rs1(src1.encoding()) | rs2(src2.encoding()) | rd(dst.encoding())); + private static final int max13 = ((1 << 12) - 1); + private static final int min13 = -(1 << 12); + + public static boolean isSimm13(int src) { + return min13 <= src && src <= max13; + } + + public static final int hi22(int x) { + return x >> 10; + } + + public static final int lo10(int x) { + return x & ((1 << 10) - 1); + } + + @Override + @SuppressWarnings("unused") + public void jmp(Label l) { + new Bpa(this, l); } - public final void add(Register src1, int simm13, Register dst) { - emitInt(Ops.ArithOp.getValue() | Op3s.Add.getValue() | rs1(src1.encoding()) | ImmedTrue | simm(simm13, 13) | rd(dst.encoding())); + public static class Add extends Fmt3b { + public Add(SPARCAssembler masm, Register src1, int simm13, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Add.getValue(), src1.encoding(), simm13, dst.encoding()); + } + public Add(SPARCAssembler masm, Register src1, Register src2, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Add.getValue(), src1.encoding(), src2.encoding(), dst.encoding()); + } + } + + public static class Addc extends Fmt3b { + public Addc(SPARCAssembler masm, Register src1, int simm13, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Addc.getValue(), src1.encoding(), simm13, dst.encoding()); + } + public Addc(SPARCAssembler masm, Register src1, Register src2, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Addc.getValue(), src1.encoding(), src2.encoding(), dst.encoding()); + } + } + + public static class Addcc extends Fmt3b { + public Addcc(SPARCAssembler masm, Register src1, int simm13, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Addcc.getValue(), src1.encoding(), simm13, dst.encoding()); + } + public Addcc(SPARCAssembler masm, Register src1, Register src2, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Addcc.getValue(), src1.encoding(), src2.encoding(), dst.encoding()); + } + } + + public static class Addccc extends Fmt3b { + public Addccc(SPARCAssembler masm, Register src1, int simm13, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Addccc.getValue(), src1.encoding(), simm13, dst.encoding()); + } + public Addccc(SPARCAssembler masm, Register src1, Register src2, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Addccc.getValue(), src1.encoding(), src2.encoding(), dst.encoding()); + } } - public final void addcc(Register src1, Register src2, Register dst) { - emitInt(Ops.ArithOp.getValue() | Op3s.Addcc.getValue() | rs1(src1.encoding()) | rs2(src2.encoding()) | rd(dst.encoding())); + public static class And extends Fmt3b { + public And(SPARCAssembler masm, Register src1, int simm13, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.And.getValue(), src1.encoding(), simm13, dst.encoding()); + } + public And(SPARCAssembler masm, Register src1, Register src2, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.And.getValue(), src1.encoding(), src2.encoding(), dst.encoding()); + } + } + + public static class Andcc extends Fmt3b { + public Andcc(SPARCAssembler masm, Register src1, int simm13, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Andcc.getValue(), src1.encoding(), simm13, dst.encoding()); + } + public Andcc(SPARCAssembler masm, Register src1, Register src2, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Andcc.getValue(), src1.encoding(), src2.encoding(), dst.encoding()); + } + } + + public static class Andn extends Fmt3b { + public Andn(SPARCAssembler masm, Register src1, int simm13, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Andn.getValue(), src1.encoding(), simm13, dst.encoding()); + } + public Andn(SPARCAssembler masm, Register src1, Register src2, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Andn.getValue(), src1.encoding(), src2.encoding(), dst.encoding()); + } } - public final void addcc(Register src1, int simm13, Register dst) { - emitInt(Ops.ArithOp.getValue() | Op3s.Addcc.getValue() | rs1(src1.encoding()) | ImmedTrue | simm(simm13, 13) | rd(dst.encoding())); + public static class Andncc extends Fmt3b { + public Andncc(SPARCAssembler masm, Register src1, int simm13, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Andncc.getValue(), src1.encoding(), simm13, dst.encoding()); + } + public Andncc(SPARCAssembler masm, Register src1, Register src2, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Andncc.getValue(), src1.encoding(), src2.encoding(), dst.encoding()); + } + } + + public static class Bpa extends Fmt2c { + public Bpa(SPARCAssembler masm, int simmm19) { + super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.Always.getValue(), + Op2s.Bp.getValue(), CC.Icc.getValue(), 1, simmm19); + } + public Bpa(SPARCAssembler masm, Label label) { + super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.Always.getValue(), + Op2s.Bp.getValue(), CC.Icc.getValue(), 1, + label.isBound() ? label.position() : patchUnbound(masm, label)); + } } - public final void addc(Register src1, Register src2, Register dst) { - emitInt(Ops.ArithOp.getValue() | Op3s.Addc.getValue() | rs1(src1.encoding()) | rs2(src2.encoding()) | rd(dst.encoding())); + public static class Bpcc extends Fmt2c { + public Bpcc(SPARCAssembler masm, CC cc, int simmm19) { + super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.CarryClear.getValue(), + Op2s.Bp.getValue(), cc.getValue(), 1, simmm19); + } + public Bpcc(SPARCAssembler masm, CC cc, Label label) { + super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.CarryClear.getValue(), + Op2s.Bp.getValue(), cc.getValue(), 1, + label.isBound() ? label.position() : patchUnbound(masm, label)); + } } - public final void addc(Register src1, int simm13, Register dst) { - emitInt(Ops.ArithOp.getValue() | Op3s.Addc.getValue() | rs1(src1.encoding()) | ImmedTrue | simm(simm13, 13) | rd(dst.encoding())); + public static class Bpcs extends Fmt2c { + public Bpcs(SPARCAssembler masm, CC cc, int simmm19) { + super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.CarrySet.getValue(), + Op2s.Bp.getValue(), cc.getValue(), 1, simmm19); + } + public Bpcs(SPARCAssembler masm, CC cc, Label label) { + super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.CarrySet.getValue(), + Op2s.Bp.getValue(), cc.getValue(), 1, + label.isBound() ? label.position() : patchUnbound(masm, label)); + } } - public final void addccc(Register src1, Register src2, Register dst) { - emitInt(Ops.ArithOp.getValue() | Op3s.Addccc.getValue() | rs1(src1.encoding()) | rs2(src2.encoding()) | rd(dst.encoding())); + public static class Bpe extends Fmt2c { + public Bpe(SPARCAssembler masm, CC cc, int simmm19) { + super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.Equal.getValue(), + Op2s.Bp.getValue(), cc.getValue(), 1, simmm19); + } + public Bpe(SPARCAssembler masm, CC cc, Label label) { + super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.Equal.getValue(), + Op2s.Bp.getValue(), cc.getValue(), 1, + label.isBound() ? label.position() : patchUnbound(masm, label)); + } + } + + public static class Bpg extends Fmt2c { + public Bpg(SPARCAssembler masm, CC cc, int simmm19) { + super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.Greater.getValue(), + Op2s.Bp.getValue(), cc.getValue(), 1, simmm19); + } + public Bpg(SPARCAssembler masm, CC cc, Label label) { + super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.Greater.getValue(), + Op2s.Bp.getValue(), cc.getValue(), 1, + label.isBound() ? label.position() : patchUnbound(masm, label)); + } } - public final void addccc(Register src1, int simm13, Register dst) { - emitInt(Ops.ArithOp.getValue() | Op3s.Addccc.getValue() | rs1(src1.encoding()) | ImmedTrue | simm(simm13, 13) | rd(dst.encoding())); + public static class Bpge extends Fmt2c { + public Bpge(SPARCAssembler masm, CC cc, int simmm19) { + super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.GreaterEqual.getValue(), + Op2s.Bp.getValue(), cc.getValue(), 1, simmm19); + } + public Bpge(SPARCAssembler masm, CC cc, Label label) { + super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.GreaterEqual.getValue(), + Op2s.Bp.getValue(), cc.getValue(), 1, + label.isBound() ? label.position() : patchUnbound(masm, label)); + } } - public final void and(Register src1, Register src2, Register dst) { - emitInt(Ops.ArithOp.getValue() | Op3s.And.getValue() | rs1(src1.encoding()) | rs2(src2.encoding()) | rd(dst.encoding())); + public static class Bpgu extends Fmt2c { + public Bpgu(SPARCAssembler masm, CC cc, int simmm19) { + super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.GreaterUnsigned.getValue(), + Op2s.Bp.getValue(), cc.getValue(), 1, simmm19); + } + public Bpgu(SPARCAssembler masm, CC cc, Label label) { + super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.GreaterUnsigned.getValue(), + Op2s.Bp.getValue(), cc.getValue(), 1, + label.isBound() ? label.position() : patchUnbound(masm, label)); + } + } + + public static class Bpl extends Fmt2c { + public Bpl(SPARCAssembler masm, CC cc, int simmm19) { + super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.Less.getValue(), + Op2s.Bp.getValue(), cc.getValue(), 1, simmm19); + } + public Bpl(SPARCAssembler masm, CC cc, Label label) { + super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.Less.getValue(), + Op2s.Bp.getValue(), cc.getValue(), 1, + label.isBound() ? label.position() : patchUnbound(masm, label)); + } } - public final void and(Register src1, int simm13, Register dst) { - emitInt(Ops.ArithOp.getValue() | Op3s.And.getValue() | rs1(src1.encoding()) | ImmedTrue | simm(simm13, 13) | rd(dst.encoding())); + public static class Bple extends Fmt2c { + public Bple(SPARCAssembler masm, CC cc, int simmm19) { + super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.LessEqual.getValue(), + Op2s.Bp.getValue(), cc.getValue(), 1, simmm19); + } + public Bple(SPARCAssembler masm, CC cc, Label label) { + super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.LessEqual.getValue(), + Op2s.Bp.getValue(), cc.getValue(), 1, + label.isBound() ? label.position() : patchUnbound(masm, label)); + } } - public final void andcc(Register src1, Register src2, Register dst) { - emitInt(Ops.ArithOp.getValue() | Op3s.Andcc.getValue() | rs1(src1.encoding()) | rs2(src2.encoding()) | rd(dst.encoding())); + public static class Bpleu extends Fmt2c { + public Bpleu(SPARCAssembler masm, CC cc, int simmm19) { + super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.LessEqualUnsigned.getValue(), + Op2s.Bp.getValue(), cc.getValue(), 1, simmm19); + } + public Bpleu(SPARCAssembler masm, CC cc, Label label) { + super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.LessEqualUnsigned.getValue(), + Op2s.Bp.getValue(), cc.getValue(), 1, + label.isBound() ? label.position() : patchUnbound(masm, label)); + } + } + + public static class Bpn extends Fmt2c { + public Bpn(SPARCAssembler masm, CC cc, int simmm19) { + super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.Never.getValue(), + Op2s.Bp.getValue(), cc.getValue(), 1, simmm19); + } + public Bpn(SPARCAssembler masm, CC cc, Label label) { + super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.Never.getValue(), + Op2s.Bp.getValue(), cc.getValue(), 1, + label.isBound() ? label.position() : patchUnbound(masm, label)); + } } - public final void andcc(Register src1, int simm13, Register dst) { - emitInt(Ops.ArithOp.getValue() | Op3s.Andcc.getValue() | rs1(src1.encoding()) | ImmedTrue | simm(simm13, 13) | rd(dst.encoding())); + public static class Bpne extends Fmt2c { + public Bpne(SPARCAssembler masm, CC cc, int simmm19) { + super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.NotZero.getValue(), + Op2s.Bp.getValue(), cc.getValue(), 1, simmm19); + } + public Bpne(SPARCAssembler masm, CC cc, Label label) { + super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.NotZero.getValue(), + Op2s.Bp.getValue(), cc.getValue(), 1, + label.isBound() ? label.position() : patchUnbound(masm, label)); + } } - public final void andn(Register src1, Register src2, Register dst) { - emitInt(Ops.ArithOp.getValue() | Op3s.Andn.getValue() | rs1(src1.encoding()) | rs2(src2.encoding()) | rd(dst.encoding())); + public static class Bpneg extends Fmt2c { + public Bpneg(SPARCAssembler masm, CC cc, int simmm19) { + super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.Negative.getValue(), + Op2s.Bp.getValue(), cc.getValue(), 1, simmm19); + } + public Bpneg(SPARCAssembler masm, CC cc, Label label) { + super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.Negative.getValue(), + Op2s.Bp.getValue(), cc.getValue(), 1, + label.isBound() ? label.position() : patchUnbound(masm, label)); + } } - public final void andn(Register src1, int simm13, Register dst) { - emitInt(Ops.ArithOp.getValue() | Op3s.Andn.getValue() | rs1(src1.encoding()) | ImmedTrue | simm(simm13, 13) | rd(dst.encoding())); + public static class Bppos extends Fmt2c { + public Bppos(SPARCAssembler masm, CC cc, int simmm19) { + super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.Positive.getValue(), + Op2s.Bp.getValue(), cc.getValue(), 1, simmm19); + } + public Bppos(SPARCAssembler masm, CC cc, Label label) { + super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.Positive.getValue(), + Op2s.Bp.getValue(), cc.getValue(), 1, + label.isBound() ? label.position() : patchUnbound(masm, label)); + } + } + + public static class Bpvc extends Fmt2c { + public Bpvc(SPARCAssembler masm, CC cc, int simmm19) { + super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.OverflowClear.getValue(), + Op2s.Bp.getValue(), cc.getValue(), 1, simmm19); + } + public Bpvc(SPARCAssembler masm, CC cc, Label label) { + super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.OverflowClear.getValue(), + Op2s.Bp.getValue(), cc.getValue(), 1, + label.isBound() ? label.position() : patchUnbound(masm, label)); + } } - public final void andncc(Register src1, Register src2, Register dst) { - emitInt(Ops.ArithOp.getValue() | Op3s.Andncc.getValue() | rs1(src1.encoding()) | rs2(src2.encoding()) | rd(dst.encoding())); + public static class Bpvs extends Fmt2c { + public Bpvs(SPARCAssembler masm, CC cc, int simmm19) { + super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.OverflowSet.getValue(), + Op2s.Bp.getValue(), cc.getValue(), 1, simmm19); + } + public Bpvs(SPARCAssembler masm, CC cc, Label label) { + super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.OverflowSet.getValue(), + Op2s.Bp.getValue(), cc.getValue(), 1, + label.isBound() ? label.position() : patchUnbound(masm, label)); + } + } + + private static int patchUnbound(SPARCAssembler masm, Label label) { + label.addPatchAt(masm.codeBuffer.position()); + return 0; + } + + public static class Fadds extends Fmt3p { + public Fadds(SPARCAssembler masm, Register src1, Register src2, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Fpop1.getValue(), Opfs.Fadds.getValue(), + src1.encoding(), src2.encoding(), dst.encoding()); + } + } + + public static class Faddd extends Fmt3p { + public Faddd(SPARCAssembler masm, Register src1, Register src2, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Fpop1.getValue(), Opfs.Faddd.getValue(), + src1.encoding(), src2.encoding(), dst.encoding()); + } } - public final void andncc(Register src1, int simm13, Register dst) { - emitInt(Ops.ArithOp.getValue() | Op3s.Andncc.getValue() | rs1(src1.encoding()) | ImmedTrue | simm(simm13, 13) | rd(dst.encoding())); + public static class Faddq extends Fmt3p { + public Faddq(SPARCAssembler masm, Register src1, Register src2, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Fpop1.getValue(), Opfs.Faddq.getValue(), + src1.encoding(), src2.encoding(), dst.encoding()); + } + } + + public static class Fdivs extends Fmt3p { + public Fdivs(SPARCAssembler masm, Register src1, Register src2, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Fpop1.getValue(), Opfs.Fdivs.getValue(), + src1.encoding(), src2.encoding(), dst.encoding()); + } } - public final void mulscc(Register src1, Register src2, Register dst) { - emitInt(Ops.ArithOp.getValue() | Op3s.Mulscc.getValue() | rs1(src1.encoding()) | rs2(src2.encoding()) | rd(dst.encoding())); + public static class Fdivd extends Fmt3p { + public Fdivd(SPARCAssembler masm, Register src1, Register src2, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Fpop1.getValue(), Opfs.Fdivd.getValue(), + src1.encoding(), src2.encoding(), dst.encoding()); + } + } + + public static class Fmuls extends Fmt3p { + public Fmuls(SPARCAssembler masm, Register src1, Register src2, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Fpop1.getValue(), Opfs.Fmuls.getValue(), + src1.encoding(), src2.encoding(), dst.encoding()); + } + } + + public static class Fmuld extends Fmt3p { + public Fmuld(SPARCAssembler masm, Register src1, Register src2, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Fpop1.getValue(), Opfs.Fmuld.getValue(), + src1.encoding(), src2.encoding(), dst.encoding()); + } } - public final void mulscc(Register src1, int simm13, Register dst) { - emitInt(Ops.ArithOp.getValue() | Op3s.Mulscc.getValue() | rs1(src1.encoding()) | ImmedTrue | simm(simm13, 13) | rd(dst.encoding())); + public static class Fnegs extends Fmt3n { + public Fnegs(SPARCAssembler masm, Register src2, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Fpop1.getValue(), Opfs.Fnegs.getValue(), + src2.encoding(), dst.encoding()); + } + } + + public static class Fnegd extends Fmt3n { + public Fnegd(SPARCAssembler masm, Register src2, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Fpop1.getValue(), Opfs.Fnegd.getValue(), + src2.encoding(), dst.encoding()); + } + } + + public static class Fstoi extends Fmt3n { + public Fstoi(SPARCAssembler masm, Register src2, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Fpop1.getValue(), Opfs.Fstoi.getValue(), + src2.encoding(), dst.encoding()); + } + } + + public static class Fdtoi extends Fmt3n { + public Fdtoi(SPARCAssembler masm, Register src2, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Fpop1.getValue(), Opfs.Fdtoi.getValue(), + src2.encoding(), dst.encoding()); + } + } + + public static class Flushw extends Fmt3r { + public Flushw(SPARCAssembler masm) { + super(masm, Ops.ArithOp.getValue(), 0, Op3s.Flushw.getValue()); + } } - public final void mulx(Register src1, Register src2, Register dst) { - emitInt(Ops.ArithOp.getValue() | Op3s.Mulx.getValue() | rs1(src1.encoding()) | rs2(src2.encoding()) | rd(dst.encoding())); + public static class Fsqrtd extends Fmt3p { + public Fsqrtd(SPARCAssembler masm, Register src2, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Fpop1.getValue(), Opfs.Fsqrtd.getValue(), + 0, src2.encoding(), dst.encoding()); + } + } + + + public static class Fsubs extends Fmt3p { + public Fsubs(SPARCAssembler masm, Register src1, Register src2, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Fpop1.getValue(), Opfs.Fsubs.getValue(), + src1.encoding(), src2.encoding(), dst.encoding()); + } } - public final void mulx(Register src1, int simm13, Register dst) { - emitInt(Ops.ArithOp.getValue() | Op3s.Mulx.getValue() | rs1(src1.encoding()) | ImmedTrue | simm(simm13, 13) | rd(dst.encoding())); + public static class Fsubd extends Fmt3p { + public Fsubd(SPARCAssembler masm, Register src1, Register src2, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Fpop1.getValue(), Opfs.Fsubd.getValue(), + src1.encoding(), src2.encoding(), dst.encoding()); + } } - public final void or(Register src1, Register src2, Register dst) { - emitInt(Ops.ArithOp.getValue() | Op3s.Or.getValue() | rs1(src1.encoding()) | rs2(src2.encoding()) | rd(dst.encoding())); + public static class Fsubq extends Fmt3p { + public Fsubq(SPARCAssembler masm, Register src1, Register src2, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Fpop1.getValue(), Opfs.Fsubq.getValue(), + src1.encoding(), src2.encoding(), dst.encoding()); + } + } + + public static class Jmpl extends Fmt3b { + public Jmpl(SPARCAssembler asm, SPARCAddress src, Register dst) { + super(asm, Ops.ArithOp.getValue(), Op3s.Jmpl.getValue(), + src.getBase().encoding(), src.getDisplacement(), dst.encoding()); + } + } + + public static class Lddf extends Fmt3b { + public Lddf(SPARCAssembler masm, SPARCAddress src, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Lddf.getValue(), + src.getBase().encoding(), src.getDisplacement(), dst.encoding()); + } } - public final void or(Register src1, int simm13, Register dst) { - emitInt(Ops.ArithOp.getValue() | Op3s.Or.getValue() | rs1(src1.encoding()) | ImmedTrue | simm(simm13, 13) | rd(dst.encoding())); + public static class Ldf extends Fmt3b { + public Ldf(SPARCAssembler masm, SPARCAddress src, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Ldf.getValue(), + src.getBase().encoding(), src.getDisplacement(), dst.encoding()); + } + } + + public static class Ldsb extends Fmt3b { + public Ldsb(SPARCAssembler masm, SPARCAddress src, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Ldsb.getValue(), + src.getBase().encoding(), src.getDisplacement(), dst.encoding()); + } + } + + public static class Ldsh extends Fmt3b { + public Ldsh(SPARCAssembler masm, SPARCAddress src, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Ldsh.getValue(), + src.getBase().encoding(), src.getDisplacement(), dst.encoding()); + } + } + + public static class Ldsw extends Fmt3b { + public Ldsw(SPARCAssembler masm, SPARCAddress src, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Ldsw.getValue(), + src.getBase().encoding(), src.getDisplacement(), dst.encoding()); + } + } + + public static class Lduw extends Fmt3b { + public Lduw(SPARCAssembler masm, SPARCAddress src, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Lduw.getValue(), + src.getBase().encoding(), src.getDisplacement(), dst.encoding()); + } } - public final void orcc(Register src1, Register src2, Register dst) { - emitInt(Ops.ArithOp.getValue() | Op3s.Orcc.getValue() | rs1(src1.encoding()) | rs2(src2.encoding()) | rd(dst.encoding())); + public static class Ldx extends Fmt3b { + public Ldx(SPARCAssembler masm, SPARCAddress src, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Ldx.getValue(), + src.getBase().encoding(), src.getDisplacement(), dst.encoding()); + } + } + + public static class Membar extends Fmt3b { + public Membar(SPARCAssembler masm, int barriers) { + super(masm, Ops.ArithOp.getValue(), Op3s.Membar.getValue(), + SPARC.r15.encoding(), ImmedTrue | barriers, SPARC.r0.encoding()); + } } - public final void orcc(Register src1, int simm13, Register dst) { - emitInt(Ops.ArithOp.getValue() | Op3s.Orcc.getValue() | rs1(src1.encoding()) | ImmedTrue | simm(simm13, 13) | rd(dst.encoding())); + public static class Movcc extends Fmt4c { + public Movcc(SPARCAssembler masm, ConditionFlag cond, CC cca, Register src2, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Movcc.getValue(), cond.getValue(), cca.getValue(), + src2.encoding(), dst.encoding()); + } + public Movcc(SPARCAssembler masm, ConditionFlag cond, CC cca, int simm11a, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Movcc.getValue(), cond.getValue(), cca.getValue(), + simm11a, dst.encoding()); + } + } + + public static class Movr extends Fmt3f { + public Movr(SPARCAssembler masm, RCondition rc, Register src1, Register src2, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Movr.getValue(), rc.getValue(), + src1.encoding(), src2.encoding(), dst.encoding()); + } + public Movr(SPARCAssembler masm, RCondition rc, Register src1, int simm10, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Movr.getValue(), rc.getValue(), + src1.encoding(), simm10, dst.encoding()); + } } - public final void orn(Register src1, Register src2, Register dst) { - emitInt(Ops.ArithOp.getValue() | Op3s.Orn.getValue() | rs1(src1.encoding()) | rs2(src2.encoding()) | rd(dst.encoding())); + @Deprecated + public static class Mulscc extends Fmt3b { + @Deprecated + public Mulscc(SPARCAssembler masm, Register src1, int simm13, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Mulscc.getValue(), src1.encoding(), simm13, dst.encoding()); + } + @Deprecated + public Mulscc(SPARCAssembler masm, Register src1, Register src2, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Mulscc.getValue(), src1.encoding(), src2.encoding(), dst.encoding()); + } } - public final void orn(Register src1, int simm13, Register dst) { - emitInt(Ops.ArithOp.getValue() | Op3s.Orn.getValue() | rs1(src1.encoding()) | ImmedTrue | simm(simm13, 13) | rd(dst.encoding())); + public static class Mulx extends Fmt3b { + public Mulx(SPARCAssembler masm, Register src1, int simm13, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Mulx.getValue(), src1.encoding(), simm13, dst.encoding()); + } + public Mulx(SPARCAssembler masm, Register src1, Register src2, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Mulx.getValue(), src1.encoding(), src2.encoding(), dst.encoding()); + } + } + + public static class NullCheck extends Fmt3b { + public NullCheck(SPARCAssembler masm, SPARCAddress src) { + super(masm, Ops.ArithOp.getValue(), Op3s.Ldx.getValue(), + src.getBase().encoding(), src.getDisplacement(), SPARC.r0.encoding()); + } } - public final void orncc(Register src1, Register src2, Register dst) { - emitInt(Ops.ArithOp.getValue() | Op3s.Orncc.getValue() | rs1(src1.encoding()) | rs2(src2.encoding()) | rd(dst.encoding())); + public static class Or extends Fmt3b { + public Or(SPARCAssembler masm, Register src1, int simm13, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Or.getValue(), src1.encoding(), simm13, dst.encoding()); + } + public Or(SPARCAssembler masm, Register src1, Register src2, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Or.getValue(), src1.encoding(), src2.encoding(), dst.encoding()); + } + } + + public static class Orcc extends Fmt3b { + public Orcc(SPARCAssembler masm, Register src1, int simm13, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Orcc.getValue(), src1.encoding(), simm13, dst.encoding()); + } + public Orcc(SPARCAssembler masm, Register src1, Register src2, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Orcc.getValue(), src1.encoding(), src2.encoding(), dst.encoding()); + } } - public final void orncc(Register src1, int simm13, Register dst) { - emitInt(Ops.ArithOp.getValue() | Op3s.Orncc.getValue() | rs1(src1.encoding()) | ImmedTrue | simm(simm13, 13) | rd(dst.encoding())); + public static class Orn extends Fmt3b { + public Orn(SPARCAssembler masm, Register src1, int simm13, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Orn.getValue(), src1.encoding(), simm13, dst.encoding()); + } + public Orn(SPARCAssembler masm, Register src1, Register src2, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Orn.getValue(), src1.encoding(), src2.encoding(), dst.encoding()); + } } - public final void rdy(Register dst) { - emitInt(Ops.ArithOp.getValue() | Op3s.Rdreg.getValue() | rd(dst.encoding())); + public static class Orncc extends Fmt3b { + public Orncc(SPARCAssembler masm, Register src1, int simm13, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Orncc.getValue(), src1.encoding(), simm13, dst.encoding()); + } + public Orncc(SPARCAssembler masm, Register src1, Register src2, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Orncc.getValue(), src1.encoding(), src2.encoding(), dst.encoding()); + } + } + + public static class Popc extends Fmt3b { + public Popc(SPARCAssembler masm, int simm13, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Popc.getValue(), 0, simm13, dst.encoding()); + } + public Popc(SPARCAssembler masm, Register src2, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Popc.getValue(), 0, src2.encoding(), dst.encoding()); + } } // A.44 Read State Register - public final void rdccr(Register dst) { - emitInt(Ops.ArithOp.getValue() | Op3s.Rdreg.getValue() | rd(dst.encoding()) | 0x00008000); + @Deprecated + public static class Rdy extends Fmt3q { + public Rdy(SPARCAssembler masm, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Rdreg.getValue(), 0, dst.encoding()); + } + } + + public static class Rdccr extends Fmt3q { + public Rdccr(SPARCAssembler masm, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Rdreg.getValue(), 2, dst.encoding()); + } } - public final void rdasi(Register dst) { - emitInt(Ops.ArithOp.getValue() | Op3s.Rdreg.getValue() | rd(dst.encoding()) | 0x0000C000); + public static class Rdasi extends Fmt3q { + public Rdasi(SPARCAssembler masm, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Rdreg.getValue(), 3, dst.encoding()); + } + } + + public static class Rdtick extends Fmt3q { + public Rdtick(SPARCAssembler masm, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Rdreg.getValue(), 4, dst.encoding()); + } + } + + public static class Rdpc extends Fmt3q { + public Rdpc(SPARCAssembler masm, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Rdreg.getValue(), 5, dst.encoding()); + } + } + + public static class Rdfprs extends Fmt3q { + public Rdfprs(SPARCAssembler masm, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Rdreg.getValue(), 6, dst.encoding()); + } } - public final void rdtick(Register dst) { - emitInt(Ops.ArithOp.getValue() | Op3s.Rdreg.getValue() | rd(dst.encoding()) | 0x00010000); + public static class Restore extends Fmt3b { + public Restore(SPARCAssembler asm, Register src1, Register src2, Register dst) { + super(asm, Ops.ArithOp.getValue(), Op3s.Restore.getValue(), + src1.encoding(), src2.encoding(), dst.encoding()); + } + } + + public static class Restored extends Fmt3r { + public Restored(SPARCAssembler asm) { + super(asm, Ops.ArithOp.getValue(), 1, Op3s.Saved.getValue()); + } + } + + public static class Return extends Fmt3d { + public Return(SPARCAssembler masm, Register src1, int simm13) { + super(masm, Ops.ArithOp.getValue(), Op3s.Rett.getValue(), src1.encoding(), simm13); + } + public Return(SPARCAssembler masm, Register src1, Register src2) { + super(masm, Ops.ArithOp.getValue(), Op3s.Rett.getValue(), src1.encoding(), src2.encoding()); + } } - public final void rdpc(Register dst) { - emitInt(Ops.ArithOp.getValue() | Op3s.Rdreg.getValue() | rd(dst.encoding()) | 0x00014000); + public static class Save extends Fmt3b { + public Save(SPARCAssembler asm, Register src1, Register src2, Register dst) { + super(asm, Ops.ArithOp.getValue(), Op3s.Save.getValue(), + src1.encoding(), src2.encoding(), dst.encoding()); + } } - public final void rdfprs(Register dst) { - emitInt(Ops.ArithOp.getValue() | Op3s.Rdreg.getValue() | rd(dst.encoding()) | 0x00018000); + public static class Saved extends Fmt3r { + public Saved(SPARCAssembler asm) { + super(asm, Ops.ArithOp.getValue(), 0, Op3s.Saved.getValue()); + } + } + + @Deprecated + public static class Sdiv extends Fmt3b { + @Deprecated + public Sdiv(SPARCAssembler masm, Register src1, int simm13, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Sdiv.getValue(), src1.encoding(), simm13, dst.encoding()); + } + @Deprecated + public Sdiv(SPARCAssembler masm, Register src1, Register src2, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Sdiv.getValue(), src1.encoding(), src2.encoding(), dst.encoding()); + } } @Deprecated - public final void sdiv(Register src1, Register src2, Register dst) { - emitInt(Ops.ArithOp.getValue() | Op3s.Sdiv.getValue() | rs1(src1.encoding()) | rs2(src2.encoding()) | rd(dst.encoding())); + public static class Sdivcc extends Fmt3b { + @Deprecated + public Sdivcc(SPARCAssembler masm, Register src1, int simm13, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Sdivcc.getValue(), src1.encoding(), simm13, dst.encoding()); + } + @Deprecated + public Sdivcc(SPARCAssembler masm, Register src1, Register src2, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Sdivcc.getValue(), src1.encoding(), src2.encoding(), dst.encoding()); + } + } + + public static class Sdivx extends Fmt3b { + public Sdivx(SPARCAssembler masm, Register src1, int simm13, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Sdivx.getValue(), src1.encoding(), simm13, dst.encoding()); + } + public Sdivx(SPARCAssembler masm, Register src1, Register src2, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Sdivx.getValue(), src1.encoding(), src2.encoding(), dst.encoding()); + } + } + + public static class Sethi extends Fmt2a { + public Sethi(SPARCAssembler masm, int simm22, Register dst) { + super(masm, Ops.BranchOp.getValue(), Op2s.Sethi.getValue(), simm22, dst.encoding()); + } + } + + public static class Sir extends Fmt3b { + public Sir(SPARCAssembler asm, int simm13) { + super(asm, Ops.ArithOp.getValue(), Op3s.Sir.getValue(), + SPARC.r0.encoding(), simm13, SPARC.r15.encoding()); + } + } + + public static class Sll extends Fmt3b { + public Sll(SPARCAssembler masm, Register src1, int simm13, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Sll.getValue(), src1.encoding(), simm13, dst.encoding()); + } + public Sll(SPARCAssembler masm, Register src1, Register src2, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Sll.getValue(), src1.encoding(), src2.encoding(), dst.encoding()); + } + } + + public static class Sllx extends Fmt3b { + public Sllx(SPARCAssembler masm, Register src1, int simm13, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Sllx.getValue(), src1.encoding(), simm13, dst.encoding()); + } + public Sllx(SPARCAssembler masm, Register src1, Register src2, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Sllx.getValue(), src1.encoding(), src2.encoding(), dst.encoding()); + } + } + + public static class Smul extends Fmt3b { + public Smul(SPARCAssembler masm, Register src1, int simm13, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Smul.getValue(), src1.encoding(), simm13, dst.encoding()); + } + public Smul(SPARCAssembler masm, Register src1, Register src2, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Smul.getValue(), src1.encoding(), src2.encoding(), dst.encoding()); + } } @Deprecated - public final void sdiv(Register src1, int simm13, Register dst) { - emitInt(Ops.ArithOp.getValue() | Op3s.Sdiv.getValue() | rs1(src1.encoding()) | ImmedTrue | simm(simm13, 13) | rd(dst.encoding())); + public static class Smulcc extends Fmt3b { + public Smulcc(SPARCAssembler masm, Register src1, int simm13, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Smulcc.getValue(), src1.encoding(), simm13, dst.encoding()); + } + public Smulcc(SPARCAssembler masm, Register src1, Register src2, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Smulcc.getValue(), src1.encoding(), src2.encoding(), dst.encoding()); + } + } + + public static class Sra extends Fmt3b { + public Sra(SPARCAssembler masm, Register src1, int simm13, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Sra.getValue(), src1.encoding(), simm13, dst.encoding()); + } + public Sra(SPARCAssembler masm, Register src1, Register src2, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Sra.getValue(), src1.encoding(), src2.encoding(), dst.encoding()); + } } - @Deprecated - public final void sdivcc(Register src1, Register src2, Register dst) { - emitInt(Ops.ArithOp.getValue() | Op3s.Sdivcc.getValue() | rs1(src1.encoding()) | rs2(src2.encoding()) | rd(dst.encoding())); + public static class Srax extends Fmt3b { + public Srax(SPARCAssembler masm, Register src1, int simm13, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Srax.getValue(), src1.encoding(), simm13, dst.encoding()); + } + public Srax(SPARCAssembler masm, Register src1, Register src2, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Srax.getValue(), src1.encoding(), src2.encoding(), dst.encoding()); + } + } + + public static class Srl extends Fmt3b { + public Srl(SPARCAssembler masm, Register src1, int simm13, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Srl.getValue(), src1.encoding(), simm13, dst.encoding()); + } + public Srl(SPARCAssembler masm, Register src1, Register src2, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Srl.getValue(), src1.encoding(), src2.encoding(), dst.encoding()); + } + } + + public static class Srlx extends Fmt3b { + public Srlx(SPARCAssembler masm, Register src1, int simm13, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Srlx.getValue(), src1.encoding(), simm13, dst.encoding()); + } + public Srlx(SPARCAssembler masm, Register src1, Register src2, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Srlx.getValue(), src1.encoding(), src2.encoding(), dst.encoding()); + } } @Deprecated - public final void sdivcc(Register src1, int simm13, Register dst) { - emitInt(Ops.ArithOp.getValue() | Op3s.Sdivcc.getValue() | rs1(src1.encoding()) | ImmedTrue | simm(simm13, 13) | rd(dst.encoding())); - } - - public final void sll(Register src1, Register src2, Register dst) { - emitInt(Ops.ArithOp.getValue() | Op3s.Sll.getValue() | rs1(src1.encoding()) | rs2(src2.encoding()) | rd(dst.encoding())); - } - - public final void sll(Register src1, int imm5a, Register dst) { - assert imm5a < 0x40; - emitInt(Ops.ArithOp.getValue() | Op3s.Sll.getValue() | rs1(src1.encoding()) | ImmedTrue | imm5a | rd(dst.encoding())); + public static class Stbar extends Fmt3b { + public Stbar(SPARCAssembler masm) { + super(masm, Ops.ArithOp.getValue(), Op3s.Membar.getValue(), + SPARC.r15.encoding(), 0, SPARC.r0.encoding()); + } } - public final void sllx(Register src1, Register src2, Register dst) { - emitInt(Ops.ArithOp.getValue() | Op3s.Sllx.getValue() | sx1 | rs1(src1.encoding()) | rs2(src2.encoding()) | rd(dst.encoding())); + public static class Stb extends Fmt3b { + public Stb(SPARCAssembler masm, Register dst, SPARCAddress addr) { + super(masm, Ops.ArithOp.getValue(), Op3s.Stb.getValue(), + addr.getBase().encoding(), addr.getDisplacement(), dst.encoding()); + } } - public final void sllx(Register src1, int imm5a, Register dst) { - assert imm5a < 0x40; - emitInt(Ops.ArithOp.getValue() | Op3s.Sllx.getValue() | sx1 | rs1(src1.encoding()) | ImmedTrue | imm5a | rd(dst.encoding())); - } - - public final void smul(Register src1, Register src2, Register dst) { - emitInt(Ops.ArithOp.getValue() | Op3s.Smul.getValue() | rs1(src1.encoding()) | rs2(src2.encoding()) | rd(dst.encoding())); - } - - public final void smul(Register src1, int simm13, Register dst) { - emitInt(Ops.ArithOp.getValue() | Op3s.Smul.getValue() | rs1(src1.encoding()) | ImmedTrue | simm(simm13, 13) | rd(dst.encoding())); + public static class Sth extends Fmt3b { + public Sth(SPARCAssembler masm, Register dst, SPARCAddress addr) { + super(masm, Ops.ArithOp.getValue(), Op3s.Sth.getValue(), + addr.getBase().encoding(), addr.getDisplacement(), dst.encoding()); + } } - public final void smulcc(Register src1, Register src2, Register dst) { - emitInt(Ops.ArithOp.getValue() | Op3s.Smulcc.getValue() | rs1(src1.encoding()) | rs2(src2.encoding()) | rd(dst.encoding())); - } - - public final void smulcc(Register src1, int simm13, Register dst) { - emitInt(Ops.ArithOp.getValue() | Op3s.Smulcc.getValue() | rs1(src1.encoding()) | ImmedTrue | simm(simm13, 13) | rd(dst.encoding())); + public static class Stw extends Fmt3b { + public Stw(SPARCAssembler masm, Register dst, SPARCAddress addr) { + super(masm, Ops.ArithOp.getValue(), Op3s.Stw.getValue(), + addr.getBase().encoding(), addr.getDisplacement(), dst.encoding()); + } } - public final void sra(Register src1, Register src2, Register dst) { - emitInt(Ops.ArithOp.getValue() | Op3s.Sra.getValue() | rs1(src1.encoding()) | rs2(src2.encoding()) | rd(dst.encoding())); - } - - public final void sra(Register src1, int imm5a, Register dst) { - assert imm5a < 0x40; - emitInt(Ops.ArithOp.getValue() | Op3s.Sra.getValue() | rs1(src1.encoding()) | ImmedTrue | imm5a | rd(dst.encoding())); + public static class Stx extends Fmt3b { + public Stx(SPARCAssembler masm, Register dst, SPARCAddress addr) { + super(masm, Ops.ArithOp.getValue(), Op3s.Stx.getValue(), + addr.getBase().encoding(), addr.getDisplacement(), dst.encoding()); + } } - public final void srax(Register src1, Register src2, Register dst) { - emitInt(Ops.ArithOp.getValue() | Op3s.Srax.getValue() | sx1 | rs1(src1.encoding()) | rs2(src2.encoding()) | rd(dst.encoding())); + public static class Sub extends Fmt3b { + public Sub(SPARCAssembler masm, Register src1, int simm13, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Sub.getValue(), src1.encoding(), simm13, dst.encoding()); + } + public Sub(SPARCAssembler masm, Register src1, Register src2, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Sub.getValue(), src1.encoding(), src2.encoding(), dst.encoding()); + } } - public final void srax(Register src1, int imm5a, Register dst) { - assert imm5a < 0x40; - emitInt(Ops.ArithOp.getValue() | Op3s.Srax.getValue() | sx1 | rs1(src1.encoding()) | ImmedTrue | imm5a | rd(dst.encoding())); - } - - public final void srl(Register src1, Register src2, Register dst) { - emitInt(Ops.ArithOp.getValue() | Op3s.Srl.getValue() | rs1(src1.encoding()) | rs2(src2.encoding()) | rd(dst.encoding())); - } - - public final void srl(Register src1, int imm5a, Register dst) { - assert imm5a < 0x40; - emitInt(Ops.ArithOp.getValue() | Op3s.Srl.getValue() | rs1(src1.encoding()) | ImmedTrue | imm5a | rd(dst.encoding())); + public static class Subc extends Fmt3b { + public Subc(SPARCAssembler masm, Register src1, int simm13, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Subc.getValue(), src1.encoding(), simm13, dst.encoding()); + } + public Subc(SPARCAssembler masm, Register src1, Register src2, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Subc.getValue(), src1.encoding(), src2.encoding(), dst.encoding()); + } } - public final void srlx(Register src1, Register src2, Register dst) { - emitInt(Ops.ArithOp.getValue() | Op3s.Srlx.getValue() | sx1 | rs1(src1.encoding()) | rs2(src2.encoding()) | rd(dst.encoding())); - } - - public final void srlx(Register src1, int imm5a, Register dst) { - assert imm5a < 0x40; - emitInt(Ops.ArithOp.getValue() | Op3s.Srlx.getValue() | sx1 | rs1(src1.encoding()) | ImmedTrue | imm5a | rd(dst.encoding())); - } - - public final void sub(Register src1, Register src2, Register dst) { - emitInt(Ops.ArithOp.getValue() | Op3s.Sub.getValue() | rs1(src1.encoding()) | rs2(src2.encoding()) | rd(dst.encoding())); + public static class Subcc extends Fmt3b { + public Subcc(SPARCAssembler masm, Register src1, int simm13, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Subcc.getValue(), src1.encoding(), simm13, dst.encoding()); + } + public Subcc(SPARCAssembler masm, Register src1, Register src2, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Subcc.getValue(), src1.encoding(), src2.encoding(), dst.encoding()); + } } - public final void sub(Register src1, int simm13, Register dst) { - emitInt(Ops.ArithOp.getValue() | Op3s.Sub.getValue() | rs1(src1.encoding()) | ImmedTrue | simm(simm13, 13) | rd(dst.encoding())); - } - - public final void subcc(Register src1, Register src2, Register dst) { - emitInt(Ops.ArithOp.getValue() | Op3s.Subcc.getValue() | rs1(src1.encoding()) | rs2(src2.encoding()) | rd(dst.encoding())); + public static class Subccc extends Fmt3b { + public Subccc(SPARCAssembler masm, Register src1, int simm13, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Subccc.getValue(), src1.encoding(), simm13, dst.encoding()); + } + public Subccc(SPARCAssembler masm, Register src1, Register src2, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Subccc.getValue(), src1.encoding(), src2.encoding(), dst.encoding()); + } } - public final void subcc(Register src1, int simm13, Register dst) { - emitInt(Ops.ArithOp.getValue() | Op3s.Subcc.getValue() | rs1(src1.encoding()) | ImmedTrue | simm(simm13, 13) | rd(dst.encoding())); - } - - public final void subc(Register src1, Register src2, Register dst) { - emitInt(Ops.ArithOp.getValue() | Op3s.Subc.getValue() | rs1(src1.encoding()) | rs2(src2.encoding()) | rd(dst.encoding())); - } - - public final void subc(Register src1, int simm13, Register dst) { - emitInt(Ops.ArithOp.getValue() | Op3s.Subc.getValue() | rs1(src1.encoding()) | ImmedTrue | simm(simm13, 13) | rd(dst.encoding())); + public static class Ta extends Fmt4a { + public Ta(SPARCAssembler asm, CC cc, Register src1, int trap) { + super(asm, Ops.ArithOp.getValue(), Op3s.Trap.getValue(), cc.getValue(), + src1.encoding(), trap, ConditionFlag.Always.getValue()); + } + public Ta(SPARCAssembler asm, CC cc, Register src1, Register src2) { + super(asm, Ops.ArithOp.getValue(), Op3s.Trap.getValue(), cc.getValue(), + src1.encoding(), src2.encoding(), ConditionFlag.Always.getValue()); + } } - public final void subccc(Register src1, Register src2, Register dst) { - emitInt(Ops.ArithOp.getValue() | Op3s.Subccc.getValue() | rs1(src1.encoding()) | rs2(src2.encoding()) | rd(dst.encoding())); - } - - public final void subccc(Register src1, int simm13, Register dst) { - emitInt(Ops.ArithOp.getValue() | Op3s.Subccc.getValue() | rs1(src1.encoding()) | ImmedTrue | simm(simm13, 13) | rd(dst.encoding())); - } - - public final void taddcc(Register src1, Register src2, Register dst) { - emitInt(Ops.ArithOp.getValue() | Op3s.Taddcc.getValue() | rs1(src1.encoding()) | rs2(src2.encoding()) | rd(dst.encoding())); - } - - public final void taddcc(Register src1, int simm13, Register dst) { - emitInt(Ops.ArithOp.getValue() | Op3s.Taddcc.getValue() | rs1(src1.encoding()) | ImmedTrue | simm(simm13, 13) | rd(dst.encoding())); + public static class Taddcc extends Fmt3b { + public Taddcc(SPARCAssembler masm, Register src1, int simm13, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Taddcc.getValue(), src1.encoding(), simm13, dst.encoding()); + } + public Taddcc(SPARCAssembler masm, Register src1, Register src2, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Taddcc.getValue(), src1.encoding(), src2.encoding(), dst.encoding()); + } } - public final void taddcctv(Register src1, Register src2, Register dst) { - emitInt(Ops.ArithOp.getValue() | Op3s.Taddcctv.getValue() | rs1(src1.encoding()) | rs2(src2.encoding()) | rd(dst.encoding())); - } - - public final void taddcctv(Register src1, int simm13, Register dst) { - emitInt(Ops.ArithOp.getValue() | Op3s.Taddcctv.getValue() | rs1(src1.encoding()) | ImmedTrue | simm(simm13, 13) | rd(dst.encoding())); + @Deprecated + public static class Taddcctv extends Fmt3b { + @Deprecated + public Taddcctv(SPARCAssembler masm, Register src1, int simm13, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Taddcctv.getValue(), src1.encoding(), simm13, dst.encoding()); + } + @Deprecated + public Taddcctv(SPARCAssembler masm, Register src1, Register src2, Register dst) { + super(masm, Ops.ArithOp.getValue(), dst.encoding(), Op3s.Taddcctv.getValue(), src2.encoding(), src1.encoding()); + } } - public final void tsubcc(Register src1, Register src2, Register dst) { - emitInt(Ops.ArithOp.getValue() | Op3s.Tsubcc.getValue() | rs1(src1.encoding()) | rs2(src2.encoding()) | rd(dst.encoding())); - } - - public final void tsubcc(Register src1, int simm13, Register dst) { - emitInt(Ops.ArithOp.getValue() | Op3s.Tsubcc.getValue() | rs1(src1.encoding()) | ImmedTrue | simm(simm13, 13) | rd(dst.encoding())); - } - - public final void tsubcctv(Register src1, Register src2, Register dst) { - emitInt(Ops.ArithOp.getValue() | Op3s.Tsubcctv.getValue() | rs1(src1.encoding()) | rs2(src2.encoding()) | rd(dst.encoding())); - } - - public final void tsubcctv(Register src1, int simm13, Register dst) { - emitInt(Ops.ArithOp.getValue() | Op3s.Tsubcctv.getValue() | rs1(src1.encoding()) | ImmedTrue | simm(simm13, 13) | rd(dst.encoding())); + public static class Tsubcc extends Fmt3b { + public Tsubcc(SPARCAssembler masm, Register src1, int simm13, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Tsubcc.getValue(), src1.encoding(), simm13, dst.encoding()); + } + public Tsubcc(SPARCAssembler masm, Register src1, Register src2, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Tsubcc.getValue(), src1.encoding(), src2.encoding(), dst.encoding()); + } } @Deprecated - public final void udiv(Register src1, Register src2, Register dst) { - emitInt(Ops.ArithOp.getValue() | Op3s.Udiv.getValue() | rs1(src1.encoding()) | rs2(src2.encoding()) | rd(dst.encoding())); + public static class Tsubcctv extends Fmt3b { + @Deprecated + public Tsubcctv(SPARCAssembler masm, Register src1, int simm13, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Tsubcctv.getValue(), src1.encoding(), simm13, dst.encoding()); + } + @Deprecated + public Tsubcctv(SPARCAssembler masm, Register src1, Register src2, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Tsubcctv.getValue(), src1.encoding(), src2.encoding(), dst.encoding()); + } } @Deprecated - public final void udiv(Register src1, int simm13, Register dst) { - emitInt(Ops.ArithOp.getValue() | Op3s.Udiv.getValue() | rs1(src1.encoding()) | ImmedTrue | simm(simm13, 13) | rd(dst.encoding())); + public static class Udiv extends Fmt3b { + @Deprecated + public Udiv(SPARCAssembler masm, Register src1, int simm13, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Udiv.getValue(), src1.encoding(), simm13, dst.encoding()); + } + @Deprecated + public Udiv(SPARCAssembler masm, Register src1, Register src2, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Udiv.getValue(), src1.encoding(), src2.encoding(), dst.encoding()); + } + } + + public static class Udivcc extends Fmt3b { + public Udivcc(SPARCAssembler masm, Register src1, int simm13, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Udivcc.getValue(), src1.encoding(), simm13, dst.encoding()); + } + public Udivcc(SPARCAssembler masm, Register src1, Register src2, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Udivcc.getValue(), src1.encoding(), src2.encoding(), dst.encoding()); + } } - @Deprecated - public final void udivcc(Register src1, Register src2, Register dst) { - emitInt(Ops.ArithOp.getValue() | Op3s.Udivcc.getValue() | rs1(src1.encoding()) | rs2(src2.encoding()) | rd(dst.encoding())); + public static class Udivx extends Fmt3b { + public Udivx(SPARCAssembler masm, Register src1, int simm13, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Udivx.getValue(), src1.encoding(), simm13, dst.encoding()); + } + public Udivx(SPARCAssembler masm, Register src1, Register src2, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Udivx.getValue(), dst.encoding(), src2.encoding(), src1.encoding()); + } + } + + public static class Umul extends Fmt3b { + public Umul(SPARCAssembler masm, Register src1, int simm13, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Umul.getValue(), src1.encoding(), simm13, dst.encoding()); + } + public Umul(SPARCAssembler masm, Register src1, Register src2, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Umul.getValue(), src1.encoding(), src2.encoding(), dst.encoding()); + } + } + + public static class Umulcc extends Fmt3b { + public Umulcc(SPARCAssembler masm, Register src1, int simm13, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Umulcc.getValue(), src1.encoding(), simm13, dst.encoding()); + } + public Umulcc(SPARCAssembler masm, Register src1, Register src2, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Umulcc.getValue(), src1.encoding(), src2.encoding(), dst.encoding()); + } } @Deprecated - public final void udivcc(Register src1, int simm13, Register dst) { - emitInt(Ops.ArithOp.getValue() | Op3s.Udivcc.getValue() | rs1(src1.encoding()) | ImmedTrue | simm(simm13, 13) | rd(dst.encoding())); - } - - public final void udivx(Register src1, Register src2, Register dst) { - emitInt(Ops.ArithOp.getValue() | Op3s.Udivx.getValue() | rs1(src1.encoding()) | rs2(src2.encoding()) | rd(dst.encoding())); - } - - public final void udivx(Register src1, int simm13, Register dst) { - emitInt(Ops.ArithOp.getValue() | Op3s.Udivx.getValue() | rs1(src1.encoding()) | ImmedTrue | simm(simm13, 13) | rd(dst.encoding())); + public static class Wry extends Fmt3b { + @Deprecated + public Wry(SPARCAssembler masm, int simm13, Register src2) { + super(masm, Ops.ArithOp.getValue(), Op3s.Wrreg.getValue(), 0, src2.encoding(), simm13); + } + @Deprecated + public Wry(SPARCAssembler masm, Register src1, Register src2) { + super(masm, Ops.ArithOp.getValue(), Op3s.Wrreg.getValue(), 0, src2.encoding(), src1.encoding()); + } } - public final void umul(Register src1, Register src2, Register dst) { - emitInt(Ops.ArithOp.getValue() | Op3s.Umul.getValue() | rs1(src1.encoding()) | rs2(src2.encoding()) | rd(dst.encoding())); + public static class Wrccr extends Fmt3b { + public Wrccr(SPARCAssembler masm, int simm13, Register src2) { + super(masm, Ops.ArithOp.getValue(), Op3s.Wrreg.getValue(), 2, src2.encoding(), simm13); + } + public Wrccr(SPARCAssembler masm, Register src1, Register src2) { + super(masm, Ops.ArithOp.getValue(), Op3s.Wrreg.getValue(), 2, src2.encoding(), src1.encoding()); + } } - public final void umul(Register src1, int simm13, Register dst) { - emitInt(Ops.ArithOp.getValue() | Op3s.Umul.getValue() | rs1(src1.encoding()) | ImmedTrue | simm(simm13, 13) | rd(dst.encoding())); - } - - public final void umulcc(Register src1, Register src2, Register dst) { - emitInt(Ops.ArithOp.getValue() | Op3s.Umulcc.getValue() | rs1(src1.encoding()) | rs2(src2.encoding()) | rd(dst.encoding())); - } - - public final void umulcc(Register src1, int simm13, Register dst) { - emitInt(Ops.ArithOp.getValue() | Op3s.Umulcc.getValue() | rs1(src1.encoding()) | ImmedTrue | simm(simm13, 13) | rd(dst.encoding())); + public static class Wrasi extends Fmt3b { + public Wrasi(SPARCAssembler masm, int simm13, Register src2) { + super(masm, Ops.ArithOp.getValue(), Op3s.Wrreg.getValue(), 3, src2.encoding(), simm13); + } + public Wrasi(SPARCAssembler masm, Register src1, Register src2) { + super(masm, Ops.ArithOp.getValue(), Op3s.Wrreg.getValue(), 3, src2.encoding(), src1.encoding()); + } } - public final void xor(Register src1, Register src2, Register dst) { - emitInt(Ops.ArithOp.getValue() | Op3s.Xor.getValue() | rs1(src1.encoding()) | rs2(src2.encoding()) | rd(dst.encoding())); + public static class Wrfprs extends Fmt3b { + public Wrfprs(SPARCAssembler masm, int simm13, Register src2) { + super(masm, Ops.ArithOp.getValue(), Op3s.Wrreg.getValue(), 6, src2.encoding(), simm13); + } + public Wrfprs(SPARCAssembler masm, Register src1, Register src2) { + super(masm, Ops.ArithOp.getValue(), Op3s.Wrreg.getValue(), 6, src2.encoding(), src1.encoding()); + } } - public final void xor(Register src1, int simm13, Register dst) { - emitInt(Ops.ArithOp.getValue() | Op3s.Xor.getValue() | rs1(src1.encoding()) | ImmedTrue | simm(simm13, 13) | rd(dst.encoding())); - } - - public final void xorcc(Register src1, Register src2, Register dst) { - emitInt(Ops.ArithOp.getValue() | Op3s.Xorcc.getValue() | rs1(src1.encoding()) | rs2(src2.encoding()) | rd(dst.encoding())); - } - - public final void xorcc(Register src1, int simm13, Register dst) { - emitInt(Ops.ArithOp.getValue() | Op3s.Xorcc.getValue() | rs1(src1.encoding()) | ImmedTrue | simm(simm13, 13) | rd(dst.encoding())); + public static class Xor extends Fmt3b { + public Xor(SPARCAssembler masm, Register src1, int simm13, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Xor.getValue(), src1.encoding(), simm13, dst.encoding()); + } + public Xor(SPARCAssembler masm, Register src1, Register src2, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Xor.getValue(), src1.encoding(), src2.encoding(), dst.encoding()); + } } - public final void xnor(Register src1, Register src2, Register dst) { - emitInt(Ops.ArithOp.getValue() | Op3s.Xnor.getValue() | rs1(src1.encoding()) | rs2(src2.encoding()) | rd(dst.encoding())); - } - - public final void xnor(Register src1, int simm13, Register dst) { - emitInt(Ops.ArithOp.getValue() | Op3s.Xnor.getValue() | rs1(src1.encoding()) | ImmedTrue | simm(simm13, 13) | rd(dst.encoding())); + public static class Xorcc extends Fmt3b { + public Xorcc(SPARCAssembler masm, Register src1, int simm13, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Xorcc.getValue(), src1.encoding(), simm13, dst.encoding()); + } + public Xorcc(SPARCAssembler masm, Register src1, Register src2, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Xorcc.getValue(), src1.encoding(), src2.encoding(), dst.encoding()); + } } - public final void xnorcc(Register src1, Register src2, Register dst) { - emitInt(Ops.ArithOp.getValue() | Op3s.Xnorcc.getValue() | rs1(src1.encoding()) | rs2(src2.encoding()) | rd(dst.encoding())); + public static class Xnor extends Fmt3b { + public Xnor(SPARCAssembler masm, Register src1, int simm13, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Xnor.getValue(), src1.encoding(), simm13, dst.encoding()); + } + public Xnor(SPARCAssembler masm, Register src1, Register src2, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Xnor.getValue(), src1.encoding(), src2.encoding(), dst.encoding()); + } } - public final void xnorcc(Register src1, int simm13, Register dst) { - emitInt(Ops.ArithOp.getValue() | Op3s.Xnorcc.getValue() | rs1(src1.encoding()) | ImmedTrue | simm(simm13, 13) | rd(dst.encoding())); + public static class Xnorcc extends Fmt3b { + public Xnorcc(SPARCAssembler masm, Register src1, int simm13, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Xnorcc.getValue(), src1.encoding(), simm13, dst.encoding()); + } + public Xnorcc(SPARCAssembler masm, Register src1, Register src2, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Xnorcc.getValue(), src1.encoding(), src2.encoding(), dst.encoding()); + } } - } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCMacroAssembler.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCMacroAssembler.java Fri Jun 07 14:15:38 2013 +0200 @@ -0,0 +1,330 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.asm.sparc; + +import static com.oracle.graal.asm.sparc.SPARCAssembler.CC.*; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.sparc.*; + +public class SPARCMacroAssembler extends SPARCAssembler { + + public SPARCMacroAssembler(TargetDescription target, RegisterConfig registerConfig) { + super(target, registerConfig); + } + + @SuppressWarnings("unused") + public static class Bclr { + + public Bclr(SPARCAssembler asm, Register src, Register dst) { + new Andn(asm, dst, src, dst); + } + + public Bclr(SPARCAssembler asm, int simm13, Register dst) { + new Andn(asm, dst, simm13, dst); + } + } + + @SuppressWarnings("unused") + public static class Bset { + + public Bset(SPARCAssembler asm, Register src, Register dst) { + new Or(asm, dst, src, dst); + } + + public Bset(SPARCAssembler asm, int simm13, Register dst) { + new Or(asm, dst, simm13, dst); + } + } + + @SuppressWarnings("unused") + public static class Btog { + + public Btog(SPARCAssembler asm, Register src, Register dst) { + new Xor(asm, dst, src, dst); + } + + public Btog(SPARCAssembler asm, int simm13, Register dst) { + new Xor(asm, dst, simm13, dst); + } + } + + @SuppressWarnings("unused") + public static class Btst { + + public Btst(SPARCAssembler asm, Register src1, Register src2) { + new Andcc(asm, src1, src2, SPARC.g0); + } + + public Btst(SPARCAssembler asm, Register src1, int simm13) { + new Andcc(asm, src1, simm13, SPARC.g0); + } + } + + @SuppressWarnings("unused") + public static class Clr { + + public Clr(SPARCAssembler asm, Register dst) { + new Or(asm, SPARC.g0, SPARC.g0, dst); + } + + public Clr(SPARCAssembler asm, SPARCAddress addr) { + new Stw(asm, SPARC.g0, addr); + } + } + + @SuppressWarnings("unused") + public static class Clrb { + + public Clrb(SPARCAssembler asm, SPARCAddress addr) { + new Stb(asm, SPARC.g0, addr); + } + } + + @SuppressWarnings("unused") + public static class Clrh { + + public Clrh(SPARCAssembler asm, SPARCAddress addr) { + new Sth(asm, SPARC.g0, addr); + } + } + + @SuppressWarnings("unused") + public static class Clrx { + + public Clrx(SPARCAssembler asm, SPARCAddress addr) { + new Stx(asm, SPARC.g0, addr); + } + } + + @SuppressWarnings("unused") + public static class Clruw { + + public Clruw(SPARCAssembler asm, Register src1, Register dst) { + assert src1.encoding() != dst.encoding(); + new Srl(asm, src1, SPARC.g0, dst); + } + + public Clruw(SPARCAssembler asm, Register dst) { + new Srl(asm, dst, SPARC.g0, dst); + } + } + + @SuppressWarnings("unused") + public static class Cmp { + + public Cmp(SPARCAssembler asm, Register a, Register b) { + new Subcc(asm, a, b, SPARC.g0); + } + + public Cmp(SPARCAssembler asm, Register a, int simm13) { + new Subcc(asm, a, simm13, SPARC.g0); + } + } + + @SuppressWarnings("unused") + public static class Dec { + + public Dec(SPARCAssembler asm, Register dst) { + new Sub(asm, dst, 1, dst); + } + + public Dec(SPARCAssembler asm, int simm13, Register dst) { + new Sub(asm, dst, simm13, dst); + } + } + + @SuppressWarnings("unused") + public static class Deccc { + + public Deccc(SPARCAssembler asm, Register dst) { + new Subcc(asm, dst, 1, dst); + } + + public Deccc(SPARCAssembler asm, int simm13, Register dst) { + new Subcc(asm, dst, simm13, dst); + } + } + + @SuppressWarnings("unused") + public static class Inc { + + public Inc(SPARCAssembler asm, Register dst) { + new Add(asm, dst, 1, dst); + } + + public Inc(SPARCAssembler asm, int simm13, Register dst) { + new Add(asm, dst, simm13, dst); + } + } + + @SuppressWarnings("unused") + public static class Inccc { + + public Inccc(SPARCAssembler asm, Register dst) { + new Addcc(asm, dst, 1, dst); + } + + public Inccc(SPARCAssembler asm, int simm13, Register dst) { + new Addcc(asm, dst, simm13, dst); + } + } + + @SuppressWarnings("unused") + public static class Jmp { + + public Jmp(SPARCAssembler asm, SPARCAddress address) { + new Jmpl(asm, address, SPARC.g0); + } + } + + @SuppressWarnings("unused") + public static class Neg { + + public Neg(SPARCAssembler asm, Register src2, Register dst) { + assert src2.encoding() != dst.encoding(); + new Sub(asm, SPARC.g0, src2, dst); + } + + public Neg(SPARCAssembler asm, Register dst) { + new Sub(asm, SPARC.g0, dst, dst); + } + } + + @SuppressWarnings("unused") + public static class Not { + + public Not(SPARCAssembler asm, Register src1, Register dst) { + assert src1.encoding() != dst.encoding(); + new Xnor(asm, src1, SPARC.g0, dst); + } + + public Not(SPARCAssembler asm, Register dst) { + new Xnor(asm, dst, SPARC.g0, dst); + } + } + + @SuppressWarnings("unused") + public static class RestoreWindow { + + public RestoreWindow(SPARCAssembler asm) { + new Restore(asm, SPARC.g0, SPARC.g0, SPARC.g0); + } + } + + @SuppressWarnings("unused") + public static class Ret { + + public Ret(SPARCAssembler asm) { + new Jmpl(asm, new SPARCAddress(SPARC.i0, 8), SPARC.g0); + + } + } + + @SuppressWarnings("unused") + public static class SaveWindow { + + public SaveWindow(SPARCAssembler asm) { + new Save(asm, SPARC.g0, SPARC.g0, SPARC.g0); + } + } + + @SuppressWarnings("unused") + public static class Setuw { + + public Setuw(SPARCAssembler asm, int value, Register dst) { + if (value >= 0 && ((value & 0x3FFF) == 0)) { + new Sethi(asm, hi22(value), dst); + } else if (-4095 <= value && value <= 4096) { + new Or(asm, SPARC.g0, value, dst); + } else { + new Sethi(asm, hi22(value), dst); + new Or(asm, dst, lo10(value), dst); + } + } + } + + @SuppressWarnings("unused") + public static class Setx { + + public Setx(SPARCAssembler asm, long value, Register tmp, Register dst) { + int hi = (int) (value >> 32); + int lo = (int) (value & ~0); + + if (isSimm13(lo) && value == lo) { + new Or(asm, SPARC.g0, lo, dst); + } else if (hi == 0) { + new Sethi(asm, lo, dst); // hardware version zero-extends to upper 32 + if (lo10(lo) != 0) { + new Or(asm, dst, lo10(lo), dst); + } + } else if (hi == -1) { + new Sethi(asm, ~lo, dst); // hardware version zero-extends to upper 32 + new Xor(asm, dst, lo10(lo) ^ ~lo10(~0), dst); + } else if (lo == 0) { + if (isSimm13(hi)) { + new Or(asm, SPARC.g0, hi, dst); + } else { + new Sethi(asm, hi, dst); // hardware version zero-extends to upper 32 + if (lo10(hi) != 0) { + new Or(asm, dst, lo10(hi), dst); + } + } + new Sllx(asm, dst, 32, dst); + } else { + new Sethi(asm, hi, tmp); + new Sethi(asm, lo, dst); // macro assembler version sign-extends + if (lo10(hi) != 0) { + new Or(asm, tmp, lo10(hi), tmp); + } + if (lo10(lo) != 0) { + new Or(asm, dst, lo10(lo), dst); + } + new Sllx(asm, tmp, 32, tmp); + new Or(asm, dst, tmp, dst); + } + } + } + + @SuppressWarnings("unused") + public static class Signx { + + public Signx(SPARCAssembler asm, Register src1, Register dst) { + assert src1.encoding() != dst.encoding(); + new Sra(asm, src1, SPARC.g0, dst); + } + + public Signx(SPARCAssembler asm, Register dst) { + new Sra(asm, dst, SPARC.g0, dst); + } + } + + @SuppressWarnings("unused") + public static class Trap { + + public Trap(SPARCAssembler asm, int trap) { + assert trap >= 0 && trap <= 0x7f; + new Ta(asm, Icc, SPARC.g0, trap); + } + } +} diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java --- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java Fri Jun 07 14:15:38 2013 +0200 @@ -59,18 +59,13 @@ import com.oracle.graal.lir.amd64.AMD64ControlFlow.SequentialSwitchOp; import com.oracle.graal.lir.amd64.AMD64ControlFlow.SwitchRangesOp; import com.oracle.graal.lir.amd64.AMD64ControlFlow.TableSwitchOp; -import com.oracle.graal.lir.amd64.AMD64Move.CompareAndSwapOp; import com.oracle.graal.lir.amd64.AMD64Move.LeaOp; -import com.oracle.graal.lir.amd64.AMD64Move.LoadOp; import com.oracle.graal.lir.amd64.AMD64Move.MembarOp; import com.oracle.graal.lir.amd64.AMD64Move.MoveFromRegOp; import com.oracle.graal.lir.amd64.AMD64Move.MoveToRegOp; import com.oracle.graal.lir.amd64.AMD64Move.StackLeaOp; -import com.oracle.graal.lir.amd64.AMD64Move.StoreConstantOp; -import com.oracle.graal.lir.amd64.AMD64Move.StoreOp; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; -import com.oracle.graal.nodes.java.*; import com.oracle.graal.phases.util.*; /** @@ -215,31 +210,6 @@ } @Override - public Variable emitLoad(Kind kind, Value address, DeoptimizingNode deopting) { - AMD64AddressValue loadAddress = asAddressValue(address); - Variable result = newVariable(kind); - append(new LoadOp(kind, result, loadAddress, deopting != null ? state(deopting) : null)); - return result; - } - - @Override - public void emitStore(Kind kind, Value address, Value inputVal, DeoptimizingNode deopting) { - AMD64AddressValue storeAddress = asAddressValue(address); - LIRFrameState state = deopting != null ? state(deopting) : null; - - if (isConstant(inputVal)) { - Constant c = asConstant(inputVal); - if (canStoreConstant(c)) { - append(new StoreConstantOp(kind, storeAddress, c, state)); - return; - } - } - - Variable input = load(inputVal); - append(new StoreOp(kind, storeAddress, input, state)); - } - - @Override public Variable emitAddress(StackSlot address) { Variable result = newVariable(target().wordKind); append(new StackLeaOp(result, address)); @@ -882,34 +852,6 @@ } @Override - public void visitCompareAndSwap(CompareAndSwapNode node) { - Kind kind = node.newValue().kind(); - assert kind == node.expected().kind(); - - Value expected = loadNonConst(operand(node.expected())); - Variable newValue = load(operand(node.newValue())); - - AMD64AddressValue address; - int displacement = node.displacement(); - Value index = operand(node.offset()); - if (isConstant(index) && NumUtil.isInt(asConstant(index).asLong() + displacement)) { - assert !runtime.needsDataPatch(asConstant(index)); - displacement += (int) asConstant(index).asLong(); - address = new AMD64AddressValue(kind, load(operand(node.object())), displacement); - } else { - address = new AMD64AddressValue(kind, load(operand(node.object())), load(index), Scale.Times1, displacement); - } - - RegisterValue rax = AMD64.rax.asValue(kind); - emitMove(rax, expected); - append(new CompareAndSwapOp(rax, address, rax, newValue)); - - Variable result = newVariable(node.kind()); - append(new CondMoveOp(result, Condition.EQ, load(Constant.TRUE), Constant.FALSE)); - setResult(node, result); - } - - @Override public void visitBreakpointNode(BreakpointNode node) { JavaType[] sig = new JavaType[node.arguments().size()]; for (int i = 0; i < sig.length; i++) { diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.compiler.sparc.test/src/com/oracle/graal/compiler/sparc/test/ArraySPARCTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.sparc.test/src/com/oracle/graal/compiler/sparc/test/ArraySPARCTest.java Fri Jun 07 14:15:38 2013 +0200 @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.compiler.sparc.test; + +import java.lang.reflect.*; + +import org.junit.*; + +public class ArraySPARCTest extends SPARCTestBase { + + @Test + public void testArray() { + compile("testArray1I"); + compile("testArray1J"); + compile("testArray1B"); + compile("testArray1S"); + compile("testArray1C"); + compile("testArray1F"); + compile("testArray1D"); + compile("testArray1L"); + compile("testStoreArray1I"); + compile("testStoreArray1J"); + compile("testStoreArray1B"); + compile("testStoreArray1S"); + compile("testStoreArray1F"); + compile("testStoreArray1D"); + } + + public static int testArray1I(int[] array, int i) { + return array[i]; + } + + public static long testArray1J(long[] array, int i) { + return array[i]; + } + + public static byte testArray1B(byte[] array, int i) { + return array[i]; + } + + public static short testArray1S(short[] array, int i) { + return array[i]; + } + + public static char testArray1C(char[] array, int i) { + return array[i]; + } + + public static float testArray1F(float[] array, int i) { + return array[i]; + } + + public static double testArray1D(double[] array, int i) { + return array[i]; + } + + public static Object testArray1L(Object[] array, int i) { + return array[i]; + } + + public static void testStoreArray1I(int[] array, int i, int val) { + array[i] = val; + } + + public static void testStoreArray1B(byte[] array, int i, byte val) { + array[i] = val; + } + + public static void testStoreArray1S(short[] array, int i, short val) { + array[i] = val; + } + + public static void testStoreArray1J(long[] array, int i, long val) { + array[i] = val; + } + + public static void testStoreArray1F(float[] array, int i, float val) { + array[i] = val; + } + + public static void testStoreArray1D(double[] array, int i, double val) { + array[i] = val; + } + + public static void main(String[] args) { + ArraySPARCTest test = new ArraySPARCTest(); + for (Method m : ArraySPARCTest.class.getMethods()) { + String name = m.getName(); + if (m.getAnnotation(Test.class) == null && name.startsWith("test")) { + // CheckStyle: stop system..print check + System.out.println(name + ": \n" + new String(test.compile(name).getTargetCode())); + // CheckStyle: resume system..print check + } + } + } +} diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.compiler.sparc.test/src/com/oracle/graal/compiler/sparc/test/BasicSPARCTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.sparc.test/src/com/oracle/graal/compiler/sparc/test/BasicSPARCTest.java Fri Jun 07 14:15:38 2013 +0200 @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.compiler.sparc.test; + +import java.lang.reflect.Method; + +import org.junit.Test; + + +public class BasicSPARCTest extends SPARCTestBase { + + @Test + public void testAdd() { + compile("testAddConst1I"); + } + + public int testAddConst1I(int a) { + return a + 1; + } + + public static void main(String[] args) { + BasicSPARCTest test = new BasicSPARCTest(); + Method[] methods = BasicSPARCTest.class.getMethods(); + for (Method m : methods) { + String name = m.getName(); + if (m.getAnnotation(Test.class) == null && name.startsWith("test")) { + // CheckStyle: stop system..print check + System.out.println(name + ": \n" + new String(test.compile(name).getTargetCode())); + // CheckStyle: resume system..print check + } + } + } +} diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.compiler.sparc.test/src/com/oracle/graal/compiler/sparc/test/ControlSPARCTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.sparc.test/src/com/oracle/graal/compiler/sparc/test/ControlSPARCTest.java Fri Jun 07 14:15:38 2013 +0200 @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.compiler.sparc.test; + +import org.junit.Test; + +import java.lang.reflect.Method; + +public class ControlSPARCTest extends SPARCTestBase { + + @Test + public void testControl() { + compile("testSwitch1I"); + // compile("testStatic"); + compile("testCall"); + compile("testLookupSwitch1I"); + } + + public static int testSwitch1I(int a) { + switch (a) { + case 1: + return 2; + case 2: + return 3; + default: + return 4; + } + } + + public static int testLookupSwitch1I(int a) { + switch (a) { + case 0: + return 1; + case 1: + return 2; + case 2: + return 3; + case 3: + return 1; + case 4: + return 2; + case 5: + return 3; + case 6: + return 1; + case 7: + return 2; + case 8: + return 3; + case 9: + return 1; + case 10: + return 2; + case 11: + return 3; + default: + return -1; + } + } + + @SuppressWarnings("unused") private static Object foo = null; + + public static boolean testStatic(Object o) { + foo = o; + return true; + } + + private static int method(int a, int b) { + return a + b; + } + + public static int testCall(@SuppressWarnings("unused") Object o, int a, int b) { + return method(a, b); + } + + public static void main(String[] args) { + ControlSPARCTest test = new ControlSPARCTest(); + for (Method m : ControlSPARCTest.class.getMethods()) { + String name = m.getName(); + if (m.getAnnotation(Test.class) == null && name.startsWith("test")) { + // CheckStyle: stop system..print check + System.out.println(name + ": \n" + new String(test.compile(name).getTargetCode())); + // CheckStyle: resume system..print check + } + } + } +} diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.compiler.sparc.test/src/com/oracle/graal/compiler/sparc/test/FloatSPARCTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.sparc.test/src/com/oracle/graal/compiler/sparc/test/FloatSPARCTest.java Fri Jun 07 14:15:38 2013 +0200 @@ -0,0 +1,241 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.compiler.sparc.test; + +import java.lang.reflect.Method; + +import org.junit.Test; + +public class FloatSPARCTest extends SPARCTestBase { + + @Test + public void testAdd() { + compile("testAdd2F"); + compile("testAdd2D"); + // compile("testAddFConst"); + // compile("testAddConstF"); + // compile("testAddDConst"); + // compile("testAddConstD"); + } + + public static float testAdd2F(float a, float b) { + return a + b; + } + + public static double testAdd2D(double a, double b) { + return a + b; + } + + public static float testAddFConst(float a) { + return a + 32.0F; + } + + public static float testAddConstF(float a) { + return 32.0F + a; + } + + public static double testAddDConst(double a) { + return a + 32.0; + } + + public static double testAddConstD(double a) { + return 32.0 + a; + } + + @Test + public void testSub() { + compile("testSub2F"); + compile("testSub2D"); + // compile("testSubFConst"); + // compile("testSubConstF"); + // compile("testSubDConst"); + // compile("testSubConstD"); + } + + public static float testSub2F(float a, float b) { + return a - b; + } + + public static double testSub2D(double a, double b) { + return a - b; + } + + public static float testSubFConst(float a) { + return a - 32.0F; + } + + public static float testSubConstF(float a) { + return 32.0F - a; + } + + public static double testSubDConst(double a) { + return a - 32.0; + } + + public static double testSubConstD(double a) { + return 32.0 - a; + } + + @Test + public void testMul() { + compile("testMul2F"); + compile("testMul2D"); + // compile("testMulFConst"); + // compile("testMulConstF"); + // compile("testMulDConst"); + // compile("testMulConstD"); + } + + public static float testMul2F(float a, float b) { + return a * b; + } + + public static double testMul2D(double a, double b) { + return a * b; + } + + public static float testMulFConst(float a) { + return a * 32.0F; + } + + public static float testMulConstF(float a) { + return 32.0F * a; + } + + public static double testMulDConst(double a) { + return a * 32.0; + } + + public static double testMulConstD(double a) { + return 32.0 * a; + } + + @Test + public void testDiv() { + compile("testDiv2F"); + compile("testDiv2D"); + // compile("testDivFConst"); + // compile("testDivConstF"); + // compile("testDivDConst"); + // compile("testDivConstD"); + } + + public static float testDiv2F(float a, float b) { + return a / b; + } + + public static double testDiv2D(double a, double b) { + return a / b; + } + + public static float testDivFConst(float a) { + return a / 32.0F; + } + + public static float testDivConstF(float a) { + return 32.0F / a; + } + + public static double testDivDConst(double a) { + return a / 32.0; + } + + public static double testDivConstD(double a) { + return 32.0 / a; + } + + @Test + public void testNeg() { + compile("testNeg2F"); + compile("testNeg2D"); + } + + public static float testNeg2F(float a) { + return -a; + } + + public static double testNeg2D(double a) { + return -a; + } + + @Test + public void testRem() { + // need linkage to PTX remainder() + // compile("testRem2F"); + // compile("testRem2D"); + } + + public static float testRem2F(float a, float b) { + return a % b; + } + + public static double testRem2D(double a, double b) { + return a % b; + } + + @Test + public void testFloatConversion() { + // compile("testF2I"); + // compile("testF2L"); + // compile("testF2D"); + // compile("testD2I"); + // compile("testD2L"); + // compile("testD2F"); + } + + public static int testF2I(float a) { + return (int) a; + } + + public static long testF2L(float a) { + return (long) a; + } + + public static double testF2D(float a) { + return a; + } + + public static int testD2I(double a) { + return (int) a; + } + + public static long testD2L(double a) { + return (long) a; + } + + public static float testD2F(double a) { + return (float) a; + } + + public static void main(String[] args) { + FloatSPARCTest test = new FloatSPARCTest(); + for (Method m : FloatSPARCTest.class.getMethods()) { + String name = m.getName(); + if (m.getAnnotation(Test.class) == null && name.startsWith("test") && name.startsWith("testRem") == false) { + // CheckStyle: stop system..print check + System.out.println(name + ": \n" + new String(test.compile(name).getTargetCode())); + // CheckStyle: resume system..print check + } + } + } +} diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.compiler.sparc.test/src/com/oracle/graal/compiler/sparc/test/IntegerSPARCTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.sparc.test/src/com/oracle/graal/compiler/sparc/test/IntegerSPARCTest.java Fri Jun 07 14:15:38 2013 +0200 @@ -0,0 +1,182 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.compiler.sparc.test; + +import org.junit.Ignore; +import org.junit.Test; + +import java.lang.reflect.Method; + +public class IntegerSPARCTest extends SPARCTestBase { + + @Test + public void testAdd() { + compile("testAdd2I"); + compile("testAdd2L"); + compile("testAdd2B"); + compile("testAddIConst"); + compile("testAddConstI"); + } + + public static int testAdd2I(int a, int b) { + return a + b; + } + + public static long testAdd2L(long a, long b) { + return a + b; + } + + public static int testAdd2B(byte a, byte b) { + return a + b; + } + + public static int testAddIConst(int a) { + return a + 32; + } + + public static int testAddConstI(int a) { + return 32 + a; + } + + @Test + public void testSub() { + compile("testSub2I"); + compile("testSub2L"); + compile("testSubIConst"); + compile("testSubConstI"); + } + + public static int testSub2I(int a, int b) { + return a - b; + } + + public static long testSub2L(long a, long b) { + return a - b; + } + + public static int testSubIConst(int a) { + return a - 32; + } + + public static int testSubConstI(int a) { + return 32 - a; + } + + @Test + public void testMul() { + compile("testMul2I"); + compile("testMul2L"); + compile("testMulIConst"); + compile("testMulConstI"); + } + + public static int testMul2I(int a, int b) { + return a * b; + } + + public static long testMul2L(long a, long b) { + return a * b; + } + + public static int testMulIConst(int a) { + return a * 32; + } + + public static int testMulConstI(int a) { + return 32 * a; + } + + @Test + public void testDiv() { + compile("testDiv2I"); + compile("testDiv2L"); + compile("testDivIConst"); + } + + public static int testDiv2I(int a, int b) { + return a / b; + } + + public static long testDiv2L(long a, long b) { + return a / b; + } + + public static int testDivIConst(int a) { + return a / 32; + } + + @Ignore + public void testRem() { + compile("testRem2I"); + compile("testRem2L"); + } + + public static int testRem2I(int a, int b) { + return a % b; + } + + public static long testRem2L(long a, long b) { + return a % b; + } + + @Test + public void testIntConversion() { + compile("testI2L"); + compile("testI2C"); + compile("testI2B"); + compile("testI2F"); + compile("testI2D"); + } + + public static long testI2L(int a) { + return a; + } + + public static char testI2C(int a) { + return (char) a; + } + + public static byte testI2B(int a) { + return (byte) a; + } + + public static float testI2F(int a) { + return a; + } + + public static double testI2D(int a) { + return a; + } + + public static void main(String[] args) { + IntegerSPARCTest test = new IntegerSPARCTest(); + for (Method m : IntegerSPARCTest.class.getMethods()) { + String name = m.getName(); + if (m.getAnnotation(Test.class) == null && name.startsWith("test")) { + // CheckStyle: stop system..print check + System.out.println(name + ": \n" + new String(test.compile(name).getTargetCode())); + // CheckStyle: resume system..print check + } + } + } +} diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.compiler.sparc.test/src/com/oracle/graal/compiler/sparc/test/LogicSPARCTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.sparc.test/src/com/oracle/graal/compiler/sparc/test/LogicSPARCTest.java Fri Jun 07 14:15:38 2013 +0200 @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.compiler.sparc.test; + +import java.lang.reflect.Method; + +import org.junit.Test; + +public class LogicSPARCTest extends SPARCTestBase { + + @Test + public void testAnd() { + compile("testAnd2I"); + compile("testAnd2L"); + } + + public static int testAnd2I(int a, int b) { + return a & b; + } + + public static long testAnd2L(long a, long b) { + return a & b; + } + + @Test + public void testOr() { + compile("testOr2I"); + compile("testOr2L"); + } + + public static int testOr2I(int a, int b) { + return a | b; + } + + public static long testOr2L(long a, long b) { + return a | b; + } + + @Test + public void testXor() { + compile("testXor2I"); + compile("testXor2L"); + } + + public static int testXor2I(int a, int b) { + return a ^ b; + } + + public static long testXor2L(long a, long b) { + return a ^ b; + } + + @Test + public void testNot() { + compile("testNot1I"); + compile("testNot1L"); + } + + public static int testNot1I(int a) { + return ~a; + } + + public static long testNot1L(long a) { + return ~a; + } + + @Test + public void testShiftLeft() { + compile("testShiftLeft2I"); + compile("testShiftLeft2L"); + } + + public static int testShiftLeft2I(int a, int b) { + return a << b; + } + + public static long testShiftLeft2L(long a, int b) { + return a << b; + } + + @Test + public void testShiftRight() { + compile("testShiftRight2I"); + compile("testShiftRight2L"); + compile("testUnsignedShiftRight2I"); + compile("testUnsignedShiftRight2L"); + } + + public static int testShiftRight2I(int a, int b) { + return a >> b; + } + + public static long testShiftRight2L(long a, int b) { + return a >> b; + } + + public static int testUnsignedShiftRight2I(int a, int b) { + return a >>> b; + } + + public static long testUnsignedShiftRight2L(long a, long b) { + return a >>> b; + } + + public static void main(String[] args) { + LogicSPARCTest test = new LogicSPARCTest(); + for (Method m : LogicSPARCTest.class.getMethods()) { + String name = m.getName(); + if (m.getAnnotation(Test.class) == null && name.startsWith("test")) { + // CheckStyle: stop system..print check + System.out.println(name + ": \n" + new String(test.compile(name).getTargetCode())); + // CheckStyle: resume system..print check + } + } + } +} diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.compiler.sparc.test/src/com/oracle/graal/compiler/sparc/test/SPARCTestBase.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.sparc.test/src/com/oracle/graal/compiler/sparc/test/SPARCTestBase.java Fri Jun 07 14:15:38 2013 +0200 @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.compiler.sparc.test; + +import static com.oracle.graal.api.code.CodeUtil.*; +import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.code.CallingConvention.*; +import com.oracle.graal.api.runtime.Graal; +import com.oracle.graal.compiler.GraalCompiler; +import com.oracle.graal.compiler.sparc.SPARCBackend; +import com.oracle.graal.compiler.test.GraalCompilerTest; +import com.oracle.graal.debug.Debug; +import com.oracle.graal.java.GraphBuilderConfiguration; +import com.oracle.graal.java.GraphBuilderPhase; +import com.oracle.graal.nodes.StructuredGraph; +import com.oracle.graal.nodes.spi.GraalCodeCacheProvider; +import com.oracle.graal.phases.OptimisticOptimizations; +import com.oracle.graal.phases.PhasePlan; +import com.oracle.graal.phases.PhasePlan.PhasePosition; +import com.oracle.graal.sparc.SPARC; + +public abstract class SPARCTestBase extends GraalCompilerTest { + + private StructuredGraph sg; + + protected CompilationResult compile(String test) { + StructuredGraph graph = parse(test); + sg = graph; + Debug.dump(graph, "Graph"); + TargetDescription target = new TargetDescription(new SPARC(), true, 1, 0, true); + SPARCBackend sparcBackend = new SPARCBackend(Graal.getRequiredCapability(GraalCodeCacheProvider.class), target); + PhasePlan phasePlan = new PhasePlan(); + GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(runtime, GraphBuilderConfiguration.getDefault(), OptimisticOptimizations.NONE); + phasePlan.addPhase(PhasePosition.AFTER_PARSING, graphBuilderPhase); + CallingConvention cc = getCallingConvention(runtime, Type.JavaCallee, graph.method(), false); + CompilationResult result = GraalCompiler.compileGraph(graph, cc, graph.method(), runtime, graalRuntime().getReplacements(), + sparcBackend, target, null, phasePlan, OptimisticOptimizations.NONE, + new SpeculationLog()); + return result; + } + + protected StructuredGraph getStructuredGraph() { + return sg; + } + +} + diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCBackend.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCBackend.java Fri Jun 07 14:15:38 2013 +0200 @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.compiler.sparc; + +import com.oracle.graal.api.code.CallingConvention; +import com.oracle.graal.api.code.CodeCacheProvider; +import com.oracle.graal.api.code.CompilationResult; +import com.oracle.graal.api.code.TargetDescription; +import com.oracle.graal.api.meta.ResolvedJavaMethod; +import com.oracle.graal.asm.AbstractAssembler; +import com.oracle.graal.asm.sparc.SPARCAssembler; +import com.oracle.graal.compiler.gen.LIRGenerator; +import com.oracle.graal.compiler.target.Backend; +import com.oracle.graal.lir.FrameMap; +import com.oracle.graal.lir.LIR; +import com.oracle.graal.lir.asm.FrameContext; +import com.oracle.graal.lir.asm.TargetMethodAssembler; +import com.oracle.graal.nodes.StructuredGraph; + +public class SPARCBackend extends Backend { + + public SPARCBackend(CodeCacheProvider runtime, TargetDescription target) { + super(runtime, target); + } + + @Override + public LIRGenerator newLIRGenerator(StructuredGraph graph, FrameMap frameMap, CallingConvention cc, LIR lir) { + return new SPARCLIRGenerator(graph, runtime(), target, frameMap, cc, lir); + } + + @Override + protected AbstractAssembler createAssembler(FrameMap frameMap) { + return new SPARCAssembler(target, frameMap.registerConfig); + } + + class HotSpotFrameContext implements FrameContext { + + @Override + public void enter(TargetMethodAssembler tasm) { + } + + @Override + public void leave(TargetMethodAssembler tasm) { + } + } + @Override + public TargetMethodAssembler newAssembler(LIRGenerator lirGen, CompilationResult compilationResult) { + FrameMap frameMap = lirGen.frameMap; + AbstractAssembler masm = createAssembler(frameMap); + HotSpotFrameContext frameContext = new HotSpotFrameContext(); + TargetMethodAssembler tasm = new TargetMethodAssembler(target, runtime(), frameMap, masm, frameContext, compilationResult); + tasm.setFrameSize(frameMap.frameSize()); + return tasm; + } + + @Override + public void emitCode(TargetMethodAssembler tasm, LIRGenerator lirGen, ResolvedJavaMethod installedCodeOwner) { + + // Emit code for the LIR + lirGen.lir.emitCode(tasm); + + } + + +} diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java --- a/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java Fri Jun 07 14:15:38 2013 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,355 +23,823 @@ package com.oracle.graal.compiler.sparc; -import com.oracle.graal.api.code.*; +import static com.oracle.graal.api.code.ValueUtil.*; +import static com.oracle.graal.lir.LIRValueUtil.*; +import static com.oracle.graal.lir.sparc.SPARCBitManipulationOp.IntrinsicOpcode.*; +import static com.oracle.graal.lir.sparc.SPARCMathIntrinsicOp.IntrinsicOpcode.*; +import static com.oracle.graal.lir.sparc.SPARCArithmetic.*; +import static com.oracle.graal.lir.sparc.SPARCCompare.*; + +import com.oracle.graal.api.code.CallingConvention; +import com.oracle.graal.api.code.CodeCacheProvider; +import com.oracle.graal.api.code.DeoptimizationAction; +import com.oracle.graal.api.code.ForeignCallLinkage; +import com.oracle.graal.api.code.StackSlot; +import com.oracle.graal.api.code.TargetDescription; import com.oracle.graal.api.meta.*; -import com.oracle.graal.compiler.gen.*; +import com.oracle.graal.asm.NumUtil; +import com.oracle.graal.compiler.gen.LIRGenerator; +import com.oracle.graal.compiler.target.LIRGenLowerable; +import com.oracle.graal.graph.GraalInternalError; import com.oracle.graal.lir.*; -import com.oracle.graal.lir.sparc.*; -import com.oracle.graal.nodes.*; +import com.oracle.graal.lir.StandardOp.*; +import com.oracle.graal.lir.sparc.SPARCAddressValue; +import com.oracle.graal.lir.sparc.SPARCArithmetic.BinaryRegConst; +import com.oracle.graal.lir.sparc.SPARCArithmetic.Op1Stack; +import com.oracle.graal.lir.sparc.SPARCArithmetic.Op2Stack; +import com.oracle.graal.lir.sparc.SPARCArithmetic.Op2Reg; +import com.oracle.graal.lir.sparc.SPARCArithmetic.ShiftOp; +import com.oracle.graal.lir.sparc.SPARCArithmetic.Unary1Op; +import com.oracle.graal.lir.sparc.SPARCArithmetic.Unary2Op; +import com.oracle.graal.lir.sparc.SPARCBitManipulationOp; +import com.oracle.graal.lir.sparc.SPARCBreakpointOp; +import com.oracle.graal.lir.sparc.SPARCByteSwapOp; +import com.oracle.graal.lir.sparc.SPARCCompare.CompareOp; +import com.oracle.graal.lir.sparc.SPARCControlFlow.BranchOp; +import com.oracle.graal.lir.sparc.SPARCControlFlow.CondMoveOp; +import com.oracle.graal.lir.sparc.SPARCControlFlow.FloatCondMoveOp; +import com.oracle.graal.lir.sparc.SPARCControlFlow.ReturnOp; +import com.oracle.graal.lir.sparc.SPARCControlFlow.SequentialSwitchOp; +import com.oracle.graal.lir.sparc.SPARCControlFlow.SwitchRangesOp; +import com.oracle.graal.lir.sparc.SPARCControlFlow.TableSwitchOp; +import com.oracle.graal.lir.sparc.SPARCMathIntrinsicOp; +import com.oracle.graal.lir.sparc.SPARCMove.LoadOp; +import com.oracle.graal.lir.sparc.SPARCMove.MembarOp; +import com.oracle.graal.lir.sparc.SPARCMove.MoveFromRegOp; +import com.oracle.graal.lir.sparc.SPARCMove.MoveToRegOp; +import com.oracle.graal.lir.sparc.SPARCMove.NullCheckOp; +import com.oracle.graal.lir.sparc.SPARCMove.StackLoadAddressOp; +import com.oracle.graal.lir.sparc.SPARCMove.StoreOp; +import com.oracle.graal.lir.sparc.SPARCTestOp; +import com.oracle.graal.nodes.BreakpointNode; +import com.oracle.graal.nodes.DeoptimizingNode; +import com.oracle.graal.nodes.DirectCallTargetNode; +import com.oracle.graal.nodes.IndirectCallTargetNode; +import com.oracle.graal.nodes.InfopointNode; +import com.oracle.graal.nodes.SafepointNode; +import com.oracle.graal.nodes.StructuredGraph; +import com.oracle.graal.nodes.ValueNode; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.calc.ConvertNode.Op; -import com.oracle.graal.nodes.java.*; +import com.oracle.graal.nodes.java.CompareAndSwapNode; /** * This class implements the SPARC specific portion of the LIR generator. */ public class SPARCLIRGenerator extends LIRGenerator { + public static class SPARCSpillMoveFactory implements LIR.SpillMoveFactory { + + @Override + public LIRInstruction createMove(AllocatableValue result, Value input) { + throw new InternalError("NYI"); + } + } + public SPARCLIRGenerator(StructuredGraph graph, CodeCacheProvider runtime, TargetDescription target, FrameMap frameMap, CallingConvention cc, LIR lir) { super(graph, runtime, target, frameMap, cc, lir); - // SPARC: Implement lir generator. + lir.spillMoveFactory = new SPARCSpillMoveFactory(); + } + + @Override + protected void emitNode(ValueNode node) { + if (node instanceof LIRGenLowerable) { + ((LIRGenLowerable) node).generate(this); + } else { + super.emitNode(node); + } } @Override public Variable emitMove(Value input) { - // SPARC: Auto-generated method stub - return null; + Variable result = newVariable(input.getKind()); + emitMove(result, input); + return result; + } + + @Override + public void emitMove(AllocatableValue dst, Value src) { + if (isRegister(src) || isStackSlot(dst)) { + append(new MoveFromRegOp(dst, src)); + } else { + append(new MoveToRegOp(dst, src)); + } } @Override protected boolean peephole(ValueNode valueNode) { - // SPARC: Auto-generated method stub + // No peephole optimizations for now return false; } @Override protected void emitReturn(Value input) { - // SPARC: Auto-generated method stub - + append(new ReturnOp(input)); } @Override public void emitJump(LabelRef label) { - @SuppressWarnings("unused") - SPARCLIRInstruction instruction = null; - // SPARC: Auto-generated method stub - + append(new JumpOp(label)); } @Override public void emitCompareBranch(Value left, Value right, Condition cond, boolean unorderedIsTrue, LabelRef label) { - // SPARC: Auto-generated method stub - + switch (left.getKind().getStackKind()) { + case Int: + append(new CompareOp(ICMP, left, right)); + append(new BranchOp(cond, label)); + break; + case Long: + append(new CompareOp(LCMP, left, right)); + append(new BranchOp(cond, label)); + break; + case Float: + append(new CompareOp(FCMP, left, right)); + append(new BranchOp(cond, label)); + break; + case Double: + append(new CompareOp(DCMP, left, right)); + append(new BranchOp(cond, label)); + break; + case Object: + append(new CompareOp(ACMP, left, right)); + append(new BranchOp(cond, label)); + break; + default: + throw GraalInternalError.shouldNotReachHere("" + left.getKind()); + } } @Override public void emitOverflowCheckBranch(LabelRef label, boolean negated) { - // SPARC: Auto-generated method stub - + // append(new BranchOp(negated ? ConditionFlag.NoOverflow : ConditionFlag.Overflow, label)); + throw GraalInternalError.shouldNotReachHere("emitOverflowCheckBranch: unimp"); } @Override public void emitIntegerTestBranch(Value left, Value right, boolean negated, LabelRef label) { - // SPARC: Auto-generated method stub + emitIntegerTest(left, right); + append(new BranchOp(negated ? Condition.NE : Condition.EQ, label)); + } + + private void emitIntegerTest(Value a, Value b) { + assert a.getKind().getStackKind() == Kind.Int || a.getKind() == Kind.Long; + if (LIRValueUtil.isVariable(b)) { + append(new SPARCTestOp(load(b), loadNonConst(a))); + } else { + append(new SPARCTestOp(load(a), loadNonConst(b))); + } + } + @Override + public Variable load(Value value) { + if (!isVariable(value)) { + return emitMove(value); + } + return (Variable) value; + } + + @Override + public Value loadNonConst(Value value) { + if (isConstant(value) && !canInlineConstant((Constant) value)) { + return emitMove(value); + } + return value; } @Override - public Variable emitConditionalMove(Value leftVal, Value right, Condition cond, boolean unorderedIsTrue, Value trueValue, Value falseValue) { - // SPARC: Auto-generated method stub - return null; + public Variable emitConditionalMove(Value left, Value right, Condition cond, boolean unorderedIsTrue, Value trueValue, Value falseValue) { + boolean mirrored = emitCompare(left, right); + Condition finalCondition = mirrored ? cond.mirror() : cond; + + Variable result = newVariable(trueValue.getKind()); + switch (left.getKind().getStackKind()) { + case Int: + case Long: + case Object: + append(new CondMoveOp(result, finalCondition, load(trueValue), loadNonConst(falseValue))); + break; + case Float: + case Double: + append(new FloatCondMoveOp(result, finalCondition, unorderedIsTrue, load(trueValue), load(falseValue))); + break; + default: + throw GraalInternalError.shouldNotReachHere("" + left.getKind()); + } + return result; + } + + /** + * This method emits the compare instruction, and may reorder the operands. It returns true if + * it did so. + * + * @param a the left operand of the comparison + * @param b the right operand of the comparison + * @return true if the left and right operands were switched, false otherwise + */ + private boolean emitCompare(Value a, Value b) { + Variable left; + Value right; + boolean mirrored; + if (LIRValueUtil.isVariable(b)) { + left = load(b); + right = loadNonConst(a); + mirrored = true; + } else { + left = load(a); + right = loadNonConst(b); + mirrored = false; + } + switch (left.getKind().getStackKind()) { + case Int: + append(new CompareOp(ICMP, left, right)); + break; + case Long: + append(new CompareOp(LCMP, left, right)); + break; + case Object: + append(new CompareOp(ACMP, left, right)); + break; + case Float: + append(new CompareOp(FCMP, left, right)); + break; + case Double: + append(new CompareOp(DCMP, left, right)); + break; + default: + throw GraalInternalError.shouldNotReachHere(); + } + return mirrored; } @Override - public Variable emitIntegerTestMove(Value leftVal, Value right, Value trueValue, Value falseValue) { - // SPARC: Auto-generated method stub - return null; + public Variable emitIntegerTestMove(Value left, Value right, Value trueValue, Value falseValue) { + emitIntegerTest(left, right); + Variable result = newVariable(trueValue.getKind()); + append(new CondMoveOp(result, Condition.EQ, load(trueValue), loadNonConst(falseValue))); + return result; } @Override protected void emitDirectCall(DirectCallTargetNode callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState callState) { - // SPARC: Auto-generated method stub - + throw new InternalError("NYI"); } @Override protected void emitIndirectCall(IndirectCallTargetNode callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState callState) { - // SPARC: Auto-generated method stub - + throw new InternalError("NYI"); } @Override protected void emitForeignCall(ForeignCallLinkage linkage, Value result, Value[] arguments, Value[] temps, LIRFrameState info) { - // SPARC: Auto-generated method stub - + throw new InternalError("NYI"); } @Override protected void emitSequentialSwitch(Constant[] keyConstants, LabelRef[] keyTargets, LabelRef defaultTarget, Value key) { - // SPARC: Auto-generated method stub - + // Making a copy of the switch value is necessary because jump table destroys the input + // value + if (key.getKind() == Kind.Int || key.getKind() == Kind.Long) { + append(new SequentialSwitchOp(keyConstants, keyTargets, defaultTarget, key, Value.ILLEGAL)); + } else { + assert key.getKind() == Kind.Object : key.getKind(); + append(new SequentialSwitchOp(keyConstants, keyTargets, defaultTarget, key, newVariable(Kind.Object))); + } } @Override protected void emitSwitchRanges(int[] lowKeys, int[] highKeys, LabelRef[] targets, LabelRef defaultTarget, Value key) { - // SPARC: Auto-generated method stub - + append(new SwitchRangesOp(lowKeys, highKeys, targets, defaultTarget, key)); } @Override protected void emitTableSwitch(int lowKey, LabelRef defaultTarget, LabelRef[] targets, Value key) { - // SPARC: Auto-generated method stub - + // Making a copy of the switch value is necessary because jump table destroys the input + // value + Variable tmp = emitMove(key); + append(new TableSwitchOp(lowKey, defaultTarget, targets, tmp, newVariable(target.wordKind))); } @Override public void emitBitCount(Variable result, Value operand) { - // SPARC: Auto-generated method stub - + if (operand.getKind().getStackKind() == Kind.Int) { + append(new SPARCBitManipulationOp(IPOPCNT, result, asAllocatable(operand))); + } else { + append(new SPARCBitManipulationOp(LPOPCNT, result, asAllocatable(operand))); + } } @Override public void emitBitScanForward(Variable result, Value operand) { - // SPARC: Auto-generated method stub - + append(new SPARCBitManipulationOp(BSF, result, asAllocatable(operand))); } @Override public void emitBitScanReverse(Variable result, Value operand) { - // SPARC: Auto-generated method stub - + if (operand.getKind().getStackKind() == Kind.Int) { + append(new SPARCBitManipulationOp(IBSR, result, asAllocatable(operand))); + } else { + append(new SPARCBitManipulationOp(LBSR, result, asAllocatable(operand))); + } } @Override public void emitMathAbs(Variable result, Variable input) { - // SPARC: Auto-generated method stub - + append(new BinaryRegConst(DAND, result, input, Constant.forDouble(Double.longBitsToDouble(0x7FFFFFFFFFFFFFFFL)))); } @Override public void emitMathSqrt(Variable result, Variable input) { - // SPARC: Auto-generated method stub - + append(new SPARCMathIntrinsicOp(SQRT, result, input)); } @Override public void emitMathLog(Variable result, Variable input, boolean base10) { - // SPARC: Auto-generated method stub - + append(new SPARCMathIntrinsicOp(LOG, result, input)); } @Override public void emitMathCos(Variable result, Variable input) { - // SPARC: Auto-generated method stub - + append(new SPARCMathIntrinsicOp(COS, result, input)); } @Override public void emitMathSin(Variable result, Variable input) { - // SPARC: Auto-generated method stub - + append(new SPARCMathIntrinsicOp(SIN, result, input)); } @Override public void emitMathTan(Variable result, Variable input) { - // SPARC: Auto-generated method stub - + append(new SPARCMathIntrinsicOp(TAN, result, input)); } @Override - public void emitByteSwap(Variable result, Value operand) { - // SPARC: Auto-generated method stub - + public void emitByteSwap(Variable result, Value input) { + append(new SPARCByteSwapOp(result, input)); } @Override public boolean canInlineConstant(Constant c) { - // SPARC: Auto-generated method stub - return false; + switch (c.getKind()) { + case Long: + return NumUtil.isInt(c.asLong()) && !runtime.needsDataPatch(c); + case Object: + return c.isNull(); + default: + return true; + } } @Override public boolean canStoreConstant(Constant c) { - // SPARC: Auto-generated method stub - return false; - } - - @Override - public void emitMove(AllocatableValue dst, Value src) { - // SPARC: Auto-generated method stub - + throw new InternalError("NYI"); } @Override - public Value emitAddress(Value base, long displacement, Value index, int scale) { - // SPARC: Auto-generated method stub - return null; + public SPARCAddressValue emitAddress(Value base, long displacement, Value index, int scale) { + AllocatableValue baseRegister; + long finalDisp = displacement; + if (isConstant(base)) { + if (asConstant(base).isNull()) { + baseRegister = Value.ILLEGAL; + } else if (asConstant(base).getKind() != Kind.Object) { + finalDisp += asConstant(base).asLong(); + baseRegister = Value.ILLEGAL; + } else { + baseRegister = load(base); + } + } else { + baseRegister = asAllocatable(base); + } + + if (index != Value.ILLEGAL && scale != 0) { + if (isConstant(index)) { + finalDisp += asConstant(index).asLong() * scale; + } else { + Value indexRegister; + if (scale != 1) { + indexRegister = emitMul(index, Constant.forInt(scale)); + } else { + indexRegister = index; + } + + if (baseRegister == Value.ILLEGAL) { + baseRegister = asAllocatable(indexRegister); + } else { + Variable newBase = newVariable(Kind.Int); + emitMove(newBase, baseRegister); + baseRegister = newBase; + baseRegister = emitAdd(baseRegister, indexRegister); + } + } + } + + return new SPARCAddressValue(target().wordKind, baseRegister, (int) finalDisp); + } + + private SPARCAddressValue asAddress(Value address) { + if (address instanceof SPARCAddressValue) { + return (SPARCAddressValue) address; + } else { + return emitAddress(address, 0, Value.ILLEGAL, 0); + } } @Override - public Value emitLoad(Kind kind, Value address, DeoptimizingNode canTrap) { - // SPARC: Auto-generated method stub - return null; + public Variable emitLoad(Kind kind, Value address, DeoptimizingNode deopting) { + SPARCAddressValue loadAddress = asAddress(address); + Variable result = newVariable(kind); + append(new LoadOp(kind, result, loadAddress, deopting != null ? state(deopting) : null)); + return result; } @Override - public void emitStore(Kind kind, Value address, Value input, DeoptimizingNode canTrap) { - // SPARC: Auto-generated method stub - + public void emitStore(Kind kind, Value address, Value inputVal, DeoptimizingNode deopting) { + SPARCAddressValue storeAddress = asAddress(address); + Variable input = load(inputVal); + append(new StoreOp(kind, storeAddress, input, deopting != null ? state(deopting) : null)); } @Override public Value emitAddress(StackSlot address) { - // SPARC: Auto-generated method stub - return null; + Variable result = newVariable(target().wordKind); + append(new StackLoadAddressOp(result, address)); + return result; } @Override public Value emitNegate(Value input) { - // SPARC: Auto-generated method stub - return null; + Variable result = newVariable(input.getKind()); + switch (input.getKind()) { + case Int: + append(new Op1Stack(INEG, result, input)); + break; + case Float: + append(new Op1Stack(FNEG, result, input)); + break; + case Double: + append(new Op1Stack(DNEG, result, input)); + break; + default: + throw GraalInternalError.shouldNotReachHere(); + } + return result; } @Override - public Value emitAdd(Value a, Value b) { - // SPARC: Auto-generated method stub - return null; + public Variable emitAdd(Value a, Value b) { + Variable result = newVariable(a.getKind()); + switch (a.getKind()) { + case Int: + append(new Op2Stack(IADD, result, a, loadNonConst(b))); + break; + case Long: + append(new Op2Stack(LADD, result, a, loadNonConst(b))); + break; + case Float: + append(new Op2Stack(FADD, result, a, loadNonConst(b))); + break; + case Double: + append(new Op2Stack(DADD, result, a, loadNonConst(b))); + break; + default: + throw GraalInternalError.shouldNotReachHere("missing: " + a.getKind() + " prim: " + a.getKind().isPrimitive()); + } + return result; } @Override public Value emitSub(Value a, Value b) { - // SPARC: Auto-generated method stub - return null; + Variable result = newVariable(a.getKind()); + switch (a.getKind()) { + case Int: + append(new Op2Stack(ISUB, result, a, loadNonConst(b))); + break; + case Long: + append(new Op2Stack(LSUB, result, a, loadNonConst(b))); + break; + case Float: + append(new Op2Stack(FSUB, result, a, loadNonConst(b))); + break; + case Double: + append(new Op2Stack(DSUB, result, a, loadNonConst(b))); + break; + default: + throw GraalInternalError.shouldNotReachHere("missing: " + a.getKind()); + } + return result; } @Override public Value emitMul(Value a, Value b) { - // SPARC: Auto-generated method stub - return null; + Variable result = newVariable(a.getKind()); + switch (a.getKind()) { + case Int: + append(new Op2Reg(IMUL, result, a, loadNonConst(b))); + break; + case Long: + append(new Op2Reg(LMUL, result, a, loadNonConst(b))); + break; + case Float: + append(new Op2Stack(FMUL, result, a, loadNonConst(b))); + break; + case Double: + append(new Op2Stack(DMUL, result, a, loadNonConst(b))); + break; + default: + throw GraalInternalError.shouldNotReachHere("missing: " + a.getKind()); + } + return result; } @Override public Value emitDiv(Value a, Value b, DeoptimizingNode deopting) { - // SPARC: Auto-generated method stub - return null; + Variable result = newVariable(a.getKind()); + switch (a.getKind()) { + case Int: + append(new Op2Reg(IDIV, result, a, loadNonConst(b))); + break; + case Long: + append(new Op2Reg(LDIV, result, a, loadNonConst(b))); + break; + case Float: + append(new Op2Stack(FDIV, result, a, loadNonConst(b))); + break; + case Double: + append(new Op2Stack(DDIV, result, a, loadNonConst(b))); + break; + default: + throw GraalInternalError.shouldNotReachHere("missing: " + a.getKind()); + } + return result; } @Override public Value emitRem(Value a, Value b, DeoptimizingNode deopting) { - // SPARC: Auto-generated method stub - return null; + Variable result = newVariable(a.getKind()); + switch (a.getKind()) { + case Int: + append(new Op2Reg(IREM, result, a, loadNonConst(b))); + break; + case Long: + append(new Op2Reg(LREM, result, a, loadNonConst(b))); + break; + default: + throw GraalInternalError.shouldNotReachHere("missing: " + a.getKind()); + } + return result; } @Override public Value emitUDiv(Value a, Value b, DeoptimizingNode deopting) { - // SPARC: Auto-generated method stub - return null; + @SuppressWarnings("unused") + LIRFrameState state = state(deopting); + switch (a.getKind()) { + case Int: + // emitDivRem(IUDIV, a, b, state); + // return emitMove(RAX_I); + case Long: + // emitDivRem(LUDIV, a, b, state); + // return emitMove(RAX_L); + default: + throw GraalInternalError.shouldNotReachHere(); + } } @Override public Value emitURem(Value a, Value b, DeoptimizingNode deopting) { - // SPARC: Auto-generated method stub - return null; + @SuppressWarnings("unused") + LIRFrameState state = state(deopting); + switch (a.getKind()) { + case Int: + // emitDivRem(IUREM, a, b, state); + // return emitMove(RDX_I); + case Long: + // emitDivRem(LUREM, a, b, state); + // return emitMove(RDX_L); + default: + throw GraalInternalError.shouldNotReachHere(); + } } @Override public Value emitAnd(Value a, Value b) { - // SPARC: Auto-generated method stub - return null; + Variable result = newVariable(a.getKind()); + switch (a.getKind()) { + case Int: + append(new Op2Stack(IAND, result, a, loadNonConst(b))); + break; + case Long: + append(new Op2Stack(LAND, result, a, loadNonConst(b))); + break; + + default: + throw GraalInternalError.shouldNotReachHere("missing: " + a.getKind()); + } + return result; } @Override public Value emitOr(Value a, Value b) { - // SPARC: Auto-generated method stub - return null; + Variable result = newVariable(a.getKind()); + switch (a.getKind()) { + case Int: + append(new Op2Stack(IOR, result, a, loadNonConst(b))); + break; + case Long: + append(new Op2Stack(LOR, result, a, loadNonConst(b))); + break; + default: + throw GraalInternalError.shouldNotReachHere("missing: " + a.getKind()); + } + return result; } @Override public Value emitXor(Value a, Value b) { - // SPARC: Auto-generated method stub - return null; + Variable result = newVariable(a.getKind()); + switch (a.getKind()) { + case Int: + append(new Op2Stack(IXOR, result, a, loadNonConst(b))); + break; + case Long: + append(new Op2Stack(LXOR, result, a, loadNonConst(b))); + break; + default: + throw GraalInternalError.shouldNotReachHere(); + } + return result; } @Override public Value emitShl(Value a, Value b) { - // SPARC: Auto-generated method stub - return null; + Variable result = newVariable(a.getKind()); + switch (a.getKind()) { + case Int: + append(new Op2Stack(ISHL, result, a, loadNonConst(b))); + break; + case Long: + append(new Op1Stack(LSHL, result, loadNonConst(b))); + break; + default: + throw GraalInternalError.shouldNotReachHere(); + } + return result; } @Override public Value emitShr(Value a, Value b) { - // SPARC: Auto-generated method stub - return null; + Variable result = newVariable(a.getKind()); + switch (a.getKind()) { + case Int: + append(new Op2Stack(ISHR, result, a, loadNonConst(b))); + break; + case Long: + append(new Op1Stack(LSHR, result, loadNonConst(b))); + break; + default: + throw GraalInternalError.shouldNotReachHere(); + } + return result; } @Override public Value emitUShr(Value a, Value b) { - // SPARC: Auto-generated method stub - return null; + Variable result = newVariable(a.getKind()); + switch (a.getKind()) { + case Int: + append(new ShiftOp(IUSHR, result, a, b)); + break; + case Long: + append(new ShiftOp(LUSHR, result, a, b)); + break; + default: + throw GraalInternalError.shouldNotReachHere(); + } + return result; } @Override public Value emitConvert(Op opcode, Value inputVal) { - // SPARC: Auto-generated method stub - return null; + Variable input = load(inputVal); + Variable result = newVariable(opcode.to); + switch (opcode) { + case I2L: + append(new Unary2Op(I2L, result, input)); + break; + case L2I: + append(new Unary1Op(L2I, result, input)); + break; + case I2B: + append(new Unary2Op(I2B, result, input)); + break; + case I2C: + append(new Unary1Op(I2C, result, input)); + break; + case I2S: + append(new Unary2Op(I2S, result, input)); + break; + case F2D: + append(new Unary2Op(F2D, result, input)); + break; + case D2F: + append(new Unary2Op(D2F, result, input)); + break; + case I2F: + append(new Unary2Op(I2F, result, input)); + break; + case I2D: + append(new Unary2Op(I2D, result, input)); + break; + case F2I: + append(new Unary2Op(F2I, result, input)); + break; + case D2I: + append(new Unary2Op(D2I, result, input)); + break; + case L2F: + append(new Unary2Op(L2F, result, input)); + break; + case L2D: + append(new Unary2Op(L2D, result, input)); + break; + case F2L: + append(new Unary2Op(F2L, result, input)); + break; + case D2L: + append(new Unary2Op(D2L, result, input)); + break; + case MOV_I2F: + append(new Unary2Op(MOV_I2F, result, input)); + break; + case MOV_L2D: + append(new Unary2Op(MOV_L2D, result, input)); + break; + case MOV_F2I: + append(new Unary2Op(MOV_F2I, result, input)); + break; + case MOV_D2L: + append(new Unary2Op(MOV_D2L, result, input)); + break; + case UNSIGNED_I2L: + // Instructions that move or generate 32-bit register values also set the upper 32 + // bits of the register to zero. + // Consequently, there is no need for a special zero-extension move. + emitMove(result, input); + break; + default: + throw GraalInternalError.shouldNotReachHere(); + } + return result; } @Override public void emitMembar(int barriers) { - // SPARC: Auto-generated method stub - + int necessaryBarriers = target.arch.requiredBarriers(barriers); + if (target.isMP && necessaryBarriers != 0) { + append(new MembarOp(necessaryBarriers)); + } } @Override public void emitDeoptimize(DeoptimizationAction action, DeoptimizingNode deopting) { - // SPARC: Auto-generated method stub - + append(new ReturnOp(Value.ILLEGAL)); } @Override public void visitCompareAndSwap(CompareAndSwapNode i) { - // SPARC: Auto-generated method stub - + throw new InternalError("NYI"); } @Override public void visitSafepointNode(SafepointNode i) { - // SPARC: Auto-generated method stub - + throw new InternalError("NYI"); } @Override - public void visitBreakpointNode(BreakpointNode i) { - // SPARC: Auto-generated method stub + public void visitBreakpointNode(BreakpointNode node) { + JavaType[] sig = new JavaType[node.arguments().size()]; + for (int i = 0; i < sig.length; i++) { + sig[i] = node.arguments().get(i).stamp().javaType(runtime); + } + Value[] parameters = visitInvokeArguments(frameMap.registerConfig.getCallingConvention(CallingConvention.Type.JavaCall, null, sig, target(), false), node.arguments()); + append(new SPARCBreakpointOp(parameters)); } @Override public void emitUnwind(Value operand) { - // SPARC: Auto-generated method stub - + throw new InternalError("NYI"); } @Override public void emitNullCheck(ValueNode v, DeoptimizingNode deopting) { - // SPARC: Auto-generated method stub - + assert v.kind() == Kind.Object; + append(new NullCheckOp(load(operand(v)), state(deopting))); } @Override public void visitInfopointNode(InfopointNode i) { - // SPARC: Auto-generated method stub - + throw new InternalError("NYI"); } } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/BoxingEliminationTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/BoxingEliminationTest.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/BoxingEliminationTest.java Fri Jun 07 14:15:38 2013 +0200 @@ -309,7 +309,7 @@ Assumptions assumptions = new Assumptions(false); HighTierContext context = new HighTierContext(runtime(), assumptions, replacements); new InliningPhase(runtime(), null, replacements, assumptions, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL).apply(graph); - new PartialEscapeAnalysisPhase(false, false).apply(graph, context); + new PartialEscapeAnalysisPhase(false, false, new CanonicalizerPhase(true)).apply(graph, context); new CullFrameStatesPhase().apply(graph); } @@ -326,22 +326,23 @@ Assumptions assumptions = new Assumptions(false); HighTierContext context = new HighTierContext(runtime(), assumptions, replacements); + CanonicalizerPhase canonicalizer = new CanonicalizerPhase(true); new InliningPhase(runtime(), null, replacements, assumptions, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL).apply(graph); if (loopPeeling) { new LoopTransformHighPhase().apply(graph); } new DeadCodeEliminationPhase().apply(graph); - new CanonicalizerPhase().apply(graph, context); - new PartialEscapeAnalysisPhase(false, false).apply(graph, context); + canonicalizer.apply(graph, context); + new PartialEscapeAnalysisPhase(false, false, canonicalizer).apply(graph, context); new CullFrameStatesPhase().apply(graph); new DeadCodeEliminationPhase().apply(graph); - new CanonicalizerPhase().apply(graph, context); + canonicalizer.apply(graph, context); StructuredGraph referenceGraph = parse(referenceSnippet); new InliningPhase(runtime(), null, replacements, assumptions, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL).apply(referenceGraph); new DeadCodeEliminationPhase().apply(referenceGraph); - new CanonicalizerPhase().apply(referenceGraph, context); + new CanonicalizerPhase(true).apply(referenceGraph, context); assertEquals(referenceGraph, graph, excludeVirtual); } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/CompareCanonicalizerTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/CompareCanonicalizerTest.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/CompareCanonicalizerTest.java Fri Jun 07 14:15:38 2013 +0200 @@ -35,7 +35,7 @@ private StructuredGraph getCanonicalizedGraph(String name) { StructuredGraph graph = parse(name); - new CanonicalizerPhase.Instance(runtime(), null).apply(graph); + new CanonicalizerPhase.Instance(runtime(), null, true).apply(graph); return graph; } @@ -53,7 +53,7 @@ assertEquals(referenceGraph, graph); } Assumptions assumptions = new Assumptions(false); - new CanonicalizerPhase.Instance(runtime(), assumptions).apply(referenceGraph); + new CanonicalizerPhase.Instance(runtime(), assumptions, true).apply(referenceGraph); for (int i = 1; i < 4; i++) { StructuredGraph graph = getCanonicalizedGraph("canonicalCompare" + i); assertEquals(referenceGraph, graph); diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/DegeneratedLoopsTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/DegeneratedLoopsTest.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/DegeneratedLoopsTest.java Fri Jun 07 14:15:38 2013 +0200 @@ -82,7 +82,7 @@ public void run() { StructuredGraph graph = parse(snippet); new InliningPhase(runtime(), null, replacements, new Assumptions(false), null, getDefaultPhasePlan(), OptimisticOptimizations.ALL).apply(graph); - new CanonicalizerPhase.Instance(runtime(), new Assumptions(false)).apply(graph); + new CanonicalizerPhase.Instance(runtime(), new Assumptions(false), true).apply(graph); Debug.dump(graph, "Graph"); StructuredGraph referenceGraph = parse(REFERENCE_SNIPPET); Debug.dump(referenceGraph, "ReferenceGraph"); diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/EliminateNestedCheckCastsTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/EliminateNestedCheckCastsTest.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/EliminateNestedCheckCastsTest.java Fri Jun 07 14:15:38 2013 +0200 @@ -115,7 +115,7 @@ StructuredGraph graph = parse(snippet); Debug.dump(graph, "After parsing: " + snippet); Assert.assertEquals(checkcasts, graph.getNodes().filter(CheckCastNode.class).count()); - new CanonicalizerPhase.Instance(runtime(), new Assumptions(false)).apply(graph); + new CanonicalizerPhase.Instance(runtime(), new Assumptions(false), true).apply(graph); Assert.assertEquals(afterCanon, graph.getNodes(CheckCastNode.class).count()); return graph; } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FinalizableSubclassTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FinalizableSubclassTest.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FinalizableSubclassTest.java Fri Jun 07 14:15:38 2013 +0200 @@ -68,7 +68,7 @@ GraphBuilderConfiguration conf = GraphBuilderConfiguration.getSnippetDefault(); new GraphBuilderPhase(runtime, conf, OptimisticOptimizations.ALL).apply(graph); new InliningPhase(runtime(), null, replacements, assumptions, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL).apply(graph); - new CanonicalizerPhase.Instance(runtime(), assumptions).apply(graph); + new CanonicalizerPhase.Instance(runtime(), assumptions, true).apply(graph); return graph; } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FloatingReadTest.java diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java Fri Jun 07 14:15:38 2013 +0200 @@ -23,6 +23,7 @@ package com.oracle.graal.compiler.test; import static com.oracle.graal.api.code.CodeUtil.*; +import static com.oracle.graal.phases.GraalOptions.*; import java.lang.reflect.*; import java.util.*; @@ -420,7 +421,7 @@ InstalledCode installedCode = Debug.scope("Compiling", new Object[]{runtime, new DebugDumpScope(String.valueOf(id), true)}, new Callable() { public InstalledCode call() throws Exception { - final boolean printCompilation = GraalOptions.PrintCompilation && !TTY.isSuppressed(); + final boolean printCompilation = PrintCompilation.getValue() && !TTY.isSuppressed(); if (printCompilation) { TTY.println(String.format("@%-6d Graal %-70s %-45s %-50s ...", id, method.getDeclaringClass().getName(), method.getName(), method.getSignature())); } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/IfCanonicalizerTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/IfCanonicalizerTest.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/IfCanonicalizerTest.java Fri Jun 07 14:15:38 2013 +0200 @@ -144,7 +144,7 @@ n.replaceFirstInput(local, constant); } Debug.dump(graph, "Graph"); - new CanonicalizerPhase.Instance(runtime(), new Assumptions(false)).apply(graph); + new CanonicalizerPhase.Instance(runtime(), new Assumptions(false), true).apply(graph); StructuredGraph referenceGraph = parse(REFERENCE_SNIPPET); assertEquals(referenceGraph, graph); } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/InvokeExceptionTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/InvokeExceptionTest.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/InvokeExceptionTest.java Fri Jun 07 14:15:38 2013 +0200 @@ -66,7 +66,7 @@ } Assumptions assumptions = new Assumptions(false); new InliningPhase(runtime(), hints, replacements, assumptions, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL).apply(graph); - new CanonicalizerPhase.Instance(runtime(), assumptions).apply(graph); + new CanonicalizerPhase.Instance(runtime(), assumptions, true).apply(graph); new DeadCodeEliminationPhase().apply(graph); } } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/InvokeHintsTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/InvokeHintsTest.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/InvokeHintsTest.java Fri Jun 07 14:15:38 2013 +0200 @@ -77,7 +77,7 @@ Assumptions assumptions = new Assumptions(false); new InliningPhase(runtime(), hints, replacements, assumptions, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL).apply(graph); - new CanonicalizerPhase.Instance(runtime(), assumptions).apply(graph); + new CanonicalizerPhase.Instance(runtime(), assumptions, true).apply(graph); new DeadCodeEliminationPhase().apply(graph); StructuredGraph referenceGraph = parse(REFERENCE_SNIPPET); assertEquals(referenceGraph, graph); diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/LoopUnswitchTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/LoopUnswitchTest.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/LoopUnswitchTest.java Fri Jun 07 14:15:38 2013 +0200 @@ -133,8 +133,8 @@ } Assumptions assumptions = new Assumptions(false); - new CanonicalizerPhase.Instance(runtime(), assumptions).apply(graph); - new CanonicalizerPhase.Instance(runtime(), assumptions).apply(referenceGraph); + new CanonicalizerPhase.Instance(runtime(), assumptions, true).apply(graph); + new CanonicalizerPhase.Instance(runtime(), assumptions, true).apply(referenceGraph); Debug.scope("Test", new DebugDumpScope("Test:" + snippet), new Runnable() { @Override diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MemoryScheduleTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MemoryScheduleTest.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MemoryScheduleTest.java Fri Jun 07 14:15:38 2013 +0200 @@ -33,7 +33,7 @@ import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.extended.*; -import com.oracle.graal.nodes.spi.Lowerable.*; +import com.oracle.graal.nodes.spi.Lowerable.LoweringType; import com.oracle.graal.nodes.util.*; import com.oracle.graal.phases.*; import com.oracle.graal.phases.common.*; @@ -220,11 +220,11 @@ public SchedulePhase call() throws Exception { StructuredGraph graph = parse(snippet); Assumptions assumptions = new Assumptions(false); - new CanonicalizerPhase.Instance(runtime, assumptions).apply(graph); + HighTierContext context = new HighTierContext(runtime(), assumptions, replacements); + new CanonicalizerPhase(true).apply(graph, context); if (mode == TestMode.INLINED_WITHOUT_FRAMESTATES) { new InliningPhase(runtime(), null, replacements, assumptions, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL).apply(graph); } - HighTierContext context = new HighTierContext(runtime(), assumptions, replacements); new LoweringPhase(LoweringType.BEFORE_GUARDS).apply(graph, context); if (mode == TestMode.WITHOUT_FRAMESTATES || mode == TestMode.INLINED_WITHOUT_FRAMESTATES) { for (Node node : graph.getNodes()) { diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MonitorGraphTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MonitorGraphTest.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MonitorGraphTest.java Fri Jun 07 14:15:38 2013 +0200 @@ -94,7 +94,7 @@ } Assumptions assumptions = new Assumptions(false); new InliningPhase(runtime(), hints, replacements, assumptions, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL).apply(graph); - new CanonicalizerPhase.Instance(runtime(), assumptions).apply(graph); + new CanonicalizerPhase.Instance(runtime(), assumptions, true).apply(graph); new DeadCodeEliminationPhase().apply(graph); return graph; } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/PushNodesThroughPiTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/PushNodesThroughPiTest.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/PushNodesThroughPiTest.java Fri Jun 07 14:15:38 2013 +0200 @@ -93,10 +93,11 @@ private StructuredGraph compileTestSnippet(final String snippet) { StructuredGraph graph = parse(snippet); HighTierContext context = new HighTierContext(runtime(), new Assumptions(false), replacements); + CanonicalizerPhase canonicalizer = new CanonicalizerPhase(true); new LoweringPhase(LoweringType.BEFORE_GUARDS).apply(graph, context); - new CanonicalizerPhase().apply(graph, context); + canonicalizer.apply(graph, context); new PushThroughPiPhase().apply(graph); - new CanonicalizerPhase().apply(graph, context); + canonicalizer.apply(graph, context); return graph; } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ReadAfterCheckCastTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ReadAfterCheckCastTest.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ReadAfterCheckCastTest.java Fri Jun 07 14:15:38 2013 +0200 @@ -25,6 +25,7 @@ import org.junit.*; import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; import com.oracle.graal.debug.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.extended.*; @@ -88,14 +89,14 @@ new FloatingReadPhase().apply(graph); new EliminatePartiallyRedundantGuardsPhase(true, false).apply(graph); new ReadEliminationPhase().apply(graph); - new CanonicalizerPhase().apply(graph, context); + new CanonicalizerPhase(true).apply(graph, context); Debug.dump(graph, "After lowering"); for (FloatingReadNode node : graph.getNodes(LocalNode.class).first().usages().filter(FloatingReadNode.class)) { // Checking that the parameter a is not directly used for the access to field // x10 (because x10 must be guarded by the checkcast). - Assert.assertTrue(node.location().getLocationIdentity() == LocationNode.FINAL_LOCATION); + Assert.assertTrue(node.location().getLocationIdentity() == LocationIdentity.FINAL_LOCATION); } } }); diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ReassociateAndCanonicalTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ReassociateAndCanonicalTest.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ReassociateAndCanonicalTest.java Fri Jun 07 14:15:38 2013 +0200 @@ -244,9 +244,9 @@ private void test(String test, String ref) { StructuredGraph testGraph = parse(test); Assumptions assumptions = new Assumptions(false); - new CanonicalizerPhase.Instance(runtime(), assumptions).apply(testGraph); + new CanonicalizerPhase.Instance(runtime(), assumptions, true).apply(testGraph); StructuredGraph refGraph = parse(ref); - new CanonicalizerPhase.Instance(runtime(), assumptions).apply(refGraph); + new CanonicalizerPhase.Instance(runtime(), assumptions, true).apply(refGraph); assertEquals(testGraph, refGraph); } } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ScalarTypeSystemTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ScalarTypeSystemTest.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ScalarTypeSystemTest.java Fri Jun 07 14:15:38 2013 +0200 @@ -166,9 +166,9 @@ StructuredGraph graph = parse(snippet); Debug.dump(graph, "Graph"); Assumptions assumptions = new Assumptions(false); - new CanonicalizerPhase.Instance(runtime(), assumptions).apply(graph); + new CanonicalizerPhase.Instance(runtime(), assumptions, true).apply(graph); new ConditionalEliminationPhase(runtime()).apply(graph); - new CanonicalizerPhase.Instance(runtime(), assumptions).apply(graph); + new CanonicalizerPhase.Instance(runtime(), assumptions, true).apply(graph); StructuredGraph referenceGraph = parse(referenceSnippet); assertEquals(referenceGraph, graph); } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/StampCanonicalizerTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/StampCanonicalizerTest.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/StampCanonicalizerTest.java Fri Jun 07 14:15:38 2013 +0200 @@ -98,7 +98,7 @@ private void testZeroReturn(String methodName) { StructuredGraph graph = parse(methodName); - new CanonicalizerPhase.Instance(runtime(), new Assumptions(false)).apply(graph); + new CanonicalizerPhase.Instance(runtime(), new Assumptions(false), true).apply(graph); new DeadCodeEliminationPhase().apply(graph); assertConstantReturn(graph, 0); } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/StraighteningTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/StraighteningTest.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/StraighteningTest.java Fri Jun 07 14:15:38 2013 +0200 @@ -89,7 +89,7 @@ // No debug scope to reduce console noise for @Test(expected = ...) tests StructuredGraph graph = parse(snippet); Debug.dump(graph, "Graph"); - new CanonicalizerPhase.Instance(runtime(), new Assumptions(false)).apply(graph); + new CanonicalizerPhase.Instance(runtime(), new Assumptions(false), true).apply(graph); StructuredGraph referenceGraph = parse(REFERENCE_SNIPPET); assertEquals(referenceGraph, graph); } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/TypeSystemTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/TypeSystemTest.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/TypeSystemTest.java Fri Jun 07 14:15:38 2013 +0200 @@ -186,13 +186,13 @@ StructuredGraph graph = parse(snippet); Debug.dump(graph, "Graph"); Assumptions assumptions = new Assumptions(false); - new CanonicalizerPhase.Instance(runtime(), assumptions).apply(graph); + new CanonicalizerPhase.Instance(runtime(), assumptions, true).apply(graph); new ConditionalEliminationPhase(runtime()).apply(graph); - new CanonicalizerPhase.Instance(runtime(), assumptions).apply(graph); + new CanonicalizerPhase.Instance(runtime(), assumptions, true).apply(graph); // a second canonicalizer is needed to process nested MaterializeNodes - new CanonicalizerPhase.Instance(runtime(), assumptions).apply(graph); + new CanonicalizerPhase.Instance(runtime(), assumptions, true).apply(graph); StructuredGraph referenceGraph = parse(referenceSnippet); - new CanonicalizerPhase.Instance(runtime(), assumptions).apply(referenceGraph); + new CanonicalizerPhase.Instance(runtime(), assumptions, true).apply(referenceGraph); assertEquals(referenceGraph, graph); } @@ -242,9 +242,9 @@ StructuredGraph graph = parse(snippet); Debug.dump(graph, "Graph"); Assumptions assumptions = new Assumptions(false); - new CanonicalizerPhase.Instance(runtime(), assumptions).apply(graph); + new CanonicalizerPhase.Instance(runtime(), assumptions, true).apply(graph); new ConditionalEliminationPhase(runtime()).apply(graph); - new CanonicalizerPhase.Instance(runtime(), assumptions).apply(graph); + new CanonicalizerPhase.Instance(runtime(), assumptions, true).apply(graph); Debug.dump(graph, "Graph"); Assert.assertFalse("shouldn't have nodes of type " + clazz, graph.getNodes(clazz).iterator().hasNext()); } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/WriteBarrierAdditionTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/WriteBarrierAdditionTest.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/WriteBarrierAdditionTest.java Fri Jun 07 14:15:38 2013 +0200 @@ -27,10 +27,10 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.debug.*; import com.oracle.graal.hotspot.phases.*; +import com.oracle.graal.nodes.HeapAccess.WriteBarrierType; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.extended.*; -import com.oracle.graal.nodes.extended.WriteNode.WriteBarrierType; -import com.oracle.graal.nodes.spi.Lowerable.*; +import com.oracle.graal.nodes.spi.Lowerable.LoweringType; import com.oracle.graal.phases.common.*; import com.oracle.graal.phases.tiers.*; diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/WriteBarrierVerificationTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/WriteBarrierVerificationTest.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/WriteBarrierVerificationTest.java Fri Jun 07 14:15:38 2013 +0200 @@ -33,7 +33,6 @@ import com.oracle.graal.debug.internal.*; import com.oracle.graal.hotspot.phases.*; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.extended.LocationNode.LocationIdentity; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.Lowerable.LoweringType; import com.oracle.graal.phases.*; diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/backend/AllocatorTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/backend/AllocatorTest.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/backend/AllocatorTest.java Fri Jun 07 14:15:38 2013 +0200 @@ -23,6 +23,7 @@ package com.oracle.graal.compiler.test.backend; import static com.oracle.graal.api.code.CodeUtil.*; +import static com.oracle.graal.phases.GraalOptions.*; import java.util.*; import java.util.concurrent.*; @@ -112,7 +113,7 @@ private RegisterStats getRegisterStats(final StructuredGraph graph) { final PhasePlan phasePlan = getDefaultPhasePlan(); - final Assumptions assumptions = new Assumptions(GraalOptions.OptAssumptions); + final Assumptions assumptions = new Assumptions(OptAssumptions.getValue()); final LIR lir = Debug.scope("FrontEnd", new Callable() { diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/deopt/CompiledMethodTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/deopt/CompiledMethodTest.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/deopt/CompiledMethodTest.java Fri Jun 07 14:15:38 2013 +0200 @@ -55,7 +55,7 @@ public void test1() { Method method = getMethod("testMethod"); final StructuredGraph graph = parse(method); - new CanonicalizerPhase.Instance(runtime(), new Assumptions(false)).apply(graph); + new CanonicalizerPhase.Instance(runtime(), new Assumptions(false), true).apply(graph); new DeadCodeEliminationPhase().apply(graph); for (Node node : graph.getNodes()) { diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EscapeAnalysisTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EscapeAnalysisTest.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EscapeAnalysisTest.java Fri Jun 07 14:15:38 2013 +0200 @@ -222,7 +222,7 @@ HighTierContext context = new HighTierContext(runtime(), assumptions, replacements); new InliningPhase(runtime(), null, replacements, assumptions, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL).apply(graph); new DeadCodeEliminationPhase().apply(graph); - new PartialEscapeAnalysisPhase(iterativeEscapeAnalysis, false).apply(graph, context); + new PartialEscapeAnalysisPhase(iterativeEscapeAnalysis, false, new CanonicalizerPhase(true)).apply(graph, context); Assert.assertEquals(1, graph.getNodes(ReturnNode.class).count()); ReturnNode returnNode = graph.getNodes(ReturnNode.class).first(); if (expectedConstantResult != null) { diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/IterativeInliningTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/IterativeInliningTest.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/IterativeInliningTest.java Fri Jun 07 14:15:38 2013 +0200 @@ -22,6 +22,7 @@ */ package com.oracle.graal.compiler.test.ea; +import static com.oracle.graal.phases.GraalOptions.*; import static org.junit.Assert.*; import java.util.concurrent.*; @@ -33,6 +34,7 @@ import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.java.*; import com.oracle.graal.phases.*; +import com.oracle.graal.phases.common.*; import com.oracle.graal.phases.tiers.*; import com.oracle.graal.virtual.phases.ea.*; @@ -100,8 +102,8 @@ private void processMethod(final String snippet) { graph = parse(snippet); - GraalOptions.OptEarlyReadElimination = true; + OptEarlyReadElimination.setValue(true); HighTierContext context = new HighTierContext(runtime(), new Assumptions(false), replacements); - new IterativeInliningPhase(replacements, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL, false).apply(graph, context); + new IterativeInliningPhase(replacements, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL, false, new CanonicalizerPhase(true)).apply(graph, context); } } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PEAReadEliminationTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PEAReadEliminationTest.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PEAReadEliminationTest.java Fri Jun 07 14:15:38 2013 +0200 @@ -224,6 +224,6 @@ Assumptions assumptions = new Assumptions(false); HighTierContext context = new HighTierContext(runtime(), assumptions, replacements); new InliningPhase(runtime(), null, replacements, assumptions, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL).apply(graph); - new PartialEscapeAnalysisPhase(false, true).apply(graph, context); + new PartialEscapeAnalysisPhase(false, true, new CanonicalizerPhase(true)).apply(graph, context); } } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PartialEscapeAnalysisTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PartialEscapeAnalysisTest.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PartialEscapeAnalysisTest.java Fri Jun 07 14:15:38 2013 +0200 @@ -164,12 +164,13 @@ HighTierContext context = new HighTierContext(runtime(), assumptions, replacements); new InliningPhase(runtime(), null, replacements, assumptions, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL).apply(graph); new DeadCodeEliminationPhase().apply(graph); - new CanonicalizerPhase().apply(graph, context); - new PartialEscapeAnalysisPhase(false, false).apply(graph, context); + CanonicalizerPhase canonicalizer = new CanonicalizerPhase(true); + canonicalizer.apply(graph, context); + new PartialEscapeAnalysisPhase(false, false, canonicalizer).apply(graph, context); new CullFrameStatesPhase().apply(graph); new DeadCodeEliminationPhase().apply(graph); - new CanonicalizerPhase().apply(graph, context); + canonicalizer.apply(graph, context); return graph; } }); diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/inlining/InliningTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/inlining/InliningTest.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/inlining/InliningTest.java Fri Jun 07 14:15:38 2013 +0200 @@ -161,7 +161,7 @@ Debug.dump(graph, "Graph"); new InliningPhase(runtime(), null, replacements, assumptions, null, phasePlan, OptimisticOptimizations.ALL).apply(graph); Debug.dump(graph, "Graph"); - new CanonicalizerPhase.Instance(runtime(), assumptions).apply(graph); + new CanonicalizerPhase.Instance(runtime(), assumptions, true).apply(graph); new DeadCodeEliminationPhase().apply(graph); return graph; } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/DebugFilter.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/DebugFilter.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/DebugFilter.java Fri Jun 07 14:15:38 2013 +0200 @@ -27,11 +27,11 @@ import com.oracle.graal.debug.*; import com.oracle.graal.debug.internal.*; -import com.oracle.graal.phases.*; /** - * Implements the filter specified by the {@link GraalOptions#Dump}, {@link GraalOptions#Log}, - * {@link GraalOptions#Meter} and {@link GraalOptions#Time} options. + * Implements the filter specified by the {@link GraalDebugConfig#Dump}, + * {@link GraalDebugConfig#Log}, {@link GraalDebugConfig#Meter} and {@link GraalDebugConfig#Time} + * options. *

    * These options enable the associated debug facility if their filter matches the * {@linkplain DebugScope#getQualifiedName() name} of the {@linkplain Debug#currentScope() current diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java Fri Jun 07 14:15:38 2013 +0200 @@ -22,6 +22,8 @@ */ package com.oracle.graal.compiler; +import static com.oracle.graal.phases.GraalOptions.*; + import java.util.*; import java.util.concurrent.*; @@ -38,6 +40,7 @@ import com.oracle.graal.nodes.cfg.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.util.*; +import com.oracle.graal.options.*; import com.oracle.graal.phases.*; import com.oracle.graal.phases.PhasePlan.PhasePosition; import com.oracle.graal.phases.common.*; @@ -52,6 +55,13 @@ */ public class GraalCompiler { + // @formatter:off + @Option(help = "") + public static final OptionValue VerifyUsageWithEquals = new OptionValue<>(true); + @Option(help = "Enable inlining") + public static final OptionValue Inline = new OptionValue<>(true); + // @formatter:on + /** * Requests compilation of a given graph. * @@ -69,7 +79,7 @@ Debug.scope("GraalCompiler", new Object[]{graph, runtime}, new Runnable() { public void run() { - final Assumptions assumptions = new Assumptions(GraalOptions.OptAssumptions); + final Assumptions assumptions = new Assumptions(OptAssumptions.getValue()); final LIR lir = Debug.scope("FrontEnd", new Callable() { public LIR call() { @@ -125,23 +135,27 @@ } else { Debug.dump(graph, "initial state"); } - new VerifyValueUsage(runtime).apply(graph); - - if (GraalOptions.OptCanonicalizer) { - new CanonicalizerPhase.Instance(runtime, assumptions).apply(graph); + if (VerifyUsageWithEquals.getValue()) { + new VerifyUsageWithEquals(runtime, Value.class).apply(graph); + new VerifyUsageWithEquals(runtime, Register.class).apply(graph); } + CanonicalizerPhase canonicalizer = new CanonicalizerPhase(OptCanonicalizeReads.getValue()); HighTierContext highTierContext = new HighTierContext(runtime, assumptions, replacements); - if (GraalOptions.Inline && !plan.isPhaseDisabled(InliningPhase.class)) { - if (GraalOptions.IterativeInlining) { - new IterativeInliningPhase(replacements, cache, plan, optimisticOpts, GraalOptions.OptEarlyReadElimination).apply(graph, highTierContext); + if (OptCanonicalizer.getValue()) { + canonicalizer.apply(graph, highTierContext); + } + + if (Inline.getValue() && !plan.isPhaseDisabled(InliningPhase.class)) { + if (IterativeInlining.getValue()) { + new IterativeInliningPhase(replacements, cache, plan, optimisticOpts, OptEarlyReadElimination.getValue(), canonicalizer).apply(graph, highTierContext); } else { new InliningPhase(runtime, null, replacements, assumptions, cache, plan, optimisticOpts).apply(graph); new DeadCodeEliminationPhase().apply(graph); - if (GraalOptions.ConditionalElimination && GraalOptions.OptCanonicalizer) { - new CanonicalizerPhase.Instance(runtime, assumptions).apply(graph); + if (ConditionalElimination.getValue() && OptCanonicalizer.getValue()) { + canonicalizer.apply(graph, highTierContext); new IterativeConditionalEliminationPhase().apply(graph, highTierContext); } } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalDebugConfig.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalDebugConfig.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalDebugConfig.java Fri Jun 07 14:15:38 2013 +0200 @@ -31,10 +31,43 @@ import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.util.*; -import com.oracle.graal.phases.*; +import com.oracle.graal.options.*; public class GraalDebugConfig implements DebugConfig { + // @formatter:off + @Option(help = "Enable scope-based debugging", name = "Debug") + public static final OptionValue DebugEnabled = new OptionValue<>(true); + @Option(help = "Scopes to be dumped") + public static final OptionValue Dump = new OptionValue<>(null); + @Option(help = "Scopes to be metered") + public static final OptionValue Meter = new OptionValue<>(null); + @Option(help = "Scopes to be timed") + public static final OptionValue Time = new OptionValue<>(null); + @Option(help = "Scopes to be logged") + public static final OptionValue Log = new OptionValue<>(null); + @Option(help = "Filters debug scope output by method name/pattern") + public static final OptionValue MethodFilter = new OptionValue<>(null); + @Option(help = "") + public static final OptionValue PerThreadDebugValues = new OptionValue<>(false); + @Option(help = "") + public static final OptionValue SummarizeDebugValues = new OptionValue<>(false); + @Option(help = "") + public static final OptionValue SummarizePerPhase = new OptionValue<>(false); + @Option(help = "Send Graal IR to dump handlers on error") + public static final OptionValue DumpOnError = new OptionValue<>(false); + @Option(help = "Enable expensive assertions") + public static final OptionValue DetailedAsserts = new StableOptionValue() { + @Override + protected Boolean initialValue() { + boolean enabled = false; + // turn detailed assertions on when the general assertions are on (misusing the assert keyword for this) + assert (enabled = true) == true; + return enabled; + } + }; + // @formatter:on + private final DebugFilter logFilter; private final DebugFilter meterFilter; private final DebugFilter timerFilter; @@ -170,7 +203,7 @@ for (Object o : Debug.context()) { if (o instanceof Graph) { Debug.log("Context obj %s", o); - if (GraalOptions.DumpOnError) { + if (DumpOnError.getValue()) { Debug.dump(o, "Exception graph"); } else { Debug.log("Use -G:+DumpOnError to enable dumping of graphs on this error"); diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/Interval.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/Interval.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/Interval.java Fri Jun 07 14:15:38 2013 +0200 @@ -22,6 +22,10 @@ */ package com.oracle.graal.compiler.alloc; +import static com.oracle.graal.api.code.ValueUtil.*; +import static com.oracle.graal.compiler.GraalDebugConfig.*; +import static com.oracle.graal.lir.LIRValueUtil.*; + import java.util.*; import com.oracle.graal.api.code.*; @@ -29,12 +33,8 @@ import com.oracle.graal.debug.*; import com.oracle.graal.graph.*; import com.oracle.graal.lir.*; -import com.oracle.graal.phases.*; import com.oracle.graal.phases.util.*; -import static com.oracle.graal.api.code.ValueUtil.*; -import static com.oracle.graal.lir.LIRValueUtil.*; - /** * Represents an interval in the {@linkplain LinearScan linear scan register allocator}. */ @@ -922,7 +922,7 @@ // do not add use positions for precolored intervals because they are never used if (registerPriority != RegisterPriority.None && isVariable(operand)) { - if (GraalOptions.DetailedAsserts) { + if (DetailedAsserts.getValue()) { for (int i = 0; i < usePosList.size(); i++) { assert pos <= usePosList.usePos(i) : "already added a use-position with lower position"; if (i > 0) { @@ -1026,7 +1026,7 @@ // split list of use positions result.usePosList = usePosList.splitAt(splitPos); - if (GraalOptions.DetailedAsserts) { + if (DetailedAsserts.getValue()) { for (int i = 0; i < usePosList.size(); i++) { assert usePosList.usePos(i) < splitPos; } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/IntervalWalker.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/IntervalWalker.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/IntervalWalker.java Fri Jun 07 14:15:38 2013 +0200 @@ -22,11 +22,12 @@ */ package com.oracle.graal.compiler.alloc; +import static com.oracle.graal.phases.GraalOptions.*; + import com.oracle.graal.compiler.alloc.Interval.RegisterBinding; import com.oracle.graal.compiler.alloc.Interval.RegisterBindingLists; import com.oracle.graal.compiler.alloc.Interval.State; import com.oracle.graal.debug.*; -import com.oracle.graal.phases.*; /** */ @@ -208,7 +209,7 @@ boolean isActive = currentInterval.from() <= toOpId; int opId = isActive ? currentInterval.from() : toOpId; - if (GraalOptions.TraceLinearScanLevel >= 2 && !TTY.isSuppressed()) { + if (TraceLinearScanLevel.getValue() >= 2 && !TTY.isSuppressed()) { if (currentPosition < opId) { TTY.println(); TTY.println("walkTo(%d) *", opId); @@ -239,7 +240,7 @@ private void intervalMoved(Interval interval, State from, State to) { // intervalMoved() is called whenever an interval moves from one interval list to another. // In the implementation of this method it is prohibited to move the interval to any list. - if (GraalOptions.TraceLinearScanLevel >= 4 && !TTY.isSuppressed()) { + if (TraceLinearScanLevel.getValue() >= 4 && !TTY.isSuppressed()) { TTY.print(from.toString() + " to " + to.toString()); TTY.fillTo(23); TTY.out().println(interval.logString(allocator)); diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java Fri Jun 07 14:15:38 2013 +0200 @@ -24,7 +24,9 @@ import static com.oracle.graal.api.code.CodeUtil.*; import static com.oracle.graal.api.code.ValueUtil.*; +import static com.oracle.graal.compiler.GraalDebugConfig.*; import static com.oracle.graal.lir.LIRValueUtil.*; +import static com.oracle.graal.phases.GraalOptions.*; import java.util.*; @@ -501,7 +503,7 @@ // called once before assignment of register numbers void eliminateSpillMoves() { - if (GraalOptions.TraceLinearScanLevel >= 3) { + if (TraceLinearScanLevel.getValue() >= 3) { TTY.println(" Eliminating unnecessary spill moves"); } @@ -509,7 +511,7 @@ // the list is sorted by Interval.spillDefinitionPos Interval interval; interval = createUnhandledLists(mustStoreAtDefinition, null).first; - if (GraalOptions.DetailedAsserts) { + if (DetailedAsserts.getValue()) { checkIntervals(interval); } @@ -535,7 +537,7 @@ if (!isRegister(curInterval.location()) && curInterval.alwaysInMemory()) { // move target is a stack slot that is always correct, so eliminate // instruction - if (GraalOptions.TraceLinearScanLevel >= 4) { + if (TraceLinearScanLevel.getValue() >= 4) { TTY.println("eliminating move from interval %d to %d", operandNumber(move.getInput()), operandNumber(move.getResult())); } instructions.set(j, null); // null-instructions are deleted by assignRegNum @@ -561,7 +563,7 @@ insertionBuffer.append(j + 1, ir.spillMoveFactory.createMove(toLocation, fromLocation)); - if (GraalOptions.TraceLinearScanLevel >= 4) { + if (TraceLinearScanLevel.getValue() >= 4) { StackSlot slot = interval.spillSlot(); TTY.println("inserting move after definition of interval %d to stack slot %s at opId %d", interval.operandNumber, slot, opId); } @@ -593,7 +595,7 @@ assert temp.spillDefinitionPos() >= temp.from() : "invalid order"; assert temp.spillDefinitionPos() <= temp.from() + 2 : "only intervals defined once at their start-pos can be optimized"; - if (GraalOptions.TraceLinearScanLevel >= 4) { + if (TraceLinearScanLevel.getValue() >= 4) { TTY.println("interval %d (from %d to %d) must be stored at %d", temp.operandNumber, temp.from(), temp.to(), temp.spillDefinitionPos()); } @@ -658,7 +660,7 @@ assert index == numInstructions : "must match"; assert (index << 1) == opId : "must match: " + (index << 1); - if (GraalOptions.DetailedAsserts) { + if (DetailedAsserts.getValue()) { for (int i = 0; i < variables.size(); i++) { assert variables.get(i) != null && variables.get(i).index == i; } @@ -696,7 +698,7 @@ int operandNum = operandNumber(operand); if (!liveKill.get(operandNum)) { liveGen.set(operandNum); - if (GraalOptions.TraceLinearScanLevel >= 4) { + if (TraceLinearScanLevel.getValue() >= 4) { TTY.println(" Setting liveGen for operand %d at instruction %d", operandNum, op.id()); } } @@ -705,7 +707,7 @@ } } - if (GraalOptions.DetailedAsserts) { + if (DetailedAsserts.getValue()) { verifyInput(block, liveKill, operand); } return operand; @@ -718,7 +720,7 @@ int operandNum = operandNumber(operand); if (!liveKill.get(operandNum)) { liveGen.set(operandNum); - if (GraalOptions.TraceLinearScanLevel >= 4) { + if (TraceLinearScanLevel.getValue() >= 4) { TTY.println(" Setting liveGen for LIR opId %d, operand %d because of state for %s", op.id(), operandNum, op); } } @@ -737,7 +739,7 @@ } } - if (GraalOptions.DetailedAsserts) { + if (DetailedAsserts.getValue()) { // fixed intervals are never live at block boundaries, so // they need not be processed in live sets // process them only in debug mode so that this can be checked @@ -761,7 +763,7 @@ blockData.get(block).liveIn = new BitSet(liveSize); blockData.get(block).liveOut = new BitSet(liveSize); - if (GraalOptions.TraceLinearScanLevel >= 4) { + if (TraceLinearScanLevel.getValue() >= 4) { TTY.println("liveGen B%d %s", block.getId(), blockData.get(block).liveGen); TTY.println("liveKill B%d %s", block.getId(), blockData.get(block).liveKill); } @@ -850,7 +852,7 @@ liveIn.or(blockData.get(block).liveGen); } - if (GraalOptions.TraceLinearScanLevel >= 4) { + if (TraceLinearScanLevel.getValue() >= 4) { traceLiveness(changeOccurredInBlock, iterationCount, block); } } @@ -861,7 +863,7 @@ } } while (changeOccurred); - if (GraalOptions.DetailedAsserts) { + if (DetailedAsserts.getValue()) { verifyLiveness(); } @@ -869,7 +871,7 @@ Block startBlock = ir.cfg.getStartBlock(); BitSet liveInArgs = new BitSet(blockData.get(startBlock).liveIn.size()); if (!blockData.get(startBlock).liveIn.equals(liveInArgs)) { - if (GraalOptions.DetailedAsserts) { + if (DetailedAsserts.getValue()) { reportFailure(numBlocks); } @@ -970,7 +972,7 @@ if (!isProcessed(operand)) { return; } - if (GraalOptions.TraceLinearScanLevel >= 2 && kind == null) { + if (TraceLinearScanLevel.getValue() >= 2 && kind == null) { TTY.println(" use %s from %d to %d (%s)", operand, from, to, registerPriority.name()); } @@ -989,7 +991,7 @@ if (!isProcessed(operand)) { return; } - if (GraalOptions.TraceLinearScanLevel >= 2) { + if (TraceLinearScanLevel.getValue() >= 2) { TTY.println(" temp %s tempPos %d (%s)", operand, tempPos, RegisterPriority.MustHaveRegister.name()); } @@ -1010,7 +1012,7 @@ if (!isProcessed(operand)) { return; } - if (GraalOptions.TraceLinearScanLevel >= 2) { + if (TraceLinearScanLevel.getValue() >= 2) { TTY.println(" def %s defPos %d (%s)", operand, defPos, registerPriority.name()); } @@ -1031,7 +1033,7 @@ // also add register priority for dead intervals interval.addRange(defPos, defPos + 1); interval.addUsePos(defPos, registerPriority); - if (GraalOptions.TraceLinearScanLevel >= 2) { + if (TraceLinearScanLevel.getValue() >= 2) { TTY.println("Warning: def of operand %s at %d occurs without use", operand, defPos); } } @@ -1087,12 +1089,12 @@ MoveOp move = (MoveOp) op; if (optimizeMethodArgument(move.getInput())) { StackSlot slot = asStackSlot(move.getInput()); - if (GraalOptions.DetailedAsserts) { + if (DetailedAsserts.getValue()) { assert op.id() > 0 : "invalid id"; assert blockForId(op.id()).getPredecessorCount() == 0 : "move from stack must be in first block"; assert isVariable(move.getResult()) : "result of move must be a variable"; - if (GraalOptions.TraceLinearScanLevel >= 4) { + if (TraceLinearScanLevel.getValue() >= 4) { TTY.println("found move from stack slot %s to %s", slot, move.getResult()); } } @@ -1122,7 +1124,7 @@ from.setLocationHint(to); } - if (GraalOptions.TraceLinearScanLevel >= 4) { + if (TraceLinearScanLevel.getValue() >= 4) { TTY.println("operation at opId %d: added hint from interval %d to %d", op.id(), from.operandNumber, to.operandNumber); } return registerHint; @@ -1155,7 +1157,7 @@ for (int operandNum = live.nextSetBit(0); operandNum >= 0; operandNum = live.nextSetBit(operandNum + 1)) { assert live.get(operandNum) : "should not stop here otherwise"; AllocatableValue operand = operandFor(operandNum); - if (GraalOptions.TraceLinearScanLevel >= 2) { + if (TraceLinearScanLevel.getValue() >= 2) { TTY.println("live in %s to %d", operand, blockTo + 2); } @@ -1185,7 +1187,7 @@ addTemp(r.asValue(), opId, RegisterPriority.None, Kind.Illegal); } } - if (GraalOptions.TraceLinearScanLevel >= 4) { + if (TraceLinearScanLevel.getValue() >= 4) { TTY.println("operation destroys all caller-save registers"); } } @@ -1436,7 +1438,7 @@ Interval result = interval.getSplitChildAtOpId(opId, mode, this); if (result != null) { - if (GraalOptions.TraceLinearScanLevel >= 4) { + if (TraceLinearScanLevel.getValue() >= 4) { TTY.println("Split child at pos " + opId + " of interval " + interval.toString() + " is " + result.toString()); } return result; @@ -1490,7 +1492,7 @@ void resolveFindInsertPos(Block fromBlock, Block toBlock, MoveResolver moveResolver) { if (fromBlock.getSuccessorCount() <= 1) { - if (GraalOptions.TraceLinearScanLevel >= 4) { + if (TraceLinearScanLevel.getValue() >= 4) { TTY.println("inserting moves at end of fromBlock B%d", fromBlock.getId()); } @@ -1504,11 +1506,11 @@ } } else { - if (GraalOptions.TraceLinearScanLevel >= 4) { + if (TraceLinearScanLevel.getValue() >= 4) { TTY.println("inserting moves at beginning of toBlock B%d", toBlock.getId()); } - if (GraalOptions.DetailedAsserts) { + if (DetailedAsserts.getValue()) { assert ir.lir(fromBlock).get(0) instanceof StandardOp.LabelOp : "block does not start with a label"; // because the number of predecessor edges matches the number of @@ -1549,7 +1551,7 @@ // prevent optimization of two consecutive blocks if (!blockCompleted.get(pred.getLinearScanNumber()) && !blockCompleted.get(sux.getLinearScanNumber())) { - if (GraalOptions.TraceLinearScanLevel >= 3) { + if (TraceLinearScanLevel.getValue() >= 3) { TTY.println(" optimizing empty block B%d (pred: B%d, sux: B%d)", block.getId(), pred.getId(), sux.getId()); } blockCompleted.set(block.getLinearScanNumber()); @@ -1576,7 +1578,7 @@ // check for duplicate edges between the same blocks (can happen with switch // blocks) if (!alreadyResolved.get(toBlock.getLinearScanNumber())) { - if (GraalOptions.TraceLinearScanLevel >= 3) { + if (GraalOptions.TraceLinearScanLevel.getValue() >= 3) { TTY.println(" processing edge between B%d and B%d", fromBlock.getId(), toBlock.getId()); } alreadyResolved.set(toBlock.getLinearScanNumber()); @@ -1614,7 +1616,7 @@ assert interval != null : "interval must exist"; if (opId != -1) { - if (GraalOptions.DetailedAsserts) { + if (DetailedAsserts.getValue()) { Block block = blockForId(opId); if (block.getSuccessorCount() <= 1 && opId == getLastLirInstructionId(block)) { // check if spill moves could have been appended at the end of this block, but @@ -1655,7 +1657,7 @@ } void computeOopMap(IntervalWalker iw, LIRInstruction op, BitSet registerRefMap, BitSet frameRefMap) { - if (GraalOptions.TraceLinearScanLevel >= 3) { + if (TraceLinearScanLevel.getValue() >= 3) { TTY.println("creating oop map at opId %d", op.id()); } @@ -1839,14 +1841,14 @@ sortIntervalsAfterAllocation(); - if (GraalOptions.DetailedAsserts) { + if (DetailedAsserts.getValue()) { verify(); } eliminateSpillMoves(); assignLocations(); - if (GraalOptions.DetailedAsserts) { + if (DetailedAsserts.getValue()) { verifyIntervals(); } } @@ -1864,7 +1866,7 @@ } void printIntervals(String label) { - if (GraalOptions.TraceLinearScanLevel >= 1) { + if (TraceLinearScanLevel.getValue() >= 1) { int i; TTY.println(); TTY.println(label); @@ -1894,27 +1896,27 @@ boolean verify() { // (check that all intervals have a correct register and that no registers are overwritten) - if (GraalOptions.TraceLinearScanLevel >= 2) { + if (TraceLinearScanLevel.getValue() >= 2) { TTY.println(" verifying intervals *"); } verifyIntervals(); - if (GraalOptions.TraceLinearScanLevel >= 2) { + if (TraceLinearScanLevel.getValue() >= 2) { TTY.println(" verifying that no oops are in fixed intervals *"); } // verifyNoOopsInFixedIntervals(); - if (GraalOptions.TraceLinearScanLevel >= 2) { + if (TraceLinearScanLevel.getValue() >= 2) { TTY.println(" verifying that unpinned constants are not alive across block boundaries"); } verifyConstants(); - if (GraalOptions.TraceLinearScanLevel >= 2) { + if (TraceLinearScanLevel.getValue() >= 2) { TTY.println(" verifying register allocation *"); } verifyRegisters(); - if (GraalOptions.TraceLinearScanLevel >= 2) { + if (TraceLinearScanLevel.getValue() >= 2) { TTY.println(" no errors found *"); } @@ -1986,7 +1988,7 @@ Value l1 = i1.location(); Value l2 = i2.location(); if (i1.intersects(i2) && (l1.equals(l2))) { - if (GraalOptions.DetailedAsserts) { + if (DetailedAsserts.getValue()) { TTY.println("Intervals %d and %d overlap and have the same register assigned", i1.operandNumber, i2.operandNumber); TTY.println(i1.logString(this)); TTY.println(i2.logString(this)); @@ -2066,7 +2068,7 @@ // visit all operands where the liveAtEdge bit is set for (int operandNum = liveAtEdge.nextSetBit(0); operandNum >= 0; operandNum = liveAtEdge.nextSetBit(operandNum + 1)) { - if (GraalOptions.TraceLinearScanLevel >= 4) { + if (TraceLinearScanLevel.getValue() >= 4) { TTY.println("checking interval %d of block B%d", operandNum, block.getId()); } Value operand = operandFor(operandNum); diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScanWalker.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScanWalker.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScanWalker.java Fri Jun 07 14:15:38 2013 +0200 @@ -25,6 +25,7 @@ import static com.oracle.graal.api.code.CodeUtil.*; import static com.oracle.graal.api.code.ValueUtil.*; import static com.oracle.graal.lir.LIRValueUtil.*; +import static com.oracle.graal.phases.GraalOptions.*; import java.util.*; @@ -38,7 +39,6 @@ import com.oracle.graal.lir.*; import com.oracle.graal.lir.StandardOp.MoveOp; import com.oracle.graal.nodes.cfg.*; -import com.oracle.graal.phases.*; import com.oracle.graal.phases.util.*; /** @@ -297,7 +297,7 @@ int optimalSplitPos = -1; if (minSplitPos == maxSplitPos) { // trivial case, no optimization of split position possible - if (GraalOptions.TraceLinearScanLevel >= 4) { + if (TraceLinearScanLevel.getValue() >= 4) { TTY.println(" min-pos and max-pos are equal, no optimization possible"); } optimalSplitPos = minSplitPos; @@ -321,7 +321,7 @@ assert minBlock.getLinearScanNumber() <= maxBlock.getLinearScanNumber() : "invalid order"; if (minBlock == maxBlock) { // split position cannot be moved to block boundary : so split as late as possible - if (GraalOptions.TraceLinearScanLevel >= 4) { + if (TraceLinearScanLevel.getValue() >= 4) { TTY.println(" cannot move split pos to block boundary because minPos and maxPos are in same block"); } optimalSplitPos = maxSplitPos; @@ -333,14 +333,14 @@ // as mustHaveRegister) with a hole before each definition. When the register is // needed // for the second definition : an earlier reloading is unnecessary. - if (GraalOptions.TraceLinearScanLevel >= 4) { + if (TraceLinearScanLevel.getValue() >= 4) { TTY.println(" interval has hole just before maxSplitPos, so splitting at maxSplitPos"); } optimalSplitPos = maxSplitPos; } else { // seach optimal block boundary between minSplitPos and maxSplitPos - if (GraalOptions.TraceLinearScanLevel >= 4) { + if (TraceLinearScanLevel.getValue() >= 4) { TTY.println(" moving split pos to optimal block boundary between block B%d and B%d", minBlock.getId(), maxBlock.getId()); } @@ -349,7 +349,7 @@ // max-position : // then split before this loop int loopEndPos = interval.nextUsageExact(RegisterPriority.LiveAtLoopEnd, allocator.getLastLirInstructionId(minBlock) + 2); - if (GraalOptions.TraceLinearScanLevel >= 4) { + if (TraceLinearScanLevel.getValue() >= 4) { TTY.println(" loop optimization: loop end found at pos %d", loopEndPos); } @@ -364,7 +364,7 @@ // of the interval (normally, only mustHaveRegister causes a reloading) Block loopBlock = allocator.blockForId(loopEndPos); - if (GraalOptions.TraceLinearScanLevel >= 4) { + if (TraceLinearScanLevel.getValue() >= 4) { TTY.println(" interval is used in loop that ends in block B%d, so trying to move maxBlock back from B%d to B%d", loopBlock.getId(), maxBlock.getId(), loopBlock.getId()); } @@ -373,11 +373,11 @@ optimalSplitPos = findOptimalSplitPos(minBlock, loopBlock, allocator.getLastLirInstructionId(loopBlock) + 2); if (optimalSplitPos == allocator.getLastLirInstructionId(loopBlock) + 2) { optimalSplitPos = -1; - if (GraalOptions.TraceLinearScanLevel >= 4) { + if (TraceLinearScanLevel.getValue() >= 4) { TTY.println(" loop optimization not necessary"); } } else { - if (GraalOptions.TraceLinearScanLevel >= 4) { + if (TraceLinearScanLevel.getValue() >= 4) { TTY.println(" loop optimization successful"); } } @@ -391,7 +391,7 @@ } } } - if (GraalOptions.TraceLinearScanLevel >= 4) { + if (TraceLinearScanLevel.getValue() >= 4) { TTY.println(" optimal split position: %d", optimalSplitPos); } @@ -403,13 +403,13 @@ // 1) the left part has already a location assigned // 2) the right part is sorted into to the unhandled-list void splitBeforeUsage(Interval interval, int minSplitPos, int maxSplitPos) { - if (GraalOptions.TraceLinearScanLevel >= 2) { + if (TraceLinearScanLevel.getValue() >= 2) { TTY.println("----- splitting interval: "); } - if (GraalOptions.TraceLinearScanLevel >= 4) { + if (TraceLinearScanLevel.getValue() >= 4) { TTY.println(interval.logString(allocator)); } - if (GraalOptions.TraceLinearScanLevel >= 2) { + if (TraceLinearScanLevel.getValue() >= 2) { TTY.println(" between %d and %d", minSplitPos, maxSplitPos); } @@ -427,7 +427,7 @@ if (optimalSplitPos == interval.to() && interval.nextUsage(RegisterPriority.MustHaveRegister, minSplitPos) == Integer.MAX_VALUE) { // the split position would be just before the end of the interval // . no split at all necessary - if (GraalOptions.TraceLinearScanLevel >= 4) { + if (TraceLinearScanLevel.getValue() >= 4) { TTY.println(" no split necessary because optimal split position is at end of interval"); } return; @@ -442,7 +442,7 @@ optimalSplitPos = (optimalSplitPos - 1) | 1; } - if (GraalOptions.TraceLinearScanLevel >= 4) { + if (TraceLinearScanLevel.getValue() >= 4) { TTY.println(" splitting at position %d", optimalSplitPos); } assert allocator.isBlockBegin(optimalSplitPos) || (optimalSplitPos % 2 == 1) : "split pos must be odd when not on block boundary"; @@ -455,10 +455,10 @@ assert splitPart.from() >= currentInterval.currentFrom() : "cannot append new interval before current walk position"; unhandledLists.addToListSortedByStartAndUsePositions(RegisterBinding.Any, splitPart); - if (GraalOptions.TraceLinearScanLevel >= 2) { + if (TraceLinearScanLevel.getValue() >= 2) { TTY.println(" split interval in two parts (insertMoveWhenActivated: %b)", moveNecessary); } - if (GraalOptions.TraceLinearScanLevel >= 2) { + if (TraceLinearScanLevel.getValue() >= 2) { TTY.print(" "); TTY.println(interval.logString(allocator)); TTY.print(" "); @@ -476,7 +476,7 @@ int maxSplitPos = currentPosition; int minSplitPos = Math.max(interval.previousUsage(RegisterPriority.ShouldHaveRegister, maxSplitPos) + 1, interval.from()); - if (GraalOptions.TraceLinearScanLevel >= 2) { + if (TraceLinearScanLevel.getValue() >= 2) { TTY.print("----- splitting and spilling interval: "); TTY.println(interval.logString(allocator)); TTY.println(" between %d and %d", minSplitPos, maxSplitPos); @@ -490,7 +490,7 @@ if (minSplitPos == interval.from()) { // the whole interval is never used, so spill it entirely to memory - if (GraalOptions.TraceLinearScanLevel >= 2) { + if (TraceLinearScanLevel.getValue() >= 2) { TTY.println(" spilling entire interval because split pos is at beginning of interval"); TTY.println(" use positions: " + interval.usePosList().size()); } @@ -509,7 +509,7 @@ if (isRegister(parent.location())) { if (parent.firstUsage(RegisterPriority.ShouldHaveRegister) == Integer.MAX_VALUE) { // parent is never used, so kick it out of its assigned register - if (GraalOptions.TraceLinearScanLevel >= 4) { + if (TraceLinearScanLevel.getValue() >= 4) { TTY.println(" kicking out interval %d out of its register because it is never used", parent.operandNumber); } allocator.assignSpillSlot(parent); @@ -534,7 +534,7 @@ optimalSplitPos = (optimalSplitPos - 1) | 1; } - if (GraalOptions.TraceLinearScanLevel >= 4) { + if (TraceLinearScanLevel.getValue() >= 4) { TTY.println(" splitting at position %d", optimalSplitPos); } assert allocator.isBlockBegin(optimalSplitPos) || (optimalSplitPos % 2 == 1) : "split pos must be odd when not on block boundary"; @@ -545,7 +545,7 @@ allocator.changeSpillState(spilledPart, optimalSplitPos); if (!allocator.isBlockBegin(optimalSplitPos)) { - if (GraalOptions.TraceLinearScanLevel >= 4) { + if (TraceLinearScanLevel.getValue() >= 4) { TTY.println(" inserting move from interval %d to %d", interval.operandNumber, spilledPart.operandNumber); } insertMove(optimalSplitPos, interval, spilledPart); @@ -555,7 +555,7 @@ assert spilledPart.currentSplitChild() == interval : "overwriting wrong currentSplitChild"; spilledPart.makeCurrentSplitChild(); - if (GraalOptions.TraceLinearScanLevel >= 2) { + if (TraceLinearScanLevel.getValue() >= 2) { TTY.println(" split interval in two parts"); TTY.print(" "); TTY.println(interval.logString(allocator)); @@ -604,7 +604,7 @@ } boolean allocFreeRegister(Interval interval) { - if (GraalOptions.TraceLinearScanLevel >= 2) { + if (TraceLinearScanLevel.getValue() >= 2) { TTY.println("trying to find free register for " + interval.logString(allocator)); } @@ -620,7 +620,7 @@ // (either as a fixed register or a normal allocated register in the past) // only intervals overlapping with cur are processed, non-overlapping invervals can be // ignored safely - if (GraalOptions.TraceLinearScanLevel >= 4) { + if (TraceLinearScanLevel.getValue() >= 4) { TTY.println(" state of registers:"); for (Register register : availableRegs) { int i = register.number; @@ -632,7 +632,7 @@ Interval locationHint = interval.locationHint(true); if (locationHint != null && locationHint.location() != null && isRegister(locationHint.location())) { hint = asRegister(locationHint.location()); - if (GraalOptions.TraceLinearScanLevel >= 4) { + if (TraceLinearScanLevel.getValue() >= 4) { TTY.println(" hint register %d from interval %s", hint.number, locationHint.logString(allocator)); } } @@ -654,12 +654,12 @@ int number = availableReg.number; if (usePos[number] >= intervalTo) { // this register is free for the full interval - if (minFullReg == null || availableReg == hint || (usePos[number] < usePos[minFullReg.number] && minFullReg != hint)) { + if (minFullReg == null || availableReg.equals(hint) || (usePos[number] < usePos[minFullReg.number] && !minFullReg.equals(hint))) { minFullReg = availableReg; } } else if (usePos[number] > regNeededUntil) { // this register is at least free until regNeededUntil - if (maxPartialReg == null || availableReg == hint || (usePos[number] > usePos[maxPartialReg.number] && maxPartialReg != hint)) { + if (maxPartialReg == null || availableReg.equals(hint) || (usePos[number] > usePos[maxPartialReg.number] && !maxPartialReg.equals(hint))) { maxPartialReg = availableReg; } } @@ -676,7 +676,7 @@ splitPos = usePos[reg.number]; interval.assignLocation(reg.asValue(interval.kind())); - if (GraalOptions.TraceLinearScanLevel >= 2) { + if (TraceLinearScanLevel.getValue() >= 2) { TTY.println("selected register %d", reg.number); } @@ -702,7 +702,7 @@ // Split an Interval and spill it to memory so that cur can be placed in a register void allocLockedRegister(Interval interval) { - if (GraalOptions.TraceLinearScanLevel >= 2) { + if (TraceLinearScanLevel.getValue() >= 2) { TTY.println("need to split and spill to get register for " + interval.logString(allocator)); } @@ -715,7 +715,7 @@ spillCollectActiveAny(); spillCollectInactiveAny(interval); - if (GraalOptions.TraceLinearScanLevel >= 4) { + if (TraceLinearScanLevel.getValue() >= 4) { TTY.println(" state of registers:"); for (Register reg : availableRegs) { int i = reg.number; @@ -748,7 +748,7 @@ if (reg == null || usePos[reg.number] <= firstUsage) { // the first use of cur is later than the spilling position -> spill cur - if (GraalOptions.TraceLinearScanLevel >= 4) { + if (TraceLinearScanLevel.getValue() >= 4) { TTY.println("able to spill current interval. firstUsage(register): %d, usePos: %d", firstUsage, reg == null ? 0 : usePos[reg.number]); } @@ -767,7 +767,7 @@ int splitPos = blockPos[reg.number]; - if (GraalOptions.TraceLinearScanLevel >= 4) { + if (TraceLinearScanLevel.getValue() >= 4) { TTY.println("decided to use register %d", reg.number); } assert splitPos > 0 : "invalid splitPos"; @@ -796,7 +796,7 @@ if (isOdd(pos)) { // the current instruction is a call that blocks all registers if (pos < allocator.maxOpId() && allocator.hasCall(pos + 1) && interval.to() > pos + 1) { - if (GraalOptions.TraceLinearScanLevel >= 4) { + if (TraceLinearScanLevel.getValue() >= 4) { TTY.println(" free register cannot be available because all registers blocked by following call"); } @@ -888,11 +888,11 @@ Interval interval = currentInterval; boolean result = true; - if (GraalOptions.TraceLinearScanLevel >= 2) { + if (TraceLinearScanLevel.getValue() >= 2) { TTY.println("+++++ activating interval " + interval.logString(allocator)); } - if (GraalOptions.TraceLinearScanLevel >= 4) { + if (TraceLinearScanLevel.getValue() >= 4) { TTY.println(" splitParent: %s, insertMoveWhenActivated: %b", interval.splitParent().operandNumber, interval.insertMoveWhenActivated()); } @@ -901,7 +901,7 @@ // activating an interval that has a stack slot assigned . split it at first use // position // used for method parameters - if (GraalOptions.TraceLinearScanLevel >= 4) { + if (TraceLinearScanLevel.getValue() >= 4) { TTY.println(" interval has spill slot assigned (method parameter) . split it before first use"); } splitStackInterval(interval); @@ -911,7 +911,7 @@ if (interval.location() == null) { // interval has not assigned register . normal allocation // (this is the normal case for most intervals) - if (GraalOptions.TraceLinearScanLevel >= 4) { + if (TraceLinearScanLevel.getValue() >= 4) { TTY.println(" normal allocation of register"); } @@ -937,7 +937,7 @@ assert interval.isSplitChild(); assert interval.currentSplitChild() != null; assert !interval.currentSplitChild().operand.equals(operand) : "cannot insert move between same interval"; - if (GraalOptions.TraceLinearScanLevel >= 4) { + if (TraceLinearScanLevel.getValue() >= 4) { TTY.println("Inserting move from interval %d to %d because insertMoveWhenActivated is set", interval.currentSplitChild().operandNumber, interval.operandNumber); } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/MoveResolver.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/MoveResolver.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/MoveResolver.java Fri Jun 07 14:15:38 2013 +0200 @@ -23,6 +23,7 @@ package com.oracle.graal.compiler.alloc; import static com.oracle.graal.api.code.ValueUtil.*; +import static com.oracle.graal.phases.GraalOptions.*; import java.util.*; @@ -30,7 +31,6 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.debug.*; import com.oracle.graal.lir.*; -import com.oracle.graal.phases.*; /** */ @@ -201,7 +201,7 @@ insertionBuffer.append(insertIdx, allocator.ir.spillMoveFactory.createMove(toOpr, fromOpr)); - if (GraalOptions.TraceLinearScanLevel >= 4) { + if (TraceLinearScanLevel.getValue() >= 4) { TTY.println("MoveResolver: inserted move from %d (%s) to %d (%s)", fromInterval.operandNumber, fromInterval.location(), toInterval.operandNumber, toInterval.location()); } } @@ -213,7 +213,7 @@ AllocatableValue toOpr = toInterval.operand; insertionBuffer.append(insertIdx, allocator.ir.spillMoveFactory.createMove(toOpr, fromOpr)); - if (GraalOptions.TraceLinearScanLevel >= 4) { + if (TraceLinearScanLevel.getValue() >= 4) { TTY.print("MoveResolver: inserted move from constant %s to %d (%s)", fromOpr, toInterval.operandNumber, toInterval.location()); } } @@ -285,7 +285,7 @@ } spillInterval.assignLocation(spillSlot); - if (GraalOptions.TraceLinearScanLevel >= 4) { + if (TraceLinearScanLevel.getValue() >= 4) { TTY.println("created new Interval %s for spilling", spillInterval.operand); } @@ -327,7 +327,7 @@ } void addMapping(Interval fromInterval, Interval toInterval) { - if (GraalOptions.TraceLinearScanLevel >= 4) { + if (TraceLinearScanLevel.getValue() >= 4) { TTY.println("MoveResolver: adding mapping from interval %d (%s) to interval %d (%s)", fromInterval.operandNumber, fromInterval.location(), toInterval.operandNumber, toInterval.location()); } @@ -339,7 +339,7 @@ } void addMapping(Value fromOpr, Interval toInterval) { - if (GraalOptions.TraceLinearScanLevel >= 4) { + if (TraceLinearScanLevel.getValue() >= 4) { TTY.println("MoveResolver: adding mapping from %s to %d (%s)", fromOpr, toInterval.operandNumber, toInterval.location()); } assert isConstant(fromOpr) : "only for constants"; diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/RegisterVerifier.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/RegisterVerifier.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/RegisterVerifier.java Fri Jun 07 14:15:38 2013 +0200 @@ -23,6 +23,7 @@ package com.oracle.graal.compiler.alloc; import static com.oracle.graal.api.code.ValueUtil.*; +import static com.oracle.graal.phases.GraalOptions.*; import java.util.*; @@ -33,7 +34,6 @@ import com.oracle.graal.lir.*; import com.oracle.graal.lir.LIRInstruction.*; import com.oracle.graal.nodes.cfg.*; -import com.oracle.graal.phases.*; import com.oracle.graal.phases.util.*; /** @@ -92,7 +92,7 @@ } private void processBlock(Block block) { - if (GraalOptions.TraceLinearScanLevel >= 2) { + if (TraceLinearScanLevel.getValue() >= 2) { TTY.println(); TTY.println("processBlock B%d", block.getId()); } @@ -100,7 +100,7 @@ // must copy state because it is modified Interval[] inputState = copy(stateForBlock(block)); - if (GraalOptions.TraceLinearScanLevel >= 4) { + if (TraceLinearScanLevel.getValue() >= 4) { TTY.println("Input-State of intervals:"); TTY.print(" "); for (int i = 0; i < stateSize(); i++) { @@ -142,7 +142,7 @@ savedStateCorrect = false; savedState[i] = null; - if (GraalOptions.TraceLinearScanLevel >= 4) { + if (TraceLinearScanLevel.getValue() >= 4) { TTY.println("processSuccessor B%d: invalidating slot %d", block.getId(), i); } } @@ -151,12 +151,12 @@ if (savedStateCorrect) { // already processed block with correct inputState - if (GraalOptions.TraceLinearScanLevel >= 2) { + if (TraceLinearScanLevel.getValue() >= 2) { TTY.println("processSuccessor B%d: previous visit already correct", block.getId()); } } else { // must re-visit this block - if (GraalOptions.TraceLinearScanLevel >= 2) { + if (TraceLinearScanLevel.getValue() >= 2) { TTY.println("processSuccessor B%d: must re-visit because input state changed", block.getId()); } addToWorkList(block); @@ -164,7 +164,7 @@ } else { // block was not processed before, so set initial inputState - if (GraalOptions.TraceLinearScanLevel >= 2) { + if (TraceLinearScanLevel.getValue() >= 2) { TTY.println("processSuccessor B%d: initial visit", block.getId()); } @@ -182,11 +182,11 @@ Register reg = asRegister(location); int regNum = reg.number; if (interval != null) { - if (GraalOptions.TraceLinearScanLevel >= 4) { + if (TraceLinearScanLevel.getValue() >= 4) { TTY.println(" %s = %s", reg, interval.operand); } } else if (inputState[regNum] != null) { - if (GraalOptions.TraceLinearScanLevel >= 4) { + if (TraceLinearScanLevel.getValue() >= 4) { TTY.println(" %s = null", reg); } } @@ -209,7 +209,7 @@ for (int i = 0; i < ops.size(); i++) { final LIRInstruction op = ops.get(i); - if (GraalOptions.TraceLinearScanLevel >= 4) { + if (TraceLinearScanLevel.getValue() >= 4) { TTY.println(op.toStringWithIdPrefix()); } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java Fri Jun 07 14:15:38 2013 +0200 @@ -26,6 +26,7 @@ import static com.oracle.graal.api.code.ValueUtil.*; import static com.oracle.graal.api.meta.Value.*; import static com.oracle.graal.lir.LIRValueUtil.*; +import static com.oracle.graal.phases.GraalOptions.*; import java.util.*; import java.util.Map.Entry; @@ -46,7 +47,6 @@ import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.virtual.*; -import com.oracle.graal.phases.*; import com.oracle.graal.phases.util.*; /** @@ -203,7 +203,7 @@ return value; } - protected LabelRef getLIRBlock(FixedNode b) { + public LabelRef getLIRBlock(FixedNode b) { Block result = lir.cfg.blockFor(b); int suxIndex = currentBlock.getSuccessors().indexOf(result); assert suxIndex != -1 : "Block not in successor list of current block"; @@ -259,8 +259,7 @@ } public void append(LIRInstruction op) { - assert LIRVerifier.verify(op); - if (GraalOptions.PrintIRWithLIR && !TTY.isSuppressed()) { + if (PrintIRWithLIR.getValue() && !TTY.isSuppressed()) { if (currentInstruction != null && lastInstructionPrinted != currentInstruction) { lastInstructionPrinted = currentInstruction; InstructionPrinter ip = new InstructionPrinter(TTY.out()); @@ -269,11 +268,12 @@ TTY.println(op.toStringWithIdPrefix()); TTY.println(); } + assert LIRVerifier.verify(op); lir.lir(currentBlock).add(op); } public void doBlock(Block block) { - if (GraalOptions.PrintIRWithLIR) { + if (PrintIRWithLIR.getValue()) { TTY.print(block.toString()); } @@ -284,7 +284,7 @@ append(new LabelOp(new Label(), block.isAligned())); - if (GraalOptions.TraceLIRGeneratorLevel >= 1) { + if (TraceLIRGeneratorLevel.getValue() >= 1) { TTY.println("BEGIN Generating LIR for block B" + block.getId()); } @@ -315,12 +315,12 @@ } } } - if (GraalOptions.TraceLIRGeneratorLevel >= 2) { + if (TraceLIRGeneratorLevel.getValue() >= 2) { if (fs == null) { TTY.println("STATE RESET"); } else { TTY.println("STATE CHANGE (singlePred)"); - if (GraalOptions.TraceLIRGeneratorLevel >= 3) { + if (TraceLIRGeneratorLevel.getValue() >= 3) { TTY.println(fs.toString(Node.Verbosity.Debugger)); } } @@ -331,7 +331,7 @@ List nodes = lir.nodesFor(block); for (int i = 0; i < nodes.size(); i++) { Node instr = nodes.get(i); - if (GraalOptions.TraceLIRGeneratorLevel >= 3) { + if (TraceLIRGeneratorLevel.getValue() >= 3) { TTY.println("LIRGen for " + instr); } FrameState stateAfter = null; @@ -358,9 +358,9 @@ if (stateAfter != null) { lastState = stateAfter; assert checkStateReady(lastState); - if (GraalOptions.TraceLIRGeneratorLevel >= 2) { + if (TraceLIRGeneratorLevel.getValue() >= 2) { TTY.println("STATE CHANGE"); - if (GraalOptions.TraceLIRGeneratorLevel >= 3) { + if (TraceLIRGeneratorLevel.getValue() >= 3) { TTY.println(stateAfter.toString(Node.Verbosity.Debugger)); } } @@ -373,7 +373,7 @@ emitJump(getLIRBlock((FixedNode) successors.first())); } - if (GraalOptions.TraceLIRGeneratorLevel >= 1) { + if (TraceLIRGeneratorLevel.getValue() >= 1) { TTY.println("END Generating LIR for block B" + block.getId()); } @@ -384,7 +384,7 @@ blockLastState.put(block, lastState); currentBlock = null; - if (GraalOptions.PrintIRWithLIR) { + if (PrintIRWithLIR.getValue()) { TTY.println(); } } @@ -414,7 +414,7 @@ } private void doRoot(ValueNode instr) { - if (GraalOptions.TraceLIRGeneratorLevel >= 2) { + if (TraceLIRGeneratorLevel.getValue() >= 2) { TTY.println("Emitting LIR for instruction " + instr); } currentInstruction = instr; @@ -484,7 +484,7 @@ } private void moveToPhi(MergeNode merge, AbstractEndNode pred) { - if (GraalOptions.TraceLIRGeneratorLevel >= 1) { + if (TraceLIRGeneratorLevel.getValue() >= 1) { TTY.println("MOVE TO PHI from " + pred + " to " + merge); } PhiResolver resolver = new PhiResolver(this); @@ -660,7 +660,7 @@ @Override public Variable emitForeignCall(ForeignCallLinkage linkage, DeoptimizingNode info, Value... args) { - LIRFrameState state = info != null ? state(info) : null; + LIRFrameState state = !linkage.canDeoptimize() ? null : stateFor(info.getDeoptimizationState(), info.getDeoptimizationReason()); // move the arguments into the correct location CallingConvention linkageCc = linkage.getCallingConvention(); @@ -707,7 +707,7 @@ int switchRangeCount = switchRangeCount(x); if (switchRangeCount == 0) { emitJump(getLIRBlock(x.defaultSuccessor())); - } else if (switchRangeCount >= GraalOptions.MinimumJumpTableSize && keyCount / (double) valueRange >= GraalOptions.MinTableSwitchDensity) { + } else if (switchRangeCount >= MinimumJumpTableSize.getValue() && keyCount / (double) valueRange >= MinTableSwitchDensity.getValue()) { int minValue = x.keyAt(0).asInt(); assert valueRange < Integer.MAX_VALUE; LabelRef[] targets = new LabelRef[(int) valueRange]; @@ -718,7 +718,7 @@ targets[x.keyAt(i).asInt() - minValue] = getLIRBlock(x.keySuccessor(i)); } emitTableSwitch(minValue, defaultTarget, targets, value); - } else if (keyCount / switchRangeCount >= GraalOptions.RangeTestsSwitchDensity) { + } else if (keyCount / switchRangeCount >= RangeTestsSwitchDensity.getValue()) { emitSwitchRanges(x, switchRangeCount, value, defaultTarget); } else { emitSequentialSwitch(x, value, defaultTarget); diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/HighTier.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/HighTier.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/HighTier.java Fri Jun 07 14:15:38 2013 +0200 @@ -22,6 +22,8 @@ */ package com.oracle.graal.compiler.phases; +import static com.oracle.graal.phases.GraalOptions.*; + import com.oracle.graal.loop.phases.*; import com.oracle.graal.nodes.spi.Lowerable.LoweringType; import com.oracle.graal.phases.*; @@ -32,39 +34,40 @@ public class HighTier extends PhaseSuite { public HighTier() { - if (GraalOptions.FullUnroll) { - addPhase(new LoopFullUnrollPhase()); + CanonicalizerPhase canonicalizer = new CanonicalizerPhase(OptCanonicalizeReads.getValue()); + + if (FullUnroll.getValue()) { + addPhase(new LoopFullUnrollPhase(OptCanonicalizeReads.getValue())); } - if (GraalOptions.OptTailDuplication) { + if (OptTailDuplication.getValue()) { addPhase(new TailDuplicationPhase()); } - if (GraalOptions.PartialEscapeAnalysis) { - addPhase(new PartialEscapeAnalysisPhase(true, GraalOptions.OptEarlyReadElimination)); + if (PartialEscapeAnalysis.getValue()) { + addPhase(new PartialEscapeAnalysisPhase(true, OptEarlyReadElimination.getValue(), canonicalizer)); } - if (GraalOptions.OptConvertDeoptsToGuards) { + if (OptConvertDeoptsToGuards.getValue()) { addPhase(new ConvertDeoptimizeToGuardPhase()); } addPhase(new LockEliminationPhase()); - if (GraalOptions.OptLoopTransform) { + if (OptLoopTransform.getValue()) { addPhase(new LoopTransformHighPhase()); addPhase(new LoopTransformLowPhase()); } addPhase(new RemoveValueProxyPhase()); - if (GraalOptions.CullFrameStates) { + if (CullFrameStates.getValue()) { addPhase(new CullFrameStatesPhase()); } - if (GraalOptions.OptCanonicalizer) { - addPhase(new CanonicalizerPhase()); + if (OptCanonicalizer.getValue()) { + addPhase(canonicalizer); } addPhase(new LoweringPhase(LoweringType.BEFORE_GUARDS)); } - } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/MidTier.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/MidTier.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/MidTier.java Fri Jun 07 14:15:38 2013 +0200 @@ -22,6 +22,8 @@ */ package com.oracle.graal.compiler.phases; +import static com.oracle.graal.phases.GraalOptions.*; + import com.oracle.graal.loop.phases.*; import com.oracle.graal.phases.*; import com.oracle.graal.phases.common.*; @@ -30,41 +32,43 @@ public class MidTier extends PhaseSuite { public MidTier() { - if (GraalOptions.OptPushThroughPi) { + CanonicalizerPhase canonicalizer = new CanonicalizerPhase(OptCanonicalizeReads.getValue()); + + if (OptPushThroughPi.getValue()) { addPhase(new PushThroughPiPhase()); - if (GraalOptions.OptCanonicalizer) { - addPhase(new CanonicalizerPhase()); + if (OptCanonicalizer.getValue()) { + addPhase(canonicalizer); } } - if (GraalOptions.OptFloatingReads) { - IncrementalCanonicalizerPhase canonicalizer = new IncrementalCanonicalizerPhase<>(); - canonicalizer.addPhase(new FloatingReadPhase()); - addPhase(canonicalizer); - if (GraalOptions.OptReadElimination) { + if (OptFloatingReads.getValue()) { + IncrementalCanonicalizerPhase incCanonicalizer = new IncrementalCanonicalizerPhase<>(); + incCanonicalizer.addPhase(new FloatingReadPhase()); + addPhase(incCanonicalizer); + if (OptReadElimination.getValue()) { addPhase(new ReadEliminationPhase()); } } addPhase(new RemoveValueProxyPhase()); - if (GraalOptions.OptCanonicalizer) { - addPhase(new CanonicalizerPhase()); + if (OptCanonicalizer.getValue()) { + addPhase(canonicalizer); } - if (GraalOptions.OptEliminatePartiallyRedundantGuards) { + if (OptEliminatePartiallyRedundantGuards.getValue()) { addPhase(new EliminatePartiallyRedundantGuardsPhase(false, true)); } - if (GraalOptions.ConditionalElimination && GraalOptions.OptCanonicalizer) { + if (ConditionalElimination.getValue() && OptCanonicalizer.getValue()) { addPhase(new IterativeConditionalEliminationPhase()); } - if (GraalOptions.OptEliminatePartiallyRedundantGuards) { + if (OptEliminatePartiallyRedundantGuards.getValue()) { addPhase(new EliminatePartiallyRedundantGuardsPhase(true, true)); } - if (GraalOptions.OptCanonicalizer) { - addPhase(new CanonicalizerPhase()); + if (OptCanonicalizer.getValue()) { + addPhase(canonicalizer); } addPhase(new LoopSafepointEliminationPhase()); @@ -73,8 +77,8 @@ addPhase(new GuardLoweringPhase()); - if (GraalOptions.OptCanonicalizer) { - addPhase(new CanonicalizerPhase()); + if (OptCanonicalizer.getValue()) { + addPhase(canonicalizer); } } } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.graph/.checkstyle_checks.xml --- a/graal/com.oracle.graal.graph/.checkstyle_checks.xml Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.graph/.checkstyle_checks.xml Fri Jun 07 14:15:38 2013 +0200 @@ -203,6 +203,12 @@ + + + + + + diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java --- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java Fri Jun 07 14:15:38 2013 +0200 @@ -199,13 +199,13 @@ if (field.isAnnotationPresent(Node.Input.class)) { assert !field.isAnnotationPresent(Node.Successor.class) : "field cannot be both input and successor"; if (INPUT_LIST_CLASS.isAssignableFrom(type)) { - assert Modifier.isFinal(field.getModifiers()) : "NodeInputList input field " + field + " should be final"; - assert !Modifier.isPublic(field.getModifiers()) : "NodeInputList input field " + field + " should not be public"; + GraalInternalError.guarantee(Modifier.isFinal(field.getModifiers()), "NodeInputList input field %s should be final", field); + GraalInternalError.guarantee(!Modifier.isPublic(field.getModifiers()), "NodeInputList input field %s should not be public", field); inputListOffsets.add(offset); } else { - assert NODE_CLASS.isAssignableFrom(type) || type.isInterface() : "invalid input type: " + type; - assert !Modifier.isFinal(field.getModifiers()) : "Node input field " + field + " should not be final"; - assert Modifier.isPrivate(field.getModifiers()) : "Node input field " + field + " should be private"; + GraalInternalError.guarantee(NODE_CLASS.isAssignableFrom(type) || type.isInterface(), "invalid input type: %s", type); + GraalInternalError.guarantee(!Modifier.isFinal(field.getModifiers()), "Node input field %s should not be final", field); + GraalInternalError.guarantee(Modifier.isPrivate(field.getModifiers()), "Node input field %s should be private", field); inputOffsets.add(offset); } if (field.getAnnotation(Node.Input.class).notDataflow()) { @@ -213,19 +213,19 @@ } } else if (field.isAnnotationPresent(Node.Successor.class)) { if (SUCCESSOR_LIST_CLASS.isAssignableFrom(type)) { - assert Modifier.isFinal(field.getModifiers()) : "NodeSuccessorList successor field " + field + " should be final"; - assert !Modifier.isPublic(field.getModifiers()) : "NodeSuccessorList successor field " + field + " should not be public"; + GraalInternalError.guarantee(Modifier.isFinal(field.getModifiers()), "NodeSuccessorList successor field % should be final", field); + GraalInternalError.guarantee(!Modifier.isPublic(field.getModifiers()), "NodeSuccessorList successor field %s should not be public", field); successorListOffsets.add(offset); } else { - assert NODE_CLASS.isAssignableFrom(type) : "invalid successor type: " + type; - assert !Modifier.isFinal(field.getModifiers()) : "Node successor field " + field + " should not be final"; - assert Modifier.isPrivate(field.getModifiers()) : "Node successor field " + field + " should be private"; + GraalInternalError.guarantee(NODE_CLASS.isAssignableFrom(type), "invalid successor type: %s", type); + GraalInternalError.guarantee(!Modifier.isFinal(field.getModifiers()), "Node successor field %s should not be final", field); + GraalInternalError.guarantee(Modifier.isPrivate(field.getModifiers()), "Node successor field %s should be private", field); successorOffsets.add(offset); } } else { - assert !NODE_CLASS.isAssignableFrom(type) || field.getName().equals("Null") : "suspicious node field: " + field; - assert !INPUT_LIST_CLASS.isAssignableFrom(type) : "suspicious node input list field: " + field; - assert !SUCCESSOR_LIST_CLASS.isAssignableFrom(type) : "suspicious node successor list field: " + field; + GraalInternalError.guarantee(!NODE_CLASS.isAssignableFrom(type) || field.getName().equals("Null"), "suspicious node field: %s", field); + GraalInternalError.guarantee(!INPUT_LIST_CLASS.isAssignableFrom(type), "suspicious node input list field: %s", field); + GraalInternalError.guarantee(!SUCCESSOR_LIST_CLASS.isAssignableFrom(type), "suspicious node successor list field: %s", field); dataOffsets.add(offset); } } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64DeoptimizeOp.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64DeoptimizeOp.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64DeoptimizeOp.java Fri Jun 07 14:15:38 2013 +0200 @@ -30,7 +30,6 @@ import com.oracle.graal.asm.amd64.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.lir.*; -import com.oracle.graal.lir.LIRInstruction.Opcode; import com.oracle.graal.lir.amd64.*; import com.oracle.graal.lir.asm.*; diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java Fri Jun 07 14:15:38 2013 +0200 @@ -50,7 +50,6 @@ import com.oracle.graal.lir.asm.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.cfg.*; -import com.oracle.graal.phases.*; /** * HotSpot AMD64 specific backend. @@ -75,7 +74,7 @@ * the current frame */ protected static void emitStackOverflowCheck(TargetMethodAssembler tasm, boolean afterFrameInit) { - if (GraalOptions.StackShadowPages > 0) { + if (StackShadowPages.getValue() > 0) { AMD64MacroAssembler asm = (AMD64MacroAssembler) tasm.asm; int frameSize = tasm.frameMap.frameSize(); @@ -83,7 +82,7 @@ int lastFramePage = frameSize / unsafe.pageSize(); // emit multiple stack bangs for methods with frames larger than a page for (int i = 0; i <= lastFramePage; i++) { - int disp = (i + GraalOptions.StackShadowPages) * unsafe.pageSize(); + int disp = (i + StackShadowPages.getValue()) * unsafe.pageSize(); if (afterFrameInit) { disp -= frameSize; } @@ -112,7 +111,7 @@ emitStackOverflowCheck(tasm, false); } asm.decrementq(rsp, frameSize); - if (GraalOptions.ZapStackOnMethodEntry) { + if (ZapStackOnMethodEntry.getValue()) { final int intSize = 4; for (int i = 0; i < frameSize / intSize; ++i) { asm.movl(new AMD64Address(rsp, i * intSize), 0xC1C1C1C1); @@ -158,7 +157,7 @@ AMD64HotSpotLIRGenerator gen = (AMD64HotSpotLIRGenerator) lirGen; FrameMap frameMap = gen.frameMap; LIR lir = gen.lir; - boolean omitFrame = CanOmitFrame && !frameMap.frameNeedsAllocating() && !lir.hasArgInCallerFrame(); + boolean omitFrame = CanOmitFrame.getValue() && !frameMap.frameNeedsAllocating() && !lir.hasArgInCallerFrame(); Stub stub = gen.getStub(); AbstractAssembler masm = createAssembler(frameMap); diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotCRuntimeCallEpilogueOp.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotCRuntimeCallEpilogueOp.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotCRuntimeCallEpilogueOp.java Fri Jun 07 14:15:38 2013 +0200 @@ -27,7 +27,7 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.asm.amd64.*; import com.oracle.graal.hotspot.*; -import com.oracle.graal.lir.LIRInstruction.Opcode; +import com.oracle.graal.lir.*; import com.oracle.graal.lir.amd64.*; import com.oracle.graal.lir.asm.*; diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotCRuntimeCallPrologueOp.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotCRuntimeCallPrologueOp.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotCRuntimeCallPrologueOp.java Fri Jun 07 14:15:38 2013 +0200 @@ -27,11 +27,11 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.asm.amd64.*; -import com.oracle.graal.lir.LIRInstruction.Opcode; +import com.oracle.graal.lir.*; import com.oracle.graal.lir.amd64.*; import com.oracle.graal.lir.asm.*; -@Opcode("CRUNTIME_CALL_PROLOGUE") +@Opcode final class AMD64HotSpotCRuntimeCallPrologueOp extends AMD64LIRInstruction { @Override diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotDeoptimizeCallerOp.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotDeoptimizeCallerOp.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotDeoptimizeCallerOp.java Fri Jun 07 14:15:38 2013 +0200 @@ -29,7 +29,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.amd64.*; import com.oracle.graal.hotspot.*; -import com.oracle.graal.lir.LIRInstruction.Opcode; +import com.oracle.graal.lir.*; import com.oracle.graal.lir.amd64.*; import com.oracle.graal.lir.asm.*; diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotEpilogueOp.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotEpilogueOp.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotEpilogueOp.java Fri Jun 07 14:15:38 2013 +0200 @@ -53,7 +53,7 @@ masm.movq(rbp, (AMD64Address) tasm.asAddress(savedRbp)); } else { Register framePointer = asRegister(savedRbp); - if (framePointer != rbp) { + if (!framePointer.equals(rbp)) { masm.movq(rbp, framePointer); } } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotJumpToExceptionHandlerInCallerOp.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotJumpToExceptionHandlerInCallerOp.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotJumpToExceptionHandlerInCallerOp.java Fri Jun 07 14:15:38 2013 +0200 @@ -31,7 +31,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.amd64.*; import com.oracle.graal.asm.amd64.AMD64Assembler.ConditionFlag; -import com.oracle.graal.lir.LIRInstruction.Opcode; +import com.oracle.graal.lir.*; import com.oracle.graal.lir.asm.*; /** diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java Fri Jun 07 14:15:38 2013 +0200 @@ -45,9 +45,18 @@ import com.oracle.graal.lir.StandardOp.ParametersOp; import com.oracle.graal.lir.StandardOp.PlaceholderOp; import com.oracle.graal.lir.amd64.*; +import com.oracle.graal.lir.amd64.AMD64ControlFlow.CondMoveOp; +import com.oracle.graal.lir.amd64.AMD64Move.CompareAndSwapCompressedOp; import com.oracle.graal.lir.amd64.AMD64Move.CompareAndSwapOp; +import com.oracle.graal.lir.amd64.AMD64Move.LoadCompressedOop; +import com.oracle.graal.lir.amd64.AMD64Move.LoadOp; import com.oracle.graal.lir.amd64.AMD64Move.MoveFromRegOp; +import com.oracle.graal.lir.amd64.AMD64Move.StoreCompressedOop; +import com.oracle.graal.lir.amd64.AMD64Move.StoreConstantOp; +import com.oracle.graal.lir.amd64.AMD64Move.StoreOp; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.calc.*; +import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind; /** @@ -211,8 +220,7 @@ @Override public Variable emitForeignCall(ForeignCallLinkage linkage, DeoptimizingNode info, Value... args) { Stub stub = getStub(); - HotSpotForeignCallLinkage hsLinkage = (HotSpotForeignCallLinkage) linkage; - boolean destroysRegisters = hsLinkage.destroysRegisters(); + boolean destroysRegisters = linkage.destroysRegisters(); AMD64SaveRegistersOp save = null; StackSlot[] savedRegisterLocations = null; @@ -234,7 +242,7 @@ Variable result; - if (!hsLinkage.isLeaf()) { + if (linkage.canDeoptimize()) { assert info != null; append(new AMD64HotSpotCRuntimeCallPrologueOp()); result = super.emitForeignCall(linkage, info, args); @@ -391,4 +399,78 @@ op.savedRbp = savedRbp; } } + + private static boolean isCompressCandidate(DeoptimizingNode access) { + return access != null && ((HeapAccess) access).compress(); + } + + @Override + public Variable emitLoad(Kind kind, Value address, DeoptimizingNode access) { + AMD64AddressValue loadAddress = asAddressValue(address); + Variable result = newVariable(kind); + assert access == null || access instanceof HeapAccess; + if (runtime().config.useCompressedOops && isCompressCandidate(access)) { + assert kind == Kind.Object; + Variable scratch = newVariable(Kind.Long); + append(new LoadCompressedOop(kind, result, scratch, loadAddress, access != null ? state(access) : null, runtime().config.narrowOopBase, runtime().config.narrowOopShift, + runtime().config.logMinObjAlignment)); + } else { + append(new LoadOp(kind, result, loadAddress, access != null ? state(access) : null)); + } + return result; + } + + @Override + public void emitStore(Kind kind, Value address, Value inputVal, DeoptimizingNode access) { + AMD64AddressValue storeAddress = asAddressValue(address); + LIRFrameState state = access != null ? state(access) : null; + if (isConstant(inputVal)) { + Constant c = asConstant(inputVal); + if (canStoreConstant(c)) { + append(new StoreConstantOp(kind, storeAddress, c, state, runtime().config.useCompressedOops && isCompressCandidate(access))); + return; + } + } + Variable input = load(inputVal); + if (runtime().config.useCompressedOops && isCompressCandidate(access)) { + assert kind == Kind.Object; + Variable scratch = newVariable(Kind.Long); + append(new StoreCompressedOop(kind, storeAddress, input, scratch, state, runtime().config.narrowOopBase, runtime().config.narrowOopShift, runtime().config.logMinObjAlignment)); + } else { + append(new StoreOp(kind, storeAddress, input, state)); + } + } + + @Override + public void visitCompareAndSwap(CompareAndSwapNode node) { + Kind kind = node.newValue().kind(); + assert kind == node.expected().kind(); + + Value expected = loadNonConst(operand(node.expected())); + Variable newValue = load(operand(node.newValue())); + + AMD64AddressValue address; + int displacement = node.displacement(); + Value index = operand(node.offset()); + if (isConstant(index) && NumUtil.isInt(asConstant(index).asLong() + displacement)) { + assert !runtime.needsDataPatch(asConstant(index)); + displacement += (int) asConstant(index).asLong(); + address = new AMD64AddressValue(kind, load(operand(node.object())), displacement); + } else { + address = new AMD64AddressValue(kind, load(operand(node.object())), load(index), Scale.Times1, displacement); + } + + RegisterValue raxRes = AMD64.rax.asValue(kind); + emitMove(raxRes, expected); + if (runtime().config.useCompressedOops && node.compress()) { + assert kind == Kind.Object; + Variable scratch = newVariable(Kind.Long); + append(new CompareAndSwapCompressedOp(raxRes, address, raxRes, newValue, scratch, runtime().config.narrowOopBase, runtime().config.narrowOopShift, runtime().config.logMinObjAlignment)); + } else { + append(new CompareAndSwapOp(raxRes, address, raxRes, newValue)); + } + Variable result = newVariable(node.kind()); + append(new CondMoveOp(result, Condition.EQ, load(Constant.TRUE), Constant.FALSE)); + setResult(node, result); + } } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotPatchReturnAddressOp.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotPatchReturnAddressOp.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotPatchReturnAddressOp.java Fri Jun 07 14:15:38 2013 +0200 @@ -28,7 +28,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.amd64.*; -import com.oracle.graal.lir.LIRInstruction.Opcode; +import com.oracle.graal.lir.*; import com.oracle.graal.lir.amd64.*; import com.oracle.graal.lir.asm.*; diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRegisterConfig.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRegisterConfig.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRegisterConfig.java Fri Jun 07 14:15:38 2013 +0200 @@ -23,6 +23,7 @@ package com.oracle.graal.hotspot.amd64; import static com.oracle.graal.amd64.AMD64.*; +import static com.oracle.graal.phases.GraalOptions.*; import java.util.*; @@ -32,13 +33,12 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; import com.oracle.graal.hotspot.*; -import com.oracle.graal.phases.*; public class AMD64HotSpotRegisterConfig implements RegisterConfig { private final Architecture architecture; - private final Register[] allocatable = initAllocatable(); + private final Register[] allocatable; private final HashMap categorized = new HashMap<>(); @@ -86,25 +86,34 @@ throw new IllegalArgumentException("register " + name + " is not allocatable"); } - private static Register[] initAllocatable() { + private static Register[] initAllocatable(boolean reserveForHeapBase) { + Register[] registers = null; // @formatter:off - Register[] allocatable = { + if (reserveForHeapBase) { + registers = new Register[] { + rax, rbx, rcx, rdx, /*rsp,*/ rbp, rsi, rdi, r8, r9, r10, r11, /*r12,*/ r13, r14, /*r15, */ + xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, + xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15 + }; + } else { + registers = new Register[] { rax, rbx, rcx, rdx, /*rsp,*/ rbp, rsi, rdi, r8, r9, r10, r11, r12, r13, r14, /*r15, */ xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15 - }; - // @formatter:on + }; + } + // @formatter:on - if (GraalOptions.RegisterPressure != null) { - String[] names = GraalOptions.RegisterPressure.split(","); + if (RegisterPressure.getValue() != null) { + String[] names = RegisterPressure.getValue().split(","); Register[] regs = new Register[names.length]; for (int i = 0; i < names.length; i++) { - regs[i] = findRegister(names[i], allocatable); + regs[i] = findRegister(names[i], registers); } return regs; } - return allocatable; + return registers; } public AMD64HotSpotRegisterConfig(Architecture architecture, HotSpotVMConfig config) { @@ -119,6 +128,7 @@ } csl = null; + allocatable = initAllocatable(config.useCompressedOops); attributesMap = RegisterAttributes.createMap(this, AMD64.allRegisters); } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotReturnOp.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotReturnOp.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotReturnOp.java Fri Jun 07 14:15:38 2013 +0200 @@ -26,7 +26,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.amd64.*; -import com.oracle.graal.lir.LIRInstruction.Opcode; +import com.oracle.graal.lir.*; import com.oracle.graal.lir.asm.*; /** diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRuntime.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRuntime.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRuntime.java Fri Jun 07 14:15:38 2013 +0200 @@ -24,6 +24,7 @@ import static com.oracle.graal.amd64.AMD64.*; import static com.oracle.graal.api.code.CallingConvention.Type.*; +import static com.oracle.graal.api.meta.LocationIdentity.*; import static com.oracle.graal.api.meta.Value.*; import static com.oracle.graal.hotspot.HotSpotBackend.*; import static com.oracle.graal.hotspot.HotSpotForeignCallLinkage.*; @@ -60,14 +61,14 @@ RegisterValue exception = rax.asValue(Kind.Object); RegisterValue exceptionPc = rdx.asValue(word); CallingConvention exceptionCc = new CallingConvention(0, ILLEGAL, exception, exceptionPc); - register(new HotSpotForeignCallLinkage(EXCEPTION_HANDLER, 0L, PRESERVES_REGISTERS, LEAF, exceptionCc)); - register(new HotSpotForeignCallLinkage(EXCEPTION_HANDLER_IN_CALLER, JUMP_ADDRESS, PRESERVES_REGISTERS, LEAF, exceptionCc)); + register(new HotSpotForeignCallLinkage(EXCEPTION_HANDLER, 0L, PRESERVES_REGISTERS, LEAF, exceptionCc, NOT_REEXECUTABLE, ANY_LOCATION)); + register(new HotSpotForeignCallLinkage(EXCEPTION_HANDLER_IN_CALLER, JUMP_ADDRESS, PRESERVES_REGISTERS, LEAF, exceptionCc, NOT_REEXECUTABLE, ANY_LOCATION)); // The x86 crypto stubs do callee saving - registerForeignCall(ENCRYPT_BLOCK, config.aescryptEncryptBlockStub, NativeCall, PRESERVES_REGISTERS, LEAF); - registerForeignCall(DECRYPT_BLOCK, config.aescryptDecryptBlockStub, NativeCall, PRESERVES_REGISTERS, LEAF); - registerForeignCall(ENCRYPT, config.cipherBlockChainingEncryptAESCryptStub, NativeCall, PRESERVES_REGISTERS, LEAF); - registerForeignCall(DECRYPT, config.cipherBlockChainingDecryptAESCryptStub, NativeCall, PRESERVES_REGISTERS, LEAF); + registerForeignCall(ENCRYPT_BLOCK, config.aescryptEncryptBlockStub, NativeCall, PRESERVES_REGISTERS, LEAF, NOT_REEXECUTABLE, ANY_LOCATION); + registerForeignCall(DECRYPT_BLOCK, config.aescryptDecryptBlockStub, NativeCall, PRESERVES_REGISTERS, LEAF, NOT_REEXECUTABLE, ANY_LOCATION); + registerForeignCall(ENCRYPT, config.cipherBlockChainingEncryptAESCryptStub, NativeCall, PRESERVES_REGISTERS, LEAF, NOT_REEXECUTABLE, ANY_LOCATION); + registerForeignCall(DECRYPT, config.cipherBlockChainingDecryptAESCryptStub, NativeCall, PRESERVES_REGISTERS, LEAF, NOT_REEXECUTABLE, ANY_LOCATION); convertSnippets = new AMD64ConvertSnippets.Templates(this, replacements, graalRuntime.getTarget()); super.registerReplacements(replacements); diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotUnwindOp.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotUnwindOp.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotUnwindOp.java Fri Jun 07 14:15:38 2013 +0200 @@ -31,7 +31,7 @@ import com.oracle.graal.asm.amd64.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.stubs.*; -import com.oracle.graal.lir.LIRInstruction.Opcode; +import com.oracle.graal.lir.*; import com.oracle.graal.lir.amd64.*; import com.oracle.graal.lir.asm.*; diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotspotDirectStaticCallOp.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotspotDirectStaticCallOp.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotspotDirectStaticCallOp.java Fri Jun 07 14:15:38 2013 +0200 @@ -27,7 +27,6 @@ import com.oracle.graal.asm.amd64.*; import com.oracle.graal.hotspot.bridge.*; import com.oracle.graal.lir.*; -import com.oracle.graal.lir.LIRInstruction.Opcode; import com.oracle.graal.lir.amd64.*; import com.oracle.graal.lir.amd64.AMD64Call.DirectCallOp; import com.oracle.graal.lir.asm.*; diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotspotDirectVirtualCallOp.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotspotDirectVirtualCallOp.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotspotDirectVirtualCallOp.java Fri Jun 07 14:15:38 2013 +0200 @@ -29,7 +29,6 @@ import com.oracle.graal.asm.amd64.*; import com.oracle.graal.hotspot.bridge.*; import com.oracle.graal.lir.*; -import com.oracle.graal.lir.LIRInstruction.Opcode; import com.oracle.graal.lir.amd64.*; import com.oracle.graal.lir.amd64.AMD64Call.DirectCallOp; import com.oracle.graal.lir.asm.*; diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64IndirectCallOp.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64IndirectCallOp.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64IndirectCallOp.java Fri Jun 07 14:15:38 2013 +0200 @@ -31,7 +31,6 @@ import com.oracle.graal.asm.amd64.*; import com.oracle.graal.hotspot.bridge.*; import com.oracle.graal.lir.*; -import com.oracle.graal.lir.LIRInstruction.Opcode; import com.oracle.graal.lir.amd64.*; import com.oracle.graal.lir.amd64.AMD64Call.IndirectCallOp; import com.oracle.graal.lir.asm.*; @@ -61,13 +60,13 @@ public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) { tasm.recordMark(Marks.MARK_INLINE_INVOKE); Register callReg = asRegister(targetAddress); - assert callReg != METHOD; + assert !callReg.equals(METHOD); AMD64Call.indirectCall(tasm, masm, callReg, callTarget, state); } @Override protected void verify() { super.verify(); - assert asRegister(metaspaceMethod) == METHOD; + assert asRegister(metaspaceMethod).equals(METHOD); } } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64SafepointOp.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64SafepointOp.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64SafepointOp.java Fri Jun 07 14:15:38 2013 +0200 @@ -32,7 +32,6 @@ import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.bridge.*; import com.oracle.graal.lir.*; -import com.oracle.graal.lir.LIRInstruction.Opcode; import com.oracle.graal.lir.amd64.*; import com.oracle.graal.lir.asm.*; import com.oracle.graal.nodes.spi.*; @@ -59,7 +58,7 @@ @Override public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler asm) { int pos = asm.codeBuffer.position(); - int offset = SafepointPollOffset % unsafe.pageSize(); + int offset = SafepointPollOffset.getValue() % unsafe.pageSize(); RegisterValue scratch = (RegisterValue) temp; if (config.isPollingPageFar) { asm.movq(scratch.getRegister(), config.safepointPollingAddress + offset); diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64TailcallOp.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64TailcallOp.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64TailcallOp.java Fri Jun 07 14:15:38 2013 +0200 @@ -27,7 +27,7 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.amd64.*; -import com.oracle.graal.lir.LIRInstruction.Opcode; +import com.oracle.graal.lir.*; import com.oracle.graal.lir.amd64.*; import com.oracle.graal.lir.asm.*; diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java Fri Jun 07 14:15:38 2013 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,14 +24,17 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.asm.*; -import com.oracle.graal.compiler.gen.*; -import com.oracle.graal.compiler.sparc.*; +import com.oracle.graal.asm.AbstractAssembler; +import com.oracle.graal.asm.sparc.SPARCAssembler; +import com.oracle.graal.compiler.gen.LIRGenerator; +import com.oracle.graal.compiler.sparc.SPARCLIRGenerator; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.meta.*; +import com.oracle.graal.hotspot.stubs.Stub; import com.oracle.graal.lir.*; import com.oracle.graal.lir.asm.*; import com.oracle.graal.nodes.*; +import static com.oracle.graal.phases.GraalOptions.*; /** * HotSpot SPARC specific backend. @@ -49,14 +52,44 @@ @Override protected AbstractAssembler createAssembler(FrameMap frameMap) { - // SPARC: Create assembler. - return null; + return new SPARCAssembler(target, frameMap.registerConfig); + } + + class HotSpotFrameContext implements FrameContext { + + final boolean isStub; + + HotSpotFrameContext(boolean isStub) { + this.isStub = isStub; + } + + @Override + public void enter(TargetMethodAssembler tasm) { + } + + @Override + public void leave(TargetMethodAssembler tasm) { + } } @Override public TargetMethodAssembler newAssembler(LIRGenerator lirGen, CompilationResult compilationResult) { - // SPARC: Create assembler. - return null; + SPARCHotSpotLIRGenerator gen = (SPARCHotSpotLIRGenerator) lirGen; + FrameMap frameMap = gen.frameMap; + LIR lir = gen.lir; + boolean omitFrame = CanOmitFrame.getValue() && !frameMap.frameNeedsAllocating() && !lir.hasArgInCallerFrame(); + + Stub stub = gen.getStub(); + AbstractAssembler masm = createAssembler(frameMap); + HotSpotFrameContext frameContext = omitFrame ? null : new HotSpotFrameContext(stub != null); + TargetMethodAssembler tasm = new TargetMethodAssembler(target, runtime(), frameMap, masm, frameContext, compilationResult); + tasm.setFrameSize(frameMap.frameSize()); + StackSlot deoptimizationRescueSlot = gen.deoptimizationRescueSlot; + if (deoptimizationRescueSlot != null && stub == null) { + tasm.compilationResult.setCustomStackAreaOffset(frameMap.offsetForStackSlot(deoptimizationRescueSlot)); + } + + return tasm; } @Override diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotGraalRuntime.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotGraalRuntime.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotGraalRuntime.java Fri Jun 07 14:15:38 2013 +0200 @@ -47,7 +47,7 @@ @Override protected TargetDescription createTarget() { // SPARC: Create target description. - return null; + throw new InternalError("NYI"); } @Override diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java Fri Jun 07 14:15:38 2013 +0200 @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.hotspot.sparc; + +import com.oracle.graal.api.code.CallingConvention; +import com.oracle.graal.api.code.CodeCacheProvider; +import com.oracle.graal.api.code.DeoptimizationAction; +import com.oracle.graal.api.code.StackSlot; +import com.oracle.graal.api.code.TargetDescription; +import com.oracle.graal.api.meta.DeoptimizationReason; +import com.oracle.graal.api.meta.Value; +import com.oracle.graal.compiler.sparc.SPARCLIRGenerator; +import com.oracle.graal.hotspot.HotSpotLIRGenerator; +import com.oracle.graal.hotspot.nodes.DirectCompareAndSwapNode; +import com.oracle.graal.hotspot.stubs.Stub; +import com.oracle.graal.lir.FrameMap; +import com.oracle.graal.lir.LIR; +import com.oracle.graal.nodes.StructuredGraph; +import com.oracle.graal.nodes.ValueNode; + +public class SPARCHotSpotLIRGenerator extends SPARCLIRGenerator implements HotSpotLIRGenerator { + + public StackSlot deoptimizationRescueSlot; + + public SPARCHotSpotLIRGenerator(StructuredGraph graph, + CodeCacheProvider runtime, TargetDescription target, + FrameMap frameMap, CallingConvention cc, LIR lir) { + super(graph, runtime, target, frameMap, cc, lir); + // TODO Auto-generated constructor stub + } + + @Override + public void emitTailcall(Value[] args, Value address) { + // TODO Auto-generated method stub + } + + @Override + public void emitDeoptimizeCaller(DeoptimizationAction action, + DeoptimizationReason reason) { + // TODO Auto-generated method stub + } + + @Override + public void emitPatchReturnAddress(ValueNode address) { + // TODO Auto-generated method stub + } + + @Override + public void emitJumpToExceptionHandlerInCaller(ValueNode handlerInCallerPc, + ValueNode exception, ValueNode exceptionPc) { + // TODO Auto-generated method stub + } + + @Override + public void visitDirectCompareAndSwap(DirectCompareAndSwapNode x) { + // TODO Auto-generated method stub + } + + @Override + public StackSlot getLockSlot(int lockDepth) { + // TODO Auto-generated method stub + return null; + } + + public Stub getStub() { + // TODO Auto-generated method stub + return null; + } + +} diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/AheadOfTimeCompilationTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/AheadOfTimeCompilationTest.java Fri Jun 07 14:15:38 2013 +0200 @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.hotspot.test; + +import static com.oracle.graal.api.code.CodeUtil.*; + +import org.junit.*; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.code.CallingConvention.Type; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.*; +import com.oracle.graal.compiler.test.*; +import com.oracle.graal.hotspot.phases.*; +import com.oracle.graal.java.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.extended.*; +import com.oracle.graal.phases.*; +import com.oracle.graal.phases.PhasePlan.PhasePosition; + +/** + * use + * + *

    + * mx unittest AheadOfTimeCompilationTest @-XX:CompileCommand='print,*AheadOfTimeCompilationTest.*'
    + * 
    + * + * to print disassembly. + */ +public class AheadOfTimeCompilationTest extends GraalCompilerTest { + + public static final Object STATICFINALOBJECT = new Object(); + + public static Object getStaticFinalObject() { + return AheadOfTimeCompilationTest.STATICFINALOBJECT; + } + + @Test + @Ignore + public void testStaticFinalObject1() { + StructuredGraph result2 = compile("getStaticFinalObject", true); + assert result2.getNodes().filter(ConstantNode.class).count() == 1; + assert result2.getNodes(FloatingReadNode.class).count() == 1; + } + + @Test + public void testStaticFinalObject2() { + StructuredGraph result1 = compile("getStaticFinalObject", false); + assert result1.getNodes().filter(ConstantNode.class).count() == 1; + assert result1.getNodes(FloatingReadNode.class).count() == 0; + } + + private StructuredGraph compile(String test, boolean compileAOT) { + StructuredGraph graph = parse(test); + ResolvedJavaMethod method = graph.method(); + + boolean originalSetting = GraalOptions.OptCanonicalizeReads.getValue(); + GraalOptions.OptCanonicalizeReads.setValue(!compileAOT); + PhasePlan phasePlan = new PhasePlan(); + final StructuredGraph graphCopy = graph.copy(); + GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(runtime, GraphBuilderConfiguration.getDefault(), OptimisticOptimizations.ALL); + phasePlan.addPhase(PhasePosition.AFTER_PARSING, graphBuilderPhase); + phasePlan.addPhase(PhasePosition.LOW_LEVEL, new WriteBarrierAdditionPhase()); + editPhasePlan(method, graph, phasePlan); + CallingConvention cc = getCallingConvention(runtime, Type.JavaCallee, graph.method(), false); + final CompilationResult compResult = GraalCompiler.compileGraph(graph, cc, method, runtime, replacements, backend, runtime().getTarget(), null, phasePlan, OptimisticOptimizations.ALL, + new SpeculationLog()); + addMethod(method, compResult, graphCopy); + + GraalOptions.OptCanonicalizeReads.setValue(originalSetting); + + return graph; + } +} diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/CompileTheWorldTest.java --- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/CompileTheWorldTest.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/CompileTheWorldTest.java Fri Jun 07 14:15:38 2013 +0200 @@ -26,6 +26,7 @@ import com.oracle.graal.compiler.test.*; import com.oracle.graal.hotspot.*; +import com.oracle.graal.phases.*; /** * Tests {@link CompileTheWorld} functionality. @@ -34,9 +35,11 @@ @Test public void testRtJar() throws Throwable { + boolean originalSetting = GraalOptions.ExitVMOnException.getValue(); // Compile a couple classes in rt.jar String file = System.getProperty("java.home") + "/lib/rt.jar"; new CompileTheWorld(file, 1, 5).compile(); + GraalOptions.ExitVMOnException.setValue(originalSetting); } } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/CompressedOopTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/CompressedOopTest.java Fri Jun 07 14:15:38 2013 +0200 @@ -0,0 +1,421 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.oracle.graal.hotspot.test; + +import java.lang.reflect.*; +import java.util.*; +import java.util.concurrent.atomic.*; + +import org.junit.*; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.api.runtime.*; +import com.oracle.graal.compiler.test.*; +import com.oracle.graal.hotspot.meta.*; + +/** + * The following tests perform object/array equality and assignments in various ways. The selected + * cases have been the problematic ones while implementing the Compressed Oops support. + */ + +public class CompressedOopTest extends GraalCompilerTest { + + private final MetaAccessProvider metaAccessProvider; + Object[] argsToBind; + + public CompressedOopTest() { + this.metaAccessProvider = Graal.getRequiredCapability(MetaAccessProvider.class); + } + + @Test + public void test() throws NoSuchMethodException, SecurityException, InvalidInstalledCodeException { + final Method fooMethod = CompressedOopTest.class.getMethod("fieldTest", Object.class, Object.class, Object.class); + final HotSpotResolvedJavaMethod fooJavaMethod = (HotSpotResolvedJavaMethod) metaAccessProvider.lookupJavaMethod(fooMethod); + final HotSpotInstalledCode fooCode = (HotSpotInstalledCode) getCode(fooJavaMethod, parse(fooMethod)); + argsToBind = new Object[]{fooCode}; + final Method benchmarkMethod = CompressedOopTest.class.getMethod("benchmark", HotSpotInstalledCode.class, Object.class, Object.class, Object.class); + final ResolvedJavaMethod benchmarkJavaMethod = metaAccessProvider.lookupJavaMethod(benchmarkMethod); + final HotSpotInstalledCode installedBenchmarkCode = (HotSpotInstalledCode) getCode(benchmarkJavaMethod, parse(benchmarkMethod)); + Container c1 = new Container(); + Assert.assertEquals(c1.b, installedBenchmarkCode.executeVarargs(argsToBind[0], c1, c1, c1)); + } + + @Test + public void test1() throws NoSuchMethodException, SecurityException, InvalidInstalledCodeException { + final Method fooMethod = CompressedOopTest.class.getMethod("arrayTest", Object.class, Object.class, Object.class); + final HotSpotResolvedJavaMethod fooJavaMethod = (HotSpotResolvedJavaMethod) metaAccessProvider.lookupJavaMethod(fooMethod); + final HotSpotInstalledCode fooCode = (HotSpotInstalledCode) getCode(fooJavaMethod, parse(fooMethod)); + argsToBind = new Object[]{fooCode}; + final Method benchmarkMethod = CompressedOopTest.class.getMethod("benchmark", HotSpotInstalledCode.class, Object.class, Object.class, Object.class); + final ResolvedJavaMethod benchmarkJavaMethod = metaAccessProvider.lookupJavaMethod(benchmarkMethod); + final HotSpotInstalledCode installedBenchmarkCode = (HotSpotInstalledCode) getCode(benchmarkJavaMethod, parse(benchmarkMethod)); + ArrayContainer ac = new ArrayContainer(); + Assert.assertEquals(ac.a[9], installedBenchmarkCode.executeVarargs(argsToBind[0], ac.a, 0, 9)); + Assert.assertEquals(ac.a[8], installedBenchmarkCode.executeVarargs(argsToBind[0], ac.a, 1, 8)); + Assert.assertEquals(ac.a[7], installedBenchmarkCode.executeVarargs(argsToBind[0], ac.a, 2, 7)); + Assert.assertEquals(ac.a[6], installedBenchmarkCode.executeVarargs(argsToBind[0], ac.a, 3, 6)); + Assert.assertEquals(ac.a[5], installedBenchmarkCode.executeVarargs(argsToBind[0], ac.a, 4, 5)); + Assert.assertEquals(ac.a[4], installedBenchmarkCode.executeVarargs(argsToBind[0], ac.a, 5, 4)); + Assert.assertEquals(ac.a[3], installedBenchmarkCode.executeVarargs(argsToBind[0], ac.a, 6, 3)); + Assert.assertEquals(ac.a[2], installedBenchmarkCode.executeVarargs(argsToBind[0], ac.a, 7, 2)); + Assert.assertEquals(ac.a[1], installedBenchmarkCode.executeVarargs(argsToBind[0], ac.a, 8, 1)); + Assert.assertEquals(ac.a[0], installedBenchmarkCode.executeVarargs(argsToBind[0], ac.a, 9, 0)); + } + + @Test + public void test2() throws NoSuchMethodException, SecurityException, InvalidInstalledCodeException { + final Method fooMethod = CompressedOopTest.class.getMethod("arrayCopyTest", Object.class, Object.class, Object.class); + final HotSpotResolvedJavaMethod fooJavaMethod = (HotSpotResolvedJavaMethod) metaAccessProvider.lookupJavaMethod(fooMethod); + final HotSpotInstalledCode fooCode = (HotSpotInstalledCode) getCode(fooJavaMethod, parse(fooMethod)); + argsToBind = new Object[]{fooCode}; + ArrayContainer source = new ArrayContainer(); + ArrayContainer destination = new ArrayContainer(); + Assert.assertEquals(source.a.length, destination.a.length); + Assert.assertFalse(Arrays.equals(source.a, destination.a)); + fooCode.execute(source.a, destination.a, source.a); + Assert.assertArrayEquals(source.a, destination.a); + } + + @Test + public void test3() throws NoSuchMethodException, SecurityException, InvalidInstalledCodeException { + final Method fooMethod = CompressedOopTest.class.getMethod("compareAndSwapTest", Object.class, Object.class, Object.class); + final HotSpotResolvedJavaMethod fooJavaMethod = (HotSpotResolvedJavaMethod) metaAccessProvider.lookupJavaMethod(fooMethod); + final HotSpotInstalledCode fooCode = (HotSpotInstalledCode) getCode(fooJavaMethod, parse(fooMethod)); + argsToBind = new Object[]{fooCode}; + Object initial = new Object(); + Object replacement = new Object(); + AtomicReference cas = new AtomicReference<>(); + Assert.assertEquals(cas.get(), null); + fooCode.execute(cas, null, initial); + Assert.assertEquals(cas.get(), initial); + fooCode.execute(cas, initial, replacement); + Assert.assertEquals(cas.get(), replacement); + } + + @Test + public void test4() throws NoSuchMethodException, SecurityException, InvalidInstalledCodeException { + final Method fooMethod = CompressedOopTest.class.getMethod("charArrayCopyTest", Object.class, Object.class, Object.class); + final HotSpotResolvedJavaMethod fooJavaMethod = (HotSpotResolvedJavaMethod) metaAccessProvider.lookupJavaMethod(fooMethod); + final HotSpotInstalledCode fooCode = (HotSpotInstalledCode) getCode(fooJavaMethod, parse(fooMethod)); + argsToBind = new Object[]{fooCode}; + StringContainer1 source1 = new StringContainer1(); + StringContainer2 source2 = new StringContainer2(); + char[] result = new char[source1.value.length + source2.value.length]; + fooCode.execute(source1.value, source2.value, result); + Assert.assertArrayEquals(new char[]{'T', 'e', 's', 't', ' ', 'S', 't', 'r', 'i', 'n', 'g'}, result); + } + + @Test + public void test5() throws NoSuchMethodException, SecurityException, InvalidInstalledCodeException { + final Method fooMethod = CompressedOopTest.class.getMethod("charContainerArrayCopyTest", Object.class, Object.class, Object.class); + final HotSpotResolvedJavaMethod fooJavaMethod = (HotSpotResolvedJavaMethod) metaAccessProvider.lookupJavaMethod(fooMethod); + final HotSpotInstalledCode fooCode = (HotSpotInstalledCode) getCode(fooJavaMethod, parse(fooMethod)); + argsToBind = new Object[]{fooCode}; + StringContainer1 source1 = new StringContainer1(); + StringContainer2 source2 = new StringContainer2(); + char[] result = new char[source1.value.length + source2.value.length]; + fooCode.execute(source1, source2, result); + Assert.assertArrayEquals(new char[]{'T', 'e', 's', 't', ' ', 'S', 't', 'r', 'i', 'n', 'g'}, result); + } + + @Test + public void test6() throws NoSuchMethodException, SecurityException, InvalidInstalledCodeException { + final Method fooMethod = CompressedOopTest.class.getMethod("stringCopyTest", Object.class, Object.class, Object.class); + final HotSpotResolvedJavaMethod fooJavaMethod = (HotSpotResolvedJavaMethod) metaAccessProvider.lookupJavaMethod(fooMethod); + final HotSpotInstalledCode fooCode = (HotSpotInstalledCode) getCode(fooJavaMethod, parse(fooMethod)); + argsToBind = new Object[]{fooCode}; + String a = new String("Test "); + String b = new String("String"); + String c = (String) fooCode.execute(a, b, null); + Assert.assertTrue(c.equals("Test String")); + } + + @Test + public void test7() throws NoSuchMethodException, SecurityException, InvalidInstalledCodeException { + final Method fooMethod = CompressedOopTest.class.getMethod("queueTest", Object.class, Object.class, Object.class); + final HotSpotResolvedJavaMethod fooJavaMethod = (HotSpotResolvedJavaMethod) metaAccessProvider.lookupJavaMethod(fooMethod); + final HotSpotInstalledCode fooCode = (HotSpotInstalledCode) getCode(fooJavaMethod, parse(fooMethod)); + argsToBind = new Object[]{fooCode}; + ArrayDeque q = new ArrayDeque<>(); + Object[] objects = new Object[512]; + for (int i = 0; i < objects.length; i++) { + objects[i] = new Object(); + } + + int j = 0; + while (j < objects.length) { + fooCode.execute(q, objects[j], null); + j++; + } + + System.gc(); + Assert.assertTrue(q.size() == objects.length); + Assert.assertTrue(!q.isEmpty()); + + j = 0; + while (j < objects.length) { + Assert.assertTrue(objects[j] == q.remove()); + j++; + } + + Assert.assertTrue(q.size() == 0); + Assert.assertTrue(q.isEmpty()); + } + + @Test + public void test8() throws NoSuchMethodException, SecurityException, InvalidInstalledCodeException { + final Method fooMethod = CompressedOopTest.class.getMethod("unmodListTest", Object.class, Object.class, Object.class); + final HotSpotResolvedJavaMethod fooJavaMethod = (HotSpotResolvedJavaMethod) metaAccessProvider.lookupJavaMethod(fooMethod); + final HotSpotInstalledCode fooCode = (HotSpotInstalledCode) getCode(fooJavaMethod, parse(fooMethod)); + argsToBind = new Object[]{fooCode}; + List list = new ArrayList<>(); + for (int i = 0; i < 512; i++) { + list.add(new Object()); + } + + Object[] array = (Object[]) fooCode.execute(list, null, null); + Assert.assertTrue(list.size() == array.length); + int i = 0; + for (Object obj : list) { + Assert.assertTrue(obj == array[i]); + i++; + } + } + + @Test + public void test9() throws NoSuchMethodException, SecurityException, InvalidInstalledCodeException { + final Method fooMethod = CompressedOopTest.class.getMethod("unmodListTest", Object.class, Object.class, Object.class); + final HotSpotResolvedJavaMethod fooJavaMethod = (HotSpotResolvedJavaMethod) metaAccessProvider.lookupJavaMethod(fooMethod); + final HotSpotInstalledCode fooCode = (HotSpotInstalledCode) getCode(fooJavaMethod, parse(fooMethod)); + argsToBind = new Object[]{fooCode}; + List list = new ArrayList<>(); + Object[] array = (Object[]) fooCode.execute(list, null, null); + Assert.assertTrue(list.size() == array.length); + } + + public void test10() throws NoSuchMethodException, SecurityException, InvalidInstalledCodeException { + final Method fooMethod = CompressedOopTest.class.getMethod("constantTest", Object.class, Object.class, Object.class); + final HotSpotResolvedJavaMethod fooJavaMethod = (HotSpotResolvedJavaMethod) metaAccessProvider.lookupJavaMethod(fooMethod); + final HotSpotInstalledCode fooCode = (HotSpotInstalledCode) getCode(fooJavaMethod, parse(fooMethod)); + argsToBind = new Object[]{fooCode}; + Container c = new Container(); + Assert.assertFalse((boolean) fooCode.execute(c, null, null)); + } + + @Test + public void test11() throws NoSuchMethodException, SecurityException, InvalidInstalledCodeException { + final Method fooMethod = CompressedOopTest.class.getMethod("stringEqualsTest", String.class, String.class, Object.class); + final HotSpotResolvedJavaMethod fooJavaMethod = (HotSpotResolvedJavaMethod) metaAccessProvider.lookupJavaMethod(fooMethod); + final HotSpotInstalledCode fooCode = (HotSpotInstalledCode) getCode(fooJavaMethod, parse(fooMethod)); + argsToBind = new Object[]{fooCode}; + String s1 = new String("Test"); + String s2 = new String("Test"); + boolean result = ((Boolean) (fooCode.execute(s1, s2, null))).booleanValue(); + Assert.assertTrue(result); + } + + @Test + public void test12() throws NoSuchMethodException, SecurityException, InvalidInstalledCodeException { + final Method fooMethod = CompressedOopTest.class.getMethod("stringConstantEqualsTest", String.class, String.class, Object.class); + final HotSpotResolvedJavaMethod fooJavaMethod = (HotSpotResolvedJavaMethod) metaAccessProvider.lookupJavaMethod(fooMethod); + final HotSpotInstalledCode fooCode = (HotSpotInstalledCode) getCode(fooJavaMethod, parse(fooMethod)); + argsToBind = new Object[]{fooCode}; + String s1 = new String("Test"); + boolean result = ((Boolean) (fooCode.execute(s1, null, null))).booleanValue(); + Assert.assertTrue(result); + } + + public static Object benchmark(HotSpotInstalledCode code, Object o1, Object o2, Object o3) throws InvalidInstalledCodeException { + return code.execute(o1, o2, o3); + } + + public static Object fieldTest(Object c1, @SuppressWarnings("unused") Object c2, @SuppressWarnings("unused") Object c3) { + ((Container) c1).a = ((Container) c1).b; + return ((Container) c1).a; + } + + public static Object arrayTest(Object c1, Object c2, Object c3) { + Object[] array = (Object[]) c1; + int initialIndex = ((Integer) c2).intValue(); + int replacingIndex = ((Integer) c3).intValue(); + array[initialIndex] = array[replacingIndex]; + return array[initialIndex]; + } + + public static void arrayCopyTest(Object c1, Object c2, @SuppressWarnings("unused") Object c3) { + Object[] source = (Object[]) c1; + Object[] destination = (Object[]) c2; + System.arraycopy(source, 0, destination, 0, source.length); + } + + public static String stringCopyTest(Object c1, Object c2, @SuppressWarnings("unused") Object c3) { + String source = (String) c1; + String destination = (String) c2; + return source + destination; + } + + public static char[] charArrayCopyTest(Object c1, Object c2, Object c3) { + char[] source1 = (char[]) c1; + char[] source2 = (char[]) c2; + char[] result = (char[]) c3; + + for (int i = 0; i < source1.length; i++) { + result[i] = source1[i]; + } + + for (int i = 0; i < source2.length; i++) { + result[source1.length + i] = source2[i]; + } + return result; + } + + public static char[] charContainerArrayCopyTest(Object c1, Object c2, Object c3) { + char[] source1 = ((StringContainer1) c1).value; + char[] source2 = ((StringContainer2) c2).value; + char[] result = (char[]) c3; + + for (int i = 0; i < source1.length; i++) { + result[i] = source1[i]; + } + + for (int i = 0; i < source2.length; i++) { + result[source1.length + i] = source2[i]; + } + return result; + } + + @SuppressWarnings("unchecked") + public static void compareAndSwapTest(Object c1, Object c2, Object c3) throws ClassCastException { + AtomicReference cas = (AtomicReference) c1; + cas.compareAndSet(c2, c3); + } + + @SuppressWarnings("unchecked") + public static HashMap hashMapCloneTest(Object c1, @SuppressWarnings("unused") Object c2, @SuppressWarnings("unused") Object c3) { + HashMap map = (HashMap) c1; + return (HashMap) map.clone(); + } + + @SuppressWarnings("unchecked") + public static void hashMapCopyTest(Object c1, Object c2, @SuppressWarnings("unused") Object c3) { + HashMap map = (HashMap) c1; + HashMap map1 = (HashMap) c2; + map.clear(); + map.putAll(map1); + } + + @SuppressWarnings("unchecked") + public static void queueTest(Object c1, Object c2, @SuppressWarnings("unused") Object c3) { + ArrayDeque queue = (ArrayDeque) c1; + queue.add(c2); + } + + @SuppressWarnings("unchecked") + public static Object[] unmodListTest(Object c1, @SuppressWarnings("unused") Object c2, @SuppressWarnings("unused") Object c3) { + List queue = (ArrayList) c1; + Object[] result = Collections.unmodifiableCollection(queue).toArray(new Object[queue.size()]); + return result; + } + + public static Boolean constantTest(Object c1, @SuppressWarnings("unused") Object c2, @SuppressWarnings("unused") Object c3) { + ConstantContainer container = (ConstantContainer) c1; + return container.a.equals(container.b); + } + + public static Boolean stringEqualsTest(String c1, String c2, @SuppressWarnings("unused") Object c3) { + return c1.equals(c2); + } + + public static Boolean stringConstantEqualsTest(String c1, @SuppressWarnings("unused") String c2, @SuppressWarnings("unused") Object c3) { + return "Test".equals(c1); + } + +} + +class Container { + + public Object a = new Object(); + public Object b = new Object(); +} + +class ArrayContainer { + + public Object[] a = new Object[10]; + + public ArrayContainer() { + for (int i = 0; i < 10; i++) { + a[i] = new Object(); + } + } +} + +class HashMapContainer { + + public HashMap a = new HashMap<>(); + + public HashMapContainer() { + for (int i = 0; i < 10; i++) { + a.put(new Object(), new Object()); + } + } +} + +class StringContainer1 { + + public char[] value = new char[5]; + + public StringContainer1() { + value[0] = 'T'; + value[1] = 'e'; + value[2] = 's'; + value[3] = 't'; + value[4] = ' '; + + } +} + +class StringContainer2 { + + public char[] value = new char[6]; + + public StringContainer2() { + value[0] = 'S'; + value[1] = 't'; + value[2] = 'r'; + value[3] = 'i'; + value[4] = 'n'; + value[5] = 'g'; + } +} + +class ConstantContainer { + + public final Object a = new Object(); + public final Object b = new Object(); + + public ConstantContainer() { + + } +} diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java Fri Jun 07 14:15:38 2013 +0200 @@ -24,17 +24,18 @@ import static com.oracle.graal.api.code.CodeUtil.*; import static com.oracle.graal.nodes.StructuredGraph.*; +import static com.oracle.graal.phases.GraalOptions.*; -import java.lang.reflect.Modifier; +import java.lang.reflect.*; import java.util.concurrent.*; import com.oracle.graal.api.code.*; -import com.oracle.graal.api.code.CallingConvention.*; +import com.oracle.graal.api.code.CallingConvention.Type; import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.*; import com.oracle.graal.debug.*; import com.oracle.graal.debug.internal.*; -import com.oracle.graal.graph.*; +import com.oracle.graal.hotspot.bridge.*; import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; @@ -62,6 +63,8 @@ private final int id; private final int priority; + private StructuredGraph graph; + public static CompilationTask create(HotSpotGraalRuntime graalRuntime, PhasePlan plan, OptimisticOptimizations optimisticOpts, HotSpotResolvedJavaMethod method, int entryBCI, int id, int priority) { return new CompilationTask(graalRuntime, plan, optimisticOpts, method, entryBCI, id, priority); } @@ -107,8 +110,8 @@ return; } inProgress = true; - if (GraalOptions.DynamicCompilePriority) { - int threadPriority = priority < GraalOptions.SlowQueueCutoff ? Thread.NORM_PRIORITY : Thread.MIN_PRIORITY; + if (DynamicCompilePriority.getValue()) { + int threadPriority = priority < VMToCompilerImpl.SlowQueueCutoff.getValue() ? Thread.NORM_PRIORITY : Thread.MIN_PRIORITY; if (Thread.currentThread().getPriority() != threadPriority) { Thread.currentThread().setPriority(threadPriority); } @@ -132,17 +135,17 @@ public void runCompilation() { CompilationStatistics stats = CompilationStatistics.create(method, entryBCI != StructuredGraph.INVOCATION_ENTRY_BCI); try (TimerCloseable a = CompilationTime.start()) { - final boolean printCompilation = GraalOptions.PrintCompilation && !TTY.isSuppressed(); + final boolean printCompilation = PrintCompilation.getValue() && !TTY.isSuppressed(); if (printCompilation) { TTY.println(String.format("%-6d Graal %-70s %-45s %-50s %s...", id, method.getDeclaringClass().getName(), method.getName(), method.getSignature(), entryBCI == StructuredGraph.INVOCATION_ENTRY_BCI ? "" : "(OSR@" + entryBCI + ") ")); } - if (GraalOptions.HotSpotPrintCompilation) { + if (HotSpotPrintCompilation.getValue()) { printCompilation(); } CompilationResult result = null; - TTY.Filter filter = new TTY.Filter(GraalOptions.PrintFilter, method); + TTY.Filter filter = new TTY.Filter(PrintFilter.getValue(), method); long start = System.currentTimeMillis(); try { result = Debug.scope("Compiling", new DebugDumpScope(String.valueOf(id), true), new Callable() { @@ -151,7 +154,7 @@ public CompilationResult call() throws Exception { graalRuntime.evictDeoptedGraphs(); Replacements replacements = graalRuntime.getReplacements(); - StructuredGraph graph = replacements.getMethodSubstitution(method); + graph = replacements.getMethodSubstitution(method); if (graph == null || entryBCI != INVOCATION_ENTRY_BCI) { graph = new StructuredGraph(method, entryBCI); } else { @@ -172,20 +175,22 @@ } } - installMethod(result, null); + installMethod(result); } catch (BailoutException bailout) { Debug.metric("Bailouts").increment(); - if (GraalOptions.ExitVMOnBailout) { + if (ExitVMOnBailout.getValue()) { TTY.cachedOut.println(MetaUtil.format("Bailout in %H.%n(%p)", method)); bailout.printStackTrace(TTY.cachedOut); System.exit(-1); - } else if (GraalOptions.PrintBailout) { + } else if (PrintBailout.getValue()) { TTY.cachedOut.println(MetaUtil.format("Bailout in %H.%n(%p)", method)); bailout.printStackTrace(TTY.cachedOut); } } catch (Throwable t) { - if (GraalOptions.ExitVMOnException) { + if (PrintStackTraceOnException.getValue() || ExitVMOnException.getValue()) { t.printStackTrace(TTY.cachedOut); + } + if (ExitVMOnException.getValue()) { System.exit(-1); } } @@ -202,7 +207,7 @@ MetaUtil.format("%H::%n(%p)", method), isOSR ? "@ " + entryBCI + " " : "", method.getCodeSize())); } - private void installMethod(final CompilationResult compResult, final Graph graph) { + private void installMethod(final CompilationResult compResult) { Debug.scope("CodeInstall", new Object[]{new DebugDumpScope(String.valueOf(id), true), graalRuntime.getRuntime(), method}, new Runnable() { @Override @@ -211,6 +216,9 @@ if (Debug.isDumpEnabled()) { Debug.dump(new Object[]{compResult, installedCode}, "After code installation"); } + if (Debug.isLogEnabled()) { + Debug.log("%s", graalRuntime.getRuntime().disassemble(installedCode)); + } } }); diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompileTheWorld.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompileTheWorld.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompileTheWorld.java Fri Jun 07 14:15:38 2013 +0200 @@ -23,6 +23,7 @@ package com.oracle.graal.hotspot; import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; +import static com.oracle.graal.phases.GraalOptions.*; import java.io.File; import java.lang.reflect.Constructor; @@ -75,7 +76,7 @@ * {@link GraalOptions#CompileTheWorldStopAt}. */ public CompileTheWorld() { - this(GraalOptions.CompileTheWorld, GraalOptions.CompileTheWorldStartAt, GraalOptions.CompileTheWorldStopAt); + this(CompileTheWorld.getValue(), CompileTheWorldStartAt.getValue(), CompileTheWorldStopAt.getValue()); } /** @@ -91,7 +92,7 @@ this.stopAt = stopAt; // We don't want the VM to exit when a method fails to compile. - GraalOptions.ExitVMOnException = false; + ExitVMOnException.setValue(false); } /** diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilerThread.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilerThread.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilerThread.java Fri Jun 07 14:15:38 2013 +0200 @@ -22,6 +22,7 @@ */ package com.oracle.graal.hotspot; +import static com.oracle.graal.compiler.GraalDebugConfig.*; import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; import java.io.*; @@ -29,7 +30,6 @@ import com.oracle.graal.compiler.*; import com.oracle.graal.debug.*; -import com.oracle.graal.phases.*; import com.oracle.graal.printer.*; public final class CompilerThread extends Thread { @@ -60,7 +60,7 @@ @Override public void run() { GraalDebugConfig hotspotDebugConfig = null; - if (GraalOptions.Debug) { + if (DebugEnabled.getValue()) { PrintStream log = graalRuntime().getVMToCompiler().log(); DebugEnvironment.initialize(log); } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotCompiledCode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotCompiledCode.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotCompiledCode.java Fri Jun 07 14:15:38 2013 +0200 @@ -25,9 +25,9 @@ import java.util.*; import com.oracle.graal.api.code.*; -import com.oracle.graal.api.code.CompilationResult.ExceptionHandler; -import com.oracle.graal.api.code.CompilationResult.Mark; -import com.oracle.graal.api.code.CompilationResult.Site; +import com.oracle.graal.api.code.CompilationResult.CodeComment; +import com.oracle.graal.api.code.CompilationResult.JumpTable; +import com.oracle.graal.api.code.CompilationResult.*; /** * A {@link CompilationResult} with additional HotSpot-specific information required for installing @@ -40,6 +40,18 @@ public final Site[] sites; public final ExceptionHandler[] exceptionHandlers; + public final Comment[] comments; + + public static class Comment { + + public final String text; + public final int pcOffset; + + public Comment(int pcOffset, String text) { + this.text = text; + this.pcOffset = pcOffset; + } + } public HotSpotCompiledCode(CompilationResult compResult) { this.comp = compResult; @@ -49,6 +61,24 @@ } else { exceptionHandlers = compResult.getExceptionHandlers().toArray(new ExceptionHandler[compResult.getExceptionHandlers().size()]); } + List annotations = compResult.getAnnotations(); + comments = new Comment[annotations.size()]; + if (!annotations.isEmpty()) { + for (int i = 0; i < comments.length; i++) { + CodeAnnotation annotation = annotations.get(i); + String text; + if (annotation instanceof CodeComment) { + CodeComment codeComment = (CodeComment) annotation; + text = codeComment.value; + } else if (annotation instanceof JumpTable) { + JumpTable jumpTable = (JumpTable) annotation; + text = "JumpTable [" + jumpTable.low + " .. " + jumpTable.high + "]"; + } else { + text = annotation.toString(); + } + comments[i] = new Comment(annotation.position, text); + } + } } static class SiteComparator implements Comparator { diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotForeignCallLinkage.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotForeignCallLinkage.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotForeignCallLinkage.java Fri Jun 07 14:15:38 2013 +0200 @@ -88,11 +88,18 @@ private final Transition transition; /** - * The locations defined/killed by the call. + * The registers and stack slots defined/killed by the call. */ private Value[] temporaries = AllocatableValue.NONE; /** + * The memory locations killed by the call. + */ + private final LocationIdentity[] killedLocations; + + private final boolean reexecutable; + + /** * Creates a {@link HotSpotForeignCallLinkage}. * * @param descriptor the descriptor of the call @@ -100,11 +107,16 @@ * @param effect specifies if the call destroys or preserves all registers (apart from * temporaries which are always destroyed) * @param ccType calling convention type - * @param transition specifies if this is a {@linkplain #isLeaf() leaf} call + * @param transition specifies if this is a {@linkplain #canDeoptimize() leaf} call + * @param reexecutable specifies if the call can be re-executed without (meaningful) side + * effects. Deoptimization will not return to a point before a call that cannot be + * re-executed. + * @param killedLocations the memory locations killed by the call */ - public static HotSpotForeignCallLinkage create(ForeignCallDescriptor descriptor, long address, RegisterEffect effect, Type ccType, Transition transition) { + public static HotSpotForeignCallLinkage create(ForeignCallDescriptor descriptor, long address, RegisterEffect effect, Type ccType, Transition transition, boolean reexecutable, + LocationIdentity... killedLocations) { CallingConvention targetCc = createCallingConvention(descriptor, ccType); - return new HotSpotForeignCallLinkage(descriptor, address, effect, transition, targetCc); + return new HotSpotForeignCallLinkage(descriptor, address, effect, transition, targetCc, reexecutable, killedLocations); } /** @@ -130,12 +142,15 @@ } } - public HotSpotForeignCallLinkage(ForeignCallDescriptor descriptor, long address, RegisterEffect effect, Transition transition, CallingConvention cc) { + public HotSpotForeignCallLinkage(ForeignCallDescriptor descriptor, long address, RegisterEffect effect, Transition transition, CallingConvention cc, boolean reexecutable, + LocationIdentity... killedLocations) { this.address = address; this.effect = effect; this.transition = transition; this.descriptor = descriptor; this.cc = cc; + this.reexecutable = reexecutable; + this.killedLocations = killedLocations; } @Override @@ -153,6 +168,14 @@ return sb.toString(); } + public boolean isReexecutable() { + return reexecutable; + } + + public LocationIdentity[] getKilledLocations() { + return killedLocations; + } + public CallingConvention getCallingConvention() { return cc; } @@ -212,11 +235,8 @@ return effect == DESTROYS_REGISTERS; } - /** - * Determines if this is call to a function that does not lock, GC or throw exceptions. That is, - * the thread's execution state during the call is never inspected by another thread. - */ - public boolean isLeaf() { - return transition == Transition.LEAF; + @Override + public boolean canDeoptimize() { + return transition != Transition.LEAF; } } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java Fri Jun 07 14:15:38 2013 +0200 @@ -35,8 +35,11 @@ import com.oracle.graal.hotspot.logging.*; import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.options.*; import com.oracle.graal.phases.*; +//import static com.oracle.graal.phases.GraalOptions.*; + /** * Singleton class holding the instance of the {@link GraalRuntime}. * @@ -84,9 +87,14 @@ runtime.compilerToVm = toVM; } + // @formatter:off + @Option(help = "The runtime configuration to use") + private static final OptionValue GraalRuntime = new OptionValue<>("basic"); + // @formatter:on + protected static HotSpotGraalRuntimeFactory findFactory(String architecture) { for (HotSpotGraalRuntimeFactory factory : ServiceLoader.loadInstalled(HotSpotGraalRuntimeFactory.class)) { - if (factory.getArchitecture().equals(architecture) && factory.getName().equals(GraalOptions.GraalRuntime)) { + if (factory.getArchitecture().equals(architecture) && factory.getName().equals(GraalRuntime.getValue())) { return factory; } } @@ -123,9 +131,9 @@ return unsafe.getInt(object, offset); } - protected/* final */CompilerToVM compilerToVm; + protected/* final */CompilerToVM compilerToVm; protected/* final */CompilerToGPU compilerToGpu; - protected/* final */VMToCompiler vmToCompiler; + protected/* final */VMToCompiler vmToCompiler; protected final HotSpotRuntime runtime; protected final TargetDescription target; @@ -138,13 +146,13 @@ private final HotSpotBackend backend; protected HotSpotGraalRuntime() { - CompilerToVM toVM = new CompilerToVMImpl(); + CompilerToVM toVM = new CompilerToVMImpl(); CompilerToGPU toGPU = new CompilerToGPUImpl(); // initialize VmToCompiler VMToCompiler toCompiler = new VMToCompilerImpl(this); - compilerToVm = toVM; + compilerToVm = toVM; compilerToGpu = toGPU; vmToCompiler = toCompiler; config = new HotSpotVMConfig(); @@ -153,16 +161,16 @@ // Set some global options: if (config.compileTheWorld) { - GraalOptions.CompileTheWorld = CompileTheWorld.SUN_BOOT_CLASS_PATH; + GraalOptions.CompileTheWorld.setValue(CompileTheWorld.SUN_BOOT_CLASS_PATH); } if (config.compileTheWorldStartAt != 1) { - GraalOptions.CompileTheWorldStartAt = config.compileTheWorldStartAt; + GraalOptions.CompileTheWorldStartAt.setValue(config.compileTheWorldStartAt); } if (config.compileTheWorldStopAt != Integer.MAX_VALUE) { - GraalOptions.CompileTheWorldStopAt = config.compileTheWorldStopAt; + GraalOptions.CompileTheWorldStopAt.setValue(config.compileTheWorldStopAt); } - GraalOptions.HotSpotPrintCompilation = config.printCompilation; - GraalOptions.HotSpotPrintInlining = config.printInlining; + GraalOptions.HotSpotPrintCompilation.setValue(config.printCompilation); + GraalOptions.HotSpotPrintInlining.setValue(config.printInlining); if (Boolean.valueOf(System.getProperty("graal.printconfig"))) { printConfig(config); @@ -180,8 +188,8 @@ replacements = new HotSpotReplacementsImpl(runtime, assumptions, runtime.getGraalRuntime().getTarget()); backend = createBackend(); - GraalOptions.StackShadowPages = config.stackShadowPages; - if (GraalOptions.CacheGraphs) { + GraalOptions.StackShadowPages.setValue(config.stackShadowPages); + if (GraalOptions.CacheGraphs.getValue()) { cache = new HotSpotGraphCache(); } } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotOptions.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotOptions.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotOptions.java Fri Jun 07 14:15:38 2013 +0200 @@ -23,14 +23,28 @@ package com.oracle.graal.hotspot; -import java.lang.reflect.*; import java.util.*; import com.oracle.graal.hotspot.logging.*; -import com.oracle.graal.phases.*; +import com.oracle.graal.options.*; public class HotSpotOptions { + private static final Map options = new HashMap<>(); + + static { + ServiceLoader sl = ServiceLoader.loadInstalled(Options.class); + for (Options opts : sl) { + for (OptionDescriptor desc : opts) { + if (desc.getClass().getName().startsWith("com.oracle.graal")) { + String name = desc.getName(); + OptionDescriptor existing = options.put(name, desc); + assert existing == null : "Option named \"" + name + "\" has multiple definitions: " + existing.getLocation() + " and " + desc.getLocation(); + } + } + } + } + // Called from VM code public static boolean setOption(String option) { if (option.length() == 0) { @@ -38,7 +52,7 @@ } Object value = null; - String fieldName = null; + String optionName = null; String valueString = null; if (option.equals("+PrintFlags")) { @@ -48,70 +62,60 @@ char first = option.charAt(0); if (first == '+' || first == '-') { - fieldName = option.substring(1); + optionName = option.substring(1); value = (first == '+'); } else { int index = option.indexOf('='); if (index == -1) { - fieldName = option; + optionName = option; valueString = null; } else { - fieldName = option.substring(0, index); + optionName = option.substring(0, index); valueString = option.substring(index + 1); } } - Field f; - try { - f = GraalOptions.class.getDeclaredField(fieldName); - Class fType = f.getType(); + OptionDescriptor desc = options.get(optionName); + if (desc == null) { + Logger.info("Could not find option " + optionName + " (use -G:+PrintFlags to see Graal options)"); + return false; + } - if (value == null) { - if (fType == Boolean.TYPE) { - Logger.info("Value for boolean option '" + fieldName + "' must use '-G:+" + fieldName + "' or '-G:-" + fieldName + "' format"); - return false; - } + Class optionType = desc.getType(); - if (valueString == null) { - Logger.info("Value for option '" + fieldName + "' must use '-G:" + fieldName + "=' format"); - return false; - } + if (value == null) { + if (optionType == Boolean.TYPE || optionType == Boolean.class) { + Logger.info("Value for boolean option '" + optionName + "' must use '-G:+" + optionName + "' or '-G:-" + optionName + "' format"); + return false; + } - if (fType == Float.TYPE) { - value = Float.parseFloat(valueString); - } else if (fType == Double.TYPE) { - value = Double.parseDouble(valueString); - } else if (fType == Integer.TYPE) { - value = Integer.parseInt(valueString); - } else if (fType == String.class) { - value = valueString; - } - } else { - if (fType != Boolean.TYPE) { - Logger.info("Value for option '" + fieldName + "' must use '-G:" + fieldName + "=' format"); - return false; - } + if (valueString == null) { + Logger.info("Value for option '" + optionName + "' must use '-G:" + optionName + "=' format"); + return false; } - if (value != null) { - f.setAccessible(true); - f.set(null, value); - // Logger.info("Set option " + fieldName + " to " + value); - } else { - Logger.info("Wrong value \"" + valueString + "\" for option " + fieldName); + if (optionType == Float.class) { + value = Float.parseFloat(valueString); + } else if (optionType == Double.class) { + value = Double.parseDouble(valueString); + } else if (optionType == Integer.class) { + value = Integer.parseInt(valueString); + } else if (optionType == String.class) { + value = valueString; + } + } else { + if (optionType != Boolean.class) { + Logger.info("Value for option '" + optionName + "' must use '-G:" + optionName + "=' format"); return false; } - } catch (SecurityException e) { - Logger.info("Security exception when setting option " + option); - return false; - } catch (NoSuchFieldException e) { - Logger.info("Could not find option " + fieldName + " (use -G:+PrintFlags to see Graal options)"); - return false; - } catch (IllegalArgumentException e) { - Logger.info("Illegal value for option " + option); - return false; - } catch (IllegalAccessException e) { - Logger.info("Illegal access exception when setting option " + option); + } + + if (value != null) { + OptionValue optionValue = desc.getOptionValue(); + optionValue.setValue(value); + // Logger.info("Set option " + fieldName + " to " + value); + } else { + Logger.info("Wrong value \"" + valueString + "\" for option " + optionName); return false; } @@ -120,23 +124,14 @@ private static void printFlags() { Logger.info("[Graal flags]"); - Field[] flags = GraalOptions.class.getDeclaredFields(); - Arrays.sort(flags, new Comparator() { + SortedMap sortedOptions = new TreeMap<>(options); + for (Map.Entry e : sortedOptions.entrySet()) { + e.getKey(); + OptionDescriptor desc = e.getValue(); + Object value = desc.getOptionValue().getValue(); + Logger.info(String.format("%9s %-40s = %-14s %s", desc.getType().getSimpleName(), e.getKey(), value, desc.getHelp())); + } - public int compare(Field o1, Field o2) { - return o1.getName().compareTo(o2.getName()); - } - }); - for (Field f : flags) { - if (Modifier.isPublic(f.getModifiers()) && Modifier.isStatic(f.getModifiers())) { - f.setAccessible(true); - try { - Object value = f.get(null); - Logger.info(String.format("%9s %-40s = %s", f.getType().getSimpleName(), f.getName(), value)); - } catch (Exception e) { - } - } - } System.exit(0); } } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java Fri Jun 07 14:15:38 2013 +0200 @@ -50,6 +50,13 @@ public boolean useAESIntrinsics; public boolean useG1GC; + // Compressed Oops related values. + public boolean useCompressedOops; + public boolean useCompressedKlassPointers; + public long narrowOopBase; + public int narrowOopShift; + public int logMinObjAlignment; + // CPU capabilities public int useSSE; public int useAVX; @@ -411,6 +418,7 @@ public long arithmeticSinAddress; public long arithmeticCosAddress; public long arithmeticTanAddress; + public long loadAndClearExceptionAddress; public int deoptReasonNone; public int deoptReasonNullCheck; diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java Fri Jun 07 14:15:38 2013 +0200 @@ -129,8 +129,9 @@ @Override public native long getMaxCallTargetOffset(long address); + // The HotSpot disassembler seems not to be thread safe so it's better to synchronize its usage @Override - public native String disassembleCodeBlob(long codeBlob); + public synchronized native String disassembleCodeBlob(long codeBlob); @Override public native byte[] getCode(long codeBlob); diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java Fri Jun 07 14:15:38 2013 +0200 @@ -23,10 +23,12 @@ package com.oracle.graal.hotspot.bridge; +import static com.oracle.graal.compiler.GraalDebugConfig.*; import static com.oracle.graal.graph.UnsafeAccess.*; import static com.oracle.graal.hotspot.CompilationTask.*; import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; import static com.oracle.graal.java.GraphBuilderPhase.*; +import static com.oracle.graal.phases.GraalOptions.*; import java.io.*; import java.lang.reflect.*; @@ -46,6 +48,7 @@ import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.debug.*; import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.options.*; import com.oracle.graal.phases.*; import com.oracle.graal.phases.PhasePlan.PhasePosition; import com.oracle.graal.phases.common.*; @@ -57,6 +60,41 @@ */ public class VMToCompilerImpl implements VMToCompiler { + //@formatter:off + @Option(help = "File to which compiler logging is sent") + private static final OptionValue LogFile = new OptionValue<>(null); + + @Option(help = "Use low priority compilation threads") + private static final OptionValue SlowCompileThreads = new OptionValue<>(false); + + @Option(help = "Use priority-based compilation queue") + private static final OptionValue PriorityCompileQueue = new OptionValue<>(true); + + @Option(help = "Print compilation queue activity periodically") + private static final OptionValue PrintQueue = new OptionValue<>(false); + + @Option(help = "") + public static final OptionValue SlowQueueCutoff = new OptionValue<>(100000); + + @Option(help = "Time limit in milliseconds for bootstrap (-1 for no limit)") + private static final OptionValue TimedBootstrap = new OptionValue<>(-1); + + @Option(help = "Number of compilation threads to use") + private static final StableOptionValue Threads = new StableOptionValue() { + + @Override + public Integer initialValue() { + return Runtime.getRuntime().availableProcessors(); + } + }; + + @Option(help = "") + private static final OptionValue GenericDynamicCounters = new OptionValue<>(false); + + @Option(help = "") + private static final OptionValue BenchmarkDynamicCounters = new OptionValue<>(null); + //@formatter:on + private final HotSpotGraalRuntime graalRuntime; public final HotSpotResolvedPrimitiveType typeBoolean; @@ -117,41 +155,38 @@ initMirror(typeLong, offset); initMirror(typeVoid, offset); - if (GraalOptions.LogFile != null) { + if (LogFile.getValue() != null) { try { final boolean enableAutoflush = true; - log = new PrintStream(new FileOutputStream(GraalOptions.LogFile), enableAutoflush); + log = new PrintStream(new FileOutputStream(LogFile.getValue()), enableAutoflush); } catch (FileNotFoundException e) { - throw new RuntimeException("couldn't open log file: " + GraalOptions.LogFile, e); + throw new RuntimeException("couldn't open log file: " + LogFile.getValue(), e); } } TTY.initialize(log); - if (GraalOptions.Log == null && GraalOptions.Meter == null && GraalOptions.Time == null && GraalOptions.Dump == null) { - if (GraalOptions.MethodFilter != null) { + if (Log.getValue() == null && Meter.getValue() == null && Time.getValue() == null && Dump.getValue() == null) { + if (MethodFilter.getValue() != null) { TTY.println("WARNING: Ignoring MethodFilter option since Log, Meter, Time and Dump options are all null"); } } if (config.ciTime) { - quietMeterAndTime = (GraalOptions.Meter == null && GraalOptions.Time == null); - GraalOptions.Debug = true; - GraalOptions.Meter = ""; - GraalOptions.Time = ""; + quietMeterAndTime = (Meter.getValue() == null && Time.getValue() == null); + DebugEnabled.setValue(true); + Meter.setValue(""); + Time.setValue(""); } - if (GraalOptions.Debug) { - Debug.enable(); - if (GraalOptions.DebugReplacements) { - DebugEnvironment.initialize(log); - } + if (DebugEnabled.getValue()) { + DebugEnvironment.initialize(log); } // Install intrinsics. final HotSpotRuntime runtime = graalRuntime.getCapability(HotSpotRuntime.class); final Replacements replacements = graalRuntime.getCapability(Replacements.class); - if (GraalOptions.Intrinsify) { + if (Intrinsify.getValue()) { Debug.scope("RegisterReplacements", new Object[]{new DebugDumpScope("RegisterReplacements")}, new Runnable() { @Override @@ -161,7 +196,7 @@ provider.registerReplacements(runtime, replacements, runtime.getTarget()); } runtime.registerReplacements(replacements); - if (GraalOptions.BootstrapReplacements) { + if (BootstrapReplacements.getValue()) { for (ResolvedJavaMethod method : replacements.getAllReplacements()) { replacements.getMacroSubstitution(method); replacements.getMethodSubstitution(method); @@ -173,21 +208,17 @@ } - if (GraalOptions.DebugReplacements) { - phaseTransition("replacements"); - } + // Create compilation queue. + BlockingQueue queue = PriorityCompileQueue.getValue() ? new PriorityBlockingQueue() : new LinkedBlockingQueue(); + compileQueue = new ThreadPoolExecutor(Threads.getValue(), Threads.getValue(), 0L, TimeUnit.MILLISECONDS, queue, CompilerThread.FACTORY); - // Create compilation queue. - BlockingQueue queue = GraalOptions.PriorityCompileQueue ? new PriorityBlockingQueue() : new LinkedBlockingQueue(); - compileQueue = new ThreadPoolExecutor(GraalOptions.Threads, GraalOptions.Threads, 0L, TimeUnit.MILLISECONDS, queue, CompilerThread.FACTORY); - - if (GraalOptions.SlowCompileThreads) { - BlockingQueue slowQueue = GraalOptions.PriorityCompileQueue ? new PriorityBlockingQueue() : new LinkedBlockingQueue(); - slowCompileQueue = new ThreadPoolExecutor(GraalOptions.Threads, GraalOptions.Threads, 0L, TimeUnit.MILLISECONDS, slowQueue, CompilerThread.LOW_PRIORITY_FACTORY); + if (SlowCompileThreads.getValue()) { + BlockingQueue slowQueue = PriorityCompileQueue.getValue() ? new PriorityBlockingQueue() : new LinkedBlockingQueue(); + slowCompileQueue = new ThreadPoolExecutor(Threads.getValue(), Threads.getValue(), 0L, TimeUnit.MILLISECONDS, slowQueue, CompilerThread.LOW_PRIORITY_FACTORY); } // Create queue status printing thread. - if (GraalOptions.PrintQueue) { + if (PrintQueue.getValue()) { Thread t = new Thread() { @Override @@ -209,8 +240,8 @@ t.start(); } - if (GraalOptions.BenchmarkDynamicCounters != null) { - String[] arguments = GraalOptions.BenchmarkDynamicCounters.split(","); + if (BenchmarkDynamicCounters.getValue() != null) { + String[] arguments = BenchmarkDynamicCounters.getValue().split(","); if (arguments.length == 0 || (arguments.length % 3) != 0) { throw new GraalInternalError("invalid arguments to BenchmarkDynamicCounters: (err|out),start,end,(err|out),start,end,... (~ matches multiple digits)"); } @@ -228,7 +259,7 @@ DynamicCounterNode.excludedClassPrefix = "Lcom/oracle/graal/"; DynamicCounterNode.enabled = true; } - if (GraalOptions.GenericDynamicCounters) { + if (GenericDynamicCounters.getValue()) { DynamicCounterNode.enabled = true; } compilerStartTime = System.nanoTime(); @@ -382,7 +413,7 @@ TTY.flush(); } } - } while ((System.currentTimeMillis() - startTime) <= GraalOptions.TimedBootstrap); + } while ((System.currentTimeMillis() - startTime) <= TimedBootstrap.getValue()); phaseTransition("bootstrap"); @@ -395,7 +426,7 @@ System.gc(); phaseTransition("bootstrap2"); - if (GraalOptions.CompileTheWorld != null) { + if (CompileTheWorld.getValue() != null) { new CompileTheWorld().compile(); System.exit(0); } @@ -413,7 +444,7 @@ private static void shutdownCompileQueue(ThreadPoolExecutor queue) throws InterruptedException { if (queue != null) { queue.shutdown(); - if (Debug.isEnabled() && GraalOptions.Dump != null) { + if (Debug.isEnabled() && Dump.getValue() != null) { // Wait 2 seconds to flush out all graph dumps that may be of interest queue.awaitTermination(2, TimeUnit.SECONDS); } @@ -437,9 +468,9 @@ ArrayList sortedValues = new ArrayList<>(debugValues); Collections.sort(sortedValues); - if (GraalOptions.SummarizeDebugValues) { + if (SummarizeDebugValues.getValue()) { printSummary(topLevelMaps, sortedValues); - } else if (GraalOptions.PerThreadDebugValues) { + } else if (PerThreadDebugValues.getValue()) { for (DebugValueMap map : topLevelMaps) { TTY.println("Showing the results for thread: " + map.getName()); map.group(); @@ -449,13 +480,13 @@ } else { DebugValueMap globalMap = new DebugValueMap("Global"); for (DebugValueMap map : topLevelMaps) { - if (GraalOptions.SummarizePerPhase) { + if (SummarizePerPhase.getValue()) { flattenChildren(map, globalMap); } else { globalMap.addChild(map); } } - if (!GraalOptions.SummarizePerPhase) { + if (!SummarizePerPhase.getValue()) { globalMap.group(); } globalMap.normalize(); @@ -471,7 +502,7 @@ } SnippetCounter.printGroups(TTY.out().out()); - if (GraalOptions.GenericDynamicCounters) { + if (GenericDynamicCounters.getValue()) { DynamicCounterNode.dump(System.out, (System.nanoTime() - compilerStartTime) / 1000000000d); } } @@ -581,7 +612,7 @@ return true; } } else { - if (GraalOptions.PriorityCompileQueue) { + if (PriorityCompileQueue.getValue()) { // normally compilation tasks will only be re-queued when they get a // priority boost, so cancel the old task and add a new one current.cancel(); @@ -604,7 +635,7 @@ } else { try { method.setCurrentTask(task); - if (GraalOptions.SlowCompileThreads && priority > GraalOptions.SlowQueueCutoff) { + if (SlowCompileThreads.getValue() && priority > SlowQueueCutoff.getValue()) { slowCompileQueue.execute(task); } else { compileQueue.execute(task); @@ -742,7 +773,7 @@ phasePlan.addPhase(PhasePosition.AFTER_PARSING, new OnStackReplacementPhase()); } phasePlan.addPhase(PhasePosition.LOW_LEVEL, new WriteBarrierAdditionPhase()); - if (GraalOptions.VerifyPhases) { + if (VerifyPhases.getValue()) { phasePlan.addPhase(PhasePosition.LOW_LEVEL, new WriteBarrierVerificationPhase()); } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotGraphCache.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotGraphCache.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotGraphCache.java Fri Jun 07 14:15:38 2013 +0200 @@ -22,6 +22,8 @@ */ package com.oracle.graal.hotspot.meta; +import static com.oracle.graal.phases.GraalOptions.*; + import java.io.*; import java.lang.ref.*; import java.util.*; @@ -30,7 +32,6 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.phases.*; /** * This class implements the graph caching system for the HotSpot platform. @@ -73,12 +74,12 @@ private static final long serialVersionUID = -3973307040793397840L; public LRUCache() { - super(GraalOptions.GraphCacheSize * 2, 0.75f, false); + super(GraphCacheSize.getValue() * 2, 0.75f, false); } @Override protected boolean removeEldestEntry(Entry> eldest) { - if (size() > GraalOptions.GraphCacheSize) { + if (size() > GraphCacheSize.getValue()) { ResolvedJavaMethod method = eldest.getValue().get(); if (method != null) { StructuredGraph cachedGraph = (StructuredGraph) method.getCompilerStorage().get(HotSpotGraphCache.this); @@ -96,7 +97,7 @@ private final Map> cachedGraphIds = Collections.synchronizedMap(new LRUCache()); public HotSpotGraphCache() { - if (GraalOptions.PrintGraphCache) { + if (PrintGraphCache.getValue()) { Runtime.getRuntime().addShutdownHook(new Thread() { @Override @@ -115,7 +116,7 @@ public StructuredGraph get(ResolvedJavaMethod method) { StructuredGraph result = (StructuredGraph) method.getCompilerStorage().get(this); - if (GraalOptions.PrintGraphCache) { + if (PrintGraphCache.getValue()) { if (result == null) { missCounter++; } else { @@ -131,7 +132,7 @@ cachedGraphIds.put(graph.graphId(), new WeakReference<>(graph.method())); graph.method().getCompilerStorage().put(this, graph); - if (GraalOptions.PrintGraphCache) { + if (PrintGraphCache.getValue()) { putCounter++; } } @@ -161,12 +162,12 @@ StructuredGraph cachedGraph = (StructuredGraph) method.getCompilerStorage().get(this); if (cachedGraph != null && cachedGraph.graphId() == graphId) { method.getCompilerStorage().remove(this); - if (GraalOptions.PrintGraphCache) { + if (PrintGraphCache.getValue()) { removeHitCounter++; } } } - if (GraalOptions.PrintGraphCache) { + if (PrintGraphCache.getValue()) { removeCounter++; } } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodData.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodData.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodData.java Fri Jun 07 14:15:38 2013 +0200 @@ -24,6 +24,7 @@ import static com.oracle.graal.graph.UnsafeAccess.*; import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; +import static com.oracle.graal.phases.GraalOptions.*; import java.util.*; @@ -32,7 +33,6 @@ import com.oracle.graal.api.meta.JavaTypeProfile.ProfiledType; import com.oracle.graal.api.meta.ProfilingInfo.TriState; import com.oracle.graal.hotspot.*; -import com.oracle.graal.phases.*; /** * Access to a HotSpot MethodData structure (defined in methodData.hpp). @@ -376,7 +376,7 @@ protected abstract long getTypesNotRecordedExecutionCount(HotSpotMethodData data, int position); private static JavaTypeProfile createTypeProfile(TriState nullSeen, ResolvedJavaType[] types, long[] counts, long totalCount, int entries) { - if (entries <= 0 || totalCount < GraalOptions.MatureExecutionsTypeProfile) { + if (entries <= 0 || totalCount < MatureExecutionsTypeProfile.getValue()) { return null; } @@ -484,7 +484,7 @@ } private static JavaMethodProfile createMethodProfile(ResolvedJavaMethod[] methods, long[] counts, long totalCount, int entries) { - if (entries <= 0 || totalCount < GraalOptions.MatureExecutionsTypeProfile) { + if (entries <= 0 || totalCount < MatureExecutionsTypeProfile.getValue()) { return null; } @@ -540,7 +540,7 @@ long notTakenCount = data.readUnsignedInt(position, NOT_TAKEN_COUNT_OFFSET); long total = takenCount + notTakenCount; - if (total < GraalOptions.MatureExecutionsBranch) { + if (total < MatureExecutionsBranch.getValue()) { return -1; } else { return takenCount / (double) total; @@ -607,7 +607,7 @@ result[i - 1] = count; } - if (totalCount < GraalOptions.MatureExecutionsPerSwitchCase * length) { + if (totalCount < MatureExecutionsPerSwitchCase.getValue() * length) { return null; } else { for (int i = 0; i < length; i++) { diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java Fri Jun 07 14:15:38 2013 +0200 @@ -31,8 +31,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.hotspot.*; -import com.oracle.graal.nodes.extended.LocationNode.LocationIdentity; -import com.oracle.graal.phases.*; +import com.oracle.graal.options.*; import com.oracle.graal.replacements.*; /** @@ -84,7 +83,7 @@ assert Modifier.isStatic(flags); if (constant == null) { if (holder.isInitialized() && !holder.getName().equals(SystemClassName)) { - if (Modifier.isFinal(getModifiers()) || assumeStaticFieldsFinal(holder.mirror())) { + if (Modifier.isFinal(getModifiers())) { constant = readValue(receiver); } } @@ -96,11 +95,18 @@ * have a non-default value. */ assert !Modifier.isStatic(flags); + Object object = receiver.asObject(); if (Modifier.isFinal(getModifiers())) { Constant value = readValue(receiver); - if (assumeNonStaticFinalFieldsAsFinal(receiver.asObject().getClass()) || !value.isDefaultForKind()) { + if (assumeNonStaticFinalFieldsAsFinal(object.getClass()) || !value.isDefaultForKind()) { return value; } + } else { + Class clazz = object.getClass(); + if (StableOptionValue.class.isAssignableFrom(clazz)) { + StableOptionValue option = (StableOptionValue) object; + return Constant.forObject(option.getValue()); + } } } return null; @@ -120,10 +126,6 @@ } } - private static boolean assumeStaticFieldsFinal(Class clazz) { - return clazz == GraalOptions.class; - } - private static boolean assumeNonStaticFinalFieldsAsFinal(Class clazz) { return clazz == SnippetCounter.class; } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java Fri Jun 07 14:15:38 2013 +0200 @@ -25,6 +25,7 @@ import static com.oracle.graal.api.meta.MetaUtil.*; import static com.oracle.graal.graph.UnsafeAccess.*; import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; +import static com.oracle.graal.phases.GraalOptions.*; import java.lang.annotation.*; import java.lang.reflect.*; @@ -37,7 +38,6 @@ import com.oracle.graal.graph.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.debug.*; -import com.oracle.graal.phases.*; /** * Implementation of {@link JavaMethod} for resolved HotSpot methods. @@ -276,7 +276,7 @@ public ProfilingInfo getProfilingInfo() { ProfilingInfo info; - if (GraalOptions.UseProfilingInformation && methodData == null) { + if (UseProfilingInformation.getValue() && methodData == null) { long metaspaceMethodData = unsafeReadWord(metaspaceMethod + graalRuntime().getConfig().methodDataOffset); if (metaspaceMethodData != 0) { methodData = new HotSpotMethodData(metaspaceMethodData); diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java Fri Jun 07 14:15:38 2013 +0200 @@ -313,6 +313,7 @@ @Override public boolean isAssignableFrom(ResolvedJavaType other) { + assert other != null; if (other instanceof HotSpotResolvedObjectType) { HotSpotResolvedObjectType otherType = (HotSpotResolvedObjectType) other; return javaMirror.isAssignableFrom(otherType.javaMirror); diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedPrimitiveType.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedPrimitiveType.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedPrimitiveType.java Fri Jun 07 14:15:38 2013 +0200 @@ -129,6 +129,7 @@ @Override public boolean isAssignableFrom(ResolvedJavaType other) { + assert other != null; return other == this; } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java Fri Jun 07 14:15:38 2013 +0200 @@ -26,6 +26,7 @@ import static com.oracle.graal.api.code.DeoptimizationAction.*; import static com.oracle.graal.api.code.MemoryBarriers.*; import static com.oracle.graal.api.meta.DeoptimizationReason.*; +import static com.oracle.graal.api.meta.LocationIdentity.*; import static com.oracle.graal.graph.UnsafeAccess.*; import static com.oracle.graal.hotspot.HotSpotBackend.*; import static com.oracle.graal.hotspot.HotSpotForeignCallLinkage.RegisterEffect.*; @@ -38,6 +39,7 @@ import static com.oracle.graal.hotspot.nodes.VMErrorNode.*; import static com.oracle.graal.hotspot.nodes.WriteBarrierPostStubCall.*; import static com.oracle.graal.hotspot.nodes.WriteBarrierPreStubCall.*; +import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*; import static com.oracle.graal.hotspot.replacements.MonitorSnippets.*; import static com.oracle.graal.hotspot.replacements.SystemSubstitutions.*; import static com.oracle.graal.hotspot.replacements.ThreadSubstitutions.*; @@ -48,6 +50,7 @@ import static com.oracle.graal.hotspot.stubs.UnwindExceptionToCallerStub.*; import static com.oracle.graal.java.GraphBuilderPhase.RuntimeCalls.*; import static com.oracle.graal.nodes.java.RegisterFinalizerNode.*; +import static com.oracle.graal.phases.GraalOptions.*; import static com.oracle.graal.replacements.Log.*; import static com.oracle.graal.replacements.MathSubstitutionsX86.*; @@ -74,15 +77,15 @@ import com.oracle.graal.hotspot.stubs.*; import com.oracle.graal.java.*; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.HeapAccess.WriteBarrierType; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.extended.*; -import com.oracle.graal.nodes.extended.WriteNode.WriteBarrierType; import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind; import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.nodes.spi.Lowerable.LoweringType; import com.oracle.graal.nodes.type.*; import com.oracle.graal.nodes.virtual.*; -import com.oracle.graal.phases.*; import com.oracle.graal.printer.*; import com.oracle.graal.replacements.*; import com.oracle.graal.word.*; @@ -95,6 +98,7 @@ public static final ForeignCallDescriptor OSR_MIGRATION_END = new ForeignCallDescriptor("OSR_migration_end", void.class, long.class); public static final ForeignCallDescriptor IDENTITY_HASHCODE = new ForeignCallDescriptor("identity_hashcode", int.class, Object.class); public static final ForeignCallDescriptor VERIFY_OOP = new ForeignCallDescriptor("verify_oop", Object.class, Object.class); + public static final ForeignCallDescriptor LOAD_AND_CLEAR_EXCEPTION = new ForeignCallDescriptor("load_and_clear_exception", Object.class, Word.class); public final HotSpotVMConfig config; @@ -190,18 +194,29 @@ /** * Creates and registers the details for linking a foreign call to a {@link Stub}. + * + * @param reexecutable specifies if the stub call can be re-executed without (meaningful) side + * effects. Deoptimization will not return to a point before a stub call that cannot + * be re-executed. + * @param killedLocations the memory locations killed by the stub call */ - protected HotSpotForeignCallLinkage registerStubCall(ForeignCallDescriptor descriptor) { - return register(HotSpotForeignCallLinkage.create(descriptor, 0L, PRESERVES_REGISTERS, JavaCallee, NOT_LEAF)); + protected HotSpotForeignCallLinkage registerStubCall(ForeignCallDescriptor descriptor, boolean reexecutable, LocationIdentity... killedLocations) { + return register(HotSpotForeignCallLinkage.create(descriptor, 0L, PRESERVES_REGISTERS, JavaCallee, NOT_LEAF, reexecutable, killedLocations)); } /** * Creates and registers the linkage for a foreign call. + * + * @param reexecutable specifies if the stub call can be re-executed without (meaningful) side + * effects. Deoptimization will not return to a point before a stub call that cannot + * be re-executed. + * @param killedLocations the memory locations killed by the stub call */ - protected HotSpotForeignCallLinkage registerForeignCall(ForeignCallDescriptor descriptor, long address, CallingConvention.Type ccType, RegisterEffect effect, Transition transition) { + protected HotSpotForeignCallLinkage registerForeignCall(ForeignCallDescriptor descriptor, long address, CallingConvention.Type ccType, RegisterEffect effect, Transition transition, + boolean reexecutable, LocationIdentity... killedLocations) { Class resultType = descriptor.getResultType(); - assert resultType.isPrimitive() || Word.class.isAssignableFrom(resultType) : "foreign calls must return objects in thread local storage: " + descriptor; - return register(HotSpotForeignCallLinkage.create(descriptor, address, effect, ccType, transition)); + assert transition == LEAF || resultType.isPrimitive() || Word.class.isAssignableFrom(resultType) : "non-leaf foreign calls must return objects in thread local storage: " + descriptor; + return register(HotSpotForeignCallLinkage.create(descriptor, address, effect, ccType, transition, reexecutable, killedLocations)); } private static void link(Stub stub) { @@ -215,9 +230,13 @@ * @param address the address of the code to call * @param prependThread true if the JavaThread value for the current thread is to be prepended * to the arguments for the call to {@code address} + * @param reexecutable specifies if the foreign call can be re-executed without (meaningful) + * side effects. Deoptimization will not return to a point before a foreign call that + * cannot be re-executed. + * @param killedLocations the memory locations killed by the foreign call */ - private void linkForeignCall(ForeignCallDescriptor descriptor, long address, boolean prependThread, Replacements replacements) { - ForeignCallStub stub = new ForeignCallStub(address, descriptor, prependThread, this, replacements); + private void linkForeignCall(Replacements replacements, ForeignCallDescriptor descriptor, long address, boolean prependThread, boolean reexecutable, LocationIdentity... killedLocations) { + ForeignCallStub stub = new ForeignCallStub(this, replacements, address, descriptor, prependThread, reexecutable, killedLocations); HotSpotForeignCallLinkage linkage = stub.getLinkage(); HotSpotForeignCallLinkage targetLinkage = stub.getTargetLinkage(); linkage.setCompiledStub(stub); @@ -225,78 +244,87 @@ register(targetLinkage); } - public void registerReplacements(Replacements replacements) { + public static final boolean PREPEND_THREAD = true; + public static final boolean DONT_PREPEND_THREAD = !PREPEND_THREAD; + + public static final boolean REEXECUTABLE = true; + public static final boolean NOT_REEXECUTABLE = !REEXECUTABLE; + + public static final LocationIdentity[] NO_LOCATIONS = {}; + + public void registerReplacements(Replacements r) { HotSpotVMConfig c = config; TargetDescription target = getTarget(); - registerForeignCall(UNCOMMON_TRAP, c.uncommonTrapStub, NativeCall, PRESERVES_REGISTERS, LEAF); - registerForeignCall(DEOPT_HANDLER, c.handleDeoptStub, NativeCall, PRESERVES_REGISTERS, LEAF); - registerForeignCall(IC_MISS_HANDLER, c.inlineCacheMissStub, NativeCall, PRESERVES_REGISTERS, LEAF); + registerForeignCall(UNCOMMON_TRAP, c.uncommonTrapStub, NativeCall, PRESERVES_REGISTERS, LEAF, REEXECUTABLE, NO_LOCATIONS); + registerForeignCall(DEOPT_HANDLER, c.handleDeoptStub, NativeCall, PRESERVES_REGISTERS, LEAF, REEXECUTABLE, NO_LOCATIONS); + registerForeignCall(IC_MISS_HANDLER, c.inlineCacheMissStub, NativeCall, PRESERVES_REGISTERS, LEAF, REEXECUTABLE, NO_LOCATIONS); - registerForeignCall(JAVA_TIME_MILLIS, c.javaTimeMillisAddress, NativeCall, DESTROYS_REGISTERS, LEAF); - registerForeignCall(JAVA_TIME_NANOS, c.javaTimeNanosAddress, NativeCall, DESTROYS_REGISTERS, LEAF); - registerForeignCall(ARITHMETIC_SIN, c.arithmeticSinAddress, NativeCall, DESTROYS_REGISTERS, LEAF); - registerForeignCall(ARITHMETIC_COS, c.arithmeticCosAddress, NativeCall, DESTROYS_REGISTERS, LEAF); - registerForeignCall(ARITHMETIC_TAN, c.arithmeticTanAddress, NativeCall, DESTROYS_REGISTERS, LEAF); + registerForeignCall(JAVA_TIME_MILLIS, c.javaTimeMillisAddress, NativeCall, DESTROYS_REGISTERS, LEAF, REEXECUTABLE, NO_LOCATIONS); + registerForeignCall(JAVA_TIME_NANOS, c.javaTimeNanosAddress, NativeCall, DESTROYS_REGISTERS, LEAF, REEXECUTABLE, NO_LOCATIONS); + registerForeignCall(ARITHMETIC_SIN, c.arithmeticSinAddress, NativeCall, DESTROYS_REGISTERS, LEAF, REEXECUTABLE, NO_LOCATIONS); + registerForeignCall(ARITHMETIC_COS, c.arithmeticCosAddress, NativeCall, DESTROYS_REGISTERS, LEAF, REEXECUTABLE, NO_LOCATIONS); + registerForeignCall(ARITHMETIC_TAN, c.arithmeticTanAddress, NativeCall, DESTROYS_REGISTERS, LEAF, REEXECUTABLE, NO_LOCATIONS); + registerForeignCall(LOAD_AND_CLEAR_EXCEPTION, c.loadAndClearExceptionAddress, NativeCall, DESTROYS_REGISTERS, LEAF, NOT_REEXECUTABLE, ANY_LOCATION); - registerForeignCall(EXCEPTION_HANDLER_FOR_PC, c.exceptionHandlerForPcAddress, NativeCall, DESTROYS_REGISTERS, NOT_LEAF); - registerForeignCall(EXCEPTION_HANDLER_FOR_RETURN_ADDRESS, c.exceptionHandlerForReturnAddressAddress, NativeCall, DESTROYS_REGISTERS, NOT_LEAF); - registerForeignCall(NEW_ARRAY_C, c.newArrayAddress, NativeCall, DESTROYS_REGISTERS, NOT_LEAF); - registerForeignCall(NEW_INSTANCE_C, c.newInstanceAddress, NativeCall, DESTROYS_REGISTERS, NOT_LEAF); - registerForeignCall(VM_MESSAGE_C, c.vmMessageAddress, NativeCall, DESTROYS_REGISTERS, NOT_LEAF); + registerForeignCall(EXCEPTION_HANDLER_FOR_PC, c.exceptionHandlerForPcAddress, NativeCall, DESTROYS_REGISTERS, NOT_LEAF, REEXECUTABLE, ANY_LOCATION); + registerForeignCall(EXCEPTION_HANDLER_FOR_RETURN_ADDRESS, c.exceptionHandlerForReturnAddressAddress, NativeCall, DESTROYS_REGISTERS, NOT_LEAF, REEXECUTABLE, ANY_LOCATION); + registerForeignCall(NEW_ARRAY_C, c.newArrayAddress, NativeCall, DESTROYS_REGISTERS, NOT_LEAF, REEXECUTABLE, ANY_LOCATION); + registerForeignCall(NEW_INSTANCE_C, c.newInstanceAddress, NativeCall, DESTROYS_REGISTERS, NOT_LEAF, REEXECUTABLE, ANY_LOCATION); + registerForeignCall(VM_MESSAGE_C, c.vmMessageAddress, NativeCall, DESTROYS_REGISTERS, NOT_LEAF, REEXECUTABLE, NO_LOCATIONS); - link(new NewInstanceStub(this, replacements, target, registerStubCall(NEW_INSTANCE))); - link(new NewArrayStub(this, replacements, target, registerStubCall(NEW_ARRAY))); - link(new ExceptionHandlerStub(this, replacements, target, foreignCalls.get(EXCEPTION_HANDLER))); - link(new UnwindExceptionToCallerStub(this, replacements, target, registerStubCall(UNWIND_EXCEPTION_TO_CALLER))); - link(new VerifyOopStub(this, replacements, target, registerStubCall(VERIFY_OOP))); + link(new NewInstanceStub(this, r, target, registerStubCall(NEW_INSTANCE, REEXECUTABLE, ANY_LOCATION))); + link(new NewArrayStub(this, r, target, registerStubCall(NEW_ARRAY, REEXECUTABLE, ANY_LOCATION))); + link(new ExceptionHandlerStub(this, r, target, foreignCalls.get(EXCEPTION_HANDLER))); + link(new UnwindExceptionToCallerStub(this, r, target, registerStubCall(UNWIND_EXCEPTION_TO_CALLER, NOT_REEXECUTABLE, ANY_LOCATION))); + link(new VerifyOopStub(this, r, target, registerStubCall(VERIFY_OOP, REEXECUTABLE, NO_LOCATIONS))); - linkForeignCall(IDENTITY_HASHCODE, c.identityHashCodeAddress, true, replacements); - linkForeignCall(REGISTER_FINALIZER, c.registerFinalizerAddress, true, replacements); - linkForeignCall(CREATE_NULL_POINTER_EXCEPTION, c.createNullPointerExceptionAddress, true, replacements); - linkForeignCall(CREATE_OUT_OF_BOUNDS_EXCEPTION, c.createOutOfBoundsExceptionAddress, true, replacements); - linkForeignCall(MONITORENTER, c.monitorenterAddress, true, replacements); - linkForeignCall(MONITOREXIT, c.monitorexitAddress, true, replacements); - linkForeignCall(WRITE_BARRIER_PRE, c.writeBarrierPreAddress, true, replacements); - linkForeignCall(WRITE_BARRIER_POST, c.writeBarrierPostAddress, true, replacements); - linkForeignCall(NEW_MULTI_ARRAY, c.newMultiArrayAddress, true, replacements); - linkForeignCall(LOG_PRINTF, c.logPrintfAddress, true, replacements); - linkForeignCall(LOG_OBJECT, c.logObjectAddress, true, replacements); - linkForeignCall(LOG_PRIMITIVE, c.logPrimitiveAddress, true, replacements); - linkForeignCall(THREAD_IS_INTERRUPTED, c.threadIsInterruptedAddress, true, replacements); - linkForeignCall(VM_ERROR, c.vmErrorAddress, true, replacements); - linkForeignCall(OSR_MIGRATION_END, c.osrMigrationEndAddress, false, replacements); + linkForeignCall(r, IDENTITY_HASHCODE, c.identityHashCodeAddress, PREPEND_THREAD, NOT_REEXECUTABLE, MARK_WORD_LOCATION); + linkForeignCall(r, REGISTER_FINALIZER, c.registerFinalizerAddress, PREPEND_THREAD, NOT_REEXECUTABLE, ANY_LOCATION); + linkForeignCall(r, CREATE_NULL_POINTER_EXCEPTION, c.createNullPointerExceptionAddress, PREPEND_THREAD, REEXECUTABLE, ANY_LOCATION); + linkForeignCall(r, CREATE_OUT_OF_BOUNDS_EXCEPTION, c.createOutOfBoundsExceptionAddress, PREPEND_THREAD, REEXECUTABLE, ANY_LOCATION); + linkForeignCall(r, MONITORENTER, c.monitorenterAddress, PREPEND_THREAD, NOT_REEXECUTABLE, ANY_LOCATION); + linkForeignCall(r, MONITOREXIT, c.monitorexitAddress, PREPEND_THREAD, NOT_REEXECUTABLE, ANY_LOCATION); + linkForeignCall(r, WRITE_BARRIER_PRE, c.writeBarrierPreAddress, PREPEND_THREAD, NOT_REEXECUTABLE, ANY_LOCATION); + linkForeignCall(r, WRITE_BARRIER_POST, c.writeBarrierPostAddress, PREPEND_THREAD, NOT_REEXECUTABLE, ANY_LOCATION); + linkForeignCall(r, NEW_MULTI_ARRAY, c.newMultiArrayAddress, PREPEND_THREAD, NOT_REEXECUTABLE, ANY_LOCATION); + linkForeignCall(r, LOG_PRINTF, c.logPrintfAddress, PREPEND_THREAD, REEXECUTABLE, NO_LOCATIONS); + linkForeignCall(r, LOG_OBJECT, c.logObjectAddress, PREPEND_THREAD, REEXECUTABLE, NO_LOCATIONS); + linkForeignCall(r, LOG_PRIMITIVE, c.logPrimitiveAddress, PREPEND_THREAD, REEXECUTABLE, NO_LOCATIONS); + linkForeignCall(r, THREAD_IS_INTERRUPTED, c.threadIsInterruptedAddress, PREPEND_THREAD, NOT_REEXECUTABLE, ANY_LOCATION); + linkForeignCall(r, VM_ERROR, c.vmErrorAddress, PREPEND_THREAD, REEXECUTABLE, NO_LOCATIONS); + linkForeignCall(r, OSR_MIGRATION_END, c.osrMigrationEndAddress, DONT_PREPEND_THREAD, NOT_REEXECUTABLE, NO_LOCATIONS); - if (GraalOptions.IntrinsifyObjectMethods) { - replacements.registerSubstitutions(ObjectSubstitutions.class); + if (IntrinsifyObjectMethods.getValue()) { + r.registerSubstitutions(ObjectSubstitutions.class); } - if (GraalOptions.IntrinsifySystemMethods) { - replacements.registerSubstitutions(SystemSubstitutions.class); + if (IntrinsifySystemMethods.getValue()) { + r.registerSubstitutions(SystemSubstitutions.class); } - if (GraalOptions.IntrinsifyThreadMethods) { - replacements.registerSubstitutions(ThreadSubstitutions.class); + if (IntrinsifyThreadMethods.getValue()) { + r.registerSubstitutions(ThreadSubstitutions.class); } - if (GraalOptions.IntrinsifyUnsafeMethods) { - replacements.registerSubstitutions(UnsafeSubstitutions.class); + if (IntrinsifyUnsafeMethods.getValue()) { + r.registerSubstitutions(UnsafeSubstitutions.class); } - if (GraalOptions.IntrinsifyClassMethods) { - replacements.registerSubstitutions(ClassSubstitutions.class); + if (IntrinsifyClassMethods.getValue()) { + r.registerSubstitutions(ClassSubstitutions.class); } - if (GraalOptions.IntrinsifyAESMethods) { - replacements.registerSubstitutions(AESCryptSubstitutions.class); - replacements.registerSubstitutions(CipherBlockChainingSubstitutions.class); + if (IntrinsifyAESMethods.getValue()) { + r.registerSubstitutions(AESCryptSubstitutions.class); + r.registerSubstitutions(CipherBlockChainingSubstitutions.class); } - if (GraalOptions.IntrinsifyReflectionMethods) { - replacements.registerSubstitutions(ReflectionSubstitutions.class); + if (IntrinsifyReflectionMethods.getValue()) { + r.registerSubstitutions(ReflectionSubstitutions.class); } - checkcastSnippets = new CheckCastSnippets.Templates(this, replacements, graalRuntime.getTarget()); - instanceofSnippets = new InstanceOfSnippets.Templates(this, replacements, graalRuntime.getTarget()); - newObjectSnippets = new NewObjectSnippets.Templates(this, replacements, graalRuntime.getTarget()); - monitorSnippets = new MonitorSnippets.Templates(this, replacements, graalRuntime.getTarget(), c.useFastLocking); - writeBarrierSnippets = new WriteBarrierSnippets.Templates(this, replacements, graalRuntime.getTarget()); - boxingSnippets = new BoxingSnippets.Templates(this, replacements, graalRuntime.getTarget()); - exceptionObjectSnippets = new LoadExceptionObjectSnippets.Templates(this, replacements, graalRuntime.getTarget()); + checkcastSnippets = new CheckCastSnippets.Templates(this, r, graalRuntime.getTarget()); + instanceofSnippets = new InstanceOfSnippets.Templates(this, r, graalRuntime.getTarget()); + newObjectSnippets = new NewObjectSnippets.Templates(this, r, graalRuntime.getTarget()); + monitorSnippets = new MonitorSnippets.Templates(this, r, graalRuntime.getTarget(), c.useFastLocking); + writeBarrierSnippets = new WriteBarrierSnippets.Templates(this, r, graalRuntime.getTarget()); + boxingSnippets = new BoxingSnippets.Templates(this, r, graalRuntime.getTarget()); + exceptionObjectSnippets = new LoadExceptionObjectSnippets.Templates(this, r, graalRuntime.getTarget()); } public HotSpotGraalRuntime getGraalRuntime() { @@ -449,7 +477,8 @@ if (n instanceof ArrayLengthNode) { ArrayLengthNode arrayLengthNode = (ArrayLengthNode) n; ValueNode array = arrayLengthNode.array(); - ReadNode arrayLengthRead = graph.add(new ReadNode(array, ConstantLocationNode.create(LocationNode.FINAL_LOCATION, Kind.Int, config.arrayLengthOffset, graph), StampFactory.positiveInt())); + ReadNode arrayLengthRead = graph.add(new ReadNode(array, ConstantLocationNode.create(FINAL_LOCATION, Kind.Int, config.arrayLengthOffset, graph), StampFactory.positiveInt(), + WriteBarrierType.NONE, false)); tool.createNullCheckGuard(arrayLengthRead, array); graph.replaceFixedWithFixed(arrayLengthNode, arrayLengthRead); } else if (n instanceof Invoke) { @@ -464,7 +493,7 @@ JavaType[] signature = MetaUtil.signatureToTypes(callTarget.targetMethod().getSignature(), callTarget.isStatic() ? null : callTarget.targetMethod().getDeclaringClass()); LoweredCallTargetNode loweredCallTarget = null; - if (callTarget.invokeKind() == InvokeKind.Virtual && GraalOptions.InlineVTableStubs && (GraalOptions.AlwaysInlineVTableStubs || invoke.isPolymorphic())) { + if (callTarget.invokeKind() == InvokeKind.Virtual && InlineVTableStubs.getValue() && (AlwaysInlineVTableStubs.getValue() || invoke.isPolymorphic())) { HotSpotResolvedJavaMethod hsMethod = (HotSpotResolvedJavaMethod) callTarget.targetMethod(); if (!hsMethod.getDeclaringClass().isInterface()) { @@ -476,8 +505,8 @@ // We use LocationNode.ANY_LOCATION for the reads that access the // compiled code entry as HotSpot does not guarantee they are final // values. - ReadNode compiledEntry = graph.add(new ReadNode(metaspaceMethod, ConstantLocationNode.create(LocationNode.ANY_LOCATION, wordKind, config.methodCompiledEntryOffset, graph), - StampFactory.forKind(wordKind()))); + ReadNode compiledEntry = graph.add(new ReadNode(metaspaceMethod, ConstantLocationNode.create(ANY_LOCATION, wordKind, config.methodCompiledEntryOffset, graph), + StampFactory.forKind(wordKind()), WriteBarrierType.NONE, false)); loweredCallTarget = graph.add(new HotSpotIndirectCallTargetNode(metaspaceMethod, compiledEntry, parameters, invoke.asNode().stamp(), signature, callTarget.targetMethod(), CallingConvention.Type.JavaCall)); @@ -500,7 +529,8 @@ HotSpotResolvedJavaField field = (HotSpotResolvedJavaField) loadField.field(); ValueNode object = loadField.isStatic() ? ConstantNode.forObject(field.getDeclaringClass().mirror(), this, graph) : loadField.object(); assert loadField.kind() != Kind.Illegal; - ReadNode memoryRead = graph.add(new ReadNode(object, createFieldLocation(graph, field), loadField.stamp())); + ReadNode memoryRead = graph.add(new ReadNode(object, createFieldLocation(graph, field), loadField.stamp(), WriteBarrierType.NONE, + (loadField.kind() == Kind.Object && !field.getName().equals("classMirrorOffset")))); tool.createNullCheckGuard(memoryRead, object); graph.replaceFixedWithFixed(loadField, memoryRead); @@ -516,7 +546,7 @@ HotSpotResolvedJavaField field = (HotSpotResolvedJavaField) storeField.field(); ValueNode object = storeField.isStatic() ? ConstantNode.forObject(field.getDeclaringClass().mirror(), this, graph) : storeField.object(); WriteBarrierType barrierType = getFieldStoreBarrierType(storeField); - WriteNode memoryWrite = graph.add(new WriteNode(object, storeField.value(), createFieldLocation(graph, field), barrierType)); + WriteNode memoryWrite = graph.add(new WriteNode(object, storeField.value(), createFieldLocation(graph, field), barrierType, storeField.field().getKind() == Kind.Object)); tool.createNullCheckGuard(memoryWrite, object); memoryWrite.setStateAfter(storeField.stateAfter()); graph.replaceFixedWithFixed(storeField, memoryWrite); @@ -532,15 +562,18 @@ } else if (n instanceof CompareAndSwapNode) { // Separate out GC barrier semantics CompareAndSwapNode cas = (CompareAndSwapNode) n; - LocationNode location = IndexedLocationNode.create(LocationNode.ANY_LOCATION, cas.expected().kind(), cas.displacement(), cas.offset(), graph, 1); + LocationNode location = IndexedLocationNode.create(ANY_LOCATION, cas.expected().kind(), cas.displacement(), cas.offset(), graph, 1); cas.setLocation(location); cas.setWriteBarrierType(getCompareAndSwapBarrier(cas)); + if (cas.expected().kind() == Kind.Object) { + cas.setCompress(); + } } else if (n instanceof LoadIndexedNode) { LoadIndexedNode loadIndexed = (LoadIndexedNode) n; GuardingNode boundsCheck = createBoundsCheck(loadIndexed, tool); Kind elementKind = loadIndexed.elementKind(); LocationNode arrayLocation = createArrayLocation(graph, elementKind, loadIndexed.index()); - ReadNode memoryRead = graph.add(new ReadNode(loadIndexed.array(), arrayLocation, loadIndexed.stamp())); + ReadNode memoryRead = graph.add(new ReadNode(loadIndexed.array(), arrayLocation, loadIndexed.stamp(), WriteBarrierType.NONE, elementKind == Kind.Object)); memoryRead.setGuard(boundsCheck); graph.replaceFixedWithFixed(loadIndexed, memoryRead); } else if (n instanceof StoreIndexedNode) { @@ -562,7 +595,7 @@ } } else { LoadHubNode arrayClass = graph.add(new LoadHubNode(array, wordKind)); - LocationNode location = ConstantLocationNode.create(LocationNode.FINAL_LOCATION, wordKind, config.arrayClassElementOffset, graph); + LocationNode location = ConstantLocationNode.create(FINAL_LOCATION, wordKind, config.arrayClassElementOffset, graph); FloatingReadNode arrayElementKlass = graph.unique(new FloatingReadNode(arrayClass, location, null, StampFactory.forKind(wordKind()))); CheckCastDynamicNode checkcast = graph.add(new CheckCastDynamicNode(arrayElementKlass, value, true)); graph.addBeforeFixed(storeIndexed, checkcast); @@ -571,7 +604,7 @@ } } WriteBarrierType barrierType = getArrayStoreBarrierType(storeIndexed); - WriteNode memoryWrite = graph.add(new WriteNode(array, value, arrayLocation, barrierType)); + WriteNode memoryWrite = graph.add(new WriteNode(array, value, arrayLocation, barrierType, elementKind == Kind.Object)); memoryWrite.setGuard(boundsCheck); memoryWrite.setStateAfter(storeIndexed.stateAfter()); graph.replaceFixedWithFixed(storeIndexed, memoryWrite); @@ -579,18 +612,18 @@ } else if (n instanceof UnsafeLoadNode) { UnsafeLoadNode load = (UnsafeLoadNode) n; assert load.kind() != Kind.Illegal; - IndexedLocationNode location = IndexedLocationNode.create(LocationNode.ANY_LOCATION, load.accessKind(), load.displacement(), load.offset(), graph, 1); - ReadNode memoryRead = graph.add(new ReadNode(load.object(), location, load.stamp())); + IndexedLocationNode location = IndexedLocationNode.create(ANY_LOCATION, load.accessKind(), load.displacement(), load.offset(), graph, 1); + ReadNode memoryRead = graph.add(new ReadNode(load.object(), location, load.stamp(), WriteBarrierType.NONE, (!load.object().isNullConstant() && load.accessKind() == Kind.Object))); // An unsafe read must not floating outside its block as may float above an explicit // null check on its object. memoryRead.setGuard(AbstractBeginNode.prevBegin(load)); graph.replaceFixedWithFixed(load, memoryRead); } else if (n instanceof UnsafeStoreNode) { UnsafeStoreNode store = (UnsafeStoreNode) n; - IndexedLocationNode location = IndexedLocationNode.create(LocationNode.ANY_LOCATION, store.accessKind(), store.displacement(), store.offset(), graph, 1); + IndexedLocationNode location = IndexedLocationNode.create(ANY_LOCATION, store.accessKind(), store.displacement(), store.offset(), graph, 1); ValueNode object = store.object(); WriteBarrierType barrierType = getUnsafeStoreBarrierType(store); - WriteNode write = graph.add(new WriteNode(object, store.value(), location, barrierType)); + WriteNode write = graph.add(new WriteNode(object, store.value(), location, barrierType, store.value().kind() == Kind.Object)); write.setStateAfter(store.stateAfter()); graph.replaceFixedWithFixed(store, write); } else if (n instanceof LoadHubNode) { @@ -606,103 +639,115 @@ graph.replaceFixed(loadMethodNode, metaspaceMethod); } else if (n instanceof FixedGuardNode) { FixedGuardNode node = (FixedGuardNode) n; - ValueAnchorNode newAnchor = graph.add(new ValueAnchorNode(tool.createGuard(node.condition(), node.getReason(), node.getAction(), node.isNegated()).asNode())); + GuardingNode guard = tool.createGuard(node.condition(), node.getReason(), node.getAction(), node.isNegated()); + ValueAnchorNode newAnchor = graph.add(new ValueAnchorNode(guard.asNode())); + node.replaceAtUsages(guard.asNode()); graph.replaceFixedWithFixed(node, newAnchor); } else if (n instanceof CommitAllocationNode) { - CommitAllocationNode commit = (CommitAllocationNode) n; + if (tool.getLoweringType() == LoweringType.AFTER_GUARDS) { + CommitAllocationNode commit = (CommitAllocationNode) n; - ValueNode[] allocations = new ValueNode[commit.getVirtualObjects().size()]; - for (int objIndex = 0; objIndex < commit.getVirtualObjects().size(); objIndex++) { - VirtualObjectNode virtual = commit.getVirtualObjects().get(objIndex); - int entryCount = virtual.entryCount(); + ValueNode[] allocations = new ValueNode[commit.getVirtualObjects().size()]; + for (int objIndex = 0; objIndex < commit.getVirtualObjects().size(); objIndex++) { + VirtualObjectNode virtual = commit.getVirtualObjects().get(objIndex); + int entryCount = virtual.entryCount(); - FixedWithNextNode newObject; - if (virtual instanceof VirtualInstanceNode) { - newObject = graph.add(new NewInstanceNode(virtual.type(), true)); - } else { - ResolvedJavaType element = ((VirtualArrayNode) virtual).componentType(); - newObject = graph.add(new NewArrayNode(element, ConstantNode.forInt(entryCount, graph), true)); + FixedWithNextNode newObject; + if (virtual instanceof VirtualInstanceNode) { + newObject = graph.add(new NewInstanceNode(virtual.type(), true)); + } else { + ResolvedJavaType element = ((VirtualArrayNode) virtual).componentType(); + newObject = graph.add(new NewArrayNode(element, ConstantNode.forInt(entryCount, graph), true)); + } + graph.addBeforeFixed(commit, newObject); + allocations[objIndex] = newObject; } - graph.addBeforeFixed(commit, newObject); - allocations[objIndex] = newObject; - } - int valuePos = 0; - for (int objIndex = 0; objIndex < commit.getVirtualObjects().size(); objIndex++) { - VirtualObjectNode virtual = commit.getVirtualObjects().get(objIndex); - int entryCount = virtual.entryCount(); + int valuePos = 0; + for (int objIndex = 0; objIndex < commit.getVirtualObjects().size(); objIndex++) { + VirtualObjectNode virtual = commit.getVirtualObjects().get(objIndex); + int entryCount = virtual.entryCount(); - ValueNode newObject = allocations[objIndex]; - if (virtual instanceof VirtualInstanceNode) { - VirtualInstanceNode instance = (VirtualInstanceNode) virtual; - for (int i = 0; i < entryCount; i++) { - ValueNode value = commit.getValues().get(valuePos++); - if (value instanceof VirtualObjectNode) { - value = allocations[commit.getVirtualObjects().indexOf(value)]; - } - if (!(value.isConstant() && value.asConstant().isDefaultForKind())) { - graph.addBeforeFixed(commit, graph.add(new WriteNode(newObject, value, createFieldLocation(graph, (HotSpotResolvedJavaField) instance.field(i)), WriteBarrierType.NONE))); + ValueNode newObject = allocations[objIndex]; + if (virtual instanceof VirtualInstanceNode) { + VirtualInstanceNode instance = (VirtualInstanceNode) virtual; + for (int i = 0; i < entryCount; i++) { + ValueNode value = commit.getValues().get(valuePos++); + if (value instanceof VirtualObjectNode) { + value = allocations[commit.getVirtualObjects().indexOf(value)]; + } + if (!(value.isConstant() && value.asConstant().isDefaultForKind())) { + WriteNode write = new WriteNode(newObject, value, createFieldLocation(graph, (HotSpotResolvedJavaField) instance.field(i)), WriteBarrierType.NONE, + instance.field(i).getKind() == Kind.Object); + + graph.addBeforeFixed(commit, graph.add(write)); + } } - } - } else { - VirtualArrayNode array = (VirtualArrayNode) virtual; - ResolvedJavaType element = array.componentType(); - for (int i = 0; i < entryCount; i++) { - ValueNode value = commit.getValues().get(valuePos++); - if (value instanceof VirtualObjectNode) { - int indexOf = commit.getVirtualObjects().indexOf(value); - assert indexOf != -1 : commit + " " + value; - value = allocations[indexOf]; - } - if (!(value.isConstant() && value.asConstant().isDefaultForKind())) { - graph.addBeforeFixed(commit, - graph.add(new WriteNode(newObject, value, createArrayLocation(graph, element.getKind(), ConstantNode.forInt(i, graph)), WriteBarrierType.NONE))); + + } else { + VirtualArrayNode array = (VirtualArrayNode) virtual; + ResolvedJavaType element = array.componentType(); + for (int i = 0; i < entryCount; i++) { + ValueNode value = commit.getValues().get(valuePos++); + if (value instanceof VirtualObjectNode) { + int indexOf = commit.getVirtualObjects().indexOf(value); + assert indexOf != -1 : commit + " " + value; + value = allocations[indexOf]; + } + if (!(value.isConstant() && value.asConstant().isDefaultForKind())) { + WriteNode write = new WriteNode(newObject, value, createArrayLocation(graph, element.getKind(), ConstantNode.forInt(i, graph)), WriteBarrierType.NONE, + value.kind() == Kind.Object); + graph.addBeforeFixed(commit, graph.add(write)); + } } } } - } - for (int objIndex = 0; objIndex < commit.getVirtualObjects().size(); objIndex++) { - FixedValueAnchorNode anchor = graph.add(new FixedValueAnchorNode(allocations[objIndex])); - allocations[objIndex] = anchor; - graph.addBeforeFixed(commit, anchor); + for (int objIndex = 0; objIndex < commit.getVirtualObjects().size(); objIndex++) { + FixedValueAnchorNode anchor = graph.add(new FixedValueAnchorNode(allocations[objIndex])); + allocations[objIndex] = anchor; + graph.addBeforeFixed(commit, anchor); + } + for (int objIndex = 0; objIndex < commit.getVirtualObjects().size(); objIndex++) { + for (int lockDepth : commit.getLocks().get(objIndex)) { + MonitorEnterNode enter = graph.add(new MonitorEnterNode(allocations[objIndex], lockDepth)); + graph.addBeforeFixed(commit, enter); + } + } + for (Node usage : commit.usages().snapshot()) { + AllocatedObjectNode addObject = (AllocatedObjectNode) usage; + int index = commit.getVirtualObjects().indexOf(addObject.getVirtualObject()); + graph.replaceFloating(addObject, allocations[index]); + } + graph.removeFixed(commit); } - for (int objIndex = 0; objIndex < commit.getVirtualObjects().size(); objIndex++) { - for (int lockDepth : commit.getLocks().get(objIndex)) { - MonitorEnterNode enter = graph.add(new MonitorEnterNode(allocations[objIndex], lockDepth)); - graph.addBeforeFixed(commit, enter); - } - } - for (Node usage : commit.usages().snapshot()) { - AllocatedObjectNode addObject = (AllocatedObjectNode) usage; - int index = commit.getVirtualObjects().indexOf(addObject.getVirtualObject()); - graph.replaceFloating(addObject, allocations[index]); - } - graph.removeFixed(commit); } else if (n instanceof CheckCastNode) { checkcastSnippets.lower((CheckCastNode) n, tool); } else if (n instanceof OSRStartNode) { - OSRStartNode osrStart = (OSRStartNode) n; - StartNode newStart = graph.add(new StartNode()); - LocalNode buffer = graph.unique(new LocalNode(0, StampFactory.forKind(wordKind()))); - ForeignCallNode migrationEnd = graph.add(new ForeignCallNode(OSR_MIGRATION_END, buffer)); - newStart.setStateAfter(osrStart.stateAfter()); + if (tool.getLoweringType() == LoweringType.AFTER_GUARDS) { + OSRStartNode osrStart = (OSRStartNode) n; + StartNode newStart = graph.add(new StartNode()); + LocalNode buffer = graph.unique(new LocalNode(0, StampFactory.forKind(wordKind()))); + ForeignCallNode migrationEnd = graph.add(new ForeignCallNode(this, OSR_MIGRATION_END, buffer)); + migrationEnd.setStateAfter(osrStart.stateAfter()); - newStart.setNext(migrationEnd); - FixedNode next = osrStart.next(); - osrStart.setNext(null); - migrationEnd.setNext(next); - graph.setStart(newStart); + newStart.setNext(migrationEnd); + FixedNode next = osrStart.next(); + osrStart.setNext(null); + migrationEnd.setNext(next); + graph.setStart(newStart); - // mirroring the calculations in c1_GraphBuilder.cpp (setup_osr_entry_block) - int localsOffset = (graph.method().getMaxLocals() - 1) * 8; - for (OSRLocalNode osrLocal : graph.getNodes(OSRLocalNode.class)) { - int size = FrameStateBuilder.stackSlots(osrLocal.kind()); - int offset = localsOffset - (osrLocal.index() + size - 1) * 8; - UnsafeLoadNode load = graph.add(new UnsafeLoadNode(buffer, offset, ConstantNode.forInt(0, graph), osrLocal.kind())); - osrLocal.replaceAndDelete(load); - graph.addBeforeFixed(migrationEnd, load); + // mirroring the calculations in c1_GraphBuilder.cpp (setup_osr_entry_block) + int localsOffset = (graph.method().getMaxLocals() - 1) * 8; + for (OSRLocalNode osrLocal : graph.getNodes(OSRLocalNode.class)) { + int size = FrameStateBuilder.stackSlots(osrLocal.kind()); + int offset = localsOffset - (osrLocal.index() + size - 1) * 8; + IndexedLocationNode location = IndexedLocationNode.create(ANY_LOCATION, osrLocal.kind(), offset, ConstantNode.forLong(0, graph), graph, 1); + ReadNode load = graph.add(new ReadNode(buffer, location, osrLocal.stamp(), WriteBarrierType.NONE, false)); + osrLocal.replaceAndDelete(load); + graph.addBeforeFixed(migrationEnd, load); + } + osrStart.replaceAtUsages(newStart); + osrStart.safeDelete(); } - osrStart.replaceAtUsages(newStart); - osrStart.safeDelete(); } else if (n instanceof CheckCastDynamicNode) { checkcastSnippets.lower((CheckCastDynamicNode) n); } else if (n instanceof InstanceOfNode) { @@ -710,19 +755,29 @@ } else if (n instanceof InstanceOfDynamicNode) { instanceofSnippets.lower((InstanceOfDynamicNode) n, tool); } else if (n instanceof NewInstanceNode) { - newObjectSnippets.lower((NewInstanceNode) n); + if (tool.getLoweringType() == LoweringType.AFTER_GUARDS) { + newObjectSnippets.lower((NewInstanceNode) n); + } } else if (n instanceof NewArrayNode) { - newObjectSnippets.lower((NewArrayNode) n); + if (tool.getLoweringType() == LoweringType.AFTER_GUARDS) { + newObjectSnippets.lower((NewArrayNode) n); + } } else if (n instanceof MonitorEnterNode) { - monitorSnippets.lower((MonitorEnterNode) n, tool); + if (tool.getLoweringType() == LoweringType.AFTER_GUARDS) { + monitorSnippets.lower((MonitorEnterNode) n, tool); + } } else if (n instanceof MonitorExitNode) { - monitorSnippets.lower((MonitorExitNode) n, tool); + if (tool.getLoweringType() == LoweringType.AFTER_GUARDS) { + monitorSnippets.lower((MonitorExitNode) n, tool); + } } else if (n instanceof SerialWriteBarrier) { writeBarrierSnippets.lower((SerialWriteBarrier) n, tool); } else if (n instanceof SerialArrayRangeWriteBarrier) { writeBarrierSnippets.lower((SerialArrayRangeWriteBarrier) n, tool); } else if (n instanceof NewMultiArrayNode) { - newObjectSnippets.lower((NewMultiArrayNode) n); + if (tool.getLoweringType() == LoweringType.AFTER_GUARDS) { + newObjectSnippets.lower((NewMultiArrayNode) n); + } } else if (n instanceof LoadExceptionObjectNode) { exceptionObjectSnippets.lower((LoadExceptionObjectNode) n); } else if (n instanceof IntegerDivNode || n instanceof IntegerRemNode || n instanceof UnsignedDivNode || n instanceof UnsignedRemNode) { @@ -749,14 +804,15 @@ assert vtableEntryOffset > 0; // We use LocationNode.ANY_LOCATION for the reads that access the vtable // entry as HotSpot does not guarantee that this is a final value. - ReadNode metaspaceMethod = graph.add(new ReadNode(hub, ConstantLocationNode.create(LocationNode.ANY_LOCATION, wordKind, vtableEntryOffset, graph), StampFactory.forKind(wordKind()))); + ReadNode metaspaceMethod = graph.add(new ReadNode(hub, ConstantLocationNode.create(ANY_LOCATION, wordKind, vtableEntryOffset, graph), StampFactory.forKind(wordKind()), WriteBarrierType.NONE, + false)); return metaspaceMethod; } private ReadNode createReadHub(LoweringTool tool, StructuredGraph graph, Kind wordKind, ValueNode object) { - LocationNode location = ConstantLocationNode.create(LocationNode.FINAL_LOCATION, wordKind, config.hubOffset, graph); + LocationNode location = ConstantLocationNode.create(FINAL_LOCATION, wordKind, config.hubOffset, graph); assert !object.isConstant() || object.asConstant().isNull(); - ReadNode hub = graph.add(new ReadNode(object, location, StampFactory.forKind(wordKind()))); + ReadNode hub = graph.add(new ReadNode(object, location, StampFactory.forKind(wordKind()), WriteBarrierType.NONE, false)); tool.createNullCheckGuard(hub, object); return hub; } @@ -807,9 +863,17 @@ return ConstantLocationNode.create(field, field.getKind(), field.offset(), graph); } + public int getScalingFactor(Kind kind) { + if (config.useCompressedOops && kind == Kind.Object) { + return this.graalRuntime.getTarget().arch.getSizeInBytes(Kind.Int); + } else { + return this.graalRuntime.getTarget().arch.getSizeInBytes(kind); + } + } + protected IndexedLocationNode createArrayLocation(Graph graph, Kind elementKind, ValueNode index) { - int scale = this.graalRuntime.getTarget().arch.getSizeInBytes(elementKind); - return IndexedLocationNode.create(LocationNode.getArrayLocation(elementKind), elementKind, getArrayBaseOffset(elementKind), index, graph, scale); + int scale = getScalingFactor(elementKind); + return IndexedLocationNode.create(NamedLocationIdentity.getArrayLocation(elementKind), elementKind, getArrayBaseOffset(elementKind), index, graph, scale); } private static GuardingNode createBoundsCheck(AccessIndexedNode n, LoweringTool tool) { @@ -967,12 +1031,16 @@ } @Override - public boolean hasSideEffect(ForeignCallDescriptor descriptor) { - // Only these two foreign calls are expected to be made with - // a node that implements StateSplit. They need to be a state - // split so that the stack trace they produce is accurate. - assert descriptor == CREATE_NULL_POINTER_EXCEPTION || descriptor == CREATE_OUT_OF_BOUNDS_EXCEPTION : descriptor; - return false; + public boolean isReexecutable(ForeignCallDescriptor descriptor) { + return foreignCalls.get(descriptor).isReexecutable(); + } + + public boolean canDeoptimize(ForeignCallDescriptor descriptor) { + return foreignCalls.get(descriptor).canDeoptimize(); + } + + public LocationIdentity[] getKilledLocations(ForeignCallDescriptor descriptor) { + return foreignCalls.get(descriptor).getKilledLocations(); } @Override diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/BeginLockScopeNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/BeginLockScopeNode.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/BeginLockScopeNode.java Fri Jun 07 14:15:38 2013 +0200 @@ -22,6 +22,8 @@ */ package com.oracle.graal.hotspot.nodes; +import static com.oracle.graal.api.meta.LocationIdentity.*; + import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.gen.*; @@ -29,7 +31,6 @@ import com.oracle.graal.hotspot.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.extended.*; -import com.oracle.graal.nodes.extended.LocationNode.LocationIdentity; import com.oracle.graal.nodes.type.*; import com.oracle.graal.word.*; @@ -55,7 +56,7 @@ @Override public LocationIdentity[] getLocationIdentities() { - return new LocationIdentity[]{LocationNode.ANY_LOCATION}; + return new LocationIdentity[]{ANY_LOCATION}; } @Override diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/DirectCompareAndSwapNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/DirectCompareAndSwapNode.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/DirectCompareAndSwapNode.java Fri Jun 07 14:15:38 2013 +0200 @@ -22,11 +22,11 @@ */ package com.oracle.graal.hotspot.nodes; +import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.gen.*; import com.oracle.graal.compiler.target.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.extended.LocationNode.LocationIdentity; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.java.*; import com.oracle.graal.word.*; diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/EndLockScopeNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/EndLockScopeNode.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/EndLockScopeNode.java Fri Jun 07 14:15:38 2013 +0200 @@ -22,11 +22,13 @@ */ package com.oracle.graal.hotspot.nodes; +import static com.oracle.graal.api.meta.LocationIdentity.*; + +import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.gen.*; import com.oracle.graal.compiler.target.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.extended.*; -import com.oracle.graal.nodes.extended.LocationNode.LocationIdentity; import com.oracle.graal.nodes.type.*; /** @@ -46,7 +48,7 @@ @Override public LocationIdentity[] getLocationIdentities() { - return new LocationIdentity[]{LocationNode.ANY_LOCATION}; + return new LocationIdentity[]{ANY_LOCATION}; } @Override diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/HotSpotNmethodExecuteNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/HotSpotNmethodExecuteNode.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/HotSpotNmethodExecuteNode.java Fri Jun 07 14:15:38 2013 +0200 @@ -30,7 +30,6 @@ import com.oracle.graal.hotspot.replacements.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.extended.*; -import com.oracle.graal.nodes.extended.LocationNode.LocationIdentity; import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -49,7 +48,7 @@ @Override public LocationIdentity[] getLocationIdentities() { - return new LocationIdentity[]{LocationNode.ANY_LOCATION}; + return new LocationIdentity[]{LocationIdentity.ANY_LOCATION}; } @Override diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewMultiArrayStubCall.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewMultiArrayStubCall.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewMultiArrayStubCall.java Fri Jun 07 14:15:38 2013 +0200 @@ -43,8 +43,8 @@ public static final ForeignCallDescriptor NEW_MULTI_ARRAY = new ForeignCallDescriptor("new_multi_array", Object.class, Word.class, int.class, Word.class); - public NewMultiArrayStubCall(ValueNode hub, int rank, ValueNode dims) { - super(NEW_MULTI_ARRAY, defaultStamp); + public NewMultiArrayStubCall(MetaAccessProvider runtime, ValueNode hub, int rank, ValueNode dims) { + super(runtime, NEW_MULTI_ARRAY, defaultStamp); this.hub = hub; this.rank = rank; this.dims = dims; diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/StubForeignCallNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/StubForeignCallNode.java Fri Jun 07 14:15:38 2013 +0200 @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.hotspot.nodes; + +import com.oracle.graal.api.code.*; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.extended.*; +import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.nodes.type.*; + +/** + * Node for a {@linkplain ForeignCallDescriptor foreign} call from within a stub. + */ +@NodeInfo(nameTemplate = "StubForeignCall#{p#descriptor/s}") +public class StubForeignCallNode extends FixedWithNextNode implements DeoptimizingNode, LIRLowerable, MemoryCheckpoint { + + @Input private final NodeInputList arguments; + private final MetaAccessProvider runtime; + @Input private FrameState deoptState; + + private final ForeignCallDescriptor descriptor; + + public StubForeignCallNode(MetaAccessProvider runtime, ForeignCallDescriptor descriptor, ValueNode... arguments) { + super(StampFactory.forKind(Kind.fromJavaClass(descriptor.getResultType()))); + this.arguments = new NodeInputList<>(this, arguments); + this.descriptor = descriptor; + this.runtime = runtime; + } + + public ForeignCallDescriptor getDescriptor() { + return descriptor; + } + + @Override + public LocationIdentity[] getLocationIdentities() { + return runtime.getKilledLocations(descriptor); + } + + protected Value[] operands(LIRGeneratorTool gen) { + Value[] operands = new Value[arguments.size()]; + for (int i = 0; i < operands.length; i++) { + operands[i] = gen.operand(arguments.get(i)); + } + return operands; + } + + @Override + public void generate(LIRGeneratorTool gen) { + assert graph().start() instanceof StubStartNode; + ForeignCallLinkage linkage = gen.getRuntime().lookupForeignCall(descriptor); + Value[] operands = operands(gen); + Value result = gen.emitForeignCall(linkage, this, operands); + if (result != null) { + gen.setResult(this, result); + } + } + + @Override + public String toString(Verbosity verbosity) { + if (verbosity == Verbosity.Name) { + return super.toString(verbosity) + "#" + descriptor; + } + return super.toString(verbosity); + } + + @Override + public boolean canDeoptimize() { + return false; + } + + @Override + public FrameState getDeoptimizationState() { + return null; + } + + @Override + public void setDeoptimizationState(FrameState state) { + } + + @Override + public DeoptimizationReason getDeoptimizationReason() { + return null; + } +} diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/WriteBarrierAdditionPhase.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/WriteBarrierAdditionPhase.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/WriteBarrierAdditionPhase.java Fri Jun 07 14:15:38 2013 +0200 @@ -23,8 +23,8 @@ package com.oracle.graal.hotspot.phases; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.HeapAccess.WriteBarrierType; import com.oracle.graal.nodes.extended.*; -import com.oracle.graal.nodes.extended.WriteNode.WriteBarrierType; import com.oracle.graal.nodes.java.*; import com.oracle.graal.phases.*; diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/WriteBarrierVerificationPhase.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/WriteBarrierVerificationPhase.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/WriteBarrierVerificationPhase.java Fri Jun 07 14:15:38 2013 +0200 @@ -27,8 +27,8 @@ import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.HeapAccess.WriteBarrierType; import com.oracle.graal.nodes.extended.*; -import com.oracle.graal.nodes.extended.WriteNode.WriteBarrierType; import com.oracle.graal.nodes.java.*; import com.oracle.graal.phases.*; diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/AESCryptSubstitutions.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/AESCryptSubstitutions.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/AESCryptSubstitutions.java Fri Jun 07 14:15:38 2013 +0200 @@ -66,7 +66,8 @@ } private static void crypt(Object rcvr, byte[] in, int inOffset, byte[] out, int outOffset, boolean encrypt) { - Word kAddr = Word.fromObject(rcvr).readWord(Word.unsigned(kOffset), ANY_LOCATION).add(arrayBaseOffset(Kind.Byte)); + Object kObject = UnsafeLoadNode.load(rcvr, 0, kOffset, Kind.Object); + Word kAddr = (Word) Word.fromObject(kObject).add(arrayBaseOffset(Kind.Byte)); Word inAddr = Word.unsigned(GetObjectAddressNode.get(in) + arrayBaseOffset(Kind.Byte) + inOffset); Word outAddr = Word.unsigned(GetObjectAddressNode.get(out) + arrayBaseOffset(Kind.Byte) + outOffset); if (encrypt) { diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/AbstractMethodHandleNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/AbstractMethodHandleNode.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/AbstractMethodHandleNode.java Fri Jun 07 14:15:38 2013 +0200 @@ -273,9 +273,20 @@ ValueNode[] args = replacementArguments.toArray(new ValueNode[replacementArguments.size()]); callTarget = new SelfReplacingMethodCallTargetNode(invokeKind, targetMethod, targetArguments, returnType, replacementTargetMethod, args, replacementReturnType); } + graph().add(callTarget); - graph().add(callTarget); - InvokeNode invoke = graph().add(new InvokeNode(callTarget, getBci())); + // The call target can have a different return type than the invoker, + // e.g. the target returns an Object but the invoker void. In this case + // we need to use the stamp of the invoker. Note: always using the + // invoker's stamp would be wrong because it's a less concrete type + // (usually java.lang.Object). + InvokeNode invoke; + if (callTarget.returnStamp().kind() != stamp().kind()) { + invoke = new InvokeNode(callTarget, getBci(), stamp()); + } else { + invoke = new InvokeNode(callTarget, getBci()); + } + graph().add(invoke); invoke.setStateAfter(stateAfter()); return invoke; } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopyNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopyNode.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopyNode.java Fri Jun 07 14:15:38 2013 +0200 @@ -22,6 +22,8 @@ */ package com.oracle.graal.hotspot.replacements; +import static com.oracle.graal.phases.GraalOptions.*; + import com.oracle.graal.api.meta.*; import com.oracle.graal.debug.*; import com.oracle.graal.graph.Node.IterableNodeType; @@ -29,7 +31,6 @@ import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.virtual.*; -import com.oracle.graal.phases.*; import com.oracle.graal.phases.common.*; import com.oracle.graal.phases.tiers.*; import com.oracle.graal.replacements.nodes.*; @@ -83,14 +84,14 @@ // the canonicalization before loop unrolling is needed to propagate the length into // additions, etc. HighTierContext context = new HighTierContext(tool.getRuntime(), tool.assumptions(), tool.getReplacements()); - new CanonicalizerPhase().apply(snippetGraph, context); - new LoopFullUnrollPhase().apply(snippetGraph, context); - new CanonicalizerPhase().apply(snippetGraph, context); + new CanonicalizerPhase(true).apply(snippetGraph, context); + new LoopFullUnrollPhase(true).apply(snippetGraph, context); + new CanonicalizerPhase(true).apply(snippetGraph, context); } @Override protected StructuredGraph getSnippetGraph(LoweringTool tool) { - if (!GraalOptions.IntrinsifyArrayCopy) { + if (!IntrinsifyArrayCopy.getValue()) { return null; } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopySnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopySnippets.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopySnippets.java Fri Jun 07 14:15:38 2013 +0200 @@ -22,7 +22,9 @@ */ package com.oracle.graal.hotspot.replacements; +import static com.oracle.graal.api.meta.LocationIdentity.*; import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*; +import static com.oracle.graal.phases.GraalOptions.*; import static com.oracle.graal.replacements.nodes.BranchProbabilityNode.*; import java.lang.reflect.*; @@ -313,12 +315,12 @@ } } - private static final SnippetCounter.Group checkCounters = GraalOptions.SnippetCounters ? new SnippetCounter.Group("System.arraycopy checkInputs") : null; + private static final SnippetCounter.Group checkCounters = SnippetCounters.getValue() ? new SnippetCounter.Group("System.arraycopy checkInputs") : null; private static final SnippetCounter checkSuccessCounter = new SnippetCounter(checkCounters, "checkSuccess", "checkSuccess"); private static final SnippetCounter checkNPECounter = new SnippetCounter(checkCounters, "checkNPE", "checkNPE"); private static final SnippetCounter checkAIOOBECounter = new SnippetCounter(checkCounters, "checkAIOOBE", "checkAIOOBE"); - private static final SnippetCounter.Group counters = GraalOptions.SnippetCounters ? new SnippetCounter.Group("System.arraycopy") : null; + private static final SnippetCounter.Group counters = SnippetCounters.getValue() ? new SnippetCounter.Group("System.arraycopy") : null; private static final SnippetCounter byteCounter = new SnippetCounter(counters, "byte[]", "arraycopy for byte[] arrays"); private static final SnippetCounter charCounter = new SnippetCounter(counters, "char[]", "arraycopy for char[] arrays"); private static final SnippetCounter shortCounter = new SnippetCounter(counters, "short[]", "arraycopy for short[] arrays"); diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CallSiteSubstitutions.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CallSiteSubstitutions.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CallSiteSubstitutions.java Fri Jun 07 14:15:38 2013 +0200 @@ -22,6 +22,8 @@ */ package com.oracle.graal.hotspot.replacements; +import static com.oracle.graal.phases.GraalOptions.*; + import java.lang.invoke.*; import com.oracle.graal.api.code.*; @@ -29,14 +31,13 @@ import com.oracle.graal.api.replacements.*; import com.oracle.graal.api.runtime.*; import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.phases.*; @ServiceProvider(ReplacementsProvider.class) public class CallSiteSubstitutions implements ReplacementsProvider { @Override public void registerReplacements(MetaAccessProvider runtime, Replacements replacements, TargetDescription target) { - if (GraalOptions.IntrinsifyCallSiteTarget) { + if (IntrinsifyCallSiteTarget.getValue()) { replacements.registerSubstitutions(ConstantCallSiteSubstitutions.class); replacements.registerSubstitutions(MutableCallSiteSubstitutions.class); replacements.registerSubstitutions(VolatileCallSiteSubstitutions.class); diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CheckCastSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CheckCastSnippets.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CheckCastSnippets.java Fri Jun 07 14:15:38 2013 +0200 @@ -27,10 +27,12 @@ import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*; import static com.oracle.graal.hotspot.replacements.TypeCheckSnippetUtils.*; import static com.oracle.graal.nodes.extended.UnsafeCastNode.*; +import static com.oracle.graal.phases.GraalOptions.*; import static com.oracle.graal.replacements.SnippetTemplate.*; import static com.oracle.graal.replacements.nodes.BranchProbabilityNode.*; import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; import com.oracle.graal.debug.*; import com.oracle.graal.graph.Node.NodeIntrinsic; import com.oracle.graal.hotspot.meta.*; @@ -38,7 +40,6 @@ import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; -import com.oracle.graal.phases.*; import com.oracle.graal.replacements.*; import com.oracle.graal.replacements.Snippet.ConstantParameter; import com.oracle.graal.replacements.Snippet.VarargsParameter; @@ -94,7 +95,7 @@ isNull.inc(); } else { Word objectHub = loadHub(object); - if (objectHub.readWord(superCheckOffset, FINAL_LOCATION).notEqual(hub)) { + if (objectHub.readWord(superCheckOffset, LocationIdentity.FINAL_LOCATION).notEqual(hub)) { displayMiss.inc(); DeoptimizeNode.deopt(InvalidateReprofile, ClassCastException); } @@ -167,7 +168,7 @@ StructuredGraph graph = checkcast.graph(); ValueNode object = checkcast.object(); HotSpotResolvedObjectType type = (HotSpotResolvedObjectType) checkcast.type(); - TypeCheckHints hintInfo = new TypeCheckHints(checkcast.type(), checkcast.profile(), tool.assumptions(), GraalOptions.CheckcastMinHintHitProbability, GraalOptions.CheckcastMaxHints); + TypeCheckHints hintInfo = new TypeCheckHints(checkcast.type(), checkcast.profile(), tool.assumptions(), CheckcastMinHintHitProbability.getValue(), CheckcastMaxHints.getValue()); ValueNode hub = ConstantNode.forConstant(type.klass(), runtime, checkcast.graph()); Arguments args; @@ -187,7 +188,7 @@ args = new Arguments(secondary); args.add("hub", hub); args.add("object", object); - args.addVarargs("hints", Word.class, StampFactory.forKind(wordKind()), hints); + args.addVarargs("hints", Word.class, StampFactory.forKind(getWordKind()), hints); } args.addConst("checkNull", !object.stamp().nonNull()); diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CipherBlockChainingSubstitutions.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CipherBlockChainingSubstitutions.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CipherBlockChainingSubstitutions.java Fri Jun 07 14:15:38 2013 +0200 @@ -62,7 +62,7 @@ @MethodSubstitution(isStatic = false) static void encrypt(Object rcvr, byte[] in, int inOffset, int inLength, byte[] out, int outOffset) { - Object embeddedCipher = Word.fromObject(rcvr).readObject(Word.unsigned(embeddedCipherOffset), ANY_LOCATION); + Object embeddedCipher = UnsafeLoadNode.load(rcvr, 0, embeddedCipherOffset, Kind.Object); if (getAESCryptClass().isInstance(embeddedCipher)) { crypt(rcvr, in, inOffset, inLength, out, outOffset, embeddedCipher, true); } else { @@ -72,7 +72,7 @@ @MethodSubstitution(isStatic = false) static void decrypt(Object rcvr, byte[] in, int inOffset, int inLength, byte[] out, int outOffset) { - Object embeddedCipher = Word.fromObject(rcvr).readObject(Word.unsigned(embeddedCipherOffset), ANY_LOCATION); + Object embeddedCipher = UnsafeLoadNode.load(rcvr, 0, embeddedCipherOffset, Kind.Object); if (in != out && getAESCryptClass().isInstance(embeddedCipher)) { crypt(rcvr, in, inOffset, inLength, out, outOffset, embeddedCipher, false); } else { @@ -81,8 +81,10 @@ } private static void crypt(Object rcvr, byte[] in, int inOffset, int inLength, byte[] out, int outOffset, Object embeddedCipher, boolean encrypt) { - Word kAddr = Word.fromObject(embeddedCipher).readWord(Word.unsigned(AESCryptSubstitutions.kOffset), ANY_LOCATION).add(arrayBaseOffset(Kind.Byte)); - Word rAddr = Word.unsigned(GetObjectAddressNode.get(rcvr)).readWord(Word.unsigned(rOffset), ANY_LOCATION).add(arrayBaseOffset(Kind.Byte)); + Object kObject = UnsafeLoadNode.load(embeddedCipher, 0, AESCryptSubstitutions.kOffset, Kind.Object); + Object rObject = UnsafeLoadNode.load(rcvr, 0, rOffset, Kind.Object); + Word kAddr = (Word) Word.fromObject(kObject).add(arrayBaseOffset(Kind.Byte)); + Word rAddr = (Word) Word.fromObject(rObject).add(arrayBaseOffset(Kind.Byte)); Word inAddr = Word.unsigned(GetObjectAddressNode.get(in) + arrayBaseOffset(Kind.Byte) + inOffset); Word outAddr = Word.unsigned(GetObjectAddressNode.get(out) + arrayBaseOffset(Kind.Byte) + outOffset); if (encrypt) { diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ClassSubstitutions.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ClassSubstitutions.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ClassSubstitutions.java Fri Jun 07 14:15:38 2013 +0200 @@ -27,6 +27,7 @@ import java.lang.reflect.*; +import com.oracle.graal.api.meta.*; import com.oracle.graal.api.replacements.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.word.*; @@ -44,7 +45,7 @@ // Class for primitive type return Modifier.ABSTRACT | Modifier.FINAL | Modifier.PUBLIC; } else { - return klass.readInt(klassModifierFlagsOffset(), FINAL_LOCATION); + return klass.readInt(klassModifierFlagsOffset(), LocationIdentity.FINAL_LOCATION); } } @@ -54,7 +55,7 @@ if (klass.equal(0)) { return false; } else { - int accessFlags = klass.readInt(klassAccessFlagsOffset(), FINAL_LOCATION); + int accessFlags = klass.readInt(klassAccessFlagsOffset(), LocationIdentity.FINAL_LOCATION); return (accessFlags & Modifier.INTERFACE) != 0; } } @@ -79,16 +80,16 @@ public static Class getSuperclass(final Class thisObj) { Word klass = loadWordFromObject(thisObj, klassOffset()); if (klass.notEqual(0)) { - int accessFlags = klass.readInt(klassAccessFlagsOffset(), FINAL_LOCATION); + int accessFlags = klass.readInt(klassAccessFlagsOffset(), LocationIdentity.FINAL_LOCATION); if ((accessFlags & Modifier.INTERFACE) == 0) { if ((readLayoutHelper(klass) & arrayKlassLayoutHelperIdentifier()) != 0) { return Object.class; } else { - Word superKlass = klass.readWord(klassSuperKlassOffset(), FINAL_LOCATION); + Word superKlass = klass.readWord(klassSuperKlassOffset(), LocationIdentity.FINAL_LOCATION); if (superKlass.equal(0)) { return null; } else { - return unsafeCast(superKlass.readObject(classMirrorOffset(), FINAL_LOCATION), Class.class, true, true); + return unsafeCast(superKlass.readObject(classMirrorOffset(), LocationIdentity.FINAL_LOCATION), Class.class, true, true); } } } @@ -101,7 +102,7 @@ Word klass = loadWordFromObject(thisObj, klassOffset()); if (klass.notEqual(0)) { if ((readLayoutHelper(klass) & arrayKlassLayoutHelperIdentifier()) != 0) { - return unsafeCast(klass.readObject(arrayKlassComponentMirrorOffset(), FINAL_LOCATION), Class.class, true, true); + return unsafeCast(klass.readObject(arrayKlassComponentMirrorOffset(), LocationIdentity.FINAL_LOCATION), Class.class, true, true); } } return null; diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotNmethodIntrinsics.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotNmethodIntrinsics.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotNmethodIntrinsics.java Fri Jun 07 14:15:38 2013 +0200 @@ -22,18 +22,19 @@ */ package com.oracle.graal.hotspot.replacements; +import static com.oracle.graal.phases.GraalOptions.*; + import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.api.runtime.*; import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.phases.*; @ServiceProvider(ReplacementsProvider.class) public class HotSpotNmethodIntrinsics implements ReplacementsProvider { @Override public void registerReplacements(MetaAccessProvider runtime, Replacements replacements, TargetDescription target) { - if (GraalOptions.IntrinsifyInstalledCodeMethods) { + if (IntrinsifyInstalledCodeMethods.getValue()) { replacements.registerSubstitutions(HotSpotNmethodSubstitutions.class); } } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotReplacementsUtil.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotReplacementsUtil.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotReplacementsUtil.java Fri Jun 07 14:15:38 2013 +0200 @@ -34,7 +34,6 @@ import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.nodes.extended.*; -import com.oracle.graal.nodes.extended.LocationNode.LocationIdentity; import com.oracle.graal.replacements.Snippet.Fold; import com.oracle.graal.replacements.nodes.*; import com.oracle.graal.word.*; @@ -46,9 +45,6 @@ */ public class HotSpotReplacementsUtil { - public static final LocationIdentity ANY_LOCATION = LocationNode.ANY_LOCATION; - public static final LocationIdentity FINAL_LOCATION = LocationNode.FINAL_LOCATION; - public static HotSpotVMConfig config() { return graalRuntime().getConfig(); } @@ -63,7 +59,7 @@ return config().verifyOops; } - public static final LocationIdentity EXCEPTION_OOP_LOCATION = LocationNode.createLocation("ExceptionOop"); + public static final LocationIdentity EXCEPTION_OOP_LOCATION = new NamedLocationIdentity("ExceptionOop"); /** * @see HotSpotVMConfig#threadExceptionOopOffset @@ -73,35 +69,35 @@ return config().threadExceptionOopOffset; } - public static final LocationIdentity EXCEPTION_PC_LOCATION = LocationNode.createLocation("ExceptionPc"); + public static final LocationIdentity EXCEPTION_PC_LOCATION = new NamedLocationIdentity("ExceptionPc"); @Fold public static int threadExceptionPcOffset() { return config().threadExceptionPcOffset; } - public static final LocationIdentity TLAB_TOP_LOCATION = LocationNode.createLocation("TlabTop"); + public static final LocationIdentity TLAB_TOP_LOCATION = new NamedLocationIdentity("TlabTop"); @Fold public static int threadTlabTopOffset() { return config().threadTlabTopOffset; } - public static final LocationIdentity TLAB_END_LOCATION = LocationNode.createLocation("TlabEnd"); + public static final LocationIdentity TLAB_END_LOCATION = new NamedLocationIdentity("TlabEnd"); @Fold private static int threadTlabEndOffset() { return config().threadTlabEndOffset; } - public static final LocationIdentity TLAB_START_LOCATION = LocationNode.createLocation("TlabStart"); + public static final LocationIdentity TLAB_START_LOCATION = new NamedLocationIdentity("TlabStart"); @Fold private static int threadTlabStartOffset() { return config().threadTlabStartOffset; } - public static final LocationIdentity PENDING_EXCEPTION_LOCATION = LocationNode.createLocation("PendingException"); + public static final LocationIdentity PENDING_EXCEPTION_LOCATION = new NamedLocationIdentity("PendingException"); /** * @see HotSpotVMConfig#pendingExceptionOffset @@ -111,7 +107,7 @@ return config().pendingExceptionOffset; } - public static final LocationIdentity OBJECT_RESULT_LOCATION = LocationNode.createLocation("ObjectResult"); + public static final LocationIdentity OBJECT_RESULT_LOCATION = new NamedLocationIdentity("ObjectResult"); @Fold private static int objectResultOffset() { @@ -200,7 +196,7 @@ } @Fold - public static Kind wordKind() { + public static Kind getWordKind() { return graalRuntime().getTarget().wordKind; } @@ -224,7 +220,7 @@ return Unsafe.getUnsafe().pageSize(); } - public static final LocationIdentity PROTOTYPE_MARK_WORD_LOCATION = LocationNode.createLocation("PrototypeMarkWord"); + public static final LocationIdentity PROTOTYPE_MARK_WORD_LOCATION = new NamedLocationIdentity("PrototypeMarkWord"); @Fold public static int prototypeMarkWordOffset() { @@ -247,7 +243,7 @@ } public static int readLayoutHelper(Word hub) { - return hub.readInt(klassLayoutHelperOffset(), FINAL_LOCATION); + return hub.readInt(klassLayoutHelperOffset(), LocationIdentity.FINAL_LOCATION); } @Fold @@ -265,14 +261,14 @@ return config().klassSuperKlassOffset; } - public static final LocationIdentity MARK_WORD_LOCATION = LocationNode.createLocation("MarkWord"); + public static final LocationIdentity MARK_WORD_LOCATION = new NamedLocationIdentity("MarkWord"); @Fold public static int markOffset() { return config().markOffset; } - public static final LocationIdentity HUB_LOCATION = LocationNode.createLocation("Hub"); + public static final LocationIdentity HUB_LOCATION = new NamedLocationIdentity("Hub"); @Fold private static int hubOffset() { @@ -399,21 +395,21 @@ return config().superCheckOffsetOffset; } - public static final LocationIdentity SECONDARY_SUPER_CACHE_LOCATION = LocationNode.createLocation("SecondarySuperCache"); + public static final LocationIdentity SECONDARY_SUPER_CACHE_LOCATION = new NamedLocationIdentity("SecondarySuperCache"); @Fold public static int secondarySuperCacheOffset() { return config().secondarySuperCacheOffset; } - public static final LocationIdentity SECONDARY_SUPERS_LOCATION = LocationNode.createLocation("SecondarySupers"); + public static final LocationIdentity SECONDARY_SUPERS_LOCATION = new NamedLocationIdentity("SecondarySupers"); @Fold public static int secondarySupersOffset() { return config().secondarySupersOffset; } - public static final LocationIdentity DISPLACED_MARK_WORD_LOCATION = LocationNode.createLocation("DisplacedMarkWord"); + public static final LocationIdentity DISPLACED_MARK_WORD_LOCATION = new NamedLocationIdentity("DisplacedMarkWord"); @Fold public static int lockDisplacedMarkOffset() { @@ -444,7 +440,14 @@ * Loads the hub from a object, null checking it first. */ public static Word loadHub(Object object) { - return loadHubIntrinsic(object, wordKind()); + return loadHubIntrinsic(object, getWordKind()); + } + + /** + * Loads the hub from a object. + */ + public static Word loadHubNoNullcheck(Object object) { + return loadWordFromObject(object, hubOffset()); } public static Object verifyOop(Object object) { @@ -472,7 +475,7 @@ } public static Word loadWordFromObject(Object object, int offset) { - return loadWordFromObjectIntrinsic(object, 0, offset, wordKind()); + return loadWordFromObjectIntrinsic(object, 0, offset, getWordKind()); } @NodeIntrinsic(value = ReadRegisterNode.class, setStampFromReturnType = true) @@ -495,7 +498,7 @@ return CodeUtil.log2(wordSize()); } - public static final LocationIdentity CLASS_STATE_LOCATION = LocationNode.createLocation("ClassState"); + public static final LocationIdentity CLASS_STATE_LOCATION = new NamedLocationIdentity("ClassState"); @Fold public static int klassStateOffset() { @@ -527,14 +530,14 @@ return config().klassInstanceSizeOffset; } - public static final LocationIdentity HEAP_TOP_LOCATION = LocationNode.createLocation("HeapTop"); + public static final LocationIdentity HEAP_TOP_LOCATION = new NamedLocationIdentity("HeapTop"); @Fold public static long heapTopAddress() { return config().heapTopAddress; } - public static final LocationIdentity HEAP_END_LOCATION = LocationNode.createLocation("HeapEnd"); + public static final LocationIdentity HEAP_END_LOCATION = new NamedLocationIdentity("HeapEnd"); @Fold public static long heapEndAddress() { @@ -556,42 +559,42 @@ return config().tlabAlignmentReserve; } - public static final LocationIdentity TLAB_SIZE_LOCATION = LocationNode.createLocation("TlabSize"); + public static final LocationIdentity TLAB_SIZE_LOCATION = new NamedLocationIdentity("TlabSize"); @Fold public static int threadTlabSizeOffset() { return config().threadTlabSizeOffset; } - public static final LocationIdentity TLAB_THREAD_ALLOCATED_BYTES_LOCATION = LocationNode.createLocation("TlabThreadAllocatedBytes"); + public static final LocationIdentity TLAB_THREAD_ALLOCATED_BYTES_LOCATION = new NamedLocationIdentity("TlabThreadAllocatedBytes"); @Fold public static int threadAllocatedBytesOffset() { return config().threadAllocatedBytesOffset; } - public static final LocationIdentity TLAB_REFILL_WASTE_LIMIT_LOCATION = LocationNode.createLocation("RefillWasteLimit"); + public static final LocationIdentity TLAB_REFILL_WASTE_LIMIT_LOCATION = new NamedLocationIdentity("RefillWasteLimit"); @Fold public static int tlabRefillWasteLimitOffset() { return config().tlabRefillWasteLimitOffset; } - public static final LocationIdentity TLAB_NOF_REFILLS_LOCATION = LocationNode.createLocation("TlabNOfRefills"); + public static final LocationIdentity TLAB_NOF_REFILLS_LOCATION = new NamedLocationIdentity("TlabNOfRefills"); @Fold public static int tlabNumberOfRefillsOffset() { return config().tlabNumberOfRefillsOffset; } - public static final LocationIdentity TLAB_FAST_REFILL_WASTE_LOCATION = LocationNode.createLocation("TlabFastRefillWaste"); + public static final LocationIdentity TLAB_FAST_REFILL_WASTE_LOCATION = new NamedLocationIdentity("TlabFastRefillWaste"); @Fold public static int tlabFastRefillWasteOffset() { return config().tlabFastRefillWasteOffset; } - public static final LocationIdentity TLAB_SLOW_ALLOCATIONS_LOCATION = LocationNode.createLocation("TlabSlowAllocations"); + public static final LocationIdentity TLAB_SLOW_ALLOCATIONS_LOCATION = new NamedLocationIdentity("TlabSlowAllocations"); @Fold public static int tlabSlowAllocationsOffset() { diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/InstanceOfSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/InstanceOfSnippets.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/InstanceOfSnippets.java Fri Jun 07 14:15:38 2013 +0200 @@ -24,6 +24,7 @@ import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*; import static com.oracle.graal.hotspot.replacements.TypeCheckSnippetUtils.*; +import static com.oracle.graal.phases.GraalOptions.*; import static com.oracle.graal.replacements.nodes.BranchProbabilityNode.*; import com.oracle.graal.api.code.*; @@ -34,7 +35,6 @@ import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; -import com.oracle.graal.phases.*; import com.oracle.graal.replacements.*; import com.oracle.graal.replacements.Snippet.ConstantParameter; import com.oracle.graal.replacements.Snippet.VarargsParameter; @@ -81,7 +81,7 @@ return falseValue; } Word objectHub = loadHub(object); - if (probability(NOT_LIKELY_PROBABILITY, objectHub.readWord(superCheckOffset, FINAL_LOCATION).notEqual(hub))) { + if (probability(NOT_LIKELY_PROBABILITY, objectHub.readWord(superCheckOffset, LocationIdentity.FINAL_LOCATION).notEqual(hub))) { displayMiss.inc(); return falseValue; } @@ -150,7 +150,7 @@ if (replacer.instanceOf instanceof InstanceOfNode) { InstanceOfNode instanceOf = (InstanceOfNode) replacer.instanceOf; ValueNode object = instanceOf.object(); - TypeCheckHints hintInfo = new TypeCheckHints(instanceOf.type(), instanceOf.profile(), tool.assumptions(), GraalOptions.InstanceOfMinHintHitProbability, GraalOptions.InstanceOfMaxHints); + TypeCheckHints hintInfo = new TypeCheckHints(instanceOf.type(), instanceOf.profile(), tool.assumptions(), InstanceOfMinHintHitProbability.getValue(), InstanceOfMaxHints.getValue()); final HotSpotResolvedObjectType type = (HotSpotResolvedObjectType) instanceOf.type(); ConstantNode hub = ConstantNode.forConstant(type.klass(), runtime, instanceOf.graph()); @@ -171,7 +171,7 @@ args = new Arguments(instanceofSecondary); args.add("hub", hub); args.add("object", object); - args.addVarargs("hints", Word.class, StampFactory.forKind(wordKind()), hints.hubs); + args.addVarargs("hints", Word.class, StampFactory.forKind(getWordKind()), hints.hubs); args.addVarargs("hintIsPositive", boolean.class, StampFactory.forKind(Kind.Boolean), hints.isPositive); } args.add("trueValue", replacer.trueValue); diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/LoadExceptionObjectSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/LoadExceptionObjectSnippets.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/LoadExceptionObjectSnippets.java Fri Jun 07 14:15:38 2013 +0200 @@ -22,11 +22,15 @@ */ package com.oracle.graal.hotspot.replacements; +import static com.oracle.graal.hotspot.meta.HotSpotRuntime.*; import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*; import static com.oracle.graal.nodes.extended.UnsafeCastNode.*; import static com.oracle.graal.replacements.SnippetTemplate.*; import com.oracle.graal.api.code.*; +import com.oracle.graal.hotspot.meta.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -34,6 +38,7 @@ import com.oracle.graal.replacements.SnippetTemplate.AbstractTemplates; import com.oracle.graal.replacements.SnippetTemplate.Arguments; import com.oracle.graal.replacements.SnippetTemplate.SnippetInfo; +import com.oracle.graal.replacements.nodes.*; import com.oracle.graal.word.*; /** @@ -41,6 +46,11 @@ */ public class LoadExceptionObjectSnippets implements Snippets { + /** + * Alternative way to implement exception object loading. + */ + private static final boolean USE_C_RUNTIME = Boolean.getBoolean("graal.loadExceptionObject.useCRuntime"); + @Snippet public static Object loadException() { Word thread = thread(); @@ -59,8 +69,18 @@ } public void lower(LoadExceptionObjectNode loadExceptionObject) { - Arguments args = new Arguments(loadException); - template(args).instantiate(runtime, loadExceptionObject, DEFAULT_REPLACER, args); + if (USE_C_RUNTIME) { + StructuredGraph graph = loadExceptionObject.graph(); + HotSpotRuntime hsRuntime = (HotSpotRuntime) runtime; + ReadRegisterNode thread = graph.add(new ReadRegisterNode(hsRuntime.threadRegister(), true, false)); + graph.addBeforeFixed(loadExceptionObject, thread); + ForeignCallNode loadExceptionC = graph.add(new ForeignCallNode(runtime, LOAD_AND_CLEAR_EXCEPTION, thread)); + loadExceptionC.setStateAfter(loadExceptionObject.stateAfter()); + graph.replaceFixedWithFixed(loadExceptionObject, loadExceptionC); + } else { + Arguments args = new Arguments(loadException); + template(args).instantiate(runtime, loadExceptionObject, DEFAULT_REPLACER, args); + } } } } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MonitorSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MonitorSnippets.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MonitorSnippets.java Fri Jun 07 14:15:38 2013 +0200 @@ -41,7 +41,6 @@ import com.oracle.graal.hotspot.nodes.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.extended.*; -import com.oracle.graal.nodes.extended.LocationNode.LocationIdentity; import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind; import com.oracle.graal.nodes.spi.*; @@ -108,7 +107,7 @@ } else { // The bias pattern is present in the object's mark word. Need to check // whether the bias owner and the epoch are both still current. - Word hub = loadHub(object); + Word hub = loadHubNoNullcheck(object); final Word prototypeMarkWord = hub.readWord(prototypeMarkWordOffset(), PROTOTYPE_MARK_WORD_LOCATION); final Word thread = thread(); final Word tmp = prototypeMarkWord.or(thread).xor(mark).and(~ageMaskInPlace()); @@ -345,7 +344,7 @@ */ private static final boolean ENABLE_BREAKPOINT = false; - private static final LocationIdentity MONITOR_COUNTER_LOCATION = LocationNode.createLocation("MonitorCounter"); + private static final LocationIdentity MONITOR_COUNTER_LOCATION = new NamedLocationIdentity("MonitorCounter"); @NodeIntrinsic(BreakpointNode.class) static native void bkpt(Object object, Word mark, Word tmp, Word value); diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippets.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippets.java Fri Jun 07 14:15:38 2013 +0200 @@ -23,9 +23,11 @@ package com.oracle.graal.hotspot.replacements; import static com.oracle.graal.api.code.UnsignedMath.*; +import static com.oracle.graal.api.meta.LocationIdentity.*; import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*; import static com.oracle.graal.nodes.extended.UnsafeArrayCastNode.*; import static com.oracle.graal.nodes.extended.UnsafeCastNode.*; +import static com.oracle.graal.phases.GraalOptions.*; import static com.oracle.graal.replacements.SnippetTemplate.*; import static com.oracle.graal.replacements.nodes.BranchProbabilityNode.*; import static com.oracle.graal.replacements.nodes.ExplodeLoopNode.*; @@ -39,7 +41,6 @@ import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; -import com.oracle.graal.phases.*; import com.oracle.graal.replacements.*; import com.oracle.graal.replacements.Snippet.ConstantParameter; import com.oracle.graal.replacements.Snippet.VarargsParameter; @@ -237,7 +238,7 @@ Kind elementKind = elementType.getKind(); ConstantNode hub = ConstantNode.forConstant(arrayType.klass(), runtime, graph); final int headerSize = HotSpotRuntime.getArrayBaseOffset(elementKind); - int log2ElementSize = CodeUtil.log2(target.arch.getSizeInBytes(elementKind)); + int log2ElementSize = CodeUtil.log2(((HotSpotRuntime) runtime).getScalingFactor(elementKind)); Arguments args = new Arguments(allocateArray); args.add("hub", hub); @@ -277,12 +278,12 @@ } } - private static final SnippetCounter.Group countersNew = GraalOptions.SnippetCounters ? new SnippetCounter.Group("NewInstance") : null; + private static final SnippetCounter.Group countersNew = SnippetCounters.getValue() ? new SnippetCounter.Group("NewInstance") : null; private static final SnippetCounter new_seqInit = new SnippetCounter(countersNew, "tlabSeqInit", "TLAB alloc with unrolled zeroing"); private static final SnippetCounter new_loopInit = new SnippetCounter(countersNew, "tlabLoopInit", "TLAB alloc with zeroing in a loop"); private static final SnippetCounter new_stub = new SnippetCounter(countersNew, "stub", "alloc and zeroing via stub"); - private static final SnippetCounter.Group countersNewArray = GraalOptions.SnippetCounters ? new SnippetCounter.Group("NewArray") : null; + private static final SnippetCounter.Group countersNewArray = SnippetCounters.getValue() ? new SnippetCounter.Group("NewArray") : null; private static final SnippetCounter newarray_loopInit = new SnippetCounter(countersNewArray, "tlabLoopInit", "TLAB alloc with zeroing in a loop"); private static final SnippetCounter newarray_stub = new SnippetCounter(countersNewArray, "stub", "alloc and zeroing via stub"); } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectCloneNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectCloneNode.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectCloneNode.java Fri Jun 07 14:15:38 2013 +0200 @@ -22,6 +22,8 @@ */ package com.oracle.graal.hotspot.replacements; +import static com.oracle.graal.phases.GraalOptions.*; + import java.lang.reflect.*; import com.oracle.graal.api.code.*; @@ -31,7 +33,6 @@ import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; import com.oracle.graal.nodes.virtual.*; -import com.oracle.graal.phases.*; import com.oracle.graal.replacements.nodes.*; public class ObjectCloneNode extends MacroNode implements VirtualizableAllocation, ArrayLengthProvider { @@ -51,7 +52,7 @@ @Override protected StructuredGraph getSnippetGraph(LoweringTool tool) { - if (!GraalOptions.IntrinsifyObjectClone) { + if (!IntrinsifyObjectClone.getValue()) { return null; } @@ -77,7 +78,7 @@ } private static boolean isCloneableType(ResolvedJavaType type, MetaAccessProvider metaAccess) { - return metaAccess.lookupJavaType(Cloneable.class).isAssignableFrom(type); + return type != null && metaAccess.lookupJavaType(Cloneable.class).isAssignableFrom(type); } private static ResolvedJavaType getConcreteType(ObjectStamp stamp, Assumptions assumptions) { diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectCloneSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectCloneSnippets.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectCloneSnippets.java Fri Jun 07 14:15:38 2013 +0200 @@ -22,7 +22,9 @@ */ package com.oracle.graal.hotspot.replacements; +import static com.oracle.graal.api.meta.LocationIdentity.*; import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*; +import static com.oracle.graal.phases.GraalOptions.*; import static com.oracle.graal.replacements.nodes.BranchProbabilityNode.*; import java.lang.reflect.*; @@ -32,7 +34,6 @@ import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.java.*; -import com.oracle.graal.phases.*; import com.oracle.graal.replacements.*; import com.oracle.graal.word.*; @@ -116,12 +117,12 @@ } } - private static final SnippetCounter.Group cloneCounters = GraalOptions.SnippetCounters ? new SnippetCounter.Group("Object.clone") : null; + private static final SnippetCounter.Group cloneCounters = SnippetCounters.getValue() ? new SnippetCounter.Group("Object.clone") : null; private static final SnippetCounter instanceCloneCounter = new SnippetCounter(cloneCounters, "instanceClone", "clone snippet for instances"); private static final SnippetCounter arrayCloneCounter = new SnippetCounter(cloneCounters, "arrayClone", "clone snippet for arrays"); private static final SnippetCounter genericCloneCounter = new SnippetCounter(cloneCounters, "genericClone", "clone snippet for arrays and instances"); - private static final SnippetCounter.Group genericCloneCounters = GraalOptions.SnippetCounters ? new SnippetCounter.Group("Object.clone generic snippet") : null; + private static final SnippetCounter.Group genericCloneCounters = SnippetCounters.getValue() ? new SnippetCounter.Group("Object.clone generic snippet") : null; private static final SnippetCounter genericInstanceCloneCounter = new SnippetCounter(genericCloneCounters, "genericInstanceClone", "generic clone implementation took instance path"); private static final SnippetCounter genericArrayCloneCounter = new SnippetCounter(genericCloneCounters, "genericArrayClone", "generic clone implementation took array path"); diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectSubstitutions.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectSubstitutions.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectSubstitutions.java Fri Jun 07 14:15:38 2013 +0200 @@ -25,8 +25,8 @@ import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*; import static com.oracle.graal.nodes.extended.UnsafeCastNode.*; +import com.oracle.graal.api.meta.*; import com.oracle.graal.api.replacements.*; -import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.word.*; @@ -40,7 +40,7 @@ @MethodSubstitution(isStatic = false) public static Class getClass(final Object thisObj) { Word hub = loadHub(thisObj); - return unsafeCast(hub.readObject(Word.signed(classMirrorOffset()), LocationNode.FINAL_LOCATION), Class.class, true, true); + return unsafeCast(hub.readObject(Word.signed(classMirrorOffset()), LocationIdentity.FINAL_LOCATION), Class.class, true, true); } @MethodSubstitution(isStatic = false) diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ReflectionGetCallerClassNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ReflectionGetCallerClassNode.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ReflectionGetCallerClassNode.java Fri Jun 07 14:15:38 2013 +0200 @@ -22,12 +22,13 @@ */ package com.oracle.graal.hotspot.replacements; +import static com.oracle.graal.phases.GraalOptions.*; + import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.phases.*; import com.oracle.graal.replacements.nodes.*; public class ReflectionGetCallerClassNode extends MacroNode implements Canonicalizable, Lowerable { @@ -64,7 +65,7 @@ * @return ConstantNode of the caller class, or null */ private ConstantNode getCallerClassNode(MetaAccessProvider runtime) { - if (!GraalOptions.IntrinsifyReflectionMethods) { + if (!IntrinsifyReflectionMethods.getValue()) { return null; } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ThreadSubstitutions.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ThreadSubstitutions.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ThreadSubstitutions.java Fri Jun 07 14:15:38 2013 +0200 @@ -22,6 +22,7 @@ */ package com.oracle.graal.hotspot.replacements; +import static com.oracle.graal.api.meta.LocationIdentity.*; import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*; import java.lang.reflect.*; @@ -43,15 +44,15 @@ @MethodSubstitution public static Thread currentThread() { - return (Thread) CurrentJavaThreadNode.get().readObject(threadObjectOffset(), FINAL_LOCATION); + return (Thread) CurrentJavaThreadNode.get().readObject(threadObjectOffset(), LocationIdentity.FINAL_LOCATION); } @MethodSubstitution(isStatic = false) public static boolean isInterrupted(final Thread thisObject, boolean clearInterrupted) { Word javaThread = CurrentJavaThreadNode.get(); - Object thread = javaThread.readObject(threadObjectOffset(), FINAL_LOCATION); + Object thread = javaThread.readObject(threadObjectOffset(), LocationIdentity.FINAL_LOCATION); if (thisObject == thread) { - Word osThread = javaThread.readWord(osThreadOffset(), FINAL_LOCATION); + Word osThread = javaThread.readWord(osThreadOffset(), LocationIdentity.FINAL_LOCATION); boolean interrupted = osThread.readInt(osThreadInterruptedOffset(), ANY_LOCATION) != 0; if (!interrupted || !clearInterrupted) { return interrupted; diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/TypeCheckSnippetUtils.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/TypeCheckSnippetUtils.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/TypeCheckSnippetUtils.java Fri Jun 07 14:15:38 2013 +0200 @@ -23,6 +23,7 @@ package com.oracle.graal.hotspot.replacements; import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*; +import static com.oracle.graal.phases.GraalOptions.*; import static com.oracle.graal.replacements.nodes.BranchProbabilityNode.*; import java.util.*; @@ -32,9 +33,6 @@ import com.oracle.graal.graph.*; import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.extended.*; -import com.oracle.graal.nodes.extended.LocationNode.LocationIdentity; -import com.oracle.graal.phases.*; import com.oracle.graal.replacements.*; import com.oracle.graal.word.*; @@ -45,7 +43,7 @@ */ public class TypeCheckSnippetUtils { - public static final LocationIdentity TYPE_DISPLAY_LOCATION = LocationNode.createLocation("TypeDisplay"); + public static final LocationIdentity TYPE_DISPLAY_LOCATION = new NamedLocationIdentity("TypeDisplay"); static boolean checkSecondarySubType(Word t, Word s) { // if (S.cache == T) return true @@ -59,7 +57,7 @@ static boolean checkUnknownSubType(Word t, Word s) { // int off = T.offset - int superCheckOffset = t.readInt(superCheckOffsetOffset(), FINAL_LOCATION); + int superCheckOffset = t.readInt(superCheckOffsetOffset(), LocationIdentity.FINAL_LOCATION); boolean primary = superCheckOffset != secondarySuperCacheOffset(); // if (T = S[off]) return true @@ -90,7 +88,7 @@ // if (S.scan_s_s_array(T)) { S.cache = T; return true; } Word secondarySupers = s.readWord(secondarySupersOffset(), SECONDARY_SUPERS_LOCATION); - int length = secondarySupers.readInt(metaspaceArrayLengthOffset(), FINAL_LOCATION); + int length = secondarySupers.readInt(metaspaceArrayLengthOffset(), LocationIdentity.FINAL_LOCATION); for (int i = 0; i < length; i++) { if (probability(NOT_LIKELY_PROBABILITY, t.equal(loadSecondarySupersElement(secondarySupers, i)))) { s.writeWord(secondarySuperCacheOffset(), t, SECONDARY_SUPER_CACHE_LOCATION); @@ -144,10 +142,10 @@ } static Word loadSecondarySupersElement(Word metaspaceArray, int index) { - return metaspaceArray.readWord(metaspaceArrayBaseOffset() + index * wordSize(), FINAL_LOCATION); + return metaspaceArray.readWord(metaspaceArrayBaseOffset() + index * wordSize(), LocationIdentity.FINAL_LOCATION); } - private static final SnippetCounter.Group counters = GraalOptions.SnippetCounters ? new SnippetCounter.Group("TypeCheck") : null; + private static final SnippetCounter.Group counters = SnippetCounters.getValue() ? new SnippetCounter.Group("TypeCheck") : null; static final SnippetCounter hintsHit = new SnippetCounter(counters, "hintsHit", "hit a hint type"); static final SnippetCounter exactHit = new SnippetCounter(counters, "exactHit", "exact type test succeeded"); static final SnippetCounter exactMiss = new SnippetCounter(counters, "exactMiss", "exact type test failed"); diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ExceptionHandlerStub.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ExceptionHandlerStub.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ExceptionHandlerStub.java Fri Jun 07 14:15:38 2013 +0200 @@ -34,7 +34,7 @@ import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.bridge.*; import com.oracle.graal.hotspot.meta.*; -import com.oracle.graal.nodes.extended.*; +import com.oracle.graal.hotspot.nodes.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.replacements.*; import com.oracle.graal.replacements.Snippet.Fold; @@ -127,6 +127,6 @@ public static final ForeignCallDescriptor EXCEPTION_HANDLER_FOR_PC = descriptorFor(ExceptionHandlerStub.class, "exceptionHandlerForPc"); - @NodeIntrinsic(value = ForeignCallNode.class, setStampFromReturnType = true) + @NodeIntrinsic(value = StubForeignCallNode.class, setStampFromReturnType = true) public static native Word exceptionHandlerForPc(@ConstantNodeParameter ForeignCallDescriptor exceptionHandlerForPc, Word thread); } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ForeignCallStub.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ForeignCallStub.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ForeignCallStub.java Fri Jun 07 14:15:38 2013 +0200 @@ -24,9 +24,9 @@ import static com.oracle.graal.api.code.CallingConvention.Type.*; import static com.oracle.graal.api.meta.MetaUtil.*; -import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; import static com.oracle.graal.hotspot.HotSpotForeignCallLinkage.RegisterEffect.*; import static com.oracle.graal.hotspot.HotSpotForeignCallLinkage.Transition.*; +import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; import java.lang.reflect.*; @@ -40,7 +40,6 @@ import com.oracle.graal.hotspot.replacements.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; -import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind; import com.oracle.graal.nodes.spi.*; @@ -80,13 +79,18 @@ * @param descriptor the signature of the call to this stub * @param prependThread true if the JavaThread value for the current thread is to be prepended * to the arguments for the call to {@code address} + * @param reexecutable specifies if the stub call can be re-executed without (meaningful) side + * effects. Deoptimization will not return to a point before a stub call that cannot + * be re-executed. + * @param killedLocations the memory locations killed by the stub call */ - public ForeignCallStub(long address, ForeignCallDescriptor descriptor, boolean prependThread, HotSpotRuntime runtime, Replacements replacements) { - super(runtime, replacements, HotSpotForeignCallLinkage.create(descriptor, 0L, PRESERVES_REGISTERS, JavaCallee, NOT_LEAF)); + public ForeignCallStub(HotSpotRuntime runtime, Replacements replacements, long address, ForeignCallDescriptor descriptor, boolean prependThread, boolean reexecutable, + LocationIdentity... killedLocations) { + super(runtime, replacements, HotSpotForeignCallLinkage.create(descriptor, 0L, PRESERVES_REGISTERS, JavaCallee, NOT_LEAF, reexecutable, killedLocations)); this.prependThread = prependThread; Class[] targetParameterTypes = createTargetParameters(descriptor); ForeignCallDescriptor targetSig = new ForeignCallDescriptor(descriptor.getName() + ":C", descriptor.getResultType(), targetParameterTypes); - target = HotSpotForeignCallLinkage.create(targetSig, address, DESTROYS_REGISTERS, NativeCall, NOT_LEAF); + target = HotSpotForeignCallLinkage.create(targetSig, address, DESTROYS_REGISTERS, NativeCall, NOT_LEAF, reexecutable, killedLocations); } /** @@ -255,7 +259,7 @@ if (kind == Kind.Object) { stamp = StampFactory.declared(type); } else { - stamp = StampFactory.forKind(kind); + stamp = StampFactory.forKind(type.getKind()); } LocalNode local = builder.add(new LocalNode(i, stamp)); locals[i] = local; @@ -278,14 +282,14 @@ return invoke; } - private ForeignCallNode createTargetCall(GraphBuilder builder, LocalNode[] locals, ReadRegisterNode thread) { + private StubForeignCallNode createTargetCall(GraphBuilder builder, LocalNode[] locals, ReadRegisterNode thread) { if (prependThread) { ValueNode[] targetArguments = new ValueNode[1 + locals.length]; targetArguments[0] = thread; System.arraycopy(locals, 0, targetArguments, 1, locals.length); - return builder.append(new ForeignCallNode(target.getDescriptor(), targetArguments)); + return builder.append(new StubForeignCallNode(runtime, target.getDescriptor(), targetArguments)); } else { - return builder.append(new ForeignCallNode(target.getDescriptor(), locals)); + return builder.append(new StubForeignCallNode(runtime, target.getDescriptor(), locals)); } } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewArrayStub.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewArrayStub.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewArrayStub.java Fri Jun 07 14:15:38 2013 +0200 @@ -36,7 +36,6 @@ import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.hotspot.nodes.*; import com.oracle.graal.hotspot.replacements.*; -import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.replacements.*; import com.oracle.graal.replacements.Snippet.ConstantParameter; @@ -89,7 +88,7 @@ */ @Snippet private static Object newArray(Word hub, int length, @ConstantParameter Word intArrayHub) { - int layoutHelper = hub.readInt(layoutHelperOffset(), FINAL_LOCATION); + int layoutHelper = hub.readInt(layoutHelperOffset(), LocationIdentity.FINAL_LOCATION); int log2ElementSize = (layoutHelper >> layoutHelperLog2ElementSizeShift()) & layoutHelperLog2ElementSizeMask(); int headerSize = (layoutHelper >> layoutHelperHeaderSizeShift()) & layoutHelperHeaderSizeMask(); int elementKind = (layoutHelper >> layoutHelperElementTypeShift()) & layoutHelperElementTypeMask(); @@ -122,6 +121,6 @@ public static final ForeignCallDescriptor NEW_ARRAY_C = descriptorFor(NewArrayStub.class, "newArrayC"); - @NodeIntrinsic(ForeignCallNode.class) + @NodeIntrinsic(StubForeignCallNode.class) public static native void newArrayC(@ConstantNodeParameter ForeignCallDescriptor newArrayC, Word thread, Word hub, int length); } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewInstanceStub.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewInstanceStub.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewInstanceStub.java Fri Jun 07 14:15:38 2013 +0200 @@ -22,6 +22,7 @@ */ package com.oracle.graal.hotspot.stubs; +import static com.oracle.graal.api.meta.LocationIdentity.*; import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; import static com.oracle.graal.hotspot.nodes.DirectCompareAndSwapNode.*; import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*; @@ -36,7 +37,6 @@ import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.hotspot.nodes.*; import com.oracle.graal.hotspot.replacements.*; -import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.replacements.*; import com.oracle.graal.replacements.Snippet.ConstantParameter; @@ -87,7 +87,7 @@ */ @Snippet private static Object newInstance(Word hub, @ConstantParameter Word intArrayHub) { - int sizeInBytes = hub.readInt(klassInstanceSizeOffset(), FINAL_LOCATION); + int sizeInBytes = hub.readInt(klassInstanceSizeOffset(), LocationIdentity.FINAL_LOCATION); if (!forceSlowPath() && inlineContiguousAllocationSupported()) { if (hub.readInt(klassStateOffset(), CLASS_STATE_LOCATION) == klassStateFullyInitialized()) { Word memory = refillAllocate(intArrayHub, sizeInBytes, logging()); @@ -241,6 +241,6 @@ public static final ForeignCallDescriptor NEW_INSTANCE_C = descriptorFor(NewInstanceStub.class, "newInstanceC"); - @NodeIntrinsic(ForeignCallNode.class) + @NodeIntrinsic(StubForeignCallNode.class) public static native void newInstanceC(@ConstantNodeParameter ForeignCallDescriptor newInstanceC, Word thread, Word hub); } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java Fri Jun 07 14:15:38 2013 +0200 @@ -173,8 +173,9 @@ if (Debug.isDumpEnabled()) { Debug.dump(new Object[]{compResult, installedCode}, "After code installation"); } - // TTY.println(stub.toString()); - // TTY.println(runtime.disassemble(installedCode)); + if (Debug.isLogEnabled()) { + Debug.log("%s", runtime.disassemble(installedCode)); + } return installedCode; } }); diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/StubUtil.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/StubUtil.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/StubUtil.java Fri Jun 07 14:15:38 2013 +0200 @@ -35,7 +35,6 @@ import com.oracle.graal.graph.Node.ConstantNodeParameter; import com.oracle.graal.graph.Node.NodeIntrinsic; import com.oracle.graal.hotspot.nodes.*; -import com.oracle.graal.nodes.extended.*; import com.oracle.graal.replacements.*; import com.oracle.graal.replacements.Snippet.Fold; import com.oracle.graal.word.*; @@ -50,15 +49,15 @@ public static final ForeignCallDescriptor VM_MESSAGE_C = descriptorFor(StubUtil.class, "vmMessageC"); /** - * Looks for a {@link ForeignCallNode} node intrinsic named {@code name} in {@code stubClass} - * and returns a {@link ForeignCallDescriptor} based on its signature and the value of - * {@code hasSideEffect}. + * Looks for a {@link StubForeignCallNode} node intrinsic named {@code name} in + * {@code stubClass} and returns a {@link ForeignCallDescriptor} based on its signature and the + * value of {@code hasSideEffect}. */ public static ForeignCallDescriptor descriptorFor(Class stubClass, String name) { Method found = null; for (Method method : stubClass.getDeclaredMethods()) { if (Modifier.isStatic(method.getModifiers()) && method.getAnnotation(NodeIntrinsic.class) != null && method.getName().equals(name)) { - if (method.getAnnotation(NodeIntrinsic.class).value() == ForeignCallNode.class) { + if (method.getAnnotation(NodeIntrinsic.class).value() == StubForeignCallNode.class) { assert found == null : "found more than one foreign call named " + name + " in " + stubClass; assert method.getParameterTypes().length != 0 && method.getParameterTypes()[0] == ForeignCallDescriptor.class : "first parameter of foreign call '" + name + "' in " + stubClass + " must be of type " + ForeignCallDescriptor.class.getSimpleName(); @@ -81,7 +80,7 @@ } } - @NodeIntrinsic(ForeignCallNode.class) + @NodeIntrinsic(StubForeignCallNode.class) private static native void vmMessageC(@ConstantNodeParameter ForeignCallDescriptor stubPrintfC, boolean vmError, Word format, long v1, long v2, long v3); /** diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/UnwindExceptionToCallerStub.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/UnwindExceptionToCallerStub.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/UnwindExceptionToCallerStub.java Fri Jun 07 14:15:38 2013 +0200 @@ -34,8 +34,8 @@ import com.oracle.graal.graph.Node.NodeIntrinsic; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.meta.*; +import com.oracle.graal.hotspot.nodes.*; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.replacements.*; import com.oracle.graal.replacements.Snippet.Fold; @@ -99,6 +99,6 @@ public static final ForeignCallDescriptor EXCEPTION_HANDLER_FOR_RETURN_ADDRESS = descriptorFor(UnwindExceptionToCallerStub.class, "exceptionHandlerForReturnAddress"); - @NodeIntrinsic(value = ForeignCallNode.class, setStampFromReturnType = true) + @NodeIntrinsic(value = StubForeignCallNode.class, setStampFromReturnType = true) public static native Word exceptionHandlerForReturnAddress(@ConstantNodeParameter ForeignCallDescriptor exceptionHandlerForReturnAddress, Word thread, Word returnAddress); } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.java/src/com/oracle/graal/java/BciBlockMapping.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/BciBlockMapping.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/BciBlockMapping.java Fri Jun 07 14:15:38 2013 +0200 @@ -23,6 +23,7 @@ package com.oracle.graal.java; import static com.oracle.graal.bytecode.Bytecodes.*; +import static com.oracle.graal.phases.GraalOptions.*; import java.util.*; @@ -31,7 +32,6 @@ import com.oracle.graal.bytecode.*; import com.oracle.graal.debug.*; import com.oracle.graal.nodes.*; -import com.oracle.graal.phases.*; /** * Builds a mapping between bytecodes and basic blocks and builds a conservative control flow graph @@ -187,7 +187,7 @@ makeExceptionEntries(); iterateOverBytecodes(); if (hasJsrBytecodes) { - if (!GraalOptions.SupportJsrBytecodes) { + if (!SupportJsrBytecodes.getValue()) { throw new JsrNotSupportedBailout("jsr/ret parsing disabled"); } createJsrAlternatives(blockMap[0]); @@ -209,7 +209,7 @@ if (Debug.isLogEnabled()) { this.log("Before LivenessAnalysis"); } - if (GraalOptions.OptLivenessAnalysis) { + if (OptLivenessAnalysis.getValue()) { Debug.scope("LivenessAnalysis", new Runnable() { @Override diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.java/src/com/oracle/graal/java/FrameStateBuilder.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/FrameStateBuilder.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/FrameStateBuilder.java Fri Jun 07 14:15:38 2013 +0200 @@ -49,6 +49,10 @@ private ValueNode[] locks; private int stackSize; + + /** + * @see BytecodeFrame#rethrowException + */ private boolean rethrowException; public FrameStateBuilder(ResolvedJavaMethod method, StructuredGraph graph, boolean eagerResolve) { @@ -82,7 +86,7 @@ if (kind == Kind.Object && type instanceof ResolvedJavaType) { stamp = StampFactory.declared((ResolvedJavaType) type); } else { - stamp = StampFactory.forKind(kind); + stamp = StampFactory.forKind(type.getKind()); } LocalNode local = graph.unique(new LocalNode(index, stamp)); storeLocal(javaIndex, local); @@ -144,7 +148,7 @@ for (int i = 0; i < stackSize(); i++) { ValueNode x = stackAt(i); ValueNode y = other.stackAt(i); - if (x != y && ValueNodeUtil.typeMismatch(x, y)) { + if (x != y && (x == null || x.isDeleted() || y == null || y.isDeleted() || x.kind() != y.kind())) { return false; } } @@ -171,11 +175,11 @@ } private ValueNode merge(ValueNode currentValue, ValueNode otherValue, MergeNode block) { - if (currentValue == null) { + if (currentValue == null || currentValue.isDeleted()) { return null; } else if (block.isPhiAtMerge(currentValue)) { - if (otherValue == null || currentValue.kind() != otherValue.kind()) { + if (otherValue == null || otherValue.isDeleted() || currentValue.kind() != otherValue.kind()) { propagateDelete((PhiNode) currentValue); return null; } @@ -184,7 +188,7 @@ } else if (currentValue != otherValue) { assert !(block instanceof LoopBeginNode) : "Phi functions for loop headers are create eagerly for all locals and stack slots"; - if (otherValue == null || currentValue.kind() != otherValue.kind()) { + if (otherValue == null || otherValue.isDeleted() || currentValue.kind() != otherValue.kind()) { return null; } @@ -308,10 +312,16 @@ } } + /** + * @see BytecodeFrame#rethrowException + */ public boolean rethrowException() { return rethrowException; } + /** + * @see BytecodeFrame#rethrowException + */ public void setRethrowException(boolean b) { rethrowException = b; } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Fri Jun 07 14:15:38 2013 +0200 @@ -27,6 +27,7 @@ import static com.oracle.graal.api.meta.DeoptimizationReason.*; import static com.oracle.graal.bytecode.Bytecodes.*; import static com.oracle.graal.java.GraphBuilderPhase.RuntimeCalls.*; +import static com.oracle.graal.phases.GraalOptions.*; import static java.lang.reflect.Modifier.*; import java.lang.reflect.*; @@ -158,7 +159,7 @@ methodSynchronizedObject = null; this.currentGraph = graph; this.frameState = new FrameStateBuilder(method, graph, graphBuilderConfig.eagerResolving()); - TTY.Filter filter = new TTY.Filter(GraalOptions.PrintFilter, method); + TTY.Filter filter = new TTY.Filter(PrintFilter.getValue(), method); try { build(); } finally { @@ -182,7 +183,7 @@ } private void build() { - if (GraalOptions.PrintProfilingInformation) { + if (PrintProfilingInformation.getValue()) { TTY.println("Profiling info for " + method); TTY.println(MetaUtil.indent(MetaUtil.profileToString(profilingInfo, method, CodeUtil.NEW_LINE), " ")); } @@ -921,11 +922,11 @@ append(new IfNode(currentGraph.unique(new IsNullNode(receiver)), trueSucc, falseSucc, 0.1)); lastInstr = falseSucc; - if (GraalOptions.OmitHotExceptionStacktrace) { + if (OmitHotExceptionStacktrace.getValue()) { ValueNode exception = ConstantNode.forObject(cachedNullPointerException, runtime, currentGraph); trueSucc.setNext(handleException(exception, bci())); } else { - ForeignCallStateSplitNode call = currentGraph.add(new ForeignCallStateSplitNode(runtime, CREATE_NULL_POINTER_EXCEPTION)); + ForeignCallNode call = currentGraph.add(new ForeignCallNode(runtime, CREATE_NULL_POINTER_EXCEPTION)); call.setStateAfter(frameState.create(bci())); trueSucc.setNext(call); call.setNext(handleException(call, bci())); @@ -945,11 +946,11 @@ append(new IfNode(currentGraph.unique(new IntegerBelowThanNode(index, length)), trueSucc, falseSucc, 0.9)); lastInstr = trueSucc; - if (GraalOptions.OmitHotExceptionStacktrace) { + if (OmitHotExceptionStacktrace.getValue()) { ValueNode exception = ConstantNode.forObject(cachedArrayIndexOutOfBoundsException, runtime, currentGraph); falseSucc.setNext(handleException(exception, bci())); } else { - ForeignCallStateSplitNode call = currentGraph.add(new ForeignCallStateSplitNode(runtime, CREATE_OUT_OF_BOUNDS_EXCEPTION, index)); + ForeignCallNode call = currentGraph.add(new ForeignCallNode(runtime, CREATE_OUT_OF_BOUNDS_EXCEPTION, index)); call.setStateAfter(frameState.create(bci())); falseSucc.setNext(call); call.setNext(handleException(call, bci())); @@ -1023,7 +1024,7 @@ if (target instanceof ResolvedJavaMethod) { ResolvedJavaMethod resolvedTarget = (ResolvedJavaMethod) target; ResolvedJavaType holder = resolvedTarget.getDeclaringClass(); - if (!holder.isInitialized() && GraalOptions.ResolveClassBeforeStaticInvoke) { + if (!holder.isInitialized() && ResolveClassBeforeStaticInvoke.getValue()) { handleUnresolvedInvoke(target, InvokeKind.Static); } else { ValueNode[] args = frameState.popArguments(resolvedTarget.getSignature().getParameterSlots(false), resolvedTarget.getSignature().getParameterCount(false)); @@ -1107,8 +1108,11 @@ } if (exact != null) { // either the holder class is exact, or the receiver object has an exact type - invokeDirect(exact.resolveMethod(target), args); - return; + ResolvedJavaMethod exactMethod = exact.resolveMethod(target); + if (exactMethod != null) { + invokeDirect(exactMethod, args); + return; + } } // devirtualization failed, produce an actual invokevirtual appendInvoke(invokeKind, target, args); @@ -1120,7 +1124,7 @@ private void appendInvoke(InvokeKind invokeKind, ResolvedJavaMethod targetMethod, ValueNode[] args) { Kind resultType = targetMethod.getSignature().getReturnKind(); - if (GraalOptions.DeoptALot) { + if (DeoptALot.getValue()) { append(new DeoptimizeNode(DeoptimizationAction.None, RuntimeConstraint)); frameState.pushReturn(resultType, ConstantNode.defaultForKind(resultType, currentGraph)); return; @@ -1763,7 +1767,7 @@ } private void traceState() { - if (GraalOptions.TraceBytecodeParserLevel >= TRACELEVEL_STATE && Debug.isLogEnabled()) { + if (TraceBytecodeParserLevel.getValue() >= TRACELEVEL_STATE && Debug.isLogEnabled()) { Debug.log(String.format("| state [nr locals = %d, stack depth = %d, method = %s]", frameState.localsSize(), frameState.stackSize(), method)); for (int i = 0; i < frameState.localsSize(); ++i) { ValueNode value = frameState.localAt(i); @@ -1993,7 +1997,7 @@ } private void traceInstruction(int bci, int opcode, boolean blockStart) { - if (GraalOptions.TraceBytecodeParserLevel >= TRACELEVEL_INSTRUCTIONS && Debug.isLogEnabled()) { + if (TraceBytecodeParserLevel.getValue() >= TRACELEVEL_INSTRUCTIONS && Debug.isLogEnabled()) { StringBuilder sb = new StringBuilder(40); sb.append(blockStart ? '+' : '|'); if (bci < 10) { diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Arithmetic.java --- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Arithmetic.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Arithmetic.java Fri Jun 07 14:15:38 2013 +0200 @@ -273,7 +273,7 @@ protected void verify() { super.verify(); // left input in rax, right input in any register but rax and rdx, result quotient in rax, result remainder in rdx - assert asRegister(x) == AMD64.rax; + assert asRegister(x).equals(AMD64.rax); assert differentRegisters(y, AMD64.rax.asValue(), AMD64.rdx.asValue()); verifyKind(opcode, divResult, x, y); verifyKind(opcode, remResult, x, y); @@ -360,9 +360,9 @@ case IMUL: masm.imull(asIntReg(dst), asIntReg(src)); break; case IOR: masm.orl(asIntReg(dst), asIntReg(src)); break; case IXOR: masm.xorl(asIntReg(dst), asIntReg(src)); break; - case ISHL: assert asIntReg(src) == AMD64.rcx; masm.shll(asIntReg(dst)); break; - case ISHR: assert asIntReg(src) == AMD64.rcx; masm.sarl(asIntReg(dst)); break; - case IUSHR: assert asIntReg(src) == AMD64.rcx; masm.shrl(asIntReg(dst)); break; + case ISHL: assert asIntReg(src).equals(AMD64.rcx); masm.shll(asIntReg(dst)); break; + case ISHR: assert asIntReg(src).equals(AMD64.rcx); masm.sarl(asIntReg(dst)); break; + case IUSHR: assert asIntReg(src).equals(AMD64.rcx); masm.shrl(asIntReg(dst)); break; case LADD: masm.addq(asLongReg(dst), asLongReg(src)); break; case LSUB: masm.subq(asLongReg(dst), asLongReg(src)); break; @@ -370,9 +370,9 @@ case LAND: masm.andq(asLongReg(dst), asLongReg(src)); break; case LOR: masm.orq(asLongReg(dst), asLongReg(src)); break; case LXOR: masm.xorq(asLongReg(dst), asLongReg(src)); break; - case LSHL: assert asIntReg(src) == AMD64.rcx; masm.shlq(asLongReg(dst)); break; - case LSHR: assert asIntReg(src) == AMD64.rcx; masm.sarq(asLongReg(dst)); break; - case LUSHR: assert asIntReg(src) == AMD64.rcx; masm.shrq(asLongReg(dst)); break; + case LSHL: assert asIntReg(src).equals(AMD64.rcx); masm.shlq(asLongReg(dst)); break; + case LSHR: assert asIntReg(src).equals(AMD64.rcx); masm.sarq(asLongReg(dst)); break; + case LUSHR: assert asIntReg(src).equals(AMD64.rcx); masm.shrq(asLongReg(dst)); break; case FADD: masm.addss(asFloatReg(dst), asFloatReg(src)); break; case FSUB: masm.subss(asFloatReg(dst), asFloatReg(src)); break; @@ -556,6 +556,6 @@ || (opcode.name().startsWith("L") && result.getKind() == Kind.Long && x.getKind() == Kind.Long && y.getKind() == Kind.Long) || (opcode.name().startsWith("F") && result.getKind() == Kind.Float && x.getKind() == Kind.Float && y.getKind() == Kind.Float) || (opcode.name().startsWith("D") && result.getKind() == Kind.Double && x.getKind() == Kind.Double && y.getKind() == Kind.Double) - || (opcode.name().matches(".U?SH.") && result.getKind() == x.getKind() && y.getKind() == Kind.Int && (isConstant(y) || asRegister(y) == AMD64.rcx)); + || (opcode.name().matches(".U?SH.") && result.getKind() == x.getKind() && y.getKind() == Kind.Int && (isConstant(y) || asRegister(y).equals(AMD64.rcx))); } } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64BitManipulationOp.java --- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64BitManipulationOp.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64BitManipulationOp.java Fri Jun 07 14:15:38 2013 +0200 @@ -25,6 +25,7 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.amd64.*; +import com.oracle.graal.lir.*; import com.oracle.graal.lir.asm.*; public class AMD64BitManipulationOp extends AMD64LIRInstruction { diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64BreakpointOp.java --- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64BreakpointOp.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64BreakpointOp.java Fri Jun 07 14:15:38 2013 +0200 @@ -26,7 +26,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.amd64.*; -import com.oracle.graal.lir.LIRInstruction.Opcode; +import com.oracle.graal.lir.*; import com.oracle.graal.lir.asm.*; /** diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64ByteSwapOp.java --- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64ByteSwapOp.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64ByteSwapOp.java Fri Jun 07 14:15:38 2013 +0200 @@ -25,7 +25,7 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.amd64.*; -import com.oracle.graal.lir.LIRInstruction.Opcode; +import com.oracle.graal.lir.*; import com.oracle.graal.lir.asm.*; @Opcode("BSWAP") diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Call.java --- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Call.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Call.java Fri Jun 07 14:15:38 2013 +0200 @@ -29,7 +29,6 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.amd64.*; import com.oracle.graal.lir.*; -import com.oracle.graal.lir.LIRInstruction.Opcode; import com.oracle.graal.lir.asm.*; import com.oracle.graal.nodes.spi.*; diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Compare.java --- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Compare.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Compare.java Fri Jun 07 14:15:38 2013 +0200 @@ -28,6 +28,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.amd64.*; import com.oracle.graal.graph.*; +import com.oracle.graal.lir.*; import com.oracle.graal.lir.asm.*; // @formatter:off diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64ControlFlow.java --- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64ControlFlow.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64ControlFlow.java Fri Jun 07 14:15:38 2013 +0200 @@ -35,7 +35,6 @@ import com.oracle.graal.asm.amd64.AMD64Assembler.ConditionFlag; import com.oracle.graal.graph.*; import com.oracle.graal.lir.*; -import com.oracle.graal.lir.LIRInstruction.Opcode; import com.oracle.graal.lir.StandardOp.FallThroughOp; import com.oracle.graal.lir.asm.*; import com.oracle.graal.nodes.calc.*; @@ -404,7 +403,7 @@ private static void cmove(TargetMethodAssembler tasm, AMD64MacroAssembler masm, Value result, ConditionFlag cond, Value other) { if (isRegister(other)) { - assert asRegister(other) != asRegister(result) : "other already overwritten by previous move"; + assert !asRegister(other).equals(asRegister(result)) : "other already overwritten by previous move"; switch (other.getKind()) { case Int: masm.cmovl(cond, asRegister(result), asRegister(other)); break; case Long: masm.cmovq(cond, asRegister(result), asRegister(other)); break; diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64MathIntrinsicOp.java --- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64MathIntrinsicOp.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64MathIntrinsicOp.java Fri Jun 07 14:15:38 2013 +0200 @@ -27,6 +27,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.amd64.*; import com.oracle.graal.graph.*; +import com.oracle.graal.lir.*; import com.oracle.graal.lir.asm.*; // @formatter:off diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Move.java --- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Move.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Move.java Fri Jun 07 14:15:38 2013 +0200 @@ -35,7 +35,6 @@ import com.oracle.graal.asm.amd64.*; import com.oracle.graal.graph.*; import com.oracle.graal.lir.*; -import com.oracle.graal.lir.LIRInstruction.Opcode; import com.oracle.graal.lir.StandardOp.MoveOp; import com.oracle.graal.lir.asm.*; @@ -118,6 +117,36 @@ } } + public static class LoadCompressedOop extends LoadOp { + + private long narrowOopBase; + private int narrowOopShift; + private int logMinObjAlignment; + @Temp({REG}) private AllocatableValue scratch; + + public LoadCompressedOop(Kind kind, AllocatableValue result, AllocatableValue scratch, AMD64AddressValue address, LIRFrameState state, long narrowOopBase, int narrowOopShift, + int logMinObjAlignment) { + super(kind, result, address, state); + this.narrowOopBase = narrowOopBase; + this.narrowOopShift = narrowOopShift; + this.logMinObjAlignment = logMinObjAlignment; + this.scratch = scratch; + } + + @Override + public void emitMemAccess(AMD64MacroAssembler masm) { + switch (kind) { + case Object: + Register resRegister = asRegister(result); + masm.movl(resRegister, address.toAddress()); + decodeOop(masm, resRegister, narrowOopBase, narrowOopShift, logMinObjAlignment); + break; + default: + throw GraalInternalError.shouldNotReachHere(); + } + } + } + public static class LoadOp extends MemOp { @Def({REG}) protected AllocatableValue result; @@ -161,6 +190,51 @@ } } + public static class StoreCompressedOop extends AMD64LIRInstruction { + + protected final Kind kind; + private long narrowOopBase; + private int narrowOopShift; + private int logMinObjAlignment; + @Temp({REG}) private AllocatableValue scratch; + @Alive({REG}) protected AllocatableValue input; + @Alive({COMPOSITE}) protected AMD64AddressValue address; + @State protected LIRFrameState state; + + public StoreCompressedOop(Kind kind, AMD64AddressValue address, AllocatableValue input, AllocatableValue scratch, LIRFrameState state, long narrowOopBase, int narrowOopShift, + int logMinObjAlignment) { + this.narrowOopBase = narrowOopBase; + this.narrowOopShift = narrowOopShift; + this.logMinObjAlignment = logMinObjAlignment; + this.scratch = scratch; + this.kind = kind; + this.address = address; + this.state = state; + this.input = input; + } + + @Override + public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) { + emitMemAccess(tasm, masm); + } + + public void emitMemAccess(TargetMethodAssembler tasm, AMD64MacroAssembler masm) { + switch (kind) { + case Object: + masm.movq(asRegister(scratch), asRegister(input)); + encodeOop(masm, asRegister(scratch), narrowOopBase, narrowOopShift, logMinObjAlignment); + if (state != null) { + tasm.recordImplicitException(masm.codeBuffer.position(), state); + } + masm.movl(address.toAddress(), asRegister(scratch)); + // masm.movq(asRegister(scratch), 0xDEADBEEF); + break; + default: + throw GraalInternalError.shouldNotReachHere(); + } + } + } + public static class StoreOp extends MemOp { @Use({REG}) protected AllocatableValue input; @@ -206,10 +280,12 @@ public static class StoreConstantOp extends MemOp { protected final Constant input; + private final boolean compress; - public StoreConstantOp(Kind kind, AMD64AddressValue address, Constant input, LIRFrameState state) { + public StoreConstantOp(Kind kind, AMD64AddressValue address, Constant input, LIRFrameState state, boolean compress) { super(kind, address, state); this.input = input; + this.compress = compress; } @Override @@ -240,7 +316,11 @@ throw GraalInternalError.shouldNotReachHere("Cannot store 64-bit constants to memory"); case Object: if (input.isNull()) { - masm.movptr(address.toAddress(), 0); + if (compress) { + masm.movl(address.toAddress(), 0); + } else { + masm.movptr(address.toAddress(), 0); + } } else { throw GraalInternalError.shouldNotReachHere("Cannot store 64-bit constants to memory"); } @@ -335,6 +415,37 @@ } } + @Opcode("CAS") + public static class CompareAndSwapCompressedOp extends AMD64LIRInstruction { + + @Def protected AllocatableValue result; + @Alive({COMPOSITE}) protected AMD64AddressValue address; + @Alive protected AllocatableValue cmpValue; + @Alive protected AllocatableValue newValue; + @Temp({REG}) protected AllocatableValue scratch; + + private long narrowOopBase; + private int narrowOopShift; + private int logMinObjAlignment; + + public CompareAndSwapCompressedOp(AllocatableValue result, AMD64AddressValue address, AllocatableValue cmpValue, AllocatableValue newValue, AllocatableValue scratch, long narrowOopBase, + int narrowOopShift, int logMinObjAlignment) { + this.narrowOopBase = narrowOopBase; + this.narrowOopShift = narrowOopShift; + this.logMinObjAlignment = logMinObjAlignment; + this.scratch = scratch; + this.result = result; + this.address = address; + this.cmpValue = cmpValue; + this.newValue = newValue; + } + + @Override + public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) { + compareAndSwapCompressed(tasm, masm, result, address, cmpValue, newValue, scratch, narrowOopBase, narrowOopShift, logMinObjAlignment); + } + } + public static void move(TargetMethodAssembler tasm, AMD64MacroAssembler masm, Value result, Value input) { if (isRegister(input)) { if (isRegister(result)) { @@ -526,7 +637,7 @@ } protected static void compareAndSwap(TargetMethodAssembler tasm, AMD64MacroAssembler masm, AllocatableValue result, AMD64AddressValue address, AllocatableValue cmpValue, AllocatableValue newValue) { - assert asRegister(cmpValue) == AMD64.rax && asRegister(result) == AMD64.rax; + assert asRegister(cmpValue).equals(AMD64.rax) && asRegister(result).equals(AMD64.rax); if (tasm.target.isMP) { masm.lock(); @@ -543,4 +654,51 @@ throw GraalInternalError.shouldNotReachHere(); } } + + protected static void compareAndSwapCompressed(TargetMethodAssembler tasm, AMD64MacroAssembler masm, AllocatableValue result, AMD64AddressValue address, AllocatableValue cmpValue, + AllocatableValue newValue, AllocatableValue scratch, long narrowOopBase, int narrowOopShift, int logMinObjAlignment) { + assert asRegister(cmpValue) == AMD64.rax && asRegister(result) == AMD64.rax; + + switch (cmpValue.getKind()) { + case Object: + final Register scratchRegister = asRegister(scratch); + final Register cmpRegister = asRegister(cmpValue); + final Register newRegister = asRegister(newValue); + encodeOop(masm, cmpRegister, narrowOopBase, narrowOopShift, logMinObjAlignment); + masm.movq(scratchRegister, newRegister); + encodeOop(masm, scratchRegister, narrowOopBase, narrowOopShift, logMinObjAlignment); + if (tasm.target.isMP) { + masm.lock(); + } + masm.cmpxchgl(scratchRegister, address.toAddress()); + break; + default: + throw GraalInternalError.shouldNotReachHere(); + } + } + + private static void encodeOop(AMD64MacroAssembler masm, Register scratchRegister, long narrowOopBase, int narrowOopShift, int logMinObjAlignment) { + if (narrowOopBase == 0) { + if (narrowOopShift != 0) { + assert logMinObjAlignment == narrowOopShift : "Encode algorithm is wrong"; + masm.shrq(scratchRegister, logMinObjAlignment); + } + } else { + masm.subq(scratchRegister, AMD64.r12); + masm.shrq(scratchRegister, logMinObjAlignment); + } + } + + private static void decodeOop(AMD64MacroAssembler masm, Register resRegister, long narrowOopBase, int narrowOopShift, int logMinObjAlignment) { + if (narrowOopBase == 0) { + if (narrowOopShift != 0) { + assert logMinObjAlignment == narrowOopShift : "Decode algorithm is wrong"; + masm.shlq(resRegister, logMinObjAlignment); + } + } else { + masm.shlq(resRegister, logMinObjAlignment); + masm.addq(resRegister, AMD64.r12); + } + } + } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64RestoreRegistersOp.java --- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64RestoreRegistersOp.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64RestoreRegistersOp.java Fri Jun 07 14:15:38 2013 +0200 @@ -26,7 +26,7 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.asm.amd64.*; -import com.oracle.graal.lir.LIRInstruction.Opcode; +import com.oracle.graal.lir.*; import com.oracle.graal.lir.asm.*; /** diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64SaveRegistersOp.java --- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64SaveRegistersOp.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64SaveRegistersOp.java Fri Jun 07 14:15:38 2013 +0200 @@ -29,7 +29,6 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.asm.amd64.*; import com.oracle.graal.lir.*; -import com.oracle.graal.lir.LIRInstruction.Opcode; import com.oracle.graal.lir.asm.*; /** diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64ZapRegistersOp.java --- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64ZapRegistersOp.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64ZapRegistersOp.java Fri Jun 07 14:15:38 2013 +0200 @@ -30,7 +30,6 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.amd64.*; import com.oracle.graal.lir.*; -import com.oracle.graal.lir.LIRInstruction.Opcode; import com.oracle.graal.lir.asm.*; /** diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXBitManipulationOp.java --- a/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXBitManipulationOp.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXBitManipulationOp.java Fri Jun 07 14:15:38 2013 +0200 @@ -26,6 +26,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.ptx.*; import com.oracle.graal.graph.*; +import com.oracle.graal.lir.*; import com.oracle.graal.lir.asm.*; public class PTXBitManipulationOp extends PTXLIRInstruction { diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXCompare.java --- a/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXCompare.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXCompare.java Fri Jun 07 14:15:38 2013 +0200 @@ -29,6 +29,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.ptx.*; import com.oracle.graal.graph.*; +import com.oracle.graal.lir.*; import com.oracle.graal.lir.asm.*; import com.oracle.graal.nodes.calc.*; diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXMove.java --- a/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXMove.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXMove.java Fri Jun 07 14:15:38 2013 +0200 @@ -30,7 +30,6 @@ import com.oracle.graal.asm.ptx.*; import com.oracle.graal.graph.*; import com.oracle.graal.lir.*; -import com.oracle.graal.lir.LIRInstruction.Opcode; import com.oracle.graal.lir.StandardOp.MoveOp; import com.oracle.graal.lir.asm.*; diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCAddressValue.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCAddressValue.java Fri Jun 07 14:15:38 2013 +0200 @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.lir.sparc; + +import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.asm.sparc.*; +import com.oracle.graal.lir.*; +import com.oracle.graal.lir.LIRInstruction.*; + +public class SPARCAddressValue extends CompositeValue { + + private static final long serialVersionUID = -3583286416638228207L; + + @Component({ REG, OperandFlag.ILLEGAL }) + protected AllocatableValue base; + protected final int displacement; + + public SPARCAddressValue(PlatformKind kind, AllocatableValue baseRegister, + int finalDisp) { + super(kind); + this.base = baseRegister; + this.displacement = finalDisp; + } + + private static Register toRegister(AllocatableValue value) { + if (value.equals(Value.ILLEGAL)) { + return Register.None; + } else { + RegisterValue reg = (RegisterValue) value; + return reg.getRegister(); + } + } + + public SPARCAddress toAddress() { + return new SPARCAddress(toRegister(base), displacement); + } + +} diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArithmetic.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArithmetic.java Fri Jun 07 14:15:38 2013 +0200 @@ -0,0 +1,605 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.lir.sparc; + +import static com.oracle.graal.api.code.ValueUtil.*; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Add; +import static com.oracle.graal.asm.sparc.SPARCAssembler.And; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Fadds; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Faddd; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Fdivs; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Fdivd; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Fdtoi; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Fmuls; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Fmuld; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Fnegs; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Fnegd; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Fstoi; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Fsubs; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Fsubd; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Mulx; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Or; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Sdivx; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Sll; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Sllx; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Srl; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Srlx; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Sra; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Sub; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Xor; +import static com.oracle.graal.asm.sparc.SPARCAssembler.isSimm13; +import static com.oracle.graal.lir.LIRInstruction.OperandFlag.CONST; +import static com.oracle.graal.lir.LIRInstruction.OperandFlag.HINT; +import static com.oracle.graal.lir.LIRInstruction.OperandFlag.REG; +import static com.oracle.graal.lir.LIRInstruction.OperandFlag.STACK; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.asm.sparc.SPARCAssembler; +import com.oracle.graal.graph.GraalInternalError; +import com.oracle.graal.lir.*; +import com.oracle.graal.lir.asm.TargetMethodAssembler; + +//@formatter:off +public enum SPARCArithmetic { + // @formatter:off + IADD, ISUB, IMUL, IDIV, IDIVREM, IREM, IUDIV, IUREM, IAND, IOR, IXOR, ISHL, ISHR, IUSHR, + LADD, LSUB, LMUL, LDIV, LDIVREM, LREM, LUDIV, LUREM, LAND, LOR, LXOR, LSHL, LSHR, LUSHR, + FADD, FSUB, FMUL, FDIV, FREM, FAND, FOR, FXOR, + DADD, DSUB, DMUL, DDIV, DREM, DAND, DOR, DXOR, + INEG, LNEG, FNEG, DNEG, + I2L, L2I, I2B, I2C, I2S, + F2D, D2F, + I2F, I2D, F2I, D2I, + L2F, L2D, F2L, D2L, + MOV_I2F, MOV_L2D, MOV_F2I, MOV_D2L; + + /** + * Binary operation with single source/destination operand and one constant. + */ + public static class BinaryRegConst extends SPARCLIRInstruction { + @Opcode private final SPARCArithmetic opcode; + @Def({REG, HINT}) protected AllocatableValue result; + @Use({REG, STACK}) protected AllocatableValue x; + protected Constant y; + + public BinaryRegConst(SPARCArithmetic opcode, AllocatableValue result, AllocatableValue x, Constant y) { + this.opcode = opcode; + this.result = result; + this.x = x; + this.y = y; + } + + @Override + public void emitCode(TargetMethodAssembler tasm, SPARCAssembler masm) { + SPARCMove.move(tasm, masm, result, x); + emit(tasm, masm, opcode, result, y, null); + } + + @Override + public void verify() { + super.verify(); + verifyKind(opcode, result, x, y); + } + } + + /** + * Unary operation with separate source and destination operand. + */ + public static class Unary2Op extends SPARCLIRInstruction { + + @Opcode + private final SPARCArithmetic opcode; + @Def({ REG }) + protected AllocatableValue result; + @Use({ REG, STACK }) + protected AllocatableValue x; + + public Unary2Op(SPARCArithmetic opcode, AllocatableValue result, AllocatableValue x) { + this.opcode = opcode; + this.result = result; + this.x = x; + } + + @Override + public void emitCode(TargetMethodAssembler tasm, SPARCAssembler masm) { + SPARCMove.move(tasm, masm, result, x); + emit(tasm, masm, opcode, result, x, null); + } + } + + /** + * Unary operation with single operand for source and destination. + */ + public static class Unary1Op extends SPARCLIRInstruction { + + @Opcode + private final SPARCArithmetic opcode; + @Def({ REG, HINT }) + protected AllocatableValue result; + @Use({ REG, STACK }) + protected AllocatableValue x; + + public Unary1Op(SPARCArithmetic opcode, AllocatableValue result, AllocatableValue x) { + this.opcode = opcode; + this.result = result; + this.x = x; + } + + @Override + public void emitCode(TargetMethodAssembler tasm, SPARCAssembler masm) { + emit(masm, opcode, result); + } + } + + public static class Op1Stack extends SPARCLIRInstruction { + + @Opcode + private final SPARCArithmetic opcode; + @Def({ REG, HINT }) + protected Value result; + @Use({ REG, STACK, CONST }) + protected Value x; + + public Op1Stack(SPARCArithmetic opcode, Value result, Value x) { + this.opcode = opcode; + this.result = result; + this.x = x; + } + + @Override + public void emitCode(TargetMethodAssembler tasm, SPARCAssembler masm) { + emit(tasm, masm, opcode, result, x, null); + } + } + + public static class Op2Stack extends SPARCLIRInstruction { + + @Opcode + private final SPARCArithmetic opcode; + @Def({ REG, HINT }) + protected Value result; + @Use({ REG, STACK, CONST }) + protected Value x; + @Alive({ REG, STACK, CONST }) + protected Value y; + + public Op2Stack(SPARCArithmetic opcode, Value result, Value x, Value y) { + this.opcode = opcode; + this.result = result; + this.x = x; + this.y = y; + } + + @Override + public void emitCode(TargetMethodAssembler tasm, SPARCAssembler masm) { + emit(tasm, masm, opcode, result, x, y, null); + } + + @Override + public void verify() { + super.verify(); + verifyKind(opcode, result, x, y); + } + } + + public static class Op2Reg extends SPARCLIRInstruction { + + @Opcode + private final SPARCArithmetic opcode; + @Def({ REG, HINT }) + protected Value result; + @Use({ REG, STACK, CONST }) + protected Value x; + @Alive({ REG, CONST }) + protected Value y; + + public Op2Reg(SPARCArithmetic opcode, Value result, Value x, Value y) { + this.opcode = opcode; + this.result = result; + this.x = x; + this.y = y; + } + + @Override + public void emitCode(TargetMethodAssembler tasm, SPARCAssembler masm) { + emit(tasm, masm, opcode, result, x, y, null); + } + + @Override + public void verify() { + super.verify(); + verifyKind(opcode, result, x, y); + } + } + + public static class ShiftOp extends SPARCLIRInstruction { + + @Opcode + private final SPARCArithmetic opcode; + @Def({ REG, HINT }) + protected Value result; + @Use({ REG, STACK, CONST }) + protected Value x; + @Alive({ REG, CONST }) + protected Value y; + + public ShiftOp(SPARCArithmetic opcode, Value result, Value x, Value y) { + this.opcode = opcode; + this.result = result; + this.x = x; + this.y = y; + } + + @Override + public void emitCode(TargetMethodAssembler tasm, SPARCAssembler masm) { + emit(tasm, masm, opcode, result, x, y, null); + } + + @Override + public void verify() { + super.verify(); + verifyKind(opcode, result, x, x); + assert y.getKind().getStackKind() == Kind.Int; + } + } + + @SuppressWarnings("unused") + protected static void emit(SPARCAssembler masm, SPARCArithmetic opcode, Value result) { + switch (opcode) { + case L2I: + new And(masm, asIntReg(result), -1, asIntReg(result)); + break; + case I2C: + new Sll(masm, asIntReg(result), 16, asIntReg(result)); + new Srl(masm, asIntReg(result), 16, asIntReg(result)); + break; + default: + throw GraalInternalError.shouldNotReachHere("missing: " + opcode); + } + } + + @SuppressWarnings("unused") + public static void emit(TargetMethodAssembler tasm, SPARCAssembler masm, + SPARCArithmetic opcode, Value dst, Value src1, Value src2, LIRFrameState info) { + int exceptionOffset = -1; + if (isConstant(src1)) { + switch (opcode) { + case ISUB: + assert isSimm13(tasm.asIntConst(src1)); + new Add(masm, asIntReg(src2), -(tasm.asIntConst(src1)), asIntReg(dst)); + break; + case IAND: + throw new InternalError("NYI"); + case IDIV: + assert isSimm13(tasm.asIntConst(src1)); + throw new InternalError("NYI"); + // new Sdivx(masm, asIntReg(src1), asIntReg(src2), + // asIntReg(dst)); + case FSUB: + throw new InternalError("NYI"); + case FDIV: + throw new InternalError("NYI"); + case DSUB: + throw new InternalError("NYI"); + case DDIV: + throw new InternalError("NYI"); + default: + throw GraalInternalError.shouldNotReachHere(); + } + } else if (isConstant(src2)) { + switch (opcode) { + case IADD: + assert isSimm13(tasm.asIntConst(src2)); + new Add(masm, asIntReg(src1), tasm.asIntConst(src2), asIntReg(dst)); + break; + case ISUB: + assert isSimm13(tasm.asIntConst(src2)); + new Sub(masm, asIntReg(src1), tasm.asIntConst(src2), asIntReg(dst)); + break; + case IMUL: + assert isSimm13(tasm.asIntConst(src2)); + new Mulx(masm, asIntReg(src1), tasm.asIntConst(src2), asIntReg(dst)); + break; + case IAND: + assert isSimm13(tasm.asIntConst(src2)); + new And(masm, asIntReg(src1), tasm.asIntConst(src2), asIntReg(dst)); + break; + case ISHL: + assert isSimm13(tasm.asIntConst(src2)); + new Sll(masm, asIntReg(src1), tasm.asIntConst(src2), asIntReg(dst)); + break; + case ISHR: + assert isSimm13(tasm.asIntConst(src2)); + new Srl(masm, asIntReg(src1), tasm.asIntConst(src2), asIntReg(dst)); + break; + case IUSHR: + assert isSimm13(tasm.asIntConst(src2)); + new Sra(masm, asIntReg(src1), tasm.asIntConst(src2), asIntReg(dst)); + break; + case IXOR: + assert isSimm13(tasm.asIntConst(src2)); + new Xor(masm, asIntReg(src1), tasm.asIntConst(src2), asIntReg(dst)); + break; + case LXOR: + assert isSimm13(tasm.asIntConst(src2)); + new Add(masm, asLongReg(src1), tasm.asIntConst(src2), asLongReg(dst)); + break; + case LUSHR: + throw new InternalError("NYI"); + case FADD: + throw new InternalError("NYI"); + case FMUL: + throw new InternalError("NYI"); + case FDIV: + throw new InternalError("NYI"); + case DADD: + throw new InternalError("NYI"); + case DMUL: + throw new InternalError("NYI"); + case DDIV: + throw new InternalError("NYI"); + default: + throw GraalInternalError.shouldNotReachHere(); + } + } else { + switch (opcode) { + case IADD: + new Add(masm, asIntReg(src1), asIntReg(src2), asIntReg(dst)); + break; + case ISUB: + new Sub(masm, asIntReg(src1), asIntReg(src2), asIntReg(dst)); + break; + case IMUL: + new Mulx(masm, asIntReg(src1), asIntReg(src2), asIntReg(dst)); + break; + case IDIV: + new Sdivx(masm, asIntReg(src1), asIntReg(src2), asIntReg(dst)); + break; + case IAND: + new And(masm, asIntReg(src1), asIntReg(src2), asIntReg(dst)); + break; + case IOR: + new Or(masm, asIntReg(src1), asIntReg(src2), asIntReg(dst)); + break; + case IXOR: + new Xor(masm, asIntReg(src1), asIntReg(src2), asIntReg(dst)); + break; + case ISHL: + new Sll(masm, asIntReg(src1), asIntReg(src2), asIntReg(dst)); + break; + case ISHR: + new Srl(masm, asIntReg(src1), asIntReg(src2), asIntReg(dst)); + break; + case IUSHR: + new Sra(masm, asIntReg(src1), asIntReg(src2), asIntReg(dst)); + break; + case IREM: + throw new InternalError("NYI"); + case LADD: + new Add(masm, asLongReg(src1), asLongReg(src2), asLongReg(dst)); + break; + case LSUB: + new Sub(masm, asLongReg(src1), asLongReg(src2), asLongReg(dst)); + break; + case LMUL: + new Mulx(masm, asLongReg(src1), asLongReg(src2), asLongReg(dst)); + break; + case LDIV: + new Sdivx(masm, asLongReg(src1), asLongReg(src2), + asLongReg(dst)); + break; + case LAND: + new And(masm, asLongReg(src1), asLongReg(src2), asLongReg(dst)); + break; + case LOR: + new Or(masm, asLongReg(src1), asLongReg(src2), asLongReg(dst)); + break; + case LXOR: + new Xor(masm, asLongReg(src1), asLongReg(src2), asLongReg(dst)); + break; + case LSHL: + new Sll(masm, asLongReg(src1), asLongReg(src2), asLongReg(dst)); + break; + case LSHR: + new Srl(masm, asLongReg(src1), asLongReg(src2), asLongReg(dst)); + break; + case LUSHR: + new Sra(masm, asLongReg(src1), asIntReg(src2), asLongReg(dst)); + break; + case LDIVREM: + case LUDIV: + case LUREM: + case LREM: + throw new InternalError("NYI"); + case FADD: + new Fadds(masm, asFloatReg(src1), asFloatReg(src2), + asFloatReg(dst)); + break; + case FSUB: + new Fsubs(masm, asFloatReg(src1), asFloatReg(src2), + asFloatReg(dst)); + break; + case FMUL: + new Fmuls(masm, asFloatReg(src1), asFloatReg(src2), + asFloatReg(dst)); + break; + case FDIV: + new Fdivs(masm, asFloatReg(src1), asFloatReg(src2), + asFloatReg(dst)); + break; + case FREM: + throw new InternalError("NYI"); + case DADD: + new Faddd(masm, asDoubleReg(src1), asDoubleReg(src2), + asDoubleReg(dst)); + break; + case DSUB: + new Fsubd(masm, asDoubleReg(src1), asDoubleReg(src2), + asDoubleReg(dst)); + break; + case DMUL: + new Fmuld(masm, asDoubleReg(src1), asDoubleReg(src2), + asDoubleReg(dst)); + break; + case DDIV: + new Fdivd(masm, asDoubleReg(src1), asDoubleReg(src2), + asDoubleReg(dst)); + break; + case DREM: + throw new InternalError("NYI"); + default: + throw GraalInternalError.shouldNotReachHere("missing: " + + opcode); + } + } + + if (info != null) { + assert exceptionOffset != -1; + tasm.recordImplicitException(exceptionOffset, info); + } + } + + @SuppressWarnings("unused") + public static void emit(TargetMethodAssembler tasm, SPARCAssembler masm, + SPARCArithmetic opcode, Value dst, Value src, LIRFrameState info) { + int exceptionOffset = -1; + if (isRegister(src)) { + switch (opcode) { + case I2L: + new Sra(masm, asIntReg(src), 0, asLongReg(dst)); + break; + case I2B: + new Sll(masm, asIntReg(src), 24, asIntReg(src)); + new Srl(masm, asIntReg(dst), 24, asIntReg(src)); + break; + case I2F: + new Fstoi(masm, asIntReg(src), asFloatReg(dst)); + break; + case I2D: + new Fdtoi(masm, asIntReg(src), asDoubleReg(dst)); + break; + case FNEG: + new Fnegs(masm, asFloatReg(src), asFloatReg(dst)); + break; + case DNEG: + new Fnegd(masm, asDoubleReg(src), asDoubleReg(dst)); + break; + case LSHL: + new Sllx(masm, asLongReg(dst), asIntReg(src), asLongReg(dst)); + break; + case LSHR: + new Srlx(masm, asLongReg(dst), asIntReg(src), asLongReg(dst)); + break; + default: + throw GraalInternalError.shouldNotReachHere("missing: " + + opcode); + } + } else if (isConstant(src)) { + switch (opcode) { + default: + throw GraalInternalError.shouldNotReachHere("missing: " + + opcode); + } + } else { + switch (opcode) { + default: + throw GraalInternalError.shouldNotReachHere("missing: " + + opcode); + } + } + + if (info != null) { + assert exceptionOffset != -1; + tasm.recordImplicitException(exceptionOffset, info); + } + } + + private static void verifyKind(SPARCArithmetic opcode, Value result, Value x, Value y) { + Kind rk; + Kind xk; + Kind yk; + Kind xsk; + Kind ysk; + + switch (opcode) { + case IADD: + case ISUB: + case IMUL: + case IDIV: + case IREM: + case IAND: + case IOR: + case IXOR: + case ISHL: + case ISHR: + case IUSHR: + rk = result.getKind(); + xsk = x.getKind().getStackKind(); + ysk = y.getKind().getStackKind(); + + assert rk == Kind.Int && xsk == Kind.Int && ysk == Kind.Int; + break; + case LADD: + case LSUB: + case LMUL: + case LDIV: + case LREM: + case LAND: + case LOR: + case LXOR: + case LSHL: + case LSHR: + case LUSHR: + rk = result.getKind(); + xk = x.getKind(); + yk = y.getKind(); + + assert rk == Kind.Long && xk == Kind.Long && yk == Kind.Long; + break; + case FADD: + case FSUB: + case FMUL: + case FDIV: + case FREM: + rk = result.getKind(); + xk = x.getKind(); + yk = y.getKind(); + + assert rk == Kind.Float && xk == Kind.Float && yk == Kind.Float; + break; + case DADD: + case DSUB: + case DMUL: + case DDIV: + case DREM: + rk = result.getKind(); + xk = x.getKind(); + yk = y.getKind(); + + assert rk == Kind.Double && xk == Kind.Double && yk == Kind.Double; + break; + default: + throw new InternalError("NYI: " + opcode); + } + } +} diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCBitManipulationOp.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCBitManipulationOp.java Fri Jun 07 14:15:38 2013 +0200 @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.lir.sparc; + +import static com.oracle.graal.asm.sparc.SPARCAssembler.Popc; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Srl; +import static com.oracle.graal.asm.sparc.SPARCAssembler.isSimm13; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.asm.sparc.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.lir.*; +import com.oracle.graal.lir.asm.*; +import com.oracle.graal.sparc.SPARC; + +public class SPARCBitManipulationOp extends SPARCLIRInstruction { + + public enum IntrinsicOpcode { + IPOPCNT, LPOPCNT, IBSR, LBSR, BSF; + } + + @Opcode private final IntrinsicOpcode opcode; + @Def protected AllocatableValue result; + @Use({OperandFlag.REG, OperandFlag.STACK}) protected AllocatableValue input; + + public SPARCBitManipulationOp(IntrinsicOpcode opcode, AllocatableValue result, AllocatableValue input) { + this.opcode = opcode; + this.result = result; + this.input = input; + } + + @Override + @SuppressWarnings("unused") + public void emitCode(TargetMethodAssembler tasm, SPARCAssembler masm) { + Register dst = ValueUtil.asIntReg(result); + if (ValueUtil.isRegister(input)) { + Register src = ValueUtil.asRegister(input); + switch (opcode) { + case IPOPCNT: + // clear upper word for 64 bit POPC + new Srl(masm, src, SPARC.g0, dst); + new Popc(masm, src, dst); + break; + case LPOPCNT: + new Popc(masm, src, dst); + break; + case BSF: // masm.bsfq(dst, src); + case IBSR: // masm.bsrl(dst, src); + case LBSR: // masm.bsrq(dst, src); + default: + throw GraalInternalError.shouldNotReachHere("missing: " + opcode); + + } + } else if (ValueUtil.isConstant(input) && isSimm13(tasm.asIntConst(input))) { + switch (opcode) { + case IPOPCNT: + new Popc(masm, tasm.asIntConst(input), dst); + break; + case LPOPCNT: + new Popc(masm, tasm.asIntConst(input), dst); + break; + default: + throw GraalInternalError.shouldNotReachHere("missing: " + opcode); + } + } else { + SPARCAddress src = (SPARCAddress) tasm.asAddress(input); + switch (opcode) { + case IPOPCNT: + // masm.popcntl(dst, src); + break; + case LPOPCNT: + // masm.popcntq(dst, src); + break; + case BSF: + // masm.bsfq(dst, src); + break; + case IBSR: + // masm.bsrl(dst, src); + break; + case LBSR: + // masm.bsrq(dst, src); + break; + } + } + } + +} diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCBreakpointOp.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCBreakpointOp.java Fri Jun 07 14:15:38 2013 +0200 @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.lir.sparc; + +import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.asm.sparc.*; +import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Trap; +import com.oracle.graal.lir.*; +import com.oracle.graal.lir.asm.*; + +/** + * Emits a breakpoint. + */ +@Opcode("BREAKPOINT") +public class SPARCBreakpointOp extends SPARCLIRInstruction { + + // historical - from hotspot src/cpu/sparc/vm + // promises that the system will not use traps 16-31 + // We want to use ST_BREAKPOINT here, but the debugger is confused by it. + public static final int ST_RESERVED_FOR_USER_0 = 0x10; + + /** + * A set of values loaded into the Java ABI parameter locations (for inspection by a debugger). + */ + @Use({REG, STACK}) protected Value[] parameters; + + public SPARCBreakpointOp(Value[] parameters) { + this.parameters = parameters; + } + + @Override + @SuppressWarnings("unused") + public void emitCode(TargetMethodAssembler tasm, SPARCAssembler asm) { + new Trap(asm, ST_RESERVED_FOR_USER_0); + } +} diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCByteSwapOp.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCByteSwapOp.java Fri Jun 07 14:15:38 2013 +0200 @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.lir.sparc; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.asm.sparc.*; +import com.oracle.graal.lir.*; +import com.oracle.graal.lir.asm.*; + +@Opcode("BSWAP") +public class SPARCByteSwapOp extends SPARCLIRInstruction { + + @Def({OperandFlag.REG, OperandFlag.HINT}) protected Value result; + @Use protected Value input; + + public SPARCByteSwapOp(Value result, Value input) { + this.result = result; + this.input = input; + } + + @Override + public void emitCode(TargetMethodAssembler tasm, SPARCAssembler masm) { + SPARCMove.move(tasm, masm, result, input); + switch (input.getKind()) { + // case Int: + // masm.bswapl(ValueUtil.asIntReg(result)); + // case Long: + // masm.bswapq(ValueUtil.asLongReg(result)); + } + } +} diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCCompare.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCCompare.java Fri Jun 07 14:15:38 2013 +0200 @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.lir.sparc; + +import static com.oracle.graal.api.code.ValueUtil.*; +import static com.oracle.graal.asm.sparc.SPARCAssembler.isSimm13; +import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.asm.sparc.SPARCAssembler; +import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Cmp; +import com.oracle.graal.graph.*; +import com.oracle.graal.lir.*; +import com.oracle.graal.lir.asm.*; + +//@formatter:off +public enum SPARCCompare { + ICMP, LCMP, ACMP, FCMP, DCMP; + + public static class CompareOp extends SPARCLIRInstruction { + + @Opcode private final SPARCCompare opcode; + @Use({REG, STACK, CONST}) protected Value x; + @Use({REG, STACK, CONST}) protected Value y; + + public CompareOp(SPARCCompare opcode, Value x, Value y) { + this.opcode = opcode; + this.x = x; + this.y = y; + } + + @Override + public void emitCode(TargetMethodAssembler tasm, SPARCAssembler masm) { + emit(tasm, masm, opcode, x, y); + } + + @Override + protected void verify() { + super.verify(); + assert (name().startsWith("I") && x.getKind() == Kind.Int && y.getKind().getStackKind() == Kind.Int) + || (name().startsWith("L") && x.getKind() == Kind.Long && y.getKind() == Kind.Long) + || (name().startsWith("A") && x.getKind() == Kind.Object && y.getKind() == Kind.Object) + || (name().startsWith("F") && x.getKind() == Kind.Float && y.getKind() == Kind.Float) + || (name().startsWith("D") && x.getKind() == Kind.Double && y.getKind() == Kind.Double); + } + } + + @SuppressWarnings("unused") + public static void emit(TargetMethodAssembler tasm, SPARCAssembler masm, SPARCCompare opcode, Value x, Value y) { + if (isRegister(y)) { + switch (opcode) { + case ICMP: + new Cmp(masm, asIntReg(x), asIntReg(y)); + break; + case LCMP: + new Cmp(masm, asLongReg(x), asLongReg(y)); + break; + case ACMP: + // masm.cmpptr(asObjectReg(x), asObjectReg(y)); + break; + case FCMP: + // masm.ucomiss(asFloatReg(x), asFloatReg(y)); + break; + case DCMP: + // masm.ucomisd(asDoubleReg(x), asDoubleReg(y)); + break; + default: + throw GraalInternalError.shouldNotReachHere(); + } + } else if (isConstant(y)) { + switch (opcode) { + case ICMP: + assert isSimm13(tasm.asIntConst(y)); + new Cmp(masm, asIntReg(x), tasm.asIntConst(y)); + break; + case LCMP: + assert isSimm13(tasm.asIntConst(y)); + new Cmp(masm, asLongReg(x), tasm.asIntConst(y)); + break; + case ACMP: + if (((Constant) y).isNull()) { + // masm.cmpq(asObjectReg(x), 0); + break; + } else { + throw GraalInternalError.shouldNotReachHere("Only null object constants are allowed in comparisons"); + } + case FCMP: + // masm.ucomiss(asFloatReg(x), (AMD64Address) tasm.asFloatConstRef(y)); + break; + case DCMP: + // masm.ucomisd(asDoubleReg(x), (AMD64Address) tasm.asDoubleConstRef(y)); + break; + default: + throw GraalInternalError.shouldNotReachHere(); + } + } else { + switch (opcode) { + case ICMP: + // masm.cmpl(asIntReg(x), (AMD64Address) tasm.asIntAddr(y)); + break; + case LCMP: + // masm.cmpq(asLongReg(x), (AMD64Address) tasm.asLongAddr(y)); + break; + case ACMP: + // masm.cmpptr(asObjectReg(x), (AMD64Address) tasm.asObjectAddr(y)); + break; + case FCMP: + // masm.ucomiss(asFloatReg(x), (AMD64Address) tasm.asFloatAddr(y)); + break; + case DCMP: + // masm.ucomisd(asDoubleReg(x), (AMD64Address) tasm.asDoubleAddr(y)); + break; + default: + throw GraalInternalError.shouldNotReachHere(); + } + } + } +} diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java Fri Jun 07 14:15:38 2013 +0200 @@ -0,0 +1,435 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.lir.sparc; + +import static com.oracle.graal.api.code.ValueUtil.*; +import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; + +import com.oracle.graal.api.code.CompilationResult.JumpTable; +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.asm.*; +import com.oracle.graal.asm.sparc.*; +import com.oracle.graal.asm.sparc.SPARCAssembler.Bpe; +import com.oracle.graal.asm.sparc.SPARCAssembler.CC; +import com.oracle.graal.asm.sparc.SPARCAssembler.ConditionFlag; +import com.oracle.graal.asm.sparc.SPARCAssembler.Subcc; +import com.oracle.graal.graph.*; +import com.oracle.graal.lir.*; +import com.oracle.graal.lir.StandardOp.FallThroughOp; +import com.oracle.graal.lir.asm.*; +import com.oracle.graal.nodes.calc.*; +import com.oracle.graal.sparc.*; + +public class SPARCControlFlow { + + public static class BranchOp extends SPARCLIRInstruction implements StandardOp.BranchOp { + + protected Condition condition; + protected LabelRef destination; + + public BranchOp(Condition condition, LabelRef destination) { + this.condition = condition; + this.destination = destination; + } + + @Override + @SuppressWarnings("unused") + public void emitCode(TargetMethodAssembler tasm, SPARCAssembler masm) { + // masm.at(); + Label l = destination.label(); + // l.addPatchAt(tasm.asm.codeBuffer.position()); + String target = l.isBound() ? "L" + l.toString() : AbstractSPARCAssembler.UNBOUND_TARGET; + // masm.bra(target); + } + + @Override + public LabelRef destination() { + return destination; + } + + @Override + public void negate(LabelRef newDestination) { + destination = newDestination; + condition = condition.negate(); + } + } + + @Opcode("CMOVE") + public static class CondMoveOp extends SPARCLIRInstruction { + + @Def({REG, HINT}) protected Value result; + @Alive({REG}) protected Value trueValue; + @Use({REG, STACK, CONST}) protected Value falseValue; + + private final ConditionFlag condition; + + public CondMoveOp(Variable result, Condition condition, Variable trueValue, Value falseValue) { + this.result = result; + this.condition = intCond(condition); + this.trueValue = trueValue; + this.falseValue = falseValue; + } + + @Override + public void emitCode(TargetMethodAssembler tasm, SPARCAssembler masm) { + cmove(tasm, masm, result, false, condition, false, trueValue, falseValue); + } + } + + @Opcode("CMOVE") + public static class FloatCondMoveOp extends SPARCLIRInstruction { + + @Def({REG}) protected Value result; + @Alive({REG}) protected Value trueValue; + @Alive({REG}) protected Value falseValue; + private final ConditionFlag condition; + private final boolean unorderedIsTrue; + + public FloatCondMoveOp(Variable result, Condition condition, boolean unorderedIsTrue, Variable trueValue, Variable falseValue) { + this.result = result; + this.condition = floatCond(condition); + this.unorderedIsTrue = unorderedIsTrue; + this.trueValue = trueValue; + this.falseValue = falseValue; + } + + @Override + public void emitCode(TargetMethodAssembler tasm, SPARCAssembler masm) { + cmove(tasm, masm, result, true, condition, unorderedIsTrue, trueValue, falseValue); + } + } + + private static void cmove(TargetMethodAssembler tasm, SPARCAssembler masm, Value result, boolean isFloat, ConditionFlag condition, boolean unorderedIsTrue, Value trueValue, Value falseValue) { + // check that we don't overwrite an input operand before it is used. + assert !result.equals(trueValue); + + SPARCMove.move(tasm, masm, result, falseValue); + cmove(tasm, masm, result, condition, trueValue); + + if (isFloat) { + if (unorderedIsTrue && !trueOnUnordered(condition)) { + // cmove(tasm, masm, result, ConditionFlag.Parity, trueValue); + } else if (!unorderedIsTrue && trueOnUnordered(condition)) { + // cmove(tasm, masm, result, ConditionFlag.Parity, falseValue); + } + } + } + + @SuppressWarnings("unused") + private static void cmove(TargetMethodAssembler tasm, SPARCAssembler masm, Value result, ConditionFlag cond, Value other) { + if (isRegister(other)) { + assert !asRegister(other).equals(asRegister(result)) : "other already overwritten by previous move"; + switch (other.getKind()) { + case Int: + // masm.cmovl(cond, asRegister(result), asRegister(other)); + break; + case Long: + // masm.cmovq(cond, asRegister(result), asRegister(other)); + break; + default: + throw GraalInternalError.shouldNotReachHere(); + } + } else { + SPARCAddress addr = (SPARCAddress) tasm.asAddress(other); + switch (other.getKind()) { + case Int: + // masm.cmovl(cond, asRegister(result), addr); + break; + case Long: + // masm.cmovq(cond, asRegister(result), addr); + break; + default: + throw GraalInternalError.shouldNotReachHere(); + } + } + } + + private static ConditionFlag intCond(Condition cond) { + switch (cond) { + case EQ: + return ConditionFlag.Equal; + case NE: + return ConditionFlag.NotEqual; + case LT: + return ConditionFlag.Less; + case LE: + return ConditionFlag.LessEqual; + case GE: + return ConditionFlag.GreaterEqual; + case GT: + return ConditionFlag.Greater; + case BE: + case AE: + case AT: + case BT: + default: + throw GraalInternalError.shouldNotReachHere(); + } + } + + private static ConditionFlag floatCond(Condition cond) { + switch (cond) { + case EQ: + return ConditionFlag.Equal; + case NE: + return ConditionFlag.NotEqual; + case LT: + case LE: + case GE: + case GT: + default: + throw GraalInternalError.shouldNotReachHere(); + } + } + + private static boolean trueOnUnordered(ConditionFlag condition) { + switch (condition) { + case NotEqual: + case Less: + return false; + case Equal: + case GreaterEqual: + return true; + default: + throw GraalInternalError.shouldNotReachHere(); + } + } + + public static class ReturnOp extends SPARCLIRInstruction { + + @Use({REG, ILLEGAL}) protected Value x; + + public ReturnOp(Value x) { + this.x = x; + } + + @Override + public void emitCode(TargetMethodAssembler tasm, SPARCAssembler masm) { + if (tasm.frameContext != null) { + tasm.frameContext.leave(tasm); + } + // masm.return(); + } + } + + public static class SequentialSwitchOp extends SPARCLIRInstruction implements FallThroughOp { + + @Use({CONST}) protected Constant[] keyConstants; + private final LabelRef[] keyTargets; + private LabelRef defaultTarget; + @Alive({REG}) protected Value key; + @Temp({REG, ILLEGAL}) protected Value scratch; + + public SequentialSwitchOp(Constant[] keyConstants, LabelRef[] keyTargets, LabelRef defaultTarget, Value key, Value scratch) { + assert keyConstants.length == keyTargets.length; + this.keyConstants = keyConstants; + this.keyTargets = keyTargets; + this.defaultTarget = defaultTarget; + this.key = key; + this.scratch = scratch; + } + + @Override + @SuppressWarnings("unused") + public void emitCode(TargetMethodAssembler tasm, SPARCAssembler masm) { + if (key.getKind() == Kind.Int) { + Register intKey = asIntReg(key); + for (int i = 0; i < keyConstants.length; i++) { + if (tasm.runtime.needsDataPatch(keyConstants[i])) { + tasm.recordDataReferenceInCode(keyConstants[i], 0, true); + } + long lc = keyConstants[i].asLong(); + assert NumUtil.isInt(lc); + new Subcc(masm, intKey, (int) lc, SPARC.r0); // CMP + Label l = keyTargets[i].label(); + l.addPatchAt(tasm.asm.codeBuffer.position()); + new Bpe(masm, CC.Icc, l); + } + } else if (key.getKind() == Kind.Long) { + Register longKey = asLongReg(key); + for (int i = 0; i < keyConstants.length; i++) { + // masm.setp_eq_s64(tasm.asLongConst(keyConstants[i]), + // longKey); + // masm.at(); + Label l = keyTargets[i].label(); + l.addPatchAt(tasm.asm.codeBuffer.position()); + new Bpe(masm, CC.Xcc, l); + } + } else if (key.getKind() == Kind.Object) { + Register intKey = asObjectReg(key); + Register temp = asObjectReg(scratch); + for (int i = 0; i < keyConstants.length; i++) { + SPARCMove.move(tasm, masm, temp.asValue(Kind.Object), keyConstants[i]); + new Subcc(masm, intKey, temp, SPARC.r0); // CMP + new Bpe(masm, CC.Icc, keyTargets[i].label()); + } + } else { + throw new GraalInternalError("sequential switch only supported for int, long and object"); + } + if (defaultTarget != null) { + masm.jmp(defaultTarget.label()); + } else { + // masm.hlt(); + } + } + + @Override + public LabelRef fallThroughTarget() { + return defaultTarget; + } + + @Override + public void setFallThroughTarget(LabelRef target) { + defaultTarget = target; + } + } + + public static class SwitchRangesOp extends SPARCLIRInstruction implements FallThroughOp { + + private final LabelRef[] keyTargets; + private LabelRef defaultTarget; + private final int[] lowKeys; + private final int[] highKeys; + @Alive protected Value key; + + public SwitchRangesOp(int[] lowKeys, int[] highKeys, LabelRef[] keyTargets, LabelRef defaultTarget, Value key) { + this.lowKeys = lowKeys; + this.highKeys = highKeys; + this.keyTargets = keyTargets; + this.defaultTarget = defaultTarget; + this.key = key; + } + + @Override + public void emitCode(TargetMethodAssembler tasm, SPARCAssembler masm) { + assert isSorted(lowKeys) && isSorted(highKeys); + + @SuppressWarnings("unused") + Label actualDefaultTarget = defaultTarget == null ? new Label() : defaultTarget.label(); + int prevHighKey = 0; + boolean skipLowCheck = false; + for (int i = 0; i < lowKeys.length; i++) { + int lowKey = lowKeys[i]; + int highKey = highKeys[i]; + if (lowKey == highKey) { + // masm.cmpl(asIntReg(key), lowKey); + // masm.jcc(ConditionFlag.Equal, keyTargets[i].label()); + skipLowCheck = false; + } else { + if (!skipLowCheck || (prevHighKey + 1) != lowKey) { + // masm.cmpl(asIntReg(key), lowKey); + // masm.jcc(ConditionFlag.Less, actualDefaultTarget); + } + // masm.cmpl(asIntReg(key), highKey); + // masm.jcc(ConditionFlag.LessEqual, keyTargets[i].label()); + skipLowCheck = true; + } + prevHighKey = highKey; + } + if (defaultTarget != null) { + // masm.jmp(defaultTarget.label()); + } else { + // masm.bind(actualDefaultTarget); + // masm.hlt(); + } + } + + @Override + protected void verify() { + super.verify(); + assert lowKeys.length == keyTargets.length; + assert highKeys.length == keyTargets.length; + assert key.getKind() == Kind.Int; + } + + @Override + public LabelRef fallThroughTarget() { + return defaultTarget; + } + + @Override + public void setFallThroughTarget(LabelRef target) { + defaultTarget = target; + } + + private static boolean isSorted(int[] values) { + for (int i = 1; i < values.length; i++) { + if (values[i - 1] >= values[i]) { + return false; + } + } + return true; + } + } + + public static class TableSwitchOp extends SPARCLIRInstruction { + + private final int lowKey; + private final LabelRef defaultTarget; + private final LabelRef[] targets; + @Alive protected Value index; + @Temp protected Value scratch; + + public TableSwitchOp(final int lowKey, final LabelRef defaultTarget, final LabelRef[] targets, Variable index, Variable scratch) { + this.lowKey = lowKey; + this.defaultTarget = defaultTarget; + this.targets = targets; + this.index = index; + this.scratch = scratch; + } + + @Override + public void emitCode(TargetMethodAssembler tasm, SPARCAssembler masm) { + tableswitch(tasm, masm, lowKey, defaultTarget, targets, asIntReg(index), asLongReg(scratch)); + } + } + + @SuppressWarnings("unused") + private static void tableswitch(TargetMethodAssembler tasm, SPARCAssembler masm, int lowKey, LabelRef defaultTarget, LabelRef[] targets, Register value, Register scratch) { + Buffer buf = masm.codeBuffer; + // Compare index against jump table bounds + int highKey = lowKey + targets.length - 1; + if (lowKey != 0) { + // subtract the low value from the switch value + // masm.sub_s32(value, value, lowKey); + // masm.setp_gt_s32(value, highKey - lowKey); + } else { + // masm.setp_gt_s32(value, highKey); + } + + // Jump to default target if index is not within the jump table + if (defaultTarget != null) { + // masm.at(); + // masm.bra(defaultTarget.label().toString()); + } + + // address of jump table + int tablePos = buf.position(); + + JumpTable jt = new JumpTable(tablePos, lowKey, highKey, 4); + tasm.compilationResult.addAnnotation(jt); + + // SPARC: unimp: tableswitch extract + } +} diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMathIntrinsicOp.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMathIntrinsicOp.java Fri Jun 07 14:15:38 2013 +0200 @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.lir.sparc; + +import static com.oracle.graal.api.code.ValueUtil.*; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.asm.sparc.SPARCAssembler; +import com.oracle.graal.asm.sparc.SPARCAssembler.Fsqrtd; +import com.oracle.graal.graph.*; +import com.oracle.graal.lir.*; +import com.oracle.graal.lir.asm.*; + +public class SPARCMathIntrinsicOp extends SPARCLIRInstruction { + + public enum IntrinsicOpcode { + SQRT, SIN, COS, TAN, LOG, LOG10 + } + + @Opcode private final IntrinsicOpcode opcode; + @Def protected Value result; + @Use protected Value input; + + public SPARCMathIntrinsicOp(IntrinsicOpcode opcode, Value result, Value input) { + this.opcode = opcode; + this.result = result; + this.input = input; + } + + @Override + @SuppressWarnings("unused") + public void emitCode(TargetMethodAssembler tasm, SPARCAssembler asm) { + switch (opcode) { + case SQRT: + new Fsqrtd(asm, asDoubleReg(result), asDoubleReg(input)); + break; + case LOG: + case LOG10: + case SIN: + case COS: + case TAN: + default: + throw GraalInternalError.shouldNotReachHere(); + } + } +} diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java Fri Jun 07 14:15:38 2013 +0200 @@ -0,0 +1,328 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.lir.sparc; + +import static com.oracle.graal.api.code.ValueUtil.*; +import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.asm.sparc.*; +import com.oracle.graal.asm.sparc.SPARCAssembler.Lddf; +import com.oracle.graal.asm.sparc.SPARCAssembler.Ldf; +import com.oracle.graal.asm.sparc.SPARCAssembler.Ldsb; +import com.oracle.graal.asm.sparc.SPARCAssembler.Ldsh; +import com.oracle.graal.asm.sparc.SPARCAssembler.Ldsw; +import com.oracle.graal.asm.sparc.SPARCAssembler.Lduw; +import com.oracle.graal.asm.sparc.SPARCAssembler.Ldx; +import com.oracle.graal.asm.sparc.SPARCAssembler.Membar; +import com.oracle.graal.asm.sparc.SPARCAssembler.NullCheck; +import com.oracle.graal.asm.sparc.SPARCAssembler.Or; +import com.oracle.graal.asm.sparc.SPARCAssembler.Stb; +import com.oracle.graal.asm.sparc.SPARCAssembler.Sth; +import com.oracle.graal.asm.sparc.SPARCAssembler.Stw; +import com.oracle.graal.asm.sparc.SPARCAssembler.Stx; +import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Setuw; +import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Setx; +import com.oracle.graal.graph.*; +import com.oracle.graal.lir.*; +import com.oracle.graal.lir.StandardOp.MoveOp; +import com.oracle.graal.lir.asm.*; +import com.oracle.graal.sparc.*; + +public class SPARCMove { + + public static class LoadOp extends SPARCLIRInstruction { + + private final Kind kind; + @Def({REG}) protected AllocatableValue result; + @Use({COMPOSITE}) protected SPARCAddressValue address; + @State protected LIRFrameState state; + + public LoadOp(Kind kind, AllocatableValue result, SPARCAddressValue address, LIRFrameState state) { + this.kind = kind; + this.result = result; + this.address = address; + this.state = state; + } + + @Override + @SuppressWarnings("unused") + public void emitCode(TargetMethodAssembler tasm, SPARCAssembler masm) { + SPARCAddress addr = address.toAddress(); + switch (kind) { + case Byte: + new Ldsb(masm, addr, asRegister(result)); + break; + case Short: + new Ldsh(masm, addr, asRegister(result)); + break; + case Char: + new Lduw(masm, addr, asRegister(result)); + break; + case Int: + new Ldsw(masm, addr, asRegister(result)); + break; + case Long: + new Ldx(masm, addr, asRegister(result)); + break; + case Float: + new Ldf(masm, addr, asRegister(result)); + break; + case Double: + new Lddf(masm, addr, asRegister(result)); + break; + case Object: + new Ldx(masm, addr, asRegister(result)); + break; + default: + throw GraalInternalError.shouldNotReachHere(); + } + } + } + + @SuppressWarnings("unused") + public static class MembarOp extends SPARCLIRInstruction { + + private final int barriers; + + public MembarOp(final int barriers) { + this.barriers = barriers; + } + + @Override + public void emitCode(TargetMethodAssembler tasm, SPARCAssembler asm) { + new Membar(asm, barriers); + } + } + + @Opcode("MOVE") + public static class MoveToRegOp extends SPARCLIRInstruction implements MoveOp { + + @Def({REG, HINT}) protected AllocatableValue result; + @Use({REG, STACK, CONST}) protected Value input; + + public MoveToRegOp(AllocatableValue result, Value input) { + this.result = result; + this.input = input; + } + + @Override + public void emitCode(TargetMethodAssembler tasm, SPARCAssembler masm) { + move(tasm, masm, getResult(), getInput()); + } + + @Override + public Value getInput() { + return input; + } + + @Override + public AllocatableValue getResult() { + return result; + } + } + + @Opcode("MOVE") + public static class MoveFromRegOp extends SPARCLIRInstruction implements MoveOp { + + @Def({REG, STACK}) protected AllocatableValue result; + @Use({REG, CONST, HINT}) protected Value input; + + public MoveFromRegOp(AllocatableValue result, Value input) { + this.result = result; + this.input = input; + } + + @Override + public void emitCode(TargetMethodAssembler tasm, SPARCAssembler masm) { + move(tasm, masm, getResult(), getInput()); + } + + @Override + public Value getInput() { + return input; + } + + @Override + public AllocatableValue getResult() { + return result; + } + } + + public static class NullCheckOp extends SPARCLIRInstruction { + + @Use({REG}) protected AllocatableValue input; + @State protected LIRFrameState state; + + public NullCheckOp(Variable input, LIRFrameState state) { + this.input = input; + this.state = state; + } + + @Override + @SuppressWarnings("unused") + public void emitCode(TargetMethodAssembler tasm, SPARCAssembler masm) { + tasm.recordImplicitException(masm.codeBuffer.position(), state); + new NullCheck(masm, new SPARCAddress(asRegister(input), 0)); + } + } + + @SuppressWarnings("unused") + public static class StackLoadAddressOp extends SPARCLIRInstruction { + + @Def({REG}) protected AllocatableValue result; + @Use({STACK, UNINITIALIZED}) protected StackSlot slot; + + public StackLoadAddressOp(AllocatableValue result, StackSlot slot) { + this.result = result; + this.slot = slot; + } + + @Override + public void emitCode(TargetMethodAssembler tasm, SPARCAssembler asm) { + new Ldx(asm, (SPARCAddress) tasm.asAddress(slot), asLongReg(result)); + } + } + + public static class StoreOp extends SPARCLIRInstruction { + + private final Kind kind; + @Use({COMPOSITE}) protected SPARCAddressValue address; + @Use({REG}) protected AllocatableValue input; + @State protected LIRFrameState state; + + public StoreOp(Kind kind, SPARCAddressValue address, AllocatableValue input, LIRFrameState state) { + this.kind = kind; + this.address = address; + this.input = input; + this.state = state; + } + + @Override + @SuppressWarnings("unused") + public void emitCode(TargetMethodAssembler tasm, SPARCAssembler masm) { + assert isRegister(input); + SPARCAddress addr = address.toAddress(); + switch (kind) { + case Byte: + new Stb(masm, asRegister(input), addr); + break; + case Short: + new Sth(masm, asRegister(input), addr); + break; + case Int: + new Stw(masm, asRegister(input), addr); + break; + case Long: + new Stx(masm, asRegister(input), addr); + break; + case Float: + new Stx(masm, asRegister(input), addr); + break; + case Double: + new Stx(masm, asRegister(input), addr); + break; + case Object: + new Stx(masm, asRegister(input), addr); + break; + default: + throw GraalInternalError.shouldNotReachHere("missing: " + address.getKind()); + } + } + } + + public static void move(TargetMethodAssembler tasm, SPARCAssembler masm, Value result, Value input) { + if (isRegister(input)) { + if (isRegister(result)) { + reg2reg(masm, result, input); + } else { + throw GraalInternalError.shouldNotReachHere(); + } + } else if (isConstant(input)) { + if (isRegister(result)) { + const2reg(tasm, masm, result, (Constant) input); + } else { + throw GraalInternalError.shouldNotReachHere(); + } + } else { + throw GraalInternalError.shouldNotReachHere(); + } + } + + @SuppressWarnings("unused") + private static void reg2reg(SPARCAssembler masm, Value result, Value input) { + if (asRegister(input).equals(asRegister(result))) { + return; + } + switch (input.getKind()) { + case Int: + new Or(masm, SPARC.r0, asRegister(input), asRegister(result)); + break; + case Long: + new Or(masm, SPARC.r0, asRegister(input), asRegister(result)); + break; + case Float: + new Or(masm, SPARC.r0, asRegister(input), asRegister(result)); + break; + case Double: + new Or(masm, SPARC.r0, asRegister(input), asRegister(result)); + break; + case Object: + new Or(masm, SPARC.r0, asRegister(input), asRegister(result)); + break; + default: + throw GraalInternalError.shouldNotReachHere("missing: " + input.getKind()); + } + } + + @SuppressWarnings("unused") + private static void const2reg(TargetMethodAssembler tasm, SPARCAssembler masm, Value result, Constant input) { + switch (input.getKind().getStackKind()) { + case Int: + if (tasm.runtime.needsDataPatch(input)) { + tasm.recordDataReferenceInCode(input, 0, true); + } + new Setuw(masm, input.asInt(), asRegister(result)); + break; + case Long: + if (tasm.runtime.needsDataPatch(input)) { + tasm.recordDataReferenceInCode(input, 0, true); + } + new Setx(masm, input.asInt(), null, asRegister(result)); + break; + case Object: + if (input.isNull()) { + new Setx(masm, 0x0L, null, asRegister(result)); + } else if (tasm.target.inlineObjects) { + tasm.recordDataReferenceInCode(input, 0, true); + new Setx(masm, 0xDEADDEADDEADDEADL, null, asRegister(result)); + } else { + throw new InternalError("NYI"); + } + break; + default: + throw GraalInternalError.shouldNotReachHere("missing: " + input.getKind()); + } + } +} diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCTestOp.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCTestOp.java Fri Jun 07 14:15:38 2013 +0200 @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.lir.sparc; + +import static com.oracle.graal.api.code.ValueUtil.*; +import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.asm.sparc.*; +import com.oracle.graal.asm.sparc.SPARCAssembler.Ldsw; +import com.oracle.graal.asm.sparc.SPARCAssembler.Ldx; +import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Cmp; +import com.oracle.graal.graph.*; +import com.oracle.graal.lir.asm.*; + +public class SPARCTestOp extends SPARCLIRInstruction { + + @Use({REG}) protected Value x; + @Use({REG, STACK, CONST}) protected Value y; + + public SPARCTestOp(Value x, Value y) { + this.x = x; + this.y = y; + } + + @Override + @SuppressWarnings("unused") + public void emitCode(TargetMethodAssembler tasm, SPARCAssembler asm) { + if (isRegister(y)) { + switch (x.getKind()) { + case Int: + new Cmp(asm, asIntReg(x), asIntReg(y)); + break; + case Long: + new Cmp(asm, asLongReg(x), asLongReg(y)); + break; + default: + throw GraalInternalError.shouldNotReachHere(); + } + } else if (isConstant(y)) { + switch (x.getKind()) { + case Int: + new Cmp(asm, asIntReg(x), tasm.asIntConst(y)); + break; + case Long: + new Cmp(asm, asLongReg(x), tasm.asIntConst(y)); + break; + default: + throw GraalInternalError.shouldNotReachHere(); + } + } else { + switch (x.getKind()) { + case Int: + new Ldsw(asm, (SPARCAddress) tasm.asIntAddr(y), asIntReg(y)); + new Cmp(asm, asIntReg(x), asIntReg(y)); + break; + case Long: + new Ldx(asm, (SPARCAddress) tasm.asLongAddr(y), asLongReg(y)); + new Cmp(asm, asLongReg(x), asLongReg(y)); + break; + default: + throw GraalInternalError.shouldNotReachHere(); + } + } + } + +} diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.lir/src/com/oracle/graal/lir/InfopointOp.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/InfopointOp.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/InfopointOp.java Fri Jun 07 14:15:38 2013 +0200 @@ -22,8 +22,6 @@ */ package com.oracle.graal.lir; -import static com.oracle.graal.lir.LIRInstruction.Opcode; - import com.oracle.graal.api.code.*; import com.oracle.graal.lir.asm.*; diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInstruction.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInstruction.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInstruction.java Fri Jun 07 14:15:38 2013 +0200 @@ -144,13 +144,6 @@ public static @interface State { } - @Retention(RetentionPolicy.RUNTIME) - @Target({ElementType.TYPE, ElementType.FIELD}) - public static @interface Opcode { - - String value() default ""; - } - /** * Flags for an operand. */ diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInstructionClass.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInstructionClass.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInstructionClass.java Fri Jun 07 14:15:38 2013 +0200 @@ -174,8 +174,8 @@ @Override protected void scan(Class clazz) { - if (clazz.getAnnotation(LIRInstruction.Opcode.class) != null) { - opcodeConstant = clazz.getAnnotation(LIRInstruction.Opcode.class).value(); + if (clazz.getAnnotation(Opcode.class) != null) { + opcodeConstant = clazz.getAnnotation(Opcode.class).value(); } opcodeOffset = -1; @@ -199,7 +199,7 @@ super.scanField(field, type, offset); } - if (field.getAnnotation(LIRInstruction.Opcode.class) != null) { + if (field.getAnnotation(Opcode.class) != null) { assert opcodeConstant == null && opcodeOffset == -1 : "Can have only one Opcode definition: " + field.getType(); opcodeOffset = offset; } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRVerifier.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRVerifier.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRVerifier.java Fri Jun 07 14:15:38 2013 +0200 @@ -31,7 +31,9 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.debug.*; import com.oracle.graal.graph.*; -import com.oracle.graal.lir.LIRInstruction.*; +import com.oracle.graal.lir.LIRInstruction.OperandFlag; +import com.oracle.graal.lir.LIRInstruction.OperandMode; +import com.oracle.graal.lir.LIRInstruction.ValueProcedure; import com.oracle.graal.nodes.cfg.*; public final class LIRVerifier { @@ -230,14 +232,17 @@ return value; } + // @formatter:off private static Value allowed(Object op, Value value, OperandMode mode, EnumSet flags) { - if ((isVariable(value) && flags.contains(OperandFlag.REG)) || (isRegister(value) && flags.contains(OperandFlag.REG)) || (isStackSlot(value) && flags.contains(OperandFlag.STACK)) || - (isConstant(value) && flags.contains(OperandFlag.CONST) && mode != OperandMode.DEF) || (isIllegal(value) && flags.contains(OperandFlag.ILLEGAL))) { + if ((isVariable(value) && flags.contains(OperandFlag.REG)) || + (isRegister(value) && flags.contains(OperandFlag.REG)) || + (isStackSlot(value) && flags.contains(OperandFlag.STACK)) || + (isConstant(value) && flags.contains(OperandFlag.CONST) && mode != OperandMode.DEF) || + (isIllegal(value) && flags.contains(OperandFlag.ILLEGAL))) { return value; } - TTY.println("instruction %s", op); - TTY.println("mode: %s flags: %s", mode, flags); - TTY.println("Unexpected value: %s %s", value.getClass().getSimpleName(), value); - throw GraalInternalError.shouldNotReachHere(); + throw new GraalInternalError("Invalid LIR%n Instruction: %s%n Mode: %s%n Flags: %s%n Unexpected value: %s %s", + op, mode, flags, value.getClass().getSimpleName(), value); } + // @formatter:on } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.lir/src/com/oracle/graal/lir/Opcode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/Opcode.java Fri Jun 07 14:15:38 2013 +0200 @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.lir; + +import java.lang.annotation.*; + +/** + * Denotes an opcode name for an annotated {@link LIRInstruction}. + *

    + * Note: Unlike the other LIR related annotations declared as inner classes of + * {@link LIRInstruction}, this annotation is in a top level file to work around a bug in Eclipse causing spurious + * warnings about unused imports. + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE, ElementType.FIELD}) +public @interface Opcode { + + String value() default ""; +} diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopPolicies.java --- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopPolicies.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopPolicies.java Fri Jun 07 14:15:38 2013 +0200 @@ -22,12 +22,13 @@ */ package com.oracle.graal.loop; +import static com.oracle.graal.phases.GraalOptions.*; + import com.oracle.graal.debug.*; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.cfg.*; import com.oracle.graal.nodes.util.*; -import com.oracle.graal.phases.*; public abstract class LoopPolicies { @@ -39,7 +40,7 @@ public static boolean shouldPeel(LoopEx loop, NodesToDoubles probabilities) { LoopBeginNode loopBegin = loop.loopBegin(); double entryProbability = probabilities.get(loopBegin.forwardEnd()); - return entryProbability > GraalOptions.MinimumPeelProbability && loop.size() + loopBegin.graph().getNodeCount() < GraalOptions.MaximumDesiredSize; + return entryProbability > MinimumPeelProbability.getValue() && loop.size() + loopBegin.graph().getNodeCount() < MaximumDesiredSize.getValue(); } public static boolean shouldFullUnroll(LoopEx loop) { @@ -48,14 +49,14 @@ } CountedLoopInfo counted = loop.counted(); long exactTrips = counted.constantMaxTripCount(); - int maxNodes = (counted.isExactTripCount() && counted.isConstantExactTripCount()) ? GraalOptions.ExactFullUnrollMaxNodes : GraalOptions.FullUnrollMaxNodes; - maxNodes = Math.min(maxNodes, GraalOptions.MaximumDesiredSize - loop.loopBegin().graph().getNodeCount()); + int maxNodes = (counted.isExactTripCount() && counted.isConstantExactTripCount()) ? ExactFullUnrollMaxNodes.getValue() : FullUnrollMaxNodes.getValue(); + maxNodes = Math.min(maxNodes, MaximumDesiredSize.getValue() - loop.loopBegin().graph().getNodeCount()); int size = Math.max(1, loop.size() - 1 - loop.loopBegin().phis().count()); return size * exactTrips <= maxNodes; } public static boolean shouldTryUnswitch(LoopEx loop) { - return loop.loopBegin().unswitches() <= GraalOptions.LoopMaxUnswitch; + return loop.loopBegin().unswitches() <= LoopMaxUnswitch.getValue(); } public static boolean shouldUnswitch(LoopEx loop, ControlSplitNode controlSplit) { @@ -77,7 +78,7 @@ } int netDiff = loopTotal - (inBranchTotal); double uncertainty = 1 - maxProbability; - int maxDiff = GraalOptions.LoopUnswitchMaxIncrease + (int) (GraalOptions.LoopUnswitchUncertaintyBoost * loop.loopBegin().loopFrequency() * uncertainty); + int maxDiff = LoopUnswitchMaxIncrease.getValue() + (int) (LoopUnswitchUncertaintyBoost.getValue() * loop.loopBegin().loopFrequency() * uncertainty); Debug.log("shouldUnswitch(%s, %s) : delta=%d, max=%d, %.2f%% inside of branches", loop, controlSplit, netDiff, maxDiff, (double) (inBranchTotal) / loopTotal * 100); return netDiff <= maxDiff; } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopTransformations.java --- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopTransformations.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopTransformations.java Fri Jun 07 14:15:38 2013 +0200 @@ -22,6 +22,8 @@ */ package com.oracle.graal.loop; +import static com.oracle.graal.phases.GraalOptions.*; + import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; @@ -29,12 +31,11 @@ import com.oracle.graal.graph.NodeClass.Position; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.extended.*; -import com.oracle.graal.phases.*; import com.oracle.graal.phases.common.*; public abstract class LoopTransformations { - private static final int UNROLL_LIMIT = GraalOptions.FullUnrollMaxNodes * 2; + private static final int UNROLL_LIMIT = FullUnrollMaxNodes.getValue() * 2; private LoopTransformations() { // does not need to be instantiated @@ -52,7 +53,7 @@ loop.inside().duplicate().insertBefore(loop); } - public static void fullUnroll(LoopEx loop, MetaAccessProvider runtime, Assumptions assumptions) { + public static void fullUnroll(LoopEx loop, MetaAccessProvider runtime, Assumptions assumptions, boolean canonicalizeReads) { // assert loop.isCounted(); //TODO (gd) strenghten : counted with known trip count int iterations = 0; LoopBeginNode loopBegin = loop.loopBegin(); @@ -60,8 +61,8 @@ while (!loopBegin.isDeleted()) { int mark = graph.getMark(); peel(loop); - new CanonicalizerPhase.Instance(runtime, assumptions, mark, null).apply(graph); - if (iterations++ > UNROLL_LIMIT || graph.getNodeCount() > GraalOptions.MaximumDesiredSize * 3) { + new CanonicalizerPhase.Instance(runtime, assumptions, canonicalizeReads, mark, null).apply(graph); + if (iterations++ > UNROLL_LIMIT || graph.getNodeCount() > MaximumDesiredSize.getValue() * 3) { throw new BailoutException("FullUnroll : Graph seems to grow out of proportion"); } } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.loop/src/com/oracle/graal/loop/phases/LoopFullUnrollPhase.java --- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/phases/LoopFullUnrollPhase.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/phases/LoopFullUnrollPhase.java Fri Jun 07 14:15:38 2013 +0200 @@ -31,8 +31,10 @@ public class LoopFullUnrollPhase extends BasePhase { private static final DebugMetric FULLY_UNROLLED_LOOPS = Debug.metric("FullUnrolls"); + private final boolean canonicalizeReads; - public LoopFullUnrollPhase() { + public LoopFullUnrollPhase(boolean canonicalizeReads) { + this.canonicalizeReads = canonicalizeReads; } @Override @@ -46,7 +48,7 @@ for (LoopEx loop : dataCounted.countedLoops()) { if (LoopPolicies.shouldFullUnroll(loop)) { Debug.log("FullUnroll %s", loop); - LoopTransformations.fullUnroll(loop, context.getRuntime(), context.getAssumptions()); + LoopTransformations.fullUnroll(loop, context.getRuntime(), context.getAssumptions(), canonicalizeReads); FULLY_UNROLLED_LOOPS.increment(); Debug.dump(graph, "After fullUnroll %s", loop); peeled = true; diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.loop/src/com/oracle/graal/loop/phases/LoopSafepointEliminationPhase.java --- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/phases/LoopSafepointEliminationPhase.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/phases/LoopSafepointEliminationPhase.java Fri Jun 07 14:15:38 2013 +0200 @@ -39,9 +39,15 @@ loops.detectedCountedLoops(); for (LoopEx loop : loops.countedLoops()) { if (loop.lirLoop().children.isEmpty() && loop.counted().getKind() == Kind.Int) { - loop.counted().createOverFlowGuard(); + boolean hasSafepoint = false; for (LoopEndNode loopEnd : loop.loopBegin().loopEnds()) { - loopEnd.disableSafepoint(); + hasSafepoint |= loopEnd.canSafepoint(); + } + if (hasSafepoint) { + loop.counted().createOverFlowGuard(); + for (LoopEndNode loopEnd : loop.loopBegin().loopEnds()) { + loopEnd.disableSafepoint(); + } } } } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.loop/src/com/oracle/graal/loop/phases/LoopTransformHighPhase.java --- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/phases/LoopTransformHighPhase.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/phases/LoopTransformHighPhase.java Fri Jun 07 14:15:38 2013 +0200 @@ -22,6 +22,8 @@ */ package com.oracle.graal.loop.phases; +import static com.oracle.graal.phases.GraalOptions.*; + import com.oracle.graal.debug.*; import com.oracle.graal.loop.*; import com.oracle.graal.nodes.*; @@ -34,7 +36,7 @@ @Override protected void run(StructuredGraph graph) { if (graph.hasLoops()) { - if (GraalOptions.LoopPeeling) { + if (LoopPeeling.getValue()) { NodesToDoubles probabilities = new ComputeProbabilityClosure(graph).apply(); LoopsData data = new LoopsData(graph); for (LoopEx loop : data.outterFirst()) { diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.loop/src/com/oracle/graal/loop/phases/LoopTransformLowPhase.java --- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/phases/LoopTransformLowPhase.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/phases/LoopTransformLowPhase.java Fri Jun 07 14:15:38 2013 +0200 @@ -22,6 +22,8 @@ */ package com.oracle.graal.loop.phases; +import static com.oracle.graal.phases.GraalOptions.*; + import com.oracle.graal.debug.*; import com.oracle.graal.graph.NodeClass.NodeClassIterator; import com.oracle.graal.loop.*; @@ -35,7 +37,7 @@ @Override protected void run(StructuredGraph graph) { if (graph.hasLoops()) { - if (GraalOptions.ReassociateInvariants) { + if (ReassociateInvariants.getValue()) { final LoopsData dataReassociate = new LoopsData(graph); Debug.scope("ReassociateInvariants", new Runnable() { @@ -47,7 +49,7 @@ } }); } - if (GraalOptions.LoopUnswitch) { + if (LoopUnswitch.getValue()) { boolean unswitched; do { unswitched = false; diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptimizeNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptimizeNode.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptimizeNode.java Fri Jun 07 14:15:38 2013 +0200 @@ -83,9 +83,4 @@ public DeoptimizationReason getDeoptimizationReason() { return reason; } - - @Override - public boolean isCallSiteDeoptimization() { - return false; - } } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptimizingFixedWithNextNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptimizingFixedWithNextNode.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptimizingFixedWithNextNode.java Fri Jun 07 14:15:38 2013 +0200 @@ -42,9 +42,4 @@ updateUsages(deoptState, f); deoptState = f; } - - @Override - public boolean isCallSiteDeoptimization() { - return false; - } } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptimizingNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptimizingNode.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptimizingNode.java Fri Jun 07 14:15:38 2013 +0200 @@ -25,29 +25,24 @@ import com.oracle.graal.api.meta.*; /** - * Interface that needs to be implemented by nodes which need deoptimization information. - * + * Interface implemented by nodes which need deoptimization information. */ public interface DeoptimizingNode { /** - * Returns true if this particular instance needs deoptimization information. - * - * @return true if this particular instance needs deoptimization information + * Determines if this node needs deoptimization information. */ boolean canDeoptimize(); /** - * Returns the deoptimization information associated with this node if any. - * - * @return the deoptimization information associated with this node if any. + * Gets the deoptimization information associated with this node if any. */ FrameState getDeoptimizationState(); /** - * Set the deoptimization information associated with this node. + * Sets the deoptimization information associated with this node. * - * @param state the FrameState which represents the deoptimization information. + * @param state the FrameState which represents the deoptimization information */ void setDeoptimizationState(FrameState state); @@ -59,13 +54,4 @@ * @return the reason for deoptimization triggered by this node. */ DeoptimizationReason getDeoptimizationReason(); - - /** - * Returns true if this node needs deoptimization information for stack-walking purposes because - * it is a call-site. While most other nodes use deoptimization information representing a state - * that happened before them, these nodes use a state that is valid during the call itself. - * - * @return true if this node needs deoptimization information for stack-walking purposes. - */ - boolean isCallSiteDeoptimization(); } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedGuardNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedGuardNode.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedGuardNode.java Fri Jun 07 14:15:38 2013 +0200 @@ -25,12 +25,13 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; +import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; import com.oracle.graal.nodes.util.*; @NodeInfo(nameTemplate = "FixedGuard(!={p#negated}) {p#reason/s}") -public final class FixedGuardNode extends FixedWithNextNode implements Simplifiable, Lowerable, Node.IterableNodeType, Negatable { +public final class FixedGuardNode extends FixedWithNextNode implements Simplifiable, Lowerable, Node.IterableNodeType, Negatable, GuardingNode { @Input private LogicNode condition; private final DeoptimizationReason reason; @@ -51,7 +52,7 @@ } public FixedGuardNode(LogicNode condition, DeoptimizationReason deoptReason, DeoptimizationAction action, boolean negated) { - super(StampFactory.forVoid()); + super(StampFactory.dependency()); this.action = action; this.negated = negated; this.condition = condition; @@ -84,6 +85,7 @@ if (condition instanceof LogicConstantNode) { LogicConstantNode c = (LogicConstantNode) condition; if (c.getValue() != negated) { + this.replaceAtUsages(BeginNode.prevBegin(this)); graph().removeFixed(this); } else { FixedNode next = this.next(); @@ -121,4 +123,9 @@ negated = !negated; return this; } + + @Override + public FixedGuardNode asNode() { + return this; + } } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FrameState.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FrameState.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FrameState.java Fri Jun 07 14:15:38 2013 +0200 @@ -41,6 +41,9 @@ protected final int stackSize; + /** + * @see BytecodeFrame#rethrowException + */ private boolean rethrowException; private boolean duringCall; @@ -160,6 +163,9 @@ this.outerFrameState = x; } + /** + * @see BytecodeFrame#rethrowException + */ public boolean rethrowException() { return rethrowException; } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/HeapAccess.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/HeapAccess.java Fri Jun 07 14:15:38 2013 +0200 @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.nodes; + +/** + * A HeapAccess is a node that access the heap and therefore may be subjected to certain rules of + * the underlying runtime. + */ +public interface HeapAccess { + + /* + * The types of write barriers attached to stores. + */ + public enum WriteBarrierType { + /* + * Primitive stores which do not necessitate write barriers. + */ + NONE, + /* + * Array object stores which necessitate precise write barriers. + */ + PRECISE, + /* + * Field object stores which necessitate imprecise write barriers. + */ + IMPRECISE + } + + /** + * Gets the write barrier type for that particular access. + */ + WriteBarrierType getWriteBarrierType(); + + /** + * Returns whether or not the heap access is a compressed pointer candidate. + */ + boolean compress(); +} diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeNode.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeNode.java Fri Jun 07 14:15:38 2013 +0200 @@ -22,13 +22,15 @@ */ package com.oracle.graal.nodes; +import static com.oracle.graal.api.meta.LocationIdentity.*; + import java.util.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.extended.*; -import com.oracle.graal.nodes.extended.LocationNode.LocationIdentity; import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.nodes.type.Stamp; import com.oracle.graal.nodes.util.*; /** @@ -47,11 +49,22 @@ /** * Constructs a new Invoke instruction. * + * @param callTarget the target method being called * @param bci the bytecode index of the original invoke (used for debug infos) - * @param callTarget the target method being called */ public InvokeNode(CallTargetNode callTarget, int bci) { - super(callTarget.returnStamp()); + this(callTarget, bci, callTarget.returnStamp()); + } + + /** + * Constructs a new Invoke instruction. + * + * @param callTarget the target method being called + * @param bci the bytecode index of the original invoke (used for debug infos) + * @param stamp the stamp to be used for this value + */ + public InvokeNode(CallTargetNode callTarget, int bci, Stamp stamp) { + super(stamp); this.callTarget = callTarget; this.bci = bci; this.polymorphic = false; @@ -93,7 +106,7 @@ @Override public LocationIdentity[] getLocationIdentities() { - return new LocationIdentity[]{LocationNode.ANY_LOCATION}; + return new LocationIdentity[]{ANY_LOCATION}; } @Override @@ -188,11 +201,6 @@ } @Override - public boolean isCallSiteDeoptimization() { - return true; - } - - @Override public GuardingNode getGuard() { return guard; } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeWithExceptionNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeWithExceptionNode.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeWithExceptionNode.java Fri Jun 07 14:15:38 2013 +0200 @@ -22,12 +22,13 @@ */ package com.oracle.graal.nodes; +import static com.oracle.graal.api.meta.LocationIdentity.*; + import java.util.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.extended.*; -import com.oracle.graal.nodes.extended.LocationNode.LocationIdentity; import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.util.*; @@ -154,7 +155,7 @@ @Override public LocationIdentity[] getLocationIdentities() { - return new LocationIdentity[]{LocationNode.ANY_LOCATION}; + return new LocationIdentity[]{ANY_LOCATION}; } public FrameState stateDuring() { @@ -237,11 +238,6 @@ } @Override - public boolean isCallSiteDeoptimization() { - return true; - } - - @Override public GuardingNode getGuard() { return guard; } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PhiNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PhiNode.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PhiNode.java Fri Jun 07 14:15:38 2013 +0200 @@ -199,6 +199,7 @@ public void addInput(ValueNode x) { assert !(x instanceof PhiNode) || ((PhiNode) x).merge() instanceof LoopBeginNode || ((PhiNode) x).merge() != this.merge(); + assert x.kind() == kind() || type != PhiType.Value; values.add(x); } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PiNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PiNode.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PiNode.java Fri Jun 07 14:15:38 2013 +0200 @@ -61,12 +61,6 @@ @Override public boolean inferStamp() { - if (stamp() instanceof ObjectStamp && object().objectStamp().alwaysNull() && objectStamp().nonNull()) { - // a null value flowing into a nonNull PiNode should be guarded by a type/isNull guard, - // but the - // compiler might see this situation before the branch is deleted - return false; - } return updateStamp(stamp().join(object().stamp())); } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StartNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StartNode.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StartNode.java Fri Jun 07 14:15:38 2013 +0200 @@ -22,8 +22,10 @@ */ package com.oracle.graal.nodes; +import static com.oracle.graal.api.meta.LocationIdentity.*; + +import com.oracle.graal.api.meta.*; import com.oracle.graal.nodes.extended.*; -import com.oracle.graal.nodes.extended.LocationNode.LocationIdentity; /** * The start node of a graph. @@ -32,6 +34,6 @@ @Override public LocationIdentity[] getLocationIdentities() { - return new LocationIdentity[]{LocationNode.ANY_LOCATION}; + return new LocationIdentity[]{ANY_LOCATION}; } } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValueNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValueNode.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValueNode.java Fri Jun 07 14:15:38 2013 +0200 @@ -60,7 +60,7 @@ * @return true if the stamp has changed, false otherwise. */ protected final boolean updateStamp(Stamp newStamp) { - if (newStamp.equals(stamp)) { + if (newStamp == null || newStamp.equals(stamp)) { return false; } else { stamp = newStamp; diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValueNodeUtil.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValueNodeUtil.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValueNodeUtil.java Fri Jun 07 14:15:38 2013 +0200 @@ -72,10 +72,6 @@ assert x == null; } - public static boolean typeMismatch(ValueNode x, ValueNode y) { - return y == null || x == null || x.kind() != y.kind(); - } - @SuppressWarnings("unchecked") public static Collection filter(Iterable nodes, Class clazz) { ArrayList phis = new ArrayList<>(); diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/Access.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/Access.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/Access.java Fri Jun 07 14:15:38 2013 +0200 @@ -24,7 +24,7 @@ import com.oracle.graal.nodes.*; -public interface Access extends DeoptimizingNode, GuardedNode { +public interface Access extends DeoptimizingNode, GuardedNode, HeapAccess { ValueNode object(); diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/AccessNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/AccessNode.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/AccessNode.java Fri Jun 07 14:15:38 2013 +0200 @@ -37,6 +37,8 @@ @Input private ValueNode object; @Input private ValueNode location; private boolean nullCheck; + private WriteBarrierType barrierType; + private boolean compress; public ValueNode object() { return object; @@ -59,14 +61,20 @@ } public AccessNode(ValueNode object, ValueNode location, Stamp stamp) { - this(object, location, stamp, null); + this(object, location, stamp, null, WriteBarrierType.NONE, false); } - public AccessNode(ValueNode object, ValueNode location, Stamp stamp, GuardingNode guard) { + public AccessNode(ValueNode object, ValueNode location, Stamp stamp, WriteBarrierType barrierType, boolean compress) { + this(object, location, stamp, null, barrierType, compress); + } + + public AccessNode(ValueNode object, ValueNode location, Stamp stamp, GuardingNode guard, WriteBarrierType barrierType, boolean compress) { super(stamp); this.object = object; this.location = location; this.guard = guard; + this.barrierType = barrierType; + this.compress = compress; } @Override @@ -94,4 +102,14 @@ updateUsages(this.guard == null ? null : this.guard.asNode(), guard == null ? null : guard.asNode()); this.guard = guard; } + + @Override + public WriteBarrierType getWriteBarrierType() { + return barrierType; + } + + @Override + public boolean compress() { + return compress; + } } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatableAccessNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatableAccessNode.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatableAccessNode.java Fri Jun 07 14:15:38 2013 +0200 @@ -34,8 +34,12 @@ super(object, location, stamp); } - public FloatableAccessNode(ValueNode object, ValueNode location, Stamp stamp, GuardingNode guard) { - super(object, location, stamp, guard); + public FloatableAccessNode(ValueNode object, ValueNode location, Stamp stamp, GuardingNode guard, WriteBarrierType barrierType, boolean compress) { + super(object, location, stamp, guard, barrierType, compress); + } + + public FloatableAccessNode(ValueNode object, ValueNode location, Stamp stamp, WriteBarrierType barrierType, boolean compress) { + super(object, location, stamp, barrierType, compress); } public abstract FloatingAccessNode asFloatingNode(ValueNode lastLocationAccess); diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingAccessNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingAccessNode.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingAccessNode.java Fri Jun 07 14:15:38 2013 +0200 @@ -32,6 +32,8 @@ @Input private LocationNode location; @Input private FrameState deoptState; private boolean nullCheck; + private WriteBarrierType barrierType; + private boolean compress; public ValueNode object() { return object; @@ -59,10 +61,12 @@ this.location = location; } - public FloatingAccessNode(ValueNode object, LocationNode location, Stamp stamp, GuardingNode guard) { + public FloatingAccessNode(ValueNode object, LocationNode location, Stamp stamp, GuardingNode guard, WriteBarrierType barrierType, boolean compress) { super(stamp, guard); this.object = object; this.location = location; + this.barrierType = barrierType; + this.compress = compress; } @Override @@ -92,8 +96,13 @@ } @Override - public boolean isCallSiteDeoptimization() { - return false; + public WriteBarrierType getWriteBarrierType() { + return barrierType; + } + + @Override + public boolean compress() { + return compress; } public abstract Access asFixedNode(); diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingReadNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingReadNode.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingReadNode.java Fri Jun 07 14:15:38 2013 +0200 @@ -37,11 +37,11 @@ @Input private Node lastLocationAccess; public FloatingReadNode(ValueNode object, LocationNode location, Node lastLocationAccess, Stamp stamp) { - this(object, location, lastLocationAccess, stamp, null); + this(object, location, lastLocationAccess, stamp, null, WriteBarrierType.NONE, false); } - public FloatingReadNode(ValueNode object, LocationNode location, Node lastLocationAccess, Stamp stamp, GuardingNode guard) { - super(object, location, stamp, guard); + public FloatingReadNode(ValueNode object, LocationNode location, Node lastLocationAccess, Stamp stamp, GuardingNode guard, WriteBarrierType barrierType, boolean compress) { + super(object, location, stamp, guard, barrierType, compress); this.lastLocationAccess = lastLocationAccess; } @@ -62,6 +62,6 @@ @Override public Access asFixedNode() { - return graph().add(new ReadNode(object(), nullCheckLocation(), stamp(), getGuard())); + return graph().add(new ReadNode(object(), nullCheckLocation(), stamp(), getGuard(), getWriteBarrierType(), compress())); } } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ForeignCallNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ForeignCallNode.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ForeignCallNode.java Fri Jun 07 14:15:38 2013 +0200 @@ -26,7 +26,6 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.extended.LocationNode.LocationIdentity; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -34,22 +33,31 @@ * Node for a {@linkplain ForeignCallDescriptor foreign} call. */ @NodeInfo(nameTemplate = "ForeignCall#{p#descriptor/s}") -public class ForeignCallNode extends DeoptimizingFixedWithNextNode implements LIRLowerable, DeoptimizingNode, MemoryCheckpoint { +public class ForeignCallNode extends AbstractStateSplit implements LIRLowerable, DeoptimizingNode, MemoryCheckpoint { @Input private final NodeInputList arguments; + private final MetaAccessProvider runtime; + @Input private FrameState deoptState; private final ForeignCallDescriptor descriptor; - public ForeignCallNode(ForeignCallDescriptor descriptor, ValueNode... arguments) { + public ForeignCallNode(MetaAccessProvider runtime, ForeignCallDescriptor descriptor, ValueNode... arguments) { super(StampFactory.forKind(Kind.fromJavaClass(descriptor.getResultType()))); this.arguments = new NodeInputList<>(this, arguments); this.descriptor = descriptor; + this.runtime = runtime; } - protected ForeignCallNode(ForeignCallDescriptor descriptor, Stamp stamp) { + protected ForeignCallNode(MetaAccessProvider runtime, ForeignCallDescriptor descriptor, Stamp stamp) { super(stamp); this.arguments = new NodeInputList<>(this); this.descriptor = descriptor; + this.runtime = runtime; + } + + @Override + public boolean hasSideEffect() { + return !runtime.isReexecutable(descriptor); } public ForeignCallDescriptor getDescriptor() { @@ -58,7 +66,7 @@ @Override public LocationIdentity[] getLocationIdentities() { - return new LocationIdentity[]{LocationNode.ANY_LOCATION}; + return runtime.getKilledLocations(descriptor); } protected Value[] operands(LIRGeneratorTool gen) { @@ -80,6 +88,30 @@ } @Override + public FrameState getDeoptimizationState() { + if (deoptState != null) { + return deoptState; + } else if (stateAfter() != null && canDeoptimize()) { + FrameState stateDuring = stateAfter(); + if ((stateDuring.stackSize() > 0 && stateDuring.stackAt(stateDuring.stackSize() - 1) == this) || (stateDuring.stackSize() > 1 && stateDuring.stackAt(stateDuring.stackSize() - 2) == this)) { + stateDuring = stateDuring.duplicateModified(stateDuring.bci, stateDuring.rethrowException(), this.kind()); + } + setDeoptimizationState(stateDuring); + return stateDuring; + } + return null; + } + + @Override + public void setDeoptimizationState(FrameState f) { + updateUsages(deoptState, f); + if (deoptState != null) { + throw new IllegalStateException(toString(Verbosity.Debugger)); + } + deoptState = f; + } + + @Override public String toString(Verbosity verbosity) { if (verbosity == Verbosity.Name) { return super.toString(verbosity) + "#" + descriptor; @@ -89,7 +121,7 @@ @Override public boolean canDeoptimize() { - return true; + return runtime.canDeoptimize(descriptor); } @Override diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ForeignCallStateSplitNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ForeignCallStateSplitNode.java Fri Jun 07 13:43:13 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,80 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.nodes.extended; - -import com.oracle.graal.api.meta.*; -import com.oracle.graal.graph.*; -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.spi.*; - -/** - * A foreign call that is also a state split. - */ -@NodeInfo(nameTemplate = "ForeignCallStateSplit#{p#descriptor/s}") -public class ForeignCallStateSplitNode extends ForeignCallNode implements LIRLowerable, StateSplit, DeoptimizingNode { - - @Input(notDataflow = true) private FrameState stateAfter; - private MetaAccessProvider runtime; - - public ForeignCallStateSplitNode(MetaAccessProvider runtime, ForeignCallDescriptor descriptor, ValueNode... arguments) { - super(descriptor, arguments); - this.runtime = runtime; - } - - public FrameState stateAfter() { - return stateAfter; - } - - public void setStateAfter(FrameState x) { - assert x == null || x.isAlive() : "frame state must be in a graph"; - updateUsages(stateAfter, x); - stateAfter = x; - } - - public boolean hasSideEffect() { - return runtime.hasSideEffect(getDescriptor()); - } - - @Override - public FrameState getDeoptimizationState() { - if (super.getDeoptimizationState() != null) { - return super.getDeoptimizationState(); - } else if (stateAfter() != null) { - FrameState stateDuring = stateAfter(); - if ((stateDuring.stackSize() > 0 && stateDuring.stackAt(stateDuring.stackSize() - 1) == this) || (stateDuring.stackSize() > 1 && stateDuring.stackAt(stateDuring.stackSize() - 2) == this)) { - stateDuring = stateDuring.duplicateModified(stateDuring.bci, stateDuring.rethrowException(), this.kind()); - } - setDeoptimizationState(stateDuring); - return stateDuring; - } - return null; - } - - @Override - public void setDeoptimizationState(FrameState f) { - if (super.getDeoptimizationState() != null) { - throw new IllegalStateException(); - } - super.setDeoptimizationState(f); - } -} diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LocationNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LocationNode.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LocationNode.java Fri Jun 07 14:15:38 2013 +0200 @@ -22,8 +22,6 @@ */ package com.oracle.graal.nodes.extended; -import java.util.*; - import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.Node.ValueNumberable; import com.oracle.graal.nodes.calc.*; @@ -38,61 +36,6 @@ public abstract class LocationNode extends FloatingNode implements LIRLowerable, ValueNumberable { /** - * Marker interface for location identities. Apart from the special values {@link #ANY_LOCATION} - * and {@link #FINAL_LOCATION}, a different location identity of two memory accesses guarantees - * that the two accesses do not interfere. - */ - public interface LocationIdentity { - } - - /** - * Denotes any location. A write to such a location kills all values in a memory map during an - * analysis of memory accesses in a graph. A read from this location cannot be moved or - * coalesced with other reads because its interaction with other reads is not known. - */ - public static final LocationIdentity ANY_LOCATION = createLocation("ANY_LOCATION"); - - /** - * Denotes the location of a value that is guaranteed to be final. - */ - public static final LocationIdentity FINAL_LOCATION = createLocation("FINAL_LOCATION"); - - /** - * Creates a new unique location identity for read and write operations. - * - * @param name the name of the new location identity, for debugging purposes - * @return the new location identity - */ - public static LocationIdentity createLocation(final String name) { - return new LocationIdentity() { - - @Override - public String toString() { - return name; - } - }; - } - - /** - * Returns the location identity for an array of the given element kind. Array accesses of the - * same kind must have the same location identity unless an alias analysis guarantees that two - * distinct arrays are accessed. - */ - public static LocationIdentity getArrayLocation(Kind elementKind) { - return ARRAY_LOCATIONS.get(elementKind); - } - - private static final EnumMap ARRAY_LOCATIONS = initArrayLocations(); - - private static EnumMap initArrayLocations() { - EnumMap result = new EnumMap<>(Kind.class); - for (Kind kind : Kind.values()) { - result.put(kind, createLocation("Array: " + kind.getJavaName())); - } - return result; - } - - /** * Marker interface for locations in snippets. */ public interface Location { diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/MembarNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/MembarNode.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/MembarNode.java Fri Jun 07 14:15:38 2013 +0200 @@ -22,6 +22,7 @@ */ package com.oracle.graal.nodes.extended; +import static com.oracle.graal.api.meta.LocationIdentity.*; import static com.oracle.graal.graph.UnsafeAccess.*; import java.lang.reflect.*; @@ -29,9 +30,9 @@ import sun.misc.*; import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.extended.LocationNode.LocationIdentity; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -52,7 +53,7 @@ @Override public LocationIdentity[] getLocationIdentities() { - return new LocationIdentity[]{LocationNode.ANY_LOCATION}; + return new LocationIdentity[]{ANY_LOCATION}; } @Override diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/MemoryCheckpoint.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/MemoryCheckpoint.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/MemoryCheckpoint.java Fri Jun 07 14:15:38 2013 +0200 @@ -22,8 +22,8 @@ */ package com.oracle.graal.nodes.extended; +import com.oracle.graal.api.meta.*; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.extended.LocationNode.LocationIdentity; /** * This interface marks subclasses of {@link FixedNode} that kill a set of memory locations @@ -34,7 +34,7 @@ /** * This method is used to determine which set of memory locations is killed by this node. - * Returning the special value {@link LocationNode#ANY_LOCATION} will kill all memory locations. + * Returning the special value {@link LocationIdentity#ANY_LOCATION} will kill all memory locations. * * @return the identities of all locations killed by this node. */ diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/OSRStartNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/OSRStartNode.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/OSRStartNode.java Fri Jun 07 14:15:38 2013 +0200 @@ -30,9 +30,7 @@ @Override public void lower(LoweringTool tool, LoweringType loweringType) { - if (loweringType == LoweringType.AFTER_GUARDS) { - tool.getRuntime().lower(this, tool); - } + tool.getRuntime().lower(this, tool); } public NodeIterable getOSRLocals() { diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java Fri Jun 07 14:15:38 2013 +0200 @@ -25,33 +25,33 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.extended.LocationNode.LocationIdentity; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; +import com.oracle.graal.nodes.virtual.*; /** * Reads an {@linkplain AccessNode accessed} value. */ -public final class ReadNode extends FloatableAccessNode implements Node.IterableNodeType, LIRLowerable, Canonicalizable, PiPushable { +public final class ReadNode extends FloatableAccessNode implements Node.IterableNodeType, LIRLowerable, Canonicalizable, PiPushable, Virtualizable { - public ReadNode(ValueNode object, ValueNode location, Stamp stamp) { - super(object, location, stamp); + public ReadNode(ValueNode object, ValueNode location, Stamp stamp, WriteBarrierType barrierType, boolean compress) { + super(object, location, stamp, barrierType, compress); } - public ReadNode(ValueNode object, ValueNode location, Stamp stamp, GuardingNode guard) { - super(object, location, stamp, guard); + public ReadNode(ValueNode object, ValueNode location, Stamp stamp, GuardingNode guard, WriteBarrierType barrierType, boolean compress) { + super(object, location, stamp, guard, barrierType, compress); } private ReadNode(ValueNode object, int displacement, LocationIdentity locationIdentity, Kind kind) { super(object, ConstantLocationNode.create(locationIdentity, kind, displacement, object.graph()), StampFactory.forKind(kind)); } - private ReadNode(ValueNode object, ValueNode location, GuardingNode guard) { + private ReadNode(ValueNode object, ValueNode location, ValueNode guard) { /* * Used by node intrinsics. Since the initial value for location is a parameter, i.e., a * LocalNode, the constructor cannot use the declared type LocationNode. */ - super(object, location, StampFactory.forNodeIntrinsic(), guard); + super(object, location, StampFactory.forNodeIntrinsic(), (GuardingNode) guard, WriteBarrierType.NONE, false); } @Override @@ -67,7 +67,7 @@ @Override public FloatingAccessNode asFloatingNode(ValueNode lastLocationAccess) { - return graph().unique(new FloatingReadNode(object(), location(), lastLocationAccess, stamp(), getGuard())); + return graph().unique(new FloatingReadNode(object(), location(), lastLocationAccess, stamp(), getGuard(), getWriteBarrierType(), compress())); } public static ValueNode canonicalizeRead(ValueNode read, LocationNode location, ValueNode object, CanonicalizerTool tool) { @@ -76,8 +76,8 @@ // Read without usages can be savely removed. return null; } - if (runtime != null && object != null && object.isConstant()) { - if (location.getLocationIdentity() == LocationNode.FINAL_LOCATION && location instanceof ConstantLocationNode) { + if (tool.canonicalizeReads() && runtime != null && object != null && object.isConstant()) { + if (location.getLocationIdentity() == LocationIdentity.FINAL_LOCATION && location instanceof ConstantLocationNode) { long displacement = ((ConstantLocationNode) location).getDisplacement(); Kind kind = location.getValueKind(); if (object.kind() == Kind.Object) { @@ -129,6 +129,21 @@ return false; } + @Override + public void virtualize(VirtualizerTool tool) { + if (location() instanceof ConstantLocationNode) { + ConstantLocationNode constantLocation = (ConstantLocationNode) location(); + State state = tool.getObjectState(object()); + if (state != null && state.getState() == EscapeState.Virtual) { + VirtualObjectNode virtual = state.getVirtualObject(); + int entryIndex = virtual.entryIndexForOffset(constantLocation.getDisplacement()); + if (entryIndex != -1 && virtual.entryKind(entryIndex) == constantLocation.getValueKind()) { + tool.replaceWith(state.getEntry(entryIndex)); + } + } + } + } + /** * Reads a value from memory. * diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/SnippetLocationNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/SnippetLocationNode.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/SnippetLocationNode.java Fri Jun 07 14:15:38 2013 +0200 @@ -22,6 +22,8 @@ */ package com.oracle.graal.nodes.extended; +import static com.oracle.graal.api.meta.LocationIdentity.*; + import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; @@ -74,7 +76,7 @@ return (LocationIdentity) locationIdentity.asConstant().asObject(); } // We do not know our actual location identity yet, so be conservative. - return LocationNode.ANY_LOCATION; + return ANY_LOCATION; } @Override diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeCastNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeCastNode.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeCastNode.java Fri Jun 07 14:15:38 2013 +0200 @@ -52,12 +52,6 @@ if (stamp() == StampFactory.forNodeIntrinsic()) { return false; } - if (object().objectStamp().alwaysNull() && objectStamp().nonNull()) { - // a null value flowing into a nonNull UnsafeCastNode should be guarded by a type/isNull - // guard, but the - // compiler might see this situation before the branch is deleted - return false; - } return updateStamp(stamp().join(object().stamp())); } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeLoadNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeLoadNode.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeLoadNode.java Fri Jun 07 14:15:38 2013 +0200 @@ -83,8 +83,8 @@ // UnsafeAccess only have an // object base ObjectStamp receiverStamp = object().objectStamp(); - if (receiverStamp.nonNull()) { - ResolvedJavaType receiverType = receiverStamp.type(); + ResolvedJavaType receiverType = receiverStamp.type(); + if (receiverStamp.nonNull() && receiverType != null) { ResolvedJavaField field = receiverType.findInstanceFieldWithOffset(displacement()); if (field != null) { return this.graph().add(new LoadFieldNode(object(), field)); diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeStoreNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeStoreNode.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeStoreNode.java Fri Jun 07 14:15:38 2013 +0200 @@ -22,12 +22,12 @@ */ package com.oracle.graal.nodes.extended; +import static com.oracle.graal.api.meta.LocationIdentity.*; import static com.oracle.graal.graph.UnsafeAccess.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.extended.LocationNode.LocationIdentity; import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -76,7 +76,7 @@ @Override public LocationIdentity[] getLocationIdentities() { - return new LocationIdentity[]{LocationNode.ANY_LOCATION}; + return new LocationIdentity[]{ANY_LOCATION}; } @Override diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ValueAnchorNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ValueAnchorNode.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ValueAnchorNode.java Fri Jun 07 14:15:38 2013 +0200 @@ -61,6 +61,10 @@ } } + public void removeAnchoredNode(ValueNode value) { + this.anchored.remove(value); + } + @Override public ValueNode canonical(CanonicalizerTool tool) { if (permanent) { diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteMemoryCheckpointNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteMemoryCheckpointNode.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteMemoryCheckpointNode.java Fri Jun 07 14:15:38 2013 +0200 @@ -22,8 +22,10 @@ */ package com.oracle.graal.nodes.extended; +import static com.oracle.graal.api.meta.LocationIdentity.*; + +import com.oracle.graal.api.meta.*; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.extended.LocationNode.LocationIdentity; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -39,7 +41,7 @@ @Override public LocationIdentity[] getLocationIdentities() { - return new LocationIdentity[]{LocationNode.ANY_LOCATION}; + return new LocationIdentity[]{ANY_LOCATION}; } @Override diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteNode.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteNode.java Fri Jun 07 14:15:38 2013 +0200 @@ -26,37 +26,19 @@ import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.extended.LocationNode.Location; -import com.oracle.graal.nodes.extended.LocationNode.LocationIdentity; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; +import com.oracle.graal.nodes.virtual.*; /** * Writes a given {@linkplain #value() value} a {@linkplain AccessNode memory location}. */ -public final class WriteNode extends AccessNode implements StateSplit, LIRLowerable, MemoryCheckpoint, Node.IterableNodeType { +public final class WriteNode extends AccessNode implements StateSplit, LIRLowerable, MemoryCheckpoint, Node.IterableNodeType, Virtualizable { @Input private ValueNode value; @Input(notDataflow = true) private FrameState stateAfter; private final WriteBarrierType barrierType; - /* - * The types of write barriers attached to stores. - */ - public enum WriteBarrierType { - /* - * Primitive stores which do not necessitate write barriers. - */ - NONE, - /* - * Array object stores which necessitate precise write barriers. - */ - PRECISE, - /* - * Field object stores which necessitate imprecise write barriers. - */ - IMPRECISE - } - public FrameState stateAfter() { return stateAfter; } @@ -75,12 +57,8 @@ return value; } - public WriteBarrierType getWriteBarrierType() { - return barrierType; - } - - public WriteNode(ValueNode object, ValueNode value, ValueNode location, WriteBarrierType barrierType) { - super(object, location, StampFactory.forVoid()); + public WriteNode(ValueNode object, ValueNode value, ValueNode location, WriteBarrierType barrierType, boolean compress) { + super(object, location, StampFactory.forVoid(), barrierType, compress); this.value = value; this.barrierType = barrierType; } @@ -92,10 +70,26 @@ } @NodeIntrinsic - public static native void writeMemory(Object object, Object value, Location location, @ConstantNodeParameter WriteBarrierType barrierType); + public static native void writeMemory(Object object, Object value, Location location, @ConstantNodeParameter WriteBarrierType barrierType, @ConstantNodeParameter boolean compress); @Override public LocationIdentity[] getLocationIdentities() { return new LocationIdentity[]{location().getLocationIdentity()}; } + + @Override + public void virtualize(VirtualizerTool tool) { + if (location() instanceof ConstantLocationNode) { + ConstantLocationNode constantLocation = (ConstantLocationNode) location(); + State state = tool.getObjectState(object()); + if (state != null && state.getState() == EscapeState.Virtual) { + VirtualObjectNode virtual = state.getVirtualObject(); + int entryIndex = virtual.entryIndexForOffset(constantLocation.getDisplacement()); + if (entryIndex != -1 && virtual.entryKind(entryIndex) == constantLocation.getValueKind()) { + tool.setVirtualEntry(state, entryIndex, value()); + tool.delete(); + } + } + } + } } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastNode.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastNode.java Fri Jun 07 14:15:38 2013 +0200 @@ -69,9 +69,6 @@ @Override public boolean inferStamp() { - if (object().objectStamp().alwaysNull() && objectStamp().nonNull()) { - return false; - } return updateStamp(stamp().join(object().stamp())); } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CompareAndSwapNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CompareAndSwapNode.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CompareAndSwapNode.java Fri Jun 07 14:15:38 2013 +0200 @@ -22,14 +22,13 @@ */ package com.oracle.graal.nodes.java; +import static com.oracle.graal.api.meta.LocationIdentity.*; import static com.oracle.graal.graph.UnsafeAccess.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.extended.*; -import com.oracle.graal.nodes.extended.LocationNode.LocationIdentity; -import com.oracle.graal.nodes.extended.WriteNode.WriteBarrierType; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -37,7 +36,7 @@ * Represents an atomic compare-and-swap operation The result is a boolean that contains whether the * value matched the expected value. */ -public class CompareAndSwapNode extends AbstractStateSplit implements StateSplit, LIRLowerable, Lowerable, MemoryCheckpoint, Node.IterableNodeType { +public class CompareAndSwapNode extends AbstractStateSplit implements StateSplit, LIRLowerable, Lowerable, MemoryCheckpoint, Node.IterableNodeType, HeapAccess { @Input private ValueNode object; @Input private ValueNode offset; @@ -46,6 +45,7 @@ @Input private LocationNode location; private final int displacement; private WriteBarrierType barrierType; + private boolean compress; public ValueNode object() { return object; @@ -76,6 +76,7 @@ this.location = location; } + @Override public WriteBarrierType getWriteBarrierType() { return barrierType; } @@ -84,6 +85,15 @@ this.barrierType = type; } + @Override + public boolean compress() { + return compress; + } + + public void setCompress() { + this.compress = true; + } + public CompareAndSwapNode(ValueNode object, int displacement, ValueNode offset, ValueNode expected, ValueNode newValue) { super(StampFactory.forKind(Kind.Boolean.getStackKind())); assert expected.kind() == newValue.kind(); @@ -93,11 +103,12 @@ this.newValue = newValue; this.displacement = displacement; this.barrierType = WriteBarrierType.NONE; + this.compress = false; } @Override public LocationIdentity[] getLocationIdentities() { - return new LocationIdentity[]{LocationNode.ANY_LOCATION}; + return new LocationIdentity[]{ANY_LOCATION}; } @Override diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ExceptionObjectNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ExceptionObjectNode.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ExceptionObjectNode.java Fri Jun 07 14:15:38 2013 +0200 @@ -22,10 +22,11 @@ */ package com.oracle.graal.nodes.java; +import static com.oracle.graal.api.meta.LocationIdentity.*; + import com.oracle.graal.api.meta.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.extended.*; -import com.oracle.graal.nodes.extended.LocationNode.LocationIdentity; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -41,7 +42,7 @@ @Override public LocationIdentity[] getLocationIdentities() { - return new LocationIdentity[]{LocationNode.ANY_LOCATION}; + return new LocationIdentity[]{ANY_LOCATION}; } @Override diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadFieldNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadFieldNode.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadFieldNode.java Fri Jun 07 14:15:38 2013 +0200 @@ -57,7 +57,7 @@ @Override public ValueNode canonical(CanonicalizerTool tool) { MetaAccessProvider runtime = tool.runtime(); - if (runtime != null) { + if (tool.canonicalizeReads() && runtime != null) { Constant constant = null; if (isStatic()) { constant = field().readConstantValue(null); diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MonitorEnterNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MonitorEnterNode.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MonitorEnterNode.java Fri Jun 07 14:15:38 2013 +0200 @@ -22,9 +22,11 @@ */ package com.oracle.graal.nodes.java; +import static com.oracle.graal.api.meta.LocationIdentity.*; + +import com.oracle.graal.api.meta.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.extended.*; -import com.oracle.graal.nodes.extended.LocationNode.LocationIdentity; import com.oracle.graal.nodes.spi.*; /** @@ -46,7 +48,7 @@ @Override public LocationIdentity[] getLocationIdentities() { - return new LocationIdentity[]{LocationNode.ANY_LOCATION}; + return new LocationIdentity[]{ANY_LOCATION}; } @Override diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MonitorExitNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MonitorExitNode.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MonitorExitNode.java Fri Jun 07 14:15:38 2013 +0200 @@ -22,10 +22,12 @@ */ package com.oracle.graal.nodes.java; +import static com.oracle.graal.api.meta.LocationIdentity.*; + +import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.extended.*; -import com.oracle.graal.nodes.extended.LocationNode.LocationIdentity; import com.oracle.graal.nodes.spi.*; /** @@ -47,7 +49,7 @@ @Override public LocationIdentity[] getLocationIdentities() { - return new LocationIdentity[]{LocationNode.ANY_LOCATION}; + return new LocationIdentity[]{ANY_LOCATION}; } @Override diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewArrayNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewArrayNode.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewArrayNode.java Fri Jun 07 14:15:38 2013 +0200 @@ -100,9 +100,7 @@ @Override public void lower(LoweringTool tool, LoweringType loweringType) { - if (loweringType == LoweringType.AFTER_GUARDS) { - tool.getRuntime().lower(this, tool); - } + tool.getRuntime().lower(this, tool); } @Override diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewInstanceNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewInstanceNode.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewInstanceNode.java Fri Jun 07 14:15:38 2013 +0200 @@ -78,9 +78,7 @@ @Override public void lower(LoweringTool tool, LoweringType loweringType) { - if (loweringType == LoweringType.AFTER_GUARDS) { - tool.getRuntime().lower(this, tool); - } + tool.getRuntime().lower(this, tool); } @Override diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewMultiArrayNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewMultiArrayNode.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewMultiArrayNode.java Fri Jun 07 14:15:38 2013 +0200 @@ -63,9 +63,7 @@ @Override public void lower(LoweringTool tool, LoweringType loweringType) { - if (loweringType == LoweringType.AFTER_GUARDS) { - tool.getRuntime().lower(this, tool); - } + tool.getRuntime().lower(this, tool); } public ResolvedJavaType type() { diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/RegisterFinalizerNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/RegisterFinalizerNode.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/RegisterFinalizerNode.java Fri Jun 07 14:15:38 2013 +0200 @@ -106,11 +106,6 @@ return null; } - @Override - public boolean isCallSiteDeoptimization() { - return false; - } - @SuppressWarnings("unused") @NodeIntrinsic public static void register(Object thisObj) { diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/StoreIndexedNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/StoreIndexedNode.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/StoreIndexedNode.java Fri Jun 07 14:15:38 2013 +0200 @@ -74,7 +74,7 @@ int index = indexValue.isConstant() ? indexValue.asConstant().asInt() : -1; if (index >= 0 && index < arrayState.getVirtualObject().entryCount()) { ResolvedJavaType componentType = arrayState.getVirtualObject().type().getComponentType(); - if (componentType.isPrimitive() || value.objectStamp().alwaysNull() || componentType.isAssignableFrom(value.objectStamp().type())) { + if (componentType.isPrimitive() || value.objectStamp().alwaysNull() || (value.objectStamp().type() != null && componentType.isAssignableFrom(value.objectStamp().type()))) { tool.setVirtualEntry(arrayState, index, value()); tool.delete(); } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/CanonicalizerTool.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/CanonicalizerTool.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/CanonicalizerTool.java Fri Jun 07 14:15:38 2013 +0200 @@ -32,5 +32,7 @@ MetaAccessProvider runtime(); + boolean canonicalizeReads(); + void removeIfUnused(Node node); } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LoweringTool.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LoweringTool.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LoweringTool.java Fri Jun 07 14:15:38 2013 +0200 @@ -28,11 +28,14 @@ import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.cfg.*; import com.oracle.graal.nodes.extended.*; +import com.oracle.graal.nodes.spi.Lowerable.LoweringType; public interface LoweringTool { GraalCodeCacheProvider getRuntime(); + LoweringType getLoweringType(); + Replacements getReplacements(); GuardingNode createNullCheckGuard(GuardedNode guardedNode, ValueNode object); diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/ObjectStamp.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/ObjectStamp.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/ObjectStamp.java Fri Jun 07 14:15:38 2013 +0200 @@ -22,6 +22,8 @@ */ package com.oracle.graal.nodes.type; +import java.lang.reflect.*; + import com.oracle.graal.api.meta.*; public class ObjectStamp extends Stamp { @@ -33,14 +35,29 @@ public ObjectStamp(ResolvedJavaType type, boolean exactType, boolean nonNull, boolean alwaysNull) { super(Kind.Object); - assert !exactType || type != null; - assert !(nonNull && alwaysNull); + assert isValid(type, exactType, nonNull, alwaysNull); this.type = type; this.exactType = exactType; this.nonNull = nonNull; this.alwaysNull = alwaysNull; } + public static boolean isValid(ResolvedJavaType type, boolean exactType, boolean nonNull, boolean alwaysNull) { + if (exactType && type == null) { + return false; + } + + if (exactType && Modifier.isAbstract(type.getModifiers()) && !type.isArray()) { + return false; + } + + if (nonNull && alwaysNull) { + return false; + } + + return true; + } + @Override public ResolvedJavaType javaType(MetaAccessProvider metaAccess) { if (type != null) { @@ -152,12 +169,19 @@ joinType = type; } } + if (joinType == type && joinExactType == exactType && joinNonNull == nonNull && joinAlwaysNull == alwaysNull) { return this; } else if (joinType == other.type && joinExactType == other.exactType && joinNonNull == other.nonNull && joinAlwaysNull == other.alwaysNull) { return other; } else { - return new ObjectStamp(joinType, joinExactType, joinNonNull, joinAlwaysNull); + if (isValid(joinType, joinExactType, joinNonNull, joinAlwaysNull)) { + return new ObjectStamp(joinType, joinExactType, joinNonNull, joinAlwaysNull); + } else { + // This situation can happen in case the compiler wants to join two contradicting + // stamps. + return null; + } } } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/CommitAllocationNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/CommitAllocationNode.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/CommitAllocationNode.java Fri Jun 07 14:15:38 2013 +0200 @@ -66,9 +66,7 @@ @Override public void lower(LoweringTool tool, LoweringType loweringType) { - if (loweringType == LoweringType.AFTER_GUARDS) { - tool.getRuntime().lower(this, tool); - } + tool.getRuntime().lower(this, tool); } @Override diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.options/src/META-INF/services/javax.annotation.processing.Processor --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.options/src/META-INF/services/javax.annotation.processing.Processor Fri Jun 07 14:15:38 2013 +0200 @@ -0,0 +1,1 @@ +com.oracle.graal.options.OptionProcessor diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.options/src/com/oracle/graal/options/Option.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.options/src/com/oracle/graal/options/Option.java Fri Jun 07 14:15:38 2013 +0200 @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.options; + +import java.lang.annotation.*; + +/** + * Describes the attributes of an option whose {@link OptionValue value} is in a static field + * annotated by this annotation type. + * + * @see OptionProcessor + * @see OptionDescriptor + */ +@Retention(RetentionPolicy.CLASS) +@Target(ElementType.FIELD) +public @interface Option { + + /** + * Gets a help message for the option. + */ + String help(); + + /** + * The name of the option. By default, the name of the annotated field should be used. + */ + String name() default ""; +} diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.options/src/com/oracle/graal/options/OptionDescriptor.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.options/src/com/oracle/graal/options/OptionDescriptor.java Fri Jun 07 14:15:38 2013 +0200 @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.options; + +/** + * Describes the attributes of a static field {@linkplain Option option} and provides access to its + * {@linkplain OptionValue value}. + */ +public class OptionDescriptor { + + protected final String name; + protected final Class type; + protected final String help; + protected final OptionValue option; + protected final String location; + + public OptionDescriptor(String name, Class type, String help, String location, OptionValue option) { + this.name = name; + this.type = type; + this.help = help; + this.option = option; + this.location = location; + } + + /** + * Gets the type of values stored in the option. + */ + public Class getType() { + return type; + } + + /** + * Gets a descriptive help message for the option. + */ + public String getHelp() { + return help; + } + + /** + * Gets the name of the option. It's up to the client of this object how to use the name to get + * a user specified value for the option from the environment. + */ + public String getName() { + return name; + } + + /** + * Gets the boxed option value. + */ + public OptionValue getOptionValue() { + return option; + } + + /** + * Gets a description of the location where this option is stored. + */ + public String getLocation() { + return location; + + } +} diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.options/src/com/oracle/graal/options/OptionProcessor.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.options/src/com/oracle/graal/options/OptionProcessor.java Fri Jun 07 14:15:38 2013 +0200 @@ -0,0 +1,295 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.options; + +import java.io.*; +import java.util.*; + +import javax.annotation.processing.*; +import javax.lang.model.*; +import javax.lang.model.element.*; +import javax.lang.model.type.*; +import javax.lang.model.util.*; +import javax.tools.Diagnostic.Kind; +import javax.tools.*; + +/** + * Processes static fields annotated with {@link Option}. An {@link Options} service is generated + * for each top level class containing at least one such field. These service objects can be + * retrieved as follows: + * + *

    + * ServiceLoader<Options> sl = ServiceLoader.loadInstalled(Options.class);
    + * for (OptionDescriptor desc : sl) {
    + *     // use desc
    + * }
    + * 
    + */ +@SupportedSourceVersion(SourceVersion.RELEASE_7) +@SupportedAnnotationTypes({"com.oracle.graal.options.Option"}) +public class OptionProcessor extends AbstractProcessor { + + private final Set processed = new HashSet<>(); + + private void processElement(Element element, OptionsInfo info) { + + if (!element.getModifiers().contains(Modifier.STATIC)) { + processingEnv.getMessager().printMessage(Kind.ERROR, "Option field must be static", element); + return; + } + + Option annotation = element.getAnnotation(Option.class); + assert annotation != null; + assert element instanceof VariableElement; + assert element.getKind() == ElementKind.FIELD; + VariableElement field = (VariableElement) element; + String fieldName = field.getSimpleName().toString(); + + Elements elements = processingEnv.getElementUtils(); + Types types = processingEnv.getTypeUtils(); + + TypeMirror fieldType = field.asType(); + if (fieldType.getKind() != TypeKind.DECLARED) { + processingEnv.getMessager().printMessage(Kind.ERROR, "Option field must be of type " + OptionValue.class.getName(), element); + return; + } + DeclaredType declaredFieldType = (DeclaredType) fieldType; + + TypeMirror optionValueType = elements.getTypeElement(OptionValue.class.getName()).asType(); + if (!types.isSubtype(fieldType, types.erasure(optionValueType))) { + String msg = String.format("Option field type %s is not a subclass of %s", fieldType, optionValueType); + processingEnv.getMessager().printMessage(Kind.ERROR, msg, element); + return; + } + + if (!field.getModifiers().contains(Modifier.STATIC)) { + processingEnv.getMessager().printMessage(Kind.ERROR, "Option field must be static", element); + return; + } + + String optionName = annotation.name(); + if (optionName.equals("")) { + optionName = fieldName; + } + + String optionType = declaredFieldType.getTypeArguments().get(0).toString(); + if (optionType.startsWith("java.lang.")) { + optionType = optionType.substring("java.lang.".length()); + } + + Element enclosing = element.getEnclosingElement(); + String declaringClass = ""; + String separator = ""; + Set originatingElementsList = info.originatingElements; + originatingElementsList.add(field); + while (enclosing != null) { + if (enclosing.getKind() == ElementKind.CLASS || enclosing.getKind() == ElementKind.INTERFACE) { + if (enclosing.getModifiers().contains(Modifier.PRIVATE)) { + String msg = String.format("Option field cannot be declared in a private %s %s", enclosing.getKind().name().toLowerCase(), enclosing); + processingEnv.getMessager().printMessage(Kind.ERROR, msg, element); + return; + } + originatingElementsList.add(enclosing); + declaringClass = enclosing.getSimpleName() + separator + declaringClass; + separator = "."; + } else { + assert enclosing.getKind() == ElementKind.PACKAGE; + } + enclosing = enclosing.getEnclosingElement(); + } + + info.options.add(new OptionInfo(optionName, annotation.help(), optionType, declaringClass, field)); + } + + private void createFiles(OptionsInfo info) { + String pkg = ((PackageElement) info.topDeclaringType.getEnclosingElement()).getQualifiedName().toString(); + Name declaringClass = info.topDeclaringType.getSimpleName(); + + String optionsClassName = declaringClass + "_" + Options.class.getSimpleName(); + Element[] originatingElements = info.originatingElements.toArray(new Element[info.originatingElements.size()]); + + Filer filer = processingEnv.getFiler(); + try (PrintWriter out = createSourceFile(pkg, optionsClassName, filer, originatingElements)) { + + out.println("// CheckStyle: stop header check"); + out.println("// GENERATED CONTENT - DO NOT EDIT"); + out.println("// Source: " + declaringClass + ".java"); + out.println("package " + pkg + ";"); + out.println(""); + out.println("import java.util.*;"); + out.println("import " + Options.class.getPackage().getName() + ".*;"); + out.println(""); + out.println("public class " + optionsClassName + " implements " + Options.class.getSimpleName() + " {"); + out.println(" @Override"); + out.println(" public Iterator<" + OptionDescriptor.class.getSimpleName() + "> iterator() {"); + out.println(" List<" + OptionDescriptor.class.getSimpleName() + "> options = Arrays.asList("); + + boolean needPrivateFieldAccessor = false; + int i = 0; + for (OptionInfo option : info.options) { + String optionValue; + if (option.field.getModifiers().contains(Modifier.PRIVATE)) { + needPrivateFieldAccessor = true; + optionValue = "field(" + option.declaringClass + ".class, \"" + option.field.getSimpleName() + "\")"; + } else { + optionValue = option.declaringClass + "." + option.field.getSimpleName(); + } + String name = option.name; + String type = option.type; + String help = option.help; + String location = pkg + "." + option.declaringClass + "." + option.field.getSimpleName(); + String comma = i == info.options.size() - 1 ? "" : ","; + out.printf(" new %s(\"%s\", %s.class, \"%s\", \"%s\", %s)%s%n", OptionDescriptor.class.getSimpleName(), name, type, help, location, optionValue, comma); + i++; + } + out.println(" );"); + out.println(" return options.iterator();"); + out.println(" }"); + if (needPrivateFieldAccessor) { + out.println(" private static " + OptionValue.class.getSimpleName() + " field(Class declaringClass, String fieldName) {"); + out.println(" try {"); + out.println(" java.lang.reflect.Field field = declaringClass.getDeclaredField(fieldName);"); + out.println(" field.setAccessible(true);"); + out.println(" return (" + OptionValue.class.getSimpleName() + ") field.get(null);"); + out.println(" } catch (Exception e) {"); + out.println(" throw (InternalError) new InternalError().initCause(e);"); + out.println(" }"); + out.println(" }"); + } + out.println("}"); + } + + try { + createProviderFile(pkg, optionsClassName, originatingElements); + } catch (IOException e) { + processingEnv.getMessager().printMessage(Kind.ERROR, e.getMessage(), info.topDeclaringType); + } + } + + private void createProviderFile(String pkg, String providerClassName, Element... originatingElements) throws IOException { + String filename = "META-INF/providers/" + pkg + "." + providerClassName; + FileObject file = processingEnv.getFiler().createResource(StandardLocation.CLASS_OUTPUT, "", filename, originatingElements); + PrintWriter writer = new PrintWriter(new OutputStreamWriter(file.openOutputStream(), "UTF-8")); + writer.println(Options.class.getName()); + writer.close(); + } + + protected PrintWriter createSourceFile(String pkg, String relativeName, Filer filer, Element... originatingElements) { + try { + // Ensure Unix line endings to comply with Graal code style guide checked by Checkstyle + JavaFileObject sourceFile = filer.createSourceFile(pkg + "." + relativeName, originatingElements); + return new PrintWriter(sourceFile.openWriter()) { + + @Override + public void println() { + print("\n"); + } + }; + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + static class OptionInfo { + + final String name; + final String help; + final String type; + final String declaringClass; + final VariableElement field; + + public OptionInfo(String name, String help, String type, String declaringClass, VariableElement field) { + this.name = name; + this.help = help; + this.type = type; + this.declaringClass = declaringClass; + this.field = field; + } + + @Override + public String toString() { + return declaringClass + "." + field; + } + } + + static class OptionsInfo { + + final Element topDeclaringType; + final List options = new ArrayList<>(); + final Set originatingElements = new HashSet<>(); + + public OptionsInfo(Element topDeclaringType) { + this.topDeclaringType = topDeclaringType; + } + } + + private static Element topDeclaringType(Element element) { + Element enclosing = element.getEnclosingElement(); + if (element == null || enclosing.getKind() == ElementKind.PACKAGE) { + assert element.getKind() == ElementKind.CLASS || element.getKind() == ElementKind.INTERFACE; + return element; + } + return topDeclaringType(enclosing); + } + + @Override + public boolean process(Set annotations, RoundEnvironment roundEnv) { + if (roundEnv.processingOver()) { + return true; + } + + Map map = new HashMap<>(); + for (Element element : roundEnv.getElementsAnnotatedWith(Option.class)) { + if (!processed.contains(element)) { + processed.add(element); + Element topDeclaringType = topDeclaringType(element); + OptionsInfo options = map.get(topDeclaringType); + if (options == null) { + options = new OptionsInfo(topDeclaringType); + map.put(topDeclaringType, options); + } + processElement(element, options); + } + } + + boolean ok = true; + Map uniqueness = new HashMap<>(); + for (OptionsInfo info : map.values()) { + for (OptionInfo option : info.options) { + OptionInfo conflict = uniqueness.put(option.name, option); + if (conflict != null) { + processingEnv.getMessager().printMessage(Kind.ERROR, "Duplicate option names for " + option + " and " + conflict, option.field); + ok = false; + } + } + } + + if (ok) { + for (OptionsInfo info : map.values()) { + createFiles(info); + } + } + + return true; + } +} diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.options/src/com/oracle/graal/options/OptionValue.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.options/src/com/oracle/graal/options/OptionValue.java Fri Jun 07 14:15:38 2013 +0200 @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.options; + +/** + * An option value. + */ +public class OptionValue { + + /** + * The raw option value. + */ + protected T value; + + public OptionValue(T value) { + this.value = value; + } + + private static final Object UNINITIALIZED = "UNINITIALIZED"; + + /** + * Creates an uninitialized option value for a subclass that initializes itself + * {@link #initialValue() lazily}. + */ + @SuppressWarnings("unchecked") + protected OptionValue() { + this.value = (T) UNINITIALIZED; + } + + /** + * Lazy initialization of value. + */ + protected T initialValue() { + throw new InternalError("Uninitialized option value must override initialValue()"); + } + + /** + * Gets the value of this option. + */ + public T getValue() { + if (value == UNINITIALIZED) { + value = initialValue(); + } + return value; + } + + /** + * Sets the value of this option. + */ + @SuppressWarnings("unchecked") + public void setValue(Object v) { + this.value = (T) v; + } +} diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.options/src/com/oracle/graal/options/Options.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.options/src/com/oracle/graal/options/Options.java Fri Jun 07 14:15:38 2013 +0200 @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.options; + +import java.util.*; + +/** + * A {@linkplain ServiceLoader service} for accessing a set of {@link OptionDescriptor}s. + */ +public interface Options extends Iterable { +} diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.options/src/com/oracle/graal/options/StableOptionValue.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.options/src/com/oracle/graal/options/StableOptionValue.java Fri Jun 07 14:15:38 2013 +0200 @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.options; + +/** + * An option that always returns the same {@linkplain #getValue() value}. + */ +public class StableOptionValue extends OptionValue { + + /** + * Creates a stable option value. + */ + public StableOptionValue(T value) { + super(value); + } + + /** + * Used to assert the invariant for stability. Without using locks, this check is not safe + * against races and so it's only an assertion. + */ + private boolean getValueCalled; + + /** + * Creates an uninitialized stable option value for a subclass that initializes itself + * {@link #initialValue() lazily}. + */ + public StableOptionValue() { + } + + /** + * Gets the value of this option. + */ + @Override + public final T getValue() { + T result = super.getValue(); + assert initGetValueCalled(); + return result; + } + + private boolean initGetValueCalled() { + getValueCalled = true; + return true; + } + + /** + * {@inheritDoc} + *

    + * This must only be called if {@link #getValue()} has never been called. + */ + @Override + public final void setValue(Object v) { + assert !getValueCalled; + super.setValue(v); + } +} diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CanonicalizerPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CanonicalizerPhase.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CanonicalizerPhase.java Fri Jun 07 14:15:38 2013 +0200 @@ -47,30 +47,20 @@ private static final DebugMetric METRIC_SIMPLIFICATION_CONSIDERED_NODES = Debug.metric("SimplificationConsideredNodes"); public static final DebugMetric METRIC_GLOBAL_VALUE_NUMBERING_HITS = Debug.metric("GlobalValueNumberingHits"); - private final CustomCanonicalizer customCanonicalizer; - private final Iterable workingSet; + private final boolean canonicalizeReads; public interface CustomCanonicalizer { ValueNode canonicalize(ValueNode node); } - public CanonicalizerPhase() { - this(null); - } - - public CanonicalizerPhase(CustomCanonicalizer customCanonicalizer) { - this(customCanonicalizer, null); - } - - public CanonicalizerPhase(CustomCanonicalizer customCanonicalizer, Iterable workingSet) { - this.customCanonicalizer = customCanonicalizer; - this.workingSet = workingSet; + public CanonicalizerPhase(boolean canonicalizeReads) { + this.canonicalizeReads = canonicalizeReads; } @Override protected void run(StructuredGraph graph, PhaseContext context) { - new Instance(context.getRuntime(), context.getAssumptions(), workingSet, customCanonicalizer).run(graph); + new Instance(context.getRuntime(), context.getAssumptions(), canonicalizeReads).run(graph); } public static class Instance extends Phase { @@ -80,12 +70,13 @@ private final MetaAccessProvider runtime; private final CustomCanonicalizer customCanonicalizer; private final Iterable initWorkingSet; + private final boolean canonicalizeReads; private NodeWorkList workList; private Tool tool; - public Instance(MetaAccessProvider runtime, Assumptions assumptions) { - this(runtime, assumptions, null, 0, null); + public Instance(MetaAccessProvider runtime, Assumptions assumptions, boolean canonicalizeReads) { + this(runtime, assumptions, canonicalizeReads, null, 0, null); } /** @@ -95,23 +86,24 @@ * should be an auto-grow node bitmap * @param customCanonicalizer */ - public Instance(MetaAccessProvider runtime, Assumptions assumptions, Iterable workingSet, CustomCanonicalizer customCanonicalizer) { - this(runtime, assumptions, workingSet, 0, customCanonicalizer); + public Instance(MetaAccessProvider runtime, Assumptions assumptions, boolean canonicalizeReads, Iterable workingSet, CustomCanonicalizer customCanonicalizer) { + this(runtime, assumptions, canonicalizeReads, workingSet, 0, customCanonicalizer); } /** * @param newNodesMark only the {@linkplain Graph#getNewNodes(int) new nodes} specified by * this mark are processed otherwise all nodes in the graph are processed */ - public Instance(MetaAccessProvider runtime, Assumptions assumptions, int newNodesMark, CustomCanonicalizer customCanonicalizer) { - this(runtime, assumptions, null, newNodesMark, customCanonicalizer); + public Instance(MetaAccessProvider runtime, Assumptions assumptions, boolean canonicalizeReads, int newNodesMark, CustomCanonicalizer customCanonicalizer) { + this(runtime, assumptions, canonicalizeReads, null, newNodesMark, customCanonicalizer); } - public Instance(MetaAccessProvider runtime, Assumptions assumptions, Iterable workingSet, int newNodesMark, CustomCanonicalizer customCanonicalizer) { + public Instance(MetaAccessProvider runtime, Assumptions assumptions, boolean canonicalizeReads, Iterable workingSet, int newNodesMark, CustomCanonicalizer customCanonicalizer) { super("Canonicalizer"); this.newNodesMark = newNodesMark; this.assumptions = assumptions; this.runtime = runtime; + this.canonicalizeReads = canonicalizeReads; this.customCanonicalizer = customCanonicalizer; this.initWorkingSet = workingSet; } @@ -127,7 +119,7 @@ if (newNodesMark > 0) { workList.addAll(graph.getNewNodes(newNodesMark)); } - tool = new Tool(workList, runtime, assumptions); + tool = new Tool(workList, runtime, assumptions, canonicalizeReads); processWorkSet(graph); } @@ -211,21 +203,6 @@ public Boolean call() { ValueNode canonical = ((Canonicalizable) node).canonical(tool); -// @formatter:off -// cases: original node: -// |Floating|Fixed-unconnected|Fixed-connected| -// -------------------------------------------- -// null| 1 | X | 3 | -// -------------------------------------------- -// Floating| 2 | X | 4 | -// canonical node: -------------------------------------------- -// Fixed-unconnected| X | X | 5 | -// -------------------------------------------- -// Fixed-connected| 2 | X | 6 | -// -------------------------------------------- -// X: must not happen (checked with assertions) -// @formatter:on - return performReplacement(node, graph, canonical); } }); @@ -242,6 +219,20 @@ return node.isDeleted(); } +// @formatter:off +// cases: original node: +// |Floating|Fixed-unconnected|Fixed-connected| +// -------------------------------------------- +// null| 1 | X | 3 | +// -------------------------------------------- +// Floating| 2 | X | 4 | +// canonical node: -------------------------------------------- +// Fixed-unconnected| X | X | 5 | +// -------------------------------------------- +// Fixed-connected| 2 | X | 6 | +// -------------------------------------------- +// X: must not happen (checked with assertions) +// @formatter:on private boolean performReplacement(final Node node, final StructuredGraph graph, ValueNode canonical) { if (canonical == node) { Debug.log("Canonicalizer: work on %s", node); @@ -323,11 +314,13 @@ private final NodeWorkList nodeWorkSet; private final MetaAccessProvider runtime; private final Assumptions assumptions; + private final boolean canonicalizeReads; - public Tool(NodeWorkList nodeWorkSet, MetaAccessProvider runtime, Assumptions assumptions) { + public Tool(NodeWorkList nodeWorkSet, MetaAccessProvider runtime, Assumptions assumptions, boolean canonicalizeReads) { this.nodeWorkSet = nodeWorkSet; this.runtime = runtime; this.assumptions = assumptions; + this.canonicalizeReads = canonicalizeReads; } @Override @@ -359,6 +352,11 @@ public void removeIfUnused(Node node) { tryKillUnused(node); } + + @Override + public boolean canonicalizeReads() { + return canonicalizeReads; + } } } } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/FloatingReadPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/FloatingReadPhase.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/FloatingReadPhase.java Fri Jun 07 14:15:38 2013 +0200 @@ -22,12 +22,14 @@ */ package com.oracle.graal.phases.common; +import static com.oracle.graal.api.meta.LocationIdentity.*; + import java.util.*; +import com.oracle.graal.api.meta.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.PhiNode.PhiType; import com.oracle.graal.nodes.extended.*; -import com.oracle.graal.nodes.extended.LocationNode.LocationIdentity; import com.oracle.graal.phases.*; import com.oracle.graal.phases.graph.*; import com.oracle.graal.phases.graph.ReentrantNodeIterator.LoopInfo; @@ -45,7 +47,7 @@ public MemoryMap(StartNode start) { this(); - lastMemorySnapshot.put(LocationNode.ANY_LOCATION, start); + lastMemorySnapshot.put(ANY_LOCATION, start); } public MemoryMap() { @@ -54,12 +56,12 @@ private ValueNode getLastLocationAccess(LocationIdentity locationIdentity) { ValueNode lastLocationAccess; - if (locationIdentity == LocationNode.FINAL_LOCATION) { + if (locationIdentity == FINAL_LOCATION) { return null; } else { lastLocationAccess = lastMemorySnapshot.get(locationIdentity); if (lastLocationAccess == null) { - lastLocationAccess = lastMemorySnapshot.get(LocationNode.ANY_LOCATION); + lastLocationAccess = lastMemorySnapshot.get(ANY_LOCATION); assert lastLocationAccess != null; } return lastLocationAccess; @@ -122,7 +124,7 @@ exit.addAll(modifiedLocations); exit.addAll(initialState); } - assert !modifiedLocations.contains(LocationNode.FINAL_LOCATION); + assert !modifiedLocations.contains(FINAL_LOCATION); modifiedInLoops.put(loop, modifiedLocations); return loopInfo.exitStates; } @@ -149,7 +151,7 @@ private static void processCheckpoint(MemoryCheckpoint checkpoint, MemoryMap state) { for (LocationIdentity identity : checkpoint.getLocationIdentities()) { - if (identity == LocationNode.ANY_LOCATION) { + if (identity == ANY_LOCATION) { state.lastMemorySnapshot.clear(); } state.lastMemorySnapshot.put(identity, (ValueNode) checkpoint); @@ -160,7 +162,7 @@ StructuredGraph graph = accessNode.graph(); assert accessNode.getNullCheck() == false; LocationIdentity locationIdentity = accessNode.location().getLocationIdentity(); - if (locationIdentity != LocationNode.ANY_LOCATION) { + if (locationIdentity != ANY_LOCATION) { ValueNode lastLocationAccess = state.getLastLocationAccess(locationIdentity); FloatingAccessNode floatingNode = accessNode.asFloatingNode(lastLocationAccess); floatingNode.setNullCheck(accessNode.getNullCheck()); @@ -182,7 +184,7 @@ for (MemoryMap other : states) { keys.addAll(other.lastMemorySnapshot.keySet()); } - assert !keys.contains(LocationNode.FINAL_LOCATION); + assert !keys.contains(FINAL_LOCATION); for (LocationIdentity key : keys) { int mergedStatesCount = 0; @@ -236,7 +238,7 @@ @Override protected Map processLoop(LoopBeginNode loop, MemoryMap initialState) { Set modifiedLocations = modifiedInLoops.get(loop); - if (modifiedLocations.contains(LocationNode.ANY_LOCATION)) { + if (modifiedLocations.contains(ANY_LOCATION)) { // create phis for all locations if ANY is modified in the loop modifiedLocations = new HashSet<>(modifiedLocations); modifiedLocations.addAll(initialState.lastMemorySnapshot.keySet()); diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/FrameStateAssignmentPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/FrameStateAssignmentPhase.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/FrameStateAssignmentPhase.java Fri Jun 07 14:15:38 2013 +0200 @@ -41,6 +41,7 @@ if (node instanceof DeoptimizingNode) { DeoptimizingNode deopt = (DeoptimizingNode) node; if (deopt.canDeoptimize() && deopt.getDeoptimizationState() == null) { + GraalInternalError.guarantee(currentState != null, "no FrameState at DeoptimizingNode %s", deopt); deopt.setDeoptimizationState(currentState); } } @@ -58,10 +59,7 @@ @Override protected FrameState merge(MergeNode merge, List states) { - if (merge.stateAfter() != null) { - return merge.stateAfter(); - } - return singleFrameState(merge, states); + return merge.stateAfter() != null ? merge.stateAfter() : singleFrameState(merge, states); } @Override @@ -73,7 +71,6 @@ protected Map processLoop(LoopBeginNode loop, FrameState initialState) { return ReentrantNodeIterator.processLoop(this, loop, initialState).exitStates; } - } @Override @@ -93,33 +90,12 @@ } private static FrameState singleFrameState(@SuppressWarnings("unused") MergeNode merge, List states) { - if (states.size() == 0) { - return null; - } - FrameState firstState = states.get(0); - FrameState singleState = firstState; - if (singleState == null) { - return null; - } - int singleBci = singleState.bci; + FrameState singleState = states.get(0); for (int i = 1; i < states.size(); ++i) { - FrameState cur = states.get(i); - if (cur == null) { + if (states.get(i) != singleState) { return null; } - - if (cur != singleState) { - singleState = null; - } - - if (cur.bci != singleBci) { - singleBci = FrameState.INVALID_FRAMESTATE_BCI; - } - } - if (singleState != null) { - return singleState; - } - return null; + return singleState; } } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/GuardLoweringPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/GuardLoweringPhase.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/GuardLoweringPhase.java Fri Jun 07 14:15:38 2013 +0200 @@ -22,6 +22,8 @@ */ package com.oracle.graal.phases.common; +import static com.oracle.graal.phases.GraalOptions.*; + import java.util.*; import java.util.Map.Entry; @@ -220,7 +222,7 @@ private static void processBlock(Block block, SchedulePhase schedule, int implicitNullCheckLimit) { List nodes = schedule.nodesFor(block); - if (GraalOptions.OptImplicitNullChecks && implicitNullCheckLimit > 0) { + if (OptImplicitNullChecks.getValue() && implicitNullCheckLimit > 0) { new UseImplicitNullChecks(implicitNullCheckLimit).processNodes(nodes, block.getBeginNode()); } new LowerGuards(block).processNodes(nodes, block.getBeginNode()); diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/IncrementalCanonicalizerPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/IncrementalCanonicalizerPhase.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/IncrementalCanonicalizerPhase.java Fri Jun 07 14:15:38 2013 +0200 @@ -43,6 +43,6 @@ protected void run(StructuredGraph graph, C context) { int mark = graph.getMark(); super.run(graph, context); - new CanonicalizerPhase.Instance(context.getRuntime(), context.getAssumptions(), mark, customCanonicalizer).apply(graph); + new CanonicalizerPhase.Instance(context.getRuntime(), context.getAssumptions(), GraalOptions.OptCanonicalizeReads.getValue(), mark, customCanonicalizer).apply(graph); } } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningPhase.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningPhase.java Fri Jun 07 14:15:38 2013 +0200 @@ -22,6 +22,8 @@ */ package com.oracle.graal.phases.common; +import static com.oracle.graal.phases.GraalOptions.*; + import java.util.*; import java.util.concurrent.*; @@ -33,6 +35,7 @@ import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; import com.oracle.graal.nodes.util.*; +import com.oracle.graal.options.*; import com.oracle.graal.phases.*; import com.oracle.graal.phases.PhasePlan.PhasePosition; import com.oracle.graal.phases.common.CanonicalizerPhase.CustomCanonicalizer; @@ -45,6 +48,11 @@ public class InliningPhase extends Phase { + // @formatter:off + @Option(help = "Unconditionally inline intrinsics") + public static final OptionValue AlwaysInlineIntrinsics = new OptionValue<>(false); + // @formatter:on + private final PhasePlan plan; private final MetaAccessProvider runtime; private final Assumptions compilationAssumptions; @@ -184,9 +192,9 @@ metricInliningRuns.increment(); Debug.dump(callerGraph, "after %s", callee); - if (GraalOptions.OptCanonicalizer) { + if (OptCanonicalizer.getValue()) { int markBeforeCanonicalization = callerGraph.getMark(); - new CanonicalizerPhase.Instance(runtime, callerAssumptions, invokeUsages, markBeforeInlining, customCanonicalizer).apply(callerGraph); + new CanonicalizerPhase.Instance(runtime, callerAssumptions, OptCanonicalizeReads.getValue(), invokeUsages, markBeforeInlining, customCanonicalizer).apply(callerGraph); // process invokes that are possibly created during canonicalization for (Node newNode : callerGraph.getNewNodes(markBeforeCanonicalization)) { @@ -257,7 +265,7 @@ callerHasMoreInformationAboutArguments = true; } else { Stamp joinedStamp = localNode.stamp().join(arg.stamp()); - if (!joinedStamp.equals(localNode.stamp())) { + if (joinedStamp != null && !joinedStamp.equals(localNode.stamp())) { localNode.setStamp(joinedStamp); callerHasMoreInformationAboutArguments = true; } @@ -270,8 +278,8 @@ // probability to check the inlining } - if (GraalOptions.OptCanonicalizer) { - new CanonicalizerPhase.Instance(runtime, assumptions).apply(newGraph); + if (OptCanonicalizer.getValue()) { + new CanonicalizerPhase.Instance(runtime, assumptions, OptCanonicalizeReads.getValue()).apply(newGraph); } return newGraph; @@ -280,7 +288,7 @@ } private StructuredGraph getCachedGraph(ResolvedJavaMethod method) { - if (GraalOptions.CacheGraphs && cache != null) { + if (CacheGraphs.getValue() && cache != null) { StructuredGraph cachedGraph = cache.get(method); if (cachedGraph != null) { return cachedGraph; @@ -297,14 +305,14 @@ new DeadCodeEliminationPhase().apply(newGraph); - if (GraalOptions.OptCanonicalizer) { - new CanonicalizerPhase.Instance(runtime, assumptions).apply(newGraph); + if (OptCanonicalizer.getValue()) { + new CanonicalizerPhase.Instance(runtime, assumptions, OptCanonicalizeReads.getValue()).apply(newGraph); } - if (GraalOptions.CullFrameStates) { + if (CullFrameStates.getValue()) { new CullFrameStatesPhase().apply(newGraph); } - if (GraalOptions.CacheGraphs && cache != null) { + if (CacheGraphs.getValue() && cache != null) { cache.put(newGraph.copy()); } return newGraph; @@ -330,7 +338,7 @@ } protected double computeMaximumSize(double relevance, int configuredMaximum) { - double inlineRatio = Math.min(GraalOptions.RelevanceCapForInlining, relevance); + double inlineRatio = Math.min(RelevanceCapForInlining.getValue(), relevance); return configuredMaximum * inlineRatio; } @@ -342,7 +350,7 @@ } protected boolean isIntrinsic(InlineInfo info) { - if (GraalOptions.AlwaysInlineIntrinsics) { + if (AlwaysInlineIntrinsics.getValue()) { return onlyIntrinsics(info); } else { return onlyForcedIntrinsics(info); @@ -412,7 +420,7 @@ } public boolean continueInlining(StructuredGraph currentGraph) { - if (currentGraph.getNodeCount() >= GraalOptions.MaximumDesiredSize) { + if (currentGraph.getNodeCount() >= MaximumDesiredSize.getValue()) { InliningUtil.logInliningDecision("inlining is cut off by MaximumDesiredSize"); metricInliningStoppedByMaxDesiredSize.increment(); return false; @@ -429,33 +437,34 @@ double inliningBonus = getInliningBonus(info); int lowLevelGraphSize = previousLowLevelGraphSize(info); - if (GraalOptions.SmallCompiledLowLevelGraphSize > 0 && lowLevelGraphSize > GraalOptions.SmallCompiledLowLevelGraphSize * inliningBonus) { + if (SmallCompiledLowLevelGraphSize.getValue() > 0 && lowLevelGraphSize > SmallCompiledLowLevelGraphSize.getValue() * inliningBonus) { return InliningUtil.logNotInlinedMethod(info, inliningDepth, "too large previous low-level graph: %d", lowLevelGraphSize); } + int nodes = determineNodeCount(info); + if (nodes < TrivialInliningSize.getValue() * inliningBonus) { + return InliningUtil.logInlinedMethod(info, inliningDepth, fullyProcessed, "trivial (nodes=%d)", nodes); + } + /* * TODO (chaeubl): invoked methods that are on important paths but not yet compiled -> * will be compiled anyways and it is likely that we are the only caller... might be * useful to inline those methods but increases bootstrap time (maybe those methods are * also getting queued in the compilation queue concurrently) */ - - int nodes = determineNodeCount(info); - if (nodes < GraalOptions.TrivialInliningSize * inliningBonus) { - return InliningUtil.logInlinedMethod(info, inliningDepth, fullyProcessed, "trivial (nodes=%d)", nodes); + double invokes = determineInvokeProbability(info); + if (LimitInlinedInvokes.getValue() > 0 && fullyProcessed && invokes > LimitInlinedInvokes.getValue() * inliningBonus) { + return InliningUtil.logNotInlinedMethod(info, inliningDepth, "callee invoke probability is too high (%f)", invokes); } - double invokes = determineInvokeProbability(info); - if (GraalOptions.LimitInlinedInvokes > 0 && fullyProcessed && invokes > GraalOptions.LimitInlinedInvokes * inliningBonus) { - return InliningUtil.logNotInlinedMethod(info, inliningDepth, "invoke probability is too high (%f)", invokes); + double maximumNodes = computeMaximumSize(relevance, (int) (MaximumInliningSize.getValue() * inliningBonus)); + if (nodes <= maximumNodes) { + return InliningUtil.logInlinedMethod(info, inliningDepth, fullyProcessed, "relevance-based (relevance=%f, probability=%f, bonus=%f, nodes=%d <= max=%f)", relevance, probability, + inliningBonus, nodes, maximumNodes); } - double maximumNodes = computeMaximumSize(relevance, (int) (GraalOptions.MaximumInliningSize * inliningBonus)); - if (nodes < maximumNodes) { - return InliningUtil.logInlinedMethod(info, inliningDepth, fullyProcessed, "relevance-based (relevance=%f, nodes=%d)", relevance, nodes); - } - - return InliningUtil.logNotInlinedMethod(info, inliningDepth, "(relevance=%f, probability=%f, bonus=%f)", relevance, probability, inliningBonus); + return InliningUtil.logNotInlinedMethod(info, inliningDepth, "relevance-based (relevance=%f, probability=%f, bonus=%f, nodes=%d > max=%f)", relevance, probability, inliningBonus, nodes, + maximumNodes); } } @@ -786,7 +795,7 @@ } public double invokeRelevance(Invoke invoke) { - return Math.min(GraalOptions.CapInheritedRelevance, relevance) * nodeRelevance.get(invoke.asNode()); + return Math.min(CapInheritedRelevance.getValue(), relevance) * nodeRelevance.get(invoke.asNode()); } } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java Fri Jun 07 14:15:38 2013 +0200 @@ -22,6 +22,8 @@ */ package com.oracle.graal.phases.common; +import static com.oracle.graal.phases.GraalOptions.*; + import java.lang.reflect.*; import java.util.*; import java.util.concurrent.*; @@ -128,7 +130,7 @@ * Print a HotSpot-style inlining message to the console. */ private static void printInlining(final ResolvedJavaMethod method, final Invoke invoke, final int inliningDepth, final boolean success, final String msg, final Object... args) { - if (GraalOptions.HotSpotPrintInlining) { + if (HotSpotPrintInlining.getValue()) { final int mod = method.getModifiers(); // 1234567 TTY.print(" "); // print timestamp @@ -698,7 +700,7 @@ replacementNodes.add(null); } - if (GraalOptions.OptTailDuplication) { + if (OptTailDuplication.getValue()) { /* * We might want to perform tail duplication at the merge after a type switch, if * there are invokes that would benefit from the improvement in type information. @@ -1059,20 +1061,29 @@ holder = receiverType; if (receiverStamp.isExactType()) { assert targetMethod.getDeclaringClass().isAssignableFrom(holder) : holder + " subtype of " + targetMethod.getDeclaringClass() + " for " + targetMethod; - return getExactInlineInfo(data, invoke, replacements, optimisticOpts, holder.resolveMethod(targetMethod)); + ResolvedJavaMethod resolvedMethod = holder.resolveMethod(targetMethod); + if (resolvedMethod != null) { + return getExactInlineInfo(data, invoke, replacements, optimisticOpts, resolvedMethod); + } } } } if (holder.isArray()) { // arrays can be treated as Objects - return getExactInlineInfo(data, invoke, replacements, optimisticOpts, holder.resolveMethod(targetMethod)); + ResolvedJavaMethod resolvedMethod = holder.resolveMethod(targetMethod); + if (resolvedMethod != null) { + return getExactInlineInfo(data, invoke, replacements, optimisticOpts, resolvedMethod); + } } if (assumptions.useOptimisticAssumptions()) { ResolvedJavaType uniqueSubtype = holder.findUniqueConcreteSubtype(); if (uniqueSubtype != null) { - return getAssumptionInlineInfo(data, invoke, replacements, optimisticOpts, uniqueSubtype.resolveMethod(targetMethod), new Assumptions.ConcreteSubtype(holder, uniqueSubtype)); + ResolvedJavaMethod resolvedMethod = uniqueSubtype.resolveMethod(targetMethod); + if (resolvedMethod != null) { + return getAssumptionInlineInfo(data, invoke, replacements, optimisticOpts, resolvedMethod, new Assumptions.ConcreteSubtype(holder, uniqueSubtype)); + } } ResolvedJavaMethod concrete = holder.findUniqueConcreteMethod(targetMethod); @@ -1148,6 +1159,9 @@ ArrayList concreteMethodsProbabilities = new ArrayList<>(); for (int i = 0; i < ptypes.length; i++) { ResolvedJavaMethod concrete = ptypes[i].getType().resolveMethod(targetMethod); + if (concrete == null) { + return logNotInlinedMethodAndReturnNull(invoke, data.inliningDepth(), targetMethod, "could not resolve method"); + } int index = concreteMethods.indexOf(concrete); double curProbability = ptypes[i].getProbability(); if (index < 0) { @@ -1168,7 +1182,7 @@ ArrayList newConcreteMethods = new ArrayList<>(); ArrayList newConcreteMethodsProbabilities = new ArrayList<>(); for (int i = 0; i < concreteMethods.size(); ++i) { - if (concreteMethodsProbabilities.get(i) >= GraalOptions.MegamorphicInliningMinMethodProbability) { + if (concreteMethodsProbabilities.get(i) >= GraalOptions.MegamorphicInliningMinMethodProbability.getValue()) { newConcreteMethods.add(concreteMethods.get(i)); newConcreteMethodsProbabilities.add(concreteMethodsProbabilities.get(i)); } @@ -1241,7 +1255,7 @@ private static boolean checkTargetConditions(InliningData data, Replacements replacements, Invoke invoke, ResolvedJavaMethod method, OptimisticOptimizations optimisticOpts) { if (method == null) { return logNotInlinedMethodAndReturnFalse(invoke, data.inliningDepth(), method, "the method is not resolved"); - } else if (Modifier.isNative(method.getModifiers()) && (!GraalOptions.Intrinsify || !InliningUtil.canIntrinsify(replacements, method))) { + } else if (Modifier.isNative(method.getModifiers()) && (!GraalOptions.Intrinsify.getValue() || !InliningUtil.canIntrinsify(replacements, method))) { return logNotInlinedMethodAndReturnFalse(invoke, data.inliningDepth(), method, "it is a non-intrinsic native method"); } else if (Modifier.isAbstract(method.getModifiers())) { return logNotInlinedMethodAndReturnFalse(invoke, data.inliningDepth(), method, "it is an abstract method"); @@ -1249,7 +1263,7 @@ return logNotInlinedMethodAndReturnFalse(invoke, data.inliningDepth(), method, "the method's class is not initialized"); } else if (!method.canBeInlined()) { return logNotInlinedMethodAndReturnFalse(invoke, data.inliningDepth(), method, "it is marked non-inlinable"); - } else if (data.countRecursiveInlining(method) > GraalOptions.MaximumRecursiveInlining) { + } else if (data.countRecursiveInlining(method) > MaximumRecursiveInlining.getValue()) { return logNotInlinedMethodAndReturnFalse(invoke, data.inliningDepth(), method, "it exceeds the maximum recursive inlining depth"); } else if (new OptimisticOptimizations(method).lessOptimisticThan(optimisticOpts)) { return logNotInlinedMethodAndReturnFalse(invoke, data.inliningDepth(), method, "the callee uses less optimistic optimizations than caller"); @@ -1283,6 +1297,10 @@ FrameState stateAfter = invoke.stateAfter(); assert stateAfter == null || stateAfter.isAlive(); + GuardingNode receiverNullCheckNode = null; + if (receiverNullCheck) { + receiverNullCheckNode = receiverNullCheck(invoke); + } IdentityHashMap replacements = new IdentityHashMap<>(); ArrayList nodes = new ArrayList<>(); @@ -1294,7 +1312,18 @@ if (node == entryPointNode || node == entryPointNode.stateAfter()) { // Do nothing. } else if (node instanceof LocalNode) { - replacements.put(node, parameters.get(((LocalNode) node).index())); + int localIndex = ((LocalNode) node).index(); + ValueNode parameter = parameters.get(localIndex); + if (receiverNullCheckNode != null && localIndex == 0) { + Stamp piStamp = parameter.stamp(); + if (piStamp instanceof ObjectStamp) { + piStamp = piStamp.join(StampFactory.objectNonNull()); + } + PiNode piReceiver = graph.add(new PiNode(parameter, piStamp)); + piReceiver.setGuard(receiverNullCheckNode); + parameter = piReceiver; + } + replacements.put(node, parameter); } else { nodes.add(node); if (node instanceof ReturnNode) { @@ -1314,9 +1343,6 @@ Map duplicates = graph.addDuplicates(nodes, replacements); FixedNode firstCFGNodeDuplicate = (FixedNode) duplicates.get(firstCFGNode); - if (receiverNullCheck) { - receiverNullCheck(invoke); - } invoke.asNode().replaceAtPredecessor(firstCFGNodeDuplicate); FrameState stateAtExceptionEdge = null; @@ -1422,15 +1448,17 @@ return true; } - public static void receiverNullCheck(Invoke invoke) { + public static GuardingNode receiverNullCheck(Invoke invoke) { MethodCallTargetNode callTarget = (MethodCallTargetNode) invoke.callTarget(); StructuredGraph graph = callTarget.graph(); NodeInputList parameters = callTarget.arguments(); ValueNode firstParam = parameters.size() <= 0 ? null : parameters.get(0); if (!callTarget.isStatic() && firstParam.kind() == Kind.Object && !firstParam.objectStamp().nonNull()) { - graph.addBeforeFixed(invoke.asNode(), - graph.add(new FixedGuardNode(graph.unique(new IsNullNode(firstParam)), DeoptimizationReason.NullCheckException, DeoptimizationAction.InvalidateReprofile, true))); + FixedGuardNode guard = graph.add(new FixedGuardNode(graph.unique(new IsNullNode(firstParam)), DeoptimizationReason.NullCheckException, DeoptimizationAction.InvalidateReprofile, true)); + graph.addBeforeFixed(invoke.asNode(), guard); + return guard; } + return null; } public static boolean canIntrinsify(Replacements replacements, ResolvedJavaMethod target) { diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InsertStateAfterPlaceholderPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InsertStateAfterPlaceholderPhase.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InsertStateAfterPlaceholderPhase.java Fri Jun 07 14:15:38 2013 +0200 @@ -48,6 +48,9 @@ @Override public ValueNode canonical(CanonicalizerTool tool) { + if (!usages().isEmpty()) { + return this; + } if (stateAfter() == null) { return null; } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/IterativeConditionalEliminationPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/IterativeConditionalEliminationPhase.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/IterativeConditionalEliminationPhase.java Fri Jun 07 14:15:38 2013 +0200 @@ -44,7 +44,7 @@ if (canonicalizationRoots.isEmpty()) { break; } - new CanonicalizerPhase.Instance(context.getRuntime(), context.getAssumptions(), canonicalizationRoots, null).apply(graph); + new CanonicalizerPhase.Instance(context.getRuntime(), context.getAssumptions(), GraalOptions.OptCanonicalizeReads.getValue(), canonicalizationRoots, null).apply(graph); canonicalizationRoots.clear(); } } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoweringPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoweringPhase.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoweringPhase.java Fri Jun 07 14:15:38 2013 +0200 @@ -22,6 +22,8 @@ */ package com.oracle.graal.phases.common; +import static com.oracle.graal.phases.GraalOptions.*; + import java.util.*; import com.oracle.graal.api.code.*; @@ -69,6 +71,11 @@ } @Override + public LoweringType getLoweringType() { + return loweringType; + } + + @Override public GuardingNode createNullCheckGuard(GuardedNode guardedNode, ValueNode object) { if (object.objectStamp().nonNull()) { // Short cut creation of null check guard if the object is known to be non-null. @@ -95,7 +102,7 @@ if (loweringType == LoweringType.AFTER_GUARDS) { throw new GraalInternalError("Cannot create guards in after-guard lowering"); } - if (GraalOptions.OptEliminateGuards) { + if (OptEliminateGuards.getValue()) { for (Node usage : condition.usages()) { if (!activeGuards.isNew(usage) && activeGuards.isMarked(usage) && ((GuardNode) usage).negated() == negated) { return (GuardNode) usage; @@ -103,7 +110,7 @@ } } GuardNode newGuard = guardAnchor.asNode().graph().unique(new GuardNode(condition, guardAnchor, deoptReason, action, negated)); - if (GraalOptions.OptEliminateGuards) { + if (OptEliminateGuards.getValue()) { activeGuards.grow(); activeGuards.mark(newGuard); } @@ -203,7 +210,7 @@ } } - if (parentAnchor == null && GraalOptions.OptEliminateGuards) { + if (parentAnchor == null && OptEliminateGuards.getValue()) { for (GuardNode guard : anchor.asNode().usages().filter(GuardNode.class)) { activeGuards.clear(guard); } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/SafepointInsertionPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/SafepointInsertionPhase.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/SafepointInsertionPhase.java Fri Jun 07 14:15:38 2013 +0200 @@ -22,6 +22,8 @@ */ package com.oracle.graal.phases.common; +import static com.oracle.graal.phases.GraalOptions.*; + import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.java.*; import com.oracle.graal.phases.*; @@ -33,7 +35,7 @@ @Override protected void run(StructuredGraph graph) { - if (GraalOptions.GenLoopSafepoints) { + if (GenLoopSafepoints.getValue()) { for (LoopEndNode loopEndNode : graph.getNodes(LoopEndNode.class)) { if (!loopEndNode.canSafepoint()) { continue; @@ -43,8 +45,8 @@ } } - if (GraalOptions.GenSafepoints) { - if (!GraalOptions.OptEliminateSafepoints || graph.getNodes(MethodCallTargetNode.class).isNotEmpty()) { + if (GenSafepoints.getValue()) { + if (!OptEliminateSafepoints.getValue() || graph.getNodes(MethodCallTargetNode.class).isNotEmpty()) { for (ReturnNode returnNode : graph.getNodes(ReturnNode.class)) { SafepointNode safepoint = graph.add(new SafepointNode()); graph.addBeforeFixed(returnNode, safepoint); diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/TailDuplicationPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/TailDuplicationPhase.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/TailDuplicationPhase.java Fri Jun 07 14:15:38 2013 +0200 @@ -22,6 +22,8 @@ */ package com.oracle.graal.phases.common; +import static com.oracle.graal.phases.GraalOptions.*; + import java.util.*; import com.oracle.graal.debug.*; @@ -80,7 +82,7 @@ public static final TailDuplicationDecision DEFAULT_DECISION = new TailDuplicationDecision() { public boolean doTransform(MergeNode merge, int fixedNodeCount) { - if (fixedNodeCount < GraalOptions.TailDuplicationTrivialSize) { + if (fixedNodeCount < TailDuplicationTrivialSize.getValue()) { return true; } HashSet improvements = new HashSet<>(); @@ -136,7 +138,7 @@ // A snapshot is taken here, so that new MergeNode instances aren't considered for tail // duplication. for (MergeNode merge : graph.getNodes(MergeNode.class).snapshot()) { - if (!(merge instanceof LoopBeginNode) && nodeProbabilities.get(merge) >= GraalOptions.TailDuplicationProbability) { + if (!(merge instanceof LoopBeginNode) && nodeProbabilities.get(merge) >= TailDuplicationProbability.getValue()) { tailDuplicate(merge, DEFAULT_DECISION, null, phaseContext); } } @@ -298,7 +300,7 @@ phi.setMerge(mergeAfter); } } - new CanonicalizerPhase(null, graph.getNewNodes(startMark)).apply(graph, phaseContext); + new CanonicalizerPhase.Instance(phaseContext.getRuntime(), phaseContext.getAssumptions(), GraalOptions.OptCanonicalizeReads.getValue(), graph.getNewNodes(startMark), null).apply(graph); Debug.dump(graph, "After tail duplication at %s", merge); } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java Fri Jun 07 14:15:38 2013 +0200 @@ -22,239 +22,330 @@ */ package com.oracle.graal.phases; +import com.oracle.graal.options.*; + /** * This class encapsulates options that control the behavior of the Graal compiler. - * - * (thomaswue) WARNING: Fields of this class are treated as final by Graal. */ // @formatter:off public final class GraalOptions { - // Checkstyle: stop - private static final boolean ____ = false; - // Checkstyle: resume - - public static int Threads; - static { - Threads = Runtime.getRuntime().availableProcessors(); - } - - public static String CompilerConfiguration = "basic"; - public static String GraalRuntime = "basic"; + @Option(help = "Enable use of compiler intrinsics") + public static final OptionValue Intrinsify = new OptionValue<>(true); + @Option(help = "Enable inlining of monomorphic calls") + static final OptionValue InlineMonomorphicCalls = new OptionValue<>(true); + @Option(help = "Enable inlining of polymorphic calls") + static final OptionValue InlinePolymorphicCalls = new OptionValue<>(true); + @Option(help = "Enable inlining of megamorphic calls") + static final OptionValue InlineMegamorphicCalls = new OptionValue<>(true); + @Option(help = "") + public static final OptionValue MegamorphicInliningMinMethodProbability = new OptionValue<>(0.33D); + @Option(help = "") + public static final OptionValue MaximumDesiredSize = new OptionValue<>(5000); + @Option(help = "") + public static final OptionValue MaximumRecursiveInlining = new OptionValue<>(1); // inlining settings - public static boolean Inline = true; - public static boolean AlwaysInlineIntrinsics = ____; - public static boolean Intrinsify = true; - static boolean InlineMonomorphicCalls = true; - static boolean InlinePolymorphicCalls = true; - static boolean InlineMegamorphicCalls = true; - public static double MegamorphicInliningMinMethodProbability = 0.33; - public static int MaximumDesiredSize = 5000; - public static int MaximumRecursiveInlining = 1; - public static float BoostInliningForEscapeAnalysis = 2f; - public static float RelevanceCapForInlining = 1f; - public static float CapInheritedRelevance = 1f; - public static boolean IterativeInlining = ____; + @Option(help = "") + public static final OptionValue BoostInliningForEscapeAnalysis = new OptionValue<>(2f); + @Option(help = "") + public static final OptionValue RelevanceCapForInlining = new OptionValue<>(1f); + @Option(help = "") + public static final OptionValue CapInheritedRelevance = new OptionValue<>(1f); + @Option(help = "") + public static final OptionValue IterativeInlining = new OptionValue<>(false); - public static int TrivialInliningSize = 10; - public static int MaximumInliningSize = 300; - public static int SmallCompiledLowLevelGraphSize = 300; - public static double LimitInlinedInvokes = 5.0; + @Option(help = "") + public static final OptionValue TrivialInliningSize = new OptionValue<>(10); + @Option(help = "") + public static final OptionValue MaximumInliningSize = new OptionValue<>(300); + @Option(help = "") + public static final OptionValue SmallCompiledLowLevelGraphSize = new OptionValue<>(300); + @Option(help = "") + public static final OptionValue LimitInlinedInvokes = new OptionValue<>(5.0); // escape analysis settings - public static boolean PartialEscapeAnalysis = true; - public static boolean EscapeAnalysisHistogram = ____; - public static int EscapeAnalysisIterations = 2; - public static String EscapeAnalyzeOnly = null; - public static int MaximumEscapeAnalysisArrayLength = 32; - public static boolean PEAInliningHints = ____; + @Option(help = "") + public static final OptionValue PartialEscapeAnalysis = new OptionValue<>(true); + @Option(help = "") + public static final OptionValue EscapeAnalysisHistogram = new OptionValue<>(false); + @Option(help = "") + public static final OptionValue EscapeAnalysisIterations = new OptionValue<>(2); + @Option(help = "") + public static final OptionValue EscapeAnalyzeOnly = new OptionValue<>(null); + @Option(help = "") + public static final OptionValue MaximumEscapeAnalysisArrayLength = new OptionValue<>(32); + @Option(help = "") + public static final OptionValue PEAInliningHints = new OptionValue<>(false); - public static double TailDuplicationProbability = 0.5; - public static int TailDuplicationTrivialSize = 1; + @Option(help = "") + public static final OptionValue TailDuplicationProbability = new OptionValue<>(0.5); + @Option(help = "") + public static final OptionValue TailDuplicationTrivialSize = new OptionValue<>(1); // profiling information - public static int DeoptsToDisableOptimisticOptimization = 40; - public static int MatureExecutionsBranch = 1; - public static int MatureExecutionsPerSwitchCase = 1; - public static int MatureExecutionsTypeProfile = 1; + @Option(help = "") + public static final OptionValue DeoptsToDisableOptimisticOptimization = new OptionValue<>(40); + @Option(help = "") + public static final OptionValue MatureExecutionsBranch = new OptionValue<>(1); + @Option(help = "") + public static final OptionValue MatureExecutionsPerSwitchCase = new OptionValue<>(1); + @Option(help = "") + public static final OptionValue MatureExecutionsTypeProfile = new OptionValue<>(1); // comilation queue - public static int TimedBootstrap = -1; - public static boolean PriorityCompileQueue = true; - public static int SlowQueueCutoff = 100000; - public static boolean SlowCompileThreads = ____; - public static boolean DynamicCompilePriority = ____; - public static String CompileTheWorld = null; - public static int CompileTheWorldStartAt = 1; - public static int CompileTheWorldStopAt = Integer.MAX_VALUE; + @Option(help = "") + public static final OptionValue DynamicCompilePriority = new OptionValue<>(false); + @Option(help = "") + public static final OptionValue CompileTheWorld = new OptionValue<>(null); + @Option(help = "") + public static final OptionValue CompileTheWorldStartAt = new OptionValue<>(1); + @Option(help = "") + public static final OptionValue CompileTheWorldStopAt = new OptionValue<>(Integer.MAX_VALUE); // graph caching - public static boolean CacheGraphs = true; - public static int GraphCacheSize = 1000; - public static boolean PrintGraphCache = ____; + @Option(help = "") + public static final OptionValue CacheGraphs = new OptionValue<>(true); + @Option(help = "") + public static final OptionValue GraphCacheSize = new OptionValue<>(1000); + @Option(help = "") + public static final OptionValue PrintGraphCache = new OptionValue<>(false); //loop transform settings TODO (gd) tune - public static boolean LoopPeeling = true; - public static boolean ReassociateInvariants = true; - public static boolean FullUnroll = true; - public static boolean LoopUnswitch = true; - public static int FullUnrollMaxNodes = 300; - public static int ExactFullUnrollMaxNodes = 1200; - public static float MinimumPeelProbability = 0.35f; - public static int LoopMaxUnswitch = 3; - public static int LoopUnswitchMaxIncrease = 50; - public static int LoopUnswitchUncertaintyBoost = 5; - public static boolean UseLoopLimitChecks = true; + @Option(help = "") + public static final OptionValue LoopPeeling = new OptionValue<>(true); + @Option(help = "") + public static final OptionValue ReassociateInvariants = new OptionValue<>(true); + @Option(help = "") + public static final OptionValue FullUnroll = new OptionValue<>(true); + @Option(help = "") + public static final OptionValue LoopUnswitch = new OptionValue<>(true); + @Option(help = "") + public static final OptionValue FullUnrollMaxNodes = new OptionValue<>(300); + @Option(help = "") + public static final OptionValue ExactFullUnrollMaxNodes = new OptionValue<>(1200); + @Option(help = "") + public static final OptionValue MinimumPeelProbability = new OptionValue<>(0.35f); + @Option(help = "") + public static final OptionValue LoopMaxUnswitch = new OptionValue<>(3); + @Option(help = "") + public static final OptionValue LoopUnswitchMaxIncrease = new OptionValue<>(50); + @Option(help = "") + public static final OptionValue LoopUnswitchUncertaintyBoost = new OptionValue<>(5); + @Option(help = "") + public static final OptionValue UseLoopLimitChecks = new OptionValue<>(true); // debugging settings - public static boolean ZapStackOnMethodEntry = ____; - public static boolean DeoptALot = ____; - public static boolean VerifyPhases = false; + @Option(help = "") + public static final OptionValue ZapStackOnMethodEntry = new OptionValue<>(false); + @Option(help = "") + public static final OptionValue DeoptALot = new OptionValue<>(false); + @Option(help = "") + public static final OptionValue VerifyPhases = new OptionValue<>(false); - public static String PrintFilter = null; + @Option(help = "") + public static final OptionValue PrintFilter = new OptionValue<>(null); // Debug settings: - public static boolean Debug = true; - public static boolean DebugReplacements = ____; - public static boolean BootstrapReplacements = ____; - public static boolean PerThreadDebugValues = ____; - public static boolean SummarizeDebugValues = ____; - public static boolean SummarizePerPhase = ____; - public static String Dump = null; - public static String Meter = null; - public static String Time = null; - public static String Log = null; - public static String LogFile = null; - public static String MethodFilter = null; - public static boolean DumpOnError = ____; - public static boolean GenericDynamicCounters = ____; - public static String BenchmarkDynamicCounters = null; + @Option(help = "") + public static final OptionValue BootstrapReplacements = new OptionValue<>(false); // Ideal graph visualizer output settings - public static boolean PrintBinaryGraphs = true; - public static boolean PrintCFG = ____; - public static boolean PrintIdealGraphFile = ____; - public static String PrintIdealGraphAddress = "127.0.0.1"; - public static int PrintIdealGraphPort = 4444; - public static int PrintBinaryGraphPort = 4445; + @Option(help = "") + public static final OptionValue PrintBinaryGraphs = new OptionValue<>(true); + @Option(help = "") + public static final OptionValue PrintCFG = new OptionValue<>(false); + @Option(help = "") + public static final OptionValue PrintIdealGraphFile = new OptionValue<>(false); + @Option(help = "") + public static final OptionValue PrintIdealGraphAddress = new OptionValue<>("127.0.0.1"); + @Option(help = "") + public static final OptionValue PrintIdealGraphPort = new OptionValue<>(4444); + @Option(help = "") + public static final OptionValue PrintBinaryGraphPort = new OptionValue<>(4445); // Other printing settings - public static boolean PrintQueue = ____; - public static boolean PrintCompilation = ____; - public static boolean PrintProfilingInformation = ____; - public static boolean PrintIRWithLIR = ____; - public static boolean PrintCodeBytes = ____; - public static boolean PrintBailout = ____; - public static int TraceLinearScanLevel = 0; - public static int TraceLIRGeneratorLevel = 0; - public static boolean TraceEscapeAnalysis = ____; - public static int TraceBytecodeParserLevel = 0; - public static boolean ExitVMOnBailout = ____; - public static boolean ExitVMOnException = true; + @Option(help = "") + public static final OptionValue PrintCompilation = new OptionValue<>(false); + @Option(help = "") + public static final OptionValue PrintProfilingInformation = new OptionValue<>(false); + @Option(help = "") + public static final OptionValue PrintIRWithLIR = new OptionValue<>(false); + @Option(help = "") + public static final OptionValue PrintCodeBytes = new OptionValue<>(false); + @Option(help = "") + public static final OptionValue PrintBailout = new OptionValue<>(false); + @Option(help = "") + public static final OptionValue TraceLinearScanLevel = new OptionValue<>(0); + @Option(help = "") + public static final OptionValue TraceLIRGeneratorLevel = new OptionValue<>(0); + @Option(help = "") + public static final OptionValue TraceEscapeAnalysis = new OptionValue<>(false); + @Option(help = "") + public static final OptionValue TraceBytecodeParserLevel = new OptionValue<>(0); + @Option(help = "") + public static final OptionValue ExitVMOnBailout = new OptionValue<>(false); + @Option(help = "") + public static final OptionValue ExitVMOnException = new OptionValue<>(true); + @Option(help = "") + public static final OptionValue PrintStackTraceOnException = new OptionValue<>(false); // HotSpot command line options - public static boolean HotSpotPrintCompilation = ____; - public static boolean HotSpotPrintInlining = ____; + @Option(help = "") + public static final OptionValue HotSpotPrintCompilation = new OptionValue<>(false); + @Option(help = "") + public static final OptionValue HotSpotPrintInlining = new OptionValue<>(false); // Register allocator debugging - public static String RegisterPressure = null; + @Option(help = "") + public static final OptionValue RegisterPressure = new OptionValue<>(null); // Code generator settings - public static boolean ConditionalElimination = true; - public static boolean CullFrameStates = ____; - public static boolean UseProfilingInformation = true; - static boolean RemoveNeverExecutedCode = true; - static boolean UseExceptionProbability = true; - static boolean UseExceptionProbabilityForOperations = true; - public static boolean OmitHotExceptionStacktrace = ____; - public static boolean GenSafepoints = true; - public static boolean GenLoopSafepoints = true; - static boolean UseTypeCheckHints = true; - public static boolean InlineVTableStubs = true; - public static boolean AlwaysInlineVTableStubs = ____; - public static boolean GenAssertionCode = ____; - public static boolean AlignCallsForPatching = true; - public static boolean ResolveClassBeforeStaticInvoke = ____; - public static boolean CanOmitFrame = true; - public static int SafepointPollOffset = 256; + @Option(help = "") + public static final OptionValue ConditionalElimination = new OptionValue<>(true); + @Option(help = "") + public static final OptionValue CullFrameStates = new OptionValue<>(false); + @Option(help = "") + public static final OptionValue UseProfilingInformation = new OptionValue<>(true); + @Option(help = "") + static final OptionValue RemoveNeverExecutedCode = new OptionValue<>(true); + @Option(help = "") + static final OptionValue UseExceptionProbability = new OptionValue<>(true); + @Option(help = "") + static final OptionValue UseExceptionProbabilityForOperations = new OptionValue<>(true); + @Option(help = "") + public static final OptionValue OmitHotExceptionStacktrace = new OptionValue<>(false); + @Option(help = "") + public static final OptionValue GenSafepoints = new OptionValue<>(true); + @Option(help = "") + public static final OptionValue GenLoopSafepoints = new OptionValue<>(true); + @Option(help = "") + static final OptionValue UseTypeCheckHints = new OptionValue<>(true); + @Option(help = "") + public static final OptionValue InlineVTableStubs = new OptionValue<>(true); + @Option(help = "") + public static final OptionValue AlwaysInlineVTableStubs = new OptionValue<>(false); + @Option(help = "") + public static final OptionValue GenAssertionCode = new OptionValue<>(false); + @Option(help = "") + public static final OptionValue AlignCallsForPatching = new OptionValue<>(true); + @Option(help = "") + public static final OptionValue ResolveClassBeforeStaticInvoke = new OptionValue<>(false); + @Option(help = "") + public static final OptionValue CanOmitFrame = new OptionValue<>(true); + @Option(help = "") + public static final OptionValue SafepointPollOffset = new OptionValue<>(256); - public static boolean MemoryAwareScheduling = true; + @Option(help = "") + public static final OptionValue MemoryAwareScheduling = new OptionValue<>(true); // Translating tableswitch instructions - public static int MinimumJumpTableSize = 5; - public static int RangeTestsSwitchDensity = 5; - public static double MinTableSwitchDensity = 0.5; - - public static boolean DetailedAsserts = ____; + @Option(help = "") + public static final OptionValue MinimumJumpTableSize = new OptionValue<>(5); + @Option(help = "") + public static final OptionValue RangeTestsSwitchDensity = new OptionValue<>(5); + @Option(help = "") + public static final OptionValue MinTableSwitchDensity = new OptionValue<>(0.5); // Runtime settings - public static int StackShadowPages = 2; + @Option(help = "") + public static final OptionValue StackShadowPages = new OptionValue<>(2); - public static boolean SupportJsrBytecodes = true; + @Option(help = "") + public static final OptionValue SupportJsrBytecodes = new OptionValue<>(true); - public static boolean OptAssumptions = true; - public static boolean OptConvertDeoptsToGuards = true; - public static boolean OptReadElimination = true; - public static boolean OptEarlyReadElimination = true; - public static boolean OptCanonicalizer = true; - public static boolean OptScheduleOutOfLoops = true; - public static boolean OptEliminateGuards = true; - public static boolean OptEliminateSafepoints = true; - public static boolean OptImplicitNullChecks = true; - public static boolean OptLivenessAnalysis = true; - public static boolean OptLoopTransform = true; - public static boolean OptFloatingReads = true; - public static boolean OptTailDuplication = true; - public static boolean OptEliminatePartiallyRedundantGuards = true; - public static boolean OptFilterProfiledTypes = true; - public static boolean OptDevirtualizeInvokesOptimistically = true; - public static boolean OptPushThroughPi = true; - + @Option(help = "") + public static final OptionValue OptAssumptions = new OptionValue<>(true); + @Option(help = "") + public static final OptionValue OptConvertDeoptsToGuards = new OptionValue<>(true); + @Option(help = "") + public static final OptionValue OptReadElimination = new OptionValue<>(true); + @Option(help = "") + public static final OptionValue OptEarlyReadElimination = new OptionValue<>(true); + @Option(help = "") + public static final OptionValue OptCanonicalizer = new OptionValue<>(true); + @Option(help = "") + public static final OptionValue OptCanonicalizeReads = new OptionValue<>(true); + @Option(help = "") + public static final OptionValue OptScheduleOutOfLoops = new OptionValue<>(true); + @Option(help = "") + public static final OptionValue OptEliminateGuards = new OptionValue<>(true); + @Option(help = "") + public static final OptionValue OptEliminateSafepoints = new OptionValue<>(true); + @Option(help = "") + public static final OptionValue OptImplicitNullChecks = new OptionValue<>(true); + @Option(help = "") + public static final OptionValue OptLivenessAnalysis = new OptionValue<>(true); + @Option(help = "") + public static final OptionValue OptLoopTransform = new OptionValue<>(true); + @Option(help = "") + public static final OptionValue OptFloatingReads = new OptionValue<>(true); + @Option(help = "") + public static final OptionValue OptTailDuplication = new OptionValue<>(true); + @Option(help = "") + public static final OptionValue OptEliminatePartiallyRedundantGuards = new OptionValue<>(true); + @Option(help = "") + public static final OptionValue OptFilterProfiledTypes = new OptionValue<>(true); + @Option(help = "") + public static final OptionValue OptDevirtualizeInvokesOptimistically = new OptionValue<>(true); + @Option(help = "") + public static final OptionValue OptPushThroughPi = new OptionValue<>(true); // Intrinsification settings - public static boolean IntrinsifyObjectClone = ____; - public static boolean IntrinsifyArrayCopy = true; - public static boolean IntrinsifyObjectMethods = true; - public static boolean IntrinsifySystemMethods = true; - public static boolean IntrinsifyClassMethods = true; - public static boolean IntrinsifyThreadMethods = true; - public static boolean IntrinsifyUnsafeMethods = true; - public static boolean IntrinsifyMathMethods = true; - public static boolean IntrinsifyAESMethods = true; - public static boolean IntrinsifyReflectionMethods = true; - public static boolean IntrinsifyInstalledCodeMethods = true; - public static boolean IntrinsifyCallSiteTarget = true; + @Option(help = "") + public static final OptionValue IntrinsifyObjectClone = new OptionValue<>(false); + @Option(help = "") + public static final OptionValue IntrinsifyArrayCopy = new OptionValue<>(true); + @Option(help = "") + public static final OptionValue IntrinsifyObjectMethods = new OptionValue<>(true); + @Option(help = "") + public static final OptionValue IntrinsifySystemMethods = new OptionValue<>(true); + @Option(help = "") + public static final OptionValue IntrinsifyClassMethods = new OptionValue<>(true); + @Option(help = "") + public static final OptionValue IntrinsifyThreadMethods = new OptionValue<>(true); + @Option(help = "") + public static final OptionValue IntrinsifyUnsafeMethods = new OptionValue<>(true); + @Option(help = "") + public static final OptionValue IntrinsifyMathMethods = new OptionValue<>(true); + @Option(help = "") + public static final OptionValue IntrinsifyAESMethods = new OptionValue<>(true); + @Option(help = "") + public static final OptionValue IntrinsifyReflectionMethods = new OptionValue<>(true); + @Option(help = "") + public static final OptionValue IntrinsifyInstalledCodeMethods = new OptionValue<>(true); + @Option(help = "") + public static final OptionValue IntrinsifyCallSiteTarget = new OptionValue<>(true); /** * Counts the various paths taken through snippets. */ - public static boolean SnippetCounters = false; + @Option(help = "") + public static final OptionValue SnippetCounters = new OptionValue<>(false); /** * If the probability that a checkcast will hit one the profiled types (up to {@link #CheckcastMaxHints}) * is below this value, the checkcast will be compiled without hints. */ - public static double CheckcastMinHintHitProbability = 0.5; + @Option(help = "") + public static final OptionValue CheckcastMinHintHitProbability = new OptionValue<>(0.5); /** * The maximum number of hint types that will be used when compiling a checkcast for which * profiling information is available. Note that {@link #CheckcastMinHintHitProbability} * also influences whether hints are used. */ - public static int CheckcastMaxHints = 2; + @Option(help = "") + public static final OptionValue CheckcastMaxHints = new OptionValue<>(2); /** * @see #CheckcastMinHintHitProbability */ - public static double InstanceOfMinHintHitProbability = 0.5; + @Option(help = "") + public static final OptionValue InstanceOfMinHintHitProbability = new OptionValue<>(0.5); /** * @see #CheckcastMaxHints */ - public static int InstanceOfMaxHints = 2; - - static { - // turn detailed assertions on when the general assertions are on (misusing the assert keyword for this) - assert (DetailedAsserts = true) == true; - } + @Option(help = "") + public static final OptionValue InstanceOfMaxHints = new OptionValue<>(2); } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.phases/src/com/oracle/graal/phases/OptimisticOptimizations.java --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/OptimisticOptimizations.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/OptimisticOptimizations.java Fri Jun 07 14:15:38 2013 +0200 @@ -79,39 +79,39 @@ } public boolean removeNeverExecutedCode() { - return GraalOptions.RemoveNeverExecutedCode && enabledOpts.contains(Optimization.RemoveNeverExecutedCode); + return GraalOptions.RemoveNeverExecutedCode.getValue() && enabledOpts.contains(Optimization.RemoveNeverExecutedCode); } public boolean useTypeCheckHints() { - return GraalOptions.UseTypeCheckHints && enabledOpts.contains(Optimization.UseTypeCheckHints); + return GraalOptions.UseTypeCheckHints.getValue() && enabledOpts.contains(Optimization.UseTypeCheckHints); } public boolean inlineMonomorphicCalls() { - return GraalOptions.InlineMonomorphicCalls && enabledOpts.contains(Optimization.UseTypeCheckedInlining); + return GraalOptions.InlineMonomorphicCalls.getValue() && enabledOpts.contains(Optimization.UseTypeCheckedInlining); } public boolean inlinePolymorphicCalls() { - return GraalOptions.InlinePolymorphicCalls && enabledOpts.contains(Optimization.UseTypeCheckedInlining); + return GraalOptions.InlinePolymorphicCalls.getValue() && enabledOpts.contains(Optimization.UseTypeCheckedInlining); } public boolean inlineMegamorphicCalls() { - return GraalOptions.InlineMegamorphicCalls && enabledOpts.contains(Optimization.UseTypeCheckedInlining); + return GraalOptions.InlineMegamorphicCalls.getValue() && enabledOpts.contains(Optimization.UseTypeCheckedInlining); } public boolean devirtualizeInvokes() { - return GraalOptions.OptDevirtualizeInvokesOptimistically && enabledOpts.contains(Optimization.UseTypeCheckedInlining); + return GraalOptions.OptDevirtualizeInvokesOptimistically.getValue() && enabledOpts.contains(Optimization.UseTypeCheckedInlining); } public boolean useExceptionProbability() { - return GraalOptions.UseExceptionProbability && enabledOpts.contains(Optimization.UseExceptionProbability); + return GraalOptions.UseExceptionProbability.getValue() && enabledOpts.contains(Optimization.UseExceptionProbability); } public boolean useExceptionProbabilityForOperations() { - return GraalOptions.UseExceptionProbabilityForOperations && enabledOpts.contains(Optimization.UseExceptionProbabilityForOperations); + return GraalOptions.UseExceptionProbabilityForOperations.getValue() && enabledOpts.contains(Optimization.UseExceptionProbabilityForOperations); } public boolean useLoopLimitChecks() { - return GraalOptions.UseLoopLimitChecks && enabledOpts.contains(Optimization.UseLoopLimitChecks); + return GraalOptions.UseLoopLimitChecks.getValue() && enabledOpts.contains(Optimization.UseLoopLimitChecks); } public boolean lessOptimisticThan(OptimisticOptimizations other) { @@ -124,6 +124,6 @@ } private static boolean checkDeoptimizations(ProfilingInfo profilingInfo, DeoptimizationReason reason) { - return profilingInfo.getDeoptimizationCount(reason) < GraalOptions.DeoptsToDisableOptimisticOptimization; + return profilingInfo.getDeoptimizationCount(reason) < GraalOptions.DeoptsToDisableOptimisticOptimization.getValue(); } } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.phases/src/com/oracle/graal/phases/VerifyPhase.java --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/VerifyPhase.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/VerifyPhase.java Fri Jun 07 14:15:38 2013 +0200 @@ -24,6 +24,12 @@ import com.oracle.graal.nodes.*; +/*** + * This phase serves as a verification, in order to check the graph for certain properties. The + * {@link #verify(StructuredGraph)} method will be used as an assertion, and implements the actual + * check. Instead of returning false, it is also valid to throw an {@link AssertionError} in the + * implemented {@link #verify(StructuredGraph)} method. + */ public abstract class VerifyPhase extends Phase { @Override diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/ReentrantBlockIterator.java --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/ReentrantBlockIterator.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/ReentrantBlockIterator.java Fri Jun 07 14:15:38 2013 +0200 @@ -37,6 +37,8 @@ public abstract static class BlockIteratorClosure { + protected abstract StateT getInitialState(); + protected abstract StateT processBlock(Block block, StateT currentState); protected abstract StateT merge(Block merge, List states); @@ -70,7 +72,11 @@ return info; } - public static IdentityHashMap apply(BlockIteratorClosure closure, Block start, StateT initialState, Set boundary) { + public static void apply(BlockIteratorClosure closure, Block start) { + apply(closure, start, closure.getInitialState(), null); + } + + private static IdentityHashMap apply(BlockIteratorClosure closure, Block start, StateT initialState, Set boundary) { Deque blockQueue = new ArrayDeque<>(); /* * States are stored on EndNodes before merges, and on BeginNodes after ControlSplitNodes. diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java Fri Jun 07 14:15:38 2013 +0200 @@ -22,8 +22,12 @@ */ package com.oracle.graal.phases.schedule; +import static com.oracle.graal.api.meta.LocationIdentity.*; +import static com.oracle.graal.phases.GraalOptions.*; + import java.util.*; +import com.oracle.graal.api.meta.*; import com.oracle.graal.debug.*; import com.oracle.graal.graph.*; import com.oracle.graal.graph.Node.Verbosity; @@ -31,7 +35,6 @@ import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.cfg.*; import com.oracle.graal.nodes.extended.*; -import com.oracle.graal.nodes.extended.LocationNode.LocationIdentity; import com.oracle.graal.nodes.virtual.*; import com.oracle.graal.phases.*; import com.oracle.graal.phases.graph.*; @@ -84,6 +87,11 @@ private class MemoryScheduleClosure extends BlockIteratorClosure> { @Override + protected HashSet getInitialState() { + return new HashSet<>(); + } + + @Override protected HashSet processBlock(Block block, HashSet currentState) { for (Node node : getBlockToNodesMap().get(block)) { if (node instanceof FloatingReadNode) { @@ -93,7 +101,7 @@ for (Iterator iter = currentState.iterator(); iter.hasNext();) { FloatingReadNode read = iter.next(); FixedNode fixed = (FixedNode) node; - if (identity == LocationNode.ANY_LOCATION || read.location().getLocationIdentity() == identity) { + if (identity == ANY_LOCATION || read.location().getLocationIdentity() == identity) { addPhantomReference(read, fixed); iter.remove(); } @@ -165,7 +173,7 @@ private final SchedulingStrategy selectedStrategy; public SchedulePhase() { - this(GraalOptions.OptScheduleOutOfLoops ? SchedulingStrategy.LATEST_OUT_OF_LOOPS : SchedulingStrategy.LATEST); + this(OptScheduleOutOfLoops.getValue() ? SchedulingStrategy.LATEST_OUT_OF_LOOPS : SchedulingStrategy.LATEST); } public SchedulePhase(SchedulingStrategy strategy) { @@ -178,13 +186,13 @@ earliestCache = graph.createNodeMap(); blockToNodesMap = new BlockMap<>(cfg); - if (GraalOptions.MemoryAwareScheduling && selectedStrategy != SchedulingStrategy.EARLIEST && graph.getNodes(FloatingReadNode.class).isNotEmpty()) { + if (MemoryAwareScheduling.getValue() && selectedStrategy != SchedulingStrategy.EARLIEST && graph.getNodes(FloatingReadNode.class).isNotEmpty()) { assignBlockToNodes(graph, SchedulingStrategy.EARLIEST); sortNodesWithinBlocks(graph, SchedulingStrategy.EARLIEST); MemoryScheduleClosure closure = new MemoryScheduleClosure(); - ReentrantBlockIterator.apply(closure, getCFG().getStartBlock(), new HashSet(), null); + ReentrantBlockIterator.apply(closure, getCFG().getStartBlock()); cfg.clearNodeToBlock(); blockToNodesMap = new BlockMap<>(cfg); diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/HighTierContext.java diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/LowTierContext.java diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/MidTierContext.java diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/PhaseContext.java diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/Suites.java --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/Suites.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/Suites.java Fri Jun 07 14:15:38 2013 +0200 @@ -25,10 +25,16 @@ import java.util.*; import com.oracle.graal.graph.*; +import com.oracle.graal.options.*; import com.oracle.graal.phases.*; public final class Suites { + // @formatter:off + @Option(help = "The compiler configuration to use") + private static final OptionValue CompilerConfiguration = new OptionValue<>("basic"); + // @formatter:on + public static final Suites DEFAULT; private final PhaseSuite highTier; @@ -69,7 +75,7 @@ } public static Suites createDefaultSuites() { - return createSuites(GraalOptions.CompilerConfiguration); + return createSuites(CompilerConfiguration.getValue()); } public static Suites createSuites(String name) { diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.phases/src/com/oracle/graal/phases/verify/VerifyUsageWithEquals.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/verify/VerifyUsageWithEquals.java Fri Jun 07 14:15:38 2013 +0200 @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.phases.verify; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.calc.*; +import com.oracle.graal.nodes.type.*; +import com.oracle.graal.phases.*; + +/** + * For certain types object identity should not be used for object equality check. This phase checks + * the correct usage of the given type. Equality checks with == or != (except null checks) results + * in an {@link AssertionError}. + */ +public class VerifyUsageWithEquals extends VerifyPhase { + + private MetaAccessProvider runtime; + private Class klass; + + public VerifyUsageWithEquals(MetaAccessProvider runtime, Class klass) { + this.runtime = runtime; + this.klass = klass; + } + + private boolean isAssignableType(ValueNode node) { + if (node.stamp() instanceof ObjectStamp) { + ResolvedJavaType valueType = runtime.lookupJavaType(klass); + ResolvedJavaType nodeType = node.objectStamp().type(); + + if (nodeType != null && valueType.isAssignableFrom(nodeType)) { + return true; + } + } + return false; + } + + private static boolean isNullConstant(ValueNode node) { + return node.isConstant() && node.asConstant().isNull(); + } + + private boolean checkUsage(ValueNode x, ValueNode y) { + return isAssignableType(x) && !isNullConstant(y); + } + + private static boolean isEqualsMethod(StructuredGraph graph) { + Signature signature = graph.method().getSignature(); + return graph.method().getName().equals("equals") && signature.getParameterCount(false) == 1 && signature.getParameterKind(0).equals(Kind.Object); + } + + @Override + protected boolean verify(StructuredGraph graph) { + for (ObjectEqualsNode cn : graph.getNodes().filter(ObjectEqualsNode.class)) { + if (!isEqualsMethod(graph)) { + // bail out if we compare an object of type klass with == or != (except null checks) + assert !(checkUsage(cn.x(), cn.y()) && checkUsage(cn.y(), cn.x())) : "Verifcation of " + klass.getName() + " usage failed: Comparing " + cn.x() + " and" + cn.y() + " in " + + graph.method() + " must use .equals() for object equality, not '==' or '!='"; + } + } + return true; + } +} diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.phases/src/com/oracle/graal/phases/verify/VerifyValueUsage.java --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/verify/VerifyValueUsage.java Fri Jun 07 13:43:13 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.phases.verify; - -import com.oracle.graal.api.meta.*; -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.calc.*; -import com.oracle.graal.nodes.type.*; -import com.oracle.graal.phases.*; - -public class VerifyValueUsage extends VerifyPhase { - - private MetaAccessProvider runtime; - - public VerifyValueUsage(MetaAccessProvider runtime) { - this.runtime = runtime; - } - - private boolean checkType(ValueNode node) { - if (node.stamp() instanceof ObjectStamp) { - ResolvedJavaType valueType = runtime.lookupJavaType(Value.class); - ResolvedJavaType nodeType = node.objectStamp().type(); - - if (valueType.isAssignableFrom(nodeType)) { - return true; - } - } - return false; - } - - @Override - protected boolean verify(StructuredGraph graph) { - for (ObjectEqualsNode cn : graph.getNodes().filter(ObjectEqualsNode.class)) { - Signature signature = graph.method().getSignature(); - if (!(graph.method().getName().equals("equals") && signature.getParameterCount(false) == 1 && signature.getParameterKind(0).equals(Kind.Object))) { - assert !((checkType(cn.x()) && !(cn.y() instanceof ConstantNode)) || (checkType(cn.y()) && !(cn.x() instanceof ConstantNode))) : "VerifyValueUsage: " + cn.x() + " or " + cn.y() + - " in " + graph.method() + " uses object identity. Should use equals() instead."; - } - } - return true; - } -} diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.printer/src/com/oracle/graal/printer/DebugEnvironment.java --- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/DebugEnvironment.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/DebugEnvironment.java Fri Jun 07 14:15:38 2013 +0200 @@ -22,12 +22,14 @@ */ package com.oracle.graal.printer; +import static com.oracle.graal.compiler.GraalDebugConfig.*; +import static com.oracle.graal.phases.GraalOptions.*; + import java.io.*; import java.util.*; import com.oracle.graal.compiler.*; import com.oracle.graal.debug.*; -import com.oracle.graal.phases.*; public class DebugEnvironment { @@ -35,13 +37,13 @@ Debug.enable(); List dumpHandlers = new ArrayList<>(); dumpHandlers.add(new GraphPrinterDumpHandler()); - if (GraalOptions.PrintCFG) { - if (GraalOptions.PrintBinaryGraphs) { + if (PrintCFG.getValue()) { + if (PrintBinaryGraphs.getValue()) { TTY.println("CFG dumping slows down PrintBinaryGraphs: use -G:-PrintCFG to disable it"); } dumpHandlers.add(new CFGPrinterObserver()); } - GraalDebugConfig hotspotDebugConfig = new GraalDebugConfig(GraalOptions.Log, GraalOptions.Meter, GraalOptions.Time, GraalOptions.Dump, GraalOptions.MethodFilter, log, dumpHandlers); + GraalDebugConfig hotspotDebugConfig = new GraalDebugConfig(Log.getValue(), Meter.getValue(), Time.getValue(), Dump.getValue(), MethodFilter.getValue(), log, dumpHandlers); Debug.setConfig(hotspotDebugConfig); } } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.printer/src/com/oracle/graal/printer/GraphPrinterDumpHandler.java --- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/GraphPrinterDumpHandler.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/GraphPrinterDumpHandler.java Fri Jun 07 14:15:38 2013 +0200 @@ -22,6 +22,8 @@ */ package com.oracle.graal.printer; +import static com.oracle.graal.phases.GraalOptions.*; + import java.io.*; import java.net.*; import java.nio.channels.*; @@ -33,7 +35,6 @@ import com.oracle.graal.compiler.*; import com.oracle.graal.debug.*; import com.oracle.graal.graph.*; -import com.oracle.graal.phases.*; import com.oracle.graal.phases.schedule.*; /** @@ -60,7 +61,7 @@ return; } previousInlineContext.clear(); - if (GraalOptions.PrintIdealGraphFile) { + if (PrintIdealGraphFile.getValue()) { initializeFilePrinter(); } else { initializeNetworkPrinter(); @@ -75,7 +76,7 @@ private void initializeFilePrinter() { String ext; - if (GraalOptions.PrintBinaryGraphs) { + if (PrintBinaryGraphs.getValue()) { ext = ".bgv"; } else { ext = ".gv.xml"; @@ -91,7 +92,7 @@ num = "-" + Integer.toString(++i); } try { - if (GraalOptions.PrintBinaryGraphs) { + if (PrintBinaryGraphs.getValue()) { printer = new BinaryGraphPrinter(FileChannel.open(file.toPath(), StandardOpenOption.WRITE, StandardOpenOption.CREATE_NEW)); } else { printer = new IdealGraphPrinter(new FileOutputStream(file)); @@ -105,10 +106,10 @@ } private void initializeNetworkPrinter() { - String host = GraalOptions.PrintIdealGraphAddress; - int port = GraalOptions.PrintBinaryGraphs ? GraalOptions.PrintBinaryGraphPort : GraalOptions.PrintIdealGraphPort; + String host = PrintIdealGraphAddress.getValue(); + int port = PrintBinaryGraphs.getValue() ? PrintBinaryGraphPort.getValue() : PrintIdealGraphPort.getValue(); try { - if (GraalOptions.PrintBinaryGraphs) { + if (PrintBinaryGraphs.getValue()) { printer = new BinaryGraphPrinter(SocketChannel.open(new InetSocketAddress(host, port))); } else { IdealGraphPrinter xmlPrinter = new IdealGraphPrinter(new Socket(host, port).getOutputStream()); diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/CompiledExceptionHandlerTest.java --- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/CompiledExceptionHandlerTest.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/CompiledExceptionHandlerTest.java Fri Jun 07 14:15:38 2013 +0200 @@ -72,7 +72,7 @@ try { raiseException(message); } catch (Exception e) { - return message; + return message + e.getMessage(); } } return null; diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/MethodSubstitutionTest.java --- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/MethodSubstitutionTest.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/MethodSubstitutionTest.java Fri Jun 07 14:15:38 2013 +0200 @@ -53,7 +53,7 @@ Debug.dump(graph, "Graph"); new InliningPhase(runtime(), null, replacements, assumptions, null, phasePlan, OptimisticOptimizations.ALL).apply(graph); Debug.dump(graph, "Graph"); - new CanonicalizerPhase.Instance(runtime(), assumptions).apply(graph); + new CanonicalizerPhase.Instance(runtime(), assumptions, true).apply(graph); new DeadCodeEliminationPhase().apply(graph); assertNotInGraph(graph, Invoke.class); diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/MonitorTest.java --- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/MonitorTest.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/MonitorTest.java Fri Jun 07 14:15:38 2013 +0200 @@ -33,6 +33,7 @@ public void test0() { test("lockObjectSimple", new Object(), new Object()); test("lockObjectSimple", new Object(), null); + test("lockObjectSimple", null, null); } @Test diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/PointerTest.java --- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/PointerTest.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/PointerTest.java Fri Jun 07 14:15:38 2013 +0200 @@ -33,7 +33,6 @@ import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.extended.*; -import com.oracle.graal.nodes.extended.LocationNode.LocationIdentity; import com.oracle.graal.replacements.*; import com.oracle.graal.replacements.Snippet.*; import com.oracle.graal.word.*; @@ -43,7 +42,7 @@ */ public class PointerTest extends GraalCompilerTest implements Snippets { - private static final LocationIdentity ID = LocationNode.createLocation("ID"); + private static final LocationIdentity ID = new NamedLocationIdentity("ID"); private static final Kind[] KINDS = new Kind[]{Kind.Byte, Kind.Char, Kind.Short, Kind.Int, Kind.Long, Kind.Float, Kind.Double, Kind.Object}; private final TargetDescription target; private final ReplacementsImpl installer; @@ -78,7 +77,7 @@ @Test public void test_read3() { for (Kind kind : KINDS) { - assertRead(parse("read" + kind.name() + "3"), kind, false, LocationNode.ANY_LOCATION); + assertRead(parse("read" + kind.name() + "3"), kind, false, LocationIdentity.ANY_LOCATION); } } @@ -99,7 +98,7 @@ @Test public void test_write3() { for (Kind kind : KINDS) { - assertWrite(parse("write" + kind.name() + "3"), kind, false, LocationNode.ANY_LOCATION); + assertWrite(parse("write" + kind.name() + "3"), kind, false, LocationIdentity.ANY_LOCATION); } } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/BoxingSnippets.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/BoxingSnippets.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/BoxingSnippets.java Fri Jun 07 14:15:38 2013 +0200 @@ -22,6 +22,7 @@ */ package com.oracle.graal.replacements; +import static com.oracle.graal.phases.GraalOptions.*; import static com.oracle.graal.replacements.SnippetTemplate.*; import java.lang.reflect.*; @@ -36,7 +37,6 @@ import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; -import com.oracle.graal.phases.*; import com.oracle.graal.replacements.Snippet.Fold; import com.oracle.graal.replacements.Snippet.SnippetInliningPolicy; import com.oracle.graal.replacements.SnippetTemplate.AbstractTemplates; @@ -237,7 +237,7 @@ } } - private static final SnippetCounter.Group integerCounters = GraalOptions.SnippetCounters ? new SnippetCounter.Group("Integer intrinsifications") : null; + private static final SnippetCounter.Group integerCounters = SnippetCounters.getValue() ? new SnippetCounter.Group("Integer intrinsifications") : null; private static final SnippetCounter valueOfCounter = new SnippetCounter(integerCounters, "valueOf", "valueOf intrinsification"); } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/GraalMethodSubstitutions.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/GraalMethodSubstitutions.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/GraalMethodSubstitutions.java Fri Jun 07 14:15:38 2013 +0200 @@ -22,11 +22,12 @@ */ package com.oracle.graal.replacements; +import static com.oracle.graal.phases.GraalOptions.*; + import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.api.runtime.*; import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.phases.*; /** * Method substitutions that are VM-independent. @@ -39,7 +40,7 @@ replacements.registerSubstitutions(clazz); } - if (GraalOptions.Intrinsify) { + if (Intrinsify.getValue()) { replacements.registerSubstitutions(MathSubstitutionsX86.class); replacements.registerSubstitutions(DoubleSubstitutions.class); replacements.registerSubstitutions(FloatSubstitutions.class); diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationPhase.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationPhase.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationPhase.java Fri Jun 07 14:15:38 2013 +0200 @@ -33,6 +33,7 @@ import com.oracle.graal.graph.Node.ConstantNodeParameter; import com.oracle.graal.graph.Node.NodeIntrinsic; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.PhiNode.PhiType; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.java.*; @@ -284,34 +285,8 @@ if (newInstance instanceof ValueNode && (((ValueNode) newInstance).kind() != Kind.Object || ((ValueNode) newInstance).stamp() == StampFactory.forNodeIntrinsic())) { StructuredGraph graph = (StructuredGraph) newInstance.graph(); for (CheckCastNode checkCastNode : newInstance.usages().filter(CheckCastNode.class).snapshot()) { - for (ProxyNode vpn : checkCastNode.usages().filter(ProxyNode.class).snapshot()) { - graph.replaceFloating(vpn, checkCastNode); - } for (Node checkCastUsage : checkCastNode.usages().snapshot()) { - if (checkCastUsage instanceof ValueAnchorNode) { - ValueAnchorNode valueAnchorNode = (ValueAnchorNode) checkCastUsage; - graph.removeFixed(valueAnchorNode); - } else if (checkCastUsage instanceof UnboxNode) { - UnboxNode unbox = (UnboxNode) checkCastUsage; - unbox.replaceAtUsages(newInstance); - graph.removeFixed(unbox); - } else if (checkCastUsage instanceof MethodCallTargetNode) { - MethodCallTargetNode checkCastCallTarget = (MethodCallTargetNode) checkCastUsage; - assert checkCastCallTarget.targetMethod().getAnnotation(NodeIntrinsic.class) != null : "checkcast at " + sourceLocation(checkCastNode) + - " not used by an unboxing method or node intrinsic, but by a call at " + sourceLocation(checkCastCallTarget.usages().first()) + " to " + - checkCastCallTarget.targetMethod(); - checkCastUsage.replaceFirstInput(checkCastNode, checkCastNode.object()); - } else if (checkCastUsage instanceof FrameState) { - checkCastUsage.replaceFirstInput(checkCastNode, null); - } else if (checkCastUsage instanceof ReturnNode && checkCastNode.object().stamp() == StampFactory.forNodeIntrinsic()) { - checkCastUsage.replaceFirstInput(checkCastNode, checkCastNode.object()); - } else if (checkCastUsage instanceof IsNullNode) { - assert checkCastUsage.usages().count() == 1 && checkCastUsage.usages().first().predecessor() == checkCastNode; - graph.replaceFloating((FloatingNode) checkCastUsage, LogicConstantNode.contradiction(graph)); - } else { - Debug.dump(graph, "exception"); - assert false : sourceLocation(checkCastUsage) + " has unexpected usage " + checkCastUsage + " of checkcast at " + sourceLocation(checkCastNode); - } + checkCheckCastUsage(graph, newInstance, checkCastNode, checkCastUsage); } FixedNode next = checkCastNode.next(); checkCastNode.setNext(null); @@ -320,4 +295,47 @@ } } } + + private static void checkCheckCastUsage(StructuredGraph graph, Node intrinsifiedNode, Node input, Node usage) { + if (usage instanceof ValueAnchorNode) { + ValueAnchorNode valueAnchorNode = (ValueAnchorNode) usage; + valueAnchorNode.removeAnchoredNode((ValueNode) input); + Debug.log("%s: Removed a ValueAnchor input", Debug.contextSnapshot(JavaMethod.class)); + } else if (usage instanceof UnboxNode) { + UnboxNode unbox = (UnboxNode) usage; + unbox.replaceAtUsages(intrinsifiedNode); + graph.removeFixed(unbox); + Debug.log("%s: Removed an UnboxNode", Debug.contextSnapshot(JavaMethod.class)); + } else if (usage instanceof MethodCallTargetNode) { + MethodCallTargetNode checkCastCallTarget = (MethodCallTargetNode) usage; + assert checkCastCallTarget.targetMethod().getAnnotation(NodeIntrinsic.class) != null : "checkcast at " + sourceLocation(input) + + " not used by an unboxing method or node intrinsic, but by a call at " + sourceLocation(checkCastCallTarget.usages().first()) + " to " + checkCastCallTarget.targetMethod(); + usage.replaceFirstInput(input, intrinsifiedNode); + Debug.log("%s: Checkcast used in an other node intrinsic", Debug.contextSnapshot(JavaMethod.class)); + } else if (usage instanceof FrameState) { + usage.replaceFirstInput(input, null); + Debug.log("%s: Checkcast used in a FS", Debug.contextSnapshot(JavaMethod.class)); + } else if (usage instanceof ReturnNode && ((ValueNode) intrinsifiedNode).stamp() == StampFactory.forNodeIntrinsic()) { + usage.replaceFirstInput(input, intrinsifiedNode); + Debug.log("%s: Checkcast used in a return with forNodeIntrinsic stamp", Debug.contextSnapshot(JavaMethod.class)); + } else if (usage instanceof IsNullNode) { + assert usage.usages().count() == 1 && usage.usages().first().predecessor() == input; + graph.replaceFloating((FloatingNode) usage, LogicConstantNode.contradiction(graph)); + Debug.log("%s: Replaced IsNull with false", Debug.contextSnapshot(JavaMethod.class)); + } else if (usage instanceof ProxyNode) { + ProxyNode proxy = (ProxyNode) usage; + assert proxy.type() == PhiType.Value; + ProxyNode newProxy = graph.unique(new ProxyNode((ValueNode) intrinsifiedNode, proxy.proxyPoint(), PhiType.Value, proxy.getIdentity())); + for (Node proxyUsage : usage.usages().snapshot()) { + checkCheckCastUsage(graph, newProxy, proxy, proxyUsage); + } + } else if (usage instanceof PiNode) { + for (Node piUsage : usage.usages().snapshot()) { + checkCheckCastUsage(graph, intrinsifiedNode, usage, piUsage); + } + } else { + Debug.dump(graph, "exception"); + assert false : sourceLocation(usage) + " has unexpected usage " + usage + " of checkcast at " + sourceLocation(input); + } + } } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java Fri Jun 07 14:15:38 2013 +0200 @@ -23,6 +23,7 @@ package com.oracle.graal.replacements; import static com.oracle.graal.api.meta.MetaUtil.*; +import static com.oracle.graal.phases.GraalOptions.*; import java.lang.reflect.*; import java.util.*; @@ -320,9 +321,9 @@ graphBuilder.apply(graph); new WordTypeVerificationPhase(runtime, target.wordKind).apply(graph); - if (GraalOptions.OptCanonicalizer) { + if (OptCanonicalizer.getValue()) { new WordTypeRewriterPhase(runtime, target.wordKind).apply(graph); - new CanonicalizerPhase.Instance(runtime, assumptions).apply(graph); + new CanonicalizerPhase.Instance(runtime, assumptions, true).apply(graph); } return graph; @@ -335,9 +336,9 @@ * @param callee the graph that was inlined into {@code caller} */ protected void afterInline(StructuredGraph caller, StructuredGraph callee) { - if (GraalOptions.OptCanonicalizer) { + if (OptCanonicalizer.getValue()) { new WordTypeRewriterPhase(runtime, target.wordKind).apply(caller); - new CanonicalizerPhase.Instance(runtime, assumptions).apply(caller); + new CanonicalizerPhase.Instance(runtime, assumptions, true).apply(caller); } } @@ -350,8 +351,8 @@ new WordTypeRewriterPhase(runtime, target.wordKind).apply(graph); new DeadCodeEliminationPhase().apply(graph); - if (GraalOptions.OptCanonicalizer) { - new CanonicalizerPhase.Instance(runtime, assumptions).apply(graph); + if (OptCanonicalizer.getValue()) { + new CanonicalizerPhase.Instance(runtime, assumptions, true).apply(graph); } } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java Fri Jun 07 14:15:38 2013 +0200 @@ -34,6 +34,7 @@ import com.oracle.graal.loop.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; +import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -384,7 +385,7 @@ new NodeIntrinsificationPhase(runtime).apply(snippetCopy); new WordTypeRewriterPhase(runtime, target.wordKind).apply(snippetCopy); - new CanonicalizerPhase.Instance(runtime, replacements.getAssumptions(), 0, null).apply(snippetCopy); + new CanonicalizerPhase.Instance(runtime, replacements.getAssumptions(), true, 0, null).apply(snippetCopy); } NodeIntrinsificationVerificationPhase.verify(snippetCopy); @@ -440,8 +441,8 @@ if (loopBegin != null) { LoopEx loop = new LoopsData(snippetCopy).loop(loopBegin); int mark = snippetCopy.getMark(); - LoopTransformations.fullUnroll(loop, runtime, replacements.getAssumptions()); - new CanonicalizerPhase.Instance(runtime, replacements.getAssumptions(), mark, null).apply(snippetCopy); + LoopTransformations.fullUnroll(loop, runtime, replacements.getAssumptions(), true); + new CanonicalizerPhase.Instance(runtime, replacements.getAssumptions(), true, mark, null).apply(snippetCopy); } FixedNode explodeLoopNext = explodeLoop.next(); explodeLoop.clearSuccessors(); @@ -723,10 +724,14 @@ } else { returnValue = (ValueNode) duplicates.get(returnNode.result()); } - assert returnValue != null || replacee.usages().isEmpty(); - replacer.replace(replacee, returnValue); + Node returnDuplicate = duplicates.get(returnNode); + if (returnValue == null && replacee.usages().isNotEmpty() && replacee instanceof MemoryCheckpoint) { + replacer.replace(replacee, (ValueNode) returnDuplicate.predecessor()); + } else { + assert returnValue != null || replacee.usages().isEmpty() : this + " " + returnValue + " " + returnNode + " " + replacee.usages(); + replacer.replace(replacee, returnValue); - Node returnDuplicate = duplicates.get(returnNode); + } if (returnDuplicate.isAlive()) { returnDuplicate.clearInputs(); returnDuplicate.replaceAndDelete(next); diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BranchProbabilityNode.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BranchProbabilityNode.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BranchProbabilityNode.java Fri Jun 07 14:15:38 2013 +0200 @@ -92,6 +92,9 @@ } } if (!couldSet) { + if (isSubstitutionGraph()) { + return this; + } throw new GraalInternalError("Wrong usage of branch probability injection!"); } return condition; @@ -99,6 +102,10 @@ return this; } + private boolean isSubstitutionGraph() { + return usages().count() == 1 && usages().first() instanceof ReturnNode; + } + /** * This intrinsic should only be used for the condition of an if statement. The parameter * condition should also only denote a simple condition and not a combined condition involving diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/DirectObjectStoreNode.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/DirectObjectStoreNode.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/DirectObjectStoreNode.java Fri Jun 07 14:15:38 2013 +0200 @@ -22,9 +22,12 @@ */ package com.oracle.graal.replacements.nodes; +import static com.oracle.graal.api.meta.LocationIdentity.*; + +import com.oracle.graal.api.meta.*; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.HeapAccess.WriteBarrierType; import com.oracle.graal.nodes.extended.*; -import com.oracle.graal.nodes.extended.WriteNode.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; import com.oracle.graal.word.*; @@ -62,8 +65,8 @@ @Override public void lower(LoweringTool tool, LoweringType loweringType) { - IndexedLocationNode location = IndexedLocationNode.create(LocationNode.ANY_LOCATION, value.kind(), displacement, offset, graph(), 1); - WriteNode write = graph().add(new WriteNode(object, value, location, WriteBarrierType.NONE)); + IndexedLocationNode location = IndexedLocationNode.create(ANY_LOCATION, value.kind(), displacement, offset, graph(), 1); + WriteNode write = graph().add(new WriteNode(object, value, location, WriteBarrierType.NONE, value.kind() == Kind.Object)); graph().replaceFixedWithFixed(this, write); } } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.sparc/src/com/oracle/graal/sparc/SPARC.java --- a/graal/com.oracle.graal.sparc/src/com/oracle/graal/sparc/SPARC.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.sparc/src/com/oracle/graal/sparc/SPARC.java Fri Jun 07 14:15:38 2013 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,10 +35,101 @@ */ public class SPARC extends Architecture { - // SPARC: Define registers. + // @formatter:off + + public static final RegisterCategory CPU = new RegisterCategory("CPU"); + public static final RegisterCategory FPU = new RegisterCategory("FPU"); + + // General purpose registers + public static final Register r0 = new Register(0, 0, "r0", CPU); + public static final Register r1 = new Register(1, 1, "r1", CPU); + public static final Register r2 = new Register(2, 2, "r2", CPU); + public static final Register r3 = new Register(3, 3, "r3", CPU); + public static final Register r4 = new Register(4, 4, "r4", CPU); + public static final Register r5 = new Register(5, 5, "r5", CPU); + public static final Register r6 = new Register(6, 6, "r6", CPU); + public static final Register r7 = new Register(7, 7, "r7", CPU); + public static final Register r8 = new Register(8, 8, "r8", CPU); + public static final Register r9 = new Register(9, 9, "r9", CPU); + public static final Register r10 = new Register(10, 10, "r10", CPU); + public static final Register r11 = new Register(11, 11, "r11", CPU); + public static final Register r12 = new Register(12, 12, "r12", CPU); + public static final Register r13 = new Register(13, 13, "r13", CPU); + public static final Register r14 = new Register(14, 14, "r14", CPU); + public static final Register r15 = new Register(15, 15, "r15", CPU); + public static final Register r16 = new Register(16, 16, "r16", CPU); + public static final Register r17 = new Register(17, 17, "r17", CPU); + public static final Register r18 = new Register(18, 18, "r18", CPU); + public static final Register r19 = new Register(19, 19, "r19", CPU); + public static final Register r20 = new Register(20, 20, "r20", CPU); + public static final Register r21 = new Register(21, 21, "r21", CPU); + public static final Register r22 = new Register(22, 22, "r22", CPU); + public static final Register r23 = new Register(23, 23, "r23", CPU); + public static final Register r24 = new Register(24, 24, "r24", CPU); + public static final Register r25 = new Register(25, 25, "r25", CPU); + public static final Register r26 = new Register(26, 26, "r26", CPU); + public static final Register r27 = new Register(27, 27, "r27", CPU); + public static final Register r28 = new Register(28, 28, "r28", CPU); + public static final Register r29 = new Register(29, 29, "r29", CPU); + public static final Register r30 = new Register(30, 30, "r30", CPU); + public static final Register r31 = new Register(31, 31, "r31", CPU); + + public static final Register g0 = r0; + public static final Register g1 = r1; + public static final Register g2 = r2; + public static final Register g3 = r3; + public static final Register g4 = r4; + public static final Register g5 = r5; + public static final Register g6 = r6; + public static final Register g7 = r7; + + public static final Register i0 = r24; + public static final Register i1 = r25; + public static final Register i2 = r26; + public static final Register i3 = r27; + public static final Register i4 = r28; + public static final Register i5 = r29; + public static final Register i6 = r30; + public static final Register i7 = r31; + + public static final Register o0 = r8; + public static final Register o1 = r9; + public static final Register o2 = r10; + public static final Register o3 = r11; + public static final Register o4 = r12; + public static final Register o5 = r13; + public static final Register o6 = r14; + public static final Register o7 = r15; + + public static final Register[] gprRegisters = { + r0, r1, r2, r3, r4, r5, r6, r7, + r8, r9, r10, r11, r12, r13, r14, r15, + r16, r17, r18, r19, r20, r21, r22, r23, + r24, r25, r26, r27, r28, r29, r30, r31 + }; + + // Floating point registers + public static final Register f0 = new Register(32, 0, "f0", FPU); + public static final Register f1 = new Register(33, 1, "f1", FPU); + public static final Register f2 = new Register(34, 2, "f2", FPU); + public static final Register f3 = new Register(35, 3, "f3", FPU); + public static final Register f4 = new Register(36, 4, "f4", FPU); + public static final Register f5 = new Register(37, 5, "f5", FPU); + public static final Register f6 = new Register(38, 6, "f6", FPU); + public static final Register f7 = new Register(39, 7, "f7", FPU); + + public static final Register[] allRegisters = { + // GPR + r0, r1, r2, r3, r4, r5, r6, r7, + r8, r9, r10, r11, r12, r13, r14, r15, + r16, r17, r18, r19, r20, r21, r22, r23, + r24, r25, r26, r27, r28, r29, r30, r31, + // FPU + f0, f1, f2, f3, f4, f5, f6, f7, + }; public SPARC() { - super("SPARC", 8, ByteOrder.LITTLE_ENDIAN, null, LOAD_STORE | STORE_STORE, 1, 0, 8); + super("SPARC", 8, ByteOrder.LITTLE_ENDIAN, allRegisters, LOAD_STORE | STORE_STORE, 1, 0, 8); // SPARC: Fix architecture parameters. } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/BlockState.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/BlockState.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/BlockState.java Fri Jun 07 14:15:38 2013 +0200 @@ -22,8 +22,6 @@ */ package com.oracle.graal.virtual.phases.ea; -import static com.oracle.graal.virtual.phases.ea.PartialEscapeAnalysisPhase.*; - import java.util.*; import com.oracle.graal.api.meta.*; @@ -32,11 +30,11 @@ import com.oracle.graal.nodes.spi.Virtualizable.EscapeState; import com.oracle.graal.nodes.virtual.*; -class BlockState { +public class BlockState { - private final IdentityHashMap objectStates = new IdentityHashMap<>(); - private final IdentityHashMap objectAliases; - private final IdentityHashMap scalarAliases; + protected final IdentityHashMap objectStates = new IdentityHashMap<>(); + protected final IdentityHashMap objectAliases; + protected final IdentityHashMap scalarAliases; final HashMap readCache; static class ReadCacheEntry { @@ -146,6 +144,10 @@ return new BlockState(this); } + public BlockState cloneEmptyState() { + return new BlockState(); + } + public void materializeBefore(FixedNode fixed, VirtualObjectNode virtual, EscapeState state, GraphEffectList materializeEffects) { PartialEscapeClosure.METRIC_MATERIALIZATIONS.increment(); List objects = new ArrayList<>(2); @@ -159,7 +161,7 @@ private void materializeWithCommit(FixedNode fixed, VirtualObjectNode virtual, List objects, List locks, List values, List otherAllocations, EscapeState state) { - trace("materializing %s", virtual); + VirtualUtil.trace("materializing %s", virtual); ObjectState obj = getObjectState(virtual); ValueNode[] entries = obj.getEntries(); @@ -241,34 +243,14 @@ return objectStates + " " + readCache; } - public static BlockState meetAliases(List states) { - BlockState newState = new BlockState(); - - newState.objectAliases.putAll(states.get(0).objectAliases); + public void meetAliases(List states) { + objectAliases.putAll(states.get(0).objectAliases); + scalarAliases.putAll(states.get(0).scalarAliases); for (int i = 1; i < states.size(); i++) { BlockState state = states.get(i); - for (Map.Entry entry : states.get(0).objectAliases.entrySet()) { - if (state.objectAliases.containsKey(entry.getKey())) { - assert state.objectAliases.get(entry.getKey()) == entry.getValue(); - } else { - newState.objectAliases.remove(entry.getKey()); - } - } + meetMaps(objectAliases, state.objectAliases); + meetMaps(scalarAliases, state.scalarAliases); } - - newState.scalarAliases.putAll(states.get(0).scalarAliases); - for (int i = 1; i < states.size(); i++) { - BlockState state = states.get(i); - for (Map.Entry entry : states.get(0).scalarAliases.entrySet()) { - if (state.scalarAliases.containsKey(entry.getKey())) { - assert state.scalarAliases.get(entry.getKey()) == entry.getValue(); - } else { - newState.scalarAliases.remove(entry.getKey()); - } - } - } - - return newState; } public Map getReadCache() { @@ -286,14 +268,14 @@ return objectAliasesEqual && objectStatesEqual && readCacheEqual && scalarAliasesEqual; } - private static boolean compareMaps(Map left, Map right) { + protected static boolean compareMaps(Map left, Map right) { if (left.size() != right.size()) { return false; } return compareMapsNoSize(left, right); } - private static boolean compareMapsNoSize(Map left, Map right) { + protected static boolean compareMapsNoSize(Map left, Map right) { if (left == right) { return true; } @@ -309,4 +291,16 @@ return true; } + protected static void meetMaps(Map target, Map source) { + Iterator> iter = target.entrySet().iterator(); + while (iter.hasNext()) { + Map.Entry entry = iter.next(); + if (source.containsKey(entry.getKey())) { + assert source.get(entry.getKey()) == entry.getValue(); + } else { + iter.remove(); + } + } + } + } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/GraphEffectList.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/GraphEffectList.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/GraphEffectList.java Fri Jun 07 14:15:38 2013 +0200 @@ -215,7 +215,7 @@ FixedNode next = node.next(); node.setNext(null); node.replaceAtPredecessor(next); - obsoleteNodes.add(node); + assert obsoleteNodes.add(node); } }); } @@ -250,7 +250,7 @@ FixedNode next = ((FixedWithNextNode) node).next(); ((FixedWithNextNode) node).setNext(null); node.replaceAtPredecessor(next); - obsoleteNodes.add(node); + assert obsoleteNodes.add(node); } } }); diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/IterativeInliningPhase.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/IterativeInliningPhase.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/IterativeInliningPhase.java Fri Jun 07 14:15:38 2013 +0200 @@ -22,6 +22,8 @@ */ package com.oracle.graal.virtual.phases.ea; +import static com.oracle.graal.phases.GraalOptions.*; + import java.util.*; import java.util.concurrent.*; @@ -40,17 +42,19 @@ private final GraphCache cache; private final OptimisticOptimizations optimisticOpts; private final boolean readElimination; + private final CanonicalizerPhase canonicalizer; - public IterativeInliningPhase(Replacements replacements, GraphCache cache, PhasePlan plan, OptimisticOptimizations optimisticOpts, boolean readElimination) { + public IterativeInliningPhase(Replacements replacements, GraphCache cache, PhasePlan plan, OptimisticOptimizations optimisticOpts, boolean readElimination, CanonicalizerPhase canonicalizer) { this.replacements = replacements; this.cache = cache; this.plan = plan; this.optimisticOpts = optimisticOpts; this.readElimination = readElimination; + this.canonicalizer = canonicalizer; } public static final void trace(String format, Object... obj) { - if (GraalOptions.TraceEscapeAnalysis) { + if (TraceEscapeAnalysis.getValue()) { Debug.log(format, obj); } } @@ -63,17 +67,17 @@ private void runIterations(final StructuredGraph graph, final boolean simple, final HighTierContext context) { Boolean continueIteration = true; - for (int iteration = 0; iteration < GraalOptions.EscapeAnalysisIterations && continueIteration; iteration++) { + for (int iteration = 0; iteration < EscapeAnalysisIterations.getValue() && continueIteration; iteration++) { continueIteration = Debug.scope("iteration " + iteration, new Callable() { @Override public Boolean call() { boolean progress = false; - PartialEscapeAnalysisPhase ea = new PartialEscapeAnalysisPhase(false, readElimination); + PartialEscapeAnalysisPhase ea = new PartialEscapeAnalysisPhase(false, readElimination, canonicalizer); boolean eaResult = ea.runAnalysis(graph, context); progress |= eaResult; - Map hints = GraalOptions.PEAInliningHints ? PartialEscapeAnalysisPhase.getHints(graph) : null; + Map hints = PEAInliningHints.getValue() ? PartialEscapeAnalysisPhase.getHints(graph) : null; InliningPhase inlining = new InliningPhase(context.getRuntime(), hints, replacements, context.getAssumptions(), cache, plan, optimisticOpts); inlining.setMaxMethodsPerInlining(simple ? 1 : Integer.MAX_VALUE); @@ -82,8 +86,8 @@ new DeadCodeEliminationPhase().apply(graph); - if (GraalOptions.ConditionalElimination && GraalOptions.OptCanonicalizer) { - new CanonicalizerPhase().apply(graph, context); + if (ConditionalElimination.getValue() && OptCanonicalizer.getValue()) { + canonicalizer.apply(graph, context); new IterativeConditionalEliminationPhase().apply(graph, context); } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeAnalysisPhase.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeAnalysisPhase.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeAnalysisPhase.java Fri Jun 07 14:15:38 2013 +0200 @@ -22,10 +22,11 @@ */ package com.oracle.graal.virtual.phases.ea; +import static com.oracle.graal.phases.GraalOptions.*; + import java.util.*; import java.util.concurrent.*; -import com.oracle.graal.api.meta.*; import com.oracle.graal.debug.*; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; @@ -35,47 +36,43 @@ import com.oracle.graal.nodes.virtual.*; import com.oracle.graal.phases.*; import com.oracle.graal.phases.common.*; -import com.oracle.graal.phases.common.CanonicalizerPhase.CustomCanonicalizer; import com.oracle.graal.phases.graph.*; import com.oracle.graal.phases.schedule.*; import com.oracle.graal.phases.tiers.*; -public class PartialEscapeAnalysisPhase extends BasePhase { +public class PartialEscapeAnalysisPhase extends BasePhase { + + public abstract static class Closure extends ReentrantBlockIterator.BlockIteratorClosure { - private final CustomCanonicalizer customCanonicalizer; - private final boolean iterative; - private final boolean readElimination; + public abstract boolean hasChanged(); - public PartialEscapeAnalysisPhase(boolean iterative, boolean readElimination) { - this(null, iterative, readElimination); + public abstract void applyEffects(); } - public PartialEscapeAnalysisPhase(CustomCanonicalizer customCanonicalizer, boolean iterative, boolean readElimination) { - this.customCanonicalizer = customCanonicalizer; + private final boolean iterative; + private final boolean readElimination; + private final CanonicalizerPhase canonicalizer; + + public PartialEscapeAnalysisPhase(boolean iterative, boolean readElimination, CanonicalizerPhase canonicalizer) { this.iterative = iterative; this.readElimination = readElimination; - } - - public static final void trace(String format, Object... obj) { - if (GraalOptions.TraceEscapeAnalysis) { - Debug.log(format, obj); - } + this.canonicalizer = canonicalizer; } @Override - protected void run(StructuredGraph graph, HighTierContext context) { + protected void run(StructuredGraph graph, PhaseContext context) { runAnalysis(graph, context); } - public boolean runAnalysis(final StructuredGraph graph, final HighTierContext context) { - if (!matches(graph, GraalOptions.EscapeAnalyzeOnly)) { + public boolean runAnalysis(final StructuredGraph graph, final PhaseContext context) { + if (!VirtualUtil.matches(graph, EscapeAnalyzeOnly.getValue())) { return false; } if (!readElimination) { boolean analyzableNodes = false; for (Node node : graph.getNodes()) { - if (node instanceof VirtualizableRoot) { + if (node instanceof VirtualizableAllocation) { analyzableNodes = true; break; } @@ -87,7 +84,7 @@ boolean continueIteration = true; boolean changed = false; - for (int iteration = 0; iteration < GraalOptions.EscapeAnalysisIterations && continueIteration; iteration++) { + for (int iteration = 0; iteration < EscapeAnalysisIterations.getValue() && continueIteration; iteration++) { boolean currentChanged = Debug.scope("iteration " + iteration, new Callable() { @Override @@ -95,23 +92,22 @@ SchedulePhase schedule = new SchedulePhase(); schedule.apply(graph, false); - PartialEscapeClosure closure = new PartialEscapeClosure(graph.createNodeBitMap(), schedule, context.getRuntime(), context.getAssumptions()); - ReentrantBlockIterator.apply(closure, schedule.getCFG().getStartBlock(), new BlockState(), null); + Closure closure = createAnalysisClosure(context, schedule); + ReentrantBlockIterator.apply(closure, schedule.getCFG().getStartBlock()); if (!closure.hasChanged()) { return false; } // apply the effects collected during the escape analysis iteration - List obsoleteNodes = closure.applyEffects(graph); + closure.applyEffects(); Debug.dump(graph, "after PartialEscapeAnalysis iteration"); - assert noObsoleteNodes(graph, obsoleteNodes); new DeadCodeEliminationPhase().apply(graph); - if (GraalOptions.OptCanonicalizer) { - new CanonicalizerPhase.Instance(context.getRuntime(), context.getAssumptions(), null, customCanonicalizer).apply(graph); + if (OptCanonicalizer.getValue()) { + canonicalizer.apply(graph, context); } return true; @@ -124,85 +120,8 @@ return changed; } - private static boolean matches(StructuredGraph graph, String filter) { - if (filter != null) { - if (filter.startsWith("~")) { - ResolvedJavaMethod method = graph.method(); - return method == null || !MetaUtil.format("%H.%n", method).contains(filter.substring(1)); - } else { - ResolvedJavaMethod method = graph.method(); - return method != null && MetaUtil.format("%H.%n", method).contains(filter); - } - } - return true; - } - - static boolean noObsoleteNodes(StructuredGraph graph, List obsoleteNodes) { - // helper code that determines the paths that keep obsolete nodes alive: - - NodeFlood flood = graph.createNodeFlood(); - IdentityHashMap path = new IdentityHashMap<>(); - flood.add(graph.start()); - for (Node current : flood) { - if (current instanceof AbstractEndNode) { - AbstractEndNode end = (AbstractEndNode) current; - flood.add(end.merge()); - if (!path.containsKey(end.merge())) { - path.put(end.merge(), end); - } - } else { - for (Node successor : current.successors()) { - flood.add(successor); - if (!path.containsKey(successor)) { - path.put(successor, current); - } - } - } - } - - for (Node node : obsoleteNodes) { - if (node instanceof FixedNode) { - assert !flood.isMarked(node) : node; - } - } - - for (Node node : graph.getNodes()) { - if (node instanceof LocalNode) { - flood.add(node); - } - if (flood.isMarked(node)) { - for (Node input : node.inputs()) { - flood.add(input); - if (!path.containsKey(input)) { - path.put(input, node); - } - } - } - } - for (Node current : flood) { - for (Node input : current.inputs()) { - flood.add(input); - if (!path.containsKey(input)) { - path.put(input, current); - } - } - } - boolean success = true; - for (Node node : obsoleteNodes) { - if (flood.isMarked(node)) { - TTY.print("offending node path:"); - Node current = node; - while (current != null) { - TTY.println(current.toString()); - current = path.get(current); - if (current != null && current instanceof FixedNode && !obsoleteNodes.contains(current)) { - break; - } - } - success = false; - } - } - return success; + protected Closure createAnalysisClosure(PhaseContext context, SchedulePhase schedule) { + return new PartialEscapeClosure<>(schedule, context.getRuntime(), context.getAssumptions()); } public static Map getHints(StructuredGraph graph) { diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java Fri Jun 07 14:15:38 2013 +0200 @@ -22,7 +22,8 @@ */ package com.oracle.graal.virtual.phases.ea; -import static com.oracle.graal.virtual.phases.ea.PartialEscapeAnalysisPhase.*; +import static com.oracle.graal.api.meta.LocationIdentity.*; +import static com.oracle.graal.phases.GraalOptions.*; import java.util.*; @@ -34,13 +35,11 @@ import com.oracle.graal.nodes.PhiNode.PhiType; import com.oracle.graal.nodes.VirtualState.NodeClosure; import com.oracle.graal.nodes.cfg.*; -import com.oracle.graal.nodes.extended.LocationNode.LocationIdentity; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.spi.Virtualizable.EscapeState; import com.oracle.graal.nodes.virtual.*; -import com.oracle.graal.phases.*; import com.oracle.graal.phases.graph.*; import com.oracle.graal.phases.graph.ReentrantBlockIterator.BlockIteratorClosure; import com.oracle.graal.phases.graph.ReentrantBlockIterator.LoopInfo; @@ -49,7 +48,7 @@ import com.oracle.graal.virtual.phases.ea.BlockState.ReadCacheEntry; import com.oracle.graal.virtual.phases.ea.EffectList.Effect; -class PartialEscapeClosure extends BlockIteratorClosure { +public class PartialEscapeClosure extends PartialEscapeAnalysisPhase.Closure { public static final DebugMetric METRIC_MATERIALIZATIONS = Debug.metric("Materializations"); public static final DebugMetric METRIC_MATERIALIZATIONS_PHI = Debug.metric("MaterializationsPhi"); @@ -73,8 +72,8 @@ private boolean changed; - public PartialEscapeClosure(NodeBitMap usages, SchedulePhase schedule, MetaAccessProvider metaAccess, Assumptions assumptions) { - this.usages = usages; + public PartialEscapeClosure(SchedulePhase schedule, MetaAccessProvider metaAccess, Assumptions assumptions) { + this.usages = schedule.getCFG().graph.createNodeBitMap(); this.schedule = schedule; this.tool = new VirtualizerToolImpl(usages, metaAccess, assumptions); this.blockEffects = new BlockMap<>(schedule.getCFG()); @@ -83,14 +82,28 @@ } } + @SuppressWarnings("unchecked") + @Override + protected BlockT getInitialState() { + return (BlockT) new BlockState(); + } + + @Override public boolean hasChanged() { return changed; } - public List applyEffects(final StructuredGraph graph) { - final ArrayList obsoleteNodes = new ArrayList<>(); + @Override + public void applyEffects() { + final StructuredGraph graph = schedule.getCFG().graph; + final ArrayList obsoleteNodes = new ArrayList<>(0); BlockIteratorClosure closure = new BlockIteratorClosure() { + @Override + protected Void getInitialState() { + return null; + } + private void apply(GraphEffectList effects, Object context) { if (!effects.isEmpty()) { Debug.log(" ==== effects for %s", context); @@ -126,8 +139,8 @@ return info.exitStates; } }; - ReentrantBlockIterator.apply(closure, schedule.getCFG().getStartBlock(), null, null); - return obsoleteNodes; + ReentrantBlockIterator.apply(closure, schedule.getCFG().getStartBlock()); + assert VirtualUtil.assertNonReachable(graph, obsoleteNodes); } public Map getHints() { @@ -135,11 +148,11 @@ } @Override - protected BlockState processBlock(Block block, BlockState state) { + protected BlockT processBlock(Block block, BlockT state) { GraphEffectList effects = blockEffects.get(block); tool.setEffects(effects); - trace("\nBlock: %s (", block); + VirtualUtil.trace("\nBlock: %s (", block); List nodeList = schedule.getBlockToNodesMap().get(block); FixedWithNextNode lastFixedNode = null; @@ -147,21 +160,21 @@ boolean deleted; boolean isMarked = usages.isMarked(node); if (isMarked || node instanceof VirtualizableRoot) { - trace("[[%s]] ", node); + VirtualUtil.trace("[[%s]] ", node); FixedNode nextFixedNode = lastFixedNode == null ? null : lastFixedNode.next(); deleted = processNode((ValueNode) node, nextFixedNode, state, effects, isMarked); } else { - trace("%s ", node); + VirtualUtil.trace("%s ", node); deleted = false; } - if (GraalOptions.OptEarlyReadElimination) { + if (OptEarlyReadElimination.getValue()) { if (!deleted && node instanceof MemoryCheckpoint) { METRIC_MEMORYCHECKOINT.increment(); MemoryCheckpoint checkpoint = (MemoryCheckpoint) node; for (LocationIdentity identity : checkpoint.getLocationIdentities()) { if (identity instanceof ResolvedJavaField) { state.killReadCache((ResolvedJavaField) identity); - } else if (identity == LocationNode.ANY_LOCATION) { + } else if (identity == ANY_LOCATION) { state.killReadCache(); } } @@ -171,11 +184,11 @@ lastFixedNode = (FixedWithNextNode) node; } } - trace(")\n end state: %s\n", state); + VirtualUtil.trace(")\n end state: %s\n", state); return state; } - private boolean processNode(final ValueNode node, FixedNode insertBefore, final BlockState state, final GraphEffectList effects, boolean isMarked) { + private boolean processNode(final ValueNode node, FixedNode insertBefore, final BlockT state, final GraphEffectList effects, boolean isMarked) { tool.reset(state, node, insertBefore); if (node instanceof Virtualizable) { ((Virtualizable) node).virtualize(tool); @@ -268,7 +281,7 @@ Invoke invoke = ((MethodCallTargetNode) node).invoke(); hints.put(invoke, 5d); } - trace("replacing input %s at %s: %s", input, node, obj); + VirtualUtil.trace("replacing input %s at %s: %s", input, node, obj); replaceWithMaterialized(input, node, insertBefore, state, obj, effects, METRIC_MATERIALIZATIONS_UNHANDLED); } } @@ -293,9 +306,9 @@ } @Override - protected BlockState merge(Block merge, List states) { + protected BlockT merge(Block merge, List states) { assert blockEffects.get(merge).isEmpty(); - MergeProcessor processor = new MergeProcessor(merge, usages, blockEffects); + MergeProcessor processor = new MergeProcessor<>(merge, usages, blockEffects); processor.merge(states); blockEffects.get(merge).addAll(processor.mergeEffects); blockEffects.get(merge).addAll(processor.afterMergeEffects); @@ -303,20 +316,22 @@ } + @SuppressWarnings("unchecked") @Override - protected BlockState cloneState(BlockState oldState) { - return oldState.cloneState(); + protected BlockT cloneState(BlockState oldState) { + return (BlockT) oldState.cloneState(); } + @SuppressWarnings("unchecked") @Override - protected List processLoop(Loop loop, BlockState initialState) { + protected List processLoop(Loop loop, BlockT initialState) { BlockState loopEntryState = initialState; BlockState lastMergedState = initialState; - MergeProcessor mergeProcessor = new MergeProcessor(loop.header, usages, blockEffects); + MergeProcessor mergeProcessor = new MergeProcessor<>(loop.header, usages, blockEffects); for (int iteration = 0; iteration < 10; iteration++) { - LoopInfo info = ReentrantBlockIterator.processLoop(this, loop, lastMergedState.cloneState()); + LoopInfo info = ReentrantBlockIterator.processLoop(this, loop, (BlockT) lastMergedState.cloneState()); - List states = new ArrayList<>(); + List states = new ArrayList<>(); states.add(initialState); states.addAll(info.endStates); mergeProcessor.merge(states); @@ -399,7 +414,7 @@ } } - private static class MergeProcessor { + private static class MergeProcessor { private final Block mergeBlock; private final MergeNode merge; @@ -412,7 +427,7 @@ private final IdentityHashMap valuePhis = new IdentityHashMap<>(); private final IdentityHashMap valueObjectMergePhis = new IdentityHashMap<>(); private final IdentityHashMap valueObjectVirtuals = new IdentityHashMap<>(); - private BlockState newState; + private BlockT newState; public MergeProcessor(Block mergeBlock, NodeBitMap usages, BlockMap blockEffects) { this.usages = usages; @@ -459,8 +474,10 @@ return result; } - private void merge(List states) { - newState = BlockState.meetAliases(states); + @SuppressWarnings("unchecked") + private void merge(List states) { + newState = (BlockT) states.get(0).cloneEmptyState(); + newState.meetAliases(states); /* * Iterative processing: Merging the materialized/virtual state of virtual objects can @@ -521,7 +538,13 @@ for (int i = 1; i < states.size(); i++) { ValueNode[] fields = objStates[i].getEntries(); if (phis[index] == null && values[index] != fields[index]) { - phis[index] = new PhiNode(values[index].kind(), merge); + Kind kind = values[index].kind(); + if (kind == Kind.Illegal) { + // Can happen if one of the values is virtual and is only + // materialized in the following loop. + kind = Kind.Object; + } + phis[index] = new PhiNode(kind, merge); } } } @@ -559,7 +582,7 @@ mergeReadCache(states); } - private boolean processPhi(PhiNode phi, List states) { + private boolean processPhi(PhiNode phi, List states) { assert states.size() == phi.valueCount(); int virtualInputs = 0; boolean materialized = false; @@ -643,7 +666,7 @@ return materialized; } - private void mergeReadCache(List states) { + private void mergeReadCache(List states) { for (Map.Entry entry : states.get(0).readCache.entrySet()) { ReadCacheEntry key = entry.getKey(); ValueNode value = entry.getValue(); @@ -682,7 +705,7 @@ } } - private void mergeReadCachePhi(PhiNode phi, ResolvedJavaField identity, List states) { + private void mergeReadCachePhi(PhiNode phi, ResolvedJavaField identity, List states) { ValueNode[] values = new ValueNode[phi.valueCount()]; for (int i = 0; i < phi.valueCount(); i++) { ValueNode value = states.get(i).getReadCache(phi.valueAt(i), identity); diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/VirtualUtil.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/VirtualUtil.java Fri Jun 07 14:15:38 2013 +0200 @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.virtual.phases.ea; + +import static com.oracle.graal.phases.GraalOptions.*; + +import java.util.*; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.debug.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.nodes.*; + +public final class VirtualUtil { + + private VirtualUtil() { + GraalInternalError.shouldNotReachHere(); + } + + public static boolean assertNonReachable(StructuredGraph graph, List obsoleteNodes) { + // helper code that determines the paths that keep obsolete nodes alive: + + NodeFlood flood = graph.createNodeFlood(); + IdentityHashMap path = new IdentityHashMap<>(); + flood.add(graph.start()); + for (Node current : flood) { + if (current instanceof AbstractEndNode) { + AbstractEndNode end = (AbstractEndNode) current; + flood.add(end.merge()); + if (!path.containsKey(end.merge())) { + path.put(end.merge(), end); + } + } else { + for (Node successor : current.successors()) { + flood.add(successor); + if (!path.containsKey(successor)) { + path.put(successor, current); + } + } + } + } + + for (Node node : obsoleteNodes) { + if (node instanceof FixedNode) { + assert !flood.isMarked(node) : node; + } + } + + for (Node node : graph.getNodes()) { + if (node instanceof LocalNode) { + flood.add(node); + } + if (flood.isMarked(node)) { + for (Node input : node.inputs()) { + flood.add(input); + if (!path.containsKey(input)) { + path.put(input, node); + } + } + } + } + for (Node current : flood) { + for (Node input : current.inputs()) { + flood.add(input); + if (!path.containsKey(input)) { + path.put(input, current); + } + } + } + boolean success = true; + for (Node node : obsoleteNodes) { + if (flood.isMarked(node)) { + TTY.print("offending node path:"); + Node current = node; + while (current != null) { + TTY.println(current.toString()); + current = path.get(current); + if (current != null && current instanceof FixedNode && !obsoleteNodes.contains(current)) { + break; + } + } + success = false; + } + } + return success; + } + + public static void trace(String format, Object... obj) { + if (TraceEscapeAnalysis.getValue()) { + Debug.log(format, obj); + } + } + + static boolean matches(StructuredGraph graph, String filter) { + if (filter != null) { + if (filter.startsWith("~")) { + ResolvedJavaMethod method = graph.method(); + return method == null || !MetaUtil.format("%H.%n", method).contains(filter.substring(1)); + } else { + ResolvedJavaMethod method = graph.method(); + return method != null && MetaUtil.format("%H.%n", method).contains(filter); + } + } + return true; + } + +} diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/VirtualizerToolImpl.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/VirtualizerToolImpl.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/VirtualizerToolImpl.java Fri Jun 07 14:15:38 2013 +0200 @@ -22,7 +22,7 @@ */ package com.oracle.graal.virtual.phases.ea; -import static com.oracle.graal.virtual.phases.ea.PartialEscapeAnalysisPhase.*; +import static com.oracle.graal.phases.GraalOptions.*; import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; @@ -33,7 +33,6 @@ import com.oracle.graal.nodes.spi.Virtualizable.State; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.virtual.*; -import com.oracle.graal.phases.*; class VirtualizerToolImpl implements VirtualizerTool { @@ -91,11 +90,12 @@ if (valueState == null) { obj.setEntry(index, getReplacedValue(value)); } else { - if (valueState.getState() == EscapeState.Virtual) { - obj.setEntry(index, value); - } else { - obj.setEntry(index, valueState.getMaterializedValue()); + ValueNode newValue = value; + if (valueState.getState() != EscapeState.Virtual) { + newValue = valueState.getMaterializedValue(); } + assert obj.getEntry(index) == null || obj.getEntry(index).kind() == newValue.kind(); + obj.setEntry(index, newValue); } } @@ -149,7 +149,7 @@ @Override public void createVirtualObject(VirtualObjectNode virtualObject, ValueNode[] entryState, int[] locks) { - trace("{{%s}} ", current); + VirtualUtil.trace("{{%s}} ", current); if (virtualObject.isAlive()) { state.addAndMarkAlias(virtualObject, virtualObject, usages); } else { @@ -165,7 +165,7 @@ @Override public int getMaximumEntryCount() { - return GraalOptions.MaximumEscapeAnalysisArrayLength; + return MaximumEscapeAnalysisArrayLength.getValue(); } @Override @@ -184,14 +184,14 @@ @Override public void addReadCache(ValueNode object, ResolvedJavaField identity, ValueNode value) { - if (GraalOptions.OptEarlyReadElimination) { + if (OptEarlyReadElimination.getValue()) { state.addReadCache(object, identity, value); } } @Override public ValueNode getReadCache(ValueNode object, ResolvedJavaField identity) { - if (GraalOptions.OptEarlyReadElimination) { + if (OptEarlyReadElimination.getValue()) { return state.getReadCache(object, identity); } return null; @@ -199,7 +199,7 @@ @Override public void killReadCache(ResolvedJavaField identity) { - if (GraalOptions.OptEarlyReadElimination) { + if (OptEarlyReadElimination.getValue()) { state.killReadCache(identity); } } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.word/src/com/oracle/graal/word/Pointer.java --- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/Pointer.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/Pointer.java Fri Jun 07 14:15:38 2013 +0200 @@ -22,8 +22,8 @@ */ package com.oracle.graal.word; +import com.oracle.graal.api.meta.*; import com.oracle.graal.nodes.extended.*; -import com.oracle.graal.nodes.extended.LocationNode.LocationIdentity; public interface Pointer extends Unsigned { diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.word/src/com/oracle/graal/word/Word.java --- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/Word.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/Word.java Fri Jun 07 14:15:38 2013 +0200 @@ -27,10 +27,10 @@ import java.lang.annotation.*; import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; -import com.oracle.graal.nodes.extended.LocationNode.LocationIdentity; public abstract class Word implements Signed, Unsigned, Pointer { diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeRewriterPhase.java --- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeRewriterPhase.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeRewriterPhase.java Fri Jun 07 14:15:38 2013 +0200 @@ -22,15 +22,16 @@ */ package com.oracle.graal.word.phases; +import static com.oracle.graal.api.meta.LocationIdentity.*; + import java.lang.reflect.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.HeapAccess.WriteBarrierType; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.extended.*; -import com.oracle.graal.nodes.extended.LocationNode.LocationIdentity; -import com.oracle.graal.nodes.extended.WriteNode.WriteBarrierType; import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.type.*; import com.oracle.graal.nodes.util.*; @@ -164,7 +165,7 @@ Kind readKind = asKind(callTargetNode.returnType()); LocationNode location; if (arguments.size() == 2) { - location = makeLocation(graph, arguments.get(1), readKind, LocationNode.ANY_LOCATION); + location = makeLocation(graph, arguments.get(1), readKind, ANY_LOCATION); } else { location = makeLocation(graph, arguments.get(1), readKind, arguments.get(2)); } @@ -176,7 +177,7 @@ Kind writeKind = asKind(targetMethod.getSignature().getParameterType(1, targetMethod.getDeclaringClass())); LocationNode location; if (arguments.size() == 3) { - location = makeLocation(graph, arguments.get(1), writeKind, LocationNode.ANY_LOCATION); + location = makeLocation(graph, arguments.get(1), writeKind, LocationIdentity.ANY_LOCATION); } else { location = makeLocation(graph, arguments.get(1), writeKind, arguments.get(3)); } @@ -309,7 +310,7 @@ } private static ValueNode readOp(StructuredGraph graph, ValueNode base, Invoke invoke, LocationNode location) { - ReadNode read = graph.add(new ReadNode(base, location, invoke.asNode().stamp())); + ReadNode read = graph.add(new ReadNode(base, location, invoke.asNode().stamp(), WriteBarrierType.NONE, false)); graph.addBeforeFixed(invoke.asNode(), read); // The read must not float outside its block otherwise it may float above an explicit zero // check on its base address @@ -318,7 +319,7 @@ } private static ValueNode writeOp(StructuredGraph graph, ValueNode base, ValueNode value, Invoke invoke, LocationNode location) { - WriteNode write = graph.add(new WriteNode(base, value, location, WriteBarrierType.NONE)); + WriteNode write = graph.add(new WriteNode(base, value, location, WriteBarrierType.NONE, false)); write.setStateAfter(invoke.stateAfter()); graph.addBeforeFixed(invoke.asNode(), write); return write; diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.truffle.api/src/com/oracle/truffle/api/SourceSection.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/SourceSection.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/SourceSection.java Fri Jun 07 14:15:38 2013 +0200 @@ -123,4 +123,58 @@ return String.format("%s:%d", source.getName(), startLine); } + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + charIndex; + result = prime * result + charLength; + result = prime * result + ((identifier == null) ? 0 : identifier.hashCode()); + result = prime * result + ((source == null) ? 0 : source.hashCode()); + result = prime * result + startColumn; + result = prime * result + startLine; + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (!(obj instanceof SourceSection)) { + return false; + } + SourceSection other = (SourceSection) obj; + if (charIndex != other.charIndex) { + return false; + } + if (charLength != other.charLength) { + return false; + } + if (identifier == null) { + if (other.identifier != null) { + return false; + } + } else if (!identifier.equals(other.identifier)) { + return false; + } + if (source == null) { + if (other.source != null) { + return false; + } + } else if (!source.equals(other.source)) { + return false; + } + if (startColumn != other.startColumn) { + return false; + } + if (startLine != other.startLine) { + return false; + } + return true; + } + } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/Node.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/Node.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/Node.java Fri Jun 07 14:15:38 2013 +0200 @@ -149,6 +149,7 @@ // Pass on the source section to the new node. newNode.assignSourceSection(sourceSection); } + onReplace(newNode, reason); return (T) this.getParent().replaceChild(this, newNode); } @@ -170,6 +171,16 @@ } /** + * Intended to be implemented by subclasses of {@link Node} to receive a notification when the + * node is rewritten. This method is invoked before the actual replace has happened. + * + * @param newNode the replacement node + * @param reason the reason the replace supplied + */ + protected void onReplace(Node newNode, String reason) { + } + + /** * Invokes the {@link NodeVisitor#visit(Node)} method for this node and recursively also for all * child nodes. * diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeInfo.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeInfo.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeInfo.java Fri Jun 07 14:15:38 2013 +0200 @@ -37,4 +37,11 @@ * @return the short name */ String shortName() default ""; + + Kind kind() default Kind.SPECIALIZED; + + public enum Kind { + UNINITIALIZED, SPECIALIZED, GENERIC + } + } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/TruffleTypes.java --- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/TruffleTypes.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/TruffleTypes.java Fri Jun 07 14:15:38 2013 +0200 @@ -26,7 +26,7 @@ import javax.lang.model.element.*; import javax.lang.model.type.*; -import javax.tools.Diagnostic.*; +import javax.tools.Diagnostic.Kind; import com.oracle.truffle.api.*; import com.oracle.truffle.api.frame.*; @@ -47,6 +47,8 @@ private final TypeMirror invalidAssumption; private final DeclaredType childAnnotation; private final DeclaredType childrenAnnotation; + private final DeclaredType nodeInfoAnnotation; + private final DeclaredType nodeInfoKind; private final TypeMirror compilerDirectives; private final TypeMirror compilerAsserts; @@ -63,6 +65,12 @@ compilerAsserts = getRequired(context, CompilerAsserts.class); assumption = getRequired(context, Assumption.class); invalidAssumption = getRequired(context, InvalidAssumptionException.class); + nodeInfoAnnotation = getRequired(context, NodeInfo.class); + nodeInfoKind = getRequired(context, NodeInfo.Kind.class); + } + + public DeclaredType getNodeInfoAnnotation() { + return nodeInfoAnnotation; } public boolean verify(ProcessorContext context, Element element, AnnotationMirror mirror) { @@ -77,6 +85,10 @@ return false; } + public DeclaredType getNodeInfoKind() { + return nodeInfoKind; + } + private DeclaredType getRequired(ProcessorContext context, Class clazz) { TypeMirror type = context.getType(clazz); if (type == null) { diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/Utils.java --- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/Utils.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/Utils.java Fri Jun 07 14:15:38 2013 +0200 @@ -40,6 +40,26 @@ */ public class Utils { + public static ExecutableElement findExecutableElement(DeclaredType type, String name) { + List elements = ElementFilter.methodsIn(type.asElement().getEnclosedElements()); + for (ExecutableElement executableElement : elements) { + if (executableElement.getSimpleName().toString().equals(name)) { + return executableElement; + } + } + return null; + } + + public static VariableElement findVariableElement(DeclaredType type, String name) { + List elements = ElementFilter.fieldsIn(type.asElement().getEnclosedElements()); + for (VariableElement variableElement : elements) { + if (variableElement.getSimpleName().toString().equals(name)) { + return variableElement; + } + } + return null; + } + public static String getMethodBody(ProcessingEnvironment env, ExecutableElement method) { if (method instanceof CodeExecutableElement) { return ((CodeExecutableElement) method).getBody(); diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/ast/CodeAnnotationMirror.java --- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/ast/CodeAnnotationMirror.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/ast/CodeAnnotationMirror.java Fri Jun 07 14:15:38 2013 +0200 @@ -26,8 +26,8 @@ import javax.lang.model.element.*; import javax.lang.model.type.*; -import javax.lang.model.util.*; +import com.oracle.truffle.codegen.processor.*; import com.oracle.truffle.codegen.processor.api.element.*; public class CodeAnnotationMirror implements WritableAnnotationMirror { @@ -60,13 +60,7 @@ } public ExecutableElement findExecutableElement(String name) { - List elements = ElementFilter.methodsIn(annotationType.asElement().getEnclosedElements()); - for (ExecutableElement executableElement : elements) { - if (executableElement.getSimpleName().toString().equals(name)) { - return executableElement; - } - } - return null; + return Utils.findExecutableElement(annotationType, name); } public static CodeAnnotationMirror clone(AnnotationMirror mirror) { diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/ast/CodeTreeBuilder.java --- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/ast/CodeTreeBuilder.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/ast/CodeTreeBuilder.java Fri Jun 07 14:15:38 2013 +0200 @@ -246,23 +246,7 @@ } public CodeTreeBuilder doubleQuote(String s) { - return startGroup().string("\"").string(s).string("\"").end(); - } - - public CodeTreeBuilder startDoubleQuote() { - startGroup().string("\""); - registerCallBack(new EndCallback() { - - @Override - public void beforeEnd() { - } - - @Override - public void afterEnd() { - string("\""); - } - }); - return this; + return startGroup().string("\"" + s + "\"").end(); } public CodeTreeBuilder string(String chunk1) { diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/ExecutableTypeData.java --- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/ExecutableTypeData.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/ExecutableTypeData.java Fri Jun 07 14:15:38 2013 +0200 @@ -75,23 +75,6 @@ return count; } - public boolean startsWithSignature(TemplateMethod method) { - for (ActualParameter param : getParameters()) { - if (!param.getSpecification().isSignature()) { - continue; - } - ActualParameter foundParam = method.findParameter(param.getLocalName()); - if (foundParam != null) { - TypeData actualType = param.getTypeSystemType(); - TypeData foundType = foundParam.getTypeSystemType(); - if (actualType == null || foundType == null || !actualType.equalsType(foundType)) { - return false; - } - } - } - return true; - } - public boolean hasGenericSignature() { List types = getSignature(); for (TypeData typeData : types) { diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/ExecutableTypeMethodParser.java --- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/ExecutableTypeMethodParser.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/ExecutableTypeMethodParser.java Fri Jun 07 14:15:38 2013 +0200 @@ -44,8 +44,15 @@ @Override public MethodSpec createSpecification(ExecutableElement method, AnnotationMirror mirror) { MethodSpec spec = createDefaultMethodSpec(method, mirror, false, null); + List requiredSpecs = new ArrayList<>(spec.getRequired()); + spec.getRequired().clear(); + + for (ParameterSpec originalSpec : requiredSpecs) { + spec.addRequired(new ParameterSpec(originalSpec, Arrays.asList(getNode().getTypeSystem().getGenericType()))); + } + spec.setVariableRequiredArguments(true); - ParameterSpec other = new ParameterSpec("other", nodeTypeMirrors(getNode())); + ParameterSpec other = new ParameterSpec("other", Arrays.asList(getNode().getTypeSystem().getGenericType())); other.setCardinality(Cardinality.MANY); other.setSignature(true); other.setIndexed(true); diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeCodeGenerator.java --- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeCodeGenerator.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeCodeGenerator.java Fri Jun 07 14:15:38 2013 +0200 @@ -766,10 +766,55 @@ } builder.startStatement().string("boolean allowed = (minimumState == ").string(nodeSpecializationClassName(node.getSpecializations().get(0))).string(".class)").end(); prefix = null; + + builder.startStatement().string("StringBuilder message = new StringBuilder(reason)").end(); + builder.startStatement().startCall("message", "append").doubleQuote(" (").end().end(); + + String sep = null; + for (ActualParameter parameter : node.getGenericSpecialization().getParameters()) { + if (!parameter.getSpecification().isSignature()) { + continue; + } + + builder.startStatement(); + builder.string("message"); + if (sep != null) { + builder.startCall(".append").doubleQuote(sep).end(); + } + builder.startCall(".append").doubleQuote(parameter.getLocalName()).end(); + builder.startCall(".append").doubleQuote(" = ").end(); + builder.startCall(".append").string(parameter.getLocalName()).end(); + builder.end(); + + if (!Utils.isPrimitive(parameter.getType())) { + builder.startIf().string(parameter.getLocalName() + " != null").end(); + builder.startBlock(); + } + builder.startStatement(); + if (Utils.isPrimitive(parameter.getType())) { + builder.startCall("message.append").doubleQuote(" (" + Utils.getSimpleName(parameter.getType()) + ")").end(); + } else { + builder.startCall("message.append").doubleQuote(" (").end(); + builder.startCall(".append").string(parameter.getLocalName() + ".getClass().getSimpleName()").end(); + builder.startCall(".append").doubleQuote(")").end(); + } + builder.end(); + if (!Utils.isPrimitive(parameter.getType())) { + builder.end(); + } + + sep = ", "; + } + + builder.startStatement().startCall("message", "append").doubleQuote(")").end().end(); } addInternalValueParameters(method, node.getGenericSpecialization(), true); + if (specialize) { + method.addParameter(new CodeVariableElement(getContext().getType(String.class), "reason")); + } + List specializations = node.getSpecializations(); if (!specialize && !node.getGenericSpecialization().isUseSpecializationsForGeneric()) { specializations = Arrays.asList(node.getGenericSpecialization()); @@ -864,6 +909,7 @@ builder.startStatement().startCall("super", "replace"); builder.startGroup().startNew(nodeSpecializationClassName(current)).string("this").end().end(); + builder.string("message.toString()"); builder.end().end(); if (current.getReturnSignature().isVoid()) { @@ -1336,6 +1382,27 @@ baseType = nodeGen.asType(); } CodeTypeElement clazz = createClass(node, modifiers(PRIVATE, STATIC, FINAL), nodeSpecializationClassName(specialization), baseType, false); + + String shortName = specialization.getNode().getShortName(); + CodeAnnotationMirror nodeInfoMirror = new CodeAnnotationMirror(getContext().getTruffleTypes().getNodeInfoAnnotation()); + if (shortName != null) { + nodeInfoMirror.setElementValue(nodeInfoMirror.findExecutableElement("shortName"), new CodeAnnotationValue(shortName)); + } + + DeclaredType nodeinfoKind = getContext().getTruffleTypes().getNodeInfoKind(); + VariableElement kind; + if (specialization.isGeneric()) { + kind = Utils.findVariableElement(nodeinfoKind, "GENERIC"); + } else if (specialization.isUninitialized()) { + kind = Utils.findVariableElement(nodeinfoKind, "UNINITIALIZED"); + } else { + kind = Utils.findVariableElement(nodeinfoKind, "SPECIALIZED"); + } + + nodeInfoMirror.setElementValue(nodeInfoMirror.findExecutableElement("kind"), new CodeAnnotationValue(kind)); + + clazz.getAnnotationMirrors().add(nodeInfoMirror); + return clazz; } @@ -1373,12 +1440,13 @@ CodeTreeBuilder builder = new CodeTreeBuilder(parent); - ExecutableTypeData foundEvaluatedPrimaryType = findFunctionalExecutableType(specialization, execType.getEvaluatedCount()); + List primaryExecutes = findFunctionalExecutableType(specialization, execType.getEvaluatedCount()); - if (execType == foundEvaluatedPrimaryType || foundEvaluatedPrimaryType == null) { + if (primaryExecutes.contains(execType) || primaryExecutes.isEmpty()) { builder.tree(createFunctionalExecute(builder, specialization, execType)); } else if (needsCastingExecuteMethod(execType, primaryType)) { - builder.tree(createCastingExecute(builder, specialization, execType, foundEvaluatedPrimaryType)); + assert !primaryExecutes.isEmpty(); + builder.tree(createCastingExecute(builder, specialization, execType, primaryExecutes.get(0))); } else { return null; } @@ -1420,7 +1488,7 @@ return false; } - private ExecutableTypeData findFunctionalExecutableType(SpecializationData specialization, int evaluatedCount) { + private List findFunctionalExecutableType(SpecializationData specialization, int evaluatedCount) { TypeData primaryType = specialization.getReturnType().getTypeSystemType(); List otherTypes = specialization.getNode().getExecutableTypes(evaluatedCount); @@ -1432,19 +1500,24 @@ filteredTypes.add(compareType); } - for (ExecutableTypeData compareType : filteredTypes) { - if (compareType.startsWithSignature(specialization)) { - return compareType; + // no direct matches found use generic where the type is Object + if (filteredTypes.isEmpty()) { + for (ExecutableTypeData compareType : otherTypes) { + if (compareType.getType().isGeneric() && !compareType.hasUnexpectedValue(getContext())) { + filteredTypes.add(compareType); + } } } - for (ExecutableTypeData compareType : otherTypes) { - if (compareType.startsWithSignature(specialization)) { - return compareType; + if (filteredTypes.isEmpty()) { + for (ExecutableTypeData compareType : otherTypes) { + if (compareType.getType().isGeneric()) { + filteredTypes.add(compareType); + } } } - return null; + return filteredTypes; } private CodeTree createCastingExecute(CodeTreeBuilder parent, SpecializationData specialization, ExecutableTypeData executable, ExecutableTypeData castExecutable) { @@ -1558,7 +1631,7 @@ if (next != null) { CodeTreeBuilder returnBuilder = new CodeTreeBuilder(builder); returnBuilder.tree(createDeoptimize(builder)); - returnBuilder.tree(createReturnExecuteAndSpecialize(builder, executable, next, null)); + returnBuilder.tree(createReturnExecuteAndSpecialize(builder, executable, next, null, "One of guards " + specialization.getGuards() + " failed")); returnSpecialized = returnBuilder.getRoot(); } builder.tree(createGuardAndCast(builder, null, specialization, specialization, true, executeNode, returnSpecialized, false)); @@ -1592,6 +1665,7 @@ returnBuilder.startCall("super", EXECUTE_SPECIALIZE_NAME); returnBuilder.startGroup().string(nodeSpecializationClassName(specialization)).string(".class").end(); addInternalValueParameterNames(returnBuilder, specialization, specialization, null, true, true); + returnBuilder.doubleQuote("Uninitialized"); returnBuilder.end(); } else if (specialization.getMethod() == null && !node.needsRewrites(context)) { emitEncounteredSynthetic(builder); @@ -1623,13 +1697,13 @@ for (SpecializationThrowsData exception : specialization.getExceptions()) { builder.end().startCatchBlock(exception.getJavaClass(), "ex"); builder.tree(createDeoptimize(builder)); - builder.tree(createReturnExecuteAndSpecialize(parent, executable, exception.getTransitionTo(), null)); + builder.tree(createReturnExecuteAndSpecialize(parent, executable, exception.getTransitionTo(), null, "Thrown " + Utils.getSimpleName(exception.getJavaClass()))); } builder.end(); } if (!specialization.getAssumptions().isEmpty()) { builder.end().startCatchBlock(getContext().getTruffleTypes().getInvalidAssumption(), "ex"); - builder.tree(createReturnExecuteAndSpecialize(parent, executable, specialization.findNextSpecialization(), null)); + builder.tree(createReturnExecuteAndSpecialize(parent, executable, specialization.findNextSpecialization(), null, "Assumption failed")); builder.end(); } @@ -1734,7 +1808,8 @@ List genericParameters = generic.getParametersAfter(genericParameter); builder.tree(createDeoptimize(builder)); builder.tree(createExecuteChildren(parent, currentExecutable, generic, genericParameters, genericParameter, false)); - builder.tree(createReturnExecuteAndSpecialize(builder, currentExecutable, specialization.findNextSpecialization(), param)); + builder.tree(createReturnExecuteAndSpecialize(builder, currentExecutable, specialization.findNextSpecialization(), param, + "Expected " + param.getLocalName() + " instanceof " + Utils.getSimpleName(param.getType()))); builder.end(); // catch block } @@ -1768,19 +1843,29 @@ builder.startCall(execType.getMethodName()); - List signatureParameters = getModel().getSignatureParameters(); int index = 0; for (ActualParameter parameter : execType.getParameters()) { if (!parameter.getSpecification().isSignature()) { builder.string(parameter.getLocalName()); } else { - if (index < signatureParameters.size()) { - ActualParameter specializationParam = signatureParameters.get(index); + if (index < targetField.getExecuteWith().size()) { + NodeChildData child = targetField.getExecuteWith().get(index); + + ParameterSpec spec = getModel().getSpecification().findParameterSpec(child.getName()); + List specializationParams = getModel().findParameters(spec); + + if (specializationParams.isEmpty()) { + builder.defaultValue(parameter.getType()); + continue; + } + + ActualParameter specializationParam = specializationParams.get(0); TypeData targetType = parameter.getTypeSystemType(); TypeData sourceType = specializationParam.getTypeSystemType(); String localName = specializationParam.getLocalName(); + if (unexpectedParameter != null && unexpectedParameter.getLocalName().equals(specializationParam.getLocalName())) { localName = "ex.getResult()"; sourceType = getModel().getNode().getTypeSystem().getGenericTypeData(); @@ -1850,13 +1935,14 @@ return builder.getRoot(); } - private CodeTree createReturnExecuteAndSpecialize(CodeTreeBuilder parent, ExecutableTypeData executable, SpecializationData nextSpecialization, ActualParameter exceptionParam) { + private CodeTree createReturnExecuteAndSpecialize(CodeTreeBuilder parent, ExecutableTypeData executable, SpecializationData nextSpecialization, ActualParameter exceptionParam, String reason) { SpecializationData generic = nextSpecialization.getNode().getGenericSpecialization(); CodeTreeBuilder specializeCall = new CodeTreeBuilder(parent); specializeCall.startCall(EXECUTE_SPECIALIZE_NAME); specializeCall.string(nodeSpecializationClassName(nextSpecialization) + ".class"); addInternalValueParameterNames(specializeCall, generic, nextSpecialization.getNode().getGenericSpecialization(), exceptionParam != null ? exceptionParam.getLocalName() : null, true, true); + specializeCall.doubleQuote(reason); specializeCall.end().end(); CodeTreeBuilder builder = new CodeTreeBuilder(parent); diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeData.java --- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeData.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeData.java Fri Jun 07 14:15:38 2013 +0200 @@ -51,6 +51,8 @@ private List shortCircuits; private List assumptions; + private String shortName; + public NodeData(TypeElement type, String id) { super(type, null, null); this.nodeId = id; @@ -72,6 +74,14 @@ this.assumptions = splitSource.assumptions; } + void setShortName(String shortName) { + this.shortName = shortName; + } + + public String getShortName() { + return shortName; + } + public boolean isSplitByMethodName() { return splitByMethodName; } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeParser.java --- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeParser.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeParser.java Fri Jun 07 14:15:38 2013 +0200 @@ -32,6 +32,7 @@ import com.oracle.truffle.api.codegen.*; import com.oracle.truffle.api.codegen.NodeClass.InheritNode; +import com.oracle.truffle.api.nodes.*; import com.oracle.truffle.codegen.processor.*; import com.oracle.truffle.codegen.processor.node.NodeChildData.Cardinality; import com.oracle.truffle.codegen.processor.node.NodeChildData.ExecutionKind; @@ -577,6 +578,11 @@ } } } + AnnotationMirror nodeInfoMirror = findFirstAnnotation(lookupTypes, NodeInfo.class); + if (nodeInfoMirror != null) { + nodeData.setShortName(Utils.getAnnotationValue(String.class, nodeInfoMirror, "shortName")); + } + nodeData.setAssumptions(new ArrayList<>(assumptionsList)); nodeData.setNodeType(nodeType); nodeData.setSplitByMethodName(splitByMethodName); diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/ParameterSpec.java --- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/ParameterSpec.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/ParameterSpec.java Fri Jun 07 14:15:38 2013 +0200 @@ -55,6 +55,16 @@ this.allowedTypes = allowedTypes; } + public ParameterSpec(ParameterSpec o, List allowedTypes) { + this.name = o.name; + this.cardinality = o.cardinality; + this.signature = o.signature; + this.indexed = o.indexed; + this.local = o.local; + this.typeDefinition = o.typeDefinition; + this.allowedTypes = allowedTypes; + } + void setTypeDefinition(TypeDef typeDefinition) { this.typeDefinition = typeDefinition; } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/TemplateMethod.java --- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/TemplateMethod.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/TemplateMethod.java Fri Jun 07 14:15:38 2013 +0200 @@ -133,6 +133,16 @@ return parameters; } + public List findParameters(ParameterSpec spec) { + List foundParameters = new ArrayList<>(); + for (ActualParameter param : getReturnTypeAndParameters()) { + if (param.getSpecification().equals(spec)) { + foundParameters.add(param); + } + } + return foundParameters; + } + public ActualParameter findParameter(String valueName) { for (ActualParameter param : getReturnTypeAndParameters()) { if (param.getLocalName().equals(valueName)) { diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/GuardData.java --- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/GuardData.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/GuardData.java Fri Jun 07 14:15:38 2013 +0200 @@ -38,4 +38,9 @@ return specialization; } + @Override + public String toString() { + return getMethodName(); + } + } diff -r fe9a97ee352b -r 81b298e0868b graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/FunctionDefinitionNode.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/FunctionDefinitionNode.java Fri Jun 07 13:43:13 2013 +0200 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/FunctionDefinitionNode.java Fri Jun 07 14:15:38 2013 +0200 @@ -61,6 +61,6 @@ @Override public String toString() { - return "Function " + name + "@" + Integer.toHexString(hashCode()); + return "Function " + name; } } diff -r fe9a97ee352b -r 81b298e0868b make/build-graal.xml --- a/make/build-graal.xml Fri Jun 07 13:43:13 2013 +0200 +++ b/make/build-graal.xml Fri Jun 07 14:15:38 2013 +0200 @@ -39,6 +39,7 @@ + @@ -80,9 +81,21 @@ + + + + + + + + + + + + diff -r fe9a97ee352b -r 81b298e0868b mx/commands.py --- a/mx/commands.py Fri Jun 07 13:43:13 2013 +0200 +++ b/mx/commands.py Fri Jun 07 14:15:38 2013 +0200 @@ -825,7 +825,7 @@ def harness(projectscp, vmArgs): if not exists(javaClass) or getmtime(javaClass) < getmtime(javaSource): subprocess.check_call([mx.java().javac, '-cp', projectscp, '-d', mxdir, javaSource]) - if _vm == 'original' or _vm.endswith('nograal'): + if not isGraalEnabled(_vm): prefixArgs = ['-esa', '-ea'] else: prefixArgs = ['-XX:-BootstrapGraal', '-esa', '-ea'] @@ -973,6 +973,11 @@ clean(cleanArgs) tasks.append(t.stop()) + t = Task('IDEConfigCheck') + mx.ideclean([]) + mx.ideinit([]) + tasks.append(t.stop()) + eclipse_exe = os.environ.get('ECLIPSE_EXE') if eclipse_exe is not None: t = Task('CodeFormatCheck') @@ -1333,6 +1338,9 @@ mx.abort('jacocoreport takes only one argument : an output directory') mx.run_java(['-jar', jacocoreport.get_path(True), '-in', 'jacoco.exec', '-g', join(_graal_home, 'graal'), out]) +def isGraalEnabled(vm): + return vm != 'original' and not vm.endswith('nograal') + def site(args): """create a website containing javadoc and the project dependency graph""" diff -r fe9a97ee352b -r 81b298e0868b mx/projects --- a/mx/projects Fri Jun 07 13:43:13 2013 +0200 +++ b/mx/projects Fri Jun 07 14:15:38 2013 +0200 @@ -100,7 +100,7 @@ project@com.oracle.graal.hotspot@sourceDirs=src project@com.oracle.graal.hotspot@dependencies=com.oracle.graal.replacements,com.oracle.graal.printer project@com.oracle.graal.hotspot@checkstyle=com.oracle.graal.graph -project@com.oracle.graal.hotspot@annotationProcessors=com.oracle.graal.replacements.verifier, com.oracle.graal.service.processor +project@com.oracle.graal.hotspot@annotationProcessors=com.oracle.graal.replacements.verifier,com.oracle.graal.service.processor project@com.oracle.graal.hotspot@javaCompliance=1.7 # graal.hotspot.amd64 @@ -113,7 +113,7 @@ # graal.hotspot.sparc project@com.oracle.graal.hotspot.sparc@subDir=graal project@com.oracle.graal.hotspot.sparc@sourceDirs=src -project@com.oracle.graal.hotspot.sparc@dependencies=com.oracle.graal.hotspot,com.oracle.graal.compiler.sparc +project@com.oracle.graal.hotspot.sparc@dependencies=com.oracle.graal.compiler.sparc project@com.oracle.graal.hotspot.sparc@checkstyle=com.oracle.graal.graph project@com.oracle.graal.hotspot.sparc@javaCompliance=1.7 @@ -138,6 +138,13 @@ project@com.oracle.graal.hotspot.amd64.test@checkstyle=com.oracle.graal.graph project@com.oracle.graal.hotspot.amd64.test@javaCompliance=1.7 +# graal.options +project@com.oracle.graal.options@subDir=graal +project@com.oracle.graal.options@sourceDirs=src +project@com.oracle.graal.options@checkstyle=com.oracle.graal.graph +project@com.oracle.graal.options@javaCompliance=1.7 +project@com.oracle.graal.options@annotationProcessorForDependents=true + # graal.graph project@com.oracle.graal.graph@subDir=graal project@com.oracle.graal.graph@sourceDirs=src @@ -188,7 +195,7 @@ # graal.lir.sparc project@com.oracle.graal.lir.sparc@subDir=graal project@com.oracle.graal.lir.sparc@sourceDirs=src -project@com.oracle.graal.lir.sparc@dependencies=com.oracle.graal.lir,com.oracle.graal.asm.sparc +project@com.oracle.graal.lir.sparc@dependencies=com.oracle.graal.asm.sparc project@com.oracle.graal.lir.sparc@checkstyle=com.oracle.graal.graph project@com.oracle.graal.lir.sparc@javaCompliance=1.7 @@ -245,7 +252,7 @@ # graal.phases project@com.oracle.graal.phases@subDir=graal project@com.oracle.graal.phases@sourceDirs=src -project@com.oracle.graal.phases@dependencies=com.oracle.graal.nodes +project@com.oracle.graal.phases@dependencies=com.oracle.graal.nodes,com.oracle.graal.options project@com.oracle.graal.phases@checkstyle=com.oracle.graal.graph project@com.oracle.graal.phases@javaCompliance=1.7 @@ -309,10 +316,17 @@ # graal.compiler.sparc project@com.oracle.graal.compiler.sparc@subDir=graal project@com.oracle.graal.compiler.sparc@sourceDirs=src -project@com.oracle.graal.compiler.sparc@dependencies=com.oracle.graal.compiler,com.oracle.graal.lir.sparc +project@com.oracle.graal.compiler.sparc@dependencies=com.oracle.graal.lir.sparc project@com.oracle.graal.compiler.sparc@checkstyle=com.oracle.graal.graph project@com.oracle.graal.compiler.sparc@javaCompliance=1.7 +# graal.compiler.sparc.test +project@com.oracle.graal.compiler.sparc.test@subDir=graal +project@com.oracle.graal.compiler.sparc.test@sourceDirs=src +project@com.oracle.graal.compiler.sparc.test@dependencies=com.oracle.graal.compiler.sparc,com.oracle.graal.compiler.test +project@com.oracle.graal.compiler.sparc.test@checkstyle=com.oracle.graal.graph +project@com.oracle.graal.compiler.sparc.test@javaCompliance=1.7 + # graal.bytecode project@com.oracle.graal.bytecode@subDir=graal project@com.oracle.graal.bytecode@sourceDirs=src @@ -392,7 +406,7 @@ # graal.asm.sparc project@com.oracle.graal.asm.sparc@subDir=graal project@com.oracle.graal.asm.sparc@sourceDirs=src -project@com.oracle.graal.asm.sparc@dependencies=com.oracle.graal.asm,com.oracle.graal.sparc +project@com.oracle.graal.asm.sparc@dependencies=com.oracle.graal.hotspot,com.oracle.graal.sparc project@com.oracle.graal.asm.sparc@checkstyle=com.oracle.graal.graph project@com.oracle.graal.asm.sparc@javaCompliance=1.7 diff -r fe9a97ee352b -r 81b298e0868b mx/sanitycheck.py --- a/mx/sanitycheck.py Fri Jun 07 13:43:13 2013 +0200 +++ b/mx/sanitycheck.py Fri Jun 07 14:15:38 2013 +0200 @@ -235,15 +235,15 @@ args = ['-XX:+CompileTheWorld', '-Xbootclasspath/p:' + rtjar] - if not vm.endswith('-nograal'): + if commands.isGraalEnabled(vm): args += ['-XX:+BootstrapGraal', '-G:-Debug'] if mode >= CTWMode.NoInline: - if vm.endswith('-nograal'): + if not commands.isGraalEnabled(vm): args.append('-XX:-Inline') else: args.append('-G:-Inline') if mode >= CTWMode.NoComplex: - if not vm.endswith('-nograal'): + if commands.isGraalEnabled(vm): args += ['-G:-OptLoopTransform', '-G:-OptTailDuplication', '-G:-FullUnroll', '-G:-MemoryAwareScheduling', '-G:-PartialEscapeAnalysis'] return Test("CompileTheWorld", args, successREs=[time], scoreMatchers=[scoreMatcher], benchmarkCompilationRate=False) diff -r fe9a97ee352b -r 81b298e0868b mxtool/mx --- a/mxtool/mx Fri Jun 07 13:43:13 2013 +0200 +++ b/mxtool/mx Fri Jun 07 14:15:38 2013 +0200 @@ -43,7 +43,7 @@ python_exe=python2.7 else type python2 > /dev/null 2>&1 - if [ $? -eq 0]; then + if [ $? -eq 0 ]; then python_exe=python2 else python_exe=python diff -r fe9a97ee352b -r 81b298e0868b mxtool/mx.py --- a/mxtool/mx.py Fri Jun 07 13:43:13 2013 +0200 +++ b/mxtool/mx.py Fri Jun 07 14:15:38 2013 +0200 @@ -133,6 +133,7 @@ """ import sys, os, errno, time, subprocess, shlex, types, urllib2, contextlib, StringIO, zipfile, signal, xml.sax.saxutils, tempfile +import xml.parsers.expat import shutil, re, xml.dom.minidom from collections import Callable from threading import Thread @@ -145,6 +146,7 @@ _libs = dict() _dists = dict() _suites = dict() +_annotationProcessors = None _mainSuite = None _opts = None _java = None @@ -218,8 +220,8 @@ libraries if 'includeLibs' is true, to the 'deps' list. """ childDeps = list(self.deps) - if includeAnnotationProcessors and hasattr(self, 'annotationProcessors') and len(self.annotationProcessors) > 0: - childDeps = self.annotationProcessors + childDeps + if includeAnnotationProcessors and len(self.annotation_processors()) > 0: + childDeps = self.annotation_processors() + childDeps if self in deps: return deps for name in childDeps: @@ -407,6 +409,19 @@ self._init_packages_and_imports() return self._imported_java_packages + def annotation_processors(self): + if not hasattr(self, '_annotationProcessors'): + ap = set() + if hasattr(self, '_declaredAnnotationProcessors'): + ap = set(self._declaredAnnotationProcessors) + + # find dependencies that auto-inject themselves as annotation processors to all dependents + allDeps = self.all_deps([], includeLibs=False, includeSelf=False, includeAnnotationProcessors=False) + for p in allDeps: + if hasattr(p, 'annotationProcessorForDependents') and p.annotationProcessorForDependents.lower() == 'true': + ap.add(p.name) + self._annotationProcessors = list(ap) + return self._annotationProcessors class Library(Dependency): def __init__(self, suite, name, path, mustExist, urls, sourcePath, sourceUrls): @@ -526,7 +541,7 @@ if not p.native and p.javaCompliance is None: abort('javaCompliance property required for non-native project ' + name) if len(ap) > 0: - p.annotationProcessors = ap + p._declaredAnnotationProcessors = ap p.__dict__.update(attrs) self.projects.append(p) @@ -730,6 +745,18 @@ """ return _projects.values() +def annotation_processors(): + """ + Get the list of all loaded projects that define an annotation processor. + """ + global _annotationProcessors + if _annotationProcessors is None: + ap = set() + for p in projects(): + ap.update(p.annotation_processors()) + _annotationProcessors = list(ap) + return _annotationProcessors + def distribution(name, fatalIfMissing=True): """ Get the distribution for a given name. This will abort if the named distribution does @@ -1514,8 +1541,9 @@ if java().debug_port is not None: javacArgs += ['-J-Xdebug', '-J-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=' + str(java().debug_port)] - if hasattr(p, 'annotationProcessors') and len(p.annotationProcessors) > 0: - processorPath = classpath(p.annotationProcessors, resolve=True) + ap = p.annotation_processors() + if len(ap) > 0: + processorPath = classpath(ap, resolve=True) genDir = p.source_gen_dir(); if exists(genDir): shutil.rmtree(genDir) @@ -1671,16 +1699,16 @@ return 0 def processorjars(): - projects = set() + projs = set() for p in sorted_deps(): if _isAnnotationProcessorDependency(p): - projects.add(p) + projs.add(p) - if len(projects) <= 0: + if len(projs) < 0: return - pnames = [p.name for p in projects] + pnames = [p.name for p in projs] build(['--projects', ",".join(pnames)]) archive(pnames) @@ -1699,6 +1727,11 @@ try: zf = zipfile.ZipFile(tmp, 'w') for p in sorted_deps(d.deps): + # skip a Java project if its Java compliance level is "higher" than the configured JDK + if java().javaCompliance < p.javaCompliance: + log('Excluding {0} from {2} (Java compliance level {1} required)'.format(p.name, p.javaCompliance, d.path)) + continue + outputDir = p.output_dir() for root, _, files in os.walk(outputDir): relpath = root[len(outputDir) + 1:] @@ -1908,19 +1941,30 @@ batch = javafilelist[:i] javafilelist = javafilelist[i:] try: - run_java(['-Xmx1g', '-jar', library('CHECKSTYLE').get_path(True), '-c', config, '-o', auditfileName] + batch) + run_java(['-Xmx1g', '-jar', library('CHECKSTYLE').get_path(True), '-f', 'xml', '-c', config, '-o', auditfileName] + batch) finally: if exists(auditfileName): - with open(auditfileName) as f: - warnings = [line.strip() for line in f if 'warning:' in line] - if len(warnings) != 0: - map(log, warnings) - return 1 + errors = [] + source = None + def start_element(name, attrs): + if name == 'file': + global source + source = attrs['name'] + elif name == 'error': + errors.append('{}:{}: {}'.format(source, attrs['line'], attrs['message'])) + + p = xml.parsers.expat.ParserCreate() + p.StartElementHandler = start_element + with open(auditfileName) as fp: + p.ParseFile(fp) + if len(errors) != 0: + map(log, errors) + return len(errors) + else: + if exists(timestampFile): + os.utime(timestampFile, None) else: - if exists(timestampFile): - os.utime(timestampFile, None) - else: - file(timestampFile, 'a') + file(timestampFile, 'a') finally: if exists(auditfileName): os.unlink(auditfileName) @@ -2155,7 +2199,7 @@ os.mkdir(srcDir) out.element('classpathentry', {'kind' : 'src', 'path' : src}) - if hasattr(p, 'annotationProcessors') and len(p.annotationProcessors) > 0: + if len(p.annotation_processors()) > 0: genDir = p.source_gen_dir(); if not exists(genDir): os.mkdir(genDir) @@ -2279,22 +2323,22 @@ eclipseSettingsDir = join(suite.dir, 'mx', 'eclipse-settings') if exists(eclipseSettingsDir): for name in os.listdir(eclipseSettingsDir): - if name == "org.eclipse.jdt.apt.core.prefs" and not (hasattr(p, 'annotationProcessors') and len(p.annotationProcessors) > 0): + if name == "org.eclipse.jdt.apt.core.prefs" and not len(p.annotation_processors()) > 0: continue path = join(eclipseSettingsDir, name) if isfile(path): with open(join(eclipseSettingsDir, name)) as f: content = f.read() content = content.replace('${javaCompliance}', str(p.javaCompliance)) - if hasattr(p, 'annotationProcessors') and len(p.annotationProcessors) > 0: + if len(p.annotation_processors()) > 0: content = content.replace('org.eclipse.jdt.core.compiler.processAnnotations=disabled', 'org.eclipse.jdt.core.compiler.processAnnotations=enabled') update_file(join(settingsDir, name), content) - if hasattr(p, 'annotationProcessors') and len(p.annotationProcessors) > 0: + if len(p.annotation_processors()) > 0: out = XMLDoc() out.open('factorypath') out.element('factorypathentry', {'kind' : 'PLUGIN', 'id' : 'org.eclipse.jst.ws.annotations.core', 'enabled' : 'true', 'runInBatchMode' : 'false'}) - for ap in p.annotationProcessors: + for ap in p.annotation_processors(): apProject = project(ap) for dep in apProject.all_deps([], True): if dep.isLibrary(): @@ -2319,22 +2363,7 @@ """ Determines if a given project is part of an annotation processor. """ - processors = set() - - for otherProject in projects(): - if hasattr(otherProject, 'annotationProcessors') and len(otherProject.annotationProcessors) > 0: - for processorName in otherProject.annotationProcessors: - processors.add(project(processorName, fatalIfMissing=True)) - - if p in processors: - return True - - for otherProject in processors: - deps = otherProject.all_deps([], True) - if p in deps: - return True - - return False + return p in sorted_deps(annotation_processors()) def _genEclipseBuilder(dotProjectDoc, p, name, mxCommand, refresh=True, async=False, logToConsole=False, xmlIndent='\t', xmlStandalone=None): launchOut = XMLDoc(); @@ -2429,7 +2458,7 @@ out.element('explicit-platform', {'explicit-source-supported' : 'true'}) out.open('source-roots') out.element('root', {'id' : 'src.dir'}) - if hasattr(p, 'annotationProcessors') and len(p.annotationProcessors) > 0: + if len(p.annotation_processors()) > 0: out.element('root', {'id' : 'src.ap-source-output.dir'}) out.close('source-roots') out.open('test-roots') @@ -2469,7 +2498,7 @@ annotationProcessorEnabled = "false" annotationProcessorReferences = "" annotationProcessorSrcFolder = "" - if hasattr(p, 'annotationProcessors') and len(p.annotationProcessors) > 0: + if len(p.annotation_processors()) > 0: annotationProcessorEnabled = "true" annotationProcessorSrcFolder = "src.ap-source-output.dir=${build.generated.sources.dir}/ap-source-output" @@ -2561,8 +2590,8 @@ deps = p.all_deps([], True) annotationProcessorOnlyDeps = [] - if hasattr(p, 'annotationProcessors') and len(p.annotationProcessors) > 0: - for ap in p.annotationProcessors: + if len(p.annotation_processors()) > 0: + for ap in p.annotation_processors(): apProject = project(ap) if not apProject in deps: deps.append(apProject) diff -r fe9a97ee352b -r 81b298e0868b src/share/vm/classfile/systemDictionary.hpp --- a/src/share/vm/classfile/systemDictionary.hpp Fri Jun 07 13:43:13 2013 +0200 +++ b/src/share/vm/classfile/systemDictionary.hpp Fri Jun 07 14:15:38 2013 +0200 @@ -186,6 +186,7 @@ do_klass(BitSet_klass, java_util_BitSet, Opt) \ /* graal.hotspot */ \ do_klass(HotSpotCompiledCode_klass, com_oracle_graal_hotspot_HotSpotCompiledCode, Opt) \ + do_klass(HotSpotCompiledCode_Comment_klass, com_oracle_graal_hotspot_HotSpotCompiledCode_Comment, Opt) \ do_klass(HotSpotCompiledNmethod_klass, com_oracle_graal_hotspot_HotSpotCompiledNmethod, Opt) \ do_klass(HotSpotCompiledRuntimeStub_klass, com_oracle_graal_hotspot_HotSpotCompiledRuntimeStub, Opt) \ do_klass(HotSpotForeignCallLinkage_klass, com_oracle_graal_hotspot_HotSpotForeignCallLinkage, Opt) \ diff -r fe9a97ee352b -r 81b298e0868b src/share/vm/classfile/vmSymbols.hpp --- a/src/share/vm/classfile/vmSymbols.hpp Fri Jun 07 13:43:13 2013 +0200 +++ b/src/share/vm/classfile/vmSymbols.hpp Fri Jun 07 14:15:38 2013 +0200 @@ -297,6 +297,7 @@ template(com_oracle_graal_hotspot_HotSpotKlassOop, "com/oracle/graal/hotspot/HotSpotKlassOop") \ template(com_oracle_graal_hotspot_HotSpotOptions, "com/oracle/graal/hotspot/HotSpotOptions") \ template(com_oracle_graal_hotspot_HotSpotCompiledCode, "com/oracle/graal/hotspot/HotSpotCompiledCode") \ + template(com_oracle_graal_hotspot_HotSpotCompiledCode_Comment, "com/oracle/graal/hotspot/HotSpotCompiledCode$Comment") \ template(com_oracle_graal_hotspot_HotSpotCompiledNmethod, "com/oracle/graal/hotspot/HotSpotCompiledNmethod") \ template(com_oracle_graal_hotspot_HotSpotCompiledRuntimeStub, "com/oracle/graal/hotspot/HotSpotCompiledRuntimeStub") \ template(com_oracle_graal_hotspot_HotSpotForeignCallLinkage, "com/oracle/graal/hotspot/HotSpotForeignCallLinkage") \ diff -r fe9a97ee352b -r 81b298e0868b src/share/vm/graal/graalCodeInstaller.cpp --- a/src/share/vm/graal/graalCodeInstaller.cpp Fri Jun 07 13:43:13 2013 +0200 +++ b/src/share/vm/graal/graalCodeInstaller.cpp Fri Jun 07 14:15:38 2013 +0200 @@ -256,7 +256,13 @@ arrayOop values = (arrayOop) VirtualObject::values(value); for (jint i = 0; i < values->length(); i++) { ScopeValue* cur_second = NULL; - ScopeValue* value = get_hotspot_value(((oop*) values->base(T_OBJECT))[i], total_frame_size, objects, cur_second, oop_recorder); + oop object; + if(UseCompressedOops) { + object=oopDesc::decode_heap_oop(((narrowOop*) values->base(T_OBJECT))[i]); + } else { + object=((oop*) (values->base(T_OBJECT)))[i]; + } + ScopeValue* value = get_hotspot_value(object, total_frame_size, objects, cur_second, oop_recorder); if (isLongArray && cur_second == NULL) { // we're trying to put ints into a long array... this isn't really valid, but it's used for some optimizations. @@ -410,6 +416,9 @@ // (very) conservative estimate: each site needs a constant section entry _constants_size = _sites->length() * (BytesPerLong*2); +#ifndef PRODUCT + _comments = (arrayOop) HotSpotCompiledCode::comments(compiled_code); +#endif _next_call_type = MARK_INVOKE_INVALID; } @@ -434,9 +443,13 @@ memcpy(_instructions->start(), _code->base(T_BYTE), _code_size); _instructions->set_end(_instructions->start() + _code_size); - oop* sites = (oop*) _sites->base(T_OBJECT); + oop site; for (int i = 0; i < _sites->length(); i++) { - oop site = sites[i]; + if(UseCompressedOops) { + site=oopDesc::decode_heap_oop(((narrowOop*) _sites->base(T_OBJECT))[i]); + } else { + site=((oop*) (_sites->base(T_OBJECT)))[i]; + } jint pc_offset = CompilationResult_Site::pcOffset(site); if (site->is_a(CompilationResult_Call::klass())) { @@ -463,6 +476,23 @@ fatal("unexpected Site subclass"); } } + +#ifndef PRODUCT + if (_comments != NULL) { + oop comment; + for (int i = 0; i < _comments->length(); i++) { + if(UseCompressedOops) { + comment=oopDesc::decode_heap_oop(((narrowOop*) _comments->base(T_OBJECT))[i]); + } else { + comment=((oop*) (_comments->base(T_OBJECT)))[i]; + } + assert(comment->is_a(HotSpotCompiledCode_Comment::klass()), "cce"); + jint offset = HotSpotCompiledCode_Comment::pcOffset(comment); + char* text = java_lang_String::as_utf8_string(HotSpotCompiledCode_Comment::text(comment)); + buffer.block_comment(offset, text); + } + } +#endif } void CodeInstaller::assumption_MethodContents(Handle assumption) { @@ -517,7 +547,12 @@ if (_exception_handlers != NULL) { oop* exception_handlers = (oop*) _exception_handlers->base(T_OBJECT); for (int i = 0; i < _exception_handlers->length(); i++) { - oop exc = exception_handlers[i]; + oop exc; + if(UseCompressedOops) { + exc=oopDesc::decode_heap_oop(((narrowOop*) _exception_handlers->base(T_OBJECT))[i]); + } else { + exc=((oop*) (_exception_handlers->base(T_OBJECT)))[i]; + } jint pc_offset = CompilationResult_Site::pcOffset(exc); jint handler_offset = CompilationResult_ExceptionHandler::handlerPos(exc); @@ -589,8 +624,12 @@ for (jint i = 0; i < values->length(); i++) { ScopeValue* second = NULL; - oop value = ((oop*) values->base(T_OBJECT))[i]; - + oop value; + if(UseCompressedOops) { + value=oopDesc::decode_heap_oop(((narrowOop*) values->base(T_OBJECT))[i]); + } else { + value = ((oop*) values->base(T_OBJECT))[i]; + } if (i < local_count) { ScopeValue* first = get_hotspot_value(value, _total_frame_size, objects, second, _oop_recorder); if (second != NULL) { @@ -609,10 +648,15 @@ if (second != NULL) { i++; assert(i < values->length(), "double-slot value not followed by Value.ILLEGAL"); - assert(((oop*) values->base(T_OBJECT))[i] == Value::ILLEGAL(), "double-slot value not followed by Value.ILLEGAL"); + if(UseCompressedOops) { + assert(oopDesc::decode_heap_oop(((narrowOop*) values->base(T_OBJECT))[i]) == Value::ILLEGAL(), "double-slot value not followed by Value.ILLEGAL"); + } else { + assert(((oop*) values->base(T_OBJECT))[i] == Value::ILLEGAL(), "double-slot value not followed by Value.ILLEGAL"); + } } } + _debug_recorder->dump_object_pool(objects); DebugToken* locals_token = _debug_recorder->create_scope_values(locals); diff -r fe9a97ee352b -r 81b298e0868b src/share/vm/graal/graalCodeInstaller.hpp --- a/src/share/vm/graal/graalCodeInstaller.hpp Fri Jun 07 13:43:13 2013 +0200 +++ b/src/share/vm/graal/graalCodeInstaller.hpp Fri Jun 07 14:15:38 2013 +0200 @@ -60,6 +60,9 @@ jint _custom_stack_area_offset; jint _parameter_count; jint _constants_size; +#ifndef PRODUCT + arrayOop _comments; +#endif MarkId _next_call_type; address _invoke_mark_pc; diff -r fe9a97ee352b -r 81b298e0868b src/share/vm/graal/graalCompiler.cpp --- a/src/share/vm/graal/graalCompiler.cpp Fri Jun 07 13:43:13 2013 +0200 +++ b/src/share/vm/graal/graalCompiler.cpp Fri Jun 07 14:15:38 2013 +0200 @@ -85,6 +85,7 @@ { GRAAL_VM_ENTRY_MARK; HandleMark hm; + VMToCompiler::initOptions(); for (int i = 0; i < Arguments::num_graal_args(); ++i) { const char* arg = Arguments::graal_args_array()[i]; Handle option = java_lang_String::create_from_str(arg, THREAD); diff -r fe9a97ee352b -r 81b298e0868b src/share/vm/graal/graalCompilerToVM.cpp --- a/src/share/vm/graal/graalCompilerToVM.cpp Fri Jun 07 13:43:13 2013 +0200 +++ b/src/share/vm/graal/graalCompilerToVM.cpp Fri Jun 07 14:15:38 2013 +0200 @@ -795,6 +795,7 @@ set_address("logObjectAddress", GraalRuntime::log_object); set_address("logPrintfAddress", GraalRuntime::log_printf); set_address("vmErrorAddress", GraalRuntime::vm_error); + set_address("loadAndClearExceptionAddress", GraalRuntime::load_and_clear_exception); set_address("writeBarrierPreAddress", GraalRuntime::write_barrier_pre); set_address("writeBarrierPostAddress", GraalRuntime::write_barrier_post); set_address("javaTimeMillisAddress", CAST_FROM_FN_PTR(address, os::javaTimeMillis)); @@ -830,6 +831,12 @@ set_int("vmIntrinsicLinkToSpecial", vmIntrinsics::_linkToSpecial); set_int("vmIntrinsicLinkToInterface", vmIntrinsics::_linkToInterface); + set_boolean("useCompressedOops", UseCompressedOops); + set_boolean("useCompressedKlassPointers", UseCompressedKlassPointers); + set_address("narrowOopBase", Universe::narrow_oop_base()); + set_int("narrowOopShift", Universe::narrow_oop_shift()); + set_int("logMinObjAlignment", LogMinObjAlignmentInBytes); + set_int("g1CardQueueIndexOffset", in_bytes(JavaThread::dirty_card_queue_offset() + PtrQueue::byte_offset_of_index())); set_int("g1CardQueueBufferOffset", in_bytes(JavaThread::dirty_card_queue_offset() + PtrQueue::byte_offset_of_buf())); set_int("logOfHRGrainBytes", HeapRegion::LogOfHRGrainBytes); diff -r fe9a97ee352b -r 81b298e0868b src/share/vm/graal/graalCompilerToVM.hpp --- a/src/share/vm/graal/graalCompilerToVM.hpp Fri Jun 07 13:43:13 2013 +0200 +++ b/src/share/vm/graal/graalCompilerToVM.hpp Fri Jun 07 14:15:38 2013 +0200 @@ -54,7 +54,12 @@ oop next_arg(BasicType expectedType) { assert(_index < _args->length(), "out of bounds"); - oop arg = ((oop*) _args->base(T_OBJECT))[_index++]; + oop arg; + if(UseCompressedOops) { + arg = oopDesc::decode_heap_oop(((narrowOop*) _args->base(T_OBJECT))[_index++]); + } else { + arg = ((oop*) _args->base(T_OBJECT))[_index++]; + } assert(expectedType == T_OBJECT || java_lang_boxing_object::is_instance(arg, expectedType), "arg type mismatch"); return arg; } diff -r fe9a97ee352b -r 81b298e0868b src/share/vm/graal/graalJavaAccess.hpp --- a/src/share/vm/graal/graalJavaAccess.hpp Fri Jun 07 13:43:13 2013 +0200 +++ b/src/share/vm/graal/graalJavaAccess.hpp Fri Jun 07 14:15:38 2013 +0200 @@ -87,6 +87,11 @@ oop_field(HotSpotCompiledCode, comp, "Lcom/oracle/graal/api/code/CompilationResult;") \ oop_field(HotSpotCompiledCode, sites, "[Lcom/oracle/graal/api/code/CompilationResult$Site;") \ oop_field(HotSpotCompiledCode, exceptionHandlers, "[Lcom/oracle/graal/api/code/CompilationResult$ExceptionHandler;") \ + oop_field(HotSpotCompiledCode, comments, "[Lcom/oracle/graal/hotspot/HotSpotCompiledCode$Comment;") \ + end_class \ + start_class(HotSpotCompiledCode_Comment) \ + oop_field(HotSpotCompiledCode_Comment, text, "Ljava/lang/String;") \ + int_field(HotSpotCompiledCode_Comment, pcOffset) \ end_class \ start_class(HotSpotCompiledNmethod) \ oop_field(HotSpotCompiledNmethod, method, "Lcom/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod;") \ @@ -95,8 +100,8 @@ start_class(HotSpotCompiledRuntimeStub) \ oop_field(HotSpotCompiledRuntimeStub, stubName, "Ljava/lang/String;") \ end_class \ - start_class(HotSpotForeignCallLinkage) \ - long_field(HotSpotForeignCallLinkage, address) \ + start_class(HotSpotForeignCallLinkage) \ + long_field(HotSpotForeignCallLinkage, address) \ end_class \ start_class(ExceptionHandler) \ int_field(ExceptionHandler, startBCI) \ @@ -139,7 +144,7 @@ int_field(CompilationResult_Site, pcOffset) \ end_class \ start_class(CompilationResult_Call) \ - oop_field(CompilationResult_Call, target, "Lcom/oracle/graal/api/meta/InvokeTarget;") \ + oop_field(CompilationResult_Call, target, "Lcom/oracle/graal/api/meta/InvokeTarget;") \ oop_field(CompilationResult_Call, debugInfo, "Lcom/oracle/graal/api/code/DebugInfo;") \ end_class \ start_class(CompilationResult_DataPatch) \ @@ -228,10 +233,10 @@ oop_field(VirtualObject, type, "Lcom/oracle/graal/api/meta/ResolvedJavaType;") \ oop_field(VirtualObject, values, "[Lcom/oracle/graal/api/meta/Value;") \ end_class \ - start_class(HotSpotMonitorValue) \ - oop_field(HotSpotMonitorValue, owner, "Lcom/oracle/graal/api/meta/Value;") \ - oop_field(HotSpotMonitorValue, slot, "Lcom/oracle/graal/api/code/StackSlot;") \ - boolean_field(HotSpotMonitorValue, eliminated) \ + start_class(HotSpotMonitorValue) \ + oop_field(HotSpotMonitorValue, owner, "Lcom/oracle/graal/api/meta/Value;") \ + oop_field(HotSpotMonitorValue, slot, "Lcom/oracle/graal/api/code/StackSlot;") \ + boolean_field(HotSpotMonitorValue, eliminated) \ end_class \ /* end*/ diff -r fe9a97ee352b -r 81b298e0868b src/share/vm/graal/graalRuntime.cpp --- a/src/share/vm/graal/graalRuntime.cpp Fri Jun 07 13:43:13 2013 +0200 +++ b/src/share/vm/graal/graalRuntime.cpp Fri Jun 07 14:15:38 2013 +0200 @@ -380,6 +380,13 @@ report_vm_error(__FILE__, __LINE__, error_msg, detail_msg); JRT_END +JRT_LEAF(oop, GraalRuntime::load_and_clear_exception(JavaThread* thread)) + oop exception = thread->exception_oop(); + assert(exception != NULL, "npe"); + thread->set_exception_oop(NULL); + thread->set_exception_pc(0); + return exception; +JRT_END JRT_LEAF(void, GraalRuntime::log_printf(JavaThread* thread, oop format, jlong v1, jlong v2, jlong v3)) ResourceMark rm; diff -r fe9a97ee352b -r 81b298e0868b src/share/vm/graal/graalRuntime.hpp --- a/src/share/vm/graal/graalRuntime.hpp Fri Jun 07 13:43:13 2013 +0200 +++ b/src/share/vm/graal/graalRuntime.hpp Fri Jun 07 14:15:38 2013 +0200 @@ -42,6 +42,7 @@ static void create_null_exception(JavaThread* thread); static void create_out_of_bounds_exception(JavaThread* thread, jint index); static void vm_error(JavaThread* thread, oop where, oop format, jlong value); + static oop load_and_clear_exception(JavaThread* thread); static void log_printf(JavaThread* thread, oop format, jlong v1, jlong v2, jlong v3); static void log_primitive(JavaThread* thread, jchar typeChar, jlong value, jboolean newline); // Note: Must be kept in sync with constants in com.oracle.graal.replacements.Log diff -r fe9a97ee352b -r 81b298e0868b src/share/vm/graal/graalVMToCompiler.cpp --- a/src/share/vm/graal/graalVMToCompiler.cpp Fri Jun 07 13:43:13 2013 +0200 +++ b/src/share/vm/graal/graalVMToCompiler.cpp Fri Jun 07 14:15:38 2013 +0200 @@ -75,6 +75,13 @@ return Handle(JNIHandles::resolve_non_null(_vmToCompilerPermObject)); } +void VMToCompiler::initOptions() { + KlassHandle compilerKlass = loadClass(vmSymbols::com_oracle_graal_hotspot_HotSpotOptions()); + Thread* THREAD = Thread::current(); + compilerKlass->initialize(THREAD); + check_pending_exception("Error while calling initOptions"); +} + jboolean VMToCompiler::setOption(Handle option) { assert(!option.is_null(), ""); KlassHandle compilerKlass = loadClass(vmSymbols::com_oracle_graal_hotspot_HotSpotOptions()); diff -r fe9a97ee352b -r 81b298e0868b src/share/vm/graal/graalVMToCompiler.hpp --- a/src/share/vm/graal/graalVMToCompiler.hpp Fri Jun 07 13:43:13 2013 +0200 +++ b/src/share/vm/graal/graalVMToCompiler.hpp Fri Jun 07 14:15:38 2013 +0200 @@ -50,6 +50,9 @@ return _graalRuntimePermObject; } + // public static boolean HotSpotOptions.(); + static void initOptions(); + // public static boolean HotSpotOptions.setOption(String option); static jboolean setOption(Handle option); diff -r fe9a97ee352b -r 81b298e0868b src/share/vm/oops/klass.hpp --- a/src/share/vm/oops/klass.hpp Fri Jun 07 13:43:13 2013 +0200 +++ b/src/share/vm/oops/klass.hpp Fri Jun 07 14:15:38 2013 +0200 @@ -148,10 +148,7 @@ Klass* _primary_supers[_primary_super_limit]; // java/lang/Class instance mirroring this class oop _java_mirror; -#ifdef GRAAL - // com/oracle/graal/hotspot/HotSpotResolvedObjectType mirroring this class - oop _graal_mirror; -#endif + // Superclass Klass* _super; // First subclass (NULL if none); _subklass->next_sibling() is next one @@ -252,12 +249,6 @@ oop java_mirror() const { return _java_mirror; } void set_java_mirror(oop m) { klass_oop_store(&_java_mirror, m); } -#ifdef GRAAL - // Graal mirror - oop graal_mirror() const { return _graal_mirror; } - void set_graal_mirror(oop m) { oop_store((oop*) &_graal_mirror, m); } -#endif - // modifier flags jint modifier_flags() const { return _modifier_flags; } void set_modifier_flags(jint flags) { _modifier_flags = flags; } @@ -317,7 +308,6 @@ static ByteSize layout_helper_offset() { return in_ByteSize(offset_of(Klass, _layout_helper)); } static ByteSize access_flags_offset() { return in_ByteSize(offset_of(Klass, _access_flags)); } #ifdef GRAAL - static ByteSize graal_mirror_offset() { return in_ByteSize(offset_of(Klass, _graal_mirror)); } static ByteSize next_sibling_offset() { return in_ByteSize(offset_of(Klass, _next_sibling)); } static ByteSize subklass_offset() { return in_ByteSize(offset_of(Klass, _subklass)); } #endif diff -r fe9a97ee352b -r 81b298e0868b src/share/vm/prims/unsafe.cpp --- a/src/share/vm/prims/unsafe.cpp Fri Jun 07 13:43:13 2013 +0200 +++ b/src/share/vm/prims/unsafe.cpp Fri Jun 07 14:15:38 2013 +0200 @@ -174,17 +174,27 @@ OrderAccess::release_store_fence((volatile type_name*)index_oop_from_field_offset_long(p, offset), x); // Macros for oops that check UseCompressedOops - +#ifndef GRAAL #define GET_OOP_FIELD(obj, offset, v) \ - oop p = JNIHandles::resolve(obj); \ - oop v; \ - if (UseCompressedOops) { \ + oop p = JNIHandles::resolve(obj); \ + oop v; \ + if (UseCompressedOops) { \ narrowOop n = *(narrowOop*)index_oop_from_field_offset_long(p, offset); \ - v = oopDesc::decode_heap_oop(n); \ - } else { \ - v = *(oop*)index_oop_from_field_offset_long(p, offset); \ + v = oopDesc::decode_heap_oop(n); \ + } else { \ + v = *(oop*)index_oop_from_field_offset_long(p, offset); \ } - +#else +#define GET_OOP_FIELD(obj, offset, v) \ + oop p = JNIHandles::resolve(obj); \ + oop v; \ + if (UseCompressedOops && p!=NULL && offset>=oopDesc::header_size()) { \ + narrowOop n = *(narrowOop*)index_oop_from_field_offset_long(p, offset); \ + v = oopDesc::decode_heap_oop(n); \ + } else { \ + v = *(oop*)index_oop_from_field_offset_long(p, offset); \ + } +#endif // Get/SetObject must be special-cased, since it works with handles.