Mercurial > hg > truffle
changeset 12371:e32f2b195867
Merge
author | Christos Kotselidis <christos.kotselidis@oracle.com> |
---|---|
date | Fri, 11 Oct 2013 17:21:14 +0200 |
parents | 1e4d1c150ed5 (current diff) bba234a1670e (diff) |
children | 2dfccd93510a |
files | graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/DelegatingCodeCacheProvider.java graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/DeoptimizationAction.java graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/DelegatingMetaAccessProvider.java graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/MemoryMap.java graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierAdditionTest.java graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierVerificationTest.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/VerifyHotSpotOptionsPhase.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotReplacementsUtil.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MemoryState.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/debug/SurvivingCounterNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/Canonicalizable.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/CanonicalizerTool.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/DelegatingGraalCodeCacheProvider.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/GraalCodeCacheProvider.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/Simplifiable.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/SimplifierTool.java graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/PhiStampPhase.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomTypeCheckMacroNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomTypeCheckNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/TypeCastMacroNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/TypeCastNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/UnsafeCustomizationMacroNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/UnsafeCustomizationNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/phases/ReplaceLoadFinalPhase.java src/os_cpu/bsd_x86/vm/bsd_x86_32.ad src/os_cpu/bsd_x86/vm/bsd_x86_64.ad src/os_cpu/linux_x86/vm/linux_x86_32.ad src/os_cpu/linux_x86/vm/linux_x86_64.ad src/os_cpu/solaris_sparc/vm/solaris_sparc.ad src/os_cpu/solaris_x86/vm/solaris_x86_32.ad src/os_cpu/solaris_x86/vm/solaris_x86_64.ad src/os_cpu/windows_x86/vm/windows_x86_32.ad src/os_cpu/windows_x86/vm/windows_x86_64.ad test/runtime/7196045/Test7196045.java test/runtime/8000968/Test8000968.sh |
diffstat | 623 files changed, 8960 insertions(+), 6150 deletions(-) [+] |
line wrap: on
line diff
--- a/.hgignore Fri Oct 11 17:14:35 2013 +0200 +++ b/.hgignore Fri Oct 11 17:21:14 2013 +0200 @@ -79,3 +79,6 @@ workingsets.xml .buildbot/ graal.options +agent/build/* +agent/make/filelist +agent/make/sa17.tar.gz
--- a/.hgtags Fri Oct 11 17:14:35 2013 +0200 +++ b/.hgtags Fri Oct 11 17:21:14 2013 +0200 @@ -363,3 +363,9 @@ 9f71e36a471ae4a668e08827d33035963ed10c08 hs25-b42 5787fac72e760c6a5fd9efa113b0c75caf554136 jdk8-b100 46487ba40ff225654d0c51787ed3839bafcbd9f3 hs25-b43 +f6921c876db192bba389cec062855a66372da01c jdk8-b101 +530fe88b3b2c710f42810b3580d86a0d83ad6c1c hs25-b44 +c4697c1c448416108743b59118b4a2498b339d0c jdk8-b102 +7f55137d6aa81efc6eb0035813709f2cb6a26b8b hs25-b45 +6f9be7f87b9653e94fd8fb3070891a0cc91b15bf jdk8-b103 +580430d131ccd475e2f2ad4006531b8c4813d102 hs25-b46
--- a/agent/src/share/classes/sun/jvm/hotspot/jdi/JVMTIThreadState.java Fri Oct 11 17:14:35 2013 +0200 +++ b/agent/src/share/classes/sun/jvm/hotspot/jdi/JVMTIThreadState.java Fri Oct 11 17:21:14 2013 +0200 @@ -29,11 +29,10 @@ public static final int JVMTI_THREAD_STATE_ALIVE = 0x0001; public static final int JVMTI_THREAD_STATE_TERMINATED = 0x0002; public static final int JVMTI_THREAD_STATE_RUNNABLE = 0x0004; - public static final int JVMTI_THREAD_STATE_WAITING = 0x0008; + public static final int JVMTI_THREAD_STATE_WAITING = 0x0080; public static final int JVMTI_THREAD_STATE_WAITING_INDEFINITELY = 0x0010; public static final int JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT = 0x0020; public static final int JVMTI_THREAD_STATE_SLEEPING = 0x0040; - public static final int JVMTI_THREAD_STATE_WAITING_FOR_NOTIFICATION = 0x0080; public static final int JVMTI_THREAD_STATE_IN_OBJECT_WAIT = 0x0100; public static final int JVMTI_THREAD_STATE_PARKED = 0x0200; public static final int JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER = 0x0400;
--- a/agent/src/share/classes/sun/jvm/hotspot/opto/PhaseCFG.java Fri Oct 11 17:14:35 2013 +0200 +++ b/agent/src/share/classes/sun/jvm/hotspot/opto/PhaseCFG.java Fri Oct 11 17:21:14 2013 +0200 @@ -44,7 +44,7 @@ Type type = db.lookupType("PhaseCFG"); numBlocksField = new CIntField(type.getCIntegerField("_num_blocks"), 0); blocksField = type.getAddressField("_blocks"); - bbsField = type.getAddressField("_bbs"); + bbsField = type.getAddressField("_node_to_block_mapping"); brootField = type.getAddressField("_broot"); }
--- a/agent/src/share/classes/sun/jvm/hotspot/runtime/OSThread.java Fri Oct 11 17:14:35 2013 +0200 +++ b/agent/src/share/classes/sun/jvm/hotspot/runtime/OSThread.java Fri Oct 11 17:21:14 2013 +0200 @@ -32,7 +32,7 @@ // to the sys_thread_t structure of the classic JVM implementation. public class OSThread extends VMObject { private static JIntField interruptedField; - private static JIntField threadIdField; + private static Field threadIdField; static { VM.registerVMInitializedObserver(new Observer() { public void update(Observable o, Object data) { @@ -44,7 +44,7 @@ private static synchronized void initialize(TypeDataBase db) { Type type = db.lookupType("OSThread"); interruptedField = type.getJIntField("_interrupted"); - threadIdField = type.getJIntField("_thread_id"); + threadIdField = type.getField("_thread_id"); } public OSThread(Address addr) { @@ -56,7 +56,7 @@ } public int threadId() { - return (int)threadIdField.getValue(addr); + return threadIdField.getJInt(addr); } }
--- a/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassDump.java Fri Oct 11 17:14:35 2013 +0200 +++ b/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassDump.java Fri Oct 11 17:21:14 2013 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 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 @@ -74,23 +74,24 @@ public void run() { // Ready to go with the database... try { - // The name of the filter always comes from a System property. - // If we have a pkgList, pass it, otherwise let the filter read - // its own System property for the list of classes. - String filterClassName = System.getProperty("sun.jvm.hotspot.tools.jcore.filter", - "sun.jvm.hotspot.tools.jcore.PackageNameFilter"); - try { - Class filterClass = Class.forName(filterClassName); - if (pkgList == null) { - classFilter = (ClassFilter) filterClass.newInstance(); - } else { - Constructor con = filterClass.getConstructor(String.class); - classFilter = (ClassFilter) con.newInstance(pkgList); + if (classFilter == null) { + // If not already set, the name of the filter comes from a System property. + // If we have a pkgList, pass it, otherwise let the filter read + // its own System property for the list of classes. + String filterClassName = System.getProperty("sun.jvm.hotspot.tools.jcore.filter", + "sun.jvm.hotspot.tools.jcore.PackageNameFilter"); + try { + Class filterClass = Class.forName(filterClassName); + if (pkgList == null) { + classFilter = (ClassFilter) filterClass.newInstance(); + } else { + Constructor con = filterClass.getConstructor(String.class); + classFilter = (ClassFilter) con.newInstance(pkgList); + } + } catch(Exception exp) { + System.err.println("Warning: Can not create class filter!"); } - } catch(Exception exp) { - System.err.println("Warning: Can not create class filter!"); } - String outputDirectory = System.getProperty("sun.jvm.hotspot.tools.jcore.outputDir", "."); setOutputDirectory(outputDirectory);
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/ArithmeticOperation.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/ArithmeticOperation.java Fri Oct 11 17:21:14 2013 +0200 @@ -22,9 +22,13 @@ */ package com.oracle.graal.api.code; +import com.oracle.graal.api.meta.*; + /** * An {@code ArithmeticOperation} is an operation that does primitive value arithmetic without side * effect. */ public interface ArithmeticOperation { + + Constant evalConst(Constant... inputs); }
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CodeCacheProvider.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CodeCacheProvider.java Fri Oct 11 17:21:14 2013 +0200 @@ -26,9 +26,9 @@ import com.oracle.graal.api.meta.*; /** - * Encapsulates the main functionality of the runtime for the compiler. + * Access to code cache related details and requirements. */ -public interface CodeCacheProvider extends MetaAccessProvider { +public interface CodeCacheProvider { /** * Adds the given compilation result as an implementation of the given method without making it @@ -56,7 +56,7 @@ /** * Gets the register configuration to use when compiling a given method. */ - RegisterConfig lookupRegisterConfig(); + RegisterConfig getRegisterConfig(); /** * Minimum size of the stack area reserved for outgoing parameters. This area is reserved in all @@ -72,13 +72,6 @@ ForeignCallLinkage lookupForeignCall(ForeignCallDescriptor descriptor); /** - * Encodes a deoptimization action and a deoptimization reason in an integer value. - * - * @return the encoded value as an integer - */ - int encodeDeoptActionAndReason(DeoptimizationAction action, DeoptimizationReason reason); - - /** * Determines if a {@link DataPatch} should be created for a given * {@linkplain Constant#getPrimitiveAnnotation() annotated} primitive constant that part of a * {@link CompilationResult}. A data patch is always created for an object constant.
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CodeUtil.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CodeUtil.java Fri Oct 11 17:21:14 2013 +0200 @@ -339,7 +339,7 @@ argTypes[argIndex++] = sig.getParameterType(i, null); } - RegisterConfig registerConfig = codeCache.lookupRegisterConfig(); + RegisterConfig registerConfig = codeCache.getRegisterConfig(); return registerConfig.getCallingConvention(type, retType, argTypes, codeCache.getTarget(), stackOnly); } }
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/DebugInfo.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/DebugInfo.java Fri Oct 11 17:21:14 2013 +0200 @@ -44,7 +44,6 @@ private final BytecodePosition bytecodePosition; private final BitSet registerRefMap; private final BitSet frameRefMap; - private final short deoptimizationReason; private RegisterSaveLayout calleeSaveInfo; /** @@ -55,11 +54,10 @@ * @param registerRefMap the register map * @param frameRefMap the reference map for {@code frame}, which may be {@code null} */ - public DebugInfo(BytecodePosition codePos, BitSet registerRefMap, BitSet frameRefMap, short deoptimizationReason) { + public DebugInfo(BytecodePosition codePos, BitSet registerRefMap, BitSet frameRefMap) { this.bytecodePosition = codePos; this.registerRefMap = registerRefMap; this.frameRefMap = frameRefMap; - this.deoptimizationReason = deoptimizationReason; } /** @@ -127,15 +125,6 @@ } /** - * Identifies the reason in case a deoptimization happens at this program counter. - * - * @return the reason of the deoptimization - */ - public short getDeoptimizationReason() { - return deoptimizationReason; - } - - /** * Sets the map from the registers (in the caller's frame) to the slots where they are saved in * the current frame. */
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/DelegatingCodeCacheProvider.java Fri Oct 11 17:14:35 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,72 +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.api.code; - -import com.oracle.graal.api.meta.*; - -/** - * A {@link CodeCacheProvider} that delegates to another {@link CodeCacheProvider}. - */ -public class DelegatingCodeCacheProvider extends DelegatingMetaAccessProvider implements CodeCacheProvider { - - public DelegatingCodeCacheProvider(CodeCacheProvider delegate) { - super(delegate); - } - - @Override - protected CodeCacheProvider delegate() { - return (CodeCacheProvider) super.delegate(); - } - - public InstalledCode addMethod(ResolvedJavaMethod method, CompilationResult compResult) { - return delegate().addMethod(method, compResult); - } - - public String disassemble(CompilationResult compResult, InstalledCode installedCode) { - return delegate().disassemble(compResult, installedCode); - } - - public RegisterConfig lookupRegisterConfig() { - return delegate().lookupRegisterConfig(); - } - - public int getMinimumOutgoingSize() { - return delegate().getMinimumOutgoingSize(); - } - - public ForeignCallLinkage lookupForeignCall(ForeignCallDescriptor descriptor) { - return delegate().lookupForeignCall(descriptor); - } - - public int encodeDeoptActionAndReason(DeoptimizationAction action, DeoptimizationReason reason) { - return delegate().encodeDeoptActionAndReason(action, reason); - } - - public boolean needsDataPatch(Constant constant) { - return delegate().needsDataPatch(constant); - } - - public TargetDescription getTarget() { - return delegate().getTarget(); - } -}
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/DeoptimizationAction.java Fri Oct 11 17:14:35 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,70 +0,0 @@ -/* - * Copyright (c) 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.code; - -/** - * Specifies the action that should be taken by the runtime in case a certain deoptimization is - * triggered. - */ -public enum DeoptimizationAction { - /** - * Do not invalidate the machine code. This is typically used when deoptimizing at a point where - * it's highly likely nothing will change the likelihood of the deoptimization happening again. - * For example, a compiled array allocation where the size is negative. - */ - None(false), - - /** - * Do not invalidate the machine code, but schedule a recompilation if this deoptimization is - * triggered too often. - */ - RecompileIfTooManyDeopts(true), - - /** - * Invalidate the machine code and reset the profiling information. - */ - InvalidateReprofile(true), - - /** - * Invalidate the machine code and immediately schedule a recompilation. This is typically used - * when deoptimizing to resolve an unresolved symbol in which case extra profiling is not - * required to determine that the deoptimization will not re-occur. - */ - InvalidateRecompile(true), - - /** - * Invalidate the machine code and stop compiling the outermost method of this compilation. - */ - InvalidateStopCompiling(true); - - private final boolean invalidatesCompilation; - - private DeoptimizationAction(boolean invalidatesCompilation) { - this.invalidatesCompilation = invalidatesCompilation; - } - - public boolean doesInvalidateCompilation() { - return invalidatesCompilation; - } - -}
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/SpeculationLog.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/SpeculationLog.java Fri Oct 11 17:21:14 2013 +0200 @@ -36,11 +36,11 @@ public static final int MAX_CACHE_SIZE = 1 << 15; - private List<DeoptimizationReason> speculations = new ArrayList<>(); + private List<Object> speculations = new ArrayList<>(); private boolean[] map = new boolean[10]; - private Set<DeoptimizationReason> snapshot = new HashSet<>(); + private Set<Object> snapshot = new HashSet<>(); - public short addSpeculation(DeoptimizationReason reason) { + private short addSpeculation(Object reason) { short index = (short) speculations.indexOf(reason); if (index != -1) { // Nothing to add, reason already registered. @@ -68,7 +68,10 @@ } } - public boolean maySpeculate(DeoptimizationReason reason) { - return !snapshot.contains(reason); + public Constant maySpeculate(Object reason) { + if (snapshot.contains(reason)) { + return null; + } + return Constant.forShort(addSpeculation(reason)); } }
--- a/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/MethodUniverse.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/MethodUniverse.java Fri Oct 11 17:21:14 2013 +0200 @@ -38,11 +38,11 @@ public MethodUniverse() { for (Class c : classes) { for (Method m : c.getDeclaredMethods()) { - ResolvedJavaMethod method = runtime.lookupJavaMethod(m); + ResolvedJavaMethod method = metaAccess.lookupJavaMethod(m); methods.put(m, method); } for (Constructor m : c.getDeclaredConstructors()) { - constructors.put(m, runtime.lookupJavaConstructor(m)); + constructors.put(m, metaAccess.lookupJavaConstructor(m)); } } }
--- a/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestJavaMethod.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestJavaMethod.java Fri Oct 11 17:21:14 2013 +0200 @@ -50,7 +50,7 @@ for (Map.Entry<Method, ResolvedJavaMethod> e : methods.entrySet()) { Class expected = e.getKey().getDeclaringClass(); ResolvedJavaType actual = e.getValue().getDeclaringClass(); - assertTrue(actual.equals(runtime.lookupJavaType(expected))); + assertTrue(actual.equals(metaAccess.lookupJavaType(expected))); } }
--- a/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestJavaType.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestJavaType.java Fri Oct 11 17:21:14 2013 +0200 @@ -39,7 +39,7 @@ @Test public void getKindTest() { for (Class c : classes) { - JavaType type = runtime.lookupJavaType(c); + JavaType type = metaAccess.lookupJavaType(c); Kind expected = Kind.fromJavaClass(c); Kind actual = type.getKind(); assertEquals(expected, actual);
--- a/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestMetaAccessProvider.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestMetaAccessProvider.java Fri Oct 11 17:21:14 2013 +0200 @@ -39,7 +39,7 @@ @Test public void lookupJavaTypeTest() { for (Class c : classes) { - ResolvedJavaType type = runtime.lookupJavaType(c); + ResolvedJavaType type = metaAccess.lookupJavaType(c); assertNotNull(type); assertEquals(c.getModifiers(), type.getModifiers()); if (!type.isArray()) { @@ -53,12 +53,12 @@ public void lookupJavaMethodTest() { for (Class c : classes) { for (Method reflect : c.getDeclaredMethods()) { - ResolvedJavaMethod method = runtime.lookupJavaMethod(reflect); + ResolvedJavaMethod method = metaAccess.lookupJavaMethod(reflect); assertNotNull(method); int expected = reflect.getModifiers() & Modifier.methodModifiers(); int actual = method.getModifiers(); assertEquals(String.format("%s: 0x%x != 0x%x", reflect, expected, actual), expected, actual); - assertTrue(method.getDeclaringClass().equals(runtime.lookupJavaType(reflect.getDeclaringClass()))); + assertTrue(method.getDeclaringClass().equals(metaAccess.lookupJavaType(reflect.getDeclaringClass()))); } } } @@ -67,12 +67,12 @@ public void lookupJavaFieldTest() { for (Class c : classes) { for (Field reflect : c.getDeclaredFields()) { - ResolvedJavaField field = runtime.lookupJavaField(reflect); + ResolvedJavaField field = metaAccess.lookupJavaField(reflect); assertNotNull(field); int expected = reflect.getModifiers() & Modifier.fieldModifiers(); int actual = field.getModifiers(); assertEquals(String.format("%s: 0x%x != 0x%x", reflect, expected, actual), expected, actual); - assertTrue(field.getDeclaringClass().equals(runtime.lookupJavaType(reflect.getDeclaringClass()))); + assertTrue(field.getDeclaringClass().equals(metaAccess.lookupJavaType(reflect.getDeclaringClass()))); } } } @@ -82,11 +82,11 @@ for (Constant c : constants) { if (c.getKind() == Kind.Object && !c.isNull()) { Object o = c.asObject(); - ResolvedJavaType type = runtime.lookupJavaType(c); + ResolvedJavaType type = metaAccess.lookupJavaType(c); assertNotNull(type); - assertTrue(type.equals(runtime.lookupJavaType(o.getClass()))); + assertTrue(type.equals(metaAccess.lookupJavaType(o.getClass()))); } else { - assertEquals(runtime.lookupJavaType(c), null); + assertEquals(metaAccess.lookupJavaType(c), null); } } } @@ -96,9 +96,9 @@ for (Constant c1 : constants) { for (Constant c2 : constants) { // test symmetry - assertEquals(runtime.constantEquals(c1, c2), runtime.constantEquals(c2, c1)); + assertEquals(constantReflection.constantEquals(c1, c2), constantReflection.constantEquals(c2, c1)); if (c1.getKind() != Kind.Object && c2.getKind() != Kind.Object) { - assertEquals(c1.equals(c2), runtime.constantEquals(c2, c1)); + assertEquals(c1.equals(c2), constantReflection.constantEquals(c2, c1)); } } } @@ -107,7 +107,7 @@ @Test public void lookupArrayLengthTest() { for (Constant c : constants) { - Integer actual = runtime.lookupArrayLength(c); + Integer actual = constantReflection.lookupArrayLength(c); if (c.getKind() != Kind.Object || c.isNull() || !c.asObject().getClass().isArray()) { assertNull(actual); } else {
--- a/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaMethod.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaMethod.java Fri Oct 11 17:21:14 2013 +0200 @@ -174,13 +174,13 @@ @Test public void getExceptionHandlersTest() throws NoSuchMethodException { - ResolvedJavaMethod method = runtime.lookupJavaMethod(getClass().getDeclaredMethod("methodWithExceptionHandlers", String.class, Object.class)); + ResolvedJavaMethod method = metaAccess.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)); + handlers[0].getCatchType().equals(metaAccess.lookupJavaType(IndexOutOfBoundsException.class)); + handlers[1].getCatchType().equals(metaAccess.lookupJavaType(NullPointerException.class)); + handlers[2].getCatchType().equals(metaAccess.lookupJavaType(RuntimeException.class)); } private static String nullPointerExceptionOnFirstLine(Object o, String ignored) { @@ -194,7 +194,7 @@ 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)); + ResolvedJavaMethod method = metaAccess.lookupJavaMethod(getClass().getDeclaredMethod("nullPointerExceptionOnFirstLine", Object.class, String.class)); StackTraceElement actual = method.asStackTraceElement(0); assertEquals(expected, actual); } @@ -211,7 +211,7 @@ @Test(timeout = 1000L) public void getAnnotationTest() throws NoSuchMethodException { - ResolvedJavaMethod method = runtime.lookupJavaMethod(getClass().getDeclaredMethod("getAnnotationTest")); + ResolvedJavaMethod method = metaAccess.lookupJavaMethod(getClass().getDeclaredMethod("getAnnotationTest")); Test annotation = method.getAnnotation(Test.class); assertNotNull(annotation); assertEquals(1000L, annotation.timeout()); @@ -231,7 +231,7 @@ @Test public void getParameterAnnotationsTest() throws NoSuchMethodException { - ResolvedJavaMethod method = runtime.lookupJavaMethod(getClass().getDeclaredMethod("methodWithAnnotatedParameters", HashMap.class, Class.class)); + ResolvedJavaMethod method = metaAccess.lookupJavaMethod(getClass().getDeclaredMethod("methodWithAnnotatedParameters", HashMap.class, Class.class)); Annotation[][] annotations = method.getParameterAnnotations(); assertEquals(2, annotations.length); assertEquals(1, annotations[0].length); @@ -243,7 +243,7 @@ @Test public void getGenericParameterTypesTest() throws NoSuchMethodException { - ResolvedJavaMethod method = runtime.lookupJavaMethod(getClass().getDeclaredMethod("methodWithAnnotatedParameters", HashMap.class, Class.class)); + ResolvedJavaMethod method = metaAccess.lookupJavaMethod(getClass().getDeclaredMethod("methodWithAnnotatedParameters", HashMap.class, Class.class)); Type[] genericParameterTypes = method.getGenericParameterTypes(); assertEquals(2, genericParameterTypes.length); assertEquals("java.util.HashMap<java.lang.String, java.lang.String>", genericParameterTypes[0].toString()); @@ -252,8 +252,8 @@ @Test 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)); + ResolvedJavaMethod method1 = metaAccess.lookupJavaMethod(getClass().getDeclaredMethod("methodWithAnnotatedParameters", HashMap.class, Class.class)); + ResolvedJavaMethod method2 = metaAccess.lookupJavaMethod(getClass().getDeclaredMethod("nullPointerExceptionOnFirstLine", Object.class, String.class)); assertEquals(0, method1.getMaxLocals()); assertEquals(2, method2.getMaxLocals()); @@ -261,8 +261,8 @@ @Test 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)); + ResolvedJavaMethod method1 = metaAccess.lookupJavaMethod(getClass().getDeclaredMethod("methodWithAnnotatedParameters", HashMap.class, Class.class)); + ResolvedJavaMethod method2 = metaAccess.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 // JSR 292 also sometimes need one more stack slot
--- a/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaType.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaType.java Fri Oct 11 17:21:14 2013 +0200 @@ -48,7 +48,7 @@ @Test public void findInstanceFieldWithOffsetTest() { for (Class c : classes) { - ResolvedJavaType type = runtime.lookupJavaType(c); + ResolvedJavaType type = metaAccess.lookupJavaType(c); Set<Field> reflectionFields = getInstanceFields(c, true); for (Field f : reflectionFields) { ResolvedJavaField rf = lookupField(type.getInstanceFields(true), f); @@ -64,7 +64,7 @@ @Test public void isInterfaceTest() { for (Class c : classes) { - ResolvedJavaType type = runtime.lookupJavaType(c); + ResolvedJavaType type = metaAccess.lookupJavaType(c); boolean expected = c.isInterface(); boolean actual = type.isInterface(); assertEquals(expected, actual); @@ -74,7 +74,7 @@ @Test public void isInstanceClassTest() { for (Class c : classes) { - ResolvedJavaType type = runtime.lookupJavaType(c); + ResolvedJavaType type = metaAccess.lookupJavaType(c); boolean expected = !c.isArray() && !c.isPrimitive() && !c.isInterface(); boolean actual = type.isInstanceClass(); assertEquals(expected, actual); @@ -84,7 +84,7 @@ @Test public void isArrayTest() { for (Class c : classes) { - ResolvedJavaType type = runtime.lookupJavaType(c); + ResolvedJavaType type = metaAccess.lookupJavaType(c); boolean expected = c.isArray(); boolean actual = type.isArray(); assertEquals(expected, actual); @@ -94,7 +94,7 @@ @Test public void getModifiersTest() { for (Class c : classes) { - ResolvedJavaType type = runtime.lookupJavaType(c); + ResolvedJavaType type = metaAccess.lookupJavaType(c); int expected = c.getModifiers(); int actual = type.getModifiers(); assertEquals(expected, actual); @@ -108,8 +108,8 @@ Class<?> c1 = all[i]; for (int j = i; j < all.length; j++) { Class<?> c2 = all[j]; - ResolvedJavaType t1 = runtime.lookupJavaType(c1); - ResolvedJavaType t2 = runtime.lookupJavaType(c2); + ResolvedJavaType t1 = metaAccess.lookupJavaType(c1); + ResolvedJavaType t2 = metaAccess.lookupJavaType(c2); boolean expected = c1.isAssignableFrom(c2); boolean actual = t1.isAssignableFrom(t2); assertEquals(expected, actual); @@ -127,7 +127,7 @@ Object o = c.asObject(); Class<? extends Object> cls = o.getClass(); while (cls != null) { - ResolvedJavaType type = runtime.lookupJavaType(cls); + ResolvedJavaType type = metaAccess.lookupJavaType(cls); boolean expected = cls.isInstance(o); boolean actual = type.isInstance(c); assertEquals(expected, actual); @@ -153,14 +153,14 @@ @Test public void asExactTypeTest() { for (Class c : classes) { - ResolvedJavaType type = runtime.lookupJavaType(c); + ResolvedJavaType type = metaAccess.lookupJavaType(c); ResolvedJavaType exactType = type.asExactType(); Class expected = asExactClass(c); if (expected == null) { assertTrue("exact(" + c.getName() + ") != null", exactType == null); } else { assertNotNull(exactType); - assertTrue(exactType.equals(runtime.lookupJavaType(expected))); + assertTrue(exactType.equals(metaAccess.lookupJavaType(expected))); } } } @@ -168,14 +168,14 @@ @Test public void getSuperclassTest() { for (Class c : classes) { - ResolvedJavaType type = runtime.lookupJavaType(c); + ResolvedJavaType type = metaAccess.lookupJavaType(c); Class expected = c.getSuperclass(); ResolvedJavaType actual = type.getSuperclass(); if (expected == null) { assertTrue(actual == null); } else { assertNotNull(actual); - assertTrue(actual.equals(runtime.lookupJavaType(expected))); + assertTrue(actual.equals(metaAccess.lookupJavaType(expected))); } } } @@ -183,12 +183,12 @@ @Test public void getInterfacesTest() { for (Class c : classes) { - ResolvedJavaType type = runtime.lookupJavaType(c); + ResolvedJavaType type = metaAccess.lookupJavaType(c); Class[] expected = c.getInterfaces(); ResolvedJavaType[] actual = type.getInterfaces(); assertEquals(expected.length, actual.length); for (int i = 0; i < expected.length; i++) { - assertTrue(actual[i].equals(runtime.lookupJavaType(expected[i]))); + assertTrue(actual[i].equals(metaAccess.lookupJavaType(expected[i]))); } } } @@ -234,15 +234,15 @@ Class<?> c1 = all[i]; for (int j = i; j < all.length; j++) { Class<?> c2 = all[j]; - ResolvedJavaType t1 = runtime.lookupJavaType(c1); - ResolvedJavaType t2 = runtime.lookupJavaType(c2); + ResolvedJavaType t1 = metaAccess.lookupJavaType(c1); + ResolvedJavaType t2 = metaAccess.lookupJavaType(c2); Class expected = findLeastCommonAncestor(c1, c2); ResolvedJavaType actual = t1.findLeastCommonAncestor(t2); if (expected == null) { assertTrue(actual == null); } else { assertNotNull(actual); - assertTrue(actual.equals(runtime.lookupJavaType(expected))); + assertTrue(actual.equals(metaAccess.lookupJavaType(expected))); } } } @@ -277,7 +277,7 @@ if (expected == null) { assertNull(subtype); } else { - assertTrue(subtype.equals(runtime.lookupJavaType(expected))); + assertTrue(subtype.equals(metaAccess.lookupJavaType(expected))); } } @@ -294,18 +294,18 @@ @Test public void findUniqueConcreteSubtypeTest() { - ResolvedJavaType base = runtime.lookupJavaType(Base.class); + ResolvedJavaType base = metaAccess.lookupJavaType(Base.class); checkConcreteSubtype(base, Base.class); - ResolvedJavaType a1 = runtime.lookupJavaType(Abstract1.class); - ResolvedJavaType c1 = runtime.lookupJavaType(Concrete1.class); + ResolvedJavaType a1 = metaAccess.lookupJavaType(Abstract1.class); + ResolvedJavaType c1 = metaAccess.lookupJavaType(Concrete1.class); checkConcreteSubtype(base, null); checkConcreteSubtype(a1, Concrete1.class); checkConcreteSubtype(c1, Concrete1.class); - ResolvedJavaType i1 = runtime.lookupJavaType(Interface1.class); - ResolvedJavaType c2 = runtime.lookupJavaType(Concrete2.class); + ResolvedJavaType i1 = metaAccess.lookupJavaType(Interface1.class); + ResolvedJavaType c2 = metaAccess.lookupJavaType(Concrete2.class); checkConcreteSubtype(base, null); checkConcreteSubtype(a1, null); @@ -313,11 +313,11 @@ checkConcreteSubtype(i1, Concrete2.class); checkConcreteSubtype(c2, Concrete2.class); - ResolvedJavaType c3 = runtime.lookupJavaType(Concrete3.class); + ResolvedJavaType c3 = metaAccess.lookupJavaType(Concrete3.class); checkConcreteSubtype(c2, null); checkConcreteSubtype(c3, Concrete3.class); - ResolvedJavaType a4 = runtime.lookupJavaType(Abstract4.class); + ResolvedJavaType a4 = metaAccess.lookupJavaType(Abstract4.class); checkConcreteSubtype(c3, null); checkConcreteSubtype(a4, null); } @@ -325,13 +325,13 @@ @Test public void getComponentTypeTest() { for (Class c : classes) { - ResolvedJavaType type = runtime.lookupJavaType(c); + ResolvedJavaType type = metaAccess.lookupJavaType(c); Class expected = c.getComponentType(); ResolvedJavaType actual = type.getComponentType(); if (expected == null) { assertNull(actual); } else { - assertTrue(actual.equals(runtime.lookupJavaType(expected))); + assertTrue(actual.equals(metaAccess.lookupJavaType(expected))); } } } @@ -340,10 +340,10 @@ public void getArrayClassTest() { for (Class c : classes) { if (c != void.class) { - ResolvedJavaType type = runtime.lookupJavaType(c); + ResolvedJavaType type = metaAccess.lookupJavaType(c); Class expected = getArrayClass(c); ResolvedJavaType actual = type.getArrayClass(); - assertTrue(actual.equals(runtime.lookupJavaType(expected))); + assertTrue(actual.equals(metaAccess.lookupJavaType(expected))); } } } @@ -399,9 +399,11 @@ } for (Method m : c.getDeclaredMethods()) { if (!isStatic(m.getModifiers()) && !isPrivate(m.getModifiers())) { - Method overridden = vtable.methods.put(new NameAndSignature(m), m); - if (overridden != null) { - // println(m + " overrides " + overridden); + if (isAbstract(m.getModifiers())) { + // A subclass makes a concrete method in a superclass abstract + vtable.methods.remove(new NameAndSignature(m)); + } else { + vtable.methods.put(new NameAndSignature(m), m); } } } @@ -438,25 +440,36 @@ @Test public void resolveMethodTest() { for (Class c : classes) { - if (!c.isPrimitive() && !c.isInterface()) { - ResolvedJavaType type = runtime.lookupJavaType(c); + if (c.isInterface() || c.isPrimitive()) { + ResolvedJavaType type = metaAccess.lookupJavaType(c); + for (Method m : c.getDeclaredMethods()) { + ResolvedJavaMethod impl = type.resolveMethod(metaAccess.lookupJavaMethod(m)); + assertEquals(m.toString(), null, impl); + } + } else { + ResolvedJavaType type = metaAccess.lookupJavaType(c); VTable vtable = getVTable(c); for (Method impl : vtable.methods.values()) { Set<Method> decls = findDeclarations(impl, c); for (Method decl : decls) { - ResolvedJavaMethod m = runtime.lookupJavaMethod(decl); - ResolvedJavaMethod i = runtime.lookupJavaMethod(impl); + ResolvedJavaMethod m = metaAccess.lookupJavaMethod(decl); + ResolvedJavaMethod i = metaAccess.lookupJavaMethod(impl); checkResolveMethod(type, m, i); } } + for (Method m : c.getDeclaredMethods()) { + ResolvedJavaMethod impl = type.resolveMethod(metaAccess.lookupJavaMethod(m)); + ResolvedJavaMethod expected = isAbstract(m.getModifiers()) ? null : impl; + assertEquals(type + " " + m.toString(), expected, impl); + } } } } @Test public void findUniqueConcreteMethodTest() throws NoSuchMethodException { - ResolvedJavaMethod thisMethod = runtime.lookupJavaMethod(getClass().getDeclaredMethod("findUniqueConcreteMethodTest")); - ResolvedJavaMethod ucm = runtime.lookupJavaType(getClass()).findUniqueConcreteMethod(thisMethod); + ResolvedJavaMethod thisMethod = metaAccess.lookupJavaMethod(getClass().getDeclaredMethod("findUniqueConcreteMethodTest")); + ResolvedJavaMethod ucm = metaAccess.lookupJavaType(getClass()).findUniqueConcreteMethod(thisMethod); assertEquals(thisMethod, ucm); } @@ -477,8 +490,8 @@ } 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())); + return rjf.getDeclaringClass().equals(metaAccess.lookupJavaType(f.getDeclaringClass())) && rjf.getName().equals(f.getName()) && + rjf.getType().resolve(rjf.getDeclaringClass()).equals(metaAccess.lookupJavaType(f.getType())); } public ResolvedJavaField lookupField(ResolvedJavaField[] fields, Field key) { @@ -502,10 +515,10 @@ } private boolean isHiddenFromReflection(ResolvedJavaField f) { - if (f.getDeclaringClass().equals(runtime.lookupJavaType(Throwable.class)) && f.getName().equals("backtrace")) { + if (f.getDeclaringClass().equals(metaAccess.lookupJavaType(Throwable.class)) && f.getName().equals("backtrace")) { return true; } - if (f.getDeclaringClass().equals(runtime.lookupJavaType(ConstantPool.class)) && f.getName().equals("constantPoolOop")) { + if (f.getDeclaringClass().equals(metaAccess.lookupJavaType(ConstantPool.class)) && f.getName().equals("constantPoolOop")) { return true; } return false; @@ -514,7 +527,7 @@ @Test public void getInstanceFieldsTest() { for (Class c : classes) { - ResolvedJavaType type = runtime.lookupJavaType(c); + ResolvedJavaType type = metaAccess.lookupJavaType(c); for (boolean includeSuperclasses : new boolean[]{true, false}) { Set<Field> expected = getInstanceFields(c, includeSuperclasses); ResolvedJavaField[] actual = type.getInstanceFields(includeSuperclasses); @@ -535,9 +548,52 @@ } @Test + public void getDeclaredMethodsTest() { + for (Class c : classes) { + ResolvedJavaType type = metaAccess.lookupJavaType(c); + Method[] raw = c.getDeclaredMethods(); + Set<ResolvedJavaMethod> expected = new HashSet<>(); + for (Method m : raw) { + ResolvedJavaMethod resolvedMethod = metaAccess.lookupJavaMethod(m); + assertNotNull(resolvedMethod); + expected.add(resolvedMethod); + } + Set<ResolvedJavaMethod> actual = new HashSet<>(Arrays.asList(type.getDeclaredMethods())); + assertEquals(expected, actual); + } + } + + static class A { + static String name = "foo"; + } + + static class B extends A { + } + + static class C { + } + + static class D { + void foo() { + // use of assertions causes the class to have a <clinit> + assert getClass() != null; + } + } + + @Test + public void getClassInitializerTest() { + assertNotNull(metaAccess.lookupJavaType(A.class).getClassInitializer()); + assertNotNull(metaAccess.lookupJavaType(D.class).getClassInitializer()); + assertNull(metaAccess.lookupJavaType(B.class).getClassInitializer()); + assertNull(metaAccess.lookupJavaType(C.class).getClassInitializer()); + assertNull(metaAccess.lookupJavaType(int.class).getClassInitializer()); + assertNull(metaAccess.lookupJavaType(void.class).getClassInitializer()); + } + + @Test public void getAnnotationTest() { for (Class c : classes) { - ResolvedJavaType type = runtime.lookupJavaType(c); + ResolvedJavaType type = metaAccess.lookupJavaType(c); for (Annotation a : c.getAnnotations()) { assertEquals(a, type.getAnnotation(a.annotationType())); } @@ -547,14 +603,14 @@ @Test public void memberClassesTest() { for (Class c : classes) { - ResolvedJavaType type = runtime.lookupJavaType(c); + ResolvedJavaType type = metaAccess.lookupJavaType(c); assertEquals(c.isLocalClass(), type.isLocal()); assertEquals(c.isMemberClass(), type.isMember()); Class enclc = c.getEnclosingClass(); ResolvedJavaType enclt = type.getEnclosingType(); assertFalse(enclc == null ^ enclt == null); if (enclc != null) { - assertEquals(enclt, runtime.lookupJavaType(enclc)); + assertEquals(enclt, metaAccess.lookupJavaType(enclc)); } } } @@ -562,7 +618,7 @@ @Test public void classFilePathTest() { for (Class c : classes) { - ResolvedJavaType type = runtime.lookupJavaType(c); + ResolvedJavaType type = metaAccess.lookupJavaType(c); URL path = type.getClassFilePath(); if (type.isPrimitive() || type.isArray()) { assertEquals(null, path); @@ -591,7 +647,6 @@ "initialize", "isPrimitive", "newArray", - "getDeclaredMethods", "getDeclaredConstructors", "isInitialized", "isLinked",
--- a/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TypeUniverse.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TypeUniverse.java Fri Oct 11 17:21:14 2013 +0200 @@ -40,7 +40,8 @@ public class TypeUniverse { public final Unsafe unsafe; - public final MetaAccessProvider runtime = Graal.getRequiredCapability(MetaAccessProvider.class); + public final MetaAccessProvider metaAccess = Graal.getRequiredCapability(MetaAccessProvider.class); + public final ConstantReflectionProvider constantReflection = Graal.getRequiredCapability(ConstantReflectionProvider.class); public final Collection<Class<?>> classes = new HashSet<>(); public final Map<Class<?>, Class<?>> arrayClasses = new HashMap<>(); public final List<Constant> constants = new ArrayList<>();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ConstantReflectionProvider.java Fri Oct 11 17:21:14 2013 +0200 @@ -0,0 +1,55 @@ +/* + * 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.api.meta; + +/** + * Reflection operations on values represented as {@linkplain Constant constants}. + */ +public interface ConstantReflectionProvider { + + /** + * Compares two constants for equality. The equality relationship is symmetric. + * + * @return {@code true} if the two parameters represent the same runtime object, {@code false} + * otherwise + */ + boolean constantEquals(Constant x, Constant y); + + /** + * Returns the length of an array that is wrapped in a {@link Constant} object. If {@code array} + * is not an array, or the array length is not available at this point, the return value is + * {@code null}. + */ + Integer lookupArrayLength(Constant array); + + /** + * Reads a value of this kind using a base address and a displacement. + * + * @param base the base address from which the value is read + * @param displacement the displacement within the object in bytes + * @param compressible whether this is a read of a compressed or an uncompressed pointer + * @return the read value encapsulated in a {@link Constant} object, or {@code null} if the + * value cannot be read. + */ + Constant readUnsafeConstant(Kind kind, Object base, long displacement, boolean compressible); +}
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/DelegatingMetaAccessProvider.java Fri Oct 11 17:14:35 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,89 +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.api.meta; - -import java.lang.reflect.*; - -/** - * A {@link MetaAccessProvider} that delegates to another {@link MetaAccessProvider}. - */ -public class DelegatingMetaAccessProvider implements MetaAccessProvider { - - private final MetaAccessProvider delegate; - - public DelegatingMetaAccessProvider(MetaAccessProvider delegate) { - this.delegate = delegate; - } - - protected MetaAccessProvider delegate() { - return delegate; - } - - public ResolvedJavaType lookupJavaType(Class<?> clazz) { - return delegate.lookupJavaType(clazz); - } - - public ResolvedJavaMethod lookupJavaMethod(Method reflectionMethod) { - return delegate.lookupJavaMethod(reflectionMethod); - } - - public ResolvedJavaMethod lookupJavaConstructor(Constructor reflectionConstructor) { - return delegate.lookupJavaConstructor(reflectionConstructor); - } - - public ResolvedJavaField lookupJavaField(Field reflectionField) { - return delegate.lookupJavaField(reflectionField); - } - - public ResolvedJavaType lookupJavaType(Constant constant) { - return delegate.lookupJavaType(constant); - } - - public Signature parseMethodDescriptor(String methodDescriptor) { - return delegate.parseMethodDescriptor(methodDescriptor); - } - - public boolean constantEquals(Constant x, Constant y) { - return delegate.constantEquals(x, y); - } - - public Integer lookupArrayLength(Constant array) { - return delegate.lookupArrayLength(array); - } - - public Constant readUnsafeConstant(Kind kind, Object base, long displacement, boolean compressible) { - return delegate.readUnsafeConstant(kind, base, displacement, compressible); - } - - public boolean isReexecutable(ForeignCallDescriptor descriptor) { - return delegate.isReexecutable(descriptor); - } - - public LocationIdentity[] getKilledLocations(ForeignCallDescriptor descriptor) { - return delegate.getKilledLocations(descriptor); - } - - public boolean canDeoptimize(ForeignCallDescriptor descriptor) { - return delegate.canDeoptimize(descriptor); - } -}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/DeoptimizationAction.java Fri Oct 11 17:21:14 2013 +0200 @@ -0,0 +1,70 @@ +/* + * Copyright (c) 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; + +/** + * Specifies the action that should be taken by the runtime in case a certain deoptimization is + * triggered. + */ +public enum DeoptimizationAction { + /** + * Do not invalidate the machine code. This is typically used when deoptimizing at a point where + * it's highly likely nothing will change the likelihood of the deoptimization happening again. + * For example, a compiled array allocation where the size is negative. + */ + None(false), + + /** + * Do not invalidate the machine code, but schedule a recompilation if this deoptimization is + * triggered too often. + */ + RecompileIfTooManyDeopts(true), + + /** + * Invalidate the machine code and reset the profiling information. + */ + InvalidateReprofile(true), + + /** + * Invalidate the machine code and immediately schedule a recompilation. This is typically used + * when deoptimizing to resolve an unresolved symbol in which case extra profiling is not + * required to determine that the deoptimization will not re-occur. + */ + InvalidateRecompile(true), + + /** + * Invalidate the machine code and stop compiling the outermost method of this compilation. + */ + InvalidateStopCompiling(true); + + private final boolean invalidatesCompilation; + + private DeoptimizationAction(boolean invalidatesCompilation) { + this.invalidatesCompilation = invalidatesCompilation; + } + + public boolean doesInvalidateCompilation() { + return invalidatesCompilation; + } + +}
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/MemoryMap.java Fri Oct 11 17:14:35 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,28 +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.api.meta; - -public interface MemoryMap<T> { - - T getLastLocationAccess(LocationIdentity locationIdentity); -}
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/MetaAccessProvider.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/MetaAccessProvider.java Fri Oct 11 17:21:14 2013 +0200 @@ -25,7 +25,7 @@ import java.lang.reflect.*; /** - * Interface implemented by the runtime to allow access to its metadata. + * Provides access to the metadata of a class typically provided in a class file. */ public interface MetaAccessProvider { @@ -68,35 +68,6 @@ Signature parseMethodDescriptor(String methodDescriptor); /** - * Compares two constants for equality. This is used instead of {@link Constant#equals(Object)} - * in case the runtime has an interpretation for object equality other than - * {@code x.asObject() == y.asObject()}. For primitive constants, this is equivalent to calling - * {@code x.equals(y)}. The equality relationship is symmetric. - * - * @return {@code true} if the two parameters represent the same runtime object, {@code false} - * otherwise - */ - boolean constantEquals(Constant x, Constant y); - - /** - * Returns the length of an array that is wrapped in a {@link Constant} object. If {@code array} - * is not an array, or the array length is not available at this point, the return value is - * {@code null}. - */ - Integer lookupArrayLength(Constant array); - - /** - * Reads a value of this kind using a base address and a displacement. - * - * @param base the base address from which the value is read - * @param displacement the displacement within the object in bytes - * @param compressible whether this is a read of a compressed or an uncompressed pointer - * @return the read value encapsulated in a {@link Constant} object, or {@code null} if the - * value cannot be read. - */ - Constant readUnsafeConstant(Kind kind, Object base, long displacement, boolean compressible); - - /** * 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. */ @@ -113,4 +84,11 @@ * Determines if deoptimization can occur during a given foreign call. */ boolean canDeoptimize(ForeignCallDescriptor descriptor); + + /** + * Encodes a deoptimization action and a deoptimization reason in an integer value. + * + * @return the encoded value as an integer + */ + Constant encodeDeoptActionAndReason(DeoptimizationAction action, DeoptimizationReason reason); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ObjectLocationIdentity.java Fri Oct 11 17:21:14 2013 +0200 @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2013, 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; + +import java.util.*; + +/** + * A {@link LocationIdentity} warpping an object. + */ +public final class ObjectLocationIdentity implements LocationIdentity { + + private static IdentityHashMap<Object, LocationIdentity> map = new IdentityHashMap<>(); + + private Object object; + + public static LocationIdentity create(Object object) { + synchronized (map) { + if (map.containsKey(object)) { + return map.get(object); + } else { + ObjectLocationIdentity locationIdentity = new ObjectLocationIdentity(object); + map.put(object, locationIdentity); + return locationIdentity; + } + } + } + + private ObjectLocationIdentity(Object object) { + this.object = object; + } + + @Override + public String toString() { + return "Identity(" + object + ")"; + } +}
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaField.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaField.java Fri Oct 11 17:21:14 2013 +0200 @@ -29,7 +29,7 @@ * Represents a reference to a resolved Java field. Fields, like methods and types, are resolved * through {@link ConstantPool constant pools}. */ -public interface ResolvedJavaField extends JavaField { +public interface ResolvedJavaField extends JavaField, LocationIdentity { /** * Returns the Java language modifiers for this field, as an integer. The {@link Modifier} class @@ -50,17 +50,21 @@ boolean isSynthetic(); /** - * Gets the constant value of this field for a given object, if available. + * Gets the constant value of this field. Note that a {@code static final} field may not be + * considered constant if its declaring class is not yet initialized or if it is a well known + * field that can be updated via other means (e.g., {@link System#setOut(java.io.PrintStream)}). * * @param receiver object from which this field's value is to be read. This value is ignored if * this field is static. - * @return the constant value of this field or {@code null} if the constant value is not - * available + * @return the constant value of this field or {@code null} if this field is not considered + * constant by the runtime */ Constant readConstantValue(Constant receiver); /** - * Gets the current value of this field for a given object, if available. + * Gets the current value of this field for a given object, if available. There is no guarantee + * that the same value will be returned by this method for a field unless the field is + * considered to be {@link #readConstantValue(Constant)} by the runtime. * * @param receiver object from which this field's value is to be read. This value is ignored if * this field is static.
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaType.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaType.java Fri Oct 11 17:21:14 2013 +0200 @@ -205,10 +205,13 @@ /** * Resolves the method implementation for virtual dispatches on objects of this dynamic type. + * This resolution process only searches "up" the class hierarchy of this type. A broader search + * that also walks "down" the hierarchy is implemented by + * {@link #findUniqueConcreteMethod(ResolvedJavaMethod)}. * * @param method the method to select the implementation of - * @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. + * @return the concrete method that would be selected at runtime, or {@code null} if there is no + * concrete implementation of {@code method} in this type or any of its superclasses */ ResolvedJavaMethod resolveMethod(ResolvedJavaMethod method); @@ -298,6 +301,11 @@ ResolvedJavaMethod[] getDeclaredMethods(); /** + * Returns the {@code <clinit>} method for this class if there is one. + */ + ResolvedJavaMethod getClassInitializer(); + + /** * Creates a new array with this type as the component type and the specified length. This * method is similar to {@link Array#newInstance(Class, int)}. */
--- a/graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Assembler.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Assembler.java Fri Oct 11 17:21:14 2013 +0200 @@ -747,7 +747,7 @@ emitOperandHelper(0, dst); } - private void jcc(ConditionFlag cc, int jumpTarget, boolean forceDisp32) { + public void jcc(ConditionFlag cc, int jumpTarget, boolean forceDisp32) { int shortSize = 2; int longSize = 6; long disp = jumpTarget - codeBuffer.position();
--- a/graal/com.oracle.graal.asm.hsail/src/com/oracle/graal/asm/hsail/AbstractHSAILAssembler.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.asm.hsail/src/com/oracle/graal/asm/hsail/AbstractHSAILAssembler.java Fri Oct 11 17:21:14 2013 +0200 @@ -57,6 +57,7 @@ @Override protected String createLabelName(Label l, int id) { - return "@L" + id; + int blockId = l.getBlockId(); + return "@L" + (blockId == -1 ? id : blockId); } }
--- a/graal/com.oracle.graal.asm.ptx/src/com/oracle/graal/asm/ptx/PTXAssembler.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.asm.ptx/src/com/oracle/graal/asm/ptx/PTXAssembler.java Fri Oct 11 17:21:14 2013 +0200 @@ -24,6 +24,7 @@ import static com.oracle.graal.api.code.ValueUtil.*; +import com.oracle.graal.asm.Label; import com.oracle.graal.api.code.Register; import com.oracle.graal.api.code.RegisterConfig; import com.oracle.graal.api.code.TargetDescription; @@ -32,6 +33,7 @@ import com.oracle.graal.api.meta.Value; import com.oracle.graal.nodes.calc.Condition; import com.oracle.graal.graph.GraalInternalError; +import com.oracle.graal.lir.LabelRef; import com.oracle.graal.lir.Variable; public class PTXAssembler extends AbstractPTXAssembler { @@ -185,7 +187,7 @@ assert v != null; if (isConstant(v)) { - return (emitConstant(v)); + return (emitConstant(v, comma)); } else { return (emitRegister((Variable) v, comma)); } @@ -195,28 +197,38 @@ return (" %r" + v.index + (comma ? "," : "")); } - public String emitConstant(Value v) { + public String emitConstant(Value v, boolean comma) { Constant constant = (Constant) v; + String str = null; switch (v.getKind().getTypeChar()) { case 'i': - return (String.valueOf((int) constant.asLong())); + str = String.valueOf((int) constant.asLong()); + break; case 'f': - return (String.valueOf(constant.asFloat())); + str = String.valueOf(constant.asFloat()); + break; case 'j': - return (String.valueOf(constant.asLong())); + str = String.valueOf(constant.asLong()); + break; case 'd': - return (String.valueOf(constant.asDouble())); + str = String.valueOf(constant.asDouble()); + break; default: throw GraalInternalError.shouldNotReachHere(); } + if (comma) { + return (str + ","); + } else { + return str; + } } } public static class SingleOperandFormat { protected Variable dest; - protected Value source; + protected Value source; public SingleOperandFormat(Variable dst, Value src) { setDestination(dst); @@ -288,7 +300,34 @@ } public String emitVariable(Variable v) { - return (" %r" + v.index); + String name = v.getName(); + + if (name == null) { + return (" %r" + v.index); + } else { + return name; + } + } + } + + public static class BinarySingleOperandFormat extends SingleOperandFormat { + + public BinarySingleOperandFormat(Variable dst, Value src) { + super(dst, src); + } + + @Override + public String typeForKind(Kind k) { + switch (k.getTypeChar()) { + case 's': + return "b16"; + case 'i': + return "b32"; + case 'j': + return "b64"; + default: + throw GraalInternalError.shouldNotReachHere(); + } } } @@ -300,8 +339,7 @@ @Override public String emit() { - return (typeForKind(dest.getKind()) + "." + typeForKind(source.getKind()) + " " + - emitVariable(dest) + ", " + emitValue(source) + ";"); + return (typeForKind(dest.getKind()) + "." + typeForKind(source.getKind()) + " " + emitVariable(dest) + ", " + emitValue(source) + ";"); } } @@ -327,21 +365,18 @@ @Override public String emitRegister(Variable var, boolean comma) { - /* if (space == Parameter) { - return ("param" + var.index); - } else { - return ("%r" + var.index); - } */ + /* + * if (space == Parameter) { return ("param" + var.index); } else { return ("%r" + + * var.index); } + */ return ("%r" + var.index); } public String emit(boolean isLoad) { if (isLoad) { - return (space.getStateName() + "." + typeForKind(valueKind) + " " + - emitRegister(dest, false) + ", " + emitAddress(source1, source2) + ";"); + return (space.getStateName() + "." + typeForKind(valueKind) + " " + emitRegister(dest, false) + ", " + emitAddress(source1, source2) + ";"); } else { - return (space.getStateName() + "." + typeForKind(valueKind) + " " + - emitAddress(source1, source2) + ", " + emitRegister(dest, false) + ";"); + return (space.getStateName() + "." + typeForKind(valueKind) + " " + emitAddress(source1, source2) + ", " + emitRegister(dest, false) + ";"); } } } @@ -474,7 +509,16 @@ // Checkstyle: stop method name check public final void bra(String tgt, int pred) { - emitString((pred >= 0) ? "" : ("@%p" + pred + " ") + "bra" + " " + tgt + ";" + ""); + assert pred >= 0; + + if (tgt.equals("?")) { + Thread.dumpStack(); + } + emitString("@%p" + pred + " " + "bra" + " " + tgt + ";"); + } + + public final void bra(String src) { + emitString("bra " + src + ";"); } public final void bra_uni(String tgt) { @@ -488,27 +532,42 @@ } public void emit(PTXAssembler asm) { - asm.emitString("cvt." + super.emit()); + if (dest.getKind() == Kind.Float || dest.getKind() == Kind.Double) { + // round-to-zero - might not be right + asm.emitString("cvt.rz." + super.emit()); + } else { + asm.emitString("cvt." + super.emit()); + } } } - + public static class Mov extends SingleOperandFormat { + private int predicateRegisterNumber = -1; + public Mov(Variable dst, Value src) { super(dst, src); } - /* - public Mov(Variable dst, AbstractAddress src) { - throw GraalInternalError.unimplemented("AbstractAddress Mov"); + public Mov(Variable dst, Value src, int predicate) { + super(dst, src); + this.predicateRegisterNumber = predicate; } - */ - + + /* + * public Mov(Variable dst, AbstractAddress src) { throw + * GraalInternalError.unimplemented("AbstractAddress Mov"); } + */ + public void emit(PTXAssembler asm) { - asm.emitString("mov." + super.emit()); + if (predicateRegisterNumber >= 0) { + asm.emitString("@%p" + String.valueOf(predicateRegisterNumber) + " mov." + super.emit()); + } else { + asm.emitString("mov." + super.emit()); + } } } - + public static class Neg extends SingleOperandFormat { public Neg(Variable dst, Variable src) { @@ -519,8 +578,8 @@ asm.emitString("neg." + super.emit()); } } - - public static class Not extends SingleOperandFormat { + + public static class Not extends BinarySingleOperandFormat { public Not(Variable dst, Variable src) { super(dst, src); @@ -530,7 +589,7 @@ asm.emitString("not." + super.emit()); } } - + public static class Ld extends LoadStoreFormat { public Ld(PTXStateSpace space, Variable dst, Variable src1, Value src2) { @@ -557,6 +616,47 @@ emitString("exit;" + " " + ""); } + public static class Global { + + private Kind kind; + private String name; + private LabelRef[] targets; + + public Global(Value val, String name, LabelRef[] targets) { + this.kind = val.getKind(); + this.name = name; + this.targets = targets; + } + + private static String valueForKind(Kind k) { + switch (k.getTypeChar()) { + case 'i': + return "s32"; + case 'j': + return "s64"; + default: + throw GraalInternalError.shouldNotReachHere(); + } + } + + private static String emitTargets(PTXAssembler asm, LabelRef[] refs) { + StringBuffer sb = new StringBuffer(); + + for (int i = 0; i < refs.length; i++) { + sb.append(asm.nameOf(refs[i].label())); + if (i < (refs.length - 1)) { + sb.append(", "); + } + } + + return sb.toString(); + } + + public void emit(PTXAssembler asm) { + asm.emitString(".global ." + valueForKind(kind) + " " + name + "[" + targets.length + "] = " + "{ " + emitTargets(asm, targets) + " };"); + } + } + public static class Param extends SingleOperandFormat { private boolean lastParameter; @@ -575,8 +675,33 @@ } public void emit(PTXAssembler asm) { - asm.emitString(".param ." + typeForKind(dest.getKind()) + emitParameter(dest) + (lastParameter ? "" : ",")); + asm.emitString(".param ." + paramForKind(dest.getKind()) + emitParameter(dest) + (lastParameter ? "" : ",")); } + + public String paramForKind(Kind k) { + switch (k.getTypeChar()) { + case 'z': + case 'f': + return "s32"; + case 'b': + return "s8"; + case 's': + return "s16"; + case 'c': + return "u16"; + case 'i': + return "s32"; + case 'j': + return "s64"; + case 'd': + return "f64"; + case 'a': + return "u64"; + default: + throw GraalInternalError.shouldNotReachHere(); + } + } + } public final void popc_b32(Register d, Register a) { @@ -595,9 +720,24 @@ emitString("ret.uni;" + " " + ""); } - public static class Setp { + public enum BooleanOperator { + AND("and"), OR("or"), XOR("xor"); + + private final String output; + + private BooleanOperator(String out) { + this.output = out; + } - private ConditionOperator operator; + public String getOperator() { + return output + "."; + } + } + + public static class Setp { + + private BooleanOperator booleanOperator; + private ConditionOperator operator; private Value first, second; private Kind kind; private int predicate; @@ -610,6 +750,15 @@ setConditionOperator(operatorForConditon(condition)); } + public Setp(Condition condition, BooleanOperator operator, Value first, Value second, int predicateRegisterNumber) { + setFirst(first); + setSecond(second); + setPredicate(predicateRegisterNumber); + setKind(); + setConditionOperator(operatorForConditon(condition)); + setBooleanOperator(operator); + } + public void setFirst(Value v) { first = v; } @@ -626,6 +775,10 @@ operator = co; } + public void setBooleanOperator(BooleanOperator bo) { + booleanOperator = bo; + } + private ConditionOperator operatorForConditon(Condition condition) { char typeChar = kind.getTypeChar(); @@ -635,12 +788,18 @@ case 'a': // unsigned switch (condition) { - case EQ: return ConditionOperator.U_EQ; - case NE: return ConditionOperator.U_NE; - case LT: return ConditionOperator.U_LO; - case LE: return ConditionOperator.U_LS; - case GT: return ConditionOperator.U_HI; - case GE: return ConditionOperator.U_HS; + case EQ: + return ConditionOperator.U_EQ; + case NE: + return ConditionOperator.U_NE; + case LT: + return ConditionOperator.U_LO; + case LE: + return ConditionOperator.U_LS; + case GT: + return ConditionOperator.U_HI; + case GE: + return ConditionOperator.U_HS; default: throw GraalInternalError.shouldNotReachHere(); } @@ -650,11 +809,16 @@ case 'j': // signed switch (condition) { - case EQ: return ConditionOperator.S_EQ; - case NE: return ConditionOperator.S_NE; - case LT: return ConditionOperator.S_LT; - case LE: return ConditionOperator.S_LE; - case GT: return ConditionOperator.S_GT; + case EQ: + return ConditionOperator.S_EQ; + case NE: + return ConditionOperator.S_NE; + case LT: + return ConditionOperator.S_LT; + case LE: + return ConditionOperator.S_LE; + case GT: + return ConditionOperator.S_GT; case GE: case AE: return ConditionOperator.S_GE; @@ -665,12 +829,18 @@ case 'd': // floating point - do these need to accept NaN?? switch (condition) { - case EQ: return ConditionOperator.F_EQ; - case NE: return ConditionOperator.F_NE; - case LT: return ConditionOperator.F_LT; - case LE: return ConditionOperator.F_LE; - case GT: return ConditionOperator.F_GT; - case GE: return ConditionOperator.F_GE; + case EQ: + return ConditionOperator.F_EQ; + case NE: + return ConditionOperator.F_NE; + case LT: + return ConditionOperator.F_LT; + case LE: + return ConditionOperator.F_LE; + case GT: + return ConditionOperator.F_GT; + case GE: + return ConditionOperator.F_GE; default: throw GraalInternalError.shouldNotReachHere(); } @@ -688,7 +858,7 @@ kind = first.getKind(); } } - + public String emitValue(Value v) { assert v != null; @@ -740,16 +910,23 @@ throw GraalInternalError.shouldNotReachHere(); } } - + public String emitVariable(Variable v) { return ("%r" + v.index); } public void emit(PTXAssembler asm) { - asm.emitString("setp." + operator.getOperator() + "." + typeForKind(kind) + - " %p" + predicate + emitValue(first) + emitValue(second) + ";"); + + if (booleanOperator != null) { + asm.emitString("setp." + operator.getOperator() + "." + booleanOperator.getOperator() + typeForKind(kind) + " %p" + predicate + emitValue(first) + emitValue(second) + ", %r;"); // Predicates +// need to be objects + + } else { + asm.emitString("setp." + operator.getOperator() + "." + typeForKind(kind) + " %p" + predicate + emitValue(first) + emitValue(second) + ";"); + } } } + @Override public PTXAddress makeAddress(Register base, int displacement) { throw GraalInternalError.shouldNotReachHere(); @@ -757,6 +934,16 @@ @Override public PTXAddress getPlaceholder() { - throw GraalInternalError.unimplemented("PTXAddress.getPlaceholder()"); + return null; } + + @Override + public void jmp(Label l) { + String str = nameOf(l); + if (l.equals("?")) { + Thread.dumpStack(); + } + bra(str); + } + }
--- a/graal/com.oracle.graal.asm.test/src/com/oracle/graal/asm/test/AssemblerTest.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.asm.test/src/com/oracle/graal/asm/test/AssemblerTest.java Fri Oct 11 17:21:14 2013 +0200 @@ -34,6 +34,7 @@ public abstract class AssemblerTest extends GraalTest { + private final MetaAccessProvider metaAccess; protected final CodeCacheProvider codeCache; public interface CodeGenTest { @@ -42,12 +43,17 @@ } public AssemblerTest() { + this.metaAccess = Graal.getRequiredCapability(MetaAccessProvider.class); this.codeCache = Graal.getRequiredCapability(CodeCacheProvider.class); } + public MetaAccessProvider getMetaAccess() { + return metaAccess; + } + protected InstalledCode assembleMethod(Method m, CodeGenTest test) { - ResolvedJavaMethod method = codeCache.lookupJavaMethod(m); - RegisterConfig registerConfig = codeCache.lookupRegisterConfig(); + ResolvedJavaMethod method = getMetaAccess().lookupJavaMethod(m); + RegisterConfig registerConfig = codeCache.getRegisterConfig(); CallingConvention cc = CodeUtil.getCallingConvention(codeCache, CallingConvention.Type.JavaCallee, method, false); CompilationResult compResult = new CompilationResult();
--- a/graal/com.oracle.graal.asm/src/com/oracle/graal/asm/Label.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.asm/src/com/oracle/graal/asm/Label.java Fri Oct 11 17:21:14 2013 +0200 @@ -30,13 +30,14 @@ public final class Label { private int position = -1; + private int blockId = -1; /** * References to instructions that jump to this unresolved label. These instructions need to be * patched when the label is bound using the {@link #patchInstructions(AbstractAssembler)} * method. */ - private ArrayList<Integer> patchPositions = new ArrayList<>(4); + private ArrayList<Integer> patchPositions = null; /** * Returns the position of this label in the code buffer. @@ -51,6 +52,14 @@ public Label() { } + public Label(int id) { + blockId = id; + } + + public int getBlockId() { + return blockId; + } + /** * Binds the label to the specified position. * @@ -67,15 +76,20 @@ public void addPatchAt(int branchLocation) { assert !isBound() : "Label is already bound " + this + " " + branchLocation + " at position " + position; + if (patchPositions == null) { + patchPositions = new ArrayList<>(2); + } patchPositions.add(branchLocation); } protected void patchInstructions(AbstractAssembler masm) { assert isBound() : "Label should be bound"; - int target = position; - for (int i = 0; i < patchPositions.size(); ++i) { - int pos = patchPositions.get(i); - masm.patchJumpTarget(pos, target); + if (patchPositions != null) { + int target = position; + for (int i = 0; i < patchPositions.size(); ++i) { + int pos = patchPositions.get(i); + masm.patchJumpTarget(pos, target); + } } }
--- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java Fri Oct 11 17:21:14 2013 +0200 @@ -86,8 +86,8 @@ } } - public AMD64LIRGenerator(StructuredGraph graph, CodeCacheProvider runtime, TargetDescription target, FrameMap frameMap, CallingConvention cc, LIR lir) { - super(graph, runtime, target, frameMap, cc, lir); + public AMD64LIRGenerator(StructuredGraph graph, MetaAccessProvider metaAccess, CodeCacheProvider codeCache, TargetDescription target, FrameMap frameMap, CallingConvention cc, LIR lir) { + super(graph, metaAccess, codeCache, target, frameMap, cc, lir); lir.spillMoveFactory = new AMD64SpillMoveFactory(); } @@ -96,7 +96,7 @@ // there is no immediate move of 64-bit constants on Intel switch (c.getKind()) { case Long: - return Util.isInt(c.asLong()) && !runtime.needsDataPatch(c); + return Util.isInt(c.asLong()) && !codeCache.needsDataPatch(c); case Double: return false; case Object: @@ -110,7 +110,7 @@ public boolean canInlineConstant(Constant c) { switch (c.getKind()) { case Long: - return NumUtil.isInt(c.asLong()) && !runtime.needsDataPatch(c); + return NumUtil.isInt(c.asLong()) && !codeCache.needsDataPatch(c); case Object: return c.isNull(); default: @@ -147,7 +147,7 @@ if (isConstant(base)) { if (asConstant(base).isNull()) { baseRegister = Value.ILLEGAL; - } else if (asConstant(base).getKind() != Kind.Object && !runtime.needsDataPatch(asConstant(base))) { + } else if (asConstant(base).getKind() != Kind.Object && !codeCache.needsDataPatch(asConstant(base))) { finalDisp += asConstant(base).asLong(); baseRegister = Value.ILLEGAL; } else { @@ -881,7 +881,7 @@ 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); + sig[i] = node.arguments().get(i).stamp().javaType(metaAccess); } Value[] parameters = visitInvokeArguments(frameMap.registerConfig.getCallingConvention(CallingConvention.Type.JavaCall, null, sig, target(), false), node.arguments()); @@ -890,6 +890,6 @@ @Override public void visitInfopointNode(InfopointNode i) { - append(new InfopointOp(stateFor(i.getState(), DeoptimizationReason.None), i.reason)); + append(new InfopointOp(stateFor(i.getState()), i.reason)); } }
--- a/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/ForEachToGraal.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/ForEachToGraal.java Fri Oct 11 17:21:14 2013 +0200 @@ -23,27 +23,20 @@ package com.oracle.graal.compiler.hsail; -import com.oracle.graal.api.code.CompilationResult; -import java.lang.reflect.Method; +import java.lang.reflect.*; -import com.amd.okra.OkraContext; -import com.amd.okra.OkraKernel; -import com.oracle.graal.hotspot.HotSpotGraalRuntime; -import com.oracle.graal.hotspot.HotSpotVMConfig; -import com.oracle.graal.hotspot.amd64.AMD64HotSpotRuntime; +import com.amd.okra.*; +import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.api.runtime.Graal; -import com.oracle.graal.java.GraphBuilderConfiguration; -import com.oracle.graal.java.GraphBuilderPhase; -import com.oracle.graal.nodes.StructuredGraph; -import com.oracle.graal.nodes.java.MethodCallTargetNode; -import com.oracle.graal.nodes.spi.Replacements; -import com.oracle.graal.phases.OptimisticOptimizations; -import com.oracle.graal.graph.Node; +import com.oracle.graal.debug.*; +import com.oracle.graal.graph.*; import com.oracle.graal.graph.iterators.*; -import com.oracle.graal.compiler.target.Backend; -import com.oracle.graal.nodes.spi.GraalCodeCacheProvider; -import com.oracle.graal.debug.*; +import com.oracle.graal.hotspot.*; +import com.oracle.graal.hotspot.amd64.*; +import com.oracle.graal.java.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.java.*; +import com.oracle.graal.phases.*; /** * Implements compile and dispatch of Java code containing lambda constructs. Currently only used by @@ -51,16 +44,6 @@ */ public class ForEachToGraal implements CompileAndDispatch { - protected final GraalCodeCacheProvider runtime; - protected final Replacements replacements; - protected final Backend backend; - - public ForEachToGraal() { - this.runtime = Graal.getRequiredCapability(GraalCodeCacheProvider.class); - this.replacements = Graal.getRequiredCapability(Replacements.class); - this.backend = Graal.getRequiredCapability(Backend.class); - } - private static CompilationResult getCompiledLambda(Class consumerClass) { /** * Find the accept() method in the IntConsumer, then use Graal API to find the target lambda
--- a/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILBackend.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILBackend.java Fri Oct 11 17:21:14 2013 +0200 @@ -51,8 +51,8 @@ private Map<String, String> paramTypeMap = new HashMap<>(); private Buffer codeBuffer; - public HSAILBackend(CodeCacheProvider runtime, TargetDescription target) { - super(runtime, target); + public HSAILBackend(MetaAccessProvider metaAccess, CodeCacheProvider codeCache, TargetDescription target) { + super(metaAccess, codeCache, target); paramTypeMap.put("HotSpotResolvedPrimitiveType<int>", "s32"); paramTypeMap.put("HotSpotResolvedPrimitiveType<float>", "f32"); paramTypeMap.put("HotSpotResolvedPrimitiveType<double>", "f64"); @@ -69,12 +69,12 @@ */ @Override public FrameMap newFrameMap() { - return new HSAILFrameMap(runtime(), target, new HSAILRegisterConfig()); + return new HSAILFrameMap(getCodeCache(), target, new HSAILRegisterConfig()); } @Override public LIRGenerator newLIRGenerator(StructuredGraph graph, FrameMap frameMap, CallingConvention cc, LIR lir) { - return new HSAILLIRGenerator(graph, runtime(), target, frameMap, cc, lir); + return new HSAILLIRGenerator(graph, getMetaAccess(), getCodeCache(), target, frameMap, cc, lir); } public String getPartialCodeString() { @@ -104,7 +104,7 @@ FrameMap frameMap = lirGen.frameMap; AbstractAssembler masm = new HSAILAssembler(target); HotSpotFrameContext frameContext = new HotSpotFrameContext(); - TargetMethodAssembler tasm = new TargetMethodAssembler(target, runtime(), frameMap, masm, frameContext, compilationResult); + TargetMethodAssembler tasm = new TargetMethodAssembler(target, getCodeCache(), frameMap, masm, frameContext, compilationResult); tasm.setFrameSize(frameMap.frameSize()); return tasm; } @@ -142,12 +142,12 @@ int pidx = 0; for (int i = 0; i < totalParamCount; i++) { if (i == 0 && !isStatic) { - paramtypes[i] = runtime().lookupJavaType(Object.class); + paramtypes[i] = getMetaAccess().lookupJavaType(Object.class); paramNames[i] = "%_this"; } else if (i < nonConstantParamCount) { if (isObjectLambda && (i == (nonConstantParamCount))) { // Set up the gid register mapping. - paramtypes[i] = runtime().lookupJavaType(int.class); + paramtypes[i] = getMetaAccess().lookupJavaType(int.class); paramNames[i] = "%_gid"; } else { paramtypes[i] = signature.getParameterType(pidx++, null);
--- a/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILCompilationResult.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILCompilationResult.java Fri Oct 11 17:21:14 2013 +0200 @@ -31,17 +31,16 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.api.runtime.*; import com.oracle.graal.compiler.*; -import com.oracle.graal.compiler.target.*; import com.oracle.graal.debug.*; import com.oracle.graal.graph.*; import com.oracle.graal.hsail.*; import com.oracle.graal.java.*; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; import com.oracle.graal.phases.*; import com.oracle.graal.phases.PhasePlan.PhasePosition; import com.oracle.graal.phases.tiers.*; +import com.oracle.graal.phases.util.*; /** * Class that represents a HSAIL compilation result. Includes the compiled HSAIL code. @@ -49,10 +48,6 @@ public class HSAILCompilationResult { private CompilationResult compResult; - protected static GraalCodeCacheProvider runtime = Graal.getRequiredCapability(GraalCodeCacheProvider.class); - protected static Replacements replacements = Graal.getRequiredCapability(Replacements.class); - protected static Backend backend = Graal.getRequiredCapability(Backend.class); - protected static SuitesProvider suitesProvider = Graal.getRequiredCapability(SuitesProvider.class); private static final String propPkgName = HSAILCompilationResult.class.getPackage().getName(); private static Level logLevel; private static ConsoleHandler consoleHandler; @@ -78,13 +73,15 @@ } public static HSAILCompilationResult getHSAILCompilationResult(Method meth) { - ResolvedJavaMethod javaMethod = runtime.lookupJavaMethod(meth); + MetaAccessProvider metaAccess = Graal.getRequiredCapability(MetaAccessProvider.class); + ResolvedJavaMethod javaMethod = metaAccess.lookupJavaMethod(meth); return getHSAILCompilationResult(javaMethod); } public static HSAILCompilationResult getHSAILCompilationResult(ResolvedJavaMethod javaMethod) { + MetaAccessProvider metaAccess = Graal.getRequiredCapability(MetaAccessProvider.class); StructuredGraph graph = new StructuredGraph(javaMethod); - new GraphBuilderPhase(runtime, GraphBuilderConfiguration.getEagerDefault(), OptimisticOptimizations.ALL).apply(graph); + new GraphBuilderPhase(metaAccess, GraphBuilderConfiguration.getEagerDefault(), OptimisticOptimizations.ALL).apply(graph); return getHSAILCompilationResult(graph); } @@ -117,17 +114,19 @@ public static HSAILCompilationResult getHSAILCompilationResult(StructuredGraph graph) { Debug.dump(graph, "Graph"); + Providers providers = GraalCompiler.getGraalProviders(); TargetDescription target = new TargetDescription(new HSAIL(), true, 8, 0, true); - HSAILBackend hsailBackend = new HSAILBackend(Graal.getRequiredCapability(GraalCodeCacheProvider.class), target); + HSAILBackend hsailBackend = new HSAILBackend(providers.getMetaAccess(), providers.getCodeCache(), target); PhasePlan phasePlan = new PhasePlan(); - GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(runtime, GraphBuilderConfiguration.getDefault(), OptimisticOptimizations.NONE); + GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(providers.getMetaAccess(), GraphBuilderConfiguration.getDefault(), OptimisticOptimizations.NONE); phasePlan.addPhase(PhasePosition.AFTER_PARSING, graphBuilderPhase); phasePlan.addPhase(PhasePosition.AFTER_PARSING, new HSAILPhase()); new HSAILPhase().apply(graph); CallingConvention cc = getHSAILCallingConvention(Type.JavaCallee, target, graph.method(), false); + SuitesProvider suitesProvider = Graal.getRequiredCapability(SuitesProvider.class); try { - CompilationResult compResult = GraalCompiler.compileGraph(graph, cc, graph.method(), runtime, replacements, hsailBackend, target, null, phasePlan, OptimisticOptimizations.NONE, - new SpeculationLog(), suitesProvider.getDefaultSuites(), new CompilationResult()); + CompilationResult compResult = GraalCompiler.compileGraph(graph, cc, graph.method(), providers, hsailBackend, target, null, phasePlan, OptimisticOptimizations.NONE, new SpeculationLog(), + suitesProvider.getDefaultSuites(), new CompilationResult()); return new HSAILCompilationResult(compResult); } catch (GraalInternalError e) { String partialCode = hsailBackend.getPartialCodeString();
--- a/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILLIRGenerator.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILLIRGenerator.java Fri Oct 11 17:21:14 2013 +0200 @@ -66,7 +66,7 @@ public class HSAILLIRGenerator extends LIRGenerator { private HotSpotRuntime runtime() { - return (HotSpotRuntime) runtime; + return (HotSpotRuntime) codeCache; } public static class HSAILSpillMoveFactory implements LIR.SpillMoveFactory { @@ -83,8 +83,8 @@ } } - public HSAILLIRGenerator(StructuredGraph graph, CodeCacheProvider runtime, TargetDescription target, FrameMap frameMap, CallingConvention cc, LIR lir) { - super(graph, runtime, target, frameMap, cc, lir); + public HSAILLIRGenerator(StructuredGraph graph, MetaAccessProvider metaAccess, CodeCacheProvider codeCache, TargetDescription target, FrameMap frameMap, CallingConvention cc, LIR lir) { + super(graph, metaAccess, codeCache, target, frameMap, cc, lir); lir.spillMoveFactory = new HSAILSpillMoveFactory(); } @@ -98,7 +98,7 @@ public boolean canInlineConstant(Constant c) { switch (c.getKind()) { case Long: - return NumUtil.isInt(c.asLong()) && !runtime.needsDataPatch(c); + return NumUtil.isInt(c.asLong()) && !codeCache.needsDataPatch(c); case Object: return c.isNull(); default: @@ -579,7 +579,7 @@ } @Override - public void emitDeoptimize(DeoptimizationAction action, DeoptimizingNode deopting) { + public void emitDeoptimize(Value actionAndReason, DeoptimizingNode deopting) { append(new ReturnOp(Value.ILLEGAL)); }
--- a/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/ArrayPTXTest.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/ArrayPTXTest.java Fri Oct 11 17:21:14 2013 +0200 @@ -22,97 +22,54 @@ */ package com.oracle.graal.compiler.ptx.test; -import java.lang.reflect.Method; +import static com.oracle.graal.lir.ptx.ThreadDimension.*; -import org.junit.*; +import com.oracle.graal.lir.ptx.ParallelOver; +import com.oracle.graal.lir.ptx.Warp; + +import java.lang.reflect.Method; +import java.util.Arrays; +import org.junit.Test; public class ArrayPTXTest extends PTXTestBase { - @Ignore @Test public void testArray() { - int[] arrayI = { - 1, 2, 3, 4, 5 + int[] array1 = { + 1, 2, 3, 4, 5, 6, 7, 8, 9 + }; + int[] array2 = { + 1, 2, 3, 4, 5, 6, 7, 8, 9 + }; + int[] array3 = { + 1, 2, 3, 4, 5, 6, 7, 8, 9 }; - Integer resI = (Integer) invoke(compile("testArray1I"), arrayI, 3); - printReport("testArray1I: " + resI); - // 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"); - } + + invoke(compile("testStoreArray1I"), array1, 2); + printReport("testStoreArray1I: " + Arrays.toString(array1)); - public static int testArray1I(int[] array, int i) { - return array[i]; - } - - public static long testArray1J(long[] array, int i) { - return array[i]; - } + invoke(compile("testStoreArrayWarp0"), array2, 2); + printReport("testStoreArrayWarp0: " + Arrays.toString(array2)); - public static byte testArray1B(byte[] array, int i) { - return array[i]; - } + invoke(compile("testStoreArrayWarp1I"), array3, 2); + printReport("testStoreArrayWarp1I: " + Arrays.toString(array3)); - 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 testStoreArray1I(int[] array, int i) { + array[i] = 42; } - 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 testStoreArrayWarp0(int[] array, + @Warp(dimension = X) int i) { + array[i] = 42; } - public static void testStoreArray1F(float[] array, int i, float val) { - array[i] = val; + public static void testStoreArrayWarp1I(@ParallelOver(dimension = X) int[] array, + @Warp(dimension = X) int i) { + array[i] = 42; } - public static void testStoreArray1D(double[] array, int i, double val) { - array[i] = val; - } - - public static void printReport(String message) { - // CheckStyle: stop system..print check - System.out.println(message); - // CheckStyle: resume system..print check - - } public static void main(String[] args) { ArrayPTXTest test = new ArrayPTXTest();
--- a/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/BasicPTXTest.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/BasicPTXTest.java Fri Oct 11 17:21:14 2013 +0200 @@ -24,13 +24,11 @@ import java.lang.reflect.Method; -import org.junit.Ignore; import org.junit.Test; /** * Test class for small Java methods compiled to PTX kernels. */ -@Ignore public class BasicPTXTest extends PTXTestBase { @Test
--- a/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/ControlPTXTest.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/ControlPTXTest.java Fri Oct 11 17:21:14 2013 +0200 @@ -28,14 +28,54 @@ public class ControlPTXTest extends PTXTestBase { - @Ignore @Test public void testControl() { - compile("testLoop"); - // compile("testSwitch1I"); - // compile("testStatic"); - // compile("testCall"); - // compile("testLookupSwitch1I"); + Integer ret = (Integer) invoke(compile("testLoop"), 42); + if (ret != null) { + printReport("testLoop: " + ret); + } else { + printReport("testLoop: no VALUE"); + } + ret = (Integer) invoke(compile("testSwitchDefault1I"), 3); + if (ret != null) { + printReport("testSwitchDefault1I: " + ret); + } else { + printReport("testSwitchDefault1I: no VALUE"); + } + ret = (Integer) invoke(compile("testSwitch1I"), 2); + if (ret != null) { + printReport("testSwitch1I: " + ret); + } else { + printReport("testSwitch1I: no VALUE"); + } + ret = (Integer) invoke(compile("testIfElse1I"), 222); + if (ret != null) { + printReport("testIfElse1I: " + ret); + } else { + printReport("testIfElse1I: no VALUE"); + } + ret = (Integer) invoke(compile("testIfElse2I"), 19, 64); + if (ret != null) { + printReport("testIfElse2I: " + (char) ret.intValue()); + } else { + printReport("testIfElse2I: no VALUE"); + } + Boolean bret = (Boolean) invoke(compile("testIntegerTestBranch2I"), + 0xff00, 0x00ff); + if (bret != null) { + printReport("testIntegerTestBranch2I: " + bret); + printReport("testIntegerTestBranch2I: actual: " + + testIntegerTestBranch2I(0xff00, 0x00ff)); + } else { + printReport("testIntegerTestBranch2I: no VALUE"); + } + compile("testStatic"); + compile("testCall"); + compile("testLookupSwitch1I"); + } + + public static boolean testIntegerTestBranch2I(int x, int y) { + return (x & y) == 0; } public static int testLoop(int n) { @@ -47,6 +87,31 @@ return sum; } + public static int testIfElse1I(int n) { + if (n > 22) { + return 42; + } else { + return -42; + } + } + + public static int testIfElse2I(int c, int y) { + if (c > 19) { + return 'M'; // millenial + } else if (y > 84) { + return 'Y'; // young + } else { + return 'O'; // old + } + } + + public static int testSwitchDefault1I(int a) { + switch (a) { + default: + return 4; + } + } + public static int testSwitch1I(int a) { switch (a) { case 1: @@ -61,31 +126,31 @@ public static int testLookupSwitch1I(int a) { switch (a) { case 0: - return 1; + return 10; case 1: - return 2; + return 11; case 2: - return 3; + return 12; case 3: - return 1; + return 13; case 4: - return 2; + return 14; case 5: - return 3; + return 15; case 6: - return 1; + return 16; case 7: - return 2; + return 17; case 8: - return 3; + return 18; case 9: - return 1; + return 19; case 10: - return 2; + return 20; case 11: - return 3; + return 21; default: - return -1; + return 42; } } @@ -100,7 +165,7 @@ return a + b; } - public static int testCall(@SuppressWarnings("unused") Object o, int a, int b) { + public static int testCall(int a, int b) { return method(a, b); }
--- a/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/FloatPTXTest.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/FloatPTXTest.java Fri Oct 11 17:21:14 2013 +0200 @@ -29,44 +29,46 @@ import com.oracle.graal.api.code.CompilationResult; /* PTX ISA 3.1 - 8.7.3 Floating-Point Instructions */ -@Ignore public class FloatPTXTest extends PTXTestBase { - @Ignore @Test public void testAdd() { - CompilationResult r = compile("testAdd2F"); - if (r.getTargetCode() == null) { - printReport("Compilation of testAdd2F FAILED"); + Float ret = (Float) invoke(compile("testAdd2I"), 42, 43); + if (ret != null) { + printReport("testAdd2I: " + ret); + } else { + printReport("testAdd2I: no VALUE"); } - /* - r = compile("testAdd2D"); - if (r.getTargetCode() == null) { - printReport("Compilation of testAdd2D FAILED"); + ret = (Float) invoke(compile("testAdd2F"), 42.1F, 43.5F); + if (ret != null) { + printReport("testAdd2F: " + ret); + } else { + printReport("testAdd2F: no VALUE"); } - r = compile("testAddFConst"); - if (r.getTargetCode() == null) { - printReport("Compilation of testAddFConst FAILED"); - } - r = compile("testAddConstF"); - if (r.getTargetCode() == null) { - printReport("Compilation of testConstF FAILED"); + ret = (Float) invoke(compile("testAddFConst"), 42.1F); + if (ret != null) { + printReport("testAddFConst: " + ret); + } else { + printReport("testAddFConst: no VALUE"); } - r = compile("testAddDConst"); - if (r.getTargetCode() == null) { - printReport("Compilation of testAddDConst FAILED"); + + Double dret = (Double) invoke(compile("testAdd2D"), 42.1, 43.5); + if (dret != null) { + printReport("testAdd2D: " + dret); + } else { + printReport("testAdd2D: no VALUE"); } - r = compile("testAddConstD"); - if (r.getTargetCode() == null) { - printReport("Compilation of testConstD FAILED"); - } - */ + + } + + public static float testAdd2I(int a, int b) { + return a + b; } public static float testAdd2F(float a, float b) { - return a + b; + return (a + b); } public static double testAdd2D(double a, double b) { @@ -359,13 +361,6 @@ return (float) a; } - public static void printReport(String message) { - // CheckStyle: stop system..print check - System.out.println(message); - // CheckStyle: resume system..print check - - } - public static void main(String[] args) { FloatPTXTest test = new FloatPTXTest(); for (Method m : FloatPTXTest.class.getMethods()) {
--- a/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/IntegerPTXTest.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/IntegerPTXTest.java Fri Oct 11 17:21:14 2013 +0200 @@ -30,8 +30,8 @@ @Test public void testAdd() { - /* - Integer r4 = (Integer) invoke(compile("testAdd2B"), (byte) 6, (byte) 4); + + /* Integer r4 = (Integer) invoke(compile("testAdd2B"), (byte) 6, (byte) 4); if (r4 == null) { printReport("testAdd2B FAILED"); } else if (r4.intValue() == testAdd2B((byte) 6, (byte) 4)) { @@ -49,14 +49,14 @@ printReport("testAdd2I FAILED"); } - /* Long r2 = (Long) invoke(compile("testAdd2L"), (long) 12, (long) 6); + Long r2 = (Long) invoke(compile("testAdd2L"), (long) 12, (long) 6); if (r2 == null) { printReport("testAdd2L FAILED"); } else if (r2.longValue() == testAdd2L(12, 6)) { printReport("testAdd2L PASSED"); } else { printReport("testAdd2L FAILED"); - } + } r4 = (Integer) invoke(compile("testAddIConst"), 5); if (r4 == null) { @@ -74,7 +74,7 @@ printReport("testAddConstI PASSED"); } else { printReport("testAddConstI FAILED"); - } */ + } } public static int testAdd2I(int a, int b) { @@ -97,7 +97,6 @@ return 32 + a; } - @Ignore @Test public void testSub() { @@ -155,7 +154,6 @@ return 32 - a; } - @Ignore @Test public void testMul() { @@ -348,12 +346,6 @@ return (int) a; } - public static void printReport(String message) { - // CheckStyle: stop system..print check - System.out.println(message); - // CheckStyle: resume system..print check - - } public static void main(String[] args) { IntegerPTXTest test = new IntegerPTXTest();
--- a/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/LogicPTXTest.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/LogicPTXTest.java Fri Oct 11 17:21:14 2013 +0200 @@ -24,11 +24,9 @@ import java.lang.reflect.Method; -import org.junit.Ignore; import org.junit.Test; /* PTX ISA 3.1 - 8.7.5 Logic and Shift Instructions */ -@Ignore public class LogicPTXTest extends PTXTestBase { @Test
--- a/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/PTXTestBase.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/PTXTestBase.java Fri Oct 11 17:21:14 2013 +0200 @@ -23,60 +23,61 @@ package com.oracle.graal.compiler.ptx.test; import static com.oracle.graal.api.code.CodeUtil.*; -import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; + +import java.lang.annotation.*; +import java.lang.reflect.*; 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.ptx.PTXBackend; -import com.oracle.graal.compiler.test.GraalCompilerTest; -import com.oracle.graal.debug.Debug; -import com.oracle.graal.hotspot.meta.HotSpotRuntime; -import com.oracle.graal.hotspot.meta.HotSpotResolvedJavaMethod; -import com.oracle.graal.hotspot.ptx.PTXHotSpotRuntime; -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.api.code.CallingConvention.Type; +import com.oracle.graal.compiler.*; +import com.oracle.graal.compiler.ptx.*; +import com.oracle.graal.compiler.test.*; +import com.oracle.graal.debug.*; +import com.oracle.graal.hotspot.meta.*; +import com.oracle.graal.hotspot.ptx.*; +import com.oracle.graal.java.*; +import com.oracle.graal.lir.ptx.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.phases.*; import com.oracle.graal.phases.PhasePlan.PhasePosition; import com.oracle.graal.phases.tiers.*; -import com.oracle.graal.ptx.PTX; -import java.lang.reflect.Modifier; +import com.oracle.graal.ptx.*; public abstract class PTXTestBase extends GraalCompilerTest { private StructuredGraph sg; + public void printReport(String message) { + // CheckStyle: stop system..print check + System.out.println(message); + // CheckStyle: resume system..print check + + } + protected CompilationResult compile(String test) { - if (runtime instanceof PTXHotSpotRuntime) { + if (getCodeCache() instanceof PTXHotSpotRuntime) { StructuredGraph graph = parse(test); sg = graph; Debug.dump(graph, "Graph"); TargetDescription target = new TargetDescription(new PTX(), true, 1, 0, true); - PTXBackend ptxBackend = new PTXBackend(Graal.getRequiredCapability(GraalCodeCacheProvider.class), target); + PTXBackend ptxBackend = new PTXBackend(getMetaAccess(), getCodeCache(), target); PhasePlan phasePlan = new PhasePlan(); - GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(runtime, GraphBuilderConfiguration.getDefault(), OptimisticOptimizations.NONE); + GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(getMetaAccess(), GraphBuilderConfiguration.getDefault(), OptimisticOptimizations.NONE); phasePlan.addPhase(PhasePosition.AFTER_PARSING, graphBuilderPhase); phasePlan.addPhase(PhasePosition.AFTER_PARSING, new PTXPhase()); new PTXPhase().apply(graph); - CallingConvention cc = getCallingConvention(runtime, Type.JavaCallee, graph.method(), false); + CallingConvention cc = getCallingConvention(getCodeCache(), Type.JavaCallee, graph.method(), false); /* * Use Suites.createDefaultSuites() instead of GraalCompilerTest.suites. The - * GraalCompilerTest.suites variable contains the Suites for the HotSpotRuntime. This code - * will not run on hotspot, so it should use the plain Graal default suites, without hotspot - * specific phases. - * - * Ultimately we might want to have both the kernel and the code natively compiled for GPU fallback to CPU in cases - * of ECC failure on kernel invocation. + * GraalCompilerTest.suites variable contains the Suites for the HotSpotRuntime. This + * code will not run on hotspot, so it should use the plain Graal default suites, + * without hotspot specific phases. + * + * Ultimately we might want to have both the kernel and the code natively compiled for + * GPU fallback to CPU in cases of ECC failure on kernel invocation. */ - CompilationResult result = GraalCompiler.compileGraph(graph, cc, graph.method(), runtime, - graalRuntime().getReplacements(), ptxBackend, target, - null, phasePlan, - OptimisticOptimizations.NONE, new SpeculationLog(), - Suites.createDefaultSuites(), new ExternalCompilationResult()); + CompilationResult result = GraalCompiler.compileGraph(graph, cc, graph.method(), getProviders(), ptxBackend, target, null, phasePlan, OptimisticOptimizations.NONE, + new SpeculationLog(), Suites.createDefaultSuites(), new ExternalCompilationResult()); return result; } else { return null; @@ -101,9 +102,49 @@ HotSpotResolvedJavaMethod compiledMethod = (HotSpotResolvedJavaMethod) sg.method(); boolean isStatic = Modifier.isStatic(compiledMethod.getModifiers()); Object[] executeArgs = argsWithReceiver((isStatic ? null : this), args); - HotSpotRuntime hsr = (HotSpotRuntime) runtime; - InstalledCode installedCode = hsr.addExternalMethod(sg.method(), result, sg); - Object r = installedCode.executeVarargs(executeArgs); + HotSpotRuntime hsr = (HotSpotRuntime) getCodeCache(); + InstalledCode installedCode = hsr.addExternalMethod(compiledMethod, result); + Annotation[][] params = compiledMethod.getParameterAnnotations(); + + int dimensionX = 1; + int dimensionY = 1; + int dimensionZ = 1; + + for (int p = 0; p < params.length; p++) { + Annotation[] annos = params[p]; + if (annos != null) { + for (int a = 0; a < annos.length; a++) { + Annotation aa = annos[a]; + if (args[p] instanceof int[] && aa.annotationType().equals(ParallelOver.class)) { + int[] iarray = (int[]) args[p]; + ParallelOver threadBlockDimension = (ParallelOver) aa; + switch (threadBlockDimension.dimension()) { + case X: + dimensionX = iarray.length; + break; + case Y: + dimensionY = iarray.length; + break; + case Z: + dimensionZ = iarray.length; + break; + } + } + } + } + } + Object r; + if (dimensionX != 1 || dimensionY != 1 || dimensionZ != 1) { + /* + * for now assert that the warp array block is no larger than the number of physical + * gpu cores. + */ + assert dimensionX * dimensionY * dimensionZ < PTXTargetMethodAssembler.getAvailableProcessors(); + + r = ((HotSpotNmethod) installedCode).executeParallel(dimensionX, dimensionY, dimensionZ, executeArgs); + } else { + r = installedCode.executeVarargs(executeArgs); + } return r; } catch (Throwable th) { th.printStackTrace();
--- a/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXBackend.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXBackend.java Fri Oct 11 17:21:14 2013 +0200 @@ -48,8 +48,8 @@ */ public class PTXBackend extends Backend { - public PTXBackend(CodeCacheProvider runtime, TargetDescription target) { - super(runtime, target); + public PTXBackend(MetaAccessProvider metaAccess, CodeCacheProvider codeCache, TargetDescription target) { + super(metaAccess, codeCache, target); } @Override @@ -59,12 +59,12 @@ @Override public FrameMap newFrameMap() { - return new PTXFrameMap(runtime(), target, runtime().lookupRegisterConfig()); + return new PTXFrameMap(getCodeCache(), target, getCodeCache().getRegisterConfig()); } @Override public LIRGenerator newLIRGenerator(StructuredGraph graph, FrameMap frameMap, CallingConvention cc, LIR lir) { - return new PTXLIRGenerator(graph, runtime(), target, frameMap, cc, lir); + return new PTXLIRGenerator(graph, getMetaAccess(), getCodeCache(), target, frameMap, cc, lir); } class HotSpotFrameContext implements FrameContext { @@ -94,7 +94,7 @@ FrameMap frameMap = lirGen.frameMap; AbstractAssembler masm = createAssembler(frameMap); HotSpotFrameContext frameContext = new HotSpotFrameContext(); - TargetMethodAssembler tasm = new PTXTargetMethodAssembler(target, runtime(), frameMap, masm, frameContext, compilationResult); + TargetMethodAssembler tasm = new PTXTargetMethodAssembler(target, getCodeCache(), frameMap, masm, frameContext, compilationResult); tasm.setFrameSize(0); return tasm; } @@ -109,8 +109,8 @@ Buffer codeBuffer = tasm.asm.codeBuffer; // Emit initial boiler-plate directives. - codeBuffer.emitString(".version 1.4"); - codeBuffer.emitString(".target sm_10"); + codeBuffer.emitString(".version 3.0"); + codeBuffer.emitString(".target sm_30"); codeBuffer.emitString0(".entry " + name + " ("); codeBuffer.emitString(""); @@ -140,9 +140,10 @@ } // Emit .reg space declarations - private static void emitRegisterDecl(TargetMethodAssembler tasm, LIRGenerator lirGen, - ResolvedJavaMethod codeCacheOwner) { + private static void emitRegisterDecl(TargetMethodAssembler tasm, LIRGenerator lirGen, ResolvedJavaMethod codeCacheOwner) { + assert codeCacheOwner != null : lirGen.getGraph() + " is not associated with a method"; + Buffer codeBuffer = tasm.asm.codeBuffer; final SortedSet<Integer> signed32 = new TreeSet<>(); @@ -231,6 +232,7 @@ if (maxPredRegNum > 0) { codeBuffer.emitString(".reg .pred %p<" + maxPredRegNum + ">;"); } + codeBuffer.emitString(".reg .pred %r;"); // used for setp bool } @Override @@ -246,7 +248,7 @@ } catch (GraalInternalError e) { e.printStackTrace(); // TODO : Better error handling needs to be done once - // all types of parameters are handled. + // all types of parameters are handled. codeBuffer.setPosition(0); codeBuffer.close(false); return; @@ -257,7 +259,7 @@ } catch (GraalInternalError e) { e.printStackTrace(); // TODO : Better error handling needs to be done once - // all types of parameters are handled. + // all types of parameters are handled. codeBuffer.setPosition(0); codeBuffer.close(false); return;
--- a/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXLIRGenerator.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXLIRGenerator.java Fri Oct 11 17:21:14 2013 +0200 @@ -46,6 +46,8 @@ import com.oracle.graal.lir.ptx.PTXArithmetic.Unary2Op; import com.oracle.graal.lir.ptx.PTXCompare.CompareOp; import com.oracle.graal.lir.ptx.PTXControlFlow.BranchOp; +import com.oracle.graal.lir.ptx.PTXControlFlow.CondMoveOp; +import com.oracle.graal.lir.ptx.PTXControlFlow.FloatCondMoveOp; import com.oracle.graal.lir.ptx.PTXControlFlow.ReturnOp; import com.oracle.graal.lir.ptx.PTXControlFlow.ReturnNoValOp; import com.oracle.graal.lir.ptx.PTXControlFlow.SequentialSwitchOp; @@ -62,6 +64,8 @@ import com.oracle.graal.nodes.calc.ConvertNode.Op; import com.oracle.graal.nodes.java.*; +import java.lang.annotation.*; + /** * This class implements the PTX specific portion of the LIR generator. */ @@ -83,8 +87,8 @@ } } - public PTXLIRGenerator(StructuredGraph graph, CodeCacheProvider runtime, TargetDescription target, FrameMap frameMap, CallingConvention cc, LIR lir) { - super(graph, runtime, target, frameMap, cc, lir); + public PTXLIRGenerator(StructuredGraph graph, MetaAccessProvider metaAccess, CodeCacheProvider codeCache, TargetDescription target, FrameMap frameMap, CallingConvention cc, LIR lir) { + super(graph, metaAccess, codeCache, target, frameMap, cc, lir); lir.spillMoveFactory = new PTXSpillMoveFactory(); int callVariables = cc.getArgumentCount() + (cc.getReturn() == Value.ILLEGAL ? 0 : 1); lir.setFirstVariableNumber(callVariables); @@ -105,7 +109,7 @@ public boolean canInlineConstant(Constant c) { switch (c.getKind()) { case Long: - return NumUtil.isInt(c.asLong()) && !runtime.needsDataPatch(c); + return NumUtil.isInt(c.asLong()) && !codeCache.needsDataPatch(c); case Object: return c.isNull(); default: @@ -132,22 +136,62 @@ public void emitPrologue() { // Need to emit .param directives based on incoming arguments and return value CallingConvention incomingArguments = cc; - int argCount = incomingArguments.getArgumentCount(); - // Additional argument for return value. - Variable[] params = new Variable[argCount + 1]; - for (int i = 0; i < argCount; i++) { - params[i] = (Variable) incomingArguments.getArgument(i); + Object returnObject = incomingArguments.getReturn(); + AllocatableValue[] params; + int argCount; + + if (returnObject == Value.ILLEGAL) { + params = incomingArguments.getArguments(); + } else { + argCount = incomingArguments.getArgumentCount(); + params = new Variable[argCount + 1]; + for (int i = 0; i < argCount; i++) { + params[i] = incomingArguments.getArgument(i); + } + params[argCount] = (Variable) returnObject; } - // Add the return value as the last parameter. - params[argCount] = (Variable) incomingArguments.getReturn(); append(new PTXParameterOp(params)); for (LocalNode local : graph.getNodes(LocalNode.class)) { Value param = params[local.index()]; - setResult(local, emitLoadParam(param.getKind(), param, null)); + Annotation[] annos = graph.method().getParameterAnnotations()[local.index()]; + Warp warpAnnotation = null; + + if (annos != null) { + for (int a = 0; a < annos.length; a++) { + if (annos[a].annotationType().equals(Warp.class)) { + warpAnnotation = (Warp) annos[a]; + } + } + } + if (warpAnnotation != null) { + setResult(local, emitWarpParam(param.getKind(), warpAnnotation)); + } else { + setResult(local, emitLoadParam(param.getKind(), param, null)); + } } } + public Variable emitWarpParam(Kind kind, Warp annotation) { + Variable result = newVariable(kind); + Variable tid = newVariable(Kind.Char); + + switch (annotation.dimension()) { + case X: + tid.setName("%tid.x"); + break; + case Y: + tid.setName("%tid.y"); + break; + case Z: + tid.setName("%tid.y"); + break; + } + emitMove(result, tid); + + return result; + } + @Override public Variable emitMove(Value input) { Variable result = newVariable(input.getKind()); @@ -168,38 +212,47 @@ public PTXAddressValue 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) { + } else if (asConstant(base).getKind() != Kind.Object && !codeCache.needsDataPatch(asConstant(base))) { finalDisp += asConstant(base).asLong(); baseRegister = Value.ILLEGAL; } else { baseRegister = load(base); } + } else if (base.equals(Value.ILLEGAL)) { + baseRegister = Value.ILLEGAL; } else { baseRegister = asAllocatable(base); } - @SuppressWarnings("unused") Value indexRegister; - if (!index.equals(Value.ILLEGAL) && scale != 0) { + if (!index.equals(Value.ILLEGAL)) { if (isConstant(index)) { finalDisp += asConstant(index).asLong() * scale; - indexRegister = Value.ILLEGAL; } else { + Value convertedIndex; + Value indexRegister; + + convertedIndex = emitConvert(Op.I2L, index); if (scale != 1) { - Variable longIndex = emitConvert(Op.I2L, index); if (CodeUtil.isPowerOf2(scale)) { - indexRegister = emitShl(longIndex, Constant.forLong(CodeUtil.log2(scale))); + indexRegister = emitShl(convertedIndex, Constant.forInt(CodeUtil.log2(scale))); } else { - indexRegister = emitMul(longIndex, Constant.forLong(scale)); + indexRegister = emitMul(convertedIndex, Constant.forInt(scale)); } } else { - indexRegister = asAllocatable(index); + indexRegister = convertedIndex; + } + if (baseRegister.equals(Value.ILLEGAL)) { + baseRegister = asAllocatable(indexRegister); + } else { + Variable longBaseRegister = newVariable(Kind.Long); + emitMove(longBaseRegister, baseRegister); + baseRegister = emitAdd(longBaseRegister, indexRegister); } } - } else { - indexRegister = Value.ILLEGAL; } return new PTXAddressValue(target().wordKind, baseRegister, finalDisp); @@ -275,21 +328,100 @@ @Override public void emitIntegerTestBranch(Value left, Value right, boolean negated, LabelRef label) { - throw GraalInternalError.unimplemented("PTXLIRGenerator.emitIntegerTestBranch()"); + // / emitIntegerTest(left, right); + // append(new BranchOp(negated ? Condition.NE : Condition.EQ, label)); + throw GraalInternalError.unimplemented("emitIntegerTestBranch()"); } @Override public Variable emitConditionalMove(Value left, Value right, Condition cond, boolean unorderedIsTrue, Value trueValue, Value falseValue) { - // TODO: There is no conventional conditional move instruction in PTX. - // So, this method is changed to throw NYI exception. - // To be revisited if this needs to be really implemented. - throw GraalInternalError.unimplemented("PTXLIRGenerator.emitConditionalMove()"); + + Condition finalCondition = LIRValueUtil.isVariable(right) ? cond.mirror() : cond; + + emitCompare(finalCondition, left, right); + + Variable result = newVariable(trueValue.getKind()); + switch (left.getKind().getStackKind()) { + case Int: + case Long: + case Object: + append(new CondMoveOp(result, finalCondition, load(trueValue), loadNonConst(falseValue), nextPredRegNum)); + nextPredRegNum++; + break; + case Float: + case Double: + append(new FloatCondMoveOp(result, finalCondition, unorderedIsTrue, load(trueValue), load(falseValue), nextPredRegNum)); + nextPredRegNum++; + 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(Condition cond, 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, cond, left, right, nextPredRegNum)); + break; + case Long: + append(new CompareOp(LCMP, cond, left, right, nextPredRegNum)); + break; + case Object: + append(new CompareOp(ACMP, cond, left, right, nextPredRegNum)); + break; + case Float: + append(new CompareOp(FCMP, cond, left, right, nextPredRegNum)); + break; + case Double: + append(new CompareOp(DCMP, cond, left, right, nextPredRegNum)); + break; + default: + throw GraalInternalError.shouldNotReachHere(); + } + return mirrored; + } @Override public Variable emitIntegerTestMove(Value left, Value right, Value trueValue, Value falseValue) { - throw new InternalError("NYI"); + + emitIntegerTest(left, right); + Variable result = newVariable(trueValue.getKind()); + append(new CondMoveOp(result, Condition.EQ, load(trueValue), loadNonConst(falseValue), nextPredRegNum)); + nextPredRegNum++; + + return result; + } + + private void emitIntegerTest(Value a, Value b) { + + assert a.getKind().getStackKind() == Kind.Int || a.getKind() == Kind.Long; + + if (LIRValueUtil.isVariable(b)) { + append(new PTXTestOp(load(b), loadNonConst(a), nextPredRegNum)); + } else { + append(new PTXTestOp(load(a), loadNonConst(b), nextPredRegNum)); + } } @Override @@ -504,7 +636,7 @@ append(new Op2Stack(ISHL, result, a, loadNonConst(b))); break; case Long: - append(new Op1Stack(LSHL, result, loadNonConst(b))); + append(new Op2Stack(LSHL, result, a, loadNonConst(b))); break; default: throw GraalInternalError.shouldNotReachHere(); @@ -520,7 +652,7 @@ append(new Op2Stack(ISHR, result, a, loadNonConst(b))); break; case Long: - append(new Op1Stack(LSHR, result, loadNonConst(b))); + append(new Op2Stack(LSHR, result, a, loadNonConst(b))); break; default: throw GraalInternalError.shouldNotReachHere(); @@ -619,7 +751,7 @@ } @Override - public void emitDeoptimize(DeoptimizationAction action, DeoptimizingNode deopting) { + public void emitDeoptimize(Value actionAndReason, DeoptimizingNode deopting) { append(new ReturnOp(Value.ILLEGAL)); } @@ -711,10 +843,10 @@ // 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, nextPredRegNum)); + append(new SequentialSwitchOp(keyConstants, keyTargets, defaultTarget, key, Value.ILLEGAL, nextPredRegNum++)); } else { assert key.getKind() == Kind.Object : key.getKind(); - append(new SequentialSwitchOp(keyConstants, keyTargets, defaultTarget, key, newVariable(Kind.Object), nextPredRegNum)); + append(new SequentialSwitchOp(keyConstants, keyTargets, defaultTarget, key, newVariable(Kind.Object), nextPredRegNum++)); } } @@ -764,20 +896,36 @@ } public Variable emitLoadParam(Kind kind, Value address, DeoptimizingNode deopting) { + PTXAddressValue loadAddress = asAddress(address); Variable result = newVariable(kind); append(new LoadParamOp(kind, result, loadAddress, deopting != null ? state(deopting) : null)); + return result; } public Variable emitLoadReturnAddress(Kind kind, Value address, DeoptimizingNode deopting) { + PTXAddressValue loadAddress = asAddress(address); - Variable result = newVariable(kind); + Variable result; + switch (kind) { + case Float: + result = newVariable(Kind.Int); + break; + case Double: + result = newVariable(Kind.Long); + break; + default: + result = newVariable(kind); + + } append(new LoadReturnAddrOp(kind, result, loadAddress, deopting != null ? state(deopting) : null)); + return result; } public void emitStoreReturnValue(Kind kind, Value address, Value inputVal, DeoptimizingNode deopting) { + PTXAddressValue storeAddress = asAddress(address); Variable input = load(inputVal); append(new StoreReturnValOp(kind, storeAddress, input, deopting != null ? state(deopting) : null));
--- a/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXTargetMethodAssembler.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXTargetMethodAssembler.java Fri Oct 11 17:21:14 2013 +0200 @@ -33,25 +33,41 @@ public class PTXTargetMethodAssembler extends TargetMethodAssembler { - private static CompilerToGPU toGPU = HotSpotGraalRuntime.graalRuntime().getCompilerToGPU(); + private static CompilerToGPU toGPU = + HotSpotGraalRuntime.graalRuntime().getCompilerToGPU(); + private static boolean validDevice = toGPU.deviceInit(); + private static final int totalProcessors = + (validDevice ? toGPU.availableProcessors() : 0); + + public static int getAvailableProcessors() { + return totalProcessors; + } + // detach ?? - public PTXTargetMethodAssembler(TargetDescription target, CodeCacheProvider runtime, FrameMap frameMap, - AbstractAssembler asm, FrameContext frameContext, CompilationResult compilationResult) { - super(target, runtime, frameMap, asm, frameContext, compilationResult); + public PTXTargetMethodAssembler(TargetDescription target, + CodeCacheProvider codeCache, + FrameMap frameMap, + AbstractAssembler asm, + FrameContext frameContext, + CompilationResult compilationResult) { + super(target, codeCache, frameMap, asm, frameContext, compilationResult); } @Override public CompilationResult finishTargetMethod(StructuredGraph graph) { ResolvedJavaMethod method = graph.method(); assert method != null : graph + " is not associated wth a method"; - ExternalCompilationResult graalCompile = (ExternalCompilationResult) super.finishTargetMethod(graph); + + ExternalCompilationResult graalCompile = + (ExternalCompilationResult) super.finishTargetMethod(graph); try { if ((validDevice) && (graalCompile.getTargetCode() != null)) { - long kernel = toGPU.generateKernel(graalCompile.getTargetCode(), method.getName()); + long kernel = toGPU.generateKernel(graalCompile.getTargetCode(), + method.getName()); graalCompile.setEntryPoint(kernel); } } catch (Throwable th) {
--- a/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java Fri Oct 11 17:21:14 2013 +0200 @@ -77,8 +77,8 @@ } } - public SPARCLIRGenerator(StructuredGraph graph, CodeCacheProvider runtime, TargetDescription target, FrameMap frameMap, CallingConvention cc, LIR lir) { - super(graph, runtime, target, frameMap, cc, lir); + public SPARCLIRGenerator(StructuredGraph graph, MetaAccessProvider metaAccess, CodeCacheProvider codeCache, TargetDescription target, FrameMap frameMap, CallingConvention cc, LIR lir) { + super(graph, metaAccess, codeCache, target, frameMap, cc, lir); lir.spillMoveFactory = new SPARCSpillMoveFactory(); } @@ -98,9 +98,9 @@ public boolean canInlineConstant(Constant c) { switch (c.getKind()) { case Int: - return SPARCAssembler.isSimm13(c.asInt()) && !runtime.needsDataPatch(c); + return SPARCAssembler.isSimm13(c.asInt()) && !codeCache.needsDataPatch(c); case Long: - return SPARCAssembler.isSimm13(c.asLong()) && !runtime.needsDataPatch(c); + return SPARCAssembler.isSimm13(c.asLong()) && !codeCache.needsDataPatch(c); case Object: return c.isNull(); default: @@ -837,7 +837,7 @@ } @Override - public void emitDeoptimize(DeoptimizationAction action, DeoptimizingNode deopting) { + public void emitDeoptimize(Value actionAndReason, DeoptimizingNode deopting) { append(new ReturnOp(Value.ILLEGAL)); } @@ -850,7 +850,7 @@ 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); + sig[i] = node.arguments().get(i).stamp().javaType(metaAccess); } Value[] parameters = visitInvokeArguments(frameMap.registerConfig.getCallingConvention(CallingConvention.Type.JavaCall, null, sig, target(), false), node.arguments());
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/BoxingEliminationTest.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/BoxingEliminationTest.java Fri Oct 11 17:21:14 2013 +0200 @@ -307,7 +307,7 @@ private void processMethod(final String snippet) { graph = parse(snippet); Assumptions assumptions = new Assumptions(false); - HighTierContext context = new HighTierContext(runtime(), assumptions, replacements, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL); + HighTierContext context = new HighTierContext(getProviders(), assumptions, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL); new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context); new PartialEscapePhase(false, new CanonicalizerPhase(true)).apply(graph, context); } @@ -324,7 +324,7 @@ graph = parse(snippet); Assumptions assumptions = new Assumptions(false); - HighTierContext context = new HighTierContext(runtime(), assumptions, replacements, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL); + HighTierContext context = new HighTierContext(getProviders(), assumptions, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL); CanonicalizerPhase canonicalizer = new CanonicalizerPhase(true); new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context); if (loopPeeling) {
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/CompareCanonicalizerTest.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/CompareCanonicalizerTest.java Fri Oct 11 17:21:14 2013 +0200 @@ -36,7 +36,7 @@ private StructuredGraph getCanonicalizedGraph(String name) { StructuredGraph graph = parse(name); - new CanonicalizerPhase(true).apply(graph, new PhaseContext(runtime(), null, replacements)); + new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), null)); return graph; } @@ -54,7 +54,7 @@ assertEquals(referenceGraph, graph); } Assumptions assumptions = new Assumptions(false); - new CanonicalizerPhase(true).apply(referenceGraph, new PhaseContext(runtime(), assumptions, replacements)); + new CanonicalizerPhase(true).apply(referenceGraph, new PhaseContext(getProviders(), assumptions)); for (int i = 1; i < 4; i++) { StructuredGraph graph = getCanonicalizedGraph("canonicalCompare" + i); assertEquals(referenceGraph, graph);
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest.java Fri Oct 11 17:21:14 2013 +0200 @@ -141,8 +141,8 @@ test("testNullnessSnippet", new Object(), new Object()); StructuredGraph graph = parse("testNullnessSnippet"); - new ConditionalEliminationPhase(runtime()).apply(graph); - new CanonicalizerPhase(true).apply(graph, new PhaseContext(runtime(), null, replacements)); + new ConditionalEliminationPhase(getMetaAccess()).apply(graph); + new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), null)); for (ConstantNode constant : graph.getNodes().filter(ConstantNode.class)) { assertTrue("unexpected constant: " + constant, constant.asConstant().isNull() || constant.asConstant().asInt() > 0); } @@ -164,7 +164,7 @@ @Test public void testDisjunction() { StructuredGraph graph = parse("testDisjunctionSnippet"); - new CanonicalizerPhase(true).apply(graph, new PhaseContext(runtime(), null, replacements)); + new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), null)); IfNode ifNode = (IfNode) graph.start().next(); InstanceOfNode instanceOf = (InstanceOfNode) ifNode.condition(); IsNullNode x = graph.unique(new IsNullNode(graph.getLocal(0))); @@ -172,9 +172,9 @@ ShortCircuitOrNode disjunction = graph.unique(new ShortCircuitOrNode(x, false, y, false, NOT_FREQUENT_PROBABILITY)); LogicNegationNode negation = graph.unique(new LogicNegationNode(disjunction)); ifNode.setCondition(negation); - new CanonicalizerPhase(true).apply(graph, new PhaseContext(runtime(), null, replacements)); - new ConditionalEliminationPhase(runtime()).apply(graph); - new CanonicalizerPhase(true).apply(graph, new PhaseContext(runtime(), null, replacements)); + new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), null)); + new ConditionalEliminationPhase(getMetaAccess()).apply(graph); + new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), null)); for (ConstantNode constant : graph.getNodes().filter(ConstantNode.class)) { assertTrue("unexpected constant: " + constant, constant.asConstant().isNull() || constant.asConstant().asInt() > 0); } @@ -192,8 +192,8 @@ public void testInvoke() { test("testInvokeSnippet", new Integer(16)); StructuredGraph graph = parse("testInvokeSnippet"); - new CanonicalizerPhase(true).apply(graph, new PhaseContext(runtime(), null, replacements)); - new ConditionalEliminationPhase(runtime()).apply(graph); + new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), null)); + new ConditionalEliminationPhase(getMetaAccess()).apply(graph); InvokeNode invoke = graph.getNodes().filter(InvokeNode.class).first(); assertEquals(InvokeKind.Special, ((MethodCallTargetNode) invoke.callTarget()).invokeKind()); @@ -222,9 +222,9 @@ @Test public void testTypeMerging() { StructuredGraph graph = parse("testTypeMergingSnippet"); - new CanonicalizerPhase(true).apply(graph, new PhaseContext(runtime(), null, replacements)); - new ConditionalEliminationPhase(runtime()).apply(graph); - new CanonicalizerPhase(true).apply(graph, new PhaseContext(runtime(), null, replacements)); + new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), null)); + new ConditionalEliminationPhase(getMetaAccess()).apply(graph); + new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), null)); assertEquals(0, graph.getNodes().filter(StoreFieldNode.class).count()); } @@ -239,9 +239,9 @@ @Test public void testInstanceOfCheckCast() { StructuredGraph graph = parse("testInstanceOfCheckCastSnippet"); - new CanonicalizerPhase(true).apply(graph, new PhaseContext(runtime(), null, replacements)); - new ConditionalEliminationPhase(runtime()).apply(graph); - new CanonicalizerPhase(true).apply(graph, new PhaseContext(runtime(), null, replacements)); + new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), null)); + new ConditionalEliminationPhase(getMetaAccess()).apply(graph); + new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), null)); assertEquals(0, graph.getNodes().filter(CheckCastNode.class).count()); } @@ -252,11 +252,11 @@ StructuredGraph graph = parse("testInstanceOfCheckCastSnippet"); CanonicalizerPhase canonicalizer = new CanonicalizerPhase(true); - PhaseContext context = new PhaseContext(runtime(), null, replacements); + PhaseContext context = new PhaseContext(getProviders(), null); new LoweringPhase(canonicalizer).apply(graph, context); canonicalizer.apply(graph, context); - new ConditionalEliminationPhase(runtime()).apply(graph); + new ConditionalEliminationPhase(getMetaAccess()).apply(graph); canonicalizer.apply(graph, context); assertEquals(0, graph.getNodes().filter(GuardNode.class).count());
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/DegeneratedLoopsTest.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/DegeneratedLoopsTest.java Fri Oct 11 17:21:14 2013 +0200 @@ -82,7 +82,7 @@ public void run() { StructuredGraph graph = parse(snippet); - HighTierContext context = new HighTierContext(runtime(), new Assumptions(false), replacements, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL); + HighTierContext context = new HighTierContext(getProviders(), new Assumptions(false), null, getDefaultPhasePlan(), OptimisticOptimizations.ALL); new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context); new CanonicalizerPhase(true).apply(graph, context); Debug.dump(graph, "Graph");
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/EliminateNestedCheckCastsTest.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/EliminateNestedCheckCastsTest.java Fri Oct 11 17:21:14 2013 +0200 @@ -114,7 +114,7 @@ public StructuredGraph call() throws Exception { Debug.dump(graph, "After parsing: " + snippet); Assert.assertEquals(checkcasts, graph.getNodes().filter(CheckCastNode.class).count()); - new CanonicalizerPhase(true).apply(graph, new PhaseContext(runtime(), new Assumptions(false), replacements)); + new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), new Assumptions(false))); Assert.assertEquals(afterCanon, graph.getNodes().filter(CheckCastNode.class).count()); return graph; }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FinalizableSubclassTest.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FinalizableSubclassTest.java Fri Oct 11 17:21:14 2013 +0200 @@ -63,12 +63,12 @@ private StructuredGraph parseAndProcess(Class cl, Assumptions assumptions) { Constructor<?>[] constructors = cl.getConstructors(); Assert.assertTrue(constructors.length == 1); - final ResolvedJavaMethod javaMethod = runtime.lookupJavaConstructor(constructors[0]); + final ResolvedJavaMethod javaMethod = getMetaAccess().lookupJavaConstructor(constructors[0]); StructuredGraph graph = new StructuredGraph(javaMethod); GraphBuilderConfiguration conf = GraphBuilderConfiguration.getSnippetDefault(); - new GraphBuilderPhase(runtime, conf, OptimisticOptimizations.ALL).apply(graph); - HighTierContext context = new HighTierContext(runtime(), assumptions, replacements, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL); + new GraphBuilderPhase(getMetaAccess(), conf, OptimisticOptimizations.ALL).apply(graph); + HighTierContext context = new HighTierContext(getProviders(), assumptions, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL); new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context); new CanonicalizerPhase(true).apply(graph, context); return graph;
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FloatingReadTest.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FloatingReadTest.java Fri Oct 11 17:21:14 2013 +0200 @@ -58,7 +58,7 @@ public void run() { StructuredGraph graph = parse(snippet); - PhaseContext context = new PhaseContext(runtime(), new Assumptions(false), replacements); + PhaseContext context = new PhaseContext(getProviders(), new Assumptions(false)); new LoweringPhase(new CanonicalizerPhase(true)).apply(graph, context); new FloatingReadPhase().apply(graph);
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java Fri Oct 11 17:21:14 2013 +0200 @@ -52,6 +52,7 @@ import com.oracle.graal.phases.PhasePlan.PhasePosition; import com.oracle.graal.phases.schedule.*; import com.oracle.graal.phases.tiers.*; +import com.oracle.graal.phases.util.*; import com.oracle.graal.printer.*; import com.oracle.graal.test.*; @@ -76,14 +77,20 @@ */ public abstract class GraalCompilerTest extends GraalTest { - protected final GraalCodeCacheProvider runtime; - protected final Replacements replacements; + private final CodeCacheProvider codeCache; + private final MetaAccessProvider metaAccess; + private final ConstantReflectionProvider constantReflection; + private final LoweringProvider lowerer; + private final Replacements replacements; protected final Backend backend; protected final Suites suites; public GraalCompilerTest() { this.replacements = Graal.getRequiredCapability(Replacements.class); - this.runtime = Graal.getRequiredCapability(GraalCodeCacheProvider.class); + this.metaAccess = Graal.getRequiredCapability(MetaAccessProvider.class); + this.constantReflection = Graal.getRequiredCapability(ConstantReflectionProvider.class); + this.codeCache = Graal.getRequiredCapability(CodeCacheProvider.class); + this.lowerer = Graal.getRequiredCapability(LoweringProvider.class); this.backend = Graal.getRequiredCapability(Backend.class); this.suites = Graal.getRequiredCapability(SuitesProvider.class).createSuites(); } @@ -158,8 +165,24 @@ return result.toString(); } - protected GraalCodeCacheProvider runtime() { - return runtime; + protected Providers getProviders() { + return new Providers(metaAccess, codeCache, constantReflection, lowerer, getReplacements()); + } + + protected CodeCacheProvider getCodeCache() { + return codeCache; + } + + protected ConstantReflectionProvider getConstantReflection() { + return constantReflection; + } + + protected MetaAccessProvider getMetaAccess() { + return metaAccess; + } + + protected LoweringProvider getLowerer() { + return lowerer; } /** @@ -324,7 +347,7 @@ before(method); Object[] executeArgs = argsWithReceiver(receiver, args); - ResolvedJavaMethod javaMethod = runtime.lookupJavaMethod(method); + ResolvedJavaMethod javaMethod = metaAccess.lookupJavaMethod(method); checkArgs(javaMethod, executeArgs); InstalledCode compiledMethod = getCode(javaMethod, parse(method)); @@ -347,7 +370,7 @@ if (kind == Kind.Object) { if (arg != null && javaType instanceof ResolvedJavaType) { ResolvedJavaType resolvedJavaType = (ResolvedJavaType) javaType; - Assert.assertTrue(resolvedJavaType + " from " + runtime.lookupJavaType(arg.getClass()), resolvedJavaType.isAssignableFrom(runtime.lookupJavaType(arg.getClass()))); + Assert.assertTrue(resolvedJavaType + " from " + metaAccess.lookupJavaType(arg.getClass()), resolvedJavaType.isAssignableFrom(metaAccess.lookupJavaType(arg.getClass()))); } } else { Assert.assertNotNull(arg); @@ -384,7 +407,7 @@ protected void test(Method method, Object receiver, Object... args) { Result expect = executeExpected(method, receiver, args); - if (runtime == null) { + if (getCodeCache() == null) { return; } testAgainstExpected(method, expect, receiver, args); @@ -396,7 +419,7 @@ protected Result executeActualCheckDeopt(Method method, Set<DeoptimizationReason> shouldNotDeopt, Object receiver, Object... args) { Map<DeoptimizationReason, Integer> deoptCounts = new EnumMap<>(DeoptimizationReason.class); - ResolvedJavaMethod javaMethod = runtime.lookupJavaMethod(method); + ResolvedJavaMethod javaMethod = metaAccess.lookupJavaMethod(method); ProfilingInfo profile = javaMethod.getProfilingInfo(); for (DeoptimizationReason reason : shouldNotDeopt) { deoptCounts.put(reason, profile.getDeoptimizationCount(reason)); @@ -456,7 +479,7 @@ final int id = compilationId.incrementAndGet(); - InstalledCode installedCode = Debug.scope("Compiling", new Object[]{runtime, new DebugDumpScope(String.valueOf(id), true)}, new Callable<InstalledCode>() { + InstalledCode installedCode = Debug.scope("Compiling", new Object[]{new DebugDumpScope(String.valueOf(id), true)}, new Callable<InstalledCode>() { public InstalledCode call() throws Exception { final boolean printCompilation = PrintCompilation.getValue() && !TTY.isSuppressed(); @@ -465,15 +488,15 @@ } long start = System.currentTimeMillis(); PhasePlan phasePlan = new PhasePlan(); - GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(runtime, GraphBuilderConfiguration.getDefault(), OptimisticOptimizations.ALL); + GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(metaAccess, GraphBuilderConfiguration.getDefault(), OptimisticOptimizations.ALL); phasePlan.addPhase(PhasePosition.AFTER_PARSING, graphBuilderPhase); - 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(), suites, new CompilationResult()); + CallingConvention cc = getCallingConvention(getCodeCache(), Type.JavaCallee, graph.method(), false); + final CompilationResult compResult = GraalCompiler.compileGraph(graph, cc, method, getProviders(), backend, getCodeCache().getTarget(), null, phasePlan, + OptimisticOptimizations.ALL, new SpeculationLog(), suites, new CompilationResult()); if (printCompilation) { TTY.println(String.format("@%-6d Graal %-70s %-45s %-50s | %4dms %5dB", id, "", "", "", System.currentTimeMillis() - start, compResult.getTargetCodeSize())); } - return Debug.scope("CodeInstall", new Object[]{runtime, method}, new Callable<InstalledCode>() { + return Debug.scope("CodeInstall", new Object[]{getCodeCache(), method}, new Callable<InstalledCode>() { @Override public InstalledCode call() throws Exception { @@ -507,7 +530,7 @@ } protected InstalledCode addMethod(final ResolvedJavaMethod method, final CompilationResult compResult) { - return runtime.addMethod(method, compResult); + return getCodeCache().addMethod(method, compResult); } /** @@ -544,9 +567,9 @@ private StructuredGraph parse0(Method m, GraphBuilderConfiguration conf) { assert m.getAnnotation(Test.class) == null : "shouldn't parse method with @Test annotation: " + m; - ResolvedJavaMethod javaMethod = runtime.lookupJavaMethod(m); + ResolvedJavaMethod javaMethod = metaAccess.lookupJavaMethod(m); StructuredGraph graph = new StructuredGraph(javaMethod); - new GraphBuilderPhase(runtime, conf, OptimisticOptimizations.ALL).apply(graph); + new GraphBuilderPhase(metaAccess, conf, OptimisticOptimizations.ALL).apply(graph); return graph; } @@ -558,7 +581,11 @@ PhasePlan plan = new PhasePlan(); GraphBuilderConfiguration gbConf = GraphBuilderConfiguration.getEagerDefault(); gbConf.setEagerInfopointMode(eagerInfopointMode); - plan.addPhase(PhasePosition.AFTER_PARSING, new GraphBuilderPhase(runtime, gbConf, OptimisticOptimizations.ALL)); + plan.addPhase(PhasePosition.AFTER_PARSING, new GraphBuilderPhase(metaAccess, gbConf, OptimisticOptimizations.ALL)); return plan; } + + protected Replacements getReplacements() { + return replacements; + } }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/IfCanonicalizerTest.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/IfCanonicalizerTest.java Fri Oct 11 17:21:14 2013 +0200 @@ -145,7 +145,7 @@ n.replaceFirstInput(local, constant); } Debug.dump(graph, "Graph"); - new CanonicalizerPhase(true).apply(graph, new PhaseContext(runtime(), new Assumptions(false), replacements)); + new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), new Assumptions(false))); for (FrameState fs : local.usages().filter(FrameState.class).snapshot()) { fs.replaceFirstInput(local, null); }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/InfopointReasonTest.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/InfopointReasonTest.java Fri Oct 11 17:21:14 2013 +0200 @@ -58,8 +58,8 @@ public void callInfopoints() { final Method method = getMethod("testMethod"); final StructuredGraph graph = parse(method); - CallingConvention cc = getCallingConvention(runtime, Type.JavaCallee, graph.method(), false); - final CompilationResult cr = GraalCompiler.compileGraph(graph, cc, graph.method(), runtime, replacements, backend, runtime.getTarget(), null, getDefaultPhasePlan(), + CallingConvention cc = getCallingConvention(getCodeCache(), Type.JavaCallee, graph.method(), false); + final CompilationResult cr = GraalCompiler.compileGraph(graph, cc, graph.method(), getProviders(), backend, getCodeCache().getTarget(), null, getDefaultPhasePlan(), OptimisticOptimizations.ALL, new SpeculationLog(), suites, new CompilationResult()); for (Infopoint sp : cr.getInfopoints()) { assertNotNull(sp.reason); @@ -80,8 +80,8 @@ } } assertTrue(graphLineSPs > 0); - CallingConvention cc = getCallingConvention(runtime, Type.JavaCallee, graph.method(), false); - final CompilationResult cr = GraalCompiler.compileGraph(graph, cc, graph.method(), runtime, replacements, backend, runtime.getTarget(), null, getDefaultPhasePlan(true), + CallingConvention cc = getCallingConvention(getCodeCache(), Type.JavaCallee, graph.method(), false); + final CompilationResult cr = GraalCompiler.compileGraph(graph, cc, graph.method(), getProviders(), backend, getCodeCache().getTarget(), null, getDefaultPhasePlan(true), OptimisticOptimizations.ALL, new SpeculationLog(), suites, new CompilationResult()); int lineSPs = 0; for (Infopoint sp : cr.getInfopoints()) {
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/InvokeExceptionTest.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/InvokeExceptionTest.java Fri Oct 11 17:21:14 2013 +0200 @@ -66,7 +66,7 @@ hints.put(invoke, 1000d); } Assumptions assumptions = new Assumptions(false); - HighTierContext context = new HighTierContext(runtime(), assumptions, replacements, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL); + HighTierContext context = new HighTierContext(getProviders(), assumptions, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL); new InliningPhase(hints, new CanonicalizerPhase(true)).apply(graph, context); new CanonicalizerPhase(true).apply(graph, context); new DeadCodeEliminationPhase().apply(graph);
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/InvokeHintsTest.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/InvokeHintsTest.java Fri Oct 11 17:21:14 2013 +0200 @@ -77,7 +77,7 @@ } Assumptions assumptions = new Assumptions(false); - HighTierContext context = new HighTierContext(runtime(), assumptions, replacements, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL); + HighTierContext context = new HighTierContext(getProviders(), assumptions, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL); new InliningPhase(hints, new CanonicalizerPhase(true)).apply(graph, context); new CanonicalizerPhase(true).apply(graph, context); new DeadCodeEliminationPhase().apply(graph);
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/LockEliminationTest.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/LockEliminationTest.java Fri Oct 11 17:21:14 2013 +0200 @@ -61,7 +61,7 @@ test("testSynchronizedSnippet", new A(), new A()); StructuredGraph graph = getGraph("testSynchronizedSnippet"); - new CanonicalizerPhase(true).apply(graph, new PhaseContext(runtime(), null, replacements)); + new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), null)); new LockEliminationPhase().apply(graph); assertEquals(1, graph.getNodes().filter(MonitorEnterNode.class).count()); assertEquals(1, graph.getNodes().filter(MonitorExitNode.class).count()); @@ -79,7 +79,7 @@ test("testSynchronizedMethodSnippet", new A()); StructuredGraph graph = getGraph("testSynchronizedMethodSnippet"); - new CanonicalizerPhase(true).apply(graph, new PhaseContext(runtime(), null, replacements)); + new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), null)); new LockEliminationPhase().apply(graph); assertEquals(1, graph.getNodes().filter(MonitorEnterNode.class).count()); assertEquals(1, graph.getNodes().filter(MonitorExitNode.class).count()); @@ -90,7 +90,7 @@ StructuredGraph graph = parse(method); PhasePlan phasePlan = getDefaultPhasePlan(); Assumptions assumptions = new Assumptions(true); - HighTierContext context = new HighTierContext(runtime(), assumptions, replacements, null, phasePlan, OptimisticOptimizations.ALL); + HighTierContext context = new HighTierContext(getProviders(), assumptions, null, phasePlan, OptimisticOptimizations.ALL); new CanonicalizerPhase(true).apply(graph, context); new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context); new CanonicalizerPhase(true).apply(graph, context);
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/LoopUnswitchTest.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/LoopUnswitchTest.java Fri Oct 11 17:21:14 2013 +0200 @@ -134,8 +134,8 @@ } Assumptions assumptions = new Assumptions(false); - new CanonicalizerPhase(true).apply(graph, new PhaseContext(runtime(), assumptions, replacements)); - new CanonicalizerPhase(true).apply(referenceGraph, new PhaseContext(runtime(), assumptions, replacements)); + new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), assumptions)); + new CanonicalizerPhase(true).apply(referenceGraph, new PhaseContext(getProviders(), assumptions)); Debug.scope("Test", new DebugDumpScope("Test:" + snippet), new Runnable() { @Override
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MemoryScheduleTest.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MemoryScheduleTest.java Fri Oct 11 17:21:14 2013 +0200 @@ -94,7 +94,7 @@ /** * In this case the read should be scheduled in the first block. */ - public static int testSplitSnippet1(int a) { + public static int testSplit1Snippet(int a) { try { return container.a; } finally { @@ -109,7 +109,7 @@ @Test public void testSplit1() { for (TestMode mode : TestMode.values()) { - SchedulePhase schedule = getFinalSchedule("testSplitSnippet1", mode, MemoryScheduling.OPTIMAL); + SchedulePhase schedule = getFinalSchedule("testSplit1Snippet", mode, MemoryScheduling.OPTIMAL); assertReadWithinStartBlock(schedule, true); assertReadWithinReturnBlock(schedule, false); } @@ -209,6 +209,42 @@ assertReadWithinReturnBlock(schedule, false); } + public String testStringReplaceSnippet(String input) { + return input.replace('a', 'b'); + } + + @Test + public void testStringReplace() { + getFinalSchedule("testStringReplaceSnippet", TestMode.INLINED_WITHOUT_FRAMESTATES, MemoryScheduling.OPTIMAL); + test("testStringReplaceSnippet", "acbaaa"); + } + + /** + * Here the read should float out of the loop. + */ + public static int testLoop5Snippet(int a, int b, MemoryScheduleTest obj) { + int ret = 0; + int bb = b; + for (int i = 0; i < a; i++) { + ret = obj.hash; + if (a > 10) { + bb++; + } else { + bb--; + } + ret = ret / 10; + } + return ret + bb; + } + + @Test + public void testLoop5() { + SchedulePhase schedule = getFinalSchedule("testLoop5Snippet", TestMode.WITHOUT_FRAMESTATES, MemoryScheduling.OPTIMAL); + assertEquals(7, schedule.getCFG().getBlocks().length); + assertReadWithinStartBlock(schedule, false); + assertReadWithinReturnBlock(schedule, false); + } + /** * Here the read should float to the end (into the same block as the return). */ @@ -312,6 +348,25 @@ } /** + * Here the read should float to the end. + */ + public static int testIfRead5Snippet(int a) { + if (a < 0) { + container.a = 10; + } + return container.a; + } + + @Test + public void testIfRead5() { + SchedulePhase schedule = getFinalSchedule("testIfRead5Snippet", TestMode.WITHOUT_FRAMESTATES, MemoryScheduling.OPTIMAL); + assertEquals(4, schedule.getCFG().getBlocks().length); + assertReadWithinStartBlock(schedule, false); + assertReadWithinReturnBlock(schedule, true); + assertReadAndWriteInSameBlock(schedule, false); + } + + /** * testing scheduling within a block. */ public static int testBlockScheduleSnippet() { @@ -498,7 +553,8 @@ @Override public SchedulePhase call() throws Exception { Assumptions assumptions = new Assumptions(false); - HighTierContext context = new HighTierContext(runtime(), assumptions, replacements, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL); + HighTierContext context = new HighTierContext(getProviders(), assumptions, null, getDefaultPhasePlan(), + OptimisticOptimizations.ALL); new CanonicalizerPhase(true).apply(graph, context); if (mode == TestMode.INLINED_WITHOUT_FRAMESTATES) { new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context); @@ -520,7 +576,8 @@ new FloatingReadPhase().apply(graph); new RemoveValueProxyPhase().apply(graph); - MidTierContext midContext = new MidTierContext(runtime(), assumptions, replacements, runtime().getTarget(), OptimisticOptimizations.ALL); + MidTierContext midContext = new MidTierContext(getProviders(), assumptions, getCodeCache().getTarget(), + OptimisticOptimizations.ALL); new GuardLoweringPhase().apply(graph, midContext); new LoweringPhase(new CanonicalizerPhase(true)).apply(graph, midContext); new LoweringPhase(new CanonicalizerPhase(true)).apply(graph, midContext);
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MonitorGraphTest.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MonitorGraphTest.java Fri Oct 11 17:21:14 2013 +0200 @@ -94,7 +94,7 @@ hints.put(invoke, 1000d); } Assumptions assumptions = new Assumptions(false); - HighTierContext context = new HighTierContext(runtime(), assumptions, replacements, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL); + HighTierContext context = new HighTierContext(getProviders(), assumptions, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL); new InliningPhase(hints, new CanonicalizerPhase(true)).apply(graph, context); new CanonicalizerPhase(true).apply(graph, context); new DeadCodeEliminationPhase().apply(graph);
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/PhiCreationTests.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/PhiCreationTests.java Fri Oct 11 17:21:14 2013 +0200 @@ -41,7 +41,7 @@ @Test public void test1() { StructuredGraph graph = parse("test1Snippet"); - Assert.assertFalse(graph.getNodes(PhiNode.class).iterator().hasNext()); + Assert.assertFalse(graph.getNodes().filter(PhiNode.class).iterator().hasNext()); } public static int test1Snippet(int a) { @@ -54,7 +54,7 @@ @Test public void test2() { StructuredGraph graph = parse("test2Snippet"); - Assert.assertFalse(graph.getNodes(PhiNode.class).iterator().hasNext()); + Assert.assertFalse(graph.getNodes().filter(PhiNode.class).iterator().hasNext()); } public static int test2Snippet(int a) { @@ -68,7 +68,7 @@ public void test3() { StructuredGraph graph = parse("test3Snippet"); Debug.dump(graph, "Graph"); - Assert.assertFalse(graph.getNodes(PhiNode.class).iterator().hasNext()); + Assert.assertFalse(graph.getNodes().filter(PhiNode.class).iterator().hasNext()); } public static int test3Snippet(int a) { @@ -84,7 +84,7 @@ public void test4() { StructuredGraph graph = parse("test4Snippet"); Debug.dump(graph, "Graph"); - Assert.assertFalse(graph.getNodes(PhiNode.class).iterator().hasNext()); + Assert.assertFalse(graph.getNodes().filter(PhiNode.class).iterator().hasNext()); } public static int test4Snippet(int a) {
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ProfilingInfoTest.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ProfilingInfoTest.java Fri Oct 11 17:21:14 2013 +0200 @@ -145,8 +145,8 @@ } private void testTypeProfile(String testSnippet, int bci) { - ResolvedJavaType stringType = runtime.lookupJavaType(String.class); - ResolvedJavaType stringBuilderType = runtime.lookupJavaType(StringBuilder.class); + ResolvedJavaType stringType = getMetaAccess().lookupJavaType(String.class); + ResolvedJavaType stringBuilderType = getMetaAccess().lookupJavaType(StringBuilder.class); ProfilingInfo info = profile(testSnippet, "ABC"); JavaTypeProfile typeProfile = info.getTypeProfile(bci); @@ -297,7 +297,7 @@ Method method = getMethod(methodName); Assert.assertTrue(Modifier.isStatic(method.getModifiers())); - ResolvedJavaMethod javaMethod = runtime.lookupJavaMethod(method); + ResolvedJavaMethod javaMethod = getMetaAccess().lookupJavaMethod(method); if (resetProfile) { javaMethod.reprofile(); } @@ -314,7 +314,7 @@ } private void resetProfile(String methodName) { - ResolvedJavaMethod javaMethod = runtime.lookupJavaMethod(getMethod(methodName)); + ResolvedJavaMethod javaMethod = getMetaAccess().lookupJavaMethod(getMethod(methodName)); javaMethod.reprofile(); } }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/PushNodesThroughPiTest.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/PushNodesThroughPiTest.java Fri Oct 11 17:21:14 2013 +0200 @@ -91,7 +91,7 @@ private StructuredGraph compileTestSnippet(final String snippet) { StructuredGraph graph = parse(snippet); - PhaseContext context = new PhaseContext(runtime(), new Assumptions(false), replacements); + PhaseContext context = new PhaseContext(getProviders(), new Assumptions(false)); CanonicalizerPhase canonicalizer = new CanonicalizerPhase(true); new LoweringPhase(canonicalizer).apply(graph, context); canonicalizer.apply(graph, context);
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ReadAfterCheckCastTest.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ReadAfterCheckCastTest.java Fri Oct 11 17:21:14 2013 +0200 @@ -83,7 +83,7 @@ // structure changes significantly public void run() { StructuredGraph graph = parse(snippet); - PhaseContext context = new PhaseContext(runtime(), new Assumptions(false), replacements); + PhaseContext context = new PhaseContext(getProviders(), new Assumptions(false)); new LoweringPhase(new CanonicalizerPhase(true)).apply(graph, context); new FloatingReadPhase().apply(graph); new EliminatePartiallyRedundantGuardsPhase(true, false).apply(graph);
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ReassociateAndCanonicalTest.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ReassociateAndCanonicalTest.java Fri Oct 11 17:21:14 2013 +0200 @@ -245,9 +245,9 @@ private <T extends Node & IterableNodeType> void test(String test, String ref) { StructuredGraph testGraph = parse(test); Assumptions assumptions = new Assumptions(false); - new CanonicalizerPhase(true).apply(testGraph, new PhaseContext(runtime(), assumptions, replacements)); + new CanonicalizerPhase(true).apply(testGraph, new PhaseContext(getProviders(), assumptions)); StructuredGraph refGraph = parse(ref); - new CanonicalizerPhase(true).apply(refGraph, new PhaseContext(runtime(), assumptions, replacements)); + new CanonicalizerPhase(true).apply(refGraph, new PhaseContext(getProviders(), assumptions)); assertEquals(testGraph, refGraph); } }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ScalarTypeSystemTest.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ScalarTypeSystemTest.java Fri Oct 11 17:21:14 2013 +0200 @@ -167,9 +167,9 @@ StructuredGraph graph = parse(snippet); Debug.dump(graph, "Graph"); Assumptions assumptions = new Assumptions(false); - new CanonicalizerPhase(true).apply(graph, new PhaseContext(runtime(), assumptions, replacements)); - new ConditionalEliminationPhase(runtime()).apply(graph); - new CanonicalizerPhase(true).apply(graph, new PhaseContext(runtime(), assumptions, replacements)); + new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), assumptions)); + new ConditionalEliminationPhase(getMetaAccess()).apply(graph); + new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), assumptions)); StructuredGraph referenceGraph = parse(referenceSnippet); assertEquals(referenceGraph, graph); }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/StampCanonicalizerTest.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/StampCanonicalizerTest.java Fri Oct 11 17:21:14 2013 +0200 @@ -110,7 +110,7 @@ private void testZeroReturn(String methodName) { StructuredGraph graph = parse(methodName); - new CanonicalizerPhase(true).apply(graph, new PhaseContext(runtime(), new Assumptions(false), replacements)); + new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), new Assumptions(false))); new DeadCodeEliminationPhase().apply(graph); assertConstantReturn(graph, 0); }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/StraighteningTest.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/StraighteningTest.java Fri Oct 11 17:21:14 2013 +0200 @@ -90,7 +90,7 @@ // No debug scope to reduce console noise for @Test(expected = ...) tests StructuredGraph graph = parse(snippet); Debug.dump(graph, "Graph"); - new CanonicalizerPhase(true).apply(graph, new PhaseContext(runtime(), new Assumptions(false), replacements)); + new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), new Assumptions(false))); StructuredGraph referenceGraph = parse(REFERENCE_SNIPPET); assertEquals(referenceGraph, graph); }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/TypeSystemTest.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/TypeSystemTest.java Fri Oct 11 17:21:14 2013 +0200 @@ -185,13 +185,13 @@ StructuredGraph graph = parse(snippet); Debug.dump(graph, "Graph"); Assumptions assumptions = new Assumptions(false); - new CanonicalizerPhase(true).apply(graph, new PhaseContext(runtime(), assumptions, replacements)); - new ConditionalEliminationPhase(runtime()).apply(graph); - new CanonicalizerPhase(true).apply(graph, new PhaseContext(runtime(), assumptions, replacements)); + new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), assumptions)); + new ConditionalEliminationPhase(getMetaAccess()).apply(graph); + new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), assumptions)); // a second canonicalizer is needed to process nested MaterializeNodes - new CanonicalizerPhase(true).apply(graph, new PhaseContext(runtime(), assumptions, replacements)); + new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), assumptions)); StructuredGraph referenceGraph = parse(referenceSnippet); - new CanonicalizerPhase(true).apply(referenceGraph, new PhaseContext(runtime(), assumptions, replacements)); + new CanonicalizerPhase(true).apply(referenceGraph, new PhaseContext(getProviders(), assumptions)); assertEquals(referenceGraph, graph); } @@ -241,9 +241,9 @@ StructuredGraph graph = parse(snippet); Debug.dump(graph, "Graph"); Assumptions assumptions = new Assumptions(false); - new CanonicalizerPhase(true).apply(graph, new PhaseContext(runtime(), assumptions, replacements)); - new ConditionalEliminationPhase(runtime()).apply(graph); - new CanonicalizerPhase(true).apply(graph, new PhaseContext(runtime(), assumptions, replacements)); + new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), assumptions)); + new ConditionalEliminationPhase(getMetaAccess()).apply(graph); + new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), assumptions)); Debug.dump(graph, "Graph"); Assert.assertFalse("shouldn't have nodes of type " + clazz, graph.getNodes().filter(clazz).iterator().hasNext()); }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/backend/AllocatorTest.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/backend/AllocatorTest.java Fri Oct 11 17:21:14 2013 +0200 @@ -47,7 +47,7 @@ protected void test(String snippet, final int expectedRegisters, final int expectedRegRegMoves, final int expectedSpillMoves) { final StructuredGraph graph = parse(snippet); - Debug.scope("AllocatorTest", new Object[]{graph, graph.method(), runtime}, new Runnable() { + Debug.scope("AllocatorTest", new Object[]{graph, graph.method(), getCodeCache()}, new Runnable() { @Override public void run() { @@ -119,7 +119,7 @@ @Override public LIR call() { - return GraalCompiler.emitHIR(runtime, backend.target, graph, replacements, assumptions, null, phasePlan, OptimisticOptimizations.NONE, new SpeculationLog(), suites); + return GraalCompiler.emitHIR(getProviders(), backend.target, graph, assumptions, null, phasePlan, OptimisticOptimizations.NONE, new SpeculationLog(), suites); } }); @@ -127,7 +127,7 @@ @Override public RegisterStats call() { - CallingConvention cc = getCallingConvention(runtime, Type.JavaCallee, graph.method(), false); + CallingConvention cc = getCallingConvention(getCodeCache(), Type.JavaCallee, graph.method(), false); GraalCompiler.emitLIR(backend, backend.target, lir, graph, cc); return new RegisterStats(lir); }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/deopt/CompiledMethodTest.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/deopt/CompiledMethodTest.java Fri Oct 11 17:21:14 2013 +0200 @@ -56,19 +56,19 @@ public void test1() { Method method = getMethod("testMethod"); final StructuredGraph graph = parse(method); - new CanonicalizerPhase(true).apply(graph, new PhaseContext(runtime(), new Assumptions(false), replacements)); + new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), new Assumptions(false))); new DeadCodeEliminationPhase().apply(graph); for (Node node : graph.getNodes()) { if (node instanceof ConstantNode) { ConstantNode constant = (ConstantNode) node; if (constant.kind() == Kind.Object && " ".equals(constant.value.asObject())) { - graph.replaceFloating(constant, ConstantNode.forObject("-", runtime, graph)); + graph.replaceFloating(constant, ConstantNode.forObject("-", getMetaAccess(), graph)); } } } - final ResolvedJavaMethod javaMethod = runtime.lookupJavaMethod(method); + final ResolvedJavaMethod javaMethod = getMetaAccess().lookupJavaMethod(method); InstalledCode compiledMethod = getCode(javaMethod, graph); try { Object result = compiledMethod.execute("1", "2", "3"); @@ -82,7 +82,7 @@ public void test3() { Method method = getMethod("testMethod"); final StructuredGraph graph = parse(method); - final ResolvedJavaMethod javaMethod = runtime.lookupJavaMethod(method); + final ResolvedJavaMethod javaMethod = getMetaAccess().lookupJavaMethod(method); InstalledCode compiledMethod = getCode(javaMethod, graph); try { Object result = compiledMethod.executeVarargs("1", "2", "3"); @@ -96,7 +96,7 @@ public void test4() { Method method = getMethod("testMethodVirtual"); final StructuredGraph graph = parse(method); - final ResolvedJavaMethod javaMethod = runtime.lookupJavaMethod(method); + final ResolvedJavaMethod javaMethod = getMetaAccess().lookupJavaMethod(method); InstalledCode compiledMethod = getCode(javaMethod, graph); try { f1 = "0";
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/deopt/SynchronizedMethodDeoptimizationTest.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/deopt/SynchronizedMethodDeoptimizationTest.java Fri Oct 11 17:21:14 2013 +0200 @@ -53,7 +53,7 @@ Assert.assertEquals(testString, testMethodSynchronized(testString)); } final StructuredGraph graph = parseProfiled(method); - final ResolvedJavaMethod javaMethod = runtime.lookupJavaMethod(method); + final ResolvedJavaMethod javaMethod = getMetaAccess().lookupJavaMethod(method); InstalledCode compiledMethod = getCode(javaMethod, graph); try { Object result = compiledMethod.executeVarargs(testString);
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EarlyReadEliminationTest.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EarlyReadEliminationTest.java Fri Oct 11 17:21:14 2013 +0200 @@ -41,7 +41,7 @@ protected void processMethod(final String snippet) { graph = parse(snippet); Assumptions assumptions = new Assumptions(false); - HighTierContext context = new HighTierContext(runtime(), assumptions, replacements, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL); + HighTierContext context = new HighTierContext(getProviders(), assumptions, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL); new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context); new EarlyReadEliminationPhase(new CanonicalizerPhase(true)).apply(graph, context); }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EscapeAnalysisTest.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EscapeAnalysisTest.java Fri Oct 11 17:21:14 2013 +0200 @@ -224,16 +224,16 @@ } private ReturnNode testEscapeAnalysis(String snippet, final Constant expectedConstantResult, final boolean iterativeEscapeAnalysis) { - ResolvedJavaMethod method = runtime.lookupJavaMethod(getMethod(snippet)); + ResolvedJavaMethod method = getMetaAccess().lookupJavaMethod(getMethod(snippet)); final StructuredGraph graph = new StructuredGraph(method); - return Debug.scope("GraalCompiler", new Object[]{graph, method, runtime}, new Callable<ReturnNode>() { + return Debug.scope("GraalCompiler", new Object[]{graph, method, getCodeCache()}, new Callable<ReturnNode>() { public ReturnNode call() { - new GraphBuilderPhase(runtime, GraphBuilderConfiguration.getEagerDefault(), OptimisticOptimizations.ALL).apply(graph); + new GraphBuilderPhase(getMetaAccess(), GraphBuilderConfiguration.getEagerDefault(), OptimisticOptimizations.ALL).apply(graph); Assumptions assumptions = new Assumptions(false); - HighTierContext context = new HighTierContext(runtime(), assumptions, replacements, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL); + HighTierContext context = new HighTierContext(getProviders(), assumptions, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL); new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context); new DeadCodeEliminationPhase().apply(graph); new CanonicalizerPhase(true).apply(graph, context);
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/IterativeInliningTest.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/IterativeInliningTest.java Fri Oct 11 17:21:14 2013 +0200 @@ -76,7 +76,7 @@ @Test public void testSimple() { ValueNode result = getReturn("testSimpleSnippet").result(); - assertTrue(graph.getNodes(LoadFieldNode.class).isEmpty()); + assertTrue(graph.getNodes().filter(LoadFieldNode.class).isEmpty()); assertEquals(graph.getLocal(0), result); } @@ -88,7 +88,7 @@ private void processMethod(final String snippet) { graph = parse(snippet); - HighTierContext context = new HighTierContext(runtime(), new Assumptions(false), replacements, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL); + HighTierContext context = new HighTierContext(getProviders(), new Assumptions(false), null, getDefaultPhasePlan(), OptimisticOptimizations.ALL); new IterativeInliningPhase(new CanonicalizerPhase(true)).apply(graph, context); } }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PEAReadEliminationTest.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PEAReadEliminationTest.java Fri Oct 11 17:21:14 2013 +0200 @@ -83,7 +83,7 @@ @Test public void testSimple() { ValueNode result = getReturn("testSimpleSnippet").result(); - assertTrue(graph.getNodes(LoadFieldNode.class).isEmpty()); + assertTrue(graph.getNodes().filter(LoadFieldNode.class).isEmpty()); assertTrue(result.isConstant()); assertEquals(2, result.asConstant().asInt()); } @@ -112,7 +112,7 @@ @Test public void testParam() { ValueNode result = getReturn("testParamSnippet").result(); - assertTrue(graph.getNodes(LoadFieldNode.class).isEmpty()); + assertTrue(graph.getNodes().filter(LoadFieldNode.class).isEmpty()); assertEquals(graph.getLocal(1), result); } @@ -126,7 +126,7 @@ @Test public void testMaterialized() { ValueNode result = getReturn("testMaterializedSnippet").result(); - assertTrue(graph.getNodes(LoadFieldNode.class).isEmpty()); + assertTrue(graph.getNodes().filter(LoadFieldNode.class).isEmpty()); assertEquals(graph.getLocal(0), result); } @@ -142,7 +142,7 @@ @Test public void testSimpleLoop() { ValueNode result = getReturn("testSimpleLoopSnippet").result(); - assertTrue(graph.getNodes(LoadFieldNode.class).isEmpty()); + assertTrue(graph.getNodes().filter(LoadFieldNode.class).isEmpty()); assertEquals(graph.getLocal(1), result); } @@ -160,7 +160,7 @@ @Test public void testBadLoop() { ValueNode result = getReturn("testBadLoopSnippet").result(); - assertEquals(0, graph.getNodes(LoadFieldNode.class).count()); + assertEquals(0, graph.getNodes().filter(LoadFieldNode.class).count()); assertTrue(result instanceof ProxyNode); assertTrue(((ProxyNode) result).value() instanceof PhiNode); } @@ -178,7 +178,7 @@ @Test public void testBadLoop2() { ValueNode result = getReturn("testBadLoop2Snippet").result(); - assertEquals(1, graph.getNodes(LoadFieldNode.class).count()); + assertEquals(1, graph.getNodes().filter(LoadFieldNode.class).count()); assertTrue(result instanceof LoadFieldNode); } @@ -195,7 +195,7 @@ @Test public void testPhi() { ValueNode result = getReturn("testPhiSnippet").result(); - assertTrue(graph.getNodes(LoadFieldNode.class).isEmpty()); + assertTrue(graph.getNodes().filter(LoadFieldNode.class).isEmpty()); assertTrue(result instanceof PhiNode); PhiNode phi = (PhiNode) result; assertTrue(phi.valueAt(0).isConstant()); @@ -243,7 +243,7 @@ protected void processMethod(final String snippet) { graph = parse(snippet); Assumptions assumptions = new Assumptions(false); - HighTierContext context = new HighTierContext(runtime(), assumptions, replacements, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL); + HighTierContext context = new HighTierContext(getProviders(), assumptions, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL); new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context); new PartialEscapePhase(false, true, new CanonicalizerPhase(true)).apply(graph, context); }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PartialEscapeAnalysisTest.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PartialEscapeAnalysisTest.java Fri Oct 11 17:21:14 2013 +0200 @@ -198,7 +198,7 @@ StructuredGraph graph = parse(snippet); Assumptions assumptions = new Assumptions(false); - HighTierContext context = new HighTierContext(runtime(), assumptions, replacements, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL); + HighTierContext context = new HighTierContext(getProviders(), assumptions, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL); new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context); new DeadCodeEliminationPhase().apply(graph); new CanonicalizerPhase(true).apply(graph, context);
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/inlining/InliningTest.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/inlining/InliningTest.java Fri Oct 11 17:21:14 2013 +0200 @@ -237,7 +237,7 @@ StructuredGraph graph = eagerInfopointMode ? parseDebug(method) : parse(method); PhasePlan phasePlan = getDefaultPhasePlan(eagerInfopointMode); Assumptions assumptions = new Assumptions(true); - HighTierContext context = new HighTierContext(runtime(), assumptions, replacements, null, phasePlan, OptimisticOptimizations.ALL); + HighTierContext context = new HighTierContext(getProviders(), assumptions, null, phasePlan, OptimisticOptimizations.ALL); Debug.dump(graph, "Graph"); new CanonicalizerPhase(true).apply(graph, context); new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context);
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java Fri Oct 11 17:21:14 2013 +0200 @@ -32,6 +32,7 @@ import com.oracle.graal.alloc.*; import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.api.runtime.*; import com.oracle.graal.compiler.alloc.*; import com.oracle.graal.compiler.gen.*; import com.oracle.graal.compiler.target.*; @@ -50,6 +51,7 @@ import com.oracle.graal.phases.graph.*; import com.oracle.graal.phases.schedule.*; import com.oracle.graal.phases.tiers.*; +import com.oracle.graal.phases.util.*; /** * Static methods for orchestrating the compilation of a {@linkplain StructuredGraph graph}. @@ -86,7 +88,7 @@ */ @Option(help = "Pattern for method(s) to which intrinsification will not be applied. " + "See MethodFilter class for pattern syntax.") - public static final OptionValue<String> IntrinsificationsDisabled = new OptionValue<>("Object.clone"); + public static final OptionValue<String> IntrinsificationsDisabled = new OptionValue<>(null); // @formatter:on } @@ -131,10 +133,10 @@ * argument can be null. * @return the result of the compilation */ - public static CompilationResult compileGraph(final StructuredGraph graph, final CallingConvention cc, final ResolvedJavaMethod installedCodeOwner, final GraalCodeCacheProvider runtime, - final Replacements replacements, final Backend backend, final TargetDescription target, final GraphCache cache, final PhasePlan plan, final OptimisticOptimizations optimisticOpts, + public static CompilationResult compileGraph(final StructuredGraph graph, final CallingConvention cc, final ResolvedJavaMethod installedCodeOwner, final Providers providers, + final Backend backend, final TargetDescription target, final GraphCache cache, final PhasePlan plan, final OptimisticOptimizations optimisticOpts, final SpeculationLog speculationLog, final Suites suites, final CompilationResult compilationResult) { - Debug.scope("GraalCompiler", new Object[]{graph, runtime}, new Runnable() { + Debug.scope("GraalCompiler", new Object[]{graph, providers.getCodeCache()}, new Runnable() { public void run() { final Assumptions assumptions = new Assumptions(OptAssumptions.getValue()); @@ -142,7 +144,7 @@ public LIR call() { try (TimerCloseable a = FrontEnd.start()) { - return emitHIR(runtime, target, graph, replacements, assumptions, cache, plan, optimisticOpts, speculationLog, suites); + return emitHIR(providers, target, graph, assumptions, cache, plan, optimisticOpts, speculationLog, suites); } } }); @@ -179,13 +181,9 @@ /** * Builds the graph, optimizes it. - * - * @param runtime - * - * @param target */ - public static LIR emitHIR(GraalCodeCacheProvider runtime, TargetDescription target, final StructuredGraph graph, Replacements replacements, Assumptions assumptions, GraphCache cache, - PhasePlan plan, OptimisticOptimizations optimisticOpts, final SpeculationLog speculationLog, final Suites suites) { + public static LIR emitHIR(Providers providers, TargetDescription target, final StructuredGraph graph, Assumptions assumptions, GraphCache cache, PhasePlan plan, + OptimisticOptimizations optimisticOpts, final SpeculationLog speculationLog, final Suites suites) { if (speculationLog != null) { speculationLog.snapshot(); @@ -198,13 +196,13 @@ Debug.dump(graph, "initial state"); } - HighTierContext highTierContext = new HighTierContext(runtime, assumptions, replacements, cache, plan, optimisticOpts); + HighTierContext highTierContext = new HighTierContext(providers, assumptions, cache, plan, optimisticOpts); suites.getHighTier().apply(graph, highTierContext); - MidTierContext midTierContext = new MidTierContext(runtime, assumptions, replacements, target, optimisticOpts); + MidTierContext midTierContext = new MidTierContext(providers, assumptions, target, optimisticOpts); suites.getMidTier().apply(graph, midTierContext); - LowTierContext lowTierContext = new LowTierContext(runtime, assumptions, replacements, target); + LowTierContext lowTierContext = new LowTierContext(providers, assumptions, target); suites.getLowTier().apply(graph, lowTierContext); // we do not want to store statistics about OSR compilations because it may prevent inlining @@ -229,7 +227,7 @@ List<Block> codeEmittingOrder = ComputeBlockOrder.computeCodeEmittingOrder(blocks.length, startBlock, nodeProbabilities); List<Block> linearScanOrder = ComputeBlockOrder.computeLinearScanOrder(blocks.length, startBlock, nodeProbabilities); - LIR lir = new LIR(schedule.getCFG(), schedule.getBlockToNodesMap(), linearScanOrder, codeEmittingOrder, speculationLog); + LIR lir = new LIR(schedule.getCFG(), schedule.getBlockToNodesMap(), linearScanOrder, codeEmittingOrder); Debug.dump(lir, "After linear scan order"); return lir; @@ -288,4 +286,16 @@ Debug.dump(result, "After code generation"); } + + /** + * Creates a set of providers via {@link Graal#getRequiredCapability(Class)}. + */ + public static Providers getGraalProviders() { + MetaAccessProvider metaAccess = Graal.getRequiredCapability(MetaAccessProvider.class); + CodeCacheProvider codeCache = Graal.getRequiredCapability(CodeCacheProvider.class); + ConstantReflectionProvider constantReflection = Graal.getRequiredCapability(ConstantReflectionProvider.class); + LoweringProvider lowerer = Graal.getRequiredCapability(LoweringProvider.class); + Replacements replacements = Graal.getRequiredCapability(Replacements.class); + return new Providers(metaAccess, codeCache, constantReflection, lowerer, replacements); + } }
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/DebugInfoBuilder.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/DebugInfoBuilder.java Fri Oct 11 17:21:14 2013 +0200 @@ -48,7 +48,7 @@ protected HashMap<VirtualObjectNode, VirtualObject> virtualObjects = new HashMap<>(); protected IdentityHashMap<VirtualObjectNode, EscapeObjectState> objectStates = new IdentityHashMap<>(); - public LIRFrameState build(FrameState topState, short reason, LabelRef exceptionEdge) { + public LIRFrameState build(FrameState topState, LabelRef exceptionEdge) { assert virtualObjects.size() == 0; assert objectStates.size() == 0; @@ -101,11 +101,11 @@ } objectStates.clear(); - return newLIRFrameState(reason, exceptionEdge, frame, virtualObjectsArray); + return newLIRFrameState(exceptionEdge, frame, virtualObjectsArray); } - protected LIRFrameState newLIRFrameState(short reason, LabelRef exceptionEdge, BytecodeFrame frame, VirtualObject[] virtualObjectsArray) { - return new LIRFrameState(frame, virtualObjectsArray, exceptionEdge, reason); + protected LIRFrameState newLIRFrameState(LabelRef exceptionEdge, BytecodeFrame frame, VirtualObject[] virtualObjectsArray) { + return new LIRFrameState(frame, virtualObjectsArray, exceptionEdge); } protected BytecodeFrame computeFrameForState(FrameState state) {
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java Fri Oct 11 17:21:14 2013 +0200 @@ -60,7 +60,8 @@ public final LIR lir; protected final StructuredGraph graph; - protected final CodeCacheProvider runtime; + protected final MetaAccessProvider metaAccess; + protected final CodeCacheProvider codeCache; protected final TargetDescription target; protected final CallingConvention cc; @@ -85,16 +86,17 @@ */ public abstract boolean canStoreConstant(Constant c); - public LIRGenerator(StructuredGraph graph, CodeCacheProvider runtime, TargetDescription target, FrameMap frameMap, CallingConvention cc, LIR lir) { + public LIRGenerator(StructuredGraph graph, MetaAccessProvider metaAccess, CodeCacheProvider codeCache, TargetDescription target, FrameMap frameMap, CallingConvention cc, LIR lir) { this.graph = graph; - this.runtime = runtime; + this.metaAccess = metaAccess; + this.codeCache = codeCache; this.target = target; this.frameMap = frameMap; if (graph.getEntryBCI() == StructuredGraph.INVOCATION_ENTRY_BCI) { this.cc = cc; } else { - JavaType[] parameterTypes = new JavaType[]{runtime.lookupJavaType(long.class)}; - CallingConvention tmp = frameMap.registerConfig.getCallingConvention(JavaCallee, runtime.lookupJavaType(void.class), parameterTypes, target, false); + JavaType[] parameterTypes = new JavaType[]{metaAccess.lookupJavaType(long.class)}; + CallingConvention tmp = frameMap.registerConfig.getCallingConvention(JavaCallee, metaAccess.lookupJavaType(void.class), parameterTypes, target, false); this.cc = new CallingConvention(cc.getStackSize(), cc.getReturn(), tmp.getArgument(0)); } this.nodeOperands = graph.createNodeMap(); @@ -113,8 +115,13 @@ } @Override - public CodeCacheProvider getRuntime() { - return runtime; + public MetaAccessProvider getMetaAccess() { + return metaAccess; + } + + @Override + public CodeCacheProvider getCodeCache() { + return codeCache; } public StructuredGraph getGraph() { @@ -228,26 +235,26 @@ if (!deopt.canDeoptimize()) { return null; } - return stateFor(deopt.getDeoptimizationState(), deopt.getDeoptimizationReason()); + return stateFor(deopt.getDeoptimizationState()); } public LIRFrameState stateWithExceptionEdge(DeoptimizingNode deopt, LabelRef exceptionEdge) { if (!deopt.canDeoptimize()) { return null; } - return stateForWithExceptionEdge(deopt.getDeoptimizationState(), deopt.getDeoptimizationReason(), exceptionEdge); + return stateForWithExceptionEdge(deopt.getDeoptimizationState(), exceptionEdge); } - public LIRFrameState stateFor(FrameState state, DeoptimizationReason reason) { - return stateForWithExceptionEdge(state, reason, null); + public LIRFrameState stateFor(FrameState state) { + return stateForWithExceptionEdge(state, null); } - public LIRFrameState stateForWithExceptionEdge(FrameState state, DeoptimizationReason reason, LabelRef exceptionEdge) { + public LIRFrameState stateForWithExceptionEdge(FrameState state, LabelRef exceptionEdge) { if (needOnlyOopMaps()) { - return new LIRFrameState(null, null, null, (short) -1); + return new LIRFrameState(null, null, null); } assert state != null; - return debugInfoBuilder.build(state, lir.getDeoptimizationReasons().addSpeculation(reason), exceptionEdge); + return debugInfoBuilder.build(state, exceptionEdge); } /** @@ -288,7 +295,7 @@ assert lir.lir(block) == null : "LIR list already computed for this block"; lir.setLir(block, new ArrayList<LIRInstruction>()); - append(new LabelOp(new Label(), block.isAligned())); + append(new LabelOp(new Label(block.getId()), block.isAligned())); if (TraceLIRGeneratorLevel.getValue() >= 1) { TTY.println("BEGIN Generating LIR for block B" + block.getId()); @@ -551,7 +558,7 @@ @Override public void emitInvoke(Invoke x) { LoweredCallTargetNode callTarget = (LoweredCallTargetNode) x.callTarget(); - CallingConvention invokeCc = frameMap.registerConfig.getCallingConvention(callTarget.callType(), x.asNode().stamp().javaType(runtime), callTarget.signature(), target(), false); + CallingConvention invokeCc = frameMap.registerConfig.getCallingConvention(callTarget.callType(), x.asNode().stamp().javaType(metaAccess), callTarget.signature(), target(), false); frameMap.callsMethod(invokeCc); Value[] parameters = visitInvokeArguments(invokeCc, callTarget.arguments()); @@ -619,10 +626,10 @@ LIRFrameState state = null; if (linkage.canDeoptimize()) { if (info != null) { - state = stateFor(info.getDeoptimizationState(), info.getDeoptimizationReason()); + state = stateFor(info.getDeoptimizationState()); } else { assert needOnlyOopMaps(); - state = new LIRFrameState(null, null, null, (short) -1); + state = new LIRFrameState(null, null, null); } }
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/Backend.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/Backend.java Fri Oct 11 17:21:14 2013 +0200 @@ -35,16 +35,22 @@ */ public abstract class Backend { - private final CodeCacheProvider runtime; + private final MetaAccessProvider metaAccess; + private final CodeCacheProvider codeCache; public final TargetDescription target; - protected Backend(CodeCacheProvider runtime, TargetDescription target) { - this.runtime = runtime; + protected Backend(MetaAccessProvider metaAccess, CodeCacheProvider codeCache, TargetDescription target) { + this.metaAccess = metaAccess; + this.codeCache = codeCache; this.target = target; } - public CodeCacheProvider runtime() { - return runtime; + public MetaAccessProvider getMetaAccess() { + return metaAccess; + } + + public CodeCacheProvider getCodeCache() { + return codeCache; } public abstract FrameMap newFrameMap();
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Node.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Node.java Fri Oct 11 17:21:14 2013 +0200 @@ -31,6 +31,7 @@ import com.oracle.graal.graph.NodeClass.NodeClassIterator; import com.oracle.graal.graph.NodeClass.Position; import com.oracle.graal.graph.iterators.*; +import com.oracle.graal.graph.spi.*; /** * This class is the base class for all nodes, it represent a node which can be inserted in a @@ -594,12 +595,32 @@ return newNode; } - static int count = 0; - public final Node clone(Graph into) { return clone(into, true); } + /** + * Must be overridden by subclasses that implement {@link Canonicalizable}. The implementation + * in {@link Node} exists to obviate the need to cast a node before invoking + * {@link Canonicalizable#canonical(CanonicalizerTool)}. + * + * @param tool + */ + public Node canonical(CanonicalizerTool tool) { + throw new UnsupportedOperationException(); + } + + /** + * Must be overridden by subclasses that implement {@link Simplifiable}. The implementation in + * {@link Node} exists to obviate the need to cast a node before invoking + * {@link Simplifiable#simplify(SimplifierTool)}. + * + * @param tool + */ + public void simplify(SimplifierTool tool) { + throw new UnsupportedOperationException(); + } + final Node clone(Graph into, boolean clearInputsAndSuccessors) { NodeClass nodeClass = getNodeClass(); if (nodeClass.valueNumberable() && nodeClass.isLeafNode()) {
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java Fri Oct 11 17:21:14 2013 +0200 @@ -33,6 +33,7 @@ import com.oracle.graal.graph.Node.Input; import com.oracle.graal.graph.Node.Successor; import com.oracle.graal.graph.Node.Verbosity; +import com.oracle.graal.graph.spi.*; /** * Lazily associated metadata for every {@link Node} type. The metadata includes: @@ -148,9 +149,21 @@ private static final DebugMetric ITERABLE_NODE_TYPES = Debug.metric("IterableNodeTypes"); private final DebugMetric nodeIterableCount; + /** + * Determines if this node type implements {@link Canonicalizable}. + */ + private final boolean isCanonicalizable; + + /** + * Determines if this node type implements {@link Simplifiable}. + */ + private final boolean isSimplifiable; + private NodeClass(Class<?> clazz) { super(clazz); assert NODE_CLASS.isAssignableFrom(clazz); + this.isCanonicalizable = Canonicalizable.class.isAssignableFrom(clazz); + this.isSimplifiable = Simplifiable.class.isAssignableFrom(clazz); FieldScanner scanner = new FieldScanner(new DefaultCalcOffset()); scanner.scan(clazz); @@ -259,6 +272,20 @@ return isLeafNode; } + /** + * Determines if this node type implements {@link Canonicalizable}. + */ + public boolean isCanonicalizable() { + return isCanonicalizable; + } + + /** + * Determines if this node type implements {@link Simplifiable}. + */ + public boolean isSimplifiable() { + return isSimplifiable; + } + public static int cacheSize() { return nextIterableId; } @@ -418,22 +445,19 @@ } /** - * An iterator that will iterate over the fields given in {@link #offsets}. The first - * {@link #directCount} offsets are treated as fields of type {@link Node}, while the rest of - * the fields are treated as {@link NodeList}s. All elements of these NodeLists will be visited - * by the iterator as well. This iterator can be used to iterate over the inputs or successors - * of a node. + * An iterator that will iterate over the fields given in {@link #getOffsets()}. The first + * {@link #getDirectCount()} offsets are treated as fields of type {@link Node}, while the rest + * of the fields are treated as {@link NodeList}s. All elements of these NodeLists will be + * visited by the iterator as well. This iterator can be used to iterate over the inputs or + * successors of a node. * * An iterator of this type will not return null values, unless the field values are modified * concurrently. Concurrent modifications are detected by an assertion on a best-effort basis. */ - public static final class NodeClassIterator implements Iterator<Node> { + public abstract static class NodeClassIterator implements Iterator<Node> { private final NodeClass nodeClass; - private final Node node; - private final int modCount; - private final int directCount; - private final long[] offsets; + protected final Node node; private int index; private int subIndex; @@ -441,26 +465,19 @@ * Creates an iterator that will iterate over fields in the given node. * * @param node the node which contains the fields. - * @param offsets the offsets of the fields. - * @param directCount the number of fields that should be treated as fields of type - * {@link Node}, the rest are treated as {@link NodeList}s. */ - private NodeClassIterator(Node node, long[] offsets, int directCount) { + NodeClassIterator(Node node) { this.node = node; this.nodeClass = node.getNodeClass(); - this.modCount = MODIFICATION_COUNTS_ENABLED ? node.modCount() : 0; - this.offsets = offsets; - this.directCount = directCount; index = NOT_ITERABLE; subIndex = 0; - forward(); } - private void forward() { - if (index < directCount) { + void forward() { + if (index < getDirectCount()) { index++; - while (index < directCount) { - Node element = getNode(node, offsets[index]); + while (index < getDirectCount()) { + Node element = getNode(node, getOffsets()[index]); if (element != null) { return; } @@ -469,8 +486,8 @@ } else { subIndex++; } - while (index < offsets.length) { - NodeList<Node> list = getNodeList(node, offsets[index]); + while (index < getOffsets().length) { + NodeList<Node> list = getNodeList(node, getOffsets()[index]); while (subIndex < list.size()) { if (list.get(subIndex) != null) { return; @@ -483,10 +500,10 @@ } private Node nextElement() { - if (index < directCount) { - return getNode(node, offsets[index]); - } else if (index < offsets.length) { - NodeList<Node> list = getNodeList(node, offsets[index]); + if (index < getDirectCount()) { + return getNode(node, getOffsets()[index]); + } else if (index < getOffsets().length) { + NodeList<Node> list = getNodeList(node, getOffsets()[index]); return list.get(subIndex); } throw new NoSuchElementException(); @@ -494,8 +511,77 @@ @Override public boolean hasNext() { + return index < getOffsets().length; + } + + @Override + public Node next() { try { - return index < offsets.length; + return nextElement(); + } finally { + forward(); + } + } + + public Position nextPosition() { + try { + if (index < getDirectCount()) { + return new Position(getOffsets() == nodeClass.inputOffsets, index, NOT_ITERABLE); + } else { + return new Position(getOffsets() == nodeClass.inputOffsets, index, subIndex); + } + } finally { + forward(); + } + } + + @Override + public void remove() { + throw new UnsupportedOperationException(); + } + + protected abstract int getDirectCount(); + + protected abstract long[] getOffsets(); + } + + private class NodeClassInputsIterator extends NodeClassIterator { + NodeClassInputsIterator(Node node) { + this(node, true); + } + + NodeClassInputsIterator(Node node, boolean forward) { + super(node); + if (forward) { + forward(); + } + } + + @Override + protected int getDirectCount() { + return directInputCount; + } + + @Override + protected long[] getOffsets() { + return inputOffsets; + } + } + + private final class NodeClassInputsWithModCountIterator extends NodeClassInputsIterator { + private final int modCount; + + private NodeClassInputsWithModCountIterator(Node node) { + super(node, false); + assert MODIFICATION_COUNTS_ENABLED; + this.modCount = node.modCount(); + forward(); + } + + @Override + public boolean hasNext() { + try { + return super.hasNext(); } finally { assert modCount == node.modCount() : "must not be modified"; } @@ -504,29 +590,80 @@ @Override public Node next() { try { - return nextElement(); + return super.next(); } finally { - forward(); - assert modCount == node.modCount(); + assert modCount == node.modCount() : "must not be modified"; } } + @Override public Position nextPosition() { try { - if (index < directCount) { - return new Position(offsets == nodeClass.inputOffsets, index, NOT_ITERABLE); - } else { - return new Position(offsets == nodeClass.inputOffsets, index, subIndex); - } + return super.nextPosition(); } finally { + assert modCount == node.modCount(); + } + } + } + + private class NodeClassSuccessorsIterator extends NodeClassIterator { + NodeClassSuccessorsIterator(Node node) { + this(node, true); + } + + NodeClassSuccessorsIterator(Node node, boolean forward) { + super(node); + if (forward) { forward(); - assert modCount == node.modCount(); } } @Override - public void remove() { - throw new UnsupportedOperationException(); + protected int getDirectCount() { + return directSuccessorCount; + } + + @Override + protected long[] getOffsets() { + return successorOffsets; + } + } + + private final class NodeClassSuccessorsWithModCountIterator extends NodeClassSuccessorsIterator { + private final int modCount; + + private NodeClassSuccessorsWithModCountIterator(Node node) { + super(node, false); + assert MODIFICATION_COUNTS_ENABLED; + this.modCount = node.modCount(); + forward(); + } + + @Override + public boolean hasNext() { + try { + return super.hasNext(); + } finally { + assert modCount == node.modCount() : "must not be modified"; + } + } + + @Override + public Node next() { + try { + return super.next(); + } finally { + assert modCount == node.modCount() : "must not be modified"; + } + } + + @Override + public Position nextPosition() { + try { + return super.nextPosition(); + } finally { + assert modCount == node.modCount(); + } } } @@ -781,7 +918,11 @@ @Override public NodeClassIterator iterator() { - return new NodeClassIterator(node, inputOffsets, directInputCount); + if (MODIFICATION_COUNTS_ENABLED) { + return new NodeClassInputsWithModCountIterator(node); + } else { + return new NodeClassInputsIterator(node); + } } @Override @@ -797,7 +938,11 @@ @Override public NodeClassIterator iterator() { - return new NodeClassIterator(node, successorOffsets, directSuccessorCount); + if (MODIFICATION_COUNTS_ENABLED) { + return new NodeClassSuccessorsWithModCountIterator(node); + } else { + return new NodeClassSuccessorsIterator(node); + } } @Override
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/spi/Canonicalizable.java Fri Oct 11 17:21:14 2013 +0200 @@ -0,0 +1,30 @@ +/* + * 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.graph.spi; + +import com.oracle.graal.graph.*; + +public interface Canonicalizable { + + Node canonical(CanonicalizerTool tool); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/spi/CanonicalizerTool.java Fri Oct 11 17:21:14 2013 +0200 @@ -0,0 +1,40 @@ +/* + * 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.graph.spi; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.graph.*; + +public interface CanonicalizerTool { + + Assumptions assumptions(); + + MetaAccessProvider getMetaAccess(); + + ConstantReflectionProvider getConstantReflection(); + + boolean canonicalizeReads(); + + void removeIfUnused(Node node); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/spi/Simplifiable.java Fri Oct 11 17:21:14 2013 +0200 @@ -0,0 +1,37 @@ +/* + * Copyright (c) 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.graph.spi; + +/** + * This interface allows nodes to perform more complicated simplifications, in contrast to + * {@link Canonicalizable}, which supports only replacing the current node. + * + * Implementors of this interface need to be aware that they need to call + * {@link SimplifierTool#addToWorkList(com.oracle.graal.graph.Node)} for each node that might be + * influenced (in terms of simplification and canonicalization) by the actions performed in + * simplify. + */ +public interface Simplifiable { + + void simplify(SimplifierTool tool); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/spi/SimplifierTool.java Fri Oct 11 17:21:14 2013 +0200 @@ -0,0 +1,38 @@ +/* + * Copyright (c) 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.graph.spi; + +import com.oracle.graal.graph.*; + +/** + * @see Simplifiable + */ +public interface SimplifierTool extends CanonicalizerTool { + + void deleteBranch(Node branch); + + /** + * Adds a node to the worklist independent of whether it has already been on the worklist. + */ + void addToWorkList(Node node); +}
--- a/graal/com.oracle.graal.hotspot.amd64.test/src/com/oracle/graal/hotspot/amd64/test/AMD64HotSpotFrameOmissionTest.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64.test/src/com/oracle/graal/hotspot/amd64/test/AMD64HotSpotFrameOmissionTest.java Fri Oct 11 17:21:14 2013 +0200 @@ -31,7 +31,6 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.api.runtime.*; import com.oracle.graal.asm.amd64.*; import com.oracle.graal.compiler.test.*; @@ -98,12 +97,11 @@ private void testHelper(String name, CodeGenerator gen) { Method method = getMethod(name); - ResolvedJavaMethod javaMethod = runtime.lookupJavaMethod(method); + ResolvedJavaMethod javaMethod = getMetaAccess().lookupJavaMethod(method); InstalledCode installedCode = getCode(javaMethod, parse(method)); - CodeCacheProvider codeCache = Graal.getRequiredCapability(CodeCacheProvider.class); - TargetDescription target = codeCache.getTarget(); - RegisterConfig registerConfig = codeCache.lookupRegisterConfig(); + TargetDescription target = getCodeCache().getTarget(); + RegisterConfig registerConfig = getCodeCache().getRegisterConfig(); AMD64Assembler asm = new AMD64Assembler(target, registerConfig); gen.generateCode(asm); @@ -117,7 +115,7 @@ } private Register getArgumentRegister(int index, Kind kind) { - Register[] regs = runtime.lookupRegisterConfig().getCallingConventionRegisters(CallingConvention.Type.JavaCall, kind); + Register[] regs = getCodeCache().getRegisterConfig().getCallingConventionRegisters(CallingConvention.Type.JavaCall, kind); return regs[index]; } }
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64DeoptimizeOp.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64DeoptimizeOp.java Fri Oct 11 17:21:14 2013 +0200 @@ -23,12 +23,8 @@ package com.oracle.graal.hotspot.amd64; import static com.oracle.graal.hotspot.HotSpotBackend.*; -import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; -import com.oracle.graal.api.code.*; -import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.amd64.*; -import com.oracle.graal.hotspot.*; import com.oracle.graal.lir.*; import com.oracle.graal.lir.amd64.*; import com.oracle.graal.lir.asm.*; @@ -36,21 +32,14 @@ @Opcode("DEOPT") final class AMD64DeoptimizeOp extends AMD64LIRInstruction { - private DeoptimizationAction action; - private DeoptimizationReason reason; @State private LIRFrameState info; - AMD64DeoptimizeOp(DeoptimizationAction action, DeoptimizationReason reason, LIRFrameState info) { - this.action = action; - this.reason = reason; + AMD64DeoptimizeOp(LIRFrameState info) { this.info = info; } @Override public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) { - HotSpotGraalRuntime runtime = graalRuntime(); - Register thread = runtime.getRuntime().threadRegister(); - masm.movl(new AMD64Address(thread, runtime.getConfig().pendingDeoptimizationOffset), tasm.runtime.encodeDeoptActionAndReason(action, reason)); - AMD64Call.directCall(tasm, masm, tasm.runtime.lookupForeignCall(UNCOMMON_TRAP), null, false, info); + AMD64Call.directCall(tasm, masm, tasm.codeCache.lookupForeignCall(UNCOMMON_TRAP), null, false, info); } }
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java Fri Oct 11 17:21:14 2013 +0200 @@ -69,12 +69,12 @@ @Override public FrameMap newFrameMap() { - return new AMD64FrameMap(runtime(), target, runtime().lookupRegisterConfig()); + return new AMD64FrameMap(getCodeCache(), target, getCodeCache().getRegisterConfig()); } @Override public LIRGenerator newLIRGenerator(StructuredGraph graph, FrameMap frameMap, CallingConvention cc, LIR lir) { - return new AMD64HotSpotLIRGenerator(graph, runtime(), target, frameMap, cc, lir); + return new AMD64HotSpotLIRGenerator(graph, getMetaAccess(), getCodeCache(), target, frameMap, cc, lir); } /** @@ -174,7 +174,7 @@ 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); + TargetMethodAssembler tasm = new TargetMethodAssembler(target, getCodeCache(), frameMap, masm, frameContext, compilationResult); tasm.setFrameSize(frameMap.frameSize()); StackSlot deoptimizationRescueSlot = gen.deoptimizationRescueSlot; if (deoptimizationRescueSlot != null && stub == null) { @@ -235,21 +235,20 @@ AMD64MacroAssembler asm = (AMD64MacroAssembler) tasm.asm; FrameMap frameMap = tasm.frameMap; RegisterConfig regConfig = frameMap.registerConfig; - HotSpotVMConfig config = runtime().config; - Label unverifiedStub = installedCodeOwner == null || isStatic(installedCodeOwner.getModifiers()) ? null : new Label(); + HotSpotVMConfig config = getRuntime().config; + Label verifiedStub = new Label(); // Emit the prefix - - if (unverifiedStub != null) { + if (installedCodeOwner != null && !isStatic(installedCodeOwner.getModifiers())) { tasm.recordMark(Marks.MARK_UNVERIFIED_ENTRY); - CallingConvention cc = regConfig.getCallingConvention(JavaCallee, null, new JavaType[]{runtime().lookupJavaType(Object.class)}, target, false); + CallingConvention cc = regConfig.getCallingConvention(JavaCallee, null, new JavaType[]{getRuntime().lookupJavaType(Object.class)}, target, false); Register inlineCacheKlass = rax; // see definition of IC_Klass in // c1_LIRAssembler_x86.cpp Register receiver = asRegister(cc.getArgument(0)); AMD64Address src = new AMD64Address(receiver, config.hubOffset); AMD64HotSpotLIRGenerator gen = (AMD64HotSpotLIRGenerator) lirGen; - AMD64HotSpotRuntime hr = ((AMD64HotSpotRuntime) gen.getRuntime()); + AMD64HotSpotRuntime hr = ((AMD64HotSpotRuntime) gen.getCodeCache()); if (hr.useCompressedKlassPointers()) { Register register = r10; AMD64HotSpotMove.decodeKlassPointer(asm, register, hr.heapBaseRegister(), src, config.narrowKlassBase, config.narrowKlassShift, config.logKlassAlignment); @@ -257,11 +256,12 @@ } else { asm.cmpq(inlineCacheKlass, src); } - asm.jcc(ConditionFlag.NotEqual, unverifiedStub); + AMD64Call.directConditionalJmp(tasm, asm, getCodeCache().lookupForeignCall(IC_MISS_HANDLER), ConditionFlag.NotEqual); } asm.align(config.codeEntryAlignment); tasm.recordMark(Marks.MARK_OSR_ENTRY); + asm.bind(verifiedStub); tasm.recordMark(Marks.MARK_VERIFIED_ENTRY); // Emit code for the LIR @@ -270,18 +270,13 @@ HotSpotFrameContext frameContext = (HotSpotFrameContext) tasm.frameContext; if (frameContext != null && !frameContext.isStub) { tasm.recordMark(Marks.MARK_EXCEPTION_HANDLER_ENTRY); - AMD64Call.directCall(tasm, asm, runtime().lookupForeignCall(EXCEPTION_HANDLER), null, false, null); + AMD64Call.directCall(tasm, asm, getRuntime().lookupForeignCall(EXCEPTION_HANDLER), null, false, null); tasm.recordMark(Marks.MARK_DEOPT_HANDLER_ENTRY); - AMD64Call.directCall(tasm, asm, runtime().lookupForeignCall(DEOPT_HANDLER), null, false, null); + AMD64Call.directCall(tasm, asm, getRuntime().lookupForeignCall(DEOPT_HANDLER), null, false, null); } else { // No need to emit the stubs for entries back into the method since // it has no calls that can cause such "return" entries assert !frameMap.accessesCallerFrame() : lirGen.getGraph(); } - - if (unverifiedStub != null) { - asm.bind(unverifiedStub); - AMD64Call.directJmp(tasm, asm, runtime().lookupForeignCall(IC_MISS_HANDLER)); - } } }
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotDeoptimizeCallerOp.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotDeoptimizeCallerOp.java Fri Oct 11 17:21:14 2013 +0200 @@ -23,12 +23,8 @@ package com.oracle.graal.hotspot.amd64; import static com.oracle.graal.hotspot.HotSpotBackend.*; -import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; -import com.oracle.graal.api.code.*; -import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.amd64.*; -import com.oracle.graal.hotspot.*; import com.oracle.graal.lir.*; import com.oracle.graal.lir.amd64.*; import com.oracle.graal.lir.asm.*; @@ -39,21 +35,9 @@ @Opcode("DEOPT_CALLER") final class AMD64HotSpotDeoptimizeCallerOp extends AMD64HotSpotEpilogueOp { - private final DeoptimizationAction action; - private final DeoptimizationReason reason; - - AMD64HotSpotDeoptimizeCallerOp(DeoptimizationAction action, DeoptimizationReason reason) { - this.action = action; - this.reason = reason; - } - @Override public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) { leaveFrameAndRestoreRbp(tasm, masm); - - HotSpotGraalRuntime runtime = graalRuntime(); - Register thread = runtime.getRuntime().threadRegister(); - masm.movl(new AMD64Address(thread, runtime.getConfig().pendingDeoptimizationOffset), tasm.runtime.encodeDeoptActionAndReason(action, reason)); - AMD64Call.directJmp(tasm, masm, tasm.runtime.lookupForeignCall(UNCOMMON_TRAP)); + AMD64Call.directJmp(tasm, masm, tasm.codeCache.lookupForeignCall(UNCOMMON_TRAP)); } }
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotGraalRuntime.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotGraalRuntime.java Fri Oct 11 17:21:14 2013 +0200 @@ -82,7 +82,7 @@ @Override protected Value[] getNativeABICallerSaveRegisters() { if (nativeABICallerSaveRegisters == null) { - List<Register> callerSave = new ArrayList<>(Arrays.asList(getRuntime().lookupRegisterConfig().getAllocatableRegisters())); + List<Register> callerSave = new ArrayList<>(Arrays.asList(getRuntime().getRegisterConfig().getAllocatableRegisters())); if (getConfig().windowsOs) { // http://msdn.microsoft.com/en-us/library/9z1stfyw.aspx callerSave.remove(AMD64.rdi);
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java Fri Oct 11 17:21:14 2013 +0200 @@ -25,6 +25,7 @@ import static com.oracle.graal.amd64.AMD64.*; import static com.oracle.graal.api.code.ValueUtil.*; import static com.oracle.graal.hotspot.HotSpotBackend.*; +import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; import java.lang.reflect.*; import java.util.*; @@ -66,11 +67,11 @@ public class AMD64HotSpotLIRGenerator extends AMD64LIRGenerator implements HotSpotLIRGenerator { private HotSpotRuntime runtime() { - return (HotSpotRuntime) runtime; + return (HotSpotRuntime) codeCache; } - protected AMD64HotSpotLIRGenerator(StructuredGraph graph, CodeCacheProvider runtime, TargetDescription target, FrameMap frameMap, CallingConvention cc, LIR lir) { - super(graph, runtime, target, frameMap, cc, lir); + protected AMD64HotSpotLIRGenerator(StructuredGraph graph, MetaAccessProvider metaAccess, CodeCacheProvider codeCache, TargetDescription target, FrameMap frameMap, CallingConvention cc, LIR lir) { + super(graph, metaAccess, codeCache, target, frameMap, cc, lir); } /** @@ -304,7 +305,7 @@ AMD64AddressValue address; Value index = operand(x.offset()); if (ValueUtil.isConstant(index) && NumUtil.isInt(ValueUtil.asConstant(index).asLong() + disp)) { - assert !runtime.needsDataPatch(asConstant(index)); + assert !codeCache.needsDataPatch(asConstant(index)); disp += (int) ValueUtil.asConstant(index).asLong(); address = new AMD64AddressValue(kind, load(operand(x.object())), disp); } else { @@ -354,7 +355,7 @@ @Override public void emitUnwind(Value exception) { - ForeignCallLinkage linkage = getRuntime().lookupForeignCall(HotSpotBackend.UNWIND_EXCEPTION_TO_CALLER); + ForeignCallLinkage linkage = getCodeCache().lookupForeignCall(HotSpotBackend.UNWIND_EXCEPTION_TO_CALLER); CallingConvention outgoingCc = linkage.getOutgoingCallingConvention(); assert outgoingCc.getArgumentCount() == 2; RegisterValue exceptionParameter = (RegisterValue) outgoingCc.getArgument(0); @@ -362,14 +363,29 @@ append(new AMD64HotSpotUnwindOp(exceptionParameter)); } + private void moveDeoptimizationActionAndReasonToThread(Value actionAndReason) { + int pendingDeoptimizationOffset = graalRuntime().getConfig().pendingDeoptimizationOffset; + RegisterValue thread = runtime().threadRegister().asValue(HotSpotGraalRuntime.wordKind()); + AMD64AddressValue pendingDeoptAddress = new AMD64AddressValue(actionAndReason.getKind(), thread, pendingDeoptimizationOffset); + if (actionAndReason instanceof Constant && !codeCache.needsDataPatch((Constant) actionAndReason)) { + Constant constantActionAndReason = (Constant) actionAndReason; + assert !codeCache.needsDataPatch(constantActionAndReason); + append(new StoreConstantOp(constantActionAndReason.getKind(), pendingDeoptAddress, constantActionAndReason, null)); + } else { + append(new StoreOp(actionAndReason.getKind(), pendingDeoptAddress, load(actionAndReason), null)); + } + } + @Override - public void emitDeoptimize(DeoptimizationAction action, DeoptimizingNode deopting) { - append(new AMD64DeoptimizeOp(action, deopting.getDeoptimizationReason(), state(deopting))); + public void emitDeoptimize(Value actionAndReason, DeoptimizingNode deopting) { + moveDeoptimizationActionAndReasonToThread(actionAndReason); + append(new AMD64DeoptimizeOp(state(deopting))); } @Override public void emitDeoptimizeCaller(DeoptimizationAction action, DeoptimizationReason reason) { - append(new AMD64HotSpotDeoptimizeCallerOp(action, reason)); + moveDeoptimizationActionAndReasonToThread(metaAccess.encodeDeoptActionAndReason(action, reason)); + append(new AMD64HotSpotDeoptimizeCallerOp()); } @Override @@ -380,7 +396,7 @@ @Override public void emitJumpToExceptionHandlerInCaller(ValueNode handlerInCallerPc, ValueNode exception, ValueNode exceptionPc) { Variable handler = load(operand(handlerInCallerPc)); - ForeignCallLinkage linkage = getRuntime().lookupForeignCall(EXCEPTION_HANDLER_IN_CALLER); + ForeignCallLinkage linkage = getCodeCache().lookupForeignCall(EXCEPTION_HANDLER_IN_CALLER); CallingConvention outgoingCc = linkage.getOutgoingCallingConvention(); assert outgoingCc.getArgumentCount() == 2; RegisterValue exceptionFixed = (RegisterValue) outgoingCc.getArgument(0);
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotMove.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotMove.java Fri Oct 11 17:21:14 2013 +0200 @@ -120,7 +120,7 @@ @Override public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) { - Register heapBase = ((HotSpotRuntime) tasm.runtime).heapBaseRegister(); + Register heapBase = ((HotSpotRuntime) tasm.codeCache).heapBaseRegister(); masm.movq(asRegister(scratch), asRegister(input)); if (kind == Kind.Object) { encodePointer(masm, asRegister(scratch), heapBase, base, shift, alignment); @@ -172,7 +172,7 @@ final Register scratchRegister = asRegister(scratch); final Register cmpRegister = asRegister(cmpValue); final Register newRegister = asRegister(newValue); - Register heapBase = ((HotSpotRuntime) tasm.runtime).heapBaseRegister(); + Register heapBase = ((HotSpotRuntime) tasm.codeCache).heapBaseRegister(); encodePointer(masm, cmpRegister, heapBase, base, shift, alignment); masm.movq(scratchRegister, newRegister); encodePointer(masm, scratchRegister, heapBase, base, shift, alignment);
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotReturnOp.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotReturnOp.java Fri Oct 11 17:21:14 2013 +0200 @@ -50,7 +50,7 @@ } private static Register findPollOnReturnScratchRegister() { - RegisterConfig config = HotSpotGraalRuntime.graalRuntime().getRuntime().lookupRegisterConfig(); + RegisterConfig config = HotSpotGraalRuntime.graalRuntime().getRuntime().getRegisterConfig(); for (Register r : config.getAllocatableRegisters(Kind.Long)) { if (r != config.getReturnRegister(Kind.Long) && r != AMD64.rbp) { return r;
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRuntime.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRuntime.java Fri Oct 11 17:21:14 2013 +0200 @@ -41,6 +41,7 @@ import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.phases.util.*; import com.oracle.graal.replacements.amd64.*; public class AMD64HotSpotRuntime extends HotSpotRuntime { @@ -72,7 +73,8 @@ registerForeignCall(DECRYPT, config.cipherBlockChainingDecryptAESCryptStub, NativeCall, PRESERVES_REGISTERS, LEAF, NOT_REEXECUTABLE, ANY_LOCATION); registerForeignCall(UPDATE_BYTES_CRC32, config.updateBytesCRC32Stub, NativeCall, PRESERVES_REGISTERS, LEAF, NOT_REEXECUTABLE, ANY_LOCATION); - convertSnippets = new AMD64ConvertSnippets.Templates(this, replacements, graalRuntime.getTarget()); + Providers providers = new Providers(this, this, this, this, replacements); + convertSnippets = new AMD64ConvertSnippets.Templates(providers, graalRuntime.getTarget()); super.registerReplacements(replacements); }
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotUnwindOp.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotUnwindOp.java Fri Oct 11 17:21:14 2013 +0200 @@ -50,7 +50,7 @@ public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) { leaveFrameAndRestoreRbp(tasm, masm); - ForeignCallLinkage linkage = tasm.runtime.lookupForeignCall(UNWIND_EXCEPTION_TO_CALLER); + ForeignCallLinkage linkage = tasm.codeCache.lookupForeignCall(UNWIND_EXCEPTION_TO_CALLER); CallingConvention cc = linkage.getOutgoingCallingConvention(); assert cc.getArgumentCount() == 2; assert exception.equals(cc.getArgument(0));
--- a/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotRegisterConfig.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotRegisterConfig.java Fri Oct 11 17:21:14 2013 +0200 @@ -104,7 +104,14 @@ int currentStackOffset = 0; Kind returnKind = returnType == null ? Kind.Void : returnType.getKind(); - AllocatableValue returnLocation = returnKind == Kind.Void ? Value.ILLEGAL : new Variable(returnKind, currentGeneral++); + + AllocatableValue returnLocation; + if (returnKind == Kind.Void) { + returnLocation = Value.ILLEGAL; + } else { + returnLocation = new Variable(returnKind, currentGeneral++); + } + AllocatableValue[] locations = new AllocatableValue[parameterTypes.length]; for (int i = 0; i < parameterTypes.length; i++) {
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCDeoptimizeOp.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCDeoptimizeOp.java Fri Oct 11 17:21:14 2013 +0200 @@ -22,39 +22,24 @@ */ package com.oracle.graal.hotspot.sparc; -import static com.oracle.graal.asm.sparc.SPARCMacroAssembler.*; import static com.oracle.graal.hotspot.HotSpotBackend.*; -import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; -import static com.oracle.graal.sparc.SPARC.*; -import com.oracle.graal.api.code.*; -import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.sparc.*; -import com.oracle.graal.hotspot.*; import com.oracle.graal.lir.*; +import com.oracle.graal.lir.asm.*; import com.oracle.graal.lir.sparc.*; -import com.oracle.graal.lir.asm.*; @Opcode("DEOPT") final class SPARCDeoptimizeOp extends SPARCLIRInstruction { - private DeoptimizationAction action; - private DeoptimizationReason reason; @State private LIRFrameState info; - SPARCDeoptimizeOp(DeoptimizationAction action, DeoptimizationReason reason, LIRFrameState info) { - this.action = action; - this.reason = reason; + SPARCDeoptimizeOp(LIRFrameState info) { this.info = info; } @Override public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) { - HotSpotGraalRuntime runtime = graalRuntime(); - Register thread = runtime.getRuntime().threadRegister(); - Register scratch = g3; - new Mov(tasm.runtime.encodeDeoptActionAndReason(action, reason), scratch).emit(masm); - new Stw(scratch, new SPARCAddress(thread, runtime.getConfig().pendingDeoptimizationOffset)).emit(masm); // TODO the patched call address looks odd (and is invalid) compared to other runtime calls: // 0xffffffff749bb5fc: call 0xffffffff415a720c ; {runtime_call} // [Exception Handler] @@ -63,6 +48,6 @@ // [Deopt Handler Code] // 0xffffffff749bb60c: call 0xffffffff748da540 ; {runtime_call} // 0xffffffff749bb610: nop - SPARCCall.directCall(tasm, masm, tasm.runtime.lookupForeignCall(UNCOMMON_TRAP), null, false, info); + SPARCCall.directCall(tasm, masm, tasm.codeCache.lookupForeignCall(UNCOMMON_TRAP), null, false, info); } }
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java Fri Oct 11 17:21:14 2013 +0200 @@ -66,12 +66,12 @@ @Override public FrameMap newFrameMap() { - return new SPARCFrameMap(runtime(), target, runtime().lookupRegisterConfig()); + return new SPARCFrameMap(getRuntime(), target, getRuntime().getRegisterConfig()); } @Override public LIRGenerator newLIRGenerator(StructuredGraph graph, FrameMap frameMap, CallingConvention cc, LIR lir) { - return new SPARCHotSpotLIRGenerator(graph, runtime(), target, frameMap, cc, lir); + return new SPARCHotSpotLIRGenerator(graph, getRuntime(), getRuntime(), target, frameMap, cc, lir); } /** @@ -155,7 +155,7 @@ AbstractAssembler masm = createAssembler(frameMap); // On SPARC we always use stack frames. HotSpotFrameContext frameContext = new HotSpotFrameContext(stub != null); - TargetMethodAssembler tasm = new TargetMethodAssembler(target, runtime(), frameMap, masm, frameContext, compilationResult); + TargetMethodAssembler tasm = new TargetMethodAssembler(target, getRuntime(), frameMap, masm, frameContext, compilationResult); tasm.setFrameSize(frameMap.frameSize()); StackSlot deoptimizationRescueSlot = gen.deoptimizationRescueSlot; if (deoptimizationRescueSlot != null && stub == null) { @@ -176,7 +176,7 @@ SPARCMacroAssembler masm = (SPARCMacroAssembler) tasm.asm; FrameMap frameMap = tasm.frameMap; RegisterConfig regConfig = frameMap.registerConfig; - HotSpotVMConfig config = runtime().config; + HotSpotVMConfig config = getRuntime().config; Label unverifiedStub = installedCodeOwner == null || isStatic(installedCodeOwner.getModifiers()) ? null : new Label(); // Emit the prefix @@ -184,7 +184,7 @@ if (unverifiedStub != null) { tasm.recordMark(Marks.MARK_UNVERIFIED_ENTRY); // We need to use JavaCall here because we haven't entered the frame yet. - CallingConvention cc = regConfig.getCallingConvention(JavaCall, null, new JavaType[]{runtime().lookupJavaType(Object.class)}, target, false); + CallingConvention cc = regConfig.getCallingConvention(JavaCall, null, new JavaType[]{getRuntime().lookupJavaType(Object.class)}, target, false); Register inlineCacheKlass = g5; // see MacroAssembler::ic_call Register scratch = g3; Register receiver = asRegister(cc.getArgument(0)); @@ -206,9 +206,9 @@ HotSpotFrameContext frameContext = (HotSpotFrameContext) tasm.frameContext; if (frameContext != null && !frameContext.isStub) { tasm.recordMark(Marks.MARK_EXCEPTION_HANDLER_ENTRY); - SPARCCall.directCall(tasm, masm, runtime().lookupForeignCall(EXCEPTION_HANDLER), null, false, null); + SPARCCall.directCall(tasm, masm, getRuntime().lookupForeignCall(EXCEPTION_HANDLER), null, false, null); tasm.recordMark(Marks.MARK_DEOPT_HANDLER_ENTRY); - SPARCCall.directCall(tasm, masm, runtime().lookupForeignCall(DEOPT_HANDLER), null, false, null); + SPARCCall.directCall(tasm, masm, getRuntime().lookupForeignCall(DEOPT_HANDLER), null, false, null); } else { // No need to emit the stubs for entries back into the method since // it has no calls that can cause such "return" entries @@ -218,7 +218,7 @@ if (unverifiedStub != null) { masm.bind(unverifiedStub); Register scratch = g3; - SPARCCall.indirectJmp(tasm, masm, scratch, runtime().lookupForeignCall(IC_MISS_HANDLER)); + SPARCCall.indirectJmp(tasm, masm, scratch, getRuntime().lookupForeignCall(IC_MISS_HANDLER)); } } }
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotDeoptimizeCallerOp.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotDeoptimizeCallerOp.java Fri Oct 11 17:21:14 2013 +0200 @@ -22,18 +22,14 @@ */ package com.oracle.graal.hotspot.sparc; +import static com.oracle.graal.hotspot.HotSpotBackend.*; import static com.oracle.graal.sparc.SPARC.*; -import static com.oracle.graal.asm.sparc.SPARCMacroAssembler.*; -import static com.oracle.graal.hotspot.HotSpotBackend.*; -import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; import com.oracle.graal.api.code.*; -import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.sparc.*; -import com.oracle.graal.hotspot.*; import com.oracle.graal.lir.*; +import com.oracle.graal.lir.asm.*; import com.oracle.graal.lir.sparc.*; -import com.oracle.graal.lir.asm.*; /** * Removes the current frame and tail calls the uncommon trap routine. @@ -41,14 +37,6 @@ @Opcode("DEOPT_CALLER") final class SPARCHotSpotDeoptimizeCallerOp extends SPARCHotSpotEpilogueOp { - private final DeoptimizationAction action; - private final DeoptimizationReason reason; - - SPARCHotSpotDeoptimizeCallerOp(DeoptimizationAction action, DeoptimizationReason reason) { - this.action = action; - this.reason = reason; - } - @Override public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) { leaveFrame(tasm); @@ -58,15 +46,8 @@ // final boolean isStub = true; // HotSpotFrameContext frameContext = backend.new HotSpotFrameContext(isStub); // frameContext.enter(tasm); - - HotSpotGraalRuntime runtime = graalRuntime(); - Register thread = runtime.getRuntime().threadRegister(); - - Register scratch = g5; - new Mov(tasm.runtime.encodeDeoptActionAndReason(action, reason), scratch).emit(masm); - new Stw(scratch, new SPARCAddress(thread, runtime.getConfig().pendingDeoptimizationOffset)).emit(masm); - - SPARCCall.indirectJmp(tasm, masm, scratch, tasm.runtime.lookupForeignCall(UNCOMMON_TRAP)); + Register scratch = g3; + SPARCCall.indirectJmp(tasm, masm, scratch, tasm.codeCache.lookupForeignCall(UNCOMMON_TRAP)); // frameContext.leave(tasm); }
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java Fri Oct 11 17:21:14 2013 +0200 @@ -24,6 +24,7 @@ import static com.oracle.graal.api.code.ValueUtil.*; import static com.oracle.graal.hotspot.HotSpotBackend.*; +import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; import static com.oracle.graal.sparc.SPARC.*; import java.lang.reflect.*; @@ -49,11 +50,11 @@ public class SPARCHotSpotLIRGenerator extends SPARCLIRGenerator implements HotSpotLIRGenerator { private HotSpotRuntime runtime() { - return (HotSpotRuntime) runtime; + return (HotSpotRuntime) codeCache; } - public SPARCHotSpotLIRGenerator(StructuredGraph graph, CodeCacheProvider runtime, TargetDescription target, FrameMap frameMap, CallingConvention cc, LIR lir) { - super(graph, runtime, target, frameMap, cc, lir); + public SPARCHotSpotLIRGenerator(StructuredGraph graph, MetaAccessProvider metaAccess, CodeCacheProvider codeCache, TargetDescription target, FrameMap frameMap, CallingConvention cc, LIR lir) { + super(graph, metaAccess, codeCache, target, frameMap, cc, lir); } /** @@ -127,7 +128,7 @@ Variable newValue = load(operand(x.newValue())); if (ValueUtil.isConstant(offset)) { - assert !runtime.needsDataPatch(asConstant(offset)); + assert !codeCache.needsDataPatch(asConstant(offset)); Variable longAddress = newVariable(Kind.Long); emitMove(longAddress, address); address = emitAdd(longAddress, asConstant(offset)); @@ -175,7 +176,7 @@ @Override public void emitUnwind(Value exception) { - ForeignCallLinkage linkage = getRuntime().lookupForeignCall(HotSpotBackend.UNWIND_EXCEPTION_TO_CALLER); + ForeignCallLinkage linkage = getCodeCache().lookupForeignCall(HotSpotBackend.UNWIND_EXCEPTION_TO_CALLER); CallingConvention linkageCc = linkage.getOutgoingCallingConvention(); assert linkageCc.getArgumentCount() == 2; RegisterValue exceptionParameter = (RegisterValue) linkageCc.getArgument(0); @@ -183,14 +184,23 @@ append(new SPARCHotSpotUnwindOp(exceptionParameter)); } + private void moveDeoptimizationActionAndReasonToThread(Value actionAndReason) { + int pendingDeoptimizationOffset = graalRuntime().getConfig().pendingDeoptimizationOffset; + RegisterValue thread = runtime().threadRegister().asValue(HotSpotGraalRuntime.wordKind()); + SPARCAddressValue pendingDeoptAddress = new SPARCAddressValue(actionAndReason.getKind(), thread, pendingDeoptimizationOffset); + append(new StoreOp(actionAndReason.getKind(), pendingDeoptAddress, emitMove(actionAndReason), null)); + } + @Override - public void emitDeoptimize(DeoptimizationAction action, DeoptimizingNode deopting) { - append(new SPARCDeoptimizeOp(action, deopting.getDeoptimizationReason(), state(deopting))); + public void emitDeoptimize(Value actionAndReason, DeoptimizingNode deopting) { + moveDeoptimizationActionAndReasonToThread(actionAndReason); + append(new SPARCDeoptimizeOp(state(deopting))); } @Override public void emitDeoptimizeCaller(DeoptimizationAction action, DeoptimizationReason reason) { - append(new SPARCHotSpotDeoptimizeCallerOp(action, reason)); + moveDeoptimizationActionAndReasonToThread(metaAccess.encodeDeoptActionAndReason(action, reason)); + append(new SPARCHotSpotDeoptimizeCallerOp()); } @Override @@ -201,7 +211,7 @@ @Override public void emitJumpToExceptionHandlerInCaller(ValueNode handlerInCallerPc, ValueNode exception, ValueNode exceptionPc) { Variable handler = load(operand(handlerInCallerPc)); - ForeignCallLinkage linkage = getRuntime().lookupForeignCall(EXCEPTION_HANDLER_IN_CALLER); + ForeignCallLinkage linkage = getCodeCache().lookupForeignCall(EXCEPTION_HANDLER_IN_CALLER); CallingConvention linkageCc = linkage.getOutgoingCallingConvention(); assert linkageCc.getArgumentCount() == 2; RegisterValue exceptionFixed = (RegisterValue) linkageCc.getArgument(0);
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotUnwindOp.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotUnwindOp.java Fri Oct 11 17:21:14 2013 +0200 @@ -51,7 +51,7 @@ public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) { leaveFrame(tasm); - ForeignCallLinkage linkage = tasm.runtime.lookupForeignCall(UNWIND_EXCEPTION_TO_CALLER); + ForeignCallLinkage linkage = tasm.codeCache.lookupForeignCall(UNWIND_EXCEPTION_TO_CALLER); CallingConvention cc = linkage.getOutgoingCallingConvention(); assert cc.getArgumentCount() == 2; assert exception.equals(cc.getArgument(0));
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/AheadOfTimeCompilationTest.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/AheadOfTimeCompilationTest.java Fri Oct 11 17:21:14 2013 +0200 @@ -64,7 +64,7 @@ public void testStaticFinalObjectAOT() { StructuredGraph result = compile("getStaticFinalObject", true); assertEquals(1, result.getNodes().filter(ConstantNode.class).count()); - assertEquals(runtime.getTarget().wordKind, result.getNodes().filter(ConstantNode.class).first().kind()); + assertEquals(getCodeCache().getTarget().wordKind, result.getNodes().filter(ConstantNode.class).first().kind()); assertEquals(2, result.getNodes(FloatingReadNode.class).count()); assertEquals(0, result.getNodes().filter(ReadNode.class).count()); } @@ -88,7 +88,7 @@ NodeIterable<ConstantNode> filter = result.getNodes().filter(ConstantNode.class); assertEquals(1, filter.count()); - HotSpotResolvedObjectType type = (HotSpotResolvedObjectType) runtime.lookupJavaType(AheadOfTimeCompilationTest.class); + HotSpotResolvedObjectType type = (HotSpotResolvedObjectType) getMetaAccess().lookupJavaType(AheadOfTimeCompilationTest.class); assertEquals(type.klass(), filter.first().asConstant()); assertEquals(1, result.getNodes(FloatingReadNode.class).count()); @@ -118,7 +118,7 @@ StructuredGraph result = compile("getPrimitiveClassObject", true); NodeIterable<ConstantNode> filter = result.getNodes().filter(ConstantNode.class); assertEquals(1, filter.count()); - assertEquals(runtime.getTarget().wordKind, filter.first().kind()); + assertEquals(getCodeCache().getTarget().wordKind, filter.first().kind()); assertEquals(2, result.getNodes(FloatingReadNode.class).count()); assertEquals(0, result.getNodes().filter(ReadNode.class).count()); @@ -179,7 +179,7 @@ assertEquals(1, result.getNodes().filter(ConstantNode.class).count()); ConstantNode constant = result.getNodes().filter(ConstantNode.class).first(); assertEquals(Kind.Long, constant.kind()); - assertEquals(((HotSpotResolvedObjectType) runtime.lookupJavaType(Boolean.class)).klass(), constant.asConstant()); + assertEquals(((HotSpotResolvedObjectType) getMetaAccess().lookupJavaType(Boolean.class)).klass(), constant.asConstant()); } @Test @@ -200,12 +200,12 @@ boolean originalSetting = AOTCompilation.getValue(); AOTCompilation.setValue(compileAOT); PhasePlan phasePlan = new PhasePlan(); - GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(runtime, GraphBuilderConfiguration.getDefault(), OptimisticOptimizations.ALL); + GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(getMetaAccess(), GraphBuilderConfiguration.getDefault(), OptimisticOptimizations.ALL); phasePlan.addPhase(PhasePosition.AFTER_PARSING, graphBuilderPhase); - CallingConvention cc = getCallingConvention(runtime, Type.JavaCallee, graph.method(), false); + CallingConvention cc = getCallingConvention(getCodeCache(), Type.JavaCallee, graph.method(), false); // create suites everytime, as we modify options for the compiler final Suites suitesLocal = Graal.getRequiredCapability(SuitesProvider.class).createSuites(); - final CompilationResult compResult = GraalCompiler.compileGraph(graph, cc, method, runtime, replacements, backend, runtime().getTarget(), null, phasePlan, OptimisticOptimizations.ALL, + final CompilationResult compResult = GraalCompiler.compileGraph(graph, cc, method, getProviders(), backend, getCodeCache().getTarget(), null, phasePlan, OptimisticOptimizations.ALL, new SpeculationLog(), suitesLocal, new CompilationResult()); addMethod(method, compResult);
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/ArrayCopyIntrinsificationTest.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/ArrayCopyIntrinsificationTest.java Fri Oct 11 17:21:14 2013 +0200 @@ -54,8 +54,8 @@ LoweredCallTargetNode directCall = (LoweredCallTargetNode) invoke.callTarget(); JavaMethod callee = directCall.target(); Assert.assertTrue(callee.getName().equals("<init>")); - Assert.assertTrue(runtime.lookupJavaType(ArrayIndexOutOfBoundsException.class).equals(callee.getDeclaringClass()) || - runtime.lookupJavaType(NullPointerException.class).equals(callee.getDeclaringClass())); + Assert.assertTrue(getMetaAccess().lookupJavaType(ArrayIndexOutOfBoundsException.class).equals(callee.getDeclaringClass()) || + getMetaAccess().lookupJavaType(NullPointerException.class).equals(callee.getDeclaringClass())); } } } else { @@ -65,7 +65,7 @@ Invoke invoke = (Invoke) node; LoweredCallTargetNode directCall = (LoweredCallTargetNode) invoke.callTarget(); JavaMethod callee = directCall.target(); - if (callee.getDeclaringClass().equals(runtime.lookupJavaType(System.class)) && callee.getName().equals("arraycopy")) { + if (callee.getDeclaringClass().equals(getMetaAccess().lookupJavaType(System.class)) && callee.getName().equals("arraycopy")) { found = true; } else { fail("found invoke to some method other than arraycopy: " + callee);
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/CompressedOopTest.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/CompressedOopTest.java Fri Oct 11 17:21:14 2013 +0200 @@ -40,15 +40,15 @@ */ public class CompressedOopTest extends GraalCompilerTest { - private final MetaAccessProvider metaAccessProvider; + private final MetaAccessProvider metaAccess; public CompressedOopTest() { - this.metaAccessProvider = Graal.getRequiredCapability(MetaAccessProvider.class); + this.metaAccess = Graal.getRequiredCapability(MetaAccessProvider.class); } private HotSpotInstalledCode getInstalledCode(String name) throws Exception { final Method method = CompressedOopTest.class.getMethod(name, Object.class, Object.class, Object.class); - final HotSpotResolvedJavaMethod javaMethod = (HotSpotResolvedJavaMethod) metaAccessProvider.lookupJavaMethod(method); + final HotSpotResolvedJavaMethod javaMethod = (HotSpotResolvedJavaMethod) metaAccess.lookupJavaMethod(method); final HotSpotInstalledCode installedBenchmarkCode = (HotSpotInstalledCode) getCode(javaMethod, parse(method)); return installedBenchmarkCode; }
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotCryptoSubstitutionTest.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotCryptoSubstitutionTest.java Fri Oct 11 17:21:14 2013 +0200 @@ -48,42 +48,54 @@ @Override protected InstalledCode addMethod(ResolvedJavaMethod method, CompilationResult compResult) { HotSpotResolvedJavaMethod hsMethod = (HotSpotResolvedJavaMethod) method; - HotSpotNmethod installedCode = new HotSpotNmethod(hsMethod, true, null); + HotSpotNmethod installedCode = new HotSpotNmethod(hsMethod, true); HotSpotCompiledNmethod compiledNmethod = new HotSpotCompiledNmethod(hsMethod, StructuredGraph.INVOCATION_ENTRY_BCI, compResult); CodeInstallResult result = graalRuntime().getCompilerToVM().installCode(compiledNmethod, installedCode, null); Assert.assertEquals("Error installing method " + method + ": " + result, result, CodeInstallResult.OK); - // HotSpotRuntime hsRuntime = (HotSpotRuntime) runtime; + // HotSpotRuntime hsRuntime = (HotSpotRuntime) getCodeCache(); // TTY.println(hsMethod.toString()); // TTY.println(hsRuntime.disassemble(installedCode)); return installedCode; } @Test - public void testAESEncryptSubstitution() throws Exception { + public void testEncryptSubstitution() throws Exception { byte[] seed = {0x4, 0x7, 0x1, 0x1}; SecureRandom random = new SecureRandom(seed); KeyGenerator aesKeyGen = KeyGenerator.getInstance("AES"); + KeyGenerator desKeyGen = KeyGenerator.getInstance("DESede"); aesKeyGen.init(128, random); + desKeyGen.init(168, random); SecretKey aesKey = aesKeyGen.generateKey(); + SecretKey desKey = desKeyGen.generateKey(); byte[] input = readClassfile16(getClass()); - ByteArrayOutputStream expected = new ByteArrayOutputStream(); - expected.write(runEncryptDecrypt(aesKey, "AES/CBC/NoPadding", input)); - expected.write(runEncryptDecrypt(aesKey, "AES/CBC/PKCS5Padding", input)); + ByteArrayOutputStream aesExpected = new ByteArrayOutputStream(); + aesExpected.write(runEncryptDecrypt(aesKey, "AES/CBC/NoPadding", input)); + aesExpected.write(runEncryptDecrypt(aesKey, "AES/CBC/PKCS5Padding", input)); if (compiledAndInstall("com.sun.crypto.provider.AESCrypt", "encryptBlock", "decryptBlock")) { ByteArrayOutputStream actual = new ByteArrayOutputStream(); actual.write(runEncryptDecrypt(aesKey, "AES/CBC/NoPadding", input)); actual.write(runEncryptDecrypt(aesKey, "AES/CBC/PKCS5Padding", input)); - Assert.assertArrayEquals(expected.toByteArray(), actual.toByteArray()); + Assert.assertArrayEquals(aesExpected.toByteArray(), actual.toByteArray()); } + ByteArrayOutputStream desExpected = new ByteArrayOutputStream(); + desExpected.write(runEncryptDecrypt(desKey, "DESede/CBC/NoPadding", input)); + desExpected.write(runEncryptDecrypt(desKey, "DESede/CBC/PKCS5Padding", input)); + if (compiledAndInstall("com.sun.crypto.provider.CipherBlockChaining", "encrypt", "decrypt")) { ByteArrayOutputStream actual = new ByteArrayOutputStream(); actual.write(runEncryptDecrypt(aesKey, "AES/CBC/NoPadding", input)); actual.write(runEncryptDecrypt(aesKey, "AES/CBC/PKCS5Padding", input)); - Assert.assertArrayEquals(expected.toByteArray(), actual.toByteArray()); + Assert.assertArrayEquals(aesExpected.toByteArray(), actual.toByteArray()); + + actual.reset(); + actual.write(runEncryptDecrypt(desKey, "DESede/CBC/NoPadding", input)); + actual.write(runEncryptDecrypt(desKey, "DESede/CBC/PKCS5Padding", input)); + Assert.assertArrayEquals(desExpected.toByteArray(), actual.toByteArray()); } } @@ -100,8 +112,8 @@ for (String methodName : methodNames) { Method method = lookup(className, methodName); if (method != null) { - ResolvedJavaMethod installedCodeOwner = runtime.lookupJavaMethod(method); - StructuredGraph graph = replacements.getMethodSubstitution(installedCodeOwner); + ResolvedJavaMethod installedCodeOwner = getMetaAccess().lookupJavaMethod(method); + StructuredGraph graph = getReplacements().getMethodSubstitution(installedCodeOwner); if (graph != null) { Assert.assertNotNull(getCode(installedCodeOwner, graph, true)); atLeastOneCompiled = true;
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotNmethodTest.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotNmethodTest.java Fri Oct 11 17:21:14 2013 +0200 @@ -36,7 +36,7 @@ @Test public void testInstallCodeInvalidation() { - final ResolvedJavaMethod testJavaMethod = runtime.lookupJavaMethod(getMethod("foo")); + final ResolvedJavaMethod testJavaMethod = getMetaAccess().lookupJavaMethod(getMethod("foo")); final StructuredGraph graph = parse("otherFoo"); final HotSpotNmethod nmethod = (HotSpotNmethod) getCode(testJavaMethod, graph); Assert.assertTrue(nmethod.isValid()); @@ -60,7 +60,7 @@ @Test public void testInstallCodeInvalidationWhileRunning() { - final ResolvedJavaMethod testJavaMethod = runtime.lookupJavaMethod(getMethod("foo")); + final ResolvedJavaMethod testJavaMethod = getMetaAccess().lookupJavaMethod(getMethod("foo")); final StructuredGraph graph = parse("otherFoo"); final HotSpotNmethod nmethod = (HotSpotNmethod) getCode(testJavaMethod, graph); Object result; @@ -75,7 +75,7 @@ @Test public void testInstalledCodeCalledFromCompiledCode() { - final ResolvedJavaMethod testJavaMethod = runtime.lookupJavaMethod(getMethod("foo")); + final ResolvedJavaMethod testJavaMethod = getMetaAccess().lookupJavaMethod(getMethod("foo")); final StructuredGraph graph = parse("otherFoo"); final HotSpotNmethod nmethod = (HotSpotNmethod) getCode(testJavaMethod, graph); Assert.assertTrue(nmethod.isValid());
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/InstalledCodeExecuteHelperTest.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/InstalledCodeExecuteHelperTest.java Fri Oct 11 17:21:14 2013 +0200 @@ -39,23 +39,23 @@ public class InstalledCodeExecuteHelperTest extends GraalCompilerTest { private static final int ITERATIONS = 100000; - private final MetaAccessProvider metaAccessProvider; + private final MetaAccessProvider metaAccess; Object[] argsToBind; public InstalledCodeExecuteHelperTest() { - this.metaAccessProvider = Graal.getRequiredCapability(MetaAccessProvider.class); + this.metaAccess = Graal.getRequiredCapability(MetaAccessProvider.class); } @Test public void test1() throws NoSuchMethodException, SecurityException, InvalidInstalledCodeException { final Method fooMethod = InstalledCodeExecuteHelperTest.class.getMethod("foo", Object.class, Object.class, Object.class); - final HotSpotResolvedJavaMethod fooJavaMethod = (HotSpotResolvedJavaMethod) metaAccessProvider.lookupJavaMethod(fooMethod); + final HotSpotResolvedJavaMethod fooJavaMethod = (HotSpotResolvedJavaMethod) metaAccess.lookupJavaMethod(fooMethod); final HotSpotInstalledCode fooCode = (HotSpotInstalledCode) getCode(fooJavaMethod, parse(fooMethod)); argsToBind = new Object[]{fooCode}; final Method benchmarkMethod = InstalledCodeExecuteHelperTest.class.getMethod("benchmark", HotSpotInstalledCode.class); - final ResolvedJavaMethod benchmarkJavaMethod = metaAccessProvider.lookupJavaMethod(benchmarkMethod); + final ResolvedJavaMethod benchmarkJavaMethod = metaAccess.lookupJavaMethod(benchmarkMethod); final HotSpotInstalledCode installedBenchmarkCode = (HotSpotInstalledCode) getCode(benchmarkJavaMethod, parse(benchmarkMethod)); Assert.assertEquals(Integer.valueOf(42), benchmark(fooCode)); @@ -84,12 +84,12 @@ if (argsToBind != null) { Object receiver = isStatic(m.getModifiers()) ? null : this; Object[] args = argsWithReceiver(receiver, argsToBind); - JavaType[] parameterTypes = signatureToTypes(runtime.lookupJavaMethod(m)); + JavaType[] parameterTypes = signatureToTypes(getMetaAccess().lookupJavaMethod(m)); assert parameterTypes.length == args.length; for (int i = 0; i < argsToBind.length; i++) { LocalNode local = graph.getLocal(i); Constant c = Constant.forBoxed(parameterTypes[i].getKind(), argsToBind[i]); - ConstantNode replacement = ConstantNode.forConstant(c, runtime, graph); + ConstantNode replacement = ConstantNode.forConstant(c, getMetaAccess(), graph); local.replaceAtUsages(replacement); } }
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierAdditionTest.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierAdditionTest.java Fri Oct 11 17:21:14 2013 +0200 @@ -53,13 +53,12 @@ * offsets) passed as input parameters can be checked against printed output from the G1 write * barrier snippets. The runtime checks have been validated offline. */ - public class WriteBarrierAdditionTest extends GraalCompilerTest { - private final MetaAccessProvider metaAccessProvider; + private final MetaAccessProvider metaAccess; public WriteBarrierAdditionTest() { - this.metaAccessProvider = Graal.getRequiredCapability(MetaAccessProvider.class); + this.metaAccess = Graal.getRequiredCapability(MetaAccessProvider.class); } public static class Container { @@ -175,7 +174,7 @@ } public static Object test5Snippet() throws Exception { - return UnsafeLoadNode.load(wr, 0, useCompressedOops() ? 12 : 16, Kind.Object); + return UnsafeLoadNode.load(wr, useCompressedOops() ? 12 : 16, Kind.Object); } /** @@ -250,12 +249,12 @@ public static Object testUnsafeLoad(Object a, Object b, Object c) throws Exception { final int offset = (c == null ? 0 : ((Integer) c).intValue()); final long displacement = (b == null ? 0 : ((Long) b).longValue()); - return UnsafeLoadNode.load(a, offset, displacement, Kind.Object); + return UnsafeLoadNode.load(a, offset + displacement, Kind.Object); } private HotSpotInstalledCode getInstalledCode(String name) throws Exception { final Method method = WriteBarrierAdditionTest.class.getMethod(name, Object.class, Object.class, Object.class); - final HotSpotResolvedJavaMethod javaMethod = (HotSpotResolvedJavaMethod) metaAccessProvider.lookupJavaMethod(method); + final HotSpotResolvedJavaMethod javaMethod = (HotSpotResolvedJavaMethod) metaAccess.lookupJavaMethod(method); final HotSpotInstalledCode installedBenchmarkCode = (HotSpotInstalledCode) getCode(javaMethod, parse(method)); return installedBenchmarkCode; } @@ -265,8 +264,8 @@ public void run() { StructuredGraph graph = parse(snippet); - HighTierContext highContext = new HighTierContext(runtime(), new Assumptions(false), replacements, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL); - MidTierContext midContext = new MidTierContext(runtime(), new Assumptions(false), replacements, runtime().getTarget(), OptimisticOptimizations.ALL); + HighTierContext highContext = new HighTierContext(getProviders(), new Assumptions(false), null, getDefaultPhasePlan(), OptimisticOptimizations.ALL); + MidTierContext midContext = new MidTierContext(getProviders(), new Assumptions(false), getCodeCache().getTarget(), OptimisticOptimizations.ALL); new InliningPhase(new InliningPhase.InlineEverythingPolicy(), new CanonicalizerPhase(true)).apply(graph, highContext); new LoweringPhase(new CanonicalizerPhase(true)).apply(graph, highContext); new GuardLoweringPhase().apply(graph, midContext); @@ -276,9 +275,10 @@ int barriers = 0; if (useG1GC()) { - barriers = graph.getNodes(G1ReferentFieldReadBarrier.class).count() + graph.getNodes(G1PreWriteBarrier.class).count() + graph.getNodes(G1PostWriteBarrier.class).count(); + barriers = graph.getNodes().filter(G1ReferentFieldReadBarrier.class).count() + graph.getNodes().filter(G1PreWriteBarrier.class).count() + + graph.getNodes().filter(G1PostWriteBarrier.class).count(); } else { - barriers = graph.getNodes(SerialWriteBarrier.class).count(); + barriers = graph.getNodes().filter(SerialWriteBarrier.class).count(); } Assert.assertEquals(expectedBarriers, barriers); for (WriteNode write : graph.getNodes().filter(WriteNode.class)) {
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierVerificationTest.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierVerificationTest.java Fri Oct 11 17:21:14 2013 +0200 @@ -615,10 +615,10 @@ public AssertionError call() { final StructuredGraph graph = parse(snippet); - HighTierContext highTierContext = new HighTierContext(runtime(), new Assumptions(false), replacements, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL); + HighTierContext highTierContext = new HighTierContext(getProviders(), new Assumptions(false), null, getDefaultPhasePlan(), OptimisticOptimizations.ALL); new InliningPhase(new CanonicalizerPhase(true)).apply(graph, highTierContext); - MidTierContext midTierContext = new MidTierContext(runtime(), new Assumptions(false), replacements, runtime().getTarget(), OptimisticOptimizations.ALL); + MidTierContext midTierContext = new MidTierContext(getProviders(), new Assumptions(false), getCodeCache().getTarget(), OptimisticOptimizations.ALL); new LoweringPhase(new CanonicalizerPhase(true)).apply(graph, highTierContext); new GuardLoweringPhase().apply(graph, midTierContext); @@ -629,12 +629,12 @@ int barriers = 0; // First, the total number of expected barriers is checked. - if (((HotSpotRuntime) runtime()).config.useG1GC) { - barriers = graph.getNodes(G1PreWriteBarrier.class).count() + graph.getNodes(G1PostWriteBarrier.class).count() + graph.getNodes(G1ArrayRangePreWriteBarrier.class).count() + - graph.getNodes(G1ArrayRangePostWriteBarrier.class).count(); + if (((HotSpotRuntime) getMetaAccess()).config.useG1GC) { + barriers = graph.getNodes().filter(G1PreWriteBarrier.class).count() + graph.getNodes().filter(G1PostWriteBarrier.class).count() + + graph.getNodes().filter(G1ArrayRangePreWriteBarrier.class).count() + graph.getNodes().filter(G1ArrayRangePostWriteBarrier.class).count(); Assert.assertTrue(expectedBarriers * 2 == barriers); } else { - barriers = graph.getNodes(SerialWriteBarrier.class).count() + graph.getNodes(SerialArrayRangeWriteBarrier.class).count(); + barriers = graph.getNodes().filter(SerialWriteBarrier.class).count() + graph.getNodes().filter(SerialArrayRangeWriteBarrier.class).count(); Assert.assertTrue(expectedBarriers == barriers); } // Iterate over all write nodes and remove barriers according to input indices.
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java Fri Oct 11 17:21:14 2013 +0200 @@ -42,6 +42,7 @@ import com.oracle.graal.phases.*; import com.oracle.graal.phases.common.*; import com.oracle.graal.phases.tiers.*; +import com.oracle.graal.phases.util.*; public final class CompilationTask implements Runnable { @@ -128,8 +129,7 @@ CompilationStatistics stats = CompilationStatistics.create(method, entryBCI != StructuredGraph.INVOCATION_ENTRY_BCI); 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 + ") ")); + TTY.println(getMethodDescription() + "..."); } if (HotSpotPrintCompilation.getValue()) { printCompilation(); @@ -155,13 +155,17 @@ InliningUtil.InlinedBytecodes.add(method.getCodeSize()); HotSpotRuntime runtime = graalRuntime.getRuntime(); CallingConvention cc = getCallingConvention(runtime, Type.JavaCallee, graph.method(), false); - return GraalCompiler.compileGraph(graph, cc, method, runtime, replacements, graalRuntime.getBackend(), graalRuntime.getTarget(), graalRuntime.getCache(), plan, optimisticOpts, + Providers providers = new Providers(runtime, runtime, runtime, runtime, replacements); + return GraalCompiler.compileGraph(graph, cc, method, providers, graalRuntime.getBackend(), graalRuntime.getTarget(), graalRuntime.getCache(), plan, optimisticOpts, method.getSpeculationLog(), suitesProvider.getDefaultSuites(), new CompilationResult()); } }); } finally { filter.remove(); - if (printCompilation) { + final boolean printAfterCompilation = PrintAfterCompilation.getValue() && !TTY.isSuppressed(); + if (printAfterCompilation) { + TTY.println(getMethodDescription() + String.format(" | %4dms %5dB", System.currentTimeMillis() - start, (result != null ? result.getTargetCodeSize() : -1))); + } else if (printCompilation) { TTY.println(String.format("%-6d Graal %-70s %-45s %-50s | %4dms %5dB", id, "", "", "", System.currentTimeMillis() - start, (result != null ? result.getTargetCodeSize() : -1))); } } @@ -193,6 +197,11 @@ } } + private String getMethodDescription() { + return String.format("%-6d Graal %-70s %-45s %-50s %s", id, method.getDeclaringClass().getName(), method.getName(), method.getSignature().getMethodDescriptor(), + entryBCI == StructuredGraph.INVOCATION_ENTRY_BCI ? "" : "(OSR@" + entryBCI + ") "); + } + /** * Print a HotSpot-style compilation message to the console. */
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotBackend.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotBackend.java Fri Oct 11 17:21:14 2013 +0200 @@ -69,11 +69,10 @@ public static final ForeignCallDescriptor EXCEPTION_HANDLER_IN_CALLER = new ForeignCallDescriptor("exceptionHandlerInCaller", void.class, Object.class, Word.class); public HotSpotBackend(HotSpotRuntime runtime, TargetDescription target) { - super(runtime, target); + super(runtime, runtime, target); } - @Override - public HotSpotRuntime runtime() { - return (HotSpotRuntime) super.runtime(); + public HotSpotRuntime getRuntime() { + return (HotSpotRuntime) getCodeCache(); } }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotDebugInfoBuilder.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotDebugInfoBuilder.java Fri Oct 11 17:21:14 2013 +0200 @@ -61,7 +61,7 @@ } @Override - protected LIRFrameState newLIRFrameState(short reason, LabelRef exceptionEdge, BytecodeFrame frame, VirtualObject[] virtualObjectsArray) { - return new HotSpotLIRFrameState(frame, virtualObjectsArray, exceptionEdge, reason); + protected LIRFrameState newLIRFrameState(LabelRef exceptionEdge, BytecodeFrame frame, VirtualObject[] virtualObjectsArray) { + return new HotSpotLIRFrameState(frame, virtualObjectsArray, exceptionEdge); } }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotForeignCallLinkage.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotForeignCallLinkage.java Fri Oct 11 17:21:14 2013 +0200 @@ -144,7 +144,7 @@ } TargetDescription target = graalRuntime().getTarget(); JavaType returnType = asJavaType(descriptor.getResultType(), runtime); - return runtime.lookupRegisterConfig().getCallingConvention(ccType, returnType, parameterTypes, target, false); + return runtime.getRegisterConfig().getCallingConvention(ccType, returnType, parameterTypes, target, false); } private static JavaType asJavaType(Class type, HotSpotRuntime runtime) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java Fri Oct 11 17:21:14 2013 +0200 @@ -349,7 +349,7 @@ @SuppressWarnings("unchecked") @Override public <T> T getCapability(Class<T> clazz) { - if (clazz == GraalCodeCacheProvider.class || clazz == CodeCacheProvider.class || clazz == MetaAccessProvider.class) { + if (clazz == LoweringProvider.class || clazz == CodeCacheProvider.class || clazz == MetaAccessProvider.class || clazz == ConstantReflectionProvider.class) { return (T) getRuntime(); } if (clazz == DisassemblerProvider.class || clazz == BytecodeDisassemblerProvider.class || clazz == SuitesProvider.class) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotLIRFrameState.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotLIRFrameState.java Fri Oct 11 17:21:14 2013 +0200 @@ -34,8 +34,8 @@ */ class HotSpotLIRFrameState extends LIRFrameState { - public HotSpotLIRFrameState(BytecodeFrame topFrame, VirtualObject[] virtualObjects, LabelRef exceptionEdge, short deoptimizationReason) { - super(topFrame, virtualObjects, exceptionEdge, deoptimizationReason); + public HotSpotLIRFrameState(BytecodeFrame topFrame, VirtualObject[] virtualObjects, LabelRef exceptionEdge) { + super(topFrame, virtualObjects, exceptionEdge); } @Override
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotOptions.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotOptions.java Fri Oct 11 17:21:14 2013 +0200 @@ -131,6 +131,14 @@ OptionDescriptor desc = options.get(optionName); if (desc == null) { Logger.info("Could not find option " + optionName + " (use -G:+PrintFlags to see Graal options)"); + List<OptionDescriptor> matches = fuzzyMatch(optionName); + if (!matches.isEmpty()) { + Logger.info("Did you mean one of the following?"); + for (OptionDescriptor match : matches) { + boolean isBoolean = match.getType() == boolean.class; + Logger.info(String.format(" %s%s%s", isBoolean ? "(+/-)" : "", match.getName(), isBoolean ? "" : "=<value>")); + } + } return false; } @@ -210,7 +218,7 @@ if (line.length() != 0) { line.append(' '); } - String[] embeddedLines = chunk.split("%n"); + String[] embeddedLines = chunk.split("%n", -2); if (embeddedLines.length == 1) { line.append(chunk); } else { @@ -246,4 +254,38 @@ System.exit(0); } + + /** + * Compute string similarity based on Dice's coefficient. + * + * Ported from str_similar() in globals.cpp. + */ + static float stringSimiliarity(String str1, String str2) { + int hit = 0; + for (int i = 0; i < str1.length() - 1; ++i) { + for (int j = 0; j < str2.length() - 1; ++j) { + if ((str1.charAt(i) == str2.charAt(j)) && (str1.charAt(i + 1) == str2.charAt(j + 1))) { + ++hit; + break; + } + } + } + return 2.0f * hit / (str1.length() + str2.length()); + } + + private static final float FUZZY_MATCH_THRESHOLD = 0.7F; + + /** + * Returns the set of options that fuzzy match a given option name. + */ + private static List<OptionDescriptor> fuzzyMatch(String optionName) { + List<OptionDescriptor> matches = new ArrayList<>(); + for (Map.Entry<String, OptionDescriptor> e : options.entrySet()) { + float score = stringSimiliarity(e.getKey(), optionName); + if (score >= FUZZY_MATCH_THRESHOLD) { + matches.add(e.getValue()); + } + } + return matches; + } }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotReplacementsImpl.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotReplacementsImpl.java Fri Oct 11 17:21:14 2013 +0200 @@ -40,7 +40,7 @@ private final HotSpotVMConfig config; public HotSpotReplacementsImpl(HotSpotRuntime runtime, Assumptions assumptions, TargetDescription target) { - super(runtime, assumptions, target); + super(runtime, runtime, runtime, runtime, assumptions, target); this.config = runtime.config; }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java Fri Oct 11 17:21:14 2013 +0200 @@ -247,6 +247,16 @@ public final int osThreadOffset = getUninitializedInt(); /** + * The value of JavaThread::graal_counters_offset(). + */ + public final int graalCountersThreadOffset = getUninitializedInt(); + + /** + * The length of the JavaThread::_graal_counters array. + */ + public final int graalCountersSize = getUninitializedInt(); + + /** * The value of OSThread::interrupted_offset(). */ public final int osThreadInterruptedOffset = getUninitializedInt();
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToGPU.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToGPU.java Fri Oct 11 17:21:14 2013 +0200 @@ -45,6 +45,8 @@ */ boolean deviceDetach(); + int availableProcessors(); + /** * Attempts to generate and return a bound function to the * loaded method kernel on the GPU. @@ -55,4 +57,8 @@ long generateKernel(byte[] code, String name) throws InvalidInstalledCodeException; Object executeExternalMethodVarargs(Object[] args, HotSpotInstalledCode hotspotInstalledCode) throws InvalidInstalledCodeException; + + + Object executeParallelMethodVarargs(int dimX, int dimY, int dimZ, + Object[] args, HotSpotInstalledCode hotspotInstalledCode) throws InvalidInstalledCodeException; }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToGPUImpl.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToGPUImpl.java Fri Oct 11 17:21:14 2013 +0200 @@ -38,5 +38,12 @@ public native boolean deviceDetach(); - public native Object executeExternalMethodVarargs(Object[] args, HotSpotInstalledCode hotspotInstalledCode) throws InvalidInstalledCodeException; + public native int availableProcessors(); + + public native Object executeExternalMethodVarargs(Object[] args, + HotSpotInstalledCode hotspotInstalledCode) throws InvalidInstalledCodeException; + + public native Object executeParallelMethodVarargs(int dimX, int dimY, int dimZ, + Object[] args, + HotSpotInstalledCode hotspotInstalledCode) throws InvalidInstalledCodeException; }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java Fri Oct 11 17:21:14 2013 +0200 @@ -228,4 +228,9 @@ void invalidateInstalledCode(HotSpotInstalledCode hotspotInstalledCode); boolean isTypeLinked(HotSpotResolvedObjectType hotSpotResolvedObjectType); + + /** + * Collects the current values of all Graal benchmark counters, summed up over all threads. + */ + long[] collectCounters(); }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java Fri Oct 11 17:21:14 2013 +0200 @@ -190,4 +190,6 @@ * verified entry point of the given native method. */ public static native Object executeCompiledMethodIntrinsic(Object arg1, Object arg2, Object arg3, HotSpotInstalledCode hotspotInstalledCode) throws InvalidInstalledCodeException; + + public native long[] collectCounters(); }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java Fri Oct 11 17:21:14 2013 +0200 @@ -47,7 +47,6 @@ import com.oracle.graal.hotspot.phases.*; import com.oracle.graal.java.*; 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.*; @@ -79,11 +78,6 @@ } }; - @Option(help = "") - private static final OptionValue<Boolean> GenericDynamicCounters = new OptionValue<>(false); - - @Option(help = "") - private static final OptionValue<String> BenchmarkDynamicCounters = new OptionValue<>(null); //@formatter:on private final HotSpotGraalRuntime graalRuntime; @@ -185,10 +179,10 @@ } } - assert VerifyHotSpotOptionsPhase.checkOptions(); + final HotSpotRuntime runtime = graalRuntime.getCapability(HotSpotRuntime.class); + assert VerifyOptionsPhase.checkOptions(runtime); // Install intrinsics. - final HotSpotRuntime runtime = graalRuntime.getCapability(HotSpotRuntime.class); final Replacements replacements = graalRuntime.getCapability(Replacements.class); if (Intrinsify.getValue()) { Debug.scope("RegisterReplacements", new Object[]{new DebugDumpScope("RegisterReplacements")}, new Runnable() { @@ -234,28 +228,8 @@ t.start(); } - 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)"); - } - for (int i = 0; i < arguments.length; i += 3) { - if (arguments[i].equals("err")) { - System.setErr(new PrintStream(new BenchmarkCountersOutputStream(System.err, arguments[i + 1], arguments[i + 2]))); - } else if (arguments[i].equals("out")) { - System.setOut(new PrintStream(new BenchmarkCountersOutputStream(System.out, arguments[i + 1], arguments[i + 2]))); - } else { - throw new GraalInternalError("invalid arguments to BenchmarkDynamicCounters: err|out"); - } - // dacapo: "err, starting =====, PASSED in " - // specjvm2008: "out,Iteration ~ (~s) begins: ,Iteration ~ (~s) ends: " - } - DynamicCounterNode.excludedClassPrefix = "Lcom/oracle/graal/"; - DynamicCounterNode.enabled = true; - } - if (GenericDynamicCounters.getValue()) { - DynamicCounterNode.enabled = true; - } + BenchmarkCounters.initialize(graalRuntime.getCompilerToVM()); + compilerStartTime = System.nanoTime(); } @@ -284,84 +258,6 @@ } } - private final class BenchmarkCountersOutputStream extends CallbackOutputStream { - - private long startTime; - private boolean waitingForEnd; - - private BenchmarkCountersOutputStream(PrintStream delegate, String start, String end) { - super(delegate, new String[]{start, end, "\n"}); - } - - @Override - protected void patternFound(int index) { - switch (index) { - case 0: - startTime = System.nanoTime(); - DynamicCounterNode.clear(); - break; - case 1: - waitingForEnd = true; - break; - case 2: - if (waitingForEnd) { - waitingForEnd = false; - DynamicCounterNode.dump(delegate, (System.nanoTime() - startTime) / 1000000000d); - } - break; - } - } - } - - public abstract static class CallbackOutputStream extends OutputStream { - - protected final PrintStream delegate; - private final byte[][] patterns; - private final int[] positions; - - public CallbackOutputStream(PrintStream delegate, String... patterns) { - this.delegate = delegate; - this.positions = new int[patterns.length]; - this.patterns = new byte[patterns.length][]; - for (int i = 0; i < patterns.length; i++) { - this.patterns[i] = patterns[i].getBytes(); - } - } - - protected abstract void patternFound(int index); - - @Override - public void write(int b) throws IOException { - try { - delegate.write(b); - for (int i = 0; i < patterns.length; i++) { - int j = positions[i]; - byte[] cs = patterns[i]; - byte patternChar = cs[j]; - if (patternChar == '~' && Character.isDigit(b)) { - // nothing to do... - } else { - if (patternChar == '~') { - patternChar = cs[++positions[i]]; - } - if (b == patternChar) { - positions[i]++; - } else { - positions[i] = 0; - } - } - if (positions[i] == patterns[i].length) { - positions[i] = 0; - patternFound(i); - } - } - } catch (RuntimeException e) { - e.printStackTrace(delegate); - throw e; - } - } - } - /** * Take action related to entering a new execution phase. * @@ -528,9 +424,7 @@ } SnippetCounter.printGroups(TTY.out().out()); - if (GenericDynamicCounters.getValue()) { - DynamicCounterNode.dump(System.out, (System.nanoTime() - compilerStartTime) / 1000000000d); - } + BenchmarkCounters.shutdown(graalRuntime.getCompilerToVM(), compilerStartTime); } private void flattenChildren(DebugValueMap map, DebugValueMap globalMap) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/debug/BenchmarkCounters.java Fri Oct 11 17:21:14 2013 +0200 @@ -0,0 +1,347 @@ +/* + * 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.debug; + +import java.io.*; +import java.text.*; +import java.util.*; +import java.util.concurrent.*; +import java.util.concurrent.atomic.*; + +import sun.misc.*; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.hotspot.*; +import com.oracle.graal.hotspot.bridge.*; +import com.oracle.graal.hotspot.meta.*; +import com.oracle.graal.hotspot.replacements.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.HeapAccess.*; +import com.oracle.graal.nodes.calc.*; +import com.oracle.graal.nodes.debug.*; +import com.oracle.graal.nodes.extended.*; +import com.oracle.graal.nodes.type.*; +import com.oracle.graal.options.*; +import com.oracle.graal.replacements.nodes.*; + +/** + * This class contains infrastructure to maintain counters based on {@link DynamicCounterNode}s. The + * infrastructure is enabled by specifying either the GenericDynamicCounters or + * BenchmarkDynamicCounters option.<br/> + * + * The counters are kept in a special area in the native JavaThread object, and the number of + * counters is configured in {@code thread.hpp (GRAAL_COUNTERS_SIZE)}. This file also contains an + * option to exclude compiler threads ({@code GRAAL_COUNTERS_EXCLUDE_COMPILER_THREADS}, which + * defaults to true). + * + * The subsystems that use the logging need to have their own options to turn on the counters, and + * insert DynamicCounterNodes when they're enabled. + * + * Counters will be displayed as a rate (per second) if their group name starts with "~", otherwise + * they will be displayed as a total number. + * + * <h1>Example</h1> In order to create statistics about allocations within the DaCapo pmd benchmark + * the following steps are necessary: + * <ul> + * <li>Modify {@code thread.hpp}: increase GRAAL_COUNTER_SIZE. The actual required value depends on + * the granularity of the profiling, 10000 should be enough for most cases. This will increase the + * JavaThread structure by 80kb.</li> + * <li>Also in {@code thread.hpp}: GRAAL_COUNTERS_EXCLUDE_COMPILER_THREADS specifies whether the + * numbers generated by compiler threads should be excluded (default: true).</li> + * <li>Build the Graal VM.</li> + * <li>Start the DaCapo pmd benchmark with + * {@code "-G:BenchmarkDynamicCounters=err, starting ====, PASSED in "} and + * {@code -G:+ProfileAllocations}.</li> + * <li>The numbers will only include allocation from compiled code!</li> + * <li>The counters can be further configured by modifying the + * {@link NewObjectSnippets#PROFILE_MODE} field.</li> + * </ul> + */ +public class BenchmarkCounters { + + static class Options { + + //@formatter:off + @Option(help = "Turn on the benchmark counters, and displays the results on VM shutdown") + private static final OptionValue<Boolean> GenericDynamicCounters = new OptionValue<>(false); + + @Option(help = "Turn on the benchmark counters, and listen for specific patterns on System.out/System.err:%n" + + "Format: (err|out),start pattern,end pattern (~ matches multiple digits)%n" + + "Examples:%n" + + " dacapo = 'err, starting =====, PASSED in'%n" + + " specjvm2008 = 'out,Iteration ~ (~s) begins:,Iteration ~ (~s) ends:'") + private static final OptionValue<String> BenchmarkDynamicCounters = new OptionValue<>(null); + //@formatter:on + } + + private static final boolean DUMP_STATIC = false; + + public static String excludedClassPrefix = null; + public static boolean enabled = false; + + public static final ConcurrentHashMap<String, Integer> indexes = new ConcurrentHashMap<>(); + public static final ArrayList<String> groups = new ArrayList<>(); + public static long[] delta; + public static final ArrayList<AtomicLong> staticCounters = new ArrayList<>(); + + public static int getIndex(DynamicCounterNode counter) { + if (!enabled) { + throw new GraalInternalError("counter nodes shouldn't exist when counters are not enabled"); + } + String name = counter.getName(); + String group = counter.getGroup(); + name = counter.isWithContext() ? name + " @ " + counter.graph().graphId() + ":" + MetaUtil.format("%h.%n", counter.graph().method()) + "#" + group : name + "#" + group; + Integer index = indexes.get(name); + if (index == null) { + synchronized (BenchmarkCounters.class) { + index = indexes.get(name); + if (index == null) { + index = indexes.size(); + indexes.put(name, index); + groups.add(group); + staticCounters.add(new AtomicLong()); + } + } + } + assert groups.get(index).equals(group) : "mismatching groups: " + groups.get(index) + " vs. " + group; + if (counter.getIncrement().isConstant()) { + staticCounters.get(index).addAndGet(counter.getIncrement().asConstant().asLong()); + } + return index; + } + + public static synchronized void dump(PrintStream out, double seconds, long[] counters) { + if (!groups.isEmpty()) { + out.println("====== dynamic counters (" + staticCounters.size() + " in total) ======"); + for (String group : new TreeSet<>(groups)) { + if (group != null) { + if (DUMP_STATIC) { + dumpCounters(out, seconds, counters, true, group); + } + dumpCounters(out, seconds, counters, false, group); + } + } + out.println("============================"); + + clear(counters); + } + } + + public static synchronized void clear(long[] counters) { + delta = counters; + } + + private static synchronized void dumpCounters(PrintStream out, double seconds, long[] counters, boolean staticCounter, String group) { + TreeMap<Long, String> sorted = new TreeMap<>(); + + long[] array; + if (staticCounter) { + array = new long[indexes.size()]; + for (int i = 0; i < array.length; i++) { + array[i] = staticCounters.get(i).get(); + } + } else { + array = counters.clone(); + for (int i = 0; i < array.length; i++) { + array[i] -= delta[i]; + } + } + long sum = 0; + for (Map.Entry<String, Integer> entry : indexes.entrySet()) { + int index = entry.getValue(); + if (groups.get(index).equals(group)) { + sum += array[index]; + sorted.put(array[index] * array.length + index, entry.getKey().substring(0, entry.getKey().length() - group.length() - 1)); + } + } + + if (sum > 0) { + NumberFormat format = NumberFormat.getInstance(Locale.US); + long cutoff = sorted.size() < 10 ? 1 : Math.max(1, sum / 100); + if (staticCounter) { + out.println("=========== " + group + " (static counters):"); + for (Map.Entry<Long, String> entry : sorted.entrySet()) { + long counter = entry.getKey() / array.length; + if (counter >= cutoff) { + out.println(format.format(counter) + " \t" + ((counter * 200 + 1) / sum / 2) + "% \t" + entry.getValue()); + } + } + out.println(sum + ": total"); + } else { + if (group.startsWith("~")) { + out.println("=========== " + group + " (dynamic counters), time = " + seconds + " s:"); + for (Map.Entry<Long, String> entry : sorted.entrySet()) { + long counter = entry.getKey() / array.length; + if (counter >= cutoff) { + out.println(format.format((long) (counter / seconds)) + "/s \t" + ((counter * 200 + 1) / sum / 2) + "% \t" + entry.getValue()); + } + } + out.println(format.format((long) (sum / seconds)) + "/s: total"); + } else { + out.println("=========== " + group + " (dynamic counters):"); + for (Map.Entry<Long, String> entry : sorted.entrySet()) { + long counter = entry.getKey() / array.length; + if (counter >= cutoff) { + out.println(format.format(counter) + " \t" + ((counter * 200 + 1) / sum / 2) + "% \t" + entry.getValue()); + } + } + out.println(format.format(sum) + ": total"); + } + } + } + } + + public abstract static class CallbackOutputStream extends OutputStream { + + protected final PrintStream delegate; + private final byte[][] patterns; + private final int[] positions; + + public CallbackOutputStream(PrintStream delegate, String... patterns) { + this.delegate = delegate; + this.positions = new int[patterns.length]; + this.patterns = new byte[patterns.length][]; + for (int i = 0; i < patterns.length; i++) { + this.patterns[i] = patterns[i].getBytes(); + } + } + + protected abstract void patternFound(int index); + + @Override + public void write(int b) throws IOException { + try { + delegate.write(b); + for (int i = 0; i < patterns.length; i++) { + int j = positions[i]; + byte[] cs = patterns[i]; + byte patternChar = cs[j]; + if (patternChar == '~' && Character.isDigit(b)) { + // nothing to do... + } else { + if (patternChar == '~') { + patternChar = cs[++positions[i]]; + } + if (b == patternChar) { + positions[i]++; + } else { + positions[i] = 0; + } + } + if (positions[i] == patterns[i].length) { + positions[i] = 0; + patternFound(i); + } + } + } catch (RuntimeException e) { + e.printStackTrace(delegate); + throw e; + } + } + } + + public static void initialize(final CompilerToVM compilerToVM) { + final class BenchmarkCountersOutputStream extends CallbackOutputStream { + + private long startTime; + private boolean waitingForEnd; + + private BenchmarkCountersOutputStream(PrintStream delegate, String start, String end) { + super(delegate, new String[]{start, end, "\n"}); + } + + @Override + protected void patternFound(int index) { + switch (index) { + case 0: + startTime = System.nanoTime(); + BenchmarkCounters.clear(compilerToVM.collectCounters()); + break; + case 1: + waitingForEnd = true; + break; + case 2: + if (waitingForEnd) { + waitingForEnd = false; + BenchmarkCounters.dump(delegate, (System.nanoTime() - startTime) / 1000000000d, compilerToVM.collectCounters()); + } + break; + } + } + } + + if (Options.BenchmarkDynamicCounters.getValue() != null) { + String[] arguments = Options.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)"); + } + for (int i = 0; i < arguments.length; i += 3) { + if (arguments[i].equals("err")) { + System.setErr(new PrintStream(new BenchmarkCountersOutputStream(System.err, arguments[i + 1], arguments[i + 2]))); + } else if (arguments[i].equals("out")) { + System.setOut(new PrintStream(new BenchmarkCountersOutputStream(System.out, arguments[i + 1], arguments[i + 2]))); + } else { + throw new GraalInternalError("invalid arguments to BenchmarkDynamicCounters: err|out"); + } + } + excludedClassPrefix = "Lcom/oracle/graal/"; + enabled = true; + } + if (Options.GenericDynamicCounters.getValue()) { + enabled = true; + } + if (Options.GenericDynamicCounters.getValue() || Options.BenchmarkDynamicCounters.getValue() != null) { + clear(compilerToVM.collectCounters()); + } + } + + public static void shutdown(CompilerToVM compilerToVM, long compilerStartTime) { + if (Options.GenericDynamicCounters.getValue()) { + dump(System.out, (System.nanoTime() - compilerStartTime) / 1000000000d, compilerToVM.collectCounters()); + } + } + + public static void lower(DynamicCounterNode counter, HotSpotRuntime runtime) { + StructuredGraph graph = counter.graph(); + if (excludedClassPrefix == null || !counter.graph().method().getDeclaringClass().getName().startsWith(excludedClassPrefix)) { + HotSpotVMConfig config = runtime.config; + + ReadRegisterNode thread = graph.add(new ReadRegisterNode(runtime.threadRegister(), runtime.getTarget().wordKind, true, false)); + + int index = BenchmarkCounters.getIndex(counter); + if (index >= config.graalCountersSize) { + throw new GraalInternalError("too many counters, reduce number of counters or increase GRAAL_COUNTERS_SIZE (current value: " + config.graalCountersSize + ")"); + } + ConstantLocationNode location = ConstantLocationNode.create(LocationIdentity.ANY_LOCATION, Kind.Long, config.graalCountersThreadOffset + Unsafe.ARRAY_LONG_INDEX_SCALE * index, graph); + ReadNode read = graph.add(new ReadNode(thread, location, StampFactory.forKind(Kind.Long), BarrierType.NONE, false)); + IntegerAddNode add = graph.unique(new IntegerAddNode(Kind.Long, read, counter.getIncrement())); + WriteNode write = graph.add(new WriteNode(thread, add, location, BarrierType.NONE, false)); + + graph.addBeforeFixed(counter, thread); + graph.addBeforeFixed(counter, read); + graph.addBeforeFixed(counter, write); + } + graph.removeFixed(counter); + } +}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotNmethod.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotNmethod.java Fri Oct 11 17:21:14 2013 +0200 @@ -28,7 +28,6 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.graph.*; import com.oracle.graal.hotspot.bridge.*; /** @@ -47,20 +46,17 @@ private final HotSpotResolvedJavaMethod method; private final boolean isDefault; private final boolean isExternal; - private final Graph graph; - public HotSpotNmethod(HotSpotResolvedJavaMethod method, boolean isDefault, Graph graph) { + public HotSpotNmethod(HotSpotResolvedJavaMethod method, boolean isDefault) { this.method = method; this.isDefault = isDefault; this.isExternal = false; - this.graph = graph; } - public HotSpotNmethod(HotSpotResolvedJavaMethod method, boolean isDefault, boolean isExternal, Graph graph) { + public HotSpotNmethod(HotSpotResolvedJavaMethod method, boolean isDefault, boolean isExternal) { this.method = method; this.isDefault = isDefault; this.isExternal = isExternal; - this.graph = graph; } public boolean isDefault() { @@ -71,10 +67,6 @@ return isExternal; } - public Graph getGraph() { - return graph; - } - @Override public ResolvedJavaMethod getMethod() { return method; @@ -123,6 +115,15 @@ return true; } + public Object executeParallel(int dimX, int dimY, int dimZ, Object... args) throws InvalidInstalledCodeException { + assert checkArgs(args); + + assert isExternal(); // for now + + return graalRuntime().getCompilerToGPU().executeParallelMethodVarargs(dimX, dimY, dimZ, args, this); + + } + @Override public Object executeVarargs(Object... args) throws InvalidInstalledCodeException { assert checkArgs(args);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java Fri Oct 11 17:21:14 2013 +0200 @@ -99,7 +99,7 @@ ResolvedJavaMethod initMethod = null; try { Class<?> rjm = ResolvedJavaMethod.class; - makeGraphMethod = runtime.lookupJavaMethod(ReplacementsImpl.class.getDeclaredMethod("makeGraph", rjm, rjm, SnippetInliningPolicy.class)); + makeGraphMethod = runtime.lookupJavaMethod(ReplacementsImpl.class.getDeclaredMethod("makeGraph", rjm, rjm, SnippetInliningPolicy.class, boolean.class)); initMethod = runtime.lookupJavaMethod(SnippetTemplate.AbstractTemplates.class.getDeclaredMethod("template", Arguments.class)); } catch (NoSuchMethodException | SecurityException e) { throw new GraalInternalError(e); @@ -169,6 +169,12 @@ private static final String SystemClassName = "Ljava/lang/System;"; + /** + * {@inheritDoc} + * <p> + * The {@code value} field in {@link OptionValue} is considered constant if the type of + * {@code receiver} is (assignable to) {@link StableOptionValue}. + */ @Override public Constant readConstantValue(Constant receiver) { assert !AOTCompilation.getValue() || isCalledForSnippets() : receiver; @@ -198,6 +204,7 @@ } else { Class<?> clazz = object.getClass(); if (StableOptionValue.class.isAssignableFrom(clazz)) { + assert getName().equals("value") : "Unexpected field in " + StableOptionValue.class.getName() + " hierarchy:" + this; StableOptionValue<?> option = (StableOptionValue<?>) object; return Constant.forObject(option.getValue()); }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java Fri Oct 11 17:21:14 2013 +0200 @@ -345,7 +345,11 @@ @Override public ResolvedJavaMethod resolveMethod(ResolvedJavaMethod method) { assert method instanceof HotSpotMethod; - return (ResolvedJavaMethod) graalRuntime().getCompilerToVM().resolveMethod(this, method.getName(), ((HotSpotSignature) method.getSignature()).getMethodDescriptor()); + ResolvedJavaMethod res = (ResolvedJavaMethod) graalRuntime().getCompilerToVM().resolveMethod(this, method.getName(), ((HotSpotSignature) method.getSignature()).getMethodDescriptor()); + if (res == null || isAbstract(res.getModifiers())) { + return null; + } + return res; } @Override @@ -557,13 +561,14 @@ return result; } - /** - * Gets all methods and constructors declared by this class, including the {@code <clinit>} - * method if there is one. The latter is not made accessible via standard Java reflection. - */ - public ResolvedJavaMethod[] getMethods() { - HotSpotResolvedJavaMethod[] methods = graalRuntime().getCompilerToVM().getMethods(this); - return methods; + public ResolvedJavaMethod getClassInitializer() { + ResolvedJavaMethod[] methods = graalRuntime().getCompilerToVM().getMethods(this); + for (ResolvedJavaMethod m : methods) { + if (m.isClassInitializer()) { + return m; + } + } + return null; } @Override
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedPrimitiveType.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedPrimitiveType.java Fri Oct 11 17:21:14 2013 +0200 @@ -227,6 +227,11 @@ } @Override + public ResolvedJavaMethod getClassInitializer() { + return null; + } + + @Override public Constant newArray(int length) { return Constant.forObject(Array.newInstance(javaMirror, length)); }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java Fri Oct 11 17:21:14 2013 +0200 @@ -23,8 +23,8 @@ package com.oracle.graal.hotspot.meta; import static com.oracle.graal.api.code.CallingConvention.Type.*; -import static com.oracle.graal.api.code.DeoptimizationAction.*; import static com.oracle.graal.api.code.MemoryBarriers.*; +import static com.oracle.graal.api.meta.DeoptimizationAction.*; import static com.oracle.graal.api.meta.DeoptimizationReason.*; import static com.oracle.graal.api.meta.LocationIdentity.*; import static com.oracle.graal.graph.UnsafeAccess.*; @@ -74,6 +74,7 @@ import com.oracle.graal.hotspot.HotSpotForeignCallLinkage.Transition; import com.oracle.graal.hotspot.bridge.*; import com.oracle.graal.hotspot.bridge.CompilerToVM.CodeInstallResult; +import com.oracle.graal.hotspot.debug.*; import com.oracle.graal.hotspot.nodes.*; import com.oracle.graal.hotspot.phases.*; import com.oracle.graal.hotspot.replacements.*; @@ -82,6 +83,7 @@ import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.HeapAccess.BarrierType; import com.oracle.graal.nodes.calc.*; +import com.oracle.graal.nodes.debug.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind; @@ -89,14 +91,15 @@ import com.oracle.graal.nodes.type.*; import com.oracle.graal.nodes.virtual.*; import com.oracle.graal.phases.tiers.*; +import com.oracle.graal.phases.util.*; import com.oracle.graal.printer.*; import com.oracle.graal.replacements.*; import com.oracle.graal.word.*; /** - * HotSpot implementation of {@link GraalCodeCacheProvider}. + * HotSpot implementation of {@link LoweringProvider}. */ -public abstract class HotSpotRuntime implements GraalCodeCacheProvider, DisassemblerProvider, BytecodeDisassemblerProvider, SuitesProvider { +public abstract class HotSpotRuntime implements MetaAccessProvider, ConstantReflectionProvider, CodeCacheProvider, LoweringProvider, DisassemblerProvider, BytecodeDisassemblerProvider, SuitesProvider { 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); @@ -250,9 +253,9 @@ * cannot be re-executed. * @param killedLocations the memory locations killed by the foreign call */ - private void linkForeignCall(Replacements replacements, ForeignCallDescriptor descriptor, long address, boolean prependThread, Transition transition, boolean reexecutable, + private void linkForeignCall(Providers providers, ForeignCallDescriptor descriptor, long address, boolean prependThread, Transition transition, boolean reexecutable, LocationIdentity... killedLocations) { - ForeignCallStub stub = new ForeignCallStub(this, replacements, address, descriptor, prependThread, transition, reexecutable, killedLocations); + ForeignCallStub stub = new ForeignCallStub(providers, address, descriptor, prependThread, transition, reexecutable, killedLocations); HotSpotForeignCallLinkage linkage = stub.getLinkage(); HotSpotForeignCallLinkage targetLinkage = stub.getTargetLinkage(); linkage.setCompiledStub(stub); @@ -289,29 +292,31 @@ 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, r, target, registerStubCall(NEW_INSTANCE, REEXECUTABLE, NOT_LEAF, ANY_LOCATION))); - link(new NewArrayStub(this, r, target, registerStubCall(NEW_ARRAY, REEXECUTABLE, NOT_LEAF, INIT_LOCATION))); - link(new ExceptionHandlerStub(this, r, target, foreignCalls.get(EXCEPTION_HANDLER))); - link(new UnwindExceptionToCallerStub(this, r, target, registerStubCall(UNWIND_EXCEPTION_TO_CALLER, NOT_REEXECUTABLE, NOT_LEAF, ANY_LOCATION))); - link(new VerifyOopStub(this, r, target, registerStubCall(VERIFY_OOP, REEXECUTABLE, LEAF, NO_LOCATIONS))); + Providers providers = new Providers(this, this, this, this, r); + + link(new NewInstanceStub(providers, target, registerStubCall(NEW_INSTANCE, REEXECUTABLE, NOT_LEAF, ANY_LOCATION))); + link(new NewArrayStub(providers, target, registerStubCall(NEW_ARRAY, REEXECUTABLE, NOT_LEAF, INIT_LOCATION))); + link(new ExceptionHandlerStub(providers, target, foreignCalls.get(EXCEPTION_HANDLER))); + link(new UnwindExceptionToCallerStub(providers, target, registerStubCall(UNWIND_EXCEPTION_TO_CALLER, NOT_REEXECUTABLE, NOT_LEAF, ANY_LOCATION))); + link(new VerifyOopStub(providers, target, registerStubCall(VERIFY_OOP, REEXECUTABLE, LEAF, NO_LOCATIONS))); - linkForeignCall(r, IDENTITY_HASHCODE, c.identityHashCodeAddress, PREPEND_THREAD, NOT_LEAF, NOT_REEXECUTABLE, MARK_WORD_LOCATION); - linkForeignCall(r, REGISTER_FINALIZER, c.registerFinalizerAddress, PREPEND_THREAD, NOT_LEAF, NOT_REEXECUTABLE, ANY_LOCATION); - linkForeignCall(r, CREATE_NULL_POINTER_EXCEPTION, c.createNullPointerExceptionAddress, PREPEND_THREAD, NOT_LEAF, REEXECUTABLE, ANY_LOCATION); - linkForeignCall(r, CREATE_OUT_OF_BOUNDS_EXCEPTION, c.createOutOfBoundsExceptionAddress, PREPEND_THREAD, NOT_LEAF, REEXECUTABLE, ANY_LOCATION); - linkForeignCall(r, MONITORENTER, c.monitorenterAddress, PREPEND_THREAD, NOT_LEAF, NOT_REEXECUTABLE, ANY_LOCATION); - linkForeignCall(r, MONITOREXIT, c.monitorexitAddress, PREPEND_THREAD, NOT_LEAF, NOT_REEXECUTABLE, ANY_LOCATION); - linkForeignCall(r, NEW_MULTI_ARRAY, c.newMultiArrayAddress, PREPEND_THREAD, NOT_LEAF, REEXECUTABLE, INIT_LOCATION); - linkForeignCall(r, DYNAMIC_NEW_ARRAY, c.dynamicNewArrayAddress, PREPEND_THREAD, NOT_LEAF, REEXECUTABLE, INIT_LOCATION); - linkForeignCall(r, LOG_PRINTF, c.logPrintfAddress, PREPEND_THREAD, LEAF, REEXECUTABLE, NO_LOCATIONS); - linkForeignCall(r, LOG_OBJECT, c.logObjectAddress, PREPEND_THREAD, NOT_LEAF, REEXECUTABLE, NO_LOCATIONS); - linkForeignCall(r, LOG_PRIMITIVE, c.logPrimitiveAddress, PREPEND_THREAD, NOT_LEAF, REEXECUTABLE, NO_LOCATIONS); - linkForeignCall(r, THREAD_IS_INTERRUPTED, c.threadIsInterruptedAddress, PREPEND_THREAD, NOT_LEAF, NOT_REEXECUTABLE, ANY_LOCATION); - linkForeignCall(r, VM_ERROR, c.vmErrorAddress, PREPEND_THREAD, LEAF, REEXECUTABLE, NO_LOCATIONS); - linkForeignCall(r, OSR_MIGRATION_END, c.osrMigrationEndAddress, DONT_PREPEND_THREAD, LEAF, NOT_REEXECUTABLE, NO_LOCATIONS); - linkForeignCall(r, G1WBPRECALL, c.writeBarrierPreAddress, PREPEND_THREAD, LEAF, REEXECUTABLE, NO_LOCATIONS); - linkForeignCall(r, G1WBPOSTCALL, c.writeBarrierPostAddress, PREPEND_THREAD, LEAF, REEXECUTABLE, NO_LOCATIONS); - linkForeignCall(r, VALIDATE_OBJECT, c.validateObject, PREPEND_THREAD, LEAF, REEXECUTABLE, NO_LOCATIONS); + linkForeignCall(providers, IDENTITY_HASHCODE, c.identityHashCodeAddress, PREPEND_THREAD, NOT_LEAF, NOT_REEXECUTABLE, MARK_WORD_LOCATION); + linkForeignCall(providers, REGISTER_FINALIZER, c.registerFinalizerAddress, PREPEND_THREAD, NOT_LEAF, NOT_REEXECUTABLE, ANY_LOCATION); + linkForeignCall(providers, CREATE_NULL_POINTER_EXCEPTION, c.createNullPointerExceptionAddress, PREPEND_THREAD, NOT_LEAF, REEXECUTABLE, ANY_LOCATION); + linkForeignCall(providers, CREATE_OUT_OF_BOUNDS_EXCEPTION, c.createOutOfBoundsExceptionAddress, PREPEND_THREAD, NOT_LEAF, REEXECUTABLE, ANY_LOCATION); + linkForeignCall(providers, MONITORENTER, c.monitorenterAddress, PREPEND_THREAD, NOT_LEAF, NOT_REEXECUTABLE, ANY_LOCATION); + linkForeignCall(providers, MONITOREXIT, c.monitorexitAddress, PREPEND_THREAD, NOT_LEAF, NOT_REEXECUTABLE, ANY_LOCATION); + linkForeignCall(providers, NEW_MULTI_ARRAY, c.newMultiArrayAddress, PREPEND_THREAD, NOT_LEAF, REEXECUTABLE, INIT_LOCATION); + linkForeignCall(providers, DYNAMIC_NEW_ARRAY, c.dynamicNewArrayAddress, PREPEND_THREAD, NOT_LEAF, REEXECUTABLE, INIT_LOCATION); + linkForeignCall(providers, LOG_PRINTF, c.logPrintfAddress, PREPEND_THREAD, LEAF, REEXECUTABLE, NO_LOCATIONS); + linkForeignCall(providers, LOG_OBJECT, c.logObjectAddress, PREPEND_THREAD, NOT_LEAF, REEXECUTABLE, NO_LOCATIONS); + linkForeignCall(providers, LOG_PRIMITIVE, c.logPrimitiveAddress, PREPEND_THREAD, NOT_LEAF, REEXECUTABLE, NO_LOCATIONS); + linkForeignCall(providers, THREAD_IS_INTERRUPTED, c.threadIsInterruptedAddress, PREPEND_THREAD, NOT_LEAF, NOT_REEXECUTABLE, ANY_LOCATION); + linkForeignCall(providers, VM_ERROR, c.vmErrorAddress, PREPEND_THREAD, LEAF, REEXECUTABLE, NO_LOCATIONS); + linkForeignCall(providers, OSR_MIGRATION_END, c.osrMigrationEndAddress, DONT_PREPEND_THREAD, LEAF, NOT_REEXECUTABLE, NO_LOCATIONS); + linkForeignCall(providers, G1WBPRECALL, c.writeBarrierPreAddress, PREPEND_THREAD, LEAF, REEXECUTABLE, NO_LOCATIONS); + linkForeignCall(providers, G1WBPOSTCALL, c.writeBarrierPostAddress, PREPEND_THREAD, LEAF, REEXECUTABLE, NO_LOCATIONS); + linkForeignCall(providers, VALIDATE_OBJECT, c.validateObject, PREPEND_THREAD, LEAF, REEXECUTABLE, NO_LOCATIONS); r.registerSubstitutions(ObjectSubstitutions.class); r.registerSubstitutions(SystemSubstitutions.class); @@ -323,16 +328,16 @@ r.registerSubstitutions(CRC32Substitutions.class); r.registerSubstitutions(ReflectionSubstitutions.class); - checkcastDynamicSnippets = new CheckCastDynamicSnippets.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()); - unsafeLoadSnippets = new UnsafeLoadSnippets.Templates(this, r, graalRuntime.getTarget()); + checkcastDynamicSnippets = new CheckCastDynamicSnippets.Templates(providers, graalRuntime.getTarget()); + instanceofSnippets = new InstanceOfSnippets.Templates(providers, graalRuntime.getTarget()); + newObjectSnippets = new NewObjectSnippets.Templates(providers, graalRuntime.getTarget()); + monitorSnippets = new MonitorSnippets.Templates(providers, graalRuntime.getTarget(), c.useFastLocking); + writeBarrierSnippets = new WriteBarrierSnippets.Templates(providers, graalRuntime.getTarget()); + boxingSnippets = new BoxingSnippets.Templates(providers, graalRuntime.getTarget()); + exceptionObjectSnippets = new LoadExceptionObjectSnippets.Templates(providers, graalRuntime.getTarget()); + unsafeLoadSnippets = new UnsafeLoadSnippets.Templates(providers, graalRuntime.getTarget()); - r.registerSnippetTemplateCache(new UnsafeArrayCopySnippets.Templates(this, r, graalRuntime.getTarget())); + r.registerSnippetTemplateCache(new UnsafeArrayCopySnippets.Templates(providers, graalRuntime.getTarget())); } public HotSpotGraalRuntime getGraalRuntime() { @@ -467,7 +472,7 @@ } @Override - public RegisterConfig lookupRegisterConfig() { + public RegisterConfig getRegisterConfig() { return regConfig; } @@ -554,7 +559,7 @@ ValueNode object = loadField.isStatic() ? ConstantNode.forObject(field.getDeclaringClass().mirror(), this, graph) : loadField.object(); assert loadField.kind() != Kind.Illegal; BarrierType barrierType = getFieldLoadBarrierType(field); - ReadNode memoryRead = graph.add(new ReadNode(object, createFieldLocation(graph, field), loadField.stamp(), barrierType, (loadField.kind() == Kind.Object))); + ReadNode memoryRead = graph.add(new ReadNode(object, createFieldLocation(graph, field, false), loadField.stamp(), barrierType, (loadField.kind() == Kind.Object))); graph.replaceFixedWithFixed(loadField, memoryRead); tool.createNullCheckGuard(memoryRead, object); @@ -569,7 +574,7 @@ HotSpotResolvedJavaField field = (HotSpotResolvedJavaField) storeField.field(); ValueNode object = storeField.isStatic() ? ConstantNode.forObject(field.getDeclaringClass().mirror(), this, graph) : storeField.object(); BarrierType barrierType = getFieldStoreBarrierType(storeField); - WriteNode memoryWrite = graph.add(new WriteNode(object, storeField.value(), createFieldLocation(graph, field), barrierType, storeField.field().getKind() == Kind.Object)); + WriteNode memoryWrite = graph.add(new WriteNode(object, storeField.value(), createFieldLocation(graph, field, false), barrierType, storeField.field().getKind() == Kind.Object)); tool.createNullCheckGuard(memoryWrite, object); memoryWrite.setStateAfter(storeField.stateAfter()); graph.replaceFixedWithFixed(storeField, memoryWrite); @@ -594,7 +599,7 @@ LoadIndexedNode loadIndexed = (LoadIndexedNode) n; GuardingNode boundsCheck = createBoundsCheck(loadIndexed, tool); Kind elementKind = loadIndexed.elementKind(); - LocationNode arrayLocation = createArrayLocation(graph, elementKind, loadIndexed.index()); + LocationNode arrayLocation = createArrayLocation(graph, elementKind, loadIndexed.index(), false); ReadNode memoryRead = graph.add(new ReadNode(loadIndexed.array(), arrayLocation, loadIndexed.stamp(), BarrierType.NONE, elementKind == Kind.Object)); memoryRead.setGuard(boundsCheck); graph.replaceFixedWithFixed(loadIndexed, memoryRead); @@ -602,7 +607,7 @@ StoreIndexedNode storeIndexed = (StoreIndexedNode) n; GuardingNode boundsCheck = createBoundsCheck(storeIndexed, tool); Kind elementKind = storeIndexed.elementKind(); - LocationNode arrayLocation = createArrayLocation(graph, elementKind, storeIndexed.index()); + LocationNode arrayLocation = createArrayLocation(graph, elementKind, storeIndexed.index(), false); ValueNode value = storeIndexed.value(); ValueNode array = storeIndexed.array(); @@ -645,14 +650,22 @@ checkcastDynamicSnippets.lower(checkcastDynamicNode); } } else if (n instanceof UnsafeLoadNode) { - if (graph.getGuardsStage().ordinal() > StructuredGraph.GuardsStage.FLOATING_GUARDS.ordinal()) { - UnsafeLoadNode load = (UnsafeLoadNode) n; + UnsafeLoadNode load = (UnsafeLoadNode) n; + if (load.getGuardingCondition() != null) { + boolean compressible = (!load.object().isNullConstant() && load.accessKind() == Kind.Object); + ConditionAnchorNode valueAnchorNode = graph.add(new ConditionAnchorNode(load.getGuardingCondition())); + LocationNode location = createLocation(load); + ReadNode memoryRead = graph.add(new ReadNode(load.object(), location, load.stamp(), valueAnchorNode, BarrierType.NONE, compressible)); + load.replaceAtUsages(memoryRead); + graph.replaceFixedWithFixed(load, valueAnchorNode); + graph.addAfterFixed(valueAnchorNode, memoryRead); + } else if (graph.getGuardsStage().ordinal() > StructuredGraph.GuardsStage.FLOATING_GUARDS.ordinal()) { assert load.kind() != Kind.Illegal; boolean compressible = (!load.object().isNullConstant() && load.accessKind() == Kind.Object); if (addReadBarrier(load)) { unsafeLoadSnippets.lower(load, tool); } else { - IndexedLocationNode location = IndexedLocationNode.create(ANY_LOCATION, load.accessKind(), load.displacement(), load.offset(), graph, 1); + LocationNode location = createLocation(load); ReadNode memoryRead = graph.add(new ReadNode(load.object(), location, load.stamp(), BarrierType.NONE, compressible)); // An unsafe read must not float outside its block otherwise // it may float above an explicit null check on its object. @@ -662,7 +675,7 @@ } } else if (n instanceof UnsafeStoreNode) { UnsafeStoreNode store = (UnsafeStoreNode) n; - IndexedLocationNode location = IndexedLocationNode.create(ANY_LOCATION, store.accessKind(), store.displacement(), store.offset(), graph, 1); + LocationNode location = createLocation(store); ValueNode object = store.object(); BarrierType barrierType = getUnsafeStoreBarrierType(store); WriteNode write = graph.add(new WriteNode(object, store.value(), location, barrierType, store.value().kind() == Kind.Object)); @@ -717,7 +730,7 @@ value = allocations[commit.getVirtualObjects().indexOf(value)]; } if (!(value.isConstant() && value.asConstant().isDefaultForKind())) { - WriteNode write = new WriteNode(newObject, value, createFieldLocation(graph, (HotSpotResolvedJavaField) virtualInstance.field(i)), + WriteNode write = new WriteNode(newObject, value, createFieldLocation(graph, (HotSpotResolvedJavaField) virtualInstance.field(i), true), (virtualInstance.field(i).getKind() == Kind.Object && !deferInitBarrier(newObject)) ? BarrierType.IMPRECISE : BarrierType.NONE, virtualInstance.field(i).getKind() == Kind.Object); graph.addBeforeFixed(commit, graph.add(write)); @@ -735,7 +748,7 @@ value = allocations[indexOf]; } if (!(value.isConstant() && value.asConstant().isDefaultForKind())) { - WriteNode write = new WriteNode(newObject, value, createArrayLocation(graph, element.getKind(), ConstantNode.forInt(i, graph)), + WriteNode write = new WriteNode(newObject, value, createArrayLocation(graph, element.getKind(), ConstantNode.forInt(i, graph), true), (value.kind() == Kind.Object && !deferInitBarrier(newObject)) ? BarrierType.PRECISE : BarrierType.NONE, value.kind() == Kind.Object); graph.addBeforeFixed(commit, graph.add(write)); } @@ -788,6 +801,10 @@ osrStart.replaceAtUsages(newStart); osrStart.safeDelete(); } + } else if (n instanceof DynamicCounterNode) { + if (graph.getGuardsStage() == StructuredGraph.GuardsStage.AFTER_FSA) { + BenchmarkCounters.lower((DynamicCounterNode) n, this); + } } else if (n instanceof CheckCastDynamicNode) { checkcastDynamicSnippets.lower((CheckCastDynamicNode) n); } else if (n instanceof InstanceOfNode) { @@ -851,6 +868,43 @@ } } + private static LocationNode createLocation(UnsafeAccessNode access) { + ValueNode offset = access.offset(); + if (offset.isConstant()) { + long offsetValue = offset.asConstant().asLong(); + return ConstantLocationNode.create(access.getLocationIdentity(), access.accessKind(), offsetValue, access.graph()); + } + + long displacement = 0; + int indexScaling = 1; + if (offset instanceof IntegerAddNode) { + IntegerAddNode integerAddNode = (IntegerAddNode) offset; + if (integerAddNode.y() instanceof ConstantNode) { + displacement = integerAddNode.y().asConstant().asLong(); + offset = integerAddNode.x(); + } + } + + if (offset instanceof LeftShiftNode) { + LeftShiftNode leftShiftNode = (LeftShiftNode) offset; + if (leftShiftNode.y() instanceof ConstantNode) { + long shift = leftShiftNode.y().asConstant().asLong(); + if (shift >= 1 && shift <= 3) { + if (shift == 1) { + indexScaling = 2; + } else if (shift == 2) { + indexScaling = 4; + } else { + indexScaling = 8; + } + offset = leftShiftNode.x(); + } + } + } + + return IndexedLocationNode.create(access.getLocationIdentity(), access.accessKind(), displacement, offset, access.graph(), indexScaling); + } + private static boolean addReadBarrier(UnsafeLoadNode load) { if (useG1GC() && load.graph().getGuardsStage() == StructuredGraph.GuardsStage.FIXED_DEOPTS && load.object().kind() == Kind.Object && load.accessKind() == Kind.Object && !ObjectStamp.isObjectAlwaysNull(load.object())) { @@ -941,8 +995,9 @@ return barrierType; } - protected static ConstantLocationNode createFieldLocation(StructuredGraph graph, HotSpotResolvedJavaField field) { - return ConstantLocationNode.create(field, field.getKind(), field.offset(), graph); + protected static ConstantLocationNode createFieldLocation(StructuredGraph graph, HotSpotResolvedJavaField field, boolean initialization) { + LocationIdentity loc = initialization ? INIT_LOCATION : field; + return ConstantLocationNode.create(loc, field.getKind(), field.offset(), graph); } public int getScalingFactor(Kind kind) { @@ -953,9 +1008,10 @@ } } - protected IndexedLocationNode createArrayLocation(Graph graph, Kind elementKind, ValueNode index) { + protected IndexedLocationNode createArrayLocation(Graph graph, Kind elementKind, ValueNode index, boolean initialization) { + LocationIdentity loc = initialization ? INIT_LOCATION : NamedLocationIdentity.getArrayLocation(elementKind); int scale = getScalingFactor(elementKind); - return IndexedLocationNode.create(NamedLocationIdentity.getArrayLocation(elementKind), elementKind, getArrayBaseOffset(elementKind), index, graph, scale); + return IndexedLocationNode.create(loc, elementKind, getArrayBaseOffset(elementKind), index, graph, scale); } @Override @@ -999,7 +1055,7 @@ private GuardingNode createBoundsCheck(AccessIndexedNode n, LoweringTool tool) { StructuredGraph g = n.graph(); ValueNode array = n.array(); - ValueNode arrayLength = readArrayLength(array, tool.getRuntime()); + ValueNode arrayLength = readArrayLength(array, tool.getConstantReflection()); if (arrayLength == null) { Stamp stamp = StampFactory.positiveInt(); ReadNode readArrayLength = g.add(new ReadNode(array, ConstantLocationNode.create(FINAL_LOCATION, Kind.Int, config.arrayLengthOffset, g), stamp, BarrierType.NONE, false)); @@ -1012,6 +1068,9 @@ } public ResolvedJavaType lookupJavaType(Class<?> clazz) { + if (clazz == null) { + throw new IllegalArgumentException("Class parameter was null"); + } return HotSpotResolvedObjectType.fromClass(clazz); } @@ -1043,20 +1102,15 @@ } public HotSpotInstalledCode installMethod(HotSpotResolvedJavaMethod method, int entryBCI, CompilationResult compResult) { - HotSpotInstalledCode installedCode = new HotSpotNmethod(method, true, null); + HotSpotInstalledCode installedCode = new HotSpotNmethod(method, true); graalRuntime.getCompilerToVM().installCode(new HotSpotCompiledNmethod(method, entryBCI, compResult), installedCode, method.getSpeculationLog()); return installedCode; } @Override public InstalledCode addMethod(ResolvedJavaMethod method, CompilationResult compResult) { - return addMethod(method, compResult, null); - } - - @Override - public InstalledCode addMethod(ResolvedJavaMethod method, CompilationResult compResult, Graph graph) { HotSpotResolvedJavaMethod hotspotMethod = (HotSpotResolvedJavaMethod) method; - HotSpotInstalledCode code = new HotSpotNmethod(hotspotMethod, false, graph); + HotSpotInstalledCode code = new HotSpotNmethod(hotspotMethod, false); CodeInstallResult result = graalRuntime.getCompilerToVM().installCode(new HotSpotCompiledNmethod(hotspotMethod, -1, compResult), code, null); if (result != CodeInstallResult.OK) { return null; @@ -1064,12 +1118,10 @@ return code; } - public InstalledCode addExternalMethod(ResolvedJavaMethod method, CompilationResult compResult, Graph graph) { - - // compResult.getTargetCode() == assembled PTX method string + public InstalledCode addExternalMethod(ResolvedJavaMethod method, CompilationResult compResult) { HotSpotResolvedJavaMethod javaMethod = (HotSpotResolvedJavaMethod) method; - HotSpotInstalledCode icode = new HotSpotNmethod(javaMethod, false, true, graph); + HotSpotInstalledCode icode = new HotSpotNmethod(javaMethod, false, true); HotSpotCompiledNmethod compiled = new HotSpotCompiledNmethod(javaMethod, -1, compResult); CompilerToVM vm = graalRuntime.getCompilerToVM(); CodeInstallResult result = vm.installCode(compiled, icode, null); @@ -1080,13 +1132,13 @@ } @Override - public int encodeDeoptActionAndReason(DeoptimizationAction action, DeoptimizationReason reason) { + public Constant encodeDeoptActionAndReason(DeoptimizationAction action, DeoptimizationReason reason) { final int actionShift = 0; final int reasonShift = 3; int actionValue = convertDeoptAction(action); int reasonValue = convertDeoptReason(reason); - return (~(((reasonValue) << reasonShift) + ((actionValue) << actionShift))); + return Constant.forInt(~(((reasonValue) << reasonShift) + ((actionValue) << actionShift))); } public int convertDeoptAction(DeoptimizationAction action) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassCastNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassCastNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -22,11 +22,12 @@ */ package com.oracle.graal.hotspot.nodes; +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.hotspot.replacements.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.java.*; -import com.oracle.graal.nodes.spi.*; import com.oracle.graal.replacements.nodes.*; /** @@ -48,7 +49,8 @@ return arguments.get(1); } - public ValueNode canonical(CanonicalizerTool tool) { + @Override + public Node canonical(CanonicalizerTool tool) { ValueNode javaClass = getJavaClass(); if (javaClass.isConstant()) { ValueNode object = getObject();
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassGetComponentTypeNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassGetComponentTypeNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -22,9 +22,10 @@ */ package com.oracle.graal.hotspot.nodes; +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.hotspot.replacements.*; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.spi.*; import com.oracle.graal.replacements.nodes.*; /** @@ -42,13 +43,14 @@ return arguments.get(0); } - public ValueNode canonical(CanonicalizerTool tool) { + @Override + public Node canonical(CanonicalizerTool tool) { ValueNode javaClass = getJavaClass(); if (javaClass.isConstant()) { Class c = (Class) javaClass.asConstant().asObject(); if (c != null) { Class componentType = c.getComponentType(); - return ConstantNode.forObject(componentType, tool.runtime(), graph()); + return ConstantNode.forObject(componentType, tool.getMetaAccess(), graph()); } } return this;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassGetModifiersNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassGetModifiersNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -22,9 +22,10 @@ */ package com.oracle.graal.hotspot.nodes; +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.hotspot.replacements.*; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.spi.*; import com.oracle.graal.replacements.nodes.*; /** @@ -42,7 +43,8 @@ return arguments.get(0); } - public ValueNode canonical(CanonicalizerTool tool) { + @Override + public Node canonical(CanonicalizerTool tool) { ValueNode javaClass = getJavaClass(); if (javaClass.isConstant()) { Class c = (Class) javaClass.asConstant().asObject();
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassGetSuperclassNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassGetSuperclassNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -22,9 +22,10 @@ */ package com.oracle.graal.hotspot.nodes; +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.hotspot.replacements.*; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.spi.*; import com.oracle.graal.replacements.nodes.*; /** @@ -42,13 +43,14 @@ return arguments.get(0); } - public ValueNode canonical(CanonicalizerTool tool) { + @Override + public Node canonical(CanonicalizerTool tool) { ValueNode javaClass = getJavaClass(); if (javaClass.isConstant()) { Class c = (Class) javaClass.asConstant().asObject(); if (c != null) { Class superclass = c.getSuperclass(); - return ConstantNode.forObject(superclass, tool.runtime(), graph()); + return ConstantNode.forObject(superclass, tool.getMetaAccess(), graph()); } } return this;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassIsArrayNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassIsArrayNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -22,9 +22,10 @@ */ package com.oracle.graal.hotspot.nodes; +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.hotspot.replacements.*; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.spi.*; import com.oracle.graal.replacements.nodes.*; /** @@ -42,7 +43,8 @@ return arguments.get(0); } - public ValueNode canonical(CanonicalizerTool tool) { + @Override + public Node canonical(CanonicalizerTool tool) { ValueNode javaClass = getJavaClass(); if (javaClass.isConstant()) { Class c = (Class) javaClass.asConstant().asObject();
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassIsInstanceNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassIsInstanceNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -22,12 +22,13 @@ */ package com.oracle.graal.hotspot.nodes; +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.hotspot.replacements.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.java.*; -import com.oracle.graal.nodes.spi.*; import com.oracle.graal.replacements.nodes.*; /** @@ -49,7 +50,8 @@ return arguments.get(1); } - public ValueNode canonical(CanonicalizerTool tool) { + @Override + public Node canonical(CanonicalizerTool tool) { ValueNode javaClass = getJavaClass(); if (javaClass.isConstant()) { ValueNode object = getObject();
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassIsInterfaceNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassIsInterfaceNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -22,9 +22,10 @@ */ package com.oracle.graal.hotspot.nodes; +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.hotspot.replacements.*; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.spi.*; import com.oracle.graal.replacements.nodes.*; /** @@ -42,7 +43,8 @@ return arguments.get(0); } - public ValueNode canonical(CanonicalizerTool tool) { + @Override + public Node canonical(CanonicalizerTool tool) { ValueNode javaClass = getJavaClass(); if (javaClass.isConstant()) { Class c = (Class) javaClass.asConstant().asObject();
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassIsPrimitiveNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassIsPrimitiveNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -22,9 +22,10 @@ */ package com.oracle.graal.hotspot.nodes; +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.hotspot.replacements.*; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.spi.*; import com.oracle.graal.replacements.nodes.*; /** @@ -42,7 +43,8 @@ return arguments.get(0); } - public ValueNode canonical(CanonicalizerTool tool) { + @Override + public Node canonical(CanonicalizerTool tool) { ValueNode javaClass = getJavaClass(); if (javaClass.isConstant()) { Class c = (Class) javaClass.asConstant().asObject();
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/DeoptimizeCallerNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/DeoptimizeCallerNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -22,7 +22,6 @@ */ 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.hotspot.*;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/DeoptimizingStubCall.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/DeoptimizingStubCall.java Fri Oct 11 17:21:14 2013 +0200 @@ -22,7 +22,6 @@ */ package com.oracle.graal.hotspot.nodes; -import com.oracle.graal.api.meta.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.type.*; @@ -36,9 +35,4 @@ public boolean canDeoptimize() { return true; } - - @Override - public DeoptimizationReason getDeoptimizationReason() { - return null; - } }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/G1PreWriteBarrier.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/G1PreWriteBarrier.java Fri Oct 11 17:21:14 2013 +0200 @@ -22,7 +22,6 @@ */ package com.oracle.graal.hotspot.nodes; -import com.oracle.graal.api.meta.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.extended.*; @@ -66,11 +65,6 @@ deoptimizationState = state; } - @Override - public DeoptimizationReason getDeoptimizationReason() { - return DeoptimizationReason.NullCheckException; - } - public FrameState getState() { return deoptimizationState; }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/MonitorExitStubCall.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/MonitorExitStubCall.java Fri Oct 11 17:21:14 2013 +0200 @@ -51,7 +51,7 @@ assert lockDepth != -1; HotSpotLIRGenerator hsGen = (HotSpotLIRGenerator) gen; StackSlot slot = hsGen.getLockSlot(lockDepth); - ForeignCallLinkage linkage = gen.getRuntime().lookupForeignCall(MonitorExitStubCall.MONITOREXIT); + ForeignCallLinkage linkage = gen.getCodeCache().lookupForeignCall(MonitorExitStubCall.MONITOREXIT); gen.emitForeignCall(linkage, this, gen.operand(object), gen.emitAddress(slot)); }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewArrayStubCall.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewArrayStubCall.java Fri Oct 11 17:21:14 2013 +0200 @@ -62,7 +62,7 @@ @Override public void generate(LIRGenerator gen) { - ForeignCallLinkage linkage = gen.getRuntime().lookupForeignCall(NEW_ARRAY); + ForeignCallLinkage linkage = gen.getCodeCache().lookupForeignCall(NEW_ARRAY); Variable result = gen.emitForeignCall(linkage, this, gen.operand(hub), gen.operand(length)); gen.setResult(this, result); }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewInstanceStubCall.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewInstanceStubCall.java Fri Oct 11 17:21:14 2013 +0200 @@ -60,7 +60,7 @@ @Override public void generate(LIRGenerator gen) { - ForeignCallLinkage linkage = gen.getRuntime().lookupForeignCall(NEW_INSTANCE); + ForeignCallLinkage linkage = gen.getCodeCache().lookupForeignCall(NEW_INSTANCE); Variable result = gen.emitForeignCall(linkage, this, gen.operand(hub)); gen.setResult(this, result); }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewMultiArrayStubCall.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewMultiArrayStubCall.java Fri Oct 11 17:21:14 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(MetaAccessProvider runtime, ValueNode hub, int rank, ValueNode dims) { - super(runtime, NEW_MULTI_ARRAY, defaultStamp); + public NewMultiArrayStubCall(MetaAccessProvider metaAccess, ValueNode hub, int rank, ValueNode dims) { + super(metaAccess, NEW_MULTI_ARRAY, defaultStamp); this.hub = hub; this.rank = rank; this.dims = dims;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/StubForeignCallNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/StubForeignCallNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -37,15 +37,15 @@ public class StubForeignCallNode extends FixedWithNextNode implements LIRLowerable, MemoryCheckpoint.Multi { @Input private final NodeInputList<ValueNode> arguments; - private final MetaAccessProvider runtime; + private final MetaAccessProvider metaAccess; private final ForeignCallDescriptor descriptor; - public StubForeignCallNode(MetaAccessProvider runtime, ForeignCallDescriptor descriptor, ValueNode... arguments) { + public StubForeignCallNode(MetaAccessProvider metaAccess, ForeignCallDescriptor descriptor, ValueNode... arguments) { super(StampFactory.forKind(Kind.fromJavaClass(descriptor.getResultType()))); this.arguments = new NodeInputList<>(this, arguments); this.descriptor = descriptor; - this.runtime = runtime; + this.metaAccess = metaAccess; } public ForeignCallDescriptor getDescriptor() { @@ -54,7 +54,7 @@ @Override public LocationIdentity[] getLocationIdentities() { - return runtime.getKilledLocations(descriptor); + return metaAccess.getKilledLocations(descriptor); } protected Value[] operands(LIRGeneratorTool gen) { @@ -68,7 +68,7 @@ @Override public void generate(LIRGeneratorTool gen) { assert graph().start() instanceof StubStartNode; - ForeignCallLinkage linkage = gen.getRuntime().lookupForeignCall(descriptor); + ForeignCallLinkage linkage = gen.getCodeCache().lookupForeignCall(descriptor); Value[] operands = operands(gen); Value result = gen.emitForeignCall(linkage, null, operands); if (result != null) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/VMErrorNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/VMErrorNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -57,7 +57,7 @@ Constant whereArg = Constant.forObject(whereString.intern()); Constant formatArg = Constant.forObject(format.intern()); - ForeignCallLinkage linkage = gen.getRuntime().lookupForeignCall(VMErrorNode.VM_ERROR); + ForeignCallLinkage linkage = gen.getCodeCache().lookupForeignCall(VMErrorNode.VM_ERROR); gen.emitForeignCall(linkage, null, whereArg, formatArg, gen.operand(value)); }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/WriteBarrier.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/WriteBarrier.java Fri Oct 11 17:21:14 2013 +0200 @@ -22,13 +22,12 @@ */ package com.oracle.graal.hotspot.nodes; -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.*; -public abstract class WriteBarrier extends FixedWithNextNode implements Lowerable, IterableNodeType { +public abstract class WriteBarrier extends FixedWithNextNode implements Lowerable { @Input private ValueNode object; @Input private ValueNode value; @@ -62,6 +61,6 @@ @Override public void lower(LoweringTool tool) { assert graph().getGuardsStage() == StructuredGraph.GuardsStage.AFTER_FSA; - tool.getRuntime().lower(this, tool); + tool.getLowerer().lower(this, tool); } }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/LoadJavaMirrorWithKlassPhase.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/LoadJavaMirrorWithKlassPhase.java Fri Oct 11 17:21:14 2013 +0200 @@ -51,10 +51,10 @@ for (ConstantNode node : graph.getNodes().filter(ConstantNode.class)) { Constant constant = node.asConstant(); if (constant.getKind() == Kind.Object && constant.asObject() instanceof Class<?>) { - ResolvedJavaType type = context.getRuntime().lookupJavaType((Class<?>) constant.asObject()); + ResolvedJavaType type = context.getMetaAccess().lookupJavaType((Class<?>) constant.asObject()); assert type instanceof HotSpotResolvedObjectType; - HotSpotRuntime runtime = (HotSpotRuntime) context.getRuntime(); + HotSpotRuntime runtime = (HotSpotRuntime) context.getMetaAccess(); Constant klass = ((HotSpotResolvedObjectType) type).klass(); ConstantNode klassNode = ConstantNode.forConstant(klass, runtime, graph);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/VerifyHotSpotOptionsPhase.java Fri Oct 11 17:14:35 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,154 +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.hotspot.phases; - -import static com.oracle.graal.api.meta.MetaUtil.*; -import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; -import static java.lang.reflect.Modifier.*; - -import java.util.*; - -import com.oracle.graal.api.meta.*; -import com.oracle.graal.graph.*; -import com.oracle.graal.hotspot.*; -import com.oracle.graal.hotspot.meta.*; -import com.oracle.graal.java.*; -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.java.*; -import com.oracle.graal.nodes.util.*; -import com.oracle.graal.options.*; -import com.oracle.graal.phases.*; - -/** - * Verifies that a class that declares one or more HotSpot {@linkplain OptionValue options} has a - * class initializer that only initializes the option(s). This sanity check prevents an option being - * read to initialize some global state before it is parsed on the command line. The latter occurs - * if an option declaring class has a class initializer that reads options or triggers other class - * initializers that read options. - */ -public class VerifyHotSpotOptionsPhase extends Phase { - - public static boolean checkOptions() { - HotSpotRuntime runtime = graalRuntime().getRuntime(); - ServiceLoader<Options> sl = ServiceLoader.loadInstalled(Options.class); - Set<HotSpotResolvedObjectType> checked = new HashSet<>(); - for (Options opts : sl) { - for (OptionDescriptor desc : opts) { - if (HotSpotOptions.isHotSpotOption(desc)) { - HotSpotResolvedObjectType holder = (HotSpotResolvedObjectType) runtime.lookupJavaType(desc.getDeclaringClass()); - checkType(holder, desc, runtime, checked); - } - } - } - return true; - } - - private static void checkType(HotSpotResolvedObjectType type, OptionDescriptor option, HotSpotRuntime runtime, Set<HotSpotResolvedObjectType> checked) { - if (!checked.contains(type)) { - checked.add(type); - HotSpotResolvedObjectType superType = type.getSupertype(); - if (superType != null && !MetaUtil.isJavaLangObject(superType)) { - checkType(superType, option, runtime, checked); - } - for (ResolvedJavaMethod method : type.getMethods()) { - if (method.isClassInitializer()) { - StructuredGraph graph = new StructuredGraph(method); - new GraphBuilderPhase(runtime, GraphBuilderConfiguration.getEagerDefault(), OptimisticOptimizations.ALL).apply(graph); - new VerifyHotSpotOptionsPhase(type, runtime, option).apply(graph); - } - } - } - } - - private final HotSpotRuntime runtime; - private final ResolvedJavaType declaringClass; - private final ResolvedJavaType optionValueType; - private final Set<ResolvedJavaType> boxingTypes; - private final OptionDescriptor option; - - public VerifyHotSpotOptionsPhase(ResolvedJavaType declaringClass, HotSpotRuntime runtime, OptionDescriptor option) { - this.runtime = runtime; - this.declaringClass = declaringClass; - this.optionValueType = runtime.lookupJavaType(OptionValue.class); - this.option = option; - this.boxingTypes = new HashSet<>(); - for (Class c : new Class[]{Boolean.class, Byte.class, Short.class, Character.class, Integer.class, Float.class, Long.class, Double.class}) { - this.boxingTypes.add(runtime.lookupJavaType(c)); - } - } - - /** - * Checks whether a given method is allowed to be called. - */ - private boolean checkInvokeTarget(ResolvedJavaMethod method) { - ResolvedJavaType holder = method.getDeclaringClass(); - if (method.isConstructor()) { - if (optionValueType.isAssignableFrom(holder)) { - return true; - } - } else if (boxingTypes.contains(holder)) { - return method.getName().equals("valueOf"); - } else if (method.getDeclaringClass() == runtime.lookupJavaType(Class.class)) { - return method.getName().equals("desiredAssertionStatus"); - } else if (method.getDeclaringClass().equals(declaringClass)) { - return (method.getName().equals("$jacocoInit")); - } - return false; - } - - @Override - protected void run(StructuredGraph graph) { - for (ValueNode node : graph.getNodes().filter(ValueNode.class)) { - if (node instanceof StoreFieldNode) { - HotSpotResolvedJavaField field = (HotSpotResolvedJavaField) ((StoreFieldNode) node).field(); - verify(field.getDeclaringClass() == declaringClass, node, "store to field " + format("%H.%n", field)); - verify(isStatic(field.getModifiers()), node, "store to field " + format("%H.%n", field)); - if (optionValueType.isAssignableFrom((ResolvedJavaType) field.getType())) { - verify(isFinal(field.getModifiers()), node, "option field " + format("%H.%n", field) + " not final"); - } else { - verify((field.isSynthetic()), node, "store to non-synthetic field " + format("%H.%n", field)); - } - } else if (node instanceof Invoke) { - Invoke invoke = (Invoke) node; - MethodCallTargetNode callTarget = (MethodCallTargetNode) invoke.callTarget(); - ResolvedJavaMethod targetMethod = callTarget.targetMethod(); - verify(checkInvokeTarget(targetMethod), node, "invocation of " + format("%H.%n(%p)", targetMethod)); - } - } - } - - private void verify(boolean condition, Node node, String message) { - if (!condition) { - error(node, message); - } - } - - private void error(Node node, String message) { - String loc = GraphUtil.approxSourceLocation(node); - throw new GraalInternalError(String.format("The " + option.getName() + " option is declared in " + option.getDeclaringClass() + - " whose class hierarchy contains a class initializer (in %s) with a code pattern at or near %s implying an action other than initialization of an option:%n%n %s%n%n" + - "The recommended solution is to move " + option.getName() + " into a separate class (e.g., " + option.getDeclaringClass().getName() + ".Options).%n", - toJavaName(declaringClass), loc, message)); - } -}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/AESCryptSubstitutions.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/AESCryptSubstitutions.java Fri Oct 11 17:21:14 2013 +0200 @@ -66,7 +66,7 @@ } private static void crypt(Object rcvr, byte[] in, int inOffset, byte[] out, int outOffset, boolean encrypt) { - Object kObject = UnsafeLoadNode.load(rcvr, 0, kOffset, Kind.Object); + Object kObject = UnsafeLoadNode.load(rcvr, 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);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/AbstractMethodHandleNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/AbstractMethodHandleNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -32,6 +32,7 @@ import com.oracle.graal.api.meta.ResolvedJavaType; import com.oracle.graal.graph.GraalInternalError; import com.oracle.graal.graph.NodeInputList; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.hotspot.meta.HotSpotResolvedJavaMethod; import com.oracle.graal.hotspot.meta.HotSpotResolvedObjectType; import com.oracle.graal.hotspot.meta.HotSpotSignature; @@ -43,7 +44,6 @@ import com.oracle.graal.nodes.java.MethodCallTargetNode; import com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind; import com.oracle.graal.nodes.java.SelfReplacingMethodCallTargetNode; -import com.oracle.graal.nodes.spi.Canonicalizable; import com.oracle.graal.nodes.type.*; import com.oracle.graal.replacements.nodes.MacroNode;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopyNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopyNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -75,7 +75,7 @@ return null; } Kind componentKind = srcType.getComponentType().getKind(); - final ResolvedJavaMethod snippetMethod = tool.getRuntime().lookupJavaMethod(ArrayCopySnippets.getSnippetForKind(componentKind)); + final ResolvedJavaMethod snippetMethod = tool.getMetaAccess().lookupJavaMethod(ArrayCopySnippets.getSnippetForKind(componentKind)); return Debug.scope("ArrayCopySnippet", snippetMethod, new Callable<StructuredGraph>() { @Override @@ -93,7 +93,7 @@ } // the canonicalization before loop unrolling is needed to propagate the length into // additions, etc. - PhaseContext context = new PhaseContext(tool.getRuntime(), tool.assumptions(), tool.getReplacements()); + PhaseContext context = new PhaseContext(tool.getMetaAccess(), tool.getCodeCache(), tool.getConstantReflection(), tool.getLowerer(), tool.assumptions(), tool.getReplacements()); new CanonicalizerPhase(true).apply(snippetGraph, context); new LoopFullUnrollPhase(new CanonicalizerPhase(true)).apply(snippetGraph, context); new CanonicalizerPhase(true).apply(snippetGraph, context); @@ -108,7 +108,7 @@ final Replacements replacements = tool.getReplacements(); StructuredGraph snippetGraph = selectSnippet(tool, replacements); if (snippetGraph == null) { - final ResolvedJavaMethod snippetMethod = tool.getRuntime().lookupJavaMethod(ArrayCopySnippets.genericArraycopySnippet); + final ResolvedJavaMethod snippetMethod = tool.getMetaAccess().lookupJavaMethod(ArrayCopySnippets.genericArraycopySnippet); snippetGraph = Debug.scope("ArrayCopySnippet", snippetMethod, new Callable<StructuredGraph>() { @Override
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CallSiteSubstitutions.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CallSiteSubstitutions.java Fri Oct 11 17:21:14 2013 +0200 @@ -34,7 +34,7 @@ public class CallSiteSubstitutions implements ReplacementsProvider { @Override - public void registerReplacements(MetaAccessProvider runtime, Replacements replacements, TargetDescription target) { + public void registerReplacements(MetaAccessProvider metaAccess, Replacements replacements, TargetDescription target) { replacements.registerSubstitutions(ConstantCallSiteSubstitutions.class); replacements.registerSubstitutions(MutableCallSiteSubstitutions.class); replacements.registerSubstitutions(VolatileCallSiteSubstitutions.class);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CallSiteTargetNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CallSiteTargetNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -26,6 +26,8 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.replacements.nodes.*; @@ -40,7 +42,7 @@ return arguments.get(0); } - private ConstantNode getConstantCallTarget(MetaAccessProvider metaAccessProvider, Assumptions assumptions) { + private ConstantNode getConstantCallTarget(MetaAccessProvider metaAccess, Assumptions assumptions) { if (getCallSite().isConstant() && !getCallSite().isNullConstant()) { CallSite callSite = (CallSite) getCallSite().asConstant().asObject(); MethodHandle target = callSite.getTarget(); @@ -50,14 +52,14 @@ } assumptions.record(new Assumptions.CallSiteTargetValue(callSite, target)); } - return ConstantNode.forObject(target, metaAccessProvider, graph()); + return ConstantNode.forObject(target, metaAccess, graph()); } return null; } @Override - public ValueNode canonical(CanonicalizerTool tool) { - ConstantNode target = getConstantCallTarget(tool.runtime(), tool.assumptions()); + public Node canonical(CanonicalizerTool tool) { + ConstantNode target = getConstantCallTarget(tool.getMetaAccess(), tool.assumptions()); if (target != null) { return target; } @@ -67,7 +69,7 @@ @Override public void lower(LoweringTool tool) { - ConstantNode target = getConstantCallTarget(tool.getRuntime(), tool.assumptions()); + ConstantNode target = getConstantCallTarget(tool.getMetaAccess(), tool.assumptions()); if (target != null) { graph().replaceFixedWithFloating(this, target);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CheckCastDynamicSnippets.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CheckCastDynamicSnippets.java Fri Oct 11 17:21:14 2013 +0200 @@ -22,7 +22,7 @@ */ package com.oracle.graal.hotspot.replacements; -import static com.oracle.graal.api.code.DeoptimizationAction.*; +import static com.oracle.graal.api.meta.DeoptimizationAction.*; import static com.oracle.graal.api.meta.DeoptimizationReason.*; import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*; import static com.oracle.graal.hotspot.replacements.TypeCheckSnippetUtils.*; @@ -34,8 +34,8 @@ import com.oracle.graal.debug.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.java.*; -import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; +import com.oracle.graal.phases.util.*; import com.oracle.graal.replacements.*; import com.oracle.graal.replacements.SnippetTemplate.AbstractTemplates; import com.oracle.graal.replacements.SnippetTemplate.Arguments; @@ -66,8 +66,8 @@ private final SnippetInfo dynamic = snippet(CheckCastDynamicSnippets.class, "checkcastDynamic"); - public Templates(CodeCacheProvider runtime, Replacements replacements, TargetDescription target) { - super(runtime, replacements, target); + public Templates(Providers providers, TargetDescription target) { + super(providers, target); } public void lower(CheckCastDynamicNode checkcast) { @@ -80,7 +80,7 @@ SnippetTemplate template = template(args); Debug.log("Lowering dynamic checkcast in %s: node=%s, template=%s, arguments=%s", graph, checkcast, template, args); - template.instantiate(runtime, checkcast, DEFAULT_REPLACER, args); + template.instantiate(providers.getMetaAccess(), checkcast, DEFAULT_REPLACER, args); } } }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CipherBlockChainingSubstitutions.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CipherBlockChainingSubstitutions.java Fri Oct 11 17:21:14 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 = UnsafeLoadNode.load(rcvr, 0, embeddedCipherOffset, Kind.Object); + Object embeddedCipher = UnsafeLoadNode.load(rcvr, 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 = UnsafeLoadNode.load(rcvr, 0, embeddedCipherOffset, Kind.Object); + Object embeddedCipher = UnsafeLoadNode.load(rcvr, embeddedCipherOffset, Kind.Object); if (in != out && getAESCryptClass().isInstance(embeddedCipher)) { crypt(rcvr, in, inOffset, inLength, out, outOffset, embeddedCipher, false); } else { @@ -81,8 +81,8 @@ } private static void crypt(Object rcvr, byte[] in, int inOffset, int inLength, byte[] out, int outOffset, Object embeddedCipher, boolean encrypt) { - Object kObject = UnsafeLoadNode.load(embeddedCipher, 0, AESCryptSubstitutions.kOffset, Kind.Object); - Object rObject = UnsafeLoadNode.load(rcvr, 0, rOffset, Kind.Object); + Object kObject = UnsafeLoadNode.load(embeddedCipher, AESCryptSubstitutions.kOffset, Kind.Object); + Object rObject = UnsafeLoadNode.load(rcvr, 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);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotReplacementsUtil.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotReplacementsUtil.java Fri Oct 11 17:21:14 2013 +0200 @@ -486,7 +486,7 @@ public static Word loadWordFromObject(Object object, int offset) { assert offset != hubOffset() : "Use loadHubIntrinsic instead"; - return loadWordFromObjectIntrinsic(object, 0, offset, getWordKind()); + return loadWordFromObjectIntrinsic(object, offset, getWordKind()); } @NodeIntrinsic(value = ReadRegisterNode.class, setStampFromReturnType = true) @@ -494,8 +494,8 @@ @SuppressWarnings("unused") @NodeIntrinsic(value = UnsafeLoadNode.class, setStampFromReturnType = true) - private static Word loadWordFromObjectIntrinsic(Object object, @ConstantNodeParameter int displacement, long offset, @ConstantNodeParameter Kind wordKind) { - return Word.unsigned(unsafeReadWord(object, offset + displacement)); + private static Word loadWordFromObjectIntrinsic(Object object, long offset, @ConstantNodeParameter Kind wordKind) { + return Word.unsigned(unsafeReadWord(object, offset)); } @SuppressWarnings("unused")
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/InstanceOfSnippets.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/InstanceOfSnippets.java Fri Oct 11 17:21:14 2013 +0200 @@ -22,7 +22,7 @@ */ package com.oracle.graal.hotspot.replacements; -import static com.oracle.graal.api.code.DeoptimizationAction.*; +import static com.oracle.graal.api.meta.DeoptimizationAction.*; import static com.oracle.graal.api.meta.DeoptimizationReason.*; import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*; @@ -40,6 +40,7 @@ import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; import com.oracle.graal.phases.*; +import com.oracle.graal.phases.util.*; import com.oracle.graal.replacements.*; import com.oracle.graal.replacements.Snippet.ConstantParameter; import com.oracle.graal.replacements.Snippet.VarargsParameter; @@ -200,8 +201,8 @@ private final SnippetInfo instanceofSecondary = snippet(InstanceOfSnippets.class, "instanceofSecondary"); private final SnippetInfo instanceofDynamic = snippet(InstanceOfSnippets.class, "instanceofDynamic"); - public Templates(CodeCacheProvider runtime, Replacements replacements, TargetDescription target) { - super(runtime, replacements, target); + public Templates(Providers providers, TargetDescription target) { + super(providers, target); } @Override @@ -211,13 +212,13 @@ ValueNode object = instanceOf.object(); 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()); + ConstantNode hub = ConstantNode.forConstant(type.klass(), providers.getMetaAccess(), instanceOf.graph()); Arguments args; StructuredGraph graph = hub.graph(); if (hintInfo.hintHitProbability >= hintHitProbabilityThresholdForDeoptimizingSnippet()) { - Hints hints = createHints(hintInfo, runtime, false, graph); + Hints hints = createHints(hintInfo, providers.getMetaAccess(), false, graph); args = new Arguments(instanceofWithProfile, graph.getGuardsStage()); args.add("object", object); args.addVarargs("hints", Word.class, StampFactory.forKind(wordKind()), hints.hubs); @@ -225,14 +226,14 @@ } else if (hintInfo.exact != null) { args = new Arguments(instanceofExact, graph.getGuardsStage()); args.add("object", object); - args.add("exactHub", ConstantNode.forConstant(((HotSpotResolvedObjectType) hintInfo.exact).klass(), runtime, graph)); + args.add("exactHub", ConstantNode.forConstant(((HotSpotResolvedObjectType) hintInfo.exact).klass(), providers.getMetaAccess(), graph)); } else if (type.isPrimaryType()) { args = new Arguments(instanceofPrimary, graph.getGuardsStage()); args.add("hub", hub); args.add("object", object); args.addConst("superCheckOffset", type.superCheckOffset()); } else { - Hints hints = createHints(hintInfo, runtime, false, graph); + Hints hints = createHints(hintInfo, providers.getMetaAccess(), false, graph); args = new Arguments(instanceofSecondary, graph.getGuardsStage()); args.add("hub", hub); args.add("object", object);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/LoadExceptionObjectSnippets.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/LoadExceptionObjectSnippets.java Fri Oct 11 17:21:14 2013 +0200 @@ -32,8 +32,8 @@ 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.*; +import com.oracle.graal.phases.util.*; import com.oracle.graal.replacements.*; import com.oracle.graal.replacements.SnippetTemplate.AbstractTemplates; import com.oracle.graal.replacements.SnippetTemplate.Arguments; @@ -64,22 +64,22 @@ private final SnippetInfo loadException = snippet(LoadExceptionObjectSnippets.class, "loadException"); - public Templates(CodeCacheProvider runtime, Replacements replacements, TargetDescription target) { - super(runtime, replacements, target); + public Templates(Providers providers, TargetDescription target) { + super(providers, target); } public void lower(LoadExceptionObjectNode loadExceptionObject) { if (USE_C_RUNTIME) { StructuredGraph graph = loadExceptionObject.graph(); - HotSpotRuntime hsRuntime = (HotSpotRuntime) runtime; + HotSpotRuntime hsRuntime = (HotSpotRuntime) providers.getMetaAccess(); 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)); + ForeignCallNode loadExceptionC = graph.add(new ForeignCallNode(providers.getMetaAccess(), LOAD_AND_CLEAR_EXCEPTION, thread)); loadExceptionC.setStateAfter(loadExceptionObject.stateAfter()); graph.replaceFixedWithFixed(loadExceptionObject, loadExceptionC); } else { Arguments args = new Arguments(loadException, loadExceptionObject.graph().getGuardsStage()); - template(args).instantiate(runtime, loadExceptionObject, DEFAULT_REPLACER, args); + template(args).instantiate(providers.getMetaAccess(), loadExceptionObject, DEFAULT_REPLACER, args); } } }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MethodHandleInvokeBasicNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MethodHandleInvokeBasicNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -24,10 +24,9 @@ import java.lang.invoke.MethodHandle; -import com.oracle.graal.nodes.Invoke; -import com.oracle.graal.nodes.InvokeNode; -import com.oracle.graal.nodes.ValueNode; -import com.oracle.graal.nodes.spi.CanonicalizerTool; +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; +import com.oracle.graal.nodes.*; /** * Macro node for {@link MethodHandle}{@code .invokeBasic(Object...)}. @@ -39,7 +38,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { InvokeNode invoke = getInvokeBasicTarget(); if (invoke != null) { return invoke;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MethodHandleLinkToInterfaceNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MethodHandleLinkToInterfaceNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -24,10 +24,9 @@ import java.lang.invoke.MethodHandle; -import com.oracle.graal.nodes.Invoke; -import com.oracle.graal.nodes.InvokeNode; -import com.oracle.graal.nodes.ValueNode; -import com.oracle.graal.nodes.spi.CanonicalizerTool; +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; +import com.oracle.graal.nodes.*; /** * Macro node for {@link MethodHandle}{@code .linkToInterface(Object...)}. @@ -39,7 +38,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { InvokeNode invoke = getLinkToTarget(); if (invoke != null) { return invoke;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MethodHandleLinkToSpecialNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MethodHandleLinkToSpecialNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -24,10 +24,9 @@ import java.lang.invoke.MethodHandle; -import com.oracle.graal.nodes.Invoke; -import com.oracle.graal.nodes.InvokeNode; -import com.oracle.graal.nodes.ValueNode; -import com.oracle.graal.nodes.spi.CanonicalizerTool; +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; +import com.oracle.graal.nodes.*; /** * Macro node for {@link MethodHandle}{@code .linkToSpecial(Object...)}. @@ -39,7 +38,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { InvokeNode invoke = getLinkToTarget(); if (invoke != null) { return invoke;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MethodHandleLinkToStaticNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MethodHandleLinkToStaticNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -24,10 +24,9 @@ import java.lang.invoke.MethodHandle; -import com.oracle.graal.nodes.Invoke; -import com.oracle.graal.nodes.InvokeNode; -import com.oracle.graal.nodes.ValueNode; -import com.oracle.graal.nodes.spi.CanonicalizerTool; +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; +import com.oracle.graal.nodes.*; /** * Macro node for {@link MethodHandle}{@code .linkToStatic(Object...)}. @@ -39,7 +38,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { InvokeNode invoke = getLinkToTarget(); if (invoke != null) { return invoke;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MethodHandleLinkToVirtualNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MethodHandleLinkToVirtualNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -24,10 +24,9 @@ import java.lang.invoke.MethodHandle; -import com.oracle.graal.nodes.Invoke; -import com.oracle.graal.nodes.InvokeNode; -import com.oracle.graal.nodes.ValueNode; -import com.oracle.graal.nodes.spi.CanonicalizerTool; +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; +import com.oracle.graal.nodes.*; /** * Macro node for {@link MethodHandle}{@code .linkToVirtual(Object...)}. @@ -39,7 +38,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { InvokeNode invoke = getLinkToTarget(); if (invoke != null) { return invoke;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MonitorSnippets.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MonitorSnippets.java Fri Oct 11 17:21:14 2013 +0200 @@ -40,14 +40,18 @@ import com.oracle.graal.graph.iterators.*; import com.oracle.graal.hotspot.nodes.*; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.debug.*; 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.*; import com.oracle.graal.nodes.type.*; +import com.oracle.graal.options.*; import com.oracle.graal.phases.common.*; +import com.oracle.graal.phases.util.*; import com.oracle.graal.replacements.*; import com.oracle.graal.replacements.Snippet.ConstantParameter; +import com.oracle.graal.replacements.Snippet.Fold; import com.oracle.graal.replacements.SnippetTemplate.AbstractTemplates; import com.oracle.graal.replacements.SnippetTemplate.Arguments; import com.oracle.graal.replacements.SnippetTemplate.SnippetInfo; @@ -63,6 +67,22 @@ */ public class MonitorSnippets implements Snippets { + public static class Options { + + //@formatter:off + @Option(help = "") + private static final OptionValue<Boolean> ProfileMonitors = new OptionValue<>(false); + //@formatter:on + } + + private static final boolean PROFILE_CONTEXT = false; + + @Fold + @SuppressWarnings("unused") + private static boolean doProfile(String path) { + return Options.ProfileMonitors.getValue(); + } + /** * Monitor operations on objects whose type contains this substring will be traced. */ @@ -118,7 +138,7 @@ trace(trace, " tmp: 0x%016lx\n", tmp); if (probability(FREQUENT_PROBABILITY, tmp.equal(0))) { // Object is already biased to current thread -> done - traceObject(trace, "+lock{bias:existing}", object); + traceObject(trace, "+lock{bias:existing}", object, true); return; } @@ -154,13 +174,13 @@ trace(trace, " biasedMark: 0x%016lx\n", biasedMark); if (probability(VERY_FAST_PATH_PROBABILITY, compareAndSwap(object, markOffset(), unbiasedMark, biasedMark, MARK_WORD_LOCATION).equal(unbiasedMark))) { // Object is now biased to current thread -> done - traceObject(trace, "+lock{bias:acquired}", object); + traceObject(trace, "+lock{bias:acquired}", object, true); return; } // If the biasing toward our thread failed, this means that another thread // owns the bias and we need to revoke that bias. The revocation will occur // in the interpreter runtime. - traceObject(trace, "+lock{stub:revoke}", object); + traceObject(trace, "+lock{stub:revoke}", object, true); monitorenterStub(MONITORENTER, object, lock); return; } else { @@ -174,13 +194,13 @@ trace(trace, " biasedMark: 0x%016lx\n", biasedMark); if (probability(VERY_FAST_PATH_PROBABILITY, compareAndSwap(object, markOffset(), mark, biasedMark, MARK_WORD_LOCATION).equal(mark))) { // Object is now biased to current thread -> done - traceObject(trace, "+lock{bias:transfer}", object); + traceObject(trace, "+lock{bias:transfer}", object, true); return; } // If the biasing toward our thread failed, then another thread // succeeded in biasing it toward itself and we need to revoke that // bias. The revocation will occur in the runtime in the slow case. - traceObject(trace, "+lock{stub:epoch-expired}", object); + traceObject(trace, "+lock{stub:epoch-expired}", object, true); monitorenterStub(MONITORENTER, object, lock); return; } @@ -237,16 +257,16 @@ final Word stackPointer = stackPointer(); if (probability(VERY_SLOW_PATH_PROBABILITY, currentMark.subtract(stackPointer).and(alignedMask.subtract(pageSize())).notEqual(0))) { // Most likely not a recursive lock, go into a slow runtime call - traceObject(trace, "+lock{stub:failed-cas}", object); + traceObject(trace, "+lock{stub:failed-cas}", object, true); monitorenterStub(MONITORENTER, object, lock); return; } else { // Recursively locked => write 0 to the lock slot lock.writeWord(lockDisplacedMarkOffset(), Word.zero(), DISPLACED_MARK_WORD_LOCATION); - traceObject(trace, "+lock{recursive}", object); + traceObject(trace, "+lock{recursive}", object, true); } } else { - traceObject(trace, "+lock{cas}", object); + traceObject(trace, "+lock{cas}", object, true); } } @@ -263,7 +283,7 @@ // BeginLockScope nodes do not read from object so a use of object // cannot float about the null check above final Word lock = beginLockScope(lockDepth); - traceObject(trace, "+lock{stub}", object); + traceObject(trace, "+lock{stub}", object, true); monitorenterStub(MONITORENTER, object, lock); } @@ -282,7 +302,7 @@ if (probability(FREQUENT_PROBABILITY, mark.and(biasedLockMaskInPlace()).equal(Word.unsigned(biasedLockPattern())))) { endLockScope(); decCounter(); - traceObject(trace, "-lock{bias}", object); + traceObject(trace, "-lock{bias}", object, false); return; } } @@ -295,7 +315,7 @@ if (displacedMark.equal(0)) { // Recursive locking => done - traceObject(trace, "-lock{recursive}", object); + traceObject(trace, "-lock{recursive}", object, false); } else { verifyOop(object); // Test if object's mark word is pointing to the displaced mark word, and if so, restore @@ -304,10 +324,10 @@ if (probability(VERY_SLOW_PATH_PROBABILITY, DirectCompareAndSwapNode.compareAndSwap(object, markOffset(), lock, displacedMark, MARK_WORD_LOCATION).notEqual(lock))) { // The object's mark word was not pointing to the displaced header, // we do unlocking via runtime call. - traceObject(trace, "-lock{stub}", object); + traceObject(trace, "-lock{stub}", object, false); MonitorExitStubCall.call(object, lockDepth); } else { - traceObject(trace, "-lock{cas}", object); + traceObject(trace, "-lock{cas}", object, false); } } endLockScope(); @@ -320,13 +340,16 @@ @Snippet public static void monitorexitStub(Object object, @ConstantParameter int lockDepth, @ConstantParameter boolean trace) { verifyOop(object); - traceObject(trace, "-lock{stub}", object); + traceObject(trace, "-lock{stub}", object, false); MonitorExitStubCall.call(object, lockDepth); endLockScope(); decCounter(); } - private static void traceObject(boolean enabled, String action, Object object) { + private static void traceObject(boolean enabled, String action, Object object, boolean enter) { + if (doProfile(action)) { + DynamicCounterNode.counter(action, enter ? "number of monitor enters" : "number of monitor exits", 1, PROFILE_CONTEXT); + } if (enabled) { Log.print(action); Log.print(' '); @@ -393,8 +416,8 @@ private final boolean useFastLocking; - public Templates(CodeCacheProvider runtime, Replacements replacements, TargetDescription target, boolean useFastLocking) { - super(runtime, replacements, target); + public Templates(Providers providers, TargetDescription target, boolean useFastLocking) { + super(providers, target); this.useFastLocking = useFastLocking; } @@ -414,7 +437,7 @@ boolean tracingEnabledForMethod = stateAfter != null && (isTracingEnabledForMethod(stateAfter.method()) || isTracingEnabledForMethod(graph.method())); args.addConst("trace", isTracingEnabledForType(monitorenterNode.object()) || tracingEnabledForMethod); - Map<Node, Node> nodes = template(args).instantiate(runtime, monitorenterNode, DEFAULT_REPLACER, args); + Map<Node, Node> nodes = template(args).instantiate(providers.getMetaAccess(), monitorenterNode, DEFAULT_REPLACER, args); for (Node n : nodes.values()) { if (n instanceof BeginLockScopeNode) { @@ -438,7 +461,7 @@ args.addConst("lockDepth", monitorexitNode.getLockDepth()); args.addConst("trace", isTracingEnabledForType(monitorexitNode.object()) || isTracingEnabledForMethod(stateAfter.method()) || isTracingEnabledForMethod(graph.method())); - Map<Node, Node> nodes = template(args).instantiate(runtime, monitorexitNode, DEFAULT_REPLACER, args); + Map<Node, Node> nodes = template(args).instantiate(providers.getMetaAccess(), monitorexitNode, DEFAULT_REPLACER, args); for (Node n : nodes.values()) { if (n instanceof EndLockScopeNode) { @@ -492,14 +515,14 @@ invoke.setStateAfter(graph.start().stateAfter()); graph.addAfterFixed(graph.start(), invoke); - StructuredGraph inlineeGraph = replacements.getSnippet(initCounter.getMethod()); + StructuredGraph inlineeGraph = providers.getReplacements().getSnippet(initCounter.getMethod()); InliningUtil.inline(invoke, inlineeGraph, false); List<ReturnNode> rets = graph.getNodes().filter(ReturnNode.class).snapshot(); for (ReturnNode ret : rets) { returnType = checkCounter.getMethod().getSignature().getReturnType(checkCounter.getMethod().getDeclaringClass()); String msg = "unbalanced monitors in " + MetaUtil.format("%H.%n(%p)", graph.method()) + ", count = %d"; - ConstantNode errMsg = ConstantNode.forObject(msg, runtime, graph); + ConstantNode errMsg = ConstantNode.forObject(msg, providers.getMetaAccess(), graph); callTarget = graph.add(new MethodCallTargetNode(InvokeKind.Static, checkCounter.getMethod(), new ValueNode[]{errMsg}, returnType)); invoke = graph.add(new InvokeNode(callTarget, 0)); List<ValueNode> stack = Collections.emptyList();
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippets.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippets.java Fri Oct 11 17:21:14 2013 +0200 @@ -34,17 +34,21 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.debug.*; +import com.oracle.graal.graph.*; import com.oracle.graal.graph.Node.ConstantNodeParameter; import com.oracle.graal.graph.Node.NodeIntrinsic; import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.hotspot.nodes.*; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.debug.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.java.*; -import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; +import com.oracle.graal.options.*; +import com.oracle.graal.phases.util.*; import com.oracle.graal.replacements.*; import com.oracle.graal.replacements.Snippet.ConstantParameter; +import com.oracle.graal.replacements.Snippet.Fold; import com.oracle.graal.replacements.Snippet.VarargsParameter; import com.oracle.graal.replacements.SnippetTemplate.AbstractTemplates; import com.oracle.graal.replacements.SnippetTemplate.Arguments; @@ -58,7 +62,20 @@ public class NewObjectSnippets implements Snippets { public static final LocationIdentity INIT_LOCATION = new NamedLocationIdentity("Initialization"); - public static final LocationIdentity ARRAY_LENGTH_LOCATION = new NamedLocationIdentity("ArrayLength"); + + public static class Options { + + //@formatter:off + @Option(help = "") + private static final OptionValue<Boolean> ProfileAllocations = new OptionValue<>(false); + //@formatter:on + } + + static enum ProfileMode { + AllocatingMethods, InstanceOrArray, AllocatedTypes, AllocatedTypesInMethods, Total + } + + public static final ProfileMode PROFILE_MODE = ProfileMode.Total; @Snippet public static Word allocate(int size) { @@ -77,8 +94,41 @@ return Word.zero(); } + @Fold + private static String createName(String path, String typeContext) { + switch (PROFILE_MODE) { + case AllocatingMethods: + return ""; + case InstanceOrArray: + return path; + case AllocatedTypes: + case AllocatedTypesInMethods: + return typeContext; + case Total: + return "bytes"; + default: + throw GraalInternalError.shouldNotReachHere(); + } + } + + @Fold + @SuppressWarnings("unused") + private static boolean doProfile(String path, String typeContext) { + return Options.ProfileAllocations.getValue(); + } + + private static void profileAllocation(String path, long size, String typeContext) { + if (doProfile(path, typeContext)) { + String name = createName(path, typeContext); + + boolean context = PROFILE_MODE == ProfileMode.AllocatingMethods || PROFILE_MODE == ProfileMode.AllocatedTypesInMethods; + DynamicCounterNode.counter(name, "number of bytes allocated", size, context); + DynamicCounterNode.counter(name, "number of allocations", 1, context); + } + } + @Snippet - public static Object allocateInstance(@ConstantParameter int size, Word hub, Word prototypeMarkWord, @ConstantParameter boolean fillContents) { + public static Object allocateInstance(@ConstantParameter int size, Word hub, Word prototypeMarkWord, @ConstantParameter boolean fillContents, @ConstantParameter String typeContext) { Object result; Word thread = thread(); Word top = readTlabTop(thread); @@ -91,6 +141,7 @@ new_stub.inc(); result = NewInstanceStubCall.call(hub); } + profileAllocation("instance", size, typeContext); return piCast(verifyOop(result), StampFactory.forNodeIntrinsic()); } @@ -100,15 +151,16 @@ public static final int MAX_ARRAY_FAST_PATH_ALLOCATION_LENGTH = 0x00FFFFFF; @Snippet - public static Object allocateArray(Word hub, int length, Word prototypeMarkWord, @ConstantParameter int headerSize, @ConstantParameter int log2ElementSize, @ConstantParameter boolean fillContents) { + public static Object allocateArray(Word hub, int length, Word prototypeMarkWord, @ConstantParameter int headerSize, @ConstantParameter int log2ElementSize, + @ConstantParameter boolean fillContents, @ConstantParameter String typeContext) { if (!belowThan(length, MAX_ARRAY_FAST_PATH_ALLOCATION_LENGTH)) { // This handles both negative array sizes and very large array sizes DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint); } - return allocateArrayImpl(hub, length, prototypeMarkWord, headerSize, log2ElementSize, fillContents); + return allocateArrayImpl(hub, length, prototypeMarkWord, headerSize, log2ElementSize, fillContents, typeContext); } - private static Object allocateArrayImpl(Word hub, int length, Word prototypeMarkWord, int headerSize, int log2ElementSize, boolean fillContents) { + private static Object allocateArrayImpl(Word hub, int length, Word prototypeMarkWord, int headerSize, int log2ElementSize, boolean fillContents, String typeContext) { Object result; int alignment = wordSize(); int allocationSize = computeArrayAllocationSize(length, alignment, headerSize, log2ElementSize); @@ -124,6 +176,7 @@ newarray_stub.inc(); result = NewArrayStubCall.call(hub, length); } + profileAllocation("array", allocationSize, typeContext); return piArrayCast(verifyOop(result), length, StampFactory.forNodeIntrinsic()); } @@ -157,7 +210,7 @@ int log2ElementSize = (layoutHelper >> layoutHelperLog2ElementSizeShift()) & layoutHelperLog2ElementSizeMask(); Word prototypeMarkWord = hub.readWord(prototypeMarkWordOffset(), PROTOTYPE_MARK_WORD_LOCATION); - return allocateArrayImpl(hub, length, prototypeMarkWord, headerSize, log2ElementSize, fillContents); + return allocateArrayImpl(hub, length, prototypeMarkWord, headerSize, log2ElementSize, fillContents, "dynamic type"); } /** @@ -222,7 +275,7 @@ * Formats some allocated memory with an object header and zeroes out the rest. */ public static Object formatArray(Word hub, int allocationSize, int length, int headerSize, Word memory, Word prototypeMarkWord, boolean fillContents) { - memory.writeInt(arrayLengthOffset(), length, ARRAY_LENGTH_LOCATION); + memory.writeInt(arrayLengthOffset(), length, INIT_LOCATION); /* * store hub last as the concurrent garbage collectors assume length is valid if hub field * is not null @@ -243,8 +296,8 @@ private final SnippetInfo allocateArrayDynamic = snippet(NewObjectSnippets.class, "allocateArrayDynamic"); private final SnippetInfo newmultiarray = snippet(NewObjectSnippets.class, "newmultiarray"); - public Templates(CodeCacheProvider runtime, Replacements replacements, TargetDescription target) { - super(runtime, replacements, target); + public Templates(Providers providers, TargetDescription target) { + super(providers, target); } /** @@ -254,7 +307,7 @@ StructuredGraph graph = newInstanceNode.graph(); HotSpotResolvedObjectType type = (HotSpotResolvedObjectType) newInstanceNode.instanceClass(); assert !type.isArray(); - ConstantNode hub = ConstantNode.forConstant(type.klass(), runtime, graph); + ConstantNode hub = ConstantNode.forConstant(type.klass(), providers.getMetaAccess(), graph); int size = instanceSize(type); Arguments args = new Arguments(allocateInstance, graph.getGuardsStage()); @@ -262,10 +315,11 @@ args.add("hub", hub); args.add("prototypeMarkWord", type.prototypeMarkWord()); args.addConst("fillContents", newInstanceNode.fillContents()); + args.addConst("typeContext", MetaUtil.toJavaName(type, false)); SnippetTemplate template = template(args); Debug.log("Lowering allocateInstance in %s: node=%s, template=%s, arguments=%s", graph, newInstanceNode, template, args); - template.instantiate(runtime, newInstanceNode, DEFAULT_REPLACER, args); + template.instantiate(providers.getMetaAccess(), newInstanceNode, DEFAULT_REPLACER, args); } /** @@ -276,9 +330,9 @@ ResolvedJavaType elementType = newArrayNode.elementType(); HotSpotResolvedObjectType arrayType = (HotSpotResolvedObjectType) elementType.getArrayClass(); Kind elementKind = elementType.getKind(); - ConstantNode hub = ConstantNode.forConstant(arrayType.klass(), runtime, graph); + ConstantNode hub = ConstantNode.forConstant(arrayType.klass(), providers.getMetaAccess(), graph); final int headerSize = HotSpotRuntime.getArrayBaseOffset(elementKind); - int log2ElementSize = CodeUtil.log2(((HotSpotRuntime) runtime).getScalingFactor(elementKind)); + int log2ElementSize = CodeUtil.log2(((HotSpotRuntime) providers.getMetaAccess()).getScalingFactor(elementKind)); Arguments args = new Arguments(allocateArray, graph.getGuardsStage()); args.add("hub", hub); @@ -287,10 +341,11 @@ args.addConst("headerSize", headerSize); args.addConst("log2ElementSize", log2ElementSize); args.addConst("fillContents", newArrayNode.fillContents()); + args.addConst("typeContext", MetaUtil.toJavaName(arrayType, false)); SnippetTemplate template = template(args); Debug.log("Lowering allocateArray in %s: node=%s, template=%s, arguments=%s", graph, newArrayNode, template, args); - template.instantiate(runtime, newArrayNode, DEFAULT_REPLACER, args); + template.instantiate(providers.getMetaAccess(), newArrayNode, DEFAULT_REPLACER, args); } public void lower(DynamicNewArrayNode newArrayNode) { @@ -300,7 +355,7 @@ args.addConst("fillContents", newArrayNode.fillContents()); SnippetTemplate template = template(args); - template.instantiate(runtime, newArrayNode, DEFAULT_REPLACER, args); + template.instantiate(providers.getMetaAccess(), newArrayNode, DEFAULT_REPLACER, args); } public void lower(NewMultiArrayNode newmultiarrayNode) { @@ -311,13 +366,13 @@ dims[i] = newmultiarrayNode.dimension(i); } HotSpotResolvedObjectType type = (HotSpotResolvedObjectType) newmultiarrayNode.type(); - ConstantNode hub = ConstantNode.forConstant(type.klass(), runtime, graph); + ConstantNode hub = ConstantNode.forConstant(type.klass(), providers.getMetaAccess(), graph); Arguments args = new Arguments(newmultiarray, graph.getGuardsStage()); args.add("hub", hub); args.addConst("rank", rank); args.addVarargs("dimensions", int.class, StampFactory.forKind(Kind.Int), dims); - template(args).instantiate(runtime, newmultiarrayNode, DEFAULT_REPLACER, args); + template(args).instantiate(providers.getMetaAccess(), newmultiarrayNode, DEFAULT_REPLACER, args); } private static int instanceSize(HotSpotResolvedObjectType type) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectCloneNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectCloneNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -59,49 +59,72 @@ } ResolvedJavaType type = ObjectStamp.typeOrNull(getObject()); - Method method; - /* - * The first condition tests if the parameter is an array, the second condition tests if the - * parameter can be an array. Otherwise, the parameter is known to be a non-array object. - */ - if (type.isArray()) { - method = ObjectCloneSnippets.arrayCloneMethod; - } else if (type == null || type.isAssignableFrom(tool.getRuntime().lookupJavaType(Object[].class))) { - method = ObjectCloneSnippets.genericCloneMethod; - } else { - method = ObjectCloneSnippets.instanceCloneMethod; + if (type != null) { + if (type.isArray()) { + Method method = ObjectCloneSnippets.arrayCloneMethods.get(type.getComponentType().getKind()); + if (method != null) { + final ResolvedJavaMethod snippetMethod = tool.getMetaAccess().lookupJavaMethod(method); + final Replacements replacements = tool.getReplacements(); + StructuredGraph snippetGraph = Debug.scope("ArrayCopySnippet", snippetMethod, new Callable<StructuredGraph>() { + + @Override + public StructuredGraph call() throws Exception { + return replacements.getSnippet(snippetMethod); + } + }); + + assert snippetGraph != null : "ObjectCloneSnippets should be installed"; + return lowerReplacement(snippetGraph.copy(), tool); + } + } else { + type = getConcreteType(getObject().stamp(), tool.assumptions(), tool.getMetaAccess()); + if (type != null) { + StructuredGraph newGraph = new StructuredGraph(); + LocalNode local = newGraph.add(new LocalNode(0, getObject().stamp())); + NewInstanceNode newInstance = newGraph.add(new NewInstanceNode(type, true)); + newGraph.addAfterFixed(newGraph.start(), newInstance); + ReturnNode returnNode = newGraph.add(new ReturnNode(newInstance)); + newGraph.addAfterFixed(newInstance, returnNode); + + for (ResolvedJavaField field : type.getInstanceFields(true)) { + LoadFieldNode load = newGraph.add(new LoadFieldNode(local, field)); + newGraph.addBeforeFixed(returnNode, load); + newGraph.addBeforeFixed(returnNode, newGraph.add(new StoreFieldNode(newInstance, field, load))); + } + return lowerReplacement(newGraph, tool); + } + } } - final ResolvedJavaMethod snippetMethod = tool.getRuntime().lookupJavaMethod(method); - final Replacements replacements = tool.getReplacements(); - StructuredGraph snippetGraph = Debug.scope("ArrayCopySnippet", snippetMethod, new Callable<StructuredGraph>() { - - @Override - public StructuredGraph call() throws Exception { - return replacements.getSnippet(snippetMethod); - } - }); - - assert snippetGraph != null : "ObjectCloneSnippets should be installed"; - return lowerReplacement(snippetGraph.copy(), tool); + return null; } private static boolean isCloneableType(ResolvedJavaType type, MetaAccessProvider metaAccess) { - return type != null && metaAccess.lookupJavaType(Cloneable.class).isAssignableFrom(type); + return metaAccess.lookupJavaType(Cloneable.class).isAssignableFrom(type); } - private static ResolvedJavaType getConcreteType(Stamp stamp, Assumptions assumptions) { + /* + * Looks at the given stamp and determines if it is an exact type (or can be assumed to be an + * exact type) and if it is a cloneable type. + * + * If yes, then the exact type is returned, otherwise it returns null. + */ + private static ResolvedJavaType getConcreteType(Stamp stamp, Assumptions assumptions, MetaAccessProvider metaAccess) { if (!(stamp instanceof ObjectStamp)) { return null; } ObjectStamp objectStamp = (ObjectStamp) stamp; - if (objectStamp.isExactType() || objectStamp.type() == null) { - return objectStamp.type(); + if (objectStamp.type() == null) { + return null; + } else if (objectStamp.isExactType()) { + return isCloneableType(objectStamp.type(), metaAccess) ? objectStamp.type() : null; } else { ResolvedJavaType type = objectStamp.type().findUniqueConcreteSubtype(); - if (type != null) { + if (type != null && isCloneableType(type, metaAccess)) { assumptions.recordConcreteSubtype(objectStamp.type(), type); + return type; + } else { + return null; } - return type; } } @@ -126,21 +149,19 @@ } else { obj = tool.getReplacedValue(getObject()); } - ResolvedJavaType type = getConcreteType(obj.stamp(), tool.getAssumptions()); - if (isCloneableType(type, tool.getMetaAccessProvider())) { - if (!type.isArray()) { - VirtualInstanceNode newVirtual = new VirtualInstanceNode(type, true); - ResolvedJavaField[] fields = newVirtual.getFields(); + ResolvedJavaType type = getConcreteType(obj.stamp(), tool.getAssumptions(), tool.getMetaAccessProvider()); + if (type != null && !type.isArray()) { + VirtualInstanceNode newVirtual = new VirtualInstanceNode(type, true); + ResolvedJavaField[] fields = newVirtual.getFields(); - ValueNode[] state = new ValueNode[fields.length]; - final LoadFieldNode[] loads = new LoadFieldNode[fields.length]; - for (int i = 0; i < fields.length; i++) { - state[i] = loads[i] = new LoadFieldNode(obj, fields[i]); - tool.addNode(loads[i]); - } - tool.createVirtualObject(newVirtual, state, null); - tool.replaceWithVirtual(newVirtual); + ValueNode[] state = new ValueNode[fields.length]; + final LoadFieldNode[] loads = new LoadFieldNode[fields.length]; + for (int i = 0; i < fields.length; i++) { + state[i] = loads[i] = new LoadFieldNode(obj, fields[i]); + tool.addNode(loads[i]); } + tool.createVirtualObject(newVirtual, state, null); + tool.replaceWithVirtual(newVirtual); } } }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectCloneSnippets.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectCloneSnippets.java Fri Oct 11 17:21:14 2013 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -22,114 +22,77 @@ */ 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.nodes.extended.BranchProbabilityNode.*; -import static com.oracle.graal.phases.GraalOptions.*; +import java.lang.reflect.*; +import java.util.*; -import java.lang.reflect.*; - -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.java.*; import com.oracle.graal.replacements.*; -import com.oracle.graal.word.*; public class ObjectCloneSnippets implements Snippets { - public static final Method instanceCloneMethod = getCloneMethod("instanceClone"); - public static final Method arrayCloneMethod = getCloneMethod("arrayClone"); - public static final Method genericCloneMethod = getCloneMethod("genericClone"); + public static final EnumMap<Kind, Method> arrayCloneMethods = new EnumMap<>(Kind.class); - private static Method getCloneMethod(String name) { + static { + arrayCloneMethods.put(Kind.Byte, getCloneMethod("byteArrayClone", byte[].class)); + arrayCloneMethods.put(Kind.Char, getCloneMethod("charArrayClone", char[].class)); + arrayCloneMethods.put(Kind.Int, getCloneMethod("intArrayClone", int[].class)); + arrayCloneMethods.put(Kind.Long, getCloneMethod("longArrayClone", long[].class)); + arrayCloneMethods.put(Kind.Object, getCloneMethod("objectArrayClone", Object[].class)); + } + + private static Method getCloneMethod(String name, Class<?> param) { try { - return ObjectCloneSnippets.class.getDeclaredMethod(name, Object.class); + return ObjectCloneSnippets.class.getDeclaredMethod(name, param); } catch (SecurityException | NoSuchMethodException e) { throw new GraalInternalError(e); } } - private static Object instanceClone(Object src, Word hub, int layoutHelper) { - int instanceSize = layoutHelper; - Word prototypeMarkWord = hub.readWord(prototypeMarkWordOffset(), PROTOTYPE_MARK_WORD_LOCATION); - Object result = NewObjectSnippets.allocateInstance(instanceSize, hub, prototypeMarkWord, false); - - for (int offset = instanceHeaderSize(); offset < instanceSize; offset += wordSize()) { - /* - * TODO atomicity problem on 32-bit architectures: The JVM spec requires double values - * to be copied atomically, but here they are copied as two 4-byte word values. - */ - ObjectAccess.writeWord(result, offset, ObjectAccess.readWord(src, offset, ANY_LOCATION), ANY_LOCATION); + @Snippet(removeAllFrameStates = true) + public static byte[] byteArrayClone(byte[] src) { + byte[] result = new byte[src.length]; + for (int i = 0; i < result.length; i++) { + result[i] = src[i]; } - return result; } - private static Object arrayClone(Object src, Word hub, int layoutHelper) { - int arrayLength = ArrayLengthNode.arrayLength(src); - int log2ElementSize = (layoutHelper >> layoutHelperLog2ElementSizeShift()) & layoutHelperLog2ElementSizeMask(); - int headerSize = (layoutHelper >> layoutHelperHeaderSizeShift()) & layoutHelperHeaderSizeMask(); - int sizeInBytes = NewObjectSnippets.computeArrayAllocationSize(arrayLength, wordSize(), headerSize, log2ElementSize); - - Word prototypeMarkWord = hub.readWord(prototypeMarkWordOffset(), PROTOTYPE_MARK_WORD_LOCATION); - Object result = NewObjectSnippets.allocateArray(hub, arrayLength, prototypeMarkWord, headerSize, log2ElementSize, false); - - for (int offset = headerSize; offset < sizeInBytes; offset += wordSize()) { - /* - * TODO atomicity problem on 32-bit architectures: The JVM spec requires double values - * to be copied atomically, but here they are copied as two 4-byte word values. - */ - ObjectAccess.writeWord(result, offset, ObjectAccess.readWord(src, offset, ANY_LOCATION), ANY_LOCATION); + @Snippet(removeAllFrameStates = true) + public static char[] charArrayClone(char[] src) { + char[] result = new char[src.length]; + for (int i = 0; i < result.length; i++) { + result[i] = src[i]; } return result; } - private static Word getAndCheckHub(Object src) { - Word hub = loadHub(src); - if (!(src instanceof Cloneable)) { - DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint); + @Snippet(removeAllFrameStates = true) + public static int[] intArrayClone(int[] src) { + int[] result = new int[src.length]; + for (int i = 0; i < result.length; i++) { + result[i] = src[i]; } - return hub; - } - - @Snippet - public static Object instanceClone(Object src) { - instanceCloneCounter.inc(); - Word hub = getAndCheckHub(src); - return instanceClone(src, hub, hub.readInt(layoutHelperOffset(), FINAL_LOCATION)); - } - - @Snippet - public static Object arrayClone(Object src) { - arrayCloneCounter.inc(); - Word hub = getAndCheckHub(src); - int layoutHelper = hub.readInt(layoutHelperOffset(), FINAL_LOCATION); - return arrayClone(src, hub, layoutHelper); + return result; } - @Snippet - public static Object genericClone(Object src) { - genericCloneCounter.inc(); - Word hub = getAndCheckHub(src); - int layoutHelper = hub.readInt(layoutHelperOffset(), FINAL_LOCATION); - if (probability(LIKELY_PROBABILITY, layoutHelper < 0)) { - genericArrayCloneCounter.inc(); - return arrayClone(src, hub, layoutHelper); - } else { - genericInstanceCloneCounter.inc(); - return instanceClone(src, hub, layoutHelper); + @Snippet(removeAllFrameStates = true) + public static long[] longArrayClone(long[] src) { + long[] result = new long[src.length]; + for (int i = 0; i < result.length; i++) { + result[i] = src[i]; } + return result; } - 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 = 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"); - + @Snippet(removeAllFrameStates = true) + public static Object[] objectArrayClone(Object[] src) { + Object[] result = (Object[]) DynamicNewArrayNode.newArray(GuardingPiNode.guardingNonNull(src.getClass().getComponentType()), src.length); + for (int i = 0; i < result.length; i++) { + result[i] = src[i]; + } + return result; + } }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectGetClassNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectGetClassNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -26,6 +26,8 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.api.meta.ResolvedJavaType.Representation; +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -57,7 +59,8 @@ } } - public ValueNode canonical(CanonicalizerTool tool) { + @Override + public Node canonical(CanonicalizerTool tool) { if (AOTCompilation.getValue()) { return this; } @@ -69,7 +72,7 @@ ObjectStamp objectStamp = (ObjectStamp) stamp; if (objectStamp.isExactType()) { Constant clazz = objectStamp.type().getEncoding(Representation.JavaClass); - return ConstantNode.forConstant(clazz, tool.runtime(), graph()); + return ConstantNode.forConstant(clazz, tool.getMetaAccess(), graph()); } } return this;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ReflectionGetCallerClassNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ReflectionGetCallerClassNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -26,6 +26,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; @@ -38,8 +39,8 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { - ConstantNode callerClassNode = getCallerClassNode(tool.runtime()); + public Node canonical(CanonicalizerTool tool) { + ConstantNode callerClassNode = getCallerClassNode(tool.getMetaAccess()); if (callerClassNode != null) { return callerClassNode; } @@ -48,7 +49,7 @@ @Override public void lower(LoweringTool tool) { - ConstantNode callerClassNode = getCallerClassNode(tool.getRuntime()); + ConstantNode callerClassNode = getCallerClassNode(tool.getMetaAccess()); if (callerClassNode != null) { graph().replaceFixedWithFloating(this, callerClassNode); @@ -63,10 +64,10 @@ * If inlining is deep enough this method returns a {@link ConstantNode} of the caller class by * walking the the stack. * - * @param runtime + * @param metaAccess * @return ConstantNode of the caller class, or null */ - private ConstantNode getCallerClassNode(MetaAccessProvider runtime) { + private ConstantNode getCallerClassNode(MetaAccessProvider metaAccess) { if (!shouldIntrinsify(getTargetMethod())) { return null; } @@ -92,7 +93,7 @@ if (!method.ignoredBySecurityStackWalk()) { // We have reached the desired frame; return the holder class. HotSpotResolvedObjectType callerClass = (HotSpotResolvedObjectType) method.getDeclaringClass(); - return ConstantNode.forObject(callerClass.mirror(), runtime, graph()); + return ConstantNode.forObject(callerClass.mirror(), metaAccess, graph()); } break; }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/TypeCheckSnippetUtils.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/TypeCheckSnippetUtils.java Fri Oct 11 17:21:14 2013 +0200 @@ -122,13 +122,13 @@ } } - static Hints createHints(TypeCheckHints hints, MetaAccessProvider runtime, boolean positiveOnly, Graph graph) { + static Hints createHints(TypeCheckHints hints, MetaAccessProvider metaAccess, boolean positiveOnly, Graph graph) { ConstantNode[] hubs = new ConstantNode[hints.hints.length]; boolean[] isPositive = new boolean[hints.hints.length]; int index = 0; for (int i = 0; i < hubs.length; i++) { if (!positiveOnly || hints.hints[i].positive) { - hubs[index] = ConstantNode.forConstant(((HotSpotResolvedObjectType) hints.hints[i].type).klass(), runtime, graph); + hubs[index] = ConstantNode.forConstant(((HotSpotResolvedObjectType) hints.hints[i].type).klass(), metaAccess, graph); isPositive[index] = hints.hints[i].positive; index++; }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/UnsafeArrayCopySnippets.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/UnsafeArrayCopySnippets.java Fri Oct 11 17:21:14 2013 +0200 @@ -23,8 +23,8 @@ package com.oracle.graal.hotspot.replacements; import static com.oracle.graal.api.meta.LocationIdentity.*; +import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*; -import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; import static com.oracle.graal.nodes.extended.BranchProbabilityNode.*; import static com.oracle.graal.replacements.SnippetTemplate.*; @@ -32,7 +32,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.*; import com.oracle.graal.nodes.extended.*; -import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.phases.util.*; import com.oracle.graal.replacements.*; import com.oracle.graal.replacements.SnippetTemplate.AbstractTemplates; import com.oracle.graal.replacements.SnippetTemplate.Arguments; @@ -86,42 +86,42 @@ for (long i = 0; i < postLoopBytes; i += elementSize) { srcOffset -= elementSize; destOffset -= elementSize; - Object a = UnsafeLoadNode.load(src, arrayBaseOffset, srcOffset, baseKind); - UnsafeStoreNode.store(dest, arrayBaseOffset, destOffset, a, baseKind); + Object a = UnsafeLoadNode.load(src, arrayBaseOffset + srcOffset, baseKind); + UnsafeStoreNode.store(dest, arrayBaseOffset + destOffset, a, baseKind); } // Main-loop for (long i = 0; i < mainLoopBytes; i += VECTOR_SIZE) { srcOffset -= VECTOR_SIZE; destOffset -= VECTOR_SIZE; - Long a = UnsafeLoadNode.load(src, arrayBaseOffset, srcOffset, VECTOR_KIND); - UnsafeStoreNode.store(dest, arrayBaseOffset, destOffset, a.longValue(), VECTOR_KIND); + Long a = UnsafeLoadNode.load(src, arrayBaseOffset + srcOffset, VECTOR_KIND); + UnsafeStoreNode.store(dest, arrayBaseOffset + destOffset, a.longValue(), VECTOR_KIND); } // Pre-loop for (long i = 0; i < preLoopBytes; i += elementSize) { srcOffset -= elementSize; destOffset -= elementSize; - Object a = UnsafeLoadNode.load(src, arrayBaseOffset, srcOffset, baseKind); - UnsafeStoreNode.store(dest, arrayBaseOffset, destOffset, a, baseKind); + Object a = UnsafeLoadNode.load(src, arrayBaseOffset + srcOffset, baseKind); + UnsafeStoreNode.store(dest, arrayBaseOffset + destOffset, a, baseKind); } } else { // Pre-loop for (long i = 0; i < preLoopBytes; i += elementSize) { - Object a = UnsafeLoadNode.load(src, arrayBaseOffset, srcOffset, baseKind); - UnsafeStoreNode.store(dest, arrayBaseOffset, destOffset, a, baseKind); + Object a = UnsafeLoadNode.load(src, arrayBaseOffset + srcOffset, baseKind); + UnsafeStoreNode.store(dest, arrayBaseOffset + destOffset, a, baseKind); srcOffset += elementSize; destOffset += elementSize; } // Main-loop for (long i = 0; i < mainLoopBytes; i += VECTOR_SIZE) { - Long a = UnsafeLoadNode.load(src, arrayBaseOffset, srcOffset, VECTOR_KIND); - UnsafeStoreNode.store(dest, arrayBaseOffset, destOffset, a.longValue(), VECTOR_KIND); + Long a = UnsafeLoadNode.load(src, arrayBaseOffset + srcOffset, VECTOR_KIND); + UnsafeStoreNode.store(dest, arrayBaseOffset + destOffset, a.longValue(), VECTOR_KIND); srcOffset += VECTOR_SIZE; destOffset += VECTOR_SIZE; } // Post-loop for (long i = 0; i < postLoopBytes; i += elementSize) { - Object a = UnsafeLoadNode.load(src, arrayBaseOffset, srcOffset, baseKind); - UnsafeStoreNode.store(dest, arrayBaseOffset, destOffset, a, baseKind); + Object a = UnsafeLoadNode.load(src, arrayBaseOffset + srcOffset, baseKind); + UnsafeStoreNode.store(dest, arrayBaseOffset + destOffset, a, baseKind); srcOffset += elementSize; destOffset += elementSize; } @@ -167,13 +167,13 @@ long destOffset = (long) destPos * arrayIndexScale(baseKind); if (src == dest && srcPos < destPos) { // bad aliased case for (long i = byteLength - VECTOR_SIZE; i >= 0; i -= VECTOR_SIZE) { - Long a = UnsafeLoadNode.load(src, arrayBaseOffset, i + srcOffset, VECTOR_KIND); - UnsafeStoreNode.store(dest, arrayBaseOffset, i + destOffset, a.longValue(), VECTOR_KIND); + Long a = UnsafeLoadNode.load(src, arrayBaseOffset + i + srcOffset, VECTOR_KIND); + UnsafeStoreNode.store(dest, arrayBaseOffset + i + destOffset, a.longValue(), VECTOR_KIND); } } else { for (long i = 0; i < byteLength; i += VECTOR_SIZE) { - Long a = UnsafeLoadNode.load(src, arrayBaseOffset, i + srcOffset, VECTOR_KIND); - UnsafeStoreNode.store(dest, arrayBaseOffset, i + destOffset, a.longValue(), VECTOR_KIND); + Long a = UnsafeLoadNode.load(src, arrayBaseOffset + i + srcOffset, VECTOR_KIND); + UnsafeStoreNode.store(dest, arrayBaseOffset + i + destOffset, a.longValue(), VECTOR_KIND); } } } @@ -187,8 +187,8 @@ long destOffset = (long) destPos * arrayIndexScale(baseKind); if (src == dest && srcPos < destPos) { // bad aliased case for (long i = byteLength - VECTOR_SIZE; i >= 0; i -= VECTOR_SIZE) { - Long a = UnsafeLoadNode.load(src, arrayBaseOffset, i + srcOffset, VECTOR_KIND); - UnsafeStoreNode.store(dest, arrayBaseOffset, i + destOffset, a.longValue(), VECTOR_KIND); + Long a = UnsafeLoadNode.load(src, arrayBaseOffset + i + srcOffset, VECTOR_KIND); + UnsafeStoreNode.store(dest, arrayBaseOffset + i + destOffset, a.longValue(), VECTOR_KIND); } } else { for (long i = 0; i < byteLength; i += VECTOR_SIZE) { @@ -197,8 +197,8 @@ * values to be copied atomically, but not long values. For example, on Intel 32-bit * this code is not atomic as long as the vector kind remains Kind.Long. */ - Long a = UnsafeLoadNode.load(src, arrayBaseOffset, i + srcOffset, VECTOR_KIND); - UnsafeStoreNode.store(dest, arrayBaseOffset, i + destOffset, a.longValue(), VECTOR_KIND); + Long a = UnsafeLoadNode.load(src, arrayBaseOffset + i + srcOffset, VECTOR_KIND); + UnsafeStoreNode.store(dest, arrayBaseOffset + i + destOffset, a.longValue(), VECTOR_KIND); } } } @@ -213,13 +213,13 @@ if (src == dest && srcPos < destPos) { // bad aliased case long start = (long) (length - 1) * scale; for (long i = start; i >= 0; i -= scale) { - Object a = UnsafeLoadNode.load(src, arrayBaseOffset, i + (long) srcPos * scale, Kind.Object); + Object a = UnsafeLoadNode.load(src, arrayBaseOffset + i + (long) srcPos * scale, Kind.Object); DirectObjectStoreNode.storeObject(dest, arrayBaseOffset, i + (long) destPos * scale, a); } } else { long end = (long) length * scale; for (long i = 0; i < end; i += scale) { - Object a = UnsafeLoadNode.load(src, arrayBaseOffset, i + (long) srcPos * scale, Kind.Object); + Object a = UnsafeLoadNode.load(src, arrayBaseOffset + i + (long) srcPos * scale, Kind.Object); DirectObjectStoreNode.storeObject(dest, arrayBaseOffset, i + (long) destPos * scale, a); } } @@ -256,8 +256,8 @@ private final SnippetInfo[] arraycopySnippets; private final SnippetInfo genericPrimitiveSnippet; - public Templates(MetaAccessProvider runtime, Replacements replacements, TargetDescription target) { - super(runtime, replacements, target); + public Templates(Providers providers, TargetDescription target) { + super(providers, target); arraycopySnippets = new SnippetInfo[Kind.values().length]; arraycopySnippets[Kind.Boolean.ordinal()] = snippet(UnsafeArrayCopySnippets.class, "arraycopyBoolean"); @@ -288,7 +288,7 @@ node.addSnippetArguments(args); SnippetTemplate template = template(args); - template.instantiate(runtime, node, DEFAULT_REPLACER, args); + template.instantiate(providers.getMetaAccess(), node, DEFAULT_REPLACER, args); } } }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/UnsafeLoadSnippets.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/UnsafeLoadSnippets.java Fri Oct 11 17:21:14 2013 +0200 @@ -30,6 +30,7 @@ import com.oracle.graal.nodes.HeapAccess.BarrierType; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.phases.util.*; import com.oracle.graal.replacements.*; import com.oracle.graal.replacements.SnippetTemplate.AbstractTemplates; import com.oracle.graal.replacements.SnippetTemplate.Arguments; @@ -39,9 +40,8 @@ public class UnsafeLoadSnippets implements Snippets { @Snippet - public static Object lowerUnsafeLoad(Object object, long offset, int disp) { + public static Object lowerUnsafeLoad(Object object, long displacement) { Object fixedObject = FixedValueAnchorNode.getObject(object); - long displacement = disp + offset; if (object instanceof java.lang.ref.Reference && referentOffset() == displacement) { return Word.fromObject(fixedObject).readObject((int) displacement, BarrierType.PRECISE, true); } else { @@ -53,16 +53,15 @@ private final SnippetInfo unsafeLoad = snippet(UnsafeLoadSnippets.class, "lowerUnsafeLoad"); - public Templates(CodeCacheProvider runtime, Replacements replacements, TargetDescription target) { - super(runtime, replacements, target); + public Templates(Providers providers, TargetDescription target) { + super(providers, target); } public void lower(UnsafeLoadNode load, @SuppressWarnings("unused") LoweringTool tool) { Arguments args = new Arguments(unsafeLoad, load.graph().getGuardsStage()); args.add("object", load.object()); args.add("offset", load.offset()); - args.add("disp", load.displacement()); - template(args).instantiate(runtime, load, DEFAULT_REPLACER, args); + template(args).instantiate(providers.getMetaAccess(), load, DEFAULT_REPLACER, args); } } }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/WriteBarrierSnippets.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/WriteBarrierSnippets.java Fri Oct 11 17:21:14 2013 +0200 @@ -38,6 +38,7 @@ import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; import com.oracle.graal.phases.*; +import com.oracle.graal.phases.util.*; import com.oracle.graal.replacements.*; import com.oracle.graal.replacements.Snippet.ConstantParameter; import com.oracle.graal.replacements.SnippetTemplate.AbstractTemplates; @@ -336,8 +337,8 @@ private final SnippetInfo g1ArrayRangePreWriteBarrier = snippet(WriteBarrierSnippets.class, "g1ArrayRangePreWriteBarrier"); private final SnippetInfo g1ArrayRangePostWriteBarrier = snippet(WriteBarrierSnippets.class, "g1ArrayRangePostWriteBarrier"); - public Templates(CodeCacheProvider runtime, Replacements replacements, TargetDescription target) { - super(runtime, replacements, target); + public Templates(Providers providers, TargetDescription target) { + super(providers, target); } public void lower(SerialWriteBarrier writeBarrier, @SuppressWarnings("unused") LoweringTool tool) { @@ -346,7 +347,7 @@ args.add("location", writeBarrier.getLocation()); args.addConst("usePrecise", writeBarrier.usePrecise()); args.addConst("alwaysNull", ObjectStamp.isObjectAlwaysNull(writeBarrier.getValue())); - template(args).instantiate(runtime, writeBarrier, DEFAULT_REPLACER, args); + template(args).instantiate(providers.getMetaAccess(), writeBarrier, DEFAULT_REPLACER, args); } public void lower(SerialArrayRangeWriteBarrier arrayRangeWriteBarrier, @SuppressWarnings("unused") LoweringTool tool) { @@ -354,7 +355,7 @@ args.add("object", arrayRangeWriteBarrier.getObject()); args.add("startIndex", arrayRangeWriteBarrier.getStartIndex()); args.add("length", arrayRangeWriteBarrier.getLength()); - template(args).instantiate(runtime, arrayRangeWriteBarrier, DEFAULT_REPLACER, args); + template(args).instantiate(providers.getMetaAccess(), arrayRangeWriteBarrier, DEFAULT_REPLACER, args); } public void lower(G1PreWriteBarrier writeBarrierPre, @SuppressWarnings("unused") LoweringTool tool) { @@ -365,7 +366,7 @@ args.addConst("doLoad", writeBarrierPre.doLoad()); args.addConst("nullCheck", writeBarrierPre.getNullCheck()); args.addConst("trace", traceBarrier()); - template(args).instantiate(runtime, writeBarrierPre, DEFAULT_REPLACER, args); + template(args).instantiate(providers.getMetaAccess(), writeBarrierPre, DEFAULT_REPLACER, args); } public void lower(G1ReferentFieldReadBarrier readBarrier, @SuppressWarnings("unused") LoweringTool tool) { @@ -376,7 +377,7 @@ args.addConst("doLoad", readBarrier.doLoad()); args.addConst("nullCheck", false); args.addConst("trace", traceBarrier()); - template(args).instantiate(runtime, readBarrier, DEFAULT_REPLACER, args); + template(args).instantiate(providers.getMetaAccess(), readBarrier, DEFAULT_REPLACER, args); } public void lower(G1PostWriteBarrier writeBarrierPost, @SuppressWarnings("unused") LoweringTool tool) { @@ -387,7 +388,7 @@ args.addConst("usePrecise", writeBarrierPost.usePrecise()); args.addConst("alwaysNull", ObjectStamp.isObjectAlwaysNull(writeBarrierPost.getValue())); args.addConst("trace", traceBarrier()); - template(args).instantiate(runtime, writeBarrierPost, DEFAULT_REPLACER, args); + template(args).instantiate(providers.getMetaAccess(), writeBarrierPost, DEFAULT_REPLACER, args); } public void lower(G1ArrayRangePreWriteBarrier arrayRangeWriteBarrier, @SuppressWarnings("unused") LoweringTool tool) { @@ -395,7 +396,7 @@ args.add("object", arrayRangeWriteBarrier.getObject()); args.add("startIndex", arrayRangeWriteBarrier.getStartIndex()); args.add("length", arrayRangeWriteBarrier.getLength()); - template(args).instantiate(runtime, arrayRangeWriteBarrier, DEFAULT_REPLACER, args); + template(args).instantiate(providers.getMetaAccess(), arrayRangeWriteBarrier, DEFAULT_REPLACER, args); } public void lower(G1ArrayRangePostWriteBarrier arrayRangeWriteBarrier, @SuppressWarnings("unused") LoweringTool tool) { @@ -403,7 +404,7 @@ args.add("object", arrayRangeWriteBarrier.getObject()); args.add("startIndex", arrayRangeWriteBarrier.getStartIndex()); args.add("length", arrayRangeWriteBarrier.getLength()); - template(args).instantiate(runtime, arrayRangeWriteBarrier, DEFAULT_REPLACER, args); + template(args).instantiate(providers.getMetaAccess(), arrayRangeWriteBarrier, DEFAULT_REPLACER, args); } }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ExceptionHandlerStub.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ExceptionHandlerStub.java Fri Oct 11 17:21:14 2013 +0200 @@ -32,9 +32,8 @@ import com.oracle.graal.graph.Node.NodeIntrinsic; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.bridge.*; -import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.hotspot.nodes.*; -import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.phases.util.*; import com.oracle.graal.replacements.*; import com.oracle.graal.replacements.Snippet.Fold; import com.oracle.graal.word.*; @@ -49,8 +48,8 @@ */ public class ExceptionHandlerStub extends SnippetStub { - public ExceptionHandlerStub(final HotSpotRuntime runtime, Replacements replacements, TargetDescription target, HotSpotForeignCallLinkage linkage) { - super(runtime, replacements, target, linkage); + public ExceptionHandlerStub(Providers providers, TargetDescription target, HotSpotForeignCallLinkage linkage) { + super(providers, target, linkage); } /**
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ForeignCallStub.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ForeignCallStub.java Fri Oct 11 17:21:14 2013 +0200 @@ -43,9 +43,9 @@ import com.oracle.graal.nodes.calc.*; 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.type.*; import com.oracle.graal.phases.common.*; +import com.oracle.graal.phases.util.*; import com.oracle.graal.replacements.*; import com.oracle.graal.replacements.nodes.*; import com.oracle.graal.word.*; @@ -85,9 +85,9 @@ * be re-executed. * @param killedLocations the memory locations killed by the stub call */ - public ForeignCallStub(HotSpotRuntime runtime, Replacements replacements, long address, ForeignCallDescriptor descriptor, boolean prependThread, Transition transition, boolean reexecutable, + public ForeignCallStub(Providers providers, long address, ForeignCallDescriptor descriptor, boolean prependThread, Transition transition, boolean reexecutable, LocationIdentity... killedLocations) { - super(runtime, replacements, HotSpotForeignCallLinkage.create(descriptor, 0L, PRESERVES_REGISTERS, JavaCall, JavaCallee, transition, reexecutable, killedLocations)); + super(providers, HotSpotForeignCallLinkage.create(descriptor, 0L, PRESERVES_REGISTERS, JavaCall, JavaCallee, transition, reexecutable, killedLocations)); this.prependThread = prependThread; Class[] targetParameterTypes = createTargetParameters(descriptor); ForeignCallDescriptor targetSig = new ForeignCallDescriptor(descriptor.getName() + ":C", descriptor.getResultType(), targetParameterTypes); @@ -304,8 +304,8 @@ private void inline(InvokeNode invoke) { ResolvedJavaMethod method = ((MethodCallTargetNode) invoke.callTarget()).targetMethod(); - ReplacementsImpl repl = new ReplacementsImpl(runtime, new Assumptions(false), runtime.getTarget()); - StructuredGraph calleeGraph = repl.makeGraph(method, null, null); + ReplacementsImpl repl = new ReplacementsImpl(runtime, runtime, runtime, runtime, new Assumptions(false), runtime.getTarget()); + StructuredGraph calleeGraph = repl.makeGraph(method, null, null, false); InliningUtil.inline(invoke, calleeGraph, false); } }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewArrayStub.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewArrayStub.java Fri Oct 11 17:21:14 2013 +0200 @@ -37,7 +37,7 @@ import com.oracle.graal.hotspot.nodes.*; import com.oracle.graal.hotspot.replacements.*; import com.oracle.graal.nodes.StructuredGraph.*; -import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.phases.util.*; import com.oracle.graal.replacements.*; import com.oracle.graal.replacements.Snippet.ConstantParameter; import com.oracle.graal.replacements.Snippet.Fold; @@ -53,8 +53,8 @@ */ public class NewArrayStub extends SnippetStub { - public NewArrayStub(final HotSpotRuntime runtime, Replacements replacements, TargetDescription target, HotSpotForeignCallLinkage linkage) { - super(runtime, replacements, target, linkage); + public NewArrayStub(Providers providers, TargetDescription target, HotSpotForeignCallLinkage linkage) { + super(providers, target, linkage); } @Override
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewInstanceStub.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewInstanceStub.java Fri Oct 11 17:21:14 2013 +0200 @@ -38,7 +38,7 @@ import com.oracle.graal.hotspot.nodes.*; import com.oracle.graal.hotspot.replacements.*; import com.oracle.graal.nodes.StructuredGraph.*; -import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.phases.util.*; import com.oracle.graal.replacements.*; import com.oracle.graal.replacements.Snippet.ConstantParameter; import com.oracle.graal.replacements.Snippet.Fold; @@ -54,8 +54,8 @@ */ public class NewInstanceStub extends SnippetStub { - public NewInstanceStub(final HotSpotRuntime runtime, Replacements replacements, TargetDescription target, HotSpotForeignCallLinkage linkage) { - super(runtime, replacements, target, linkage); + public NewInstanceStub(Providers providers, TargetDescription target, HotSpotForeignCallLinkage linkage) { + super(providers, target, linkage); } @Override
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/SnippetStub.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/SnippetStub.java Fri Oct 11 17:21:14 2013 +0200 @@ -27,10 +27,9 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.hotspot.*; -import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.StructuredGraph.GuardsStage; -import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.phases.util.*; import com.oracle.graal.replacements.*; import com.oracle.graal.replacements.SnippetTemplate.AbstractTemplates; import com.oracle.graal.replacements.SnippetTemplate.Arguments; @@ -43,8 +42,8 @@ static class Template extends AbstractTemplates { - Template(HotSpotRuntime runtime, Replacements replacements, TargetDescription target, Class<? extends Snippets> declaringClass) { - super(runtime, replacements, target); + Template(Providers providers, TargetDescription target, Class<? extends Snippets> declaringClass) { + super(providers, target); this.info = snippet(declaringClass, null); } @@ -66,9 +65,9 @@ * * @param linkage linkage details for a call to the stub */ - public SnippetStub(HotSpotRuntime runtime, Replacements replacements, TargetDescription target, HotSpotForeignCallLinkage linkage) { - super(runtime, replacements, linkage); - this.snippet = new Template(runtime, replacements, target, getClass()); + public SnippetStub(Providers providers, TargetDescription target, HotSpotForeignCallLinkage linkage) { + super(providers, linkage); + this.snippet = new Template(providers, target, getClass()); } @Override
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java Fri Oct 11 17:21:14 2013 +0200 @@ -40,9 +40,9 @@ import com.oracle.graal.hotspot.nodes.*; import com.oracle.graal.java.*; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.spi.*; import com.oracle.graal.phases.*; import com.oracle.graal.phases.PhasePlan.PhasePosition; +import com.oracle.graal.phases.util.*; //JaCoCo Exclude @@ -93,17 +93,17 @@ protected final HotSpotRuntime runtime; - protected final Replacements replacements; + protected final Providers providers; /** * Creates a new stub. * * @param linkage linkage details for a call to the stub */ - public Stub(HotSpotRuntime runtime, Replacements replacements, HotSpotForeignCallLinkage linkage) { + public Stub(Providers providers, HotSpotForeignCallLinkage linkage) { this.linkage = linkage; - this.runtime = runtime; - this.replacements = replacements; + this.runtime = (HotSpotRuntime) providers.getMetaAccess(); + this.providers = providers; } /** @@ -156,7 +156,7 @@ phasePlan.addPhase(PhasePosition.AFTER_PARSING, graphBuilderPhase); // The stub itself needs the incoming calling convention. CallingConvention incomingCc = linkage.getIncomingCallingConvention(); - final CompilationResult compResult = GraalCompiler.compileGraph(graph, incomingCc, getInstalledCodeOwner(), runtime, replacements, backend, runtime.getTarget(), null, phasePlan, + final CompilationResult compResult = GraalCompiler.compileGraph(graph, incomingCc, getInstalledCodeOwner(), providers, backend, runtime.getTarget(), null, phasePlan, OptimisticOptimizations.ALL, new SpeculationLog(), runtime.getDefaultSuites(), new CompilationResult()); assert destroyedRegisters != null;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/StubUtil.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/StubUtil.java Fri Oct 11 17:21:14 2013 +0200 @@ -22,7 +22,7 @@ */ package com.oracle.graal.hotspot.stubs; -import static com.oracle.graal.api.code.DeoptimizationAction.*; +import static com.oracle.graal.api.meta.DeoptimizationAction.*; import static com.oracle.graal.api.meta.DeoptimizationReason.*; import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; import static com.oracle.graal.hotspot.nodes.CStringNode.*;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/UnwindExceptionToCallerStub.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/UnwindExceptionToCallerStub.java Fri Oct 11 17:21:14 2013 +0200 @@ -32,10 +32,9 @@ import com.oracle.graal.graph.Node.ConstantNodeParameter; 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.spi.*; +import com.oracle.graal.phases.util.*; import com.oracle.graal.replacements.*; import com.oracle.graal.replacements.Snippet.Fold; import com.oracle.graal.word.*; @@ -46,8 +45,8 @@ */ public class UnwindExceptionToCallerStub extends SnippetStub { - public UnwindExceptionToCallerStub(final HotSpotRuntime runtime, Replacements replacements, TargetDescription target, HotSpotForeignCallLinkage linkage) { - super(runtime, replacements, target, linkage); + public UnwindExceptionToCallerStub(Providers providers, TargetDescription target, HotSpotForeignCallLinkage linkage) { + super(providers, target, linkage); } /**
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/VerifyOopStub.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/VerifyOopStub.java Fri Oct 11 17:21:14 2013 +0200 @@ -27,7 +27,7 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.meta.*; -import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.phases.util.*; import com.oracle.graal.replacements.*; /** @@ -35,8 +35,8 @@ */ public class VerifyOopStub extends SnippetStub { - public VerifyOopStub(final HotSpotRuntime runtime, Replacements replacements, TargetDescription target, HotSpotForeignCallLinkage linkage) { - super(runtime, replacements, target, linkage); + public VerifyOopStub(Providers providers, TargetDescription target, HotSpotForeignCallLinkage linkage) { + super(providers, target, linkage); } @Snippet
--- a/graal/com.oracle.graal.java.decompiler.test/src/com/oracle/graal/java/decompiler/test/Test.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.java.decompiler.test/src/com/oracle/graal/java/decompiler/test/Test.java Fri Oct 11 17:21:14 2013 +0200 @@ -27,7 +27,6 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.api.runtime.*; import com.oracle.graal.java.decompiler.test.example.*; -import com.oracle.graal.nodes.spi.*; import com.oracle.graal.printer.*; public class Test { @@ -39,9 +38,9 @@ */ public static void main(String[] args) throws NoSuchMethodException, SecurityException { DebugEnvironment.initialize(System.out); - GraalCodeCacheProvider runtime = Graal.getRequiredCapability(GraalCodeCacheProvider.class); + MetaAccessProvider metaAccess = Graal.getRequiredCapability(MetaAccessProvider.class); Method method = Example.class.getDeclaredMethod("loop7", new Class[]{int.class, int.class}); - final ResolvedJavaMethod javaMethod = runtime.lookupJavaMethod(method); + final ResolvedJavaMethod javaMethod = metaAccess.lookupJavaMethod(method); TestUtil.compileMethod(javaMethod); } }
--- a/graal/com.oracle.graal.java.decompiler.test/src/com/oracle/graal/java/decompiler/test/TestUtil.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.java.decompiler.test/src/com/oracle/graal/java/decompiler/test/TestUtil.java Fri Oct 11 17:21:14 2013 +0200 @@ -32,24 +32,24 @@ import com.oracle.graal.compiler.target.*; import com.oracle.graal.java.*; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.spi.*; import com.oracle.graal.phases.*; import com.oracle.graal.phases.PhasePlan.PhasePosition; import com.oracle.graal.phases.tiers.*; +import com.oracle.graal.phases.util.*; public class TestUtil { public static void compileMethod(ResolvedJavaMethod method) { - GraalCodeCacheProvider runtime = Graal.getRequiredCapability(GraalCodeCacheProvider.class); - Replacements replacements = Graal.getRequiredCapability(Replacements.class); + Providers providers = GraalCompiler.getGraalProviders(); Suites suites = Graal.getRequiredCapability(SuitesProvider.class).createSuites(); StructuredGraph graph = new StructuredGraph(method); - new GraphBuilderPhase(runtime, GraphBuilderConfiguration.getEagerDefault(), OptimisticOptimizations.ALL).apply(graph); + new GraphBuilderPhase(providers.getMetaAccess(), GraphBuilderConfiguration.getEagerDefault(), OptimisticOptimizations.ALL).apply(graph); PhasePlan phasePlan = new PhasePlan(); - GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(runtime, GraphBuilderConfiguration.getDefault(), OptimisticOptimizations.ALL); + GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(providers.getMetaAccess(), GraphBuilderConfiguration.getDefault(), OptimisticOptimizations.ALL); phasePlan.addPhase(PhasePosition.AFTER_PARSING, graphBuilderPhase); - CallingConvention cc = getCallingConvention(runtime, Type.JavaCallee, graph.method(), false); + CallingConvention cc = getCallingConvention(providers.getCodeCache(), Type.JavaCallee, graph.method(), false); Backend backend = Graal.getRequiredCapability(Backend.class); - GraalCompiler.compileGraph(graph, cc, method, runtime, replacements, backend, runtime.getTarget(), null, phasePlan, OptimisticOptimizations.ALL, new SpeculationLog(), suites, new CompilationResult()); + GraalCompiler.compileGraph(graph, cc, method, providers, backend, providers.getCodeCache().getTarget(), null, phasePlan, OptimisticOptimizations.ALL, new SpeculationLog(), suites, + new CompilationResult()); } }
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Fri Oct 11 17:21:14 2013 +0200 @@ -22,8 +22,8 @@ */ package com.oracle.graal.java; -import static com.oracle.graal.api.code.DeoptimizationAction.*; import static com.oracle.graal.api.code.TypeCheckHints.*; +import static com.oracle.graal.api.meta.DeoptimizationAction.*; import static com.oracle.graal.api.meta.DeoptimizationReason.*; import static com.oracle.graal.bytecode.Bytecodes.*; import static com.oracle.graal.java.GraphBuilderPhase.RuntimeCalls.*; @@ -50,7 +50,6 @@ import com.oracle.graal.nodes.type.*; import com.oracle.graal.nodes.util.*; import com.oracle.graal.phases.*; -import com.oracle.graal.phases.util.*; /** * The {@code GraphBuilder} class parses the bytecode of a method and builds the IR graph. @@ -86,7 +85,7 @@ */ protected BlockPlaceholderNode placeholders; - private final MetaAccessProvider runtime; + private final MetaAccessProvider metaAccess; private ConstantPool constantPool; private ResolvedJavaMethod method; private int entryBCI; @@ -151,11 +150,11 @@ return currentGraph; } - public GraphBuilderPhase(MetaAccessProvider runtime, GraphBuilderConfiguration graphBuilderConfig, OptimisticOptimizations optimisticOpts) { + public GraphBuilderPhase(MetaAccessProvider metaAccess, GraphBuilderConfiguration graphBuilderConfig, OptimisticOptimizations optimisticOpts) { this.graphBuilderConfig = graphBuilderConfig; this.optimisticOpts = optimisticOpts; - this.runtime = runtime; - assert runtime != null; + this.metaAccess = metaAccess; + assert metaAccess != null; } @Override @@ -436,7 +435,7 @@ DispatchBeginNode dispatchBegin; if (exceptionObject == null) { - dispatchBegin = currentGraph.add(new ExceptionObjectNode(runtime)); + dispatchBegin = currentGraph.add(new ExceptionObjectNode(metaAccess)); dispatchState.apush(dispatchBegin); dispatchState.setRethrowException(true); dispatchBegin.setStateAfter(dispatchState.create(bci)); @@ -895,7 +894,7 @@ private void genNewPrimitiveArray(int typeCode) { Class<?> clazz = arrayTypeCodeToClass(typeCode); - ResolvedJavaType elementType = runtime.lookupJavaType(clazz); + ResolvedJavaType elementType = metaAccess.lookupJavaType(clazz); frameState.apush(append(new NewArrayNode(elementType, frameState.ipop(), true))); } @@ -957,10 +956,10 @@ lastInstr = falseSucc; if (OmitHotExceptionStacktrace.getValue()) { - ValueNode exception = ConstantNode.forObject(cachedNullPointerException, runtime, currentGraph); + ValueNode exception = ConstantNode.forObject(cachedNullPointerException, metaAccess, currentGraph); trueSucc.setNext(handleException(exception, bci())); } else { - ForeignCallNode call = currentGraph.add(new ForeignCallNode(runtime, CREATE_NULL_POINTER_EXCEPTION)); + ForeignCallNode call = currentGraph.add(new ForeignCallNode(metaAccess, CREATE_NULL_POINTER_EXCEPTION)); call.setStateAfter(frameState.create(bci())); trueSucc.setNext(call); call.setNext(handleException(call, bci())); @@ -981,10 +980,10 @@ lastInstr = trueSucc; if (OmitHotExceptionStacktrace.getValue()) { - ValueNode exception = ConstantNode.forObject(cachedArrayIndexOutOfBoundsException, runtime, currentGraph); + ValueNode exception = ConstantNode.forObject(cachedArrayIndexOutOfBoundsException, metaAccess, currentGraph); falseSucc.setNext(handleException(exception, bci())); } else { - ForeignCallNode call = currentGraph.add(new ForeignCallNode(runtime, CREATE_OUT_OF_BOUNDS_EXCEPTION, index)); + ForeignCallNode call = currentGraph.add(new ForeignCallNode(metaAccess, CREATE_OUT_OF_BOUNDS_EXCEPTION, index)); call.setStateAfter(frameState.create(bci())); falseSucc.setNext(call); call.setNext(handleException(call, bci())); @@ -1082,7 +1081,7 @@ if (target instanceof ResolvedJavaMethod) { Object appendix = constantPool.lookupAppendix(stream.readCPI4(), Bytecodes.INVOKEDYNAMIC); if (appendix != null) { - frameState.apush(ConstantNode.forObject(appendix, runtime, currentGraph)); + frameState.apush(ConstantNode.forObject(appendix, metaAccess, currentGraph)); } ValueNode[] args = frameState.popArguments(target.getSignature().getParameterSlots(false), target.getSignature().getParameterCount(false)); appendInvoke(InvokeKind.Static, (ResolvedJavaMethod) target, args); @@ -1099,7 +1098,7 @@ boolean hasReceiver = !isStatic(((ResolvedJavaMethod) target).getModifiers()); Object appendix = constantPool.lookupAppendix(stream.readCPI(), Bytecodes.INVOKEVIRTUAL); if (appendix != null) { - frameState.apush(ConstantNode.forObject(appendix, runtime, currentGraph)); + frameState.apush(ConstantNode.forObject(appendix, metaAccess, currentGraph)); } ValueNode[] args = frameState.popArguments(target.getSignature().getParameterSlots(hasReceiver), target.getSignature().getParameterCount(hasReceiver)); if (hasReceiver) { @@ -1352,7 +1351,7 @@ protected ConstantNode appendConstant(Constant constant) { assert constant != null; - return ConstantNode.forConstant(constant, runtime, currentGraph); + return ConstantNode.forConstant(constant, metaAccess, currentGraph); } private <T extends ControlSinkNode> T append(T fixed) { @@ -1693,20 +1692,7 @@ } private static boolean isBlockEnd(Node n) { - return trueSuccessorCount(n) > 1 || n instanceof ReturnNode || n instanceof UnwindNode || n instanceof DeoptimizeNode; - } - - private static int trueSuccessorCount(Node n) { - if (n == null) { - return 0; - } - int i = 0; - for (Node s : n.successors()) { - if (Util.isFixed(s)) { - i++; - } - } - return i; + return n instanceof ControlSplitNode || n instanceof ControlSinkNode; } private void iterateBytecodesForBlock(Block block) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/VerifyOptionsPhase.java Fri Oct 11 17:21:14 2013 +0200 @@ -0,0 +1,146 @@ +/* + * 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.java; + +import static com.oracle.graal.api.meta.MetaUtil.*; +import static java.lang.reflect.Modifier.*; + +import java.util.*; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.java.*; +import com.oracle.graal.nodes.util.*; +import com.oracle.graal.options.*; +import com.oracle.graal.phases.*; + +/** + * Verifies that a class declaring one or more {@linkplain OptionValue options} has a class + * initializer that only initializes the option(s). This sanity check mitigates the possibility of + * an option value being used before the code that sets the value (e.g., from the command line) has + * been executed. + */ +public class VerifyOptionsPhase extends Phase { + + public static boolean checkOptions(MetaAccessProvider metaAccess) { + ServiceLoader<Options> sl = ServiceLoader.loadInstalled(Options.class); + Set<ResolvedJavaType> checked = new HashSet<>(); + for (Options opts : sl) { + for (OptionDescriptor desc : opts) { + ResolvedJavaType holder = metaAccess.lookupJavaType(desc.getDeclaringClass()); + checkType(holder, desc, metaAccess, checked); + } + } + return true; + } + + private static void checkType(ResolvedJavaType type, OptionDescriptor option, MetaAccessProvider metaAccess, Set<ResolvedJavaType> checked) { + if (!checked.contains(type)) { + checked.add(type); + ResolvedJavaType superType = type.getSuperclass(); + if (superType != null && !MetaUtil.isJavaLangObject(superType)) { + checkType(superType, option, metaAccess, checked); + } + for (ResolvedJavaMethod method : type.getDeclaredMethods()) { + if (method.isClassInitializer()) { + StructuredGraph graph = new StructuredGraph(method); + new GraphBuilderPhase(metaAccess, GraphBuilderConfiguration.getEagerDefault(), OptimisticOptimizations.ALL).apply(graph); + new VerifyOptionsPhase(type, metaAccess, option).apply(graph); + } + } + } + } + + private final MetaAccessProvider metaAccess; + private final ResolvedJavaType declaringClass; + private final ResolvedJavaType optionValueType; + private final Set<ResolvedJavaType> boxingTypes; + private final OptionDescriptor option; + + public VerifyOptionsPhase(ResolvedJavaType declaringClass, MetaAccessProvider metaAccess, OptionDescriptor option) { + this.metaAccess = metaAccess; + this.declaringClass = declaringClass; + this.optionValueType = metaAccess.lookupJavaType(OptionValue.class); + this.option = option; + this.boxingTypes = new HashSet<>(); + for (Class c : new Class[]{Boolean.class, Byte.class, Short.class, Character.class, Integer.class, Float.class, Long.class, Double.class}) { + this.boxingTypes.add(metaAccess.lookupJavaType(c)); + } + } + + /** + * Checks whether a given method is allowed to be called. + */ + private boolean checkInvokeTarget(ResolvedJavaMethod method) { + ResolvedJavaType holder = method.getDeclaringClass(); + if (method.isConstructor()) { + if (optionValueType.isAssignableFrom(holder)) { + return true; + } + } else if (boxingTypes.contains(holder)) { + return method.getName().equals("valueOf"); + } else if (method.getDeclaringClass() == metaAccess.lookupJavaType(Class.class)) { + return method.getName().equals("desiredAssertionStatus"); + } else if (method.getDeclaringClass().equals(declaringClass)) { + return (method.getName().equals("$jacocoInit")); + } + return false; + } + + @Override + protected void run(StructuredGraph graph) { + for (ValueNode node : graph.getNodes().filter(ValueNode.class)) { + if (node instanceof StoreFieldNode) { + ResolvedJavaField field = ((StoreFieldNode) node).field(); + verify(field.getDeclaringClass() == declaringClass, node, "store to field " + format("%H.%n", field)); + verify(isStatic(field.getModifiers()), node, "store to field " + format("%H.%n", field)); + if (optionValueType.isAssignableFrom((ResolvedJavaType) field.getType())) { + verify(isFinal(field.getModifiers()), node, "option field " + format("%H.%n", field) + " not final"); + } else { + verify((field.isSynthetic()), node, "store to non-synthetic field " + format("%H.%n", field)); + } + } else if (node instanceof Invoke) { + Invoke invoke = (Invoke) node; + MethodCallTargetNode callTarget = (MethodCallTargetNode) invoke.callTarget(); + ResolvedJavaMethod targetMethod = callTarget.targetMethod(); + verify(checkInvokeTarget(targetMethod), node, "invocation of " + format("%H.%n(%p)", targetMethod)); + } + } + } + + private void verify(boolean condition, Node node, String message) { + if (!condition) { + error(node, message); + } + } + + private void error(Node node, String message) { + String loc = GraphUtil.approxSourceLocation(node); + throw new GraalInternalError(String.format("The " + option.getName() + " option is declared in " + option.getDeclaringClass() + + " whose class hierarchy contains a class initializer (in %s) with a code pattern at or near %s implying an action other than initialization of an option:%n%n %s%n%n" + + "The recommended solution is to move " + option.getName() + " into a separate class (e.g., " + option.getDeclaringClass().getName() + ".Options).%n", + toJavaName(declaringClass), loc, message)); + } +}
--- a/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/JTTTest.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/JTTTest.java Fri Oct 11 17:21:14 2013 +0200 @@ -50,7 +50,7 @@ Object[] argsToBind; public JTTTest() { - Assert.assertNotNull(runtime); + Assert.assertNotNull(getCodeCache()); } @Override @@ -59,12 +59,12 @@ if (argsToBind != null) { Object receiver = isStatic(m.getModifiers()) ? null : this; Object[] args = argsWithReceiver(receiver, argsToBind); - JavaType[] parameterTypes = signatureToTypes(runtime.lookupJavaMethod(m)); + JavaType[] parameterTypes = signatureToTypes(getMetaAccess().lookupJavaMethod(m)); assert parameterTypes.length == args.length; for (int i = 0; i < args.length; i++) { LocalNode local = graph.getLocal(i); Constant c = Constant.forBoxed(parameterTypes[i].getKind(), args[i]); - ConstantNode replacement = ConstantNode.forConstant(c, runtime, graph); + ConstantNode replacement = ConstantNode.forConstant(c, getMetaAccess(), graph); local.replaceAtUsages(replacement); } }
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Call.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Call.java Fri Oct 11 17:21:14 2013 +0200 @@ -28,6 +28,7 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.amd64.*; +import com.oracle.graal.asm.amd64.AMD64Assembler.*; import com.oracle.graal.lir.*; import com.oracle.graal.lir.asm.*; import com.oracle.graal.nodes.spi.*; @@ -182,6 +183,14 @@ masm.ensureUniquePC(); } + public static void directConditionalJmp(TargetMethodAssembler tasm, AMD64MacroAssembler masm, InvokeTarget target, ConditionFlag cond) { + int before = masm.codeBuffer.position(); + masm.jcc(cond, 0, true); + int after = masm.codeBuffer.position(); + tasm.recordDirectCall(before, after, target, null); + masm.ensureUniquePC(); + } + public static void indirectCall(TargetMethodAssembler tasm, AMD64MacroAssembler masm, Register dst, InvokeTarget callTarget, LIRFrameState info) { int before = masm.codeBuffer.position(); masm.call(dst);
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64ControlFlow.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64ControlFlow.java Fri Oct 11 17:21:14 2013 +0200 @@ -153,7 +153,7 @@ if (key.getKind() == Kind.Int) { Register intKey = asIntReg(key); for (int i = 0; i < keyConstants.length; i++) { - if (tasm.runtime.needsDataPatch(keyConstants[i])) { + if (tasm.codeCache.needsDataPatch(keyConstants[i])) { tasm.recordDataReferenceInCode(keyConstants[i], 0, true); } long lc = keyConstants[i].asLong();
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64FrameMap.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64FrameMap.java Fri Oct 11 17:21:14 2013 +0200 @@ -28,12 +28,12 @@ /** * AMD64 specific frame map. - * + * * This is the format of an AMD64 stack frame: - * + * * <pre> * Base Contents - * + * * : : ----- * caller | incoming overflow argument n | ^ * frame : ... : | positive @@ -55,9 +55,9 @@ * : ... : | positive | | * | outgoing overflow argument 0 | | offsets v v * %sp--> +--------------------------------+--------------------------- - * + * * </pre> - * + * * The spill slot area also includes stack allocated memory blocks (ALLOCA blocks). The size of such * a block may be greater than the size of a normal spill slot or the word size. * <p> @@ -69,8 +69,8 @@ */ public class AMD64FrameMap extends FrameMap { - public AMD64FrameMap(CodeCacheProvider runtime, TargetDescription target, RegisterConfig registerConfig) { - super(runtime, target, registerConfig); + public AMD64FrameMap(CodeCacheProvider codeCache, TargetDescription target, RegisterConfig registerConfig) { + super(codeCache, target, registerConfig); // (negative) offset relative to sp + total frame size initialSpillSize = returnAddressSize() + calleeSaveAreaSize(); spillSize = initialSpillSize;
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Move.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Move.java Fri Oct 11 17:21:14 2013 +0200 @@ -441,7 +441,7 @@ */ switch (input.getKind().getStackKind()) { case Int: - if (tasm.runtime.needsDataPatch(input)) { + if (tasm.codeCache.needsDataPatch(input)) { tasm.recordDataReferenceInCode(input, 0, true); } // Do not optimize with an XOR as this instruction may be between @@ -451,7 +451,7 @@ break; case Long: - if (tasm.runtime.needsDataPatch(input)) { + if (tasm.codeCache.needsDataPatch(input)) { tasm.recordDataReferenceInCode(input, 0, true); } // Do not optimize with an XOR as this instruction may be between @@ -462,7 +462,7 @@ case Float: // This is *not* the same as 'constant == 0.0f' in the case where constant is -0.0f if (Float.floatToRawIntBits(input.asFloat()) == Float.floatToRawIntBits(0.0f)) { - assert !tasm.runtime.needsDataPatch(input); + assert !tasm.codeCache.needsDataPatch(input); masm.xorps(asFloatReg(result), asFloatReg(result)); } else { masm.movflt(asFloatReg(result), (AMD64Address) tasm.asFloatConstRef(input)); @@ -471,7 +471,7 @@ case Double: // This is *not* the same as 'constant == 0.0d' in the case where constant is -0.0d if (Double.doubleToRawLongBits(input.asDouble()) == Double.doubleToRawLongBits(0.0d)) { - assert !tasm.runtime.needsDataPatch(input); + assert !tasm.codeCache.needsDataPatch(input); masm.xorpd(asDoubleReg(result), asDoubleReg(result)); } else { masm.movdbl(asDoubleReg(result), (AMD64Address) tasm.asDoubleConstRef(input)); @@ -496,7 +496,7 @@ } private static void const2stack(TargetMethodAssembler tasm, AMD64MacroAssembler masm, Value result, Constant input) { - assert !tasm.runtime.needsDataPatch(input); + assert !tasm.codeCache.needsDataPatch(input); AMD64Address dest = (AMD64Address) tasm.asAddress(result); switch (input.getKind().getStackKind()) { case Int:
--- a/graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILFrameMap.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILFrameMap.java Fri Oct 11 17:21:14 2013 +0200 @@ -37,8 +37,8 @@ */ public final class HSAILFrameMap extends FrameMap { - public HSAILFrameMap(CodeCacheProvider runtime, TargetDescription target, RegisterConfig registerConfig) { - super(runtime, target, registerConfig); + public HSAILFrameMap(CodeCacheProvider codeCache, TargetDescription target, RegisterConfig registerConfig) { + super(codeCache, target, registerConfig); } @Override
--- a/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXArithmetic.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXArithmetic.java Fri Oct 11 17:21:14 2013 +0200 @@ -75,7 +75,7 @@ case D2I: case D2L: case D2F: - break; // cvt handles the move + break; // cvt handles the move default: PTXMove.move(tasm, masm, result, x); } @@ -422,11 +422,73 @@ } private static void verifyKind(PTXArithmetic opcode, Value result, Value x, Value y) { - if (((opcode.name().startsWith("I") && result.getKind() == Kind.Int && x.getKind().getStackKind() == Kind.Int && y.getKind().getStackKind() == Kind.Int) - || (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)) == false) { - throw GraalInternalError.shouldNotReachHere("opcode: " + opcode.name() + " x: " + x.getKind() + " y: " + y.getKind()); + 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: + rk = result.getKind(); + xk = x.getKind(); + yk = y.getKind(); + assert rk == Kind.Long && xk == Kind.Long && yk == Kind.Long; + break; + case LSHL: + case LSHR: + case LUSHR: + rk = result.getKind(); + xk = x.getKind(); + yk = y.getKind(); + assert rk == Kind.Long && xk == Kind.Long && (yk == Kind.Int || 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 : + "opcode=" + opcode + ", result kind=" + rk + ", x kind=" + xk + ", y kind=" + yk; + break; + default: + throw GraalInternalError.shouldNotReachHere("missing: " + opcode); } } }
--- a/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXControlFlow.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXControlFlow.java Fri Oct 11 17:21:14 2013 +0200 @@ -24,6 +24,7 @@ import static com.oracle.graal.asm.ptx.PTXAssembler.*; import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; +import static com.oracle.graal.lir.LIRValueUtil.*; import static com.oracle.graal.nodes.calc.Condition.*; import com.oracle.graal.api.code.CompilationResult.JumpTable; @@ -57,7 +58,8 @@ public static class ReturnNoValOp extends PTXLIRInstruction { - public ReturnNoValOp() { } + public ReturnNoValOp() { + } @Override public void emitCode(TargetMethodAssembler tasm, PTXAssembler masm) { @@ -97,30 +99,28 @@ } } - @SuppressWarnings("unused") public static class CondMoveOp extends PTXLIRInstruction { @Def({REG, HINT}) protected Value result; @Alive({REG}) protected Value trueValue; @Use({REG, STACK, CONST}) protected Value falseValue; private final Condition condition; + private final int predicate; - public CondMoveOp(Variable result, Condition condition, Variable trueValue, Value falseValue) { + public CondMoveOp(Variable result, Condition condition, Variable trueValue, Value falseValue, int predicateRegister) { this.result = result; this.condition = condition; this.trueValue = trueValue; this.falseValue = falseValue; + this.predicate = predicateRegister; } @Override public void emitCode(TargetMethodAssembler tasm, PTXAssembler masm) { - // cmove(tasm, masm, result, false, condition, false, trueValue, falseValue); - // see 8.3 Predicated Execution p. 61 of PTX ISA 3.1 - throw new InternalError("NYI"); + cmove(tasm, masm, result, false, condition, false, trueValue, falseValue, predicate); } } - @SuppressWarnings("unused") public static class FloatCondMoveOp extends PTXLIRInstruction { @Def({REG}) protected Value result; @@ -128,20 +128,71 @@ @Alive({REG}) protected Value falseValue; private final Condition condition; private final boolean unorderedIsTrue; + private final int predicate; - public FloatCondMoveOp(Variable result, Condition condition, boolean unorderedIsTrue, Variable trueValue, Variable falseValue) { + public FloatCondMoveOp(Variable result, Condition condition, boolean unorderedIsTrue, Variable trueValue, Variable falseValue, int predicateRegister) { this.result = result; this.condition = condition; this.unorderedIsTrue = unorderedIsTrue; this.trueValue = trueValue; this.falseValue = falseValue; + this.predicate = predicateRegister; } @Override public void emitCode(TargetMethodAssembler tasm, PTXAssembler masm) { - // cmove(tasm, masm, result, true, condition, unorderedIsTrue, trueValue, falseValue); - // see 8.3 Predicated Execution p. 61 of PTX ISA 3.1 - throw new InternalError("NYI"); + cmove(tasm, masm, result, true, condition, unorderedIsTrue, trueValue, falseValue, predicate); + } + } + + private static void cmove(TargetMethodAssembler tasm, PTXAssembler asm, Value result, boolean isFloat, Condition condition, boolean unorderedIsTrue, Value trueValue, Value falseValue, + int predicateRegister) { + // check that we don't overwrite an input operand before it is used. + assert !result.equals(trueValue); + + PTXMove.move(tasm, asm, result, falseValue); + cmove(asm, result, trueValue, predicateRegister); + + if (isFloat) { + if (unorderedIsTrue && !trueOnUnordered(condition)) { + // cmove(tasm, masm, result, ConditionFlag.Parity, trueValue); + throw GraalInternalError.unimplemented(); + } else if (!unorderedIsTrue && trueOnUnordered(condition)) { + // cmove(tasm, masm, result, ConditionFlag.Parity, falseValue); + throw GraalInternalError.unimplemented(); + } + } + } + + private static boolean trueOnUnordered(Condition condition) { + switch (condition) { + case NE: + case EQ: + return false; + case LT: + case GE: + return true; + default: + throw GraalInternalError.shouldNotReachHere(); + } + } + + private static void cmove(PTXAssembler asm, Value result, Value other, int predicateRegister) { + if (isVariable(other)) { + assert !asVariable(other).equals(asVariable(result)) : "other already overwritten by previous move"; + + switch (other.getKind()) { + case Int: + new Mov(asVariable(result), other, predicateRegister).emit(asm); + break; + case Long: + new Mov(asVariable(result), other, predicateRegister).emit(asm); + break; + default: + throw new InternalError("unhandled: " + other.getKind()); + } + } else { + throw GraalInternalError.shouldNotReachHere("cmove: not register"); } } @@ -171,7 +222,7 @@ if (keyKind == Kind.Int || keyKind == Kind.Long) { for (int i = 0; i < keyConstants.length; i++) { - if (tasm.runtime.needsDataPatch(keyConstants[i])) { + if (tasm.codeCache.needsDataPatch(keyConstants[i])) { tasm.recordDataReferenceInCode(keyConstants[i], 0, true); } new Setp(EQ, keyConstants[i], key, predRegNum).emit(masm); @@ -232,7 +283,9 @@ @SuppressWarnings("unused") private static void tableswitch(TargetMethodAssembler tasm, PTXAssembler masm, int lowKey, LabelRef defaultTarget, LabelRef[] targets, Value value, Value scratch, int predNum) { 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 @@ -244,15 +297,20 @@ // Jump to default target if index is not within the jump table if (defaultTarget != null) { - masm.bra(defaultTarget.label().toString(), predNum); + masm.bra(masm.nameOf(defaultTarget.label()), predNum); } // address of jump table int tablePos = buf.position(); JumpTable jt = new JumpTable(tablePos, lowKey, highKey, 4); + String name = "jumptable" + jt.position; + + new Global(value, name, targets).emit(masm); + + // bra(Value, name); + tasm.compilationResult.addAnnotation(jt); - // PTX: unimp: tableswitch extract } }
--- a/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXFrameMap.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXFrameMap.java Fri Oct 11 17:21:14 2013 +0200 @@ -37,8 +37,8 @@ */ public final class PTXFrameMap extends FrameMap { - public PTXFrameMap(CodeCacheProvider runtime, TargetDescription target, RegisterConfig registerConfig) { - super(runtime, target, registerConfig); + public PTXFrameMap(CodeCacheProvider codeCache, TargetDescription target, RegisterConfig registerConfig) { + super(codeCache, target, registerConfig); } @Override
--- a/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXMemOp.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXMemOp.java Fri Oct 11 17:21:14 2013 +0200 @@ -43,7 +43,8 @@ @Use({COMPOSITE}) protected PTXAddressValue address; @State protected LIRFrameState state; - public LoadOp(Kind kind, Variable result, PTXAddressValue address, LIRFrameState state) { + public LoadOp(Kind kind, Variable result, PTXAddressValue address, + LIRFrameState state) { this.kind = kind; this.result = result; this.address = address; @@ -62,7 +63,8 @@ case Float: case Double: case Object: - new Ld(Global, result, addr.getBase(), Constant.forLong(addr.getDisplacement())).emit(masm); + new Ld(Global, result, addr.getBase(), + Constant.forLong(addr.getDisplacement())).emit(masm); break; default: throw GraalInternalError.shouldNotReachHere(); @@ -97,7 +99,8 @@ case Float: case Double: case Object: - new St(Global, input, addr.getBase(), Constant.forLong(addr.getDisplacement())).emit(masm); + new St(Global, input, addr.getBase(), + Constant.forLong(addr.getDisplacement())).emit(masm); break; default: throw GraalInternalError.shouldNotReachHere("missing: " + address.getKind()); @@ -114,7 +117,8 @@ @Use({COMPOSITE}) protected PTXAddressValue address; @State protected LIRFrameState state; - public LoadParamOp(Kind kind, Variable result, PTXAddressValue address, LIRFrameState state) { + public LoadParamOp(Kind kind, Variable result, PTXAddressValue address, + LIRFrameState state) { this.kind = kind; this.result = result; this.address = address; @@ -133,7 +137,8 @@ case Float: case Double: case Object: - new Ld(Parameter, result, addr.getBase(), Constant.forLong(addr.getDisplacement())).emit(masm); + new Ld(Parameter, result, addr.getBase(), + Constant.forLong(addr.getDisplacement())).emit(masm); break; default: throw GraalInternalError.shouldNotReachHere(); @@ -151,7 +156,8 @@ @Use({COMPOSITE}) protected PTXAddressValue address; @State protected LIRFrameState state; - public LoadReturnAddrOp(Kind kind, Variable result, PTXAddressValue address, LIRFrameState state) { + public LoadReturnAddrOp(Kind kind, Variable result, + PTXAddressValue address, LIRFrameState state) { this.kind = kind; this.result = result; this.address = address; @@ -166,7 +172,8 @@ case Long: case Float: case Double: - new Ld(Parameter, result, addr.getBase(), Constant.forLong(addr.getDisplacement())).emit(masm); + new Ld(Parameter, result, addr.getBase(), + Constant.forLong(addr.getDisplacement())).emit(masm); break; default: throw GraalInternalError.shouldNotReachHere(); @@ -183,7 +190,8 @@ @Use({REG}) protected Variable input; @State protected LIRFrameState state; - public StoreReturnValOp(Kind kind, PTXAddressValue address, Variable input, LIRFrameState state) { + public StoreReturnValOp(Kind kind, PTXAddressValue address, + Variable input, LIRFrameState state) { this.kind = kind; this.address = address; this.input = input; @@ -202,7 +210,8 @@ case Float: case Double: case Object: - new St(Global, input, addr.getBase(), Constant.forLong(addr.getDisplacement())).emit(masm); + new St(Global, input, addr.getBase(), + Constant.forLong(addr.getDisplacement())).emit(masm); break; default: throw GraalInternalError.shouldNotReachHere("missing: " + address.getKind());
--- a/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXMove.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXMove.java Fri Oct 11 17:21:14 2013 +0200 @@ -215,7 +215,7 @@ switch (input.getKind().getStackKind()) { case Int: case Long: - if (tasm.runtime.needsDataPatch(input)) { + if (tasm.codeCache.needsDataPatch(input)) { tasm.recordDataReferenceInCode(input, 0, true); } new Mov(dest, input).emit(masm);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXTestOp.java Fri Oct 11 17:21:14 2013 +0200 @@ -0,0 +1,64 @@ +/* + * 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.ptx; + +import static com.oracle.graal.asm.ptx.PTXAssembler.BooleanOperator.*; +import static com.oracle.graal.asm.ptx.PTXAssembler.*; +import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.asm.ptx.*; +import com.oracle.graal.lir.asm.*; +import com.oracle.graal.nodes.calc.Condition; + +public class PTXTestOp extends PTXLIRInstruction { + + @Use({REG}) protected Value x; + @Use({REG, STACK, CONST}) protected Value y; + int predicate; + + public PTXTestOp(Value x, Value y, int predicate) { + this.x = x; + this.y = y; + this.predicate = predicate; + } + + @Override + public void emitCode(TargetMethodAssembler tasm, PTXAssembler masm) { + emit(masm, x, y, predicate); + } + + @Override + protected void verify() { + super.verify(); + assert (x.getKind() == Kind.Int && y.getKind().getStackKind() == Kind.Int) || (x.getKind() == Kind.Long && y.getKind() == Kind.Long) : x + " " + y; + } + + public static void emit(PTXAssembler masm, Value x, Value y, int predicate) { + /* + * This is not yet quite right - as the result for the equivalent in + * ControlPTXText.testIntegerTestBranch2I is wrong. + */ + new Setp(Condition.EQ, AND, x, y, predicate).emit(masm); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/ParallelOver.java Fri Oct 11 17:21:14 2013 +0200 @@ -0,0 +1,36 @@ +/* + * 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.ptx; + +import static com.oracle.graal.lir.ptx.ThreadDimension.*; + +import java.lang.annotation.*; +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.PARAMETER}) +public @interface ParallelOver { + + String value() default ""; + + ThreadDimension dimension() default X; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/ThreadDimension.java Fri Oct 11 17:21:14 2013 +0200 @@ -0,0 +1,30 @@ +/* + * 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.ptx; + +public enum ThreadDimension { +X, +Y, +Z +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/Warp.java Fri Oct 11 17:21:14 2013 +0200 @@ -0,0 +1,37 @@ +/* + * 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.ptx; + +import static com.oracle.graal.lir.ptx.ThreadDimension.*; + +import java.lang.annotation.*; + +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.PARAMETER}) +public @interface Warp { + + String value() default ""; + + ThreadDimension dimension() default X; +} +
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java Fri Oct 11 17:21:14 2013 +0200 @@ -279,7 +279,7 @@ if (key.getKind() == Kind.Int) { Register intKey = asIntReg(key); for (int i = 0; i < keyConstants.length; i++) { - if (tasm.runtime.needsDataPatch(keyConstants[i])) { + if (tasm.codeCache.needsDataPatch(keyConstants[i])) { tasm.recordDataReferenceInCode(keyConstants[i], 0, true); } long lc = keyConstants[i].asLong();
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCFrameMap.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCFrameMap.java Fri Oct 11 17:21:14 2013 +0200 @@ -69,8 +69,8 @@ */ public final class SPARCFrameMap extends FrameMap { - public SPARCFrameMap(CodeCacheProvider runtime, TargetDescription target, RegisterConfig registerConfig) { - super(runtime, target, registerConfig); + public SPARCFrameMap(CodeCacheProvider codeCache, TargetDescription target, RegisterConfig registerConfig) { + super(codeCache, target, registerConfig); // offset relative to sp + total frame size initialSpillSize = 0; spillSize = initialSpillSize;
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java Fri Oct 11 17:21:14 2013 +0200 @@ -413,7 +413,7 @@ private static void const2reg(TargetMethodAssembler tasm, SPARCMacroAssembler masm, Value result, Constant input) { switch (input.getKind().getStackKind()) { case Int: - if (tasm.runtime.needsDataPatch(input)) { + if (tasm.codeCache.needsDataPatch(input)) { tasm.recordDataReferenceInCode(input, 0, true); new Setuw(input.asInt(), asRegister(result)).emit(masm); } else { @@ -425,7 +425,7 @@ } break; case Long: { - if (tasm.runtime.needsDataPatch(input)) { + if (tasm.codeCache.needsDataPatch(input)) { tasm.recordDataReferenceInCode(input, 0, true); new Setx(input.asLong(), asRegister(result), true).emit(masm); } else {
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/FrameMap.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/FrameMap.java Fri Oct 11 17:21:14 2013 +0200 @@ -40,7 +40,6 @@ */ public abstract class FrameMap { - public final CodeCacheProvider runtime; public final TargetDescription target; public final RegisterConfig registerConfig; @@ -87,12 +86,11 @@ /** * Creates a new frame map for the specified method. */ - public FrameMap(CodeCacheProvider runtime, TargetDescription target, RegisterConfig registerConfig) { - this.runtime = runtime; + public FrameMap(CodeCacheProvider codeCache, TargetDescription target, RegisterConfig registerConfig) { this.target = target; this.registerConfig = registerConfig; this.frameSize = -1; - this.outgoingSize = runtime.getMinimumOutgoingSize(); + this.outgoingSize = codeCache.getMinimumOutgoingSize(); this.objectStackBlocks = new ArrayList<>(); } @@ -116,7 +114,7 @@ /** * Gets the frame size of the compiled frame, not including the size of the * {@link Architecture#getReturnAddressSize() return address slot}. - * + * * @return The size of the frame (in bytes). */ public int frameSize() { @@ -136,7 +134,7 @@ /** * Gets the total frame size of the compiled frame, including the size of the * {@link Architecture#getReturnAddressSize() return address slot}. - * + * * @return The total size of the frame (in bytes). */ public abstract int totalFrameSize(); @@ -149,7 +147,7 @@ /** * Aligns the given frame size to the stack alignment size and return the aligned size. - * + * * @param size the initial frame size to be aligned * @return the aligned frame size */ @@ -181,7 +179,7 @@ /** * Computes the offset of a stack slot relative to the frame register. - * + * * @param slot a stack slot * @return the offset of the stack slot */ @@ -197,7 +195,7 @@ /** * Computes the index of a stack slot relative to slot 0. This is also the bit index of stack * slots in the reference map. - * + * * @param slot a stack slot * @return the index of the stack slot */ @@ -209,7 +207,7 @@ /** * Gets the offset from the stack pointer to the stack area where callee-saved registers are * stored. - * + * * @return The offset to the callee save area (in bytes). */ public abstract int offsetToCalleeSaveArea(); @@ -217,7 +215,7 @@ /** * Informs the frame map that the compiled code calls a particular method, which may need stack * space for outgoing arguments. - * + * * @param cc The calling convention for the called method. */ public void callsMethod(CallingConvention cc) { @@ -226,7 +224,7 @@ /** * Reserves space for stack-based outgoing arguments. - * + * * @param argsSize The amount of space (in bytes) to reserve for stack-based outgoing arguments. */ public void reserveOutgoing(int argsSize) { @@ -239,7 +237,7 @@ * Reserves a new spill slot in the frame of the method being compiled. The returned slot is * aligned on its natural alignment, i.e., an 8-byte spill slot is aligned at an 8-byte * boundary. - * + * * @param kind The kind of the spill slot to be reserved. * @param additionalOffset * @return A spill slot denoting the reserved memory area. @@ -247,8 +245,9 @@ protected abstract StackSlot allocateNewSpillSlot(PlatformKind kind, int additionalOffset); /** - * Returns the spill slot size for the given {@link PlatformKind}. - * The default value is the size in bytes for the target architecture. + * Returns the spill slot size for the given {@link PlatformKind}. The default value is the size + * in bytes for the target architecture. + * * @param kind the {@link PlatformKind} to be stored in the spill slot. * @return the size in bytes */ @@ -258,9 +257,9 @@ /** * Reserves a spill slot in the frame of the method being compiled. The returned slot is aligned - * on its natural alignment, i.e., an 8-byte spill slot is aligned at an 8-byte boundary, - * unless overridden by a subclass. - * + * on its natural alignment, i.e., an 8-byte spill slot is aligned at an 8-byte boundary, unless + * overridden by a subclass. + * * @param kind The kind of the spill slot to be reserved. * @return A spill slot denoting the reserved memory area. */ @@ -299,7 +298,7 @@ /** * Reserves a block of memory in the frame of the method being compiled. The returned block is * aligned on a word boundary. If the requested size is 0, the method returns {@code null}. - * + * * @param size The size to reserve (in bytes). * @param refs Specifies if the block is all references. If true, the block will be in all * reference maps for this method. The caller is responsible to initialize the memory @@ -351,7 +350,7 @@ * Marks the specified location as a reference in the reference map of the debug information. * The tracked location can be a {@link RegisterValue} or a {@link StackSlot}. Note that a * {@link Constant} is automatically tracked. - * + * * @param location The location to be added to the reference map. * @param registerRefMap A register reference map, as created by {@link #initRegisterRefMap()}. * @param frameRefMap A frame reference map, as created by {@link #initFrameRefMap()}.
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIR.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIR.java Fri Oct 11 17:21:14 2013 +0200 @@ -24,7 +24,6 @@ import java.util.*; -import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.debug.*; import com.oracle.graal.graph.*; @@ -71,22 +70,15 @@ private boolean hasArgInCallerFrame; - private final SpeculationLog speculationLog; - /** * Creates a new LIR instance for the specified compilation. */ - public LIR(ControlFlowGraph cfg, BlockMap<List<ScheduledNode>> blockToNodesMap, List<Block> linearScanOrder, List<Block> codeEmittingOrder, SpeculationLog speculationLog) { + public LIR(ControlFlowGraph cfg, BlockMap<List<ScheduledNode>> blockToNodesMap, List<Block> linearScanOrder, List<Block> codeEmittingOrder) { this.cfg = cfg; this.blockToNodesMap = blockToNodesMap; this.codeEmittingOrder = codeEmittingOrder; this.linearScanOrder = linearScanOrder; this.lirInstructions = new BlockMap<>(cfg); - this.speculationLog = speculationLog; - } - - public SpeculationLog getDeoptimizationReasons() { - return speculationLog; } /**
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRFrameState.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRFrameState.java Fri Oct 11 17:21:14 2013 +0200 @@ -42,13 +42,11 @@ private final VirtualObject[] virtualObjects; public final LabelRef exceptionEdge; private DebugInfo debugInfo; - private final short deoptimizationReason; - public LIRFrameState(BytecodeFrame topFrame, VirtualObject[] virtualObjects, LabelRef exceptionEdge, short deoptimizationReason) { + public LIRFrameState(BytecodeFrame topFrame, VirtualObject[] virtualObjects, LabelRef exceptionEdge) { this.topFrame = topFrame; this.virtualObjects = virtualObjects; this.exceptionEdge = exceptionEdge; - this.deoptimizationReason = deoptimizationReason; } public boolean hasDebugInfo() { @@ -112,7 +110,7 @@ } public void finish(BitSet registerRefMap, BitSet frameRefMap) { - debugInfo = new DebugInfo(topFrame, registerRefMap, frameRefMap, deoptimizationReason); + debugInfo = new DebugInfo(topFrame, registerRefMap, frameRefMap); } @Override
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/Variable.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/Variable.java Fri Oct 11 17:21:14 2013 +0200 @@ -38,6 +38,8 @@ */ public final int index; + private String name; + /** * Creates a new variable. * @@ -50,9 +52,21 @@ this.index = index; } + public void setName(String name) { + this.name = name; + } + + public String getName() { + return name; + } + @Override public String toString() { - return "v" + index + getKindSuffix(); + if (name != null) { + return name; + } else { + return "v" + index + getKindSuffix(); + } } @Override
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/TargetMethodAssembler.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/TargetMethodAssembler.java Fri Oct 11 17:21:14 2013 +0200 @@ -51,7 +51,7 @@ public final AbstractAssembler asm; public final CompilationResult compilationResult; public final TargetDescription target; - public final CodeCacheProvider runtime; + public final CodeCacheProvider codeCache; public final FrameMap frameMap; /** @@ -62,9 +62,9 @@ private List<ExceptionInfo> exceptionInfoList; - public TargetMethodAssembler(TargetDescription target, CodeCacheProvider runtime, FrameMap frameMap, AbstractAssembler asm, FrameContext frameContext, CompilationResult compilationResult) { + public TargetMethodAssembler(TargetDescription target, CodeCacheProvider codeCache, FrameMap frameMap, AbstractAssembler asm, FrameContext frameContext, CompilationResult compilationResult) { this.target = target; - this.runtime = runtime; + this.codeCache = codeCache; this.frameMap = frameMap; this.asm = asm; this.compilationResult = compilationResult; @@ -185,7 +185,7 @@ public int asIntConst(Value value) { assert (value.getKind().getStackKind() == Kind.Int || value.getKind() == Kind.Long) && isConstant(value); Constant constant = (Constant) value; - assert !runtime.needsDataPatch(constant) : constant + " should be in a DataPatch"; + assert !codeCache.needsDataPatch(constant) : constant + " should be in a DataPatch"; long c = constant.asLong(); if (!NumUtil.isInt(c)) { throw GraalInternalError.shouldNotReachHere(); @@ -199,7 +199,7 @@ public float asFloatConst(Value value) { assert (value.getKind().getStackKind() == Kind.Float && isConstant(value)); Constant constant = (Constant) value; - assert !runtime.needsDataPatch(constant) : constant + " should be in a DataPatch"; + assert !codeCache.needsDataPatch(constant) : constant + " should be in a DataPatch"; return constant.asFloat(); } @@ -209,7 +209,7 @@ public long asLongConst(Value value) { assert (value.getKind().getStackKind() == Kind.Long && isConstant(value)); Constant constant = (Constant) value; - assert !runtime.needsDataPatch(constant) : constant + " should be in a DataPatch"; + assert !codeCache.needsDataPatch(constant) : constant + " should be in a DataPatch"; return constant.asLong(); } @@ -219,7 +219,7 @@ public double asDoubleConst(Value value) { assert (value.getKind().getStackKind() == Kind.Double && isConstant(value)); Constant constant = (Constant) value; - assert !runtime.needsDataPatch(constant) : constant + " should be in a DataPatch"; + assert !codeCache.needsDataPatch(constant) : constant + " should be in a DataPatch"; return constant.asDouble(); }
--- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/CountedLoopInfo.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/CountedLoopInfo.java Fri Oct 11 17:21:14 2013 +0200 @@ -24,7 +24,6 @@ import static com.oracle.graal.nodes.calc.IntegerArithmeticNode.*; -import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; import com.oracle.graal.loop.InductionVariable.Direction;
--- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopPolicies.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopPolicies.java Fri Oct 11 17:21:14 2013 +0200 @@ -48,11 +48,11 @@ return false; } CountedLoopInfo counted = loop.counted(); - long exactTrips = counted.constantMaxTripCount(); + long maxTrips = counted.constantMaxTripCount(); 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; + return size * maxTrips <= maxNodes; } public static boolean shouldTryUnswitch(LoopEx loop) {
--- a/graal/com.oracle.graal.nodes.test/src/com/oracle/graal/nodes/test/ObjectStampJoinTest.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes.test/src/com/oracle/graal/nodes/test/ObjectStampJoinTest.java Fri Oct 11 17:21:14 2013 +0200 @@ -151,6 +151,6 @@ } private ResolvedJavaType getType(Class<?> clazz) { - return runtime().lookupJavaType(clazz); + return getMetaAccess().lookupJavaType(clazz); } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractBeginNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractBeginNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -28,6 +28,7 @@ import com.oracle.graal.graph.*; import com.oracle.graal.graph.iterators.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractDeoptimizeNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2013, 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; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.nodes.type.*; + +/** + * This node represents an unconditional explicit request for immediate deoptimization. + * + * After this node, execution will continue using a fallback execution engine (such as an + * interpreter) at the position described by the {@link #getDeoptimizationState() deoptimization + * state}. + * + */ +public abstract class AbstractDeoptimizeNode extends ControlSinkNode implements IterableNodeType, DeoptimizingNode { + + @Input private FrameState deoptState; + + public AbstractDeoptimizeNode() { + super(StampFactory.forVoid()); + } + + @Override + public boolean canDeoptimize() { + return true; + } + + @Override + public FrameState getDeoptimizationState() { + return deoptState; + } + + @Override + public void setDeoptimizationState(FrameState f) { + updateUsages(deoptState, f); + deoptState = f; + } + + public FrameState getState() { + return deoptState; + } + + public abstract ValueNode getActionAndReason(MetaAccessProvider metaAccess); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ConditionAnchorNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -0,0 +1,97 @@ +/* + * 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; + +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; +import com.oracle.graal.nodes.extended.*; +import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.nodes.type.*; + +@NodeInfo(nameTemplate = "ConditionAnchor(!={p#negated})") +public final class ConditionAnchorNode extends FixedWithNextNode implements Canonicalizable, Lowerable, GuardingNode { + + @Input private LogicNode condition; + private boolean negated; + + public ConditionAnchorNode(LogicNode condition) { + this(condition, false); + } + + public ConditionAnchorNode(LogicNode condition, boolean negated) { + super(StampFactory.dependency()); + this.negated = negated; + this.condition = condition; + } + + public LogicNode condition() { + return condition; + } + + private void setCondition(LogicNode x) { + updateUsages(condition, x); + condition = x; + } + + public boolean isNegated() { + return negated; + } + + @Override + public String toString(Verbosity verbosity) { + if (verbosity == Verbosity.Name && negated) { + return "!" + super.toString(verbosity); + } else { + return super.toString(verbosity); + } + } + + @Override + public Node canonical(CanonicalizerTool tool) { + if (condition instanceof LogicNegationNode) { + LogicNegationNode negation = (LogicNegationNode) condition; + setCondition(negation.getInput()); + negated = !negated; + } + + if (condition instanceof LogicConstantNode) { + LogicConstantNode c = (LogicConstantNode) condition; + if (c.getValue() != negated) { + this.replaceAtUsages(null); + return null; + } else { + return graph().add(new ValueAnchorNode(null)); + } + } + + return this; + } + + @Override + public void lower(LoweringTool tool) { + if (graph().getGuardsStage() == StructuredGraph.GuardsStage.FIXED_DEOPTS) { + ValueAnchorNode newAnchor = graph().add(new ValueAnchorNode(null)); + graph().replaceFixedWithFixed(this, newAnchor); + } + } +}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ConstantNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ConstantNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -26,7 +26,6 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; -import com.oracle.graal.graph.iterators.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -50,27 +49,34 @@ * * @param value the constant */ - protected ConstantNode(Constant value, MetaAccessProvider runtime) { - super(StampFactory.forConstant(value, runtime)); + protected ConstantNode(Constant value, MetaAccessProvider metaAccess) { + super(StampFactory.forConstant(value, metaAccess)); this.value = value; } @Override public void generate(LIRGeneratorTool gen) { - if (gen.canInlineConstant(value) || onlyUsedInFrameState()) { + if (gen.canInlineConstant(value) || onlyUsedInVirtualState()) { gen.setResult(this, value); } else { gen.setResult(this, gen.emitMove(value)); } } - private boolean onlyUsedInFrameState() { - return usages().filter(NodePredicates.isNotA(FrameState.class)).isEmpty(); + private boolean onlyUsedInVirtualState() { + for (Node n : this.usages()) { + if (n instanceof VirtualState) { + // Only virtual usage. + } else { + return false; + } + } + return true; } - public static ConstantNode forConstant(Constant constant, MetaAccessProvider runtime, Graph graph) { + public static ConstantNode forConstant(Constant constant, MetaAccessProvider metaAccess, Graph graph) { if (constant.getKind() == Kind.Object) { - return graph.unique(new ConstantNode(constant, runtime)); + return graph.unique(new ConstantNode(constant, metaAccess)); } else { return graph.unique(new ConstantNode(constant)); } @@ -179,9 +185,9 @@ * @param graph * @return a node representing the object */ - public static ConstantNode forObject(Object o, MetaAccessProvider runtime, Graph graph) { + public static ConstantNode forObject(Object o, MetaAccessProvider metaAccess, Graph graph) { assert !(o instanceof Constant) : "wrapping a Constant into a Constant"; - return graph.unique(new ConstantNode(Constant.forObject(o), runtime)); + return graph.unique(new ConstantNode(Constant.forObject(o), metaAccess)); } public static ConstantNode forIntegerKind(Kind kind, long value, Graph graph) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptimizeNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptimizeNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -22,30 +22,17 @@ */ package com.oracle.graal.nodes; -import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.nodes.type.*; -/** - * This node represents an unconditional explicit request for immediate deoptimization. - * - * After this node, execution will continue using a fallback execution engine (such as an - * interpreter) at the position described by the {@link #getDeoptimizationState() deoptimization - * state}. - * - */ @NodeInfo(shortName = "Deopt", nameTemplate = "Deopt {p#reason/s}") -public class DeoptimizeNode extends ControlSinkNode implements IterableNodeType, LIRLowerable, DeoptimizingNode { - - @Input private FrameState deoptState; +public class DeoptimizeNode extends AbstractDeoptimizeNode implements LIRLowerable { private final DeoptimizationAction action; private final DeoptimizationReason reason; public DeoptimizeNode(DeoptimizationAction action, DeoptimizationReason reason) { - super(StampFactory.forVoid()); this.action = action; this.reason = reason; } @@ -60,34 +47,14 @@ @Override public void generate(LIRGeneratorTool gen) { - gen.emitDeoptimize(action, this); + gen.emitDeoptimize(gen.getMetaAccess().encodeDeoptActionAndReason(action, reason), this); + } + + @Override + public ValueNode getActionAndReason(MetaAccessProvider metaAccess) { + return ConstantNode.forConstant(metaAccess.encodeDeoptActionAndReason(action, reason), metaAccess, graph()); } @NodeIntrinsic public static native void deopt(@ConstantNodeParameter DeoptimizationAction action, @ConstantNodeParameter DeoptimizationReason reason); - - @Override - public boolean canDeoptimize() { - return true; - } - - @Override - public FrameState getDeoptimizationState() { - return deoptState; - } - - @Override - public void setDeoptimizationState(FrameState f) { - updateUsages(deoptState, f); - deoptState = f; - } - - @Override - public DeoptimizationReason getDeoptimizationReason() { - return reason; - } - - public FrameState getState() { - return deoptState; - } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptimizingNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptimizingNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -22,7 +22,6 @@ */ package com.oracle.graal.nodes; -import com.oracle.graal.api.meta.*; import com.oracle.graal.nodes.spi.*; /** @@ -46,13 +45,4 @@ * @param state the FrameState which represents the deoptimization information */ void setDeoptimizationState(FrameState state); - - /** - * Returns the reason for deoptimization triggered by this node. If deoptimization at this point - * can happen for external reasons (i.e. not explicitely triggered by this node) this method can - * return null. - * - * @return the reason for deoptimization triggered by this node. - */ - DeoptimizationReason getDeoptimizationReason(); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DynamicDeoptimizeNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2013, 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; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.nodes.spi.*; + +public class DynamicDeoptimizeNode extends AbstractDeoptimizeNode implements LIRLowerable { + @Input private ValueNode actionAndReason; + + public DynamicDeoptimizeNode(ValueNode actionAndReason) { + this.actionAndReason = actionAndReason; + } + + public ValueNode getActionAndReason() { + return actionAndReason; + } + + @Override + public ValueNode getActionAndReason(MetaAccessProvider metaAccess) { + return getActionAndReason(); + } + + public void generate(LIRGeneratorTool generator) { + generator.emitDeoptimize(generator.operand(actionAndReason), this); + } +}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/EntryMarkerNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/EntryMarkerNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -23,6 +23,7 @@ package com.oracle.graal.nodes; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.spi.*; /**
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedGuardNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedGuardNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -22,9 +22,9 @@ */ package com.oracle.graal.nodes; -import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -136,9 +136,4 @@ public boolean canDeoptimize() { return true; } - - @Override - public DeoptimizationReason getDeoptimizationReason() { - return reason; - } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -22,11 +22,10 @@ */ package com.oracle.graal.nodes; -import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.extended.*; -import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; /** @@ -91,7 +90,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (condition() instanceof LogicNegationNode) { LogicNegationNode negation = (LogicNegationNode) condition(); return graph().unique(new GuardNode(negation.getInput(), getGuard(), reason, action, !negated));
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardedValueNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardedValueNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -24,6 +24,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -74,7 +75,8 @@ } } - public ValueNode canonical(CanonicalizerTool tool) { + @Override + public Node canonical(CanonicalizerTool tool) { if (getGuard() == graph().start()) { if (stamp().equals(object().stamp())) { return object();
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardingPiNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardingPiNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -22,9 +22,9 @@ */ package com.oracle.graal.nodes; -import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.*; @@ -93,7 +93,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (stamp() == StampFactory.illegal(object.kind())) { // The guard always fails return graph().add(new DeoptimizeNode(action, reason));
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -30,6 +30,7 @@ import com.oracle.graal.debug.*; import com.oracle.graal.graph.*; import com.oracle.graal.graph.iterators.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.PhiNode.PhiType; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.java.*; @@ -182,7 +183,7 @@ if (this.trueSuccessorProbability < probabilityB) { // Reordering of those two if statements is beneficial from the point of view of // their probabilities. - if (prepareForSwap(tool.runtime(), condition(), nextIf.condition(), this.trueSuccessorProbability, probabilityB)) { + if (prepareForSwap(tool.getConstantReflection(), condition(), nextIf.condition(), this.trueSuccessorProbability, probabilityB)) { // Reording is allowed from (if1 => begin => if2) to (if2 => begin => if1). assert intermediateBegin.next() == nextIf; AbstractBeginNode bothFalseBegin = nextIf.falseSuccessor(); @@ -207,7 +208,7 @@ } } - private static boolean prepareForSwap(MetaAccessProvider runtime, LogicNode a, LogicNode b, double probabilityA, double probabilityB) { + private static boolean prepareForSwap(ConstantReflectionProvider constantReflection, LogicNode a, LogicNode b, double probabilityA, double probabilityB) { if (a instanceof InstanceOfNode) { InstanceOfNode instanceOfA = (InstanceOfNode) a; if (b instanceof IsNullNode) { @@ -296,13 +297,13 @@ } } else if (conditionA == Condition.EQ && conditionB == Condition.EQ) { boolean canSwap = false; - if ((compareA.x() == compareB.x() && valuesDistinct(runtime, compareA.y(), compareB.y()))) { + if ((compareA.x() == compareB.x() && valuesDistinct(constantReflection, compareA.y(), compareB.y()))) { canSwap = true; - } else if ((compareA.x() == compareB.y() && valuesDistinct(runtime, compareA.y(), compareB.x()))) { + } else if ((compareA.x() == compareB.y() && valuesDistinct(constantReflection, compareA.y(), compareB.x()))) { canSwap = true; - } else if ((compareA.y() == compareB.x() && valuesDistinct(runtime, compareA.x(), compareB.y()))) { + } else if ((compareA.y() == compareB.x() && valuesDistinct(constantReflection, compareA.x(), compareB.y()))) { canSwap = true; - } else if ((compareA.y() == compareB.y() && valuesDistinct(runtime, compareA.x(), compareB.x()))) { + } else if ((compareA.y() == compareB.y() && valuesDistinct(constantReflection, compareA.x(), compareB.x()))) { canSwap = true; } @@ -317,9 +318,9 @@ return false; } - private static boolean valuesDistinct(MetaAccessProvider runtime, ValueNode a, ValueNode b) { + private static boolean valuesDistinct(ConstantReflectionProvider constantReflection, ValueNode a, ValueNode b) { if (a.isConstant() && b.isConstant()) { - return !runtime.constantEquals(a.asConstant(), b.asConstant()); + return !constantReflection.constantEquals(a.asConstant(), b.asConstant()); } Stamp stampA = a.stamp(); @@ -486,7 +487,7 @@ for (int i = 0; i < xs.length; i++) { AbstractEndNode end = ends.next(); phiValues.put(end, phi.valueAt(end)); - if (compare.condition().foldCondition(xs[i], ys[i], tool.runtime(), compare.unorderedIsTrue())) { + if (compare.condition().foldCondition(xs[i], ys[i], tool.getConstantReflection(), compare.unorderedIsTrue())) { trueEnds.add(end); } else { falseEnds.add(end);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -109,7 +109,7 @@ @Override public void lower(LoweringTool tool) { - tool.getRuntime().lower(this, tool); + tool.getLowerer().lower(this, tool); } @Override @@ -174,11 +174,6 @@ } @Override - public DeoptimizationReason getDeoptimizationReason() { - return null; - } - - @Override public FrameState getDeoptimizationState() { if (deoptState == null) { FrameState stateDuring = stateDuring();
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeWithExceptionNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeWithExceptionNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -121,7 +121,7 @@ @Override public void setNext(FixedNode x) { if (x != null) { - this.setNext(AbstractBeginNode.begin(x)); + this.setNext(KillingBeginNode.begin(x, getLocationIdentity())); } else { this.setNext(null); } @@ -129,7 +129,7 @@ @Override public void lower(LoweringTool tool) { - tool.getRuntime().lower(this, tool); + tool.getLowerer().lower(this, tool); } @Override @@ -219,11 +219,6 @@ } @Override - public DeoptimizationReason getDeoptimizationReason() { - return null; - } - - @Override public FrameState getDeoptimizationState() { if (deoptState == null) { FrameState stateDuring = stateDuring();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/KillingBeginNode.java Fri Oct 11 17:21:14 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.nodes; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.nodes.extended.*; + +public class KillingBeginNode extends AbstractBeginNode implements MemoryCheckpoint.Single { + + private LocationIdentity locationIdentity; + + public KillingBeginNode(LocationIdentity locationIdentity) { + this.locationIdentity = locationIdentity; + } + + public static KillingBeginNode begin(FixedNode with, LocationIdentity locationIdentity) { + if (with instanceof KillingBeginNode) { + return (KillingBeginNode) with; + } + KillingBeginNode begin = with.graph().add(new KillingBeginNode(locationIdentity)); + begin.setNext(with); + return begin; + } + + @Override + public LocationIdentity getLocationIdentity() { + return locationIdentity; + } +}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LogicNegationNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LogicNegationNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -23,12 +23,12 @@ package com.oracle.graal.nodes; import com.oracle.graal.graph.*; -import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.graph.spi.*; /** * Logic node that negates its argument. */ -public class LogicNegationNode extends LogicNode implements Canonicalizable, IterableNodeType { +public class LogicNegationNode extends LogicNode implements Canonicalizable { @Input private LogicNode input; @@ -40,7 +40,8 @@ return input; } - public ValueNode canonical(CanonicalizerTool tool) { + @Override + public Node canonical(CanonicalizerTool tool) { if (input instanceof LogicNegationNode) { return ((LogicNegationNode) input).getInput(); } else {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopBeginNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopBeginNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -28,6 +28,7 @@ import com.oracle.graal.graph.*; import com.oracle.graal.graph.iterators.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.*;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopExitNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopExitNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -23,7 +23,7 @@ package com.oracle.graal.nodes; import com.oracle.graal.graph.*; -import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.graph.spi.*; public class LoopExitNode extends BeginStateSplitNode implements IterableNodeType {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MemoryMapNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -0,0 +1,37 @@ +/* + * 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; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.nodes.calc.*; +import com.oracle.graal.nodes.type.*; + +public abstract class MemoryMapNode extends FloatingNode { + + public MemoryMapNode() { + super(StampFactory.forVoid()); + } + + public abstract Node getLastLocationAccess(LocationIdentity locationIdentity); +}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MemoryState.java Fri Oct 11 17:14:35 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,65 +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.nodes; - -import com.oracle.graal.api.meta.*; -import com.oracle.graal.graph.*; - -public class MemoryState extends VirtualState { - - private MemoryMap<Node> memoryMap; - @Input private Node object; - - public MemoryState(MemoryMap<Node> memoryMap, FixedNode object) { - this.memoryMap = memoryMap; - this.object = object; - } - - public Node object() { - return object; - } - - public MemoryMap<Node> getMemoryMap() { - return memoryMap; - } - - @Override - public VirtualState duplicateWithVirtualState() { - throw new GraalInternalError("should not reach here"); - } - - @Override - public void applyToNonVirtual(NodeClosure<? super ValueNode> closure) { - throw new GraalInternalError("should not reach here"); - } - - @Override - public void applyToVirtual(VirtualClosure closure) { - throw new GraalInternalError("should not reach here"); - } - - @Override - public boolean isPartOfThisState(VirtualState state) { - throw new GraalInternalError("should not reach here"); - } -}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MergeNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MergeNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -27,6 +27,7 @@ import com.oracle.graal.debug.*; import com.oracle.graal.graph.*; import com.oracle.graal.graph.iterators.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.util.*;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PhiNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PhiNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -24,9 +24,9 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.extended.*; -import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; /** @@ -34,7 +34,7 @@ * variable. */ @NodeInfo(nameTemplate = "{p#type/s}Phi({i#values})") -public class PhiNode extends FloatingNode implements Canonicalizable, IterableNodeType, GuardingNode { +public class PhiNode extends FloatingNode implements Canonicalizable, GuardingNode { public static enum PhiType { Value(null), // normal value phis @@ -231,7 +231,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { ValueNode singleValue = singleValue(); if (singleValue != null) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PiArrayNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PiArrayNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -22,6 +22,8 @@ */ package com.oracle.graal.nodes; +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -45,7 +47,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (!(object() instanceof ArrayLengthProvider) || length() != ((ArrayLengthProvider) object()).length()) { return this; }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PiNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PiNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -24,6 +24,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -76,14 +77,13 @@ @Override public void virtualize(VirtualizerTool tool) { State state = tool.getObjectState(object); - if (state != null && state.getState() == EscapeState.Virtual) { - assert ObjectStamp.typeOrNull(this).isAssignableFrom(state.getVirtualObject().type()); + if (state != null && state.getState() == EscapeState.Virtual && ObjectStamp.typeOrNull(this).isAssignableFrom(state.getVirtualObject().type())) { tool.replaceWithVirtual(state.getVirtualObject()); } } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { inferStamp(); if (stamp().equals(object().stamp())) { return object();
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ProxyNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ProxyNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -24,6 +24,7 @@ import com.oracle.graal.graph.*; import com.oracle.graal.graph.Node.ValueNumberable; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.PhiNode.PhiType; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.extended.*; @@ -87,7 +88,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (type == PhiType.Value && value.isConstant()) { return value; }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ReturnNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ReturnNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -28,6 +28,7 @@ public final class ReturnNode extends ControlSinkNode implements LIRLowerable { @Input private ValueNode result; + @Input private MemoryMapNode memoryMap; public ValueNode result() { return result; @@ -40,8 +41,13 @@ * void return */ public ReturnNode(ValueNode result) { + this(result, null); + } + + public ReturnNode(ValueNode result, MemoryMapNode memoryMap) { super(StampFactory.forVoid()); this.result = result; + this.memoryMap = memoryMap; } @Override @@ -53,4 +59,13 @@ public void generate(LIRGeneratorTool gen) { gen.visitReturn(this); } + + public void setMemoryMap(MemoryMapNode memoryMap) { + updateUsages(this.memoryMap, memoryMap); + this.memoryMap = memoryMap; + } + + public MemoryMapNode getMemoryMap() { + return memoryMap; + } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/SafepointNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/SafepointNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -22,7 +22,6 @@ */ package com.oracle.graal.nodes; -import com.oracle.graal.api.meta.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -41,11 +40,6 @@ } @Override - public DeoptimizationReason getDeoptimizationReason() { - return null; - } - - @Override public boolean canDeoptimize() { return true; }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ShortCircuitOrNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ShortCircuitOrNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -23,7 +23,7 @@ package com.oracle.graal.nodes; import com.oracle.graal.graph.*; -import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.graph.spi.*; public class ShortCircuitOrNode extends LogicNode implements IterableNodeType, Canonicalizable { @@ -88,7 +88,7 @@ } @Override - public LogicNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { ShortCircuitOrNode ret = canonicalizeNegation(); if (ret != null) { return ret;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java Fri Oct 11 17:21:14 2013 +0200 @@ -250,7 +250,7 @@ node.safeDelete(); } - public void replaceFloating(FloatingNode node, ValueNode replacement) { + public void replaceFloating(FloatingNode node, Node replacement) { assert node != null && replacement != null && node.isAlive() && replacement.isAlive() : "cannot replace " + node + " with " + replacement; node.replaceAtUsages(replacement); node.safeDelete(); @@ -324,7 +324,7 @@ for (Node successor : snapshot) { if (successor != null && successor.isAlive()) { if (successor != survivingSuccessor) { - GraphUtil.killCFG((AbstractBeginNode) successor); + GraphUtil.killCFG(successor); } } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/TypeProfileProxyNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/TypeProfileProxyNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -25,6 +25,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.debug.*; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -71,7 +72,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (ObjectStamp.isExactType(object)) { // The profile is useless - we know the type! return object;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValueNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValueNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -26,7 +26,6 @@ import com.oracle.graal.graph.*; import com.oracle.graal.graph.iterators.*; import com.oracle.graal.nodes.type.*; -import com.oracle.graal.nodes.util.*; /** * This class represents a value within the graph, including local variables, phis, and all other @@ -127,13 +126,6 @@ return null; } - public <T extends Stamp> boolean verifyStamp(Class<T> stampClass) { - assert stamp() != null; - assert stampClass.isInstance(stamp()) : this + " (" + GraphUtil.approxSourceLocation(this) + ") has unexpected stamp type: expected " + stampClass.getName() + ", got " + - stamp().getClass().getName() + ", usages=" + usages(); - return true; - } - @Override public boolean verify() { assertTrue(kind() != null, "Should have a valid kind");
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/AndNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/AndNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -24,6 +24,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -41,7 +42,13 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Constant evalConst(Constant... inputs) { + assert inputs.length == 2; + return Constant.forIntegerKind(kind(), inputs[0].asLong() & inputs[1].asLong(), null); + } + + @Override + public Node canonical(CanonicalizerTool tool) { if (x() == y()) { return x(); } @@ -49,12 +56,7 @@ return graph().unique(new AndNode(kind(), y(), x())); } if (x().isConstant()) { - if (kind() == Kind.Int) { - return ConstantNode.forInt(x().asConstant().asInt() & y().asConstant().asInt(), graph()); - } else { - assert kind() == Kind.Long; - return ConstantNode.forLong(x().asConstant().asLong() & y().asConstant().asLong(), graph()); - } + return ConstantNode.forPrimitive(evalConst(x().asConstant(), y().asConstant()), graph()); } else if (y().isConstant()) { if (kind() == Kind.Int) { int c = y().asConstant().asInt();
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/CompareNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/CompareNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -24,6 +24,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; @@ -76,13 +77,13 @@ public void generate(LIRGeneratorTool gen) { } - private LogicNode optimizeConditional(Constant constant, ConditionalNode conditionalNode, MetaAccessProvider runtime, Condition cond) { + private LogicNode optimizeConditional(Constant constant, ConditionalNode conditionalNode, ConstantReflectionProvider constantReflection, Condition cond) { Constant trueConstant = conditionalNode.trueValue().asConstant(); Constant falseConstant = conditionalNode.falseValue().asConstant(); - if (falseConstant != null && trueConstant != null && runtime != null) { - boolean trueResult = cond.foldCondition(trueConstant, constant, runtime, unorderedIsTrue()); - boolean falseResult = cond.foldCondition(falseConstant, constant, runtime, unorderedIsTrue()); + if (falseConstant != null && trueConstant != null && constantReflection != null) { + boolean trueResult = cond.foldCondition(trueConstant, constant, constantReflection, unorderedIsTrue()); + boolean falseResult = cond.foldCondition(falseConstant, constant, constantReflection, unorderedIsTrue()); if (trueResult == falseResult) { return LogicConstantNode.forBoolean(trueResult, graph()); @@ -115,19 +116,19 @@ } @Override - public LogicNode canonical(CanonicalizerTool tool) { - if (x().isConstant() && y().isConstant() && tool.runtime() != null) { - return LogicConstantNode.forBoolean(condition().foldCondition(x().asConstant(), y().asConstant(), tool.runtime(), unorderedIsTrue()), graph()); + public Node canonical(CanonicalizerTool tool) { + if (x().isConstant() && y().isConstant() && tool.getMetaAccess() != null) { + return LogicConstantNode.forBoolean(condition().foldCondition(x().asConstant(), y().asConstant(), tool.getConstantReflection(), unorderedIsTrue()), graph()); } if (x().isConstant()) { if (y() instanceof ConditionalNode) { - return optimizeConditional(x().asConstant(), (ConditionalNode) y(), tool.runtime(), condition().mirror()); + return optimizeConditional(x().asConstant(), (ConditionalNode) y(), tool.getConstantReflection(), condition().mirror()); } else if (y() instanceof NormalizeCompareNode) { return optimizeNormalizeCmp(x().asConstant(), (NormalizeCompareNode) y(), true); } } else if (y().isConstant()) { if (x() instanceof ConditionalNode) { - return optimizeConditional(y().asConstant(), (ConditionalNode) x(), tool.runtime(), condition()); + return optimizeConditional(y().asConstant(), (ConditionalNode) x(), tool.getConstantReflection(), condition()); } else if (x() instanceof NormalizeCompareNode) { return optimizeNormalizeCmp(y().asConstant(), (NormalizeCompareNode) x(), false); }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/Condition.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/Condition.java Fri Oct 11 17:21:14 2013 +0200 @@ -317,13 +317,13 @@ * * @param lt the constant on the left side of the comparison * @param rt the constant on the right side of the comparison - * @param runtime needed to compare runtime-specific types + * @param constantReflection needed to compare constants * @return {@link Boolean#TRUE} if the comparison is known to be true, {@link Boolean#FALSE} if * the comparison is known to be false */ - public boolean foldCondition(Constant lt, Constant rt, CodeCacheProvider runtime) { + public boolean foldCondition(Constant lt, Constant rt, ConstantReflectionProvider constantReflection) { assert lt.getKind() != Kind.Double && lt.getKind() != Kind.Float && rt.getKind() != Kind.Double && rt.getKind() != Kind.Float; - return foldCondition(lt, rt, runtime, false); + return foldCondition(lt, rt, constantReflection, false); } /** @@ -331,12 +331,12 @@ * * @param lt the constant on the left side of the comparison * @param rt the constant on the right side of the comparison - * @param runtime needed to compare runtime-specific types + * @param constantReflection needed to compare constants * @param unorderedIsTrue true if an undecided float comparison should result in "true" * @return true if the comparison is known to be true, false if the comparison is known to be * false */ - public boolean foldCondition(Constant lt, Constant rt, MetaAccessProvider runtime, boolean unorderedIsTrue) { + public boolean foldCondition(Constant lt, Constant rt, ConstantReflectionProvider constantReflection, boolean unorderedIsTrue) { switch (lt.getKind()) { case Boolean: case Byte: @@ -401,9 +401,9 @@ case Object: { switch (this) { case EQ: - return runtime.constantEquals(lt, rt); + return constantReflection.constantEquals(lt, rt); case NE: - return !runtime.constantEquals(lt, rt); + return !constantReflection.constantEquals(lt, rt); default: throw new GraalInternalError("expected condition: %s", this); }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ConditionalNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ConditionalNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -25,6 +25,8 @@ import static com.oracle.graal.nodes.calc.CompareNode.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.spi.*; @@ -66,7 +68,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (condition instanceof LogicNegationNode) { LogicNegationNode negated = (LogicNegationNode) condition; return graph().unique(new ConditionalNode(negated.getInput(), falseValue(), trueValue()));
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ConvertNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ConvertNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -26,6 +26,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -150,52 +151,59 @@ this.value = value; } + public Constant evalConst(Constant... inputs) { + assert inputs.length == 1; + Constant c = inputs[0]; + switch (opcode) { + case I2L: + return Constant.forLong(c.asInt()); + case L2I: + return Constant.forInt((int) c.asLong()); + case I2B: + return Constant.forByte((byte) c.asInt()); + case I2C: + return Constant.forChar((char) c.asInt()); + case I2S: + return Constant.forShort((short) c.asInt()); + case F2D: + return Constant.forDouble(c.asFloat()); + case D2F: + return Constant.forFloat((float) c.asDouble()); + case I2F: + return Constant.forFloat(c.asInt()); + case I2D: + return Constant.forDouble(c.asInt()); + case F2I: + return Constant.forInt((int) c.asFloat()); + case D2I: + return Constant.forInt((int) c.asDouble()); + case L2F: + return Constant.forFloat(c.asLong()); + case L2D: + return Constant.forDouble(c.asLong()); + case F2L: + return Constant.forLong((long) c.asFloat()); + case D2L: + return Constant.forLong((long) c.asDouble()); + case UNSIGNED_I2L: + return Constant.forLong(c.asInt() & 0xffffffffL); + case MOV_I2F: + return Constant.forFloat(java.lang.Float.intBitsToFloat(c.asInt())); + case MOV_L2D: + return Constant.forDouble(java.lang.Double.longBitsToDouble(c.asLong())); + case MOV_F2I: + return Constant.forInt(java.lang.Float.floatToRawIntBits(c.asFloat())); + case MOV_D2L: + return Constant.forLong(java.lang.Double.doubleToRawLongBits(c.asDouble())); + default: + throw GraalInternalError.shouldNotReachHere(); + } + } + @Override - public ValueNode canonical(CanonicalizerTool tool) { - if (value instanceof ConstantNode) { - Constant c = ((ConstantNode) value).asConstant(); - switch (opcode) { - case I2L: - return ConstantNode.forLong(c.asInt(), graph()); - case L2I: - return ConstantNode.forInt((int) c.asLong(), graph()); - case I2B: - return ConstantNode.forByte((byte) c.asInt(), graph()); - case I2C: - return ConstantNode.forChar((char) c.asInt(), graph()); - case I2S: - return ConstantNode.forShort((short) c.asInt(), graph()); - case F2D: - return ConstantNode.forDouble(c.asFloat(), graph()); - case D2F: - return ConstantNode.forFloat((float) c.asDouble(), graph()); - case I2F: - return ConstantNode.forFloat(c.asInt(), graph()); - case I2D: - return ConstantNode.forDouble(c.asInt(), graph()); - case F2I: - return ConstantNode.forInt((int) c.asFloat(), graph()); - case D2I: - return ConstantNode.forInt((int) c.asDouble(), graph()); - case L2F: - return ConstantNode.forFloat(c.asLong(), graph()); - case L2D: - return ConstantNode.forDouble(c.asLong(), graph()); - case F2L: - return ConstantNode.forLong((long) c.asFloat(), graph()); - case D2L: - return ConstantNode.forLong((long) c.asDouble(), graph()); - case UNSIGNED_I2L: - return ConstantNode.forLong(c.asInt() & 0xffffffffL, graph()); - case MOV_I2F: - return ConstantNode.forFloat(java.lang.Float.intBitsToFloat(c.asInt()), graph()); - case MOV_L2D: - return ConstantNode.forDouble(java.lang.Double.longBitsToDouble(c.asLong()), graph()); - case MOV_F2I: - return ConstantNode.forInt(java.lang.Float.floatToRawIntBits(c.asFloat()), graph()); - case MOV_D2L: - return ConstantNode.forLong(java.lang.Double.doubleToRawLongBits(c.asDouble()), graph()); - } + public Node canonical(CanonicalizerTool tool) { + if (value.isConstant()) { + return ConstantNode.forPrimitive(evalConst(value.asConstant()), graph()); } return this; } @@ -236,7 +244,7 @@ @Override public void lower(LoweringTool tool) { - tool.getRuntime().lower(this, tool); + tool.getLowerer().lower(this, tool); } @Override
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FixedBinaryNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FixedBinaryNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -44,9 +44,4 @@ this.x = x; this.y = y; } - - @Override - public DeoptimizationReason getDeoptimizationReason() { - return DeoptimizationReason.ArithmeticException; - } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatAddNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatAddNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -24,6 +24,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; @@ -34,18 +35,23 @@ super(kind, x, y, isStrictFP); } + public Constant evalConst(Constant... inputs) { + assert inputs.length == 2; + if (kind() == Kind.Float) { + return Constant.forFloat(inputs[0].asFloat() + inputs[1].asFloat()); + } else { + assert kind() == Kind.Double; + return Constant.forDouble(inputs[0].asDouble() + inputs[1].asDouble()); + } + } + @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (x().isConstant() && !y().isConstant()) { return graph().unique(new FloatAddNode(kind(), y(), x(), isStrictFP())); } if (x().isConstant()) { - if (kind() == Kind.Float) { - return ConstantNode.forFloat(x().asConstant().asFloat() + y().asConstant().asFloat(), graph()); - } else { - assert kind() == Kind.Double; - return ConstantNode.forDouble(x().asConstant().asDouble() + y().asConstant().asDouble(), graph()); - } + return ConstantNode.forPrimitive(evalConst(x().asConstant(), y().asConstant()), graph()); } else if (y().isConstant()) { if (kind() == Kind.Float) { float c = y().asConstant().asFloat();
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatDivNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatDivNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -24,6 +24,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; @@ -34,19 +35,20 @@ super(kind, x, y, isStrictFP); } + public Constant evalConst(Constant... inputs) { + assert inputs.length == 2; + if (kind() == Kind.Float) { + return Constant.forFloat(inputs[0].asFloat() / inputs[1].asFloat()); + } else { + assert kind() == Kind.Double; + return Constant.forDouble(inputs[0].asDouble() / inputs[1].asDouble()); + } + } + @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (x().isConstant() && y().isConstant()) { - if (kind() == Kind.Float) { - if (y().asConstant().asFloat() != 0) { - return ConstantNode.forFloat(x().asConstant().asFloat() / y().asConstant().asFloat(), graph()); - } - } else { - assert kind() == Kind.Double; - if (y().asConstant().asDouble() != 0) { - return ConstantNode.forDouble(x().asConstant().asDouble() / y().asConstant().asDouble(), graph()); - } - } + return ConstantNode.forPrimitive(evalConst(x().asConstant(), y().asConstant()), graph()); } return this; }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatLessThanNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatLessThanNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -24,8 +24,8 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.spi.*; @NodeInfo(shortName = "<") public final class FloatLessThanNode extends CompareNode { @@ -58,7 +58,7 @@ } @Override - public LogicNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (x() == y() && !unorderedIsTrue()) { return LogicConstantNode.contradiction(graph()); }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatMulNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatMulNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -24,6 +24,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; @@ -34,18 +35,23 @@ super(kind, x, y, isStrictFP); } + public Constant evalConst(Constant... inputs) { + assert inputs.length == 2; + if (kind() == Kind.Float) { + return Constant.forFloat(inputs[0].asFloat() * inputs[1].asFloat()); + } else { + assert kind() == Kind.Double; + return Constant.forDouble(inputs[0].asDouble() * inputs[1].asDouble()); + } + } + @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (x().isConstant() && !y().isConstant()) { return graph().unique(new FloatMulNode(kind(), y(), x(), isStrictFP())); } if (x().isConstant()) { - if (kind() == Kind.Float) { - return ConstantNode.forFloat(x().asConstant().asFloat() * y().asConstant().asFloat(), graph()); - } else { - assert kind() == Kind.Double; - return ConstantNode.forDouble(x().asConstant().asDouble() * y().asConstant().asDouble(), graph()); - } + return ConstantNode.forPrimitive(evalConst(x().asConstant(), y().asConstant()), graph()); } return this; }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatRemNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatRemNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -24,6 +24,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; @@ -34,15 +35,20 @@ super(kind, x, y, isStrictFP); } + public Constant evalConst(Constant... inputs) { + assert inputs.length == 2; + if (kind() == Kind.Float) { + return Constant.forFloat(inputs[0].asFloat() % inputs[1].asFloat()); + } else { + assert kind() == Kind.Double; + return Constant.forDouble(inputs[0].asDouble() % inputs[1].asDouble()); + } + } + @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (x().isConstant() && y().isConstant()) { - if (kind() == Kind.Float) { - return ConstantNode.forFloat(x().asConstant().asFloat() % y().asConstant().asFloat(), graph()); - } else { - assert kind() == Kind.Double; - return ConstantNode.forDouble(x().asConstant().asDouble() % y().asConstant().asDouble(), graph()); - } + return ConstantNode.forPrimitive(evalConst(x().asConstant(), y().asConstant()), graph()); } return this; }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatSubNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatSubNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -24,6 +24,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; @@ -34,18 +35,23 @@ super(kind, x, y, isStrictFP); } + public Constant evalConst(Constant... inputs) { + assert inputs.length == 2; + if (kind() == Kind.Float) { + return Constant.forFloat(inputs[0].asFloat() - inputs[1].asFloat()); + } else { + assert kind() == Kind.Double; + return Constant.forDouble(inputs[0].asDouble() - inputs[1].asDouble()); + } + } + @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (x() == y()) { return ConstantNode.forFloatingKind(kind(), 0.0f, graph()); } if (x().isConstant() && y().isConstant()) { - if (kind() == Kind.Float) { - return ConstantNode.forFloat(x().asConstant().asFloat() - y().asConstant().asFloat(), graph()); - } else { - assert kind() == Kind.Double; - return ConstantNode.forDouble(x().asConstant().asDouble() - y().asConstant().asDouble(), graph()); - } + return ConstantNode.forPrimitive(evalConst(x().asConstant(), y().asConstant()), graph()); } else if (y().isConstant()) { if (kind() == Kind.Float) { float c = y().asConstant().asFloat();
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerAddNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerAddNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -24,6 +24,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -41,7 +42,13 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Constant evalConst(Constant... inputs) { + assert inputs.length == 2; + return Constant.forIntegerKind(kind(), inputs[0].asLong() + inputs[1].asLong(), null); + } + + @Override + public Node canonical(CanonicalizerTool tool) { if (x().isConstant() && !y().isConstant()) { return graph().unique(new IntegerAddNode(kind(), y(), x())); } @@ -60,12 +67,7 @@ } } if (x().isConstant()) { - if (kind() == Kind.Int) { - return ConstantNode.forInt(x().asConstant().asInt() + y().asConstant().asInt(), graph()); - } else { - assert kind() == Kind.Long; - return ConstantNode.forLong(x().asConstant().asLong() + y().asConstant().asLong(), graph()); - } + return ConstantNode.forPrimitive(evalConst(x().asConstant(), y().asConstant()), graph()); } else if (y().isConstant()) { long c = y().asConstant().asLong(); if (c == 0) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerBelowThanNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerBelowThanNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -24,8 +24,8 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @NodeInfo(shortName = "|<|") @@ -54,7 +54,7 @@ } @Override - public LogicNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (x() == y()) { return LogicConstantNode.contradiction(graph()); } else {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerDivNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerDivNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -25,6 +25,7 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -42,7 +43,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (x().isConstant() && y().isConstant()) { long yConst = y().asConstant().asLong(); if (yConst == 0) { @@ -111,7 +112,7 @@ @Override public void lower(LoweringTool tool) { - tool.getRuntime().lower(this, tool); + tool.getLowerer().lower(this, tool); } @Override
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerEqualsNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerEqualsNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -24,8 +24,8 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.spi.*; @NodeInfo(shortName = "==") public final class IntegerEqualsNode extends CompareNode { @@ -68,7 +68,7 @@ } @Override - public LogicNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (x() == y()) { return LogicConstantNode.tautology(graph()); } else if (x().stamp().alwaysDistinct(y().stamp())) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerLessThanNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerLessThanNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -24,8 +24,8 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @NodeInfo(shortName = "<") @@ -70,7 +70,7 @@ } @Override - public LogicNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (x() == y()) { return LogicConstantNode.contradiction(graph()); }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerMulNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerMulNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -25,6 +25,7 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; @@ -36,17 +37,18 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Constant evalConst(Constant... inputs) { + assert inputs.length == 2; + return Constant.forIntegerKind(kind(), inputs[0].asLong() * inputs[1].asLong(), null); + } + + @Override + public Node canonical(CanonicalizerTool tool) { if (x().isConstant() && !y().isConstant()) { return graph().unique(new IntegerMulNode(kind(), y(), x())); } if (x().isConstant()) { - if (kind() == Kind.Int) { - return ConstantNode.forInt(x().asConstant().asInt() * y().asConstant().asInt(), graph()); - } else { - assert kind() == Kind.Long; - return ConstantNode.forLong(x().asConstant().asLong() * y().asConstant().asLong(), graph()); - } + return ConstantNode.forPrimitive(evalConst(x().asConstant(), y().asConstant()), graph()); } else if (y().isConstant()) { long c = y().asConstant().asLong(); if (c == 1) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerRemNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerRemNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -25,6 +25,7 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -37,7 +38,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (x().isConstant() && y().isConstant()) { long yConst = y().asConstant().asLong(); if (yConst == 0) { @@ -62,7 +63,7 @@ @Override public void lower(LoweringTool tool) { - tool.getRuntime().lower(this, tool); + tool.getLowerer().lower(this, tool); } @Override
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerSubNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerSubNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -24,6 +24,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -41,7 +42,13 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Constant evalConst(Constant... inputs) { + assert inputs.length == 2; + return Constant.forIntegerKind(kind(), inputs[0].asLong() - inputs[1].asLong(), null); + } + + @Override + public Node canonical(CanonicalizerTool tool) { if (x() == y()) { return ConstantNode.forIntegerKind(kind(), 0, graph()); } @@ -80,12 +87,7 @@ } } if (x().isConstant() && y().isConstant()) { - if (kind() == Kind.Int) { - return ConstantNode.forInt(x().asConstant().asInt() - y().asConstant().asInt(), graph()); - } else { - assert kind() == Kind.Long; - return ConstantNode.forLong(x().asConstant().asLong() - y().asConstant().asLong(), graph()); - } + return ConstantNode.forPrimitive(evalConst(x().asConstant(), y().asConstant()), graph()); } else if (y().isConstant()) { long c = y().asConstant().asLong(); if (c == 0) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerTestNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerTestNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -22,6 +22,8 @@ */ package com.oracle.graal.nodes.calc; +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -61,7 +63,7 @@ } @Override - public LogicNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (x().isConstant() && y().isConstant()) { return LogicConstantNode.forBoolean((x().asConstant().asLong() & y().asConstant().asLong()) == 0, graph()); }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IsNullNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IsNullNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -23,6 +23,8 @@ package com.oracle.graal.nodes.calc; import com.oracle.graal.api.meta.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -60,7 +62,7 @@ } @Override - public LogicNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { Constant constant = object().asConstant(); if (constant != null) { assert constant.getKind() == Kind.Object;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/LeftShiftNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/LeftShiftNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -24,6 +24,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -41,8 +42,21 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { - if (y().isConstant()) { + public Constant evalConst(Constant... inputs) { + assert inputs.length == 2; + if (kind() == Kind.Int) { + return Constant.forInt(inputs[0].asInt() << inputs[1].asInt()); + } else { + assert kind() == Kind.Long; + return Constant.forLong(inputs[0].asLong() << inputs[1].asLong()); + } + } + + @Override + public Node canonical(CanonicalizerTool tool) { + if (x().isConstant() && y().isConstant()) { + return ConstantNode.forPrimitive(evalConst(x().asConstant(), y().asConstant()), graph()); + } else if (y().isConstant()) { int amount = y().asConstant().asInt(); int originalAmout = amount; int mask; @@ -53,14 +67,6 @@ mask = 0x3f; } amount &= mask; - if (x().isConstant()) { - if (kind() == Kind.Int) { - return ConstantNode.forInt(x().asConstant().asInt() << amount, graph()); - } else { - assert kind() == Kind.Long; - return ConstantNode.forLong(x().asConstant().asLong() << amount, graph()); - } - } if (amount == 0) { return x(); }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NegateNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NegateNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -22,6 +22,9 @@ */ package com.oracle.graal.nodes.calc; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -52,19 +55,26 @@ this.x = x; } + public Constant evalConst(Constant... inputs) { + assert inputs.length == 1; + switch (inputs[0].getKind()) { + case Int: + return Constant.forInt(-inputs[0].asInt()); + case Long: + return Constant.forLong(-inputs[0].asLong()); + case Float: + return Constant.forFloat(-inputs[0].asFloat()); + case Double: + return Constant.forDouble(-inputs[0].asDouble()); + default: + throw GraalInternalError.shouldNotReachHere(); + } + } + @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (x().isConstant()) { - switch (x().kind()) { - case Int: - return ConstantNode.forInt(-x().asConstant().asInt(), graph()); - case Long: - return ConstantNode.forLong(-x().asConstant().asLong(), graph()); - case Float: - return ConstantNode.forFloat(-x().asConstant().asFloat(), graph()); - case Double: - return ConstantNode.forDouble(-x().asConstant().asDouble(), graph()); - } + return ConstantNode.forPrimitive(evalConst(x.asConstant()), graph()); } if (x() instanceof NegateNode) { return ((NegateNode) x()).x();
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NotNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NotNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -23,6 +23,8 @@ package com.oracle.graal.nodes.calc; import com.oracle.graal.api.meta.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -43,6 +45,12 @@ return updateStamp(StampTool.not(x().stamp())); } + @Override + public Constant evalConst(Constant... inputs) { + assert inputs.length == 1; + return Constant.forIntegerKind(kind(), ~inputs[0].asLong(), null); + } + /** * Creates new NegateNode instance. * @@ -55,14 +63,9 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (x().isConstant()) { - switch (x().kind()) { - case Int: - return ConstantNode.forInt(~x().asConstant().asInt(), graph()); - case Long: - return ConstantNode.forLong(~x().asConstant().asLong(), graph()); - } + return ConstantNode.forPrimitive(evalConst(x().asConstant()), graph()); } if (x() instanceof NotNode) { return ((NotNode) x()).x();
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ObjectEqualsNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ObjectEqualsNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -24,6 +24,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -54,7 +55,7 @@ } @Override - public LogicNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (x() == y()) { return LogicConstantNode.tautology(graph()); }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/OrNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/OrNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -24,6 +24,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -41,7 +42,13 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Constant evalConst(Constant... inputs) { + assert inputs.length == 2; + return Constant.forIntegerKind(kind(), inputs[0].asLong() | inputs[1].asLong(), null); + } + + @Override + public Node canonical(CanonicalizerTool tool) { if (x() == y()) { return x(); } @@ -49,12 +56,7 @@ return graph().unique(new OrNode(kind(), y(), x())); } if (x().isConstant()) { - if (kind() == Kind.Int) { - return ConstantNode.forInt(x().asConstant().asInt() | y().asConstant().asInt(), graph()); - } else { - assert kind() == Kind.Long; - return ConstantNode.forLong(x().asConstant().asLong() | y().asConstant().asLong(), graph()); - } + return ConstantNode.forPrimitive(evalConst(x().asConstant(), y().asConstant()), graph()); } else if (y().isConstant()) { if (kind() == Kind.Int) { int c = y().asConstant().asInt();
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/RightShiftNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/RightShiftNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -24,6 +24,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -36,11 +37,24 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Constant evalConst(Constant... inputs) { + assert inputs.length == 2; + if (kind() == Kind.Int) { + return Constant.forInt(inputs[0].asInt() >> inputs[1].asInt()); + } else { + assert kind() == Kind.Long; + return Constant.forLong(inputs[0].asLong() >> inputs[1].asLong()); + } + } + + @Override + public Node canonical(CanonicalizerTool tool) { if (x().stamp() instanceof IntegerStamp && ((IntegerStamp) x().stamp()).isPositive()) { return graph().unique(new UnsignedRightShiftNode(kind(), x(), y())); } - if (y().isConstant()) { + if (x().isConstant() && y().isConstant()) { + return ConstantNode.forPrimitive(evalConst(x().asConstant(), y().asConstant()), graph()); + } else if (y().isConstant()) { int amount = y().asConstant().asInt(); int originalAmout = amount; int mask; @@ -51,14 +65,6 @@ mask = 0x3f; } amount &= mask; - if (x().isConstant()) { - if (kind() == Kind.Int) { - return ConstantNode.forInt(x().asConstant().asInt() >> amount, graph()); - } else { - assert kind() == Kind.Long; - return ConstantNode.forLong(x().asConstant().asLong() >> amount, graph()); - } - } if (amount == 0) { return x(); }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedDivNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedDivNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -25,6 +25,7 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -37,7 +38,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (x().isConstant() && y().isConstant()) { long yConst = y().asConstant().asLong(); if (yConst == 0) { @@ -63,7 +64,7 @@ @Override public void lower(LoweringTool tool) { - tool.getRuntime().lower(this, tool); + tool.getLowerer().lower(this, tool); } @Override
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedRemNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedRemNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -25,6 +25,7 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -37,7 +38,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (x().isConstant() && y().isConstant()) { long yConst = y().asConstant().asLong(); if (yConst == 0) { @@ -62,7 +63,7 @@ @Override public void lower(LoweringTool tool) { - tool.getRuntime().lower(this, tool); + tool.getLowerer().lower(this, tool); } @Override
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedRightShiftNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedRightShiftNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -24,6 +24,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -41,8 +42,21 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { - if (y().isConstant()) { + public Constant evalConst(Constant... inputs) { + assert inputs.length == 2; + if (kind() == Kind.Int) { + return Constant.forInt(inputs[0].asInt() >>> inputs[1].asInt()); + } else { + assert kind() == Kind.Long; + return Constant.forLong(inputs[0].asLong() >>> inputs[1].asLong()); + } + } + + @Override + public Node canonical(CanonicalizerTool tool) { + if (x().isConstant() && y().isConstant()) { + return ConstantNode.forPrimitive(evalConst(x().asConstant(), y().asConstant()), graph()); + } else if (y().isConstant()) { int amount = y().asConstant().asInt(); int originalAmout = amount; int mask; @@ -53,14 +67,6 @@ mask = 0x3f; } amount &= mask; - if (x().isConstant()) { - if (kind() == Kind.Int) { - return ConstantNode.forInt(x().asConstant().asInt() >>> amount, graph()); - } else { - assert kind() == Kind.Long; - return ConstantNode.forLong(x().asConstant().asLong() >>> amount, graph()); - } - } if (amount == 0) { return x(); }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/XorNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/XorNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -24,6 +24,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -41,7 +42,13 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Constant evalConst(Constant... inputs) { + assert inputs.length == 2; + return Constant.forIntegerKind(kind(), inputs[0].asLong() ^ inputs[1].asLong(), null); + } + + @Override + public Node canonical(CanonicalizerTool tool) { if (x() == y()) { return ConstantNode.forIntegerKind(kind(), 0, graph()); } @@ -49,12 +56,7 @@ return graph().unique(new XorNode(kind(), y(), x())); } if (x().isConstant()) { - if (kind() == Kind.Int) { - return ConstantNode.forInt(x().asConstant().asInt() ^ y().asConstant().asInt(), graph()); - } else { - assert kind() == Kind.Long; - return ConstantNode.forLong(x().asConstant().asLong() ^ y().asConstant().asLong(), graph()); - } + return ConstantNode.forPrimitive(evalConst(x().asConstant(), y().asConstant()), graph()); } else if (y().isConstant()) { if (kind() == Kind.Int) { int c = y().asConstant().asInt();
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/debug/DynamicCounterNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/debug/DynamicCounterNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -22,200 +22,61 @@ */ package com.oracle.graal.nodes.debug; -import java.io.*; -import java.util.*; - -import sun.misc.*; - -import com.oracle.graal.api.meta.*; -import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.HeapAccess.BarrierType; -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.*; /** * This node can be used to add a counter to the code that will estimate the dynamic number of calls * by adding an increment to the compiled code. This should of course only be used for - * debugging/testing purposes, and is not 100% accurate (because of concurrency issues while - * accessing the counters). + * debugging/testing purposes. * - * A unique counter will be created for each unique String passed to the constructor. + * A unique counter will be created for each unique name passed to the constructor. Depending on the + * value of withContext, the name of the root method is added to the counter's name. */ public class DynamicCounterNode extends FixedWithNextNode implements Lowerable { - private static final int MAX_COUNTERS = 10 * 1024; - public static final long[] COUNTERS = new long[MAX_COUNTERS]; - private static final long[] STATIC_COUNTERS = new long[MAX_COUNTERS]; - private static final String[] GROUPS = new String[MAX_COUNTERS]; - private static final HashMap<String, Integer> INDEXES = new HashMap<>(); - public static String excludedClassPrefix = null; - public static boolean enabled = false; + @Input private ValueNode increment; private final String name; private final String group; - private final long increment; - private final boolean addContext; + private final boolean withContext; - public DynamicCounterNode(String name, String group, long increment, boolean addContext) { + public DynamicCounterNode(String name, String group, ValueNode increment, boolean withContext) { super(StampFactory.forVoid()); - if (!enabled) { - throw new GraalInternalError("dynamic counters not enabled"); - } this.name = name; this.group = group; this.increment = increment; - this.addContext = addContext; + this.withContext = withContext; + } + + public ValueNode getIncrement() { + return increment; } public String getName() { return name; } - public long getIncrement() { - return increment; - } - - public boolean isAddContext() { - return addContext; - } - - private static synchronized int getIndex(String name) { - Integer index = INDEXES.get(name); - if (index == null) { - index = INDEXES.size(); - INDEXES.put(name, index); - if (index >= MAX_COUNTERS) { - throw new GraalInternalError("too many dynamic counters"); - } - return index; - } else { - return index; - } - } - - public static synchronized void dump(PrintStream out, double seconds) { - for (String group : new HashSet<>(Arrays.asList(GROUPS))) { - if (group != null) { - dumpCounters(out, seconds, true, group); - dumpCounters(out, seconds, false, group); - } - } - out.println("============================"); - - clear(); + public String getGroup() { + return group; } - private static void dumpCounters(PrintStream out, double seconds, boolean staticCounter, String group) { - TreeMap<Long, String> sorted = new TreeMap<>(); - - long[] array = staticCounter ? STATIC_COUNTERS : COUNTERS; - long sum = 0; - for (Map.Entry<String, Integer> entry : INDEXES.entrySet()) { - int index = entry.getValue(); - if (GROUPS[index].equals(group)) { - sum += array[index]; - sorted.put(array[index] * MAX_COUNTERS + index, entry.getKey()); - } - } - - if (sum > 0) { - long cutoff = sum / 1000; - long sum2 = 0; - if (staticCounter) { - out.println("=========== " + group + " static counters: "); - for (Map.Entry<Long, String> entry : sorted.entrySet()) { - long counter = entry.getKey() / MAX_COUNTERS; - sum2 += counter; - if (sum2 >= cutoff) { - out.println(counter + " \t" + ((counter * 200 + 1) / sum / 2) + "% \t" + entry.getValue()); - } - } - out.println(sum + ": total"); - } else { - if (group.startsWith("~")) { - out.println("=========== " + group + " dynamic counters"); - for (Map.Entry<Long, String> entry : sorted.entrySet()) { - long counter = entry.getKey() / MAX_COUNTERS; - sum2 += counter; - if (sum2 >= cutoff) { - out.println(counter + " \t" + ((counter * 200 + 1) / sum / 2) + "% \t" + entry.getValue()); - } - } - out.println(sum + "/s: total"); - } else { - out.println("=========== " + group + " dynamic counters, time = " + seconds + " s"); - for (Map.Entry<Long, String> entry : sorted.entrySet()) { - long counter = entry.getKey() / MAX_COUNTERS; - sum2 += counter; - if (sum2 >= cutoff) { - out.println((long) (counter / seconds) + "/s \t" + ((counter * 200 + 1) / sum / 2) + "% \t" + entry.getValue()); - } - } - out.println((long) (sum / seconds) + "/s: total"); - } - } - } - } - - public static void clear() { - Arrays.fill(COUNTERS, 0); + public boolean isWithContext() { + return withContext; } @Override public void lower(LoweringTool tool) { - if (!enabled) { - throw new GraalInternalError("counter nodes shouldn't exist when not enabled"); - } - if (excludedClassPrefix == null || !graph().method().getDeclaringClass().getName().startsWith(excludedClassPrefix)) { - int index = addContext ? getIndex(name + " @ " + MetaUtil.format("%h.%n", graph().method())) : getIndex(name); - STATIC_COUNTERS[index] += increment; - GROUPS[index] = group; - - ConstantNode arrayConstant = ConstantNode.forObject(COUNTERS, tool.getRuntime(), graph()); - ConstantNode indexConstant = ConstantNode.forInt(index, graph()); - LoadIndexedNode load = graph().add(new LoadIndexedNode(arrayConstant, indexConstant, Kind.Long)); - IntegerAddNode add = graph().add(new IntegerAddNode(Kind.Long, load, ConstantNode.forLong(increment, graph()))); - StoreIndexedNode store = graph().add(new StoreIndexedNode(arrayConstant, indexConstant, Kind.Long, add)); - - graph().addBeforeFixed(this, load); - graph().addBeforeFixed(this, store); - load.lower(tool); - store.lower(tool); - } - graph().removeFixed(this); + tool.getLowerer().lower(this, tool); } - public static void addLowLevel(String group, String name, long increment, boolean addContext, FixedNode position, MetaAccessProvider runtime) { - if (!enabled) { - throw new GraalInternalError("counter nodes shouldn't exist when not enabled"); - } + public static void addCounterBefore(String group, String name, long increment, boolean withContext, FixedNode position) { StructuredGraph graph = position.graph(); - if (excludedClassPrefix == null || !graph.method().getDeclaringClass().getName().startsWith(excludedClassPrefix)) { - int index = addContext ? getIndex(name + " @ " + MetaUtil.format("%h.%n", graph.method())) : getIndex(name); - STATIC_COUNTERS[index] += increment; - GROUPS[index] = group; - - ConstantNode arrayConstant = ConstantNode.forObject(COUNTERS, runtime, graph); - ConstantLocationNode location = ConstantLocationNode.create(NamedLocationIdentity.getArrayLocation(Kind.Long), Kind.Long, Unsafe.ARRAY_LONG_BASE_OFFSET + Unsafe.ARRAY_LONG_INDEX_SCALE * - index, graph); - ReadNode read = graph.add(new ReadNode(arrayConstant, location, StampFactory.forKind(Kind.Long), BarrierType.NONE, false)); - IntegerAddNode add = graph.add(new IntegerAddNode(Kind.Long, read, ConstantNode.forLong(increment, graph))); - WriteNode write = graph.add(new WriteNode(arrayConstant, add, location, BarrierType.NONE, false)); - - graph.addBeforeFixed(position, read); - graph.addBeforeFixed(position, write); - } + graph.addBeforeFixed(position, position.graph().add(new DynamicCounterNode(name, group, ConstantNode.forLong(increment, position.graph()), withContext))); } - public static void addCounterBefore(String group, String name, long increment, boolean addContext, FixedNode position) { - if (enabled) { - StructuredGraph graph = position.graph(); - DynamicCounterNode counter = graph.add(new DynamicCounterNode(name, group, increment, addContext)); - graph.addBeforeFixed(position, counter); - } - } + @NodeIntrinsic + public static native void counter(@ConstantNodeParameter String name, @ConstantNodeParameter String group, long increment, @ConstantNodeParameter boolean addContext); + }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/debug/SurvivingCounterNode.java Fri Oct 11 17:14:35 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,58 +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.nodes.debug; - -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.calc.*; -import com.oracle.graal.nodes.spi.*; - -/** - * This is a special version of the dynamic counter node that removes itself as soon as it's the - * only usage of the associated node. This way it only increments the counter if the node is - * actually executed. - */ -public class SurvivingCounterNode extends DynamicCounterNode implements Simplifiable, Virtualizable { - - @Input private ValueNode checkedValue; - - public SurvivingCounterNode(String group, String name, long increment, boolean addContext, ValueNode checkedValue) { - super(group, name, increment, addContext); - this.checkedValue = checkedValue; - } - - @Override - public void simplify(SimplifierTool tool) { - if (checkedValue instanceof FloatingNode && checkedValue.usages().count() == 1) { - tool.addToWorkList(checkedValue); - graph().removeFixed(this); - } - } - - @Override - public void virtualize(VirtualizerTool tool) { - State state = tool.getObjectState(checkedValue); - if (state != null && state.getState() == EscapeState.Virtual) { - tool.delete(); - } - } -}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/debug/WeakCounterNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -0,0 +1,65 @@ +/* + * 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.debug; + +import com.oracle.graal.graph.spi.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.calc.*; +import com.oracle.graal.nodes.spi.*; + +/** + * This is a special version of the dynamic counter node that removes itself as soon as it's the + * only usage of the associated node. This way it only increments the counter if the node is + * actually executed. + */ +public class WeakCounterNode extends DynamicCounterNode implements Simplifiable, Virtualizable { + + @Input private ValueNode checkedValue; + + public WeakCounterNode(String group, String name, ValueNode increment, boolean addContext, ValueNode checkedValue) { + super(group, name, increment, addContext); + this.checkedValue = checkedValue; + } + + @Override + public void simplify(SimplifierTool tool) { + if (checkedValue instanceof FloatingNode && checkedValue.usages().count() == 1) { + tool.addToWorkList(checkedValue); + graph().removeFixed(this); + } + } + + @Override + public void virtualize(VirtualizerTool tool) { + State state = tool.getObjectState(checkedValue); + if (state != null && state.getState() == EscapeState.Virtual) { + tool.delete(); + } + } + + public static void addCounterBefore(String group, String name, long increment, boolean addContext, ValueNode checkedValue, FixedNode position) { + StructuredGraph graph = position.graph(); + WeakCounterNode counter = graph.add(new WeakCounterNode(name, group, ConstantNode.forLong(increment, graph), addContext, checkedValue)); + graph.addBeforeFixed(position, counter); + } +}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/AccessNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/AccessNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -22,7 +22,6 @@ */ package com.oracle.graal.nodes.extended; -import com.oracle.graal.api.meta.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.type.*; @@ -83,11 +82,6 @@ } @Override - public DeoptimizationReason getDeoptimizationReason() { - return DeoptimizationReason.NullCheckException; - } - - @Override public GuardingNode getGuard() { return guard; }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/AddLocationNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/AddLocationNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -24,6 +24,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.spi.*; @@ -69,7 +70,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (x instanceof ConstantLocationNode) { return canonical((ConstantLocationNode) x, getY()); }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BoxNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BoxNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -23,6 +23,8 @@ package com.oracle.graal.nodes.extended; import com.oracle.graal.api.meta.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.spi.*; @@ -54,11 +56,11 @@ @Override public void lower(LoweringTool tool) { - tool.getRuntime().lower(this, tool); + tool.getLowerer().lower(this, tool); } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { /* * Constant values are not canonicalized into their constant boxing objects because this * would mean that the information that they came from a valueOf is lost.
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BranchProbabilityNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BranchProbabilityNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -23,6 +23,7 @@ package com.oracle.graal.nodes.extended; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.spi.*; @@ -64,7 +65,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (probability.isConstant()) { double probabilityValue = probability.asConstant().asDouble(); if (probabilityValue < 0.0) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingAccessNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingAccessNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -22,7 +22,6 @@ */ package com.oracle.graal.nodes.extended; -import com.oracle.graal.api.meta.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.type.*; @@ -75,11 +74,6 @@ } @Override - public DeoptimizationReason getDeoptimizationReason() { - return DeoptimizationReason.NullCheckException; - } - - @Override public FrameState getDeoptimizationState() { return deoptState; }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingReadNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingReadNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -24,7 +24,9 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.PhiNode.PhiType; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -65,7 +67,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { return ReadNode.canonicalizeRead(this, location(), object(), tool, isCompressible()); } @@ -73,4 +75,25 @@ public Access asFixedNode() { return graph().add(new ReadNode(object(), nullCheckLocation(), stamp(), getGuard(), getBarrierType(), isCompressible())); } + + private static boolean isMemoryCheckPoint(Node n) { + return n instanceof MemoryCheckpoint.Single || n instanceof MemoryCheckpoint.Multi; + } + + private static boolean isMemoryPhi(Node n) { + return n instanceof PhiNode && ((PhiNode) n).type() == PhiType.Memory; + } + + private static boolean isMemoryProxy(Node n) { + return n instanceof ProxyNode && ((ProxyNode) n).type() == PhiType.Memory; + } + + @Override + public boolean verify() { + Node lla = lastLocationAccess(); + if (lla != null && !(isMemoryCheckPoint(lla) || isMemoryPhi(lla) || isMemoryProxy(lla))) { + assert false : "lastLocationAccess of " + this + " should be a MemoryCheckpoint, but is " + lla; + } + return super.verify(); + } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ForeignCallNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ForeignCallNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -36,28 +36,28 @@ public class ForeignCallNode extends AbstractStateSplit implements LIRLowerable, DeoptimizingNode, MemoryCheckpoint.Multi { @Input private final NodeInputList<ValueNode> arguments; - private final MetaAccessProvider runtime; + private final MetaAccessProvider metaAccess; @Input private FrameState deoptState; private final ForeignCallDescriptor descriptor; - public ForeignCallNode(MetaAccessProvider runtime, ForeignCallDescriptor descriptor, ValueNode... arguments) { + public ForeignCallNode(MetaAccessProvider metaAccess, ForeignCallDescriptor descriptor, ValueNode... arguments) { super(StampFactory.forKind(Kind.fromJavaClass(descriptor.getResultType()))); this.arguments = new NodeInputList<>(this, arguments); this.descriptor = descriptor; - this.runtime = runtime; + this.metaAccess = metaAccess; } - protected ForeignCallNode(MetaAccessProvider runtime, ForeignCallDescriptor descriptor, Stamp stamp) { + protected ForeignCallNode(MetaAccessProvider metaAccess, ForeignCallDescriptor descriptor, Stamp stamp) { super(stamp); this.arguments = new NodeInputList<>(this); this.descriptor = descriptor; - this.runtime = runtime; + this.metaAccess = metaAccess; } @Override public boolean hasSideEffect() { - return !runtime.isReexecutable(descriptor); + return !metaAccess.isReexecutable(descriptor); } public ForeignCallDescriptor getDescriptor() { @@ -66,7 +66,7 @@ @Override public LocationIdentity[] getLocationIdentities() { - return runtime.getKilledLocations(descriptor); + return metaAccess.getKilledLocations(descriptor); } protected Value[] operands(LIRGeneratorTool gen) { @@ -79,7 +79,7 @@ @Override public void generate(LIRGeneratorTool gen) { - ForeignCallLinkage linkage = gen.getRuntime().lookupForeignCall(descriptor); + ForeignCallLinkage linkage = gen.getCodeCache().lookupForeignCall(descriptor); Value[] operands = operands(gen); Value result = gen.emitForeignCall(linkage, this, operands); if (result != null) { @@ -126,12 +126,7 @@ @Override public boolean canDeoptimize() { - return runtime.canDeoptimize(descriptor); - } - - @Override - public DeoptimizationReason getDeoptimizationReason() { - return null; + return metaAccess.canDeoptimize(descriptor); } @Override
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/IndexedLocationNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/IndexedLocationNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -24,6 +24,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -85,7 +86,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (index == null || indexScaling == 0) { return ConstantLocationNode.create(getLocationIdentity(), getValueKind(), displacement, graph()); } else if (index.isConstant()) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/IntegerSwitchNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/IntegerSwitchNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -25,6 +25,7 @@ import java.util.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadHubNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadHubNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -24,6 +24,8 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.api.meta.ResolvedJavaType.Representation; +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -60,14 +62,14 @@ @Override public void lower(LoweringTool tool) { if (graph().getGuardsStage() == StructuredGraph.GuardsStage.FIXED_DEOPTS) { - tool.getRuntime().lower(this, tool); + tool.getLowerer().lower(this, tool); } } @Override - public ValueNode canonical(CanonicalizerTool tool) { - MetaAccessProvider runtime = tool.runtime(); - if (runtime != null && object.stamp() instanceof ObjectStamp) { + public Node canonical(CanonicalizerTool tool) { + MetaAccessProvider metaAccess = tool.getMetaAccess(); + if (metaAccess != null && object.stamp() instanceof ObjectStamp) { ObjectStamp stamp = (ObjectStamp) object.stamp(); ResolvedJavaType exactType; @@ -83,7 +85,7 @@ } if (exactType != null) { - return ConstantNode.forConstant(exactType.getEncoding(Representation.ObjectHub), runtime, graph()); + return ConstantNode.forConstant(exactType.getEncoding(Representation.ObjectHub), metaAccess, graph()); } } return this;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadMethodNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadMethodNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -52,7 +52,7 @@ @Override public void lower(LoweringTool tool) { - tool.getRuntime().lower(this, tool); + tool.getLowerer().lower(this, tool); } public ResolvedJavaMethod getMethod() {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/NullCheckNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/NullCheckNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -22,7 +22,6 @@ */ package com.oracle.graal.nodes.extended; -import com.oracle.graal.api.meta.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -49,9 +48,4 @@ public boolean canDeoptimize() { return true; } - - @Override - public DeoptimizationReason getDeoptimizationReason() { - return DeoptimizationReason.NullCheckException; - } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/OSRStartNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/OSRStartNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -30,7 +30,7 @@ @Override public void lower(LoweringTool tool) { - tool.getRuntime().lower(this, tool); + tool.getLowerer().lower(this, tool); } public NodeIterable<OSRLocalNode> getOSRLocals() {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -23,6 +23,8 @@ package com.oracle.graal.nodes.extended; import com.oracle.graal.api.meta.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -41,18 +43,6 @@ super(object, location, stamp, guard, barrierType, compressible); } - public 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, 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(), (GuardingNode) guard, BarrierType.NONE, false); - } - @Override public void generate(LIRGeneratorTool gen) { Value address = location().generateAddress(gen, gen.operand(object())); @@ -60,7 +50,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { return canonicalizeRead(this, location(), object(), tool, isCompressible()); } @@ -70,29 +60,29 @@ } public static ValueNode canonicalizeRead(ValueNode read, LocationNode location, ValueNode object, CanonicalizerTool tool, boolean compressible) { - MetaAccessProvider runtime = tool.runtime(); + MetaAccessProvider metaAccess = tool.getMetaAccess(); if (read.usages().isEmpty()) { // Read without usages can be savely removed. return null; } - if (tool.canonicalizeReads() && runtime != null && object != null && object.isConstant()) { + if (tool.canonicalizeReads() && metaAccess != 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) { Object base = object.asConstant().asObject(); if (base != null) { - Constant constant = tool.runtime().readUnsafeConstant(kind, base, displacement, compressible); + Constant constant = tool.getConstantReflection().readUnsafeConstant(kind, base, displacement, compressible); if (constant != null) { - return ConstantNode.forConstant(constant, runtime, read.graph()); + return ConstantNode.forConstant(constant, metaAccess, read.graph()); } } } else if (object.kind() == Kind.Long || object.kind().getStackKind() == Kind.Int) { long base = object.asConstant().asLong(); if (base != 0L) { - Constant constant = tool.runtime().readUnsafeConstant(kind, null, base + displacement, compressible); + Constant constant = tool.getConstantReflection().readUnsafeConstant(kind, null, base + displacement, compressible); if (constant != null) { - return ConstantNode.forConstant(constant, runtime, read.graph()); + return ConstantNode.forConstant(constant, metaAccess, read.graph()); } } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/SnippetLocationNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/SnippetLocationNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -26,6 +26,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -80,7 +81,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (valueKind.isConstant() && locationIdentity.isConstant() && displacement.isConstant() && (indexScaling == null || indexScaling.isConstant())) { Kind constKind = (Kind) valueKind.asConstant().asObject(); LocationIdentity constLocation = (LocationIdentity) locationIdentity.asConstant().asObject();
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/StoreHubNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/StoreHubNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -47,7 +47,7 @@ @Override public void lower(LoweringTool tool) { - tool.getRuntime().lower(this, tool); + tool.getLowerer().lower(this, tool); } @NodeIntrinsic
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnboxNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnboxNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -23,6 +23,8 @@ package com.oracle.graal.nodes.extended; import com.oracle.graal.api.meta.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.spi.*; @@ -49,7 +51,7 @@ @Override public void lower(LoweringTool tool) { - tool.getRuntime().lower(this, tool); + tool.getLowerer().lower(this, tool); } @Override @@ -61,7 +63,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (value.isConstant()) { Constant constant = value.asConstant(); Object o = constant.asObject();
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeAccessNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeAccessNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -23,34 +23,35 @@ package com.oracle.graal.nodes.extended; import com.oracle.graal.api.meta.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; public abstract class UnsafeAccessNode extends FixedWithNextNode implements Canonicalizable { @Input private ValueNode object; @Input private ValueNode offset; - private final int displacement; private final Kind accessKind; + private final LocationIdentity locationIdentity; - public UnsafeAccessNode(Stamp stamp, ValueNode object, int displacement, ValueNode offset, Kind accessKind) { + public UnsafeAccessNode(Stamp stamp, ValueNode object, ValueNode offset, Kind accessKind, LocationIdentity locationIdentity) { super(stamp); assert accessKind != null; this.object = object; - this.displacement = displacement; this.offset = offset; this.accessKind = accessKind; + this.locationIdentity = locationIdentity; + } + + public LocationIdentity getLocationIdentity() { + return locationIdentity; } public ValueNode object() { return object; } - public int displacement() { - return displacement; - } - public ValueNode offset() { return offset; } @@ -60,14 +61,14 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { - if (offset().isConstant()) { + public Node canonical(CanonicalizerTool tool) { + if (this.getLocationIdentity() == LocationIdentity.ANY_LOCATION && offset().isConstant()) { long constantOffset = offset().asConstant().asLong(); // Try to canonicalize to a field access. ResolvedJavaType receiverType = ObjectStamp.typeOrNull(object()); if (receiverType != null) { - ResolvedJavaField field = receiverType.findInstanceFieldWithOffset(displacement() + constantOffset); + ResolvedJavaField field = receiverType.findInstanceFieldWithOffset(constantOffset); // No need for checking that the receiver is non-null. The field access includes // the null check and if a field is found, the offset is so small that this is // never a valid access of an arbitrary address. @@ -75,18 +76,9 @@ return cloneAsFieldAccess(field); } } - - if (constantOffset != 0 && Integer.MAX_VALUE - displacement() >= constantOffset) { - int intDisplacement = (int) (constantOffset + displacement()); - if (constantOffset == intDisplacement) { - return cloneWithZeroOffset(intDisplacement); - } - } } return this; } protected abstract ValueNode cloneAsFieldAccess(ResolvedJavaField field); - - protected abstract ValueNode cloneWithZeroOffset(int intDisplacement); }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeCastNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeCastNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -24,6 +24,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -58,7 +59,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { assert kind() == Kind.Object && object.kind() == Kind.Object; ObjectStamp my = (ObjectStamp) stamp();
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeLoadNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeLoadNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -35,31 +35,33 @@ * performed before the load. */ public class UnsafeLoadNode extends UnsafeAccessNode implements Lowerable, Virtualizable { + @Input private LogicNode guardingCondition; - public UnsafeLoadNode(ValueNode object, int displacement, ValueNode offset, boolean nonNull) { - this(nonNull ? StampFactory.objectNonNull() : StampFactory.object(), object, displacement, offset, Kind.Object); + public UnsafeLoadNode(ValueNode object, ValueNode offset, Kind accessKind) { + this(object, offset, accessKind, LocationIdentity.ANY_LOCATION, null); } - public UnsafeLoadNode(ValueNode object, int displacement, ValueNode offset, Kind accessKind) { - this(StampFactory.forKind(accessKind.getStackKind()), object, displacement, offset, accessKind); + public UnsafeLoadNode(ValueNode object, ValueNode offset, Kind accessKind, LocationIdentity locationIdentity, LogicNode condition) { + super(StampFactory.forKind(accessKind.getStackKind()), object, offset, accessKind, locationIdentity); + this.guardingCondition = condition; } - public UnsafeLoadNode(Stamp stamp, ValueNode object, int displacement, ValueNode offset, Kind accessKind) { - super(stamp, object, displacement, offset, accessKind); + public LogicNode getGuardingCondition() { + return guardingCondition; } @Override public void lower(LoweringTool tool) { - tool.getRuntime().lower(this, tool); + tool.getLowerer().lower(this, tool); } @Override public void virtualize(VirtualizerTool tool) { State state = tool.getObjectState(object()); if (state != null && state.getState() == EscapeState.Virtual) { - ValueNode indexValue = tool.getReplacedValue(offset()); - if (indexValue.isConstant()) { - long offset = indexValue.asConstant().asLong() + displacement(); + ValueNode offsetValue = tool.getReplacedValue(offset()); + if (offsetValue.isConstant()) { + long offset = offsetValue.asConstant().asLong(); int entryIndex = state.getVirtualObject().entryIndexForOffset(offset); if (entryIndex != -1 && state.getVirtualObject().entryKind(entryIndex) == accessKind()) { tool.replaceWith(state.getEntry(entryIndex)); @@ -73,39 +75,34 @@ return this.graph().add(new LoadFieldNode(object(), field)); } - @Override - protected ValueNode cloneWithZeroOffset(int intDisplacement) { - return graph().add(new UnsafeLoadNode(this.stamp(), object(), intDisplacement, graph().unique(ConstantNode.forInt(0, graph())), accessKind())); - } - @SuppressWarnings("unchecked") @NodeIntrinsic - public static <T> T load(Object object, @ConstantNodeParameter int displacement, long offset, @ConstantNodeParameter Kind kind) { + public static <T> T load(Object object, long offset, @ConstantNodeParameter Kind kind) { if (kind == Kind.Boolean) { - return (T) (Boolean) unsafe.getBoolean(object, displacement + offset); + return (T) (Boolean) unsafe.getBoolean(object, offset); } if (kind == Kind.Byte) { - return (T) (Byte) unsafe.getByte(object, displacement + offset); + return (T) (Byte) unsafe.getByte(object, offset); } if (kind == Kind.Short) { - return (T) (Short) unsafe.getShort(object, displacement + offset); + return (T) (Short) unsafe.getShort(object, offset); } if (kind == Kind.Char) { - return (T) (Character) unsafe.getChar(object, displacement + offset); + return (T) (Character) unsafe.getChar(object, offset); } if (kind == Kind.Int) { - return (T) (Integer) unsafe.getInt(object, displacement + offset); + return (T) (Integer) unsafe.getInt(object, offset); } if (kind == Kind.Float) { - return (T) (Float) unsafe.getFloat(object, displacement + offset); + return (T) (Float) unsafe.getFloat(object, offset); } if (kind == Kind.Long) { - return (T) (Long) unsafe.getLong(object, displacement + offset); + return (T) (Long) unsafe.getLong(object, offset); } if (kind == Kind.Double) { - return (T) (Double) unsafe.getDouble(object, displacement + offset); + return (T) (Double) unsafe.getDouble(object, offset); } assert kind == Kind.Object; - return (T) unsafe.getObject(object, displacement + offset); + return (T) unsafe.getObject(object, offset); } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeStoreNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeStoreNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -39,12 +39,12 @@ @Input private ValueNode value; @Input(notDataflow = true) private FrameState stateAfter; - public UnsafeStoreNode(ValueNode object, int displacement, ValueNode offset, ValueNode value, Kind accessKind) { - this(StampFactory.forVoid(), object, displacement, offset, value, accessKind); + public UnsafeStoreNode(ValueNode object, ValueNode offset, ValueNode value, Kind accessKind) { + this(object, offset, value, accessKind, LocationIdentity.ANY_LOCATION); } - public UnsafeStoreNode(Stamp stamp, ValueNode object, int displacement, ValueNode offset, ValueNode value, Kind accessKind) { - super(stamp, object, displacement, offset, accessKind); + public UnsafeStoreNode(ValueNode object, ValueNode offset, ValueNode value, Kind accessKind, LocationIdentity locationIdentity) { + super(StampFactory.forVoid(), object, offset, accessKind, locationIdentity); assert accessKind != Kind.Void && accessKind != Kind.Illegal; this.value = value; } @@ -69,12 +69,7 @@ @Override public void lower(LoweringTool tool) { - tool.getRuntime().lower(this, tool); - } - - @Override - public LocationIdentity getLocationIdentity() { - return LocationIdentity.ANY_LOCATION; + tool.getLowerer().lower(this, tool); } @Override @@ -83,7 +78,7 @@ if (state != null && state.getState() == EscapeState.Virtual) { ValueNode indexValue = tool.getReplacedValue(offset()); if (indexValue.isConstant()) { - long offset = indexValue.asConstant().asLong() + displacement(); + long offset = indexValue.asConstant().asLong(); int entryIndex = state.getVirtualObject().entryIndexForOffset(offset); if (entryIndex != -1 && state.getVirtualObject().entryKind(entryIndex) == accessKind()) { tool.setVirtualEntry(state, entryIndex, value()); @@ -100,13 +95,6 @@ return storeFieldNode; } - @Override - protected ValueNode cloneWithZeroOffset(int intDisplacement) { - UnsafeStoreNode unsafeStoreNode = graph().add(new UnsafeStoreNode(stamp(), object(), intDisplacement, ConstantNode.forInt(0, graph()), value(), accessKind())); - unsafeStoreNode.setStateAfter(stateAfter()); - return unsafeStoreNode; - } - public FrameState getState() { return stateAfter; } @@ -115,55 +103,55 @@ @SuppressWarnings("unused") @NodeIntrinsic - public static void store(Object object, @ConstantNodeParameter int displacement, long offset, Object value, @ConstantNodeParameter Kind kind) { - unsafe.putObject(object, offset + displacement, value); + public static void store(Object object, long offset, Object value, @ConstantNodeParameter Kind kind) { + unsafe.putObject(object, offset, value); } @SuppressWarnings("unused") @NodeIntrinsic - public static void store(Object object, @ConstantNodeParameter int displacement, long offset, boolean value, @ConstantNodeParameter Kind kind) { - unsafe.putBoolean(object, offset + displacement, value); + public static void store(Object object, long offset, boolean value, @ConstantNodeParameter Kind kind) { + unsafe.putBoolean(object, offset, value); } @SuppressWarnings("unused") @NodeIntrinsic - public static void store(Object object, @ConstantNodeParameter int displacement, long offset, byte value, @ConstantNodeParameter Kind kind) { - unsafe.putByte(object, offset + displacement, value); + public static void store(Object object, long offset, byte value, @ConstantNodeParameter Kind kind) { + unsafe.putByte(object, offset, value); } @SuppressWarnings("unused") @NodeIntrinsic - public static void store(Object object, @ConstantNodeParameter int displacement, long offset, char value, @ConstantNodeParameter Kind kind) { - unsafe.putChar(object, offset + displacement, value); + public static void store(Object object, long offset, char value, @ConstantNodeParameter Kind kind) { + unsafe.putChar(object, offset, value); } @SuppressWarnings("unused") @NodeIntrinsic - public static void store(Object object, @ConstantNodeParameter int displacement, long offset, double value, @ConstantNodeParameter Kind kind) { - unsafe.putDouble(object, offset + displacement, value); + public static void store(Object object, long offset, double value, @ConstantNodeParameter Kind kind) { + unsafe.putDouble(object, offset, value); } @SuppressWarnings("unused") @NodeIntrinsic - public static void store(Object object, @ConstantNodeParameter int displacement, long offset, float value, @ConstantNodeParameter Kind kind) { - unsafe.putFloat(object, offset + displacement, value); + public static void store(Object object, long offset, float value, @ConstantNodeParameter Kind kind) { + unsafe.putFloat(object, offset, value); } @SuppressWarnings("unused") @NodeIntrinsic - public static void store(Object object, @ConstantNodeParameter int displacement, long offset, int value, @ConstantNodeParameter Kind kind) { - unsafe.putInt(object, offset + displacement, value); + public static void store(Object object, long offset, int value, @ConstantNodeParameter Kind kind) { + unsafe.putInt(object, offset, value); } @SuppressWarnings("unused") @NodeIntrinsic - public static void store(Object object, @ConstantNodeParameter int displacement, long offset, long value, @ConstantNodeParameter Kind kind) { - unsafe.putLong(object, offset + displacement, value); + public static void store(Object object, long offset, long value, @ConstantNodeParameter Kind kind) { + unsafe.putLong(object, offset, value); } @SuppressWarnings("unused") @NodeIntrinsic - public static void store(Object object, @ConstantNodeParameter int displacement, long offset, short value, @ConstantNodeParameter Kind kind) { - unsafe.putShort(object, offset + displacement, value); + public static void store(Object object, long offset, short value, @ConstantNodeParameter Kind kind) { + unsafe.putShort(object, offset, value); } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ValueAnchorNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ValueAnchorNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -23,6 +23,7 @@ package com.oracle.graal.nodes.extended; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -30,7 +31,7 @@ /** * The ValueAnchor instruction keeps non-CFG (floating) nodes above a certain point in the graph. */ -public final class ValueAnchorNode extends FixedWithNextNode implements Canonicalizable, LIRLowerable, IterableNodeType, Virtualizable, GuardingNode { +public final class ValueAnchorNode extends FixedWithNextNode implements Canonicalizable, LIRLowerable, Virtualizable, GuardingNode { @Input private ValueNode anchored; @@ -49,7 +50,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (anchored != null && !anchored.isConstant() && !(anchored instanceof FixedNode)) { // Found entry that needs this anchor. return this;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AbstractNewArrayNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AbstractNewArrayNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -22,7 +22,8 @@ */ package com.oracle.graal.nodes.java; -import com.oracle.graal.api.meta.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -76,7 +77,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (usages().isEmpty()) { Stamp stamp = length.stamp(); if (stamp instanceof IntegerStamp && ((IntegerStamp) stamp).isPositive()) { @@ -88,16 +89,11 @@ @Override public void lower(LoweringTool tool) { - tool.getRuntime().lower(this, tool); + tool.getLowerer().lower(this, tool); } @Override public boolean canDeoptimize() { return true; } - - @Override - public DeoptimizationReason getDeoptimizationReason() { - return DeoptimizationReason.RuntimeConstraint; - } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessFieldNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessFieldNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -84,7 +84,7 @@ @Override public void lower(LoweringTool tool) { - tool.getRuntime().lower(this, tool); + tool.getLowerer().lower(this, tool); } @Override
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessIndexedNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessIndexedNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -65,6 +65,6 @@ @Override public void lower(LoweringTool tool) { - tool.getRuntime().lower(this, tool); + tool.getLowerer().lower(this, tool); } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ArrayLengthNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ArrayLengthNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -23,6 +23,8 @@ package com.oracle.graal.nodes.java; import com.oracle.graal.api.meta.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -44,8 +46,8 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { - ValueNode length = readArrayLength(array(), tool.runtime()); + public Node canonical(CanonicalizerTool tool) { + ValueNode length = readArrayLength(array(), tool.getConstantReflection()); if (length != null) { return length; } @@ -58,17 +60,17 @@ * @param array an array * @return a node representing the length of {@code array} or null if it is not available */ - public static ValueNode readArrayLength(ValueNode array, MetaAccessProvider runtime) { + public static ValueNode readArrayLength(ValueNode array, ConstantReflectionProvider constantReflection) { if (array instanceof ArrayLengthProvider) { ValueNode length = ((ArrayLengthProvider) array).length(); if (length != null) { return length; } } - if (runtime != null && array.isConstant() && !array.isNullConstant()) { + if (constantReflection != null && array.isConstant() && !array.isNullConstant()) { Constant constantValue = array.asConstant(); if (constantValue != null && constantValue.isNonNull()) { - Integer constantLength = runtime.lookupArrayLength(constantValue); + Integer constantLength = constantReflection.lookupArrayLength(constantValue); if (constantLength != null) { return ConstantNode.forInt(constantLength, array.graph()); } @@ -79,7 +81,7 @@ @Override public void lower(LoweringTool tool) { - tool.getRuntime().lower(this, tool); + tool.getLowerer().lower(this, tool); } @NodeIntrinsic
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastDynamicNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastDynamicNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -23,6 +23,8 @@ package com.oracle.graal.nodes.java; import com.oracle.graal.api.meta.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -59,7 +61,7 @@ @Override public void lower(LoweringTool tool) { - tool.getRuntime().lower(this, tool); + tool.getLowerer().lower(this, tool); } @Override @@ -68,7 +70,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { assert object() != null : this; if (ObjectStamp.isObjectAlwaysNull(object())) { @@ -76,7 +78,7 @@ } if (hub.isConstant() && hub.kind() == Kind.Object && hub.asConstant().asObject() instanceof Class) { Class clazz = (Class) hub.asConstant().asObject(); - ResolvedJavaType t = tool.runtime().lookupJavaType(clazz); + ResolvedJavaType t = tool.getMetaAccess().lookupJavaType(clazz); return graph().add(new CheckCastNode(t, object(), null, forStoreCheck)); } return this;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -22,14 +22,14 @@ */ package com.oracle.graal.nodes.java; -import static com.oracle.graal.api.code.DeoptimizationAction.*; +import static com.oracle.graal.api.meta.DeoptimizationAction.*; import static com.oracle.graal.api.meta.DeoptimizationReason.*; import static com.oracle.graal.nodes.extended.BranchProbabilityNode.*; -import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.api.meta.ProfilingInfo.TriState; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.spi.*; @@ -136,7 +136,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { assert object() != null : this; ResolvedJavaType objectType = ObjectStamp.typeOrNull(object());
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CompareAndSwapNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CompareAndSwapNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -79,7 +79,7 @@ @Override public void lower(LoweringTool tool) { - tool.getRuntime().lower(this, tool); + tool.getLowerer().lower(this, tool); } // specialized on value type until boxing/unboxing is sorted out in intrinsification
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/DynamicNewArrayNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/DynamicNewArrayNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -25,8 +25,9 @@ import java.lang.reflect.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; /** @@ -51,11 +52,11 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (elementType.isConstant()) { Class<?> elementClass = (Class<?>) elementType.asConstant().asObject(); if (elementClass != null && !(elementClass.equals(void.class))) { - ResolvedJavaType javaType = tool.runtime().lookupJavaType(elementClass); + ResolvedJavaType javaType = tool.getMetaAccess().lookupJavaType(elementClass); return graph().add(new NewArrayNode(javaType, length(), fillContents())); } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ExceptionObjectNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ExceptionObjectNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -27,6 +27,7 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.*; @@ -38,8 +39,8 @@ */ public class ExceptionObjectNode extends DispatchBeginNode implements Lowerable, MemoryCheckpoint.Single { - public ExceptionObjectNode(MetaAccessProvider runtime) { - super(StampFactory.declaredNonNull(runtime.lookupJavaType(Throwable.class))); + public ExceptionObjectNode(MetaAccessProvider metaAccess) { + super(StampFactory.declaredNonNull(metaAccess.lookupJavaType(Throwable.class))); } @Override
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfDynamicNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfDynamicNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -23,6 +23,8 @@ package com.oracle.graal.nodes.java; import com.oracle.graal.api.meta.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -51,15 +53,15 @@ @Override public void lower(LoweringTool tool) { - tool.getRuntime().lower(this, tool); + tool.getLowerer().lower(this, tool); } @Override - public LogicNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { assert object() != null : this; if (mirror().isConstant()) { Class clazz = (Class) mirror().asConstant().asObject(); - ResolvedJavaType t = tool.runtime().lookupJavaType(clazz); + ResolvedJavaType t = tool.getMetaAccess().lookupJavaType(clazz); return graph().unique(new InstanceOfNode(t, object(), null)); } return this;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -23,6 +23,8 @@ package com.oracle.graal.nodes.java; import com.oracle.graal.api.meta.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.spi.*; @@ -52,11 +54,11 @@ @Override public void lower(LoweringTool tool) { - tool.getRuntime().lower(this, tool); + tool.getLowerer().lower(this, tool); } @Override - public LogicNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { Stamp stamp = object().stamp(); if (!(stamp instanceof ObjectStamp)) { return this;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadExceptionObjectNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadExceptionObjectNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -45,6 +45,6 @@ @Override public void lower(LoweringTool tool) { - tool.getRuntime().lower(this, tool); + tool.getLowerer().lower(this, tool); } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadFieldNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadFieldNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -27,6 +27,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; import com.oracle.graal.graph.iterators.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -36,7 +37,7 @@ * The {@code LoadFieldNode} represents a read of a static or instance field. */ @NodeInfo(nameTemplate = "LoadField#{p#field/s}") -public final class LoadFieldNode extends AccessFieldNode implements Canonicalizable, IterableNodeType, VirtualizableRoot { +public final class LoadFieldNode extends AccessFieldNode implements Canonicalizable, VirtualizableRoot { /** * Creates a new LoadFieldNode instance. @@ -58,8 +59,8 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { - MetaAccessProvider runtime = tool.runtime(); + public Node canonical(CanonicalizerTool tool) { + MetaAccessProvider runtime = tool.getMetaAccess(); if (tool.canonicalizeReads() && runtime != null) { ConstantNode constant = asConstant(runtime); if (constant != null) { @@ -76,7 +77,7 @@ /** * Gets a constant value for this load if possible. */ - public ConstantNode asConstant(MetaAccessProvider runtime) { + public ConstantNode asConstant(MetaAccessProvider metaAccess) { Constant constant = null; if (isStatic()) { constant = field().readConstantValue(null); @@ -84,12 +85,12 @@ constant = field().readConstantValue(object().asConstant()); } if (constant != null) { - return ConstantNode.forConstant(constant, runtime, graph()); + return ConstantNode.forConstant(constant, metaAccess, graph()); } return null; } - private PhiNode asPhi(MetaAccessProvider runtime) { + private PhiNode asPhi(MetaAccessProvider metaAccess) { if (!isStatic() && Modifier.isFinal(field.getModifiers()) && object() instanceof PhiNode && ((PhiNode) object()).values().filter(NodePredicates.isNotA(ConstantNode.class)).isEmpty()) { PhiNode phi = (PhiNode) object(); Constant[] constants = new Constant[phi.valueCount()]; @@ -102,7 +103,7 @@ } PhiNode newPhi = graph().addWithoutUnique(new PhiNode(stamp(), phi.merge())); for (int i = 0; i < phi.valueCount(); i++) { - newPhi.addInput(ConstantNode.forConstant(constants[i], runtime, graph())); + newPhi.addInput(ConstantNode.forConstant(constants[i], metaAccess, graph())); } return newPhi; }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadIndexedNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadIndexedNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -23,7 +23,6 @@ package com.oracle.graal.nodes.java; import com.oracle.graal.api.meta.*; -import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -31,7 +30,7 @@ /** * The {@code LoadIndexedNode} represents a read from an element of an array. */ -public final class LoadIndexedNode extends AccessIndexedNode implements IterableNodeType, Virtualizable { +public final class LoadIndexedNode extends AccessIndexedNode implements Virtualizable { /** * Creates a new LoadIndexedNode.
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -26,8 +26,8 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; public class MethodCallTargetNode extends CallTargetNode implements IterableNodeType, Canonicalizable { @@ -125,7 +125,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (!isStatic()) { ValueNode receiver = receiver(); if (receiver != null && ObjectStamp.isExactType(receiver) && ObjectStamp.typeOrNull(receiver) != null) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MonitorEnterNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MonitorEnterNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -51,7 +51,7 @@ @Override public void lower(LoweringTool tool) { - tool.getRuntime().lower(this, tool); + tool.getLowerer().lower(this, tool); } public int getLockDepth() {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MonitorExitNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MonitorExitNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -52,7 +52,7 @@ @Override public void lower(LoweringTool tool) { - tool.getRuntime().lower(this, tool); + tool.getLowerer().lower(this, tool); } public int getLockDepth() {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewInstanceNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewInstanceNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -24,6 +24,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -68,7 +69,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (usages().isEmpty()) { return null; } else { @@ -78,7 +79,7 @@ @Override public void lower(LoweringTool tool) { - tool.getRuntime().lower(this, tool); + tool.getLowerer().lower(this, tool); } @Override @@ -100,9 +101,4 @@ public boolean canDeoptimize() { return true; } - - @Override - public DeoptimizationReason getDeoptimizationReason() { - return DeoptimizationReason.RuntimeConstraint; - } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewMultiArrayNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewMultiArrayNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -63,7 +63,7 @@ @Override public void lower(LoweringTool tool) { - tool.getRuntime().lower(this, tool); + tool.getLowerer().lower(this, tool); } public ResolvedJavaType type() { @@ -74,9 +74,4 @@ public boolean canDeoptimize() { return true; } - - @Override - public DeoptimizationReason getDeoptimizationReason() { - return DeoptimizationReason.RuntimeConstraint; - } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/RegisterFinalizerNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/RegisterFinalizerNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -24,6 +24,8 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -50,12 +52,12 @@ @Override public void generate(LIRGeneratorTool gen) { - ForeignCallLinkage linkage = gen.getRuntime().lookupForeignCall(REGISTER_FINALIZER); + ForeignCallLinkage linkage = gen.getCodeCache().lookupForeignCall(REGISTER_FINALIZER); gen.emitForeignCall(linkage, this, gen.operand(object())); } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (!(object.stamp() instanceof ObjectStamp)) { return this; } @@ -105,11 +107,6 @@ deoptState = f; } - @Override - public DeoptimizationReason getDeoptimizationReason() { - return null; - } - @SuppressWarnings("unused") @NodeIntrinsic public static void register(Object thisObj) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/TypeSwitchNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/TypeSwitchNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -26,6 +26,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.api.meta.ResolvedJavaType.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.*; @@ -85,7 +86,7 @@ for (int i = 0; i < keyCount(); i++) { Constant typeHub = keyAt(i); assert constant.getKind() == typeHub.getKind(); - if (tool.runtime().constantEquals(constant, typeHub)) { + if (tool.getConstantReflection().constantEquals(constant, typeHub)) { survivingEdge = keySuccessorIndex(i); } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/Canonicalizable.java Fri Oct 11 17:14:35 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,30 +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.spi; - -import com.oracle.graal.nodes.*; - -public interface Canonicalizable { - - ValueNode canonical(CanonicalizerTool tool); -}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/CanonicalizerTool.java Fri Oct 11 17:14:35 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,38 +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.spi; - -import com.oracle.graal.api.code.*; -import com.oracle.graal.api.meta.*; -import com.oracle.graal.graph.*; - -public interface CanonicalizerTool { - - Assumptions assumptions(); - - MetaAccessProvider runtime(); - - boolean canonicalizeReads(); - - void removeIfUnused(Node node); -}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/DelegatingGraalCodeCacheProvider.java Fri Oct 11 17:14:35 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2011, 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.spi; - -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.*; - -/** - * A {@link GraalCodeCacheProvider} that delegates to another {@link GraalCodeCacheProvider}. - */ -public class DelegatingGraalCodeCacheProvider extends DelegatingCodeCacheProvider implements GraalCodeCacheProvider { - - public DelegatingGraalCodeCacheProvider(CodeCacheProvider delegate) { - super(delegate); - } - - @Override - protected GraalCodeCacheProvider delegate() { - return (GraalCodeCacheProvider) super.delegate(); - } - - public InstalledCode addMethod(ResolvedJavaMethod method, CompilationResult compResult, Graph graph) { - return delegate().addMethod(method, compResult, graph); - } - - public void lower(Node n, LoweringTool tool) { - delegate().lower(n, tool); - } - - public ValueNode reconstructArrayIndex(LocationNode location) { - return delegate().reconstructArrayIndex(location); - } -}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/GraalCodeCacheProvider.java Fri Oct 11 17:14:35 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2011, 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.spi; - -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.*; - -/** - * Graal-specific extensions for the code cache provider interface. - */ -public interface GraalCodeCacheProvider extends CodeCacheProvider { - - /** - * Adds the given compilation result as an implementation of the given method without making it - * the default implementation. The graph might be inlined later on. - * - * @param method a method to which the executable code is begin added - * @param compResult the compilation result to be added - * @param graph the graph that represents the method - * @return a reference to the compiled and ready-to-run code or null if the code installation - * failed - */ - InstalledCode addMethod(ResolvedJavaMethod method, CompilationResult compResult, Graph graph); - - void lower(Node n, LoweringTool tool); - - /** - * Reconstructs the array index from a location node that was created as a lowering of an indexed - * access to an array. - * - * @param location a location pointing to an element in an array - * @return a node that gives the index of the element - */ - ValueNode reconstructArrayIndex(LocationNode location); -}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LIRGeneratorTool.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LIRGeneratorTool.java Fri Oct 11 17:21:14 2013 +0200 @@ -33,7 +33,9 @@ TargetDescription target(); - CodeCacheProvider getRuntime(); + MetaAccessProvider getMetaAccess(); + + CodeCacheProvider getCodeCache(); /** * Checks whether the supplied constant can be used without loading it into a register for most @@ -63,7 +65,7 @@ void emitMembar(int barriers); - void emitDeoptimize(DeoptimizationAction action, DeoptimizingNode deopting); + void emitDeoptimize(Value actionAndReason, DeoptimizingNode deopting); void emitNullCheck(ValueNode v, DeoptimizingNode deopting);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LoweringProvider.java Fri Oct 11 17:21:14 2013 +0200 @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2011, 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.spi; + +import com.oracle.graal.graph.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.extended.*; + +/** + * Provides a capability for replacing a higher node with one or more lower level nodes. + */ +public interface LoweringProvider { + + void lower(Node n, LoweringTool tool); + + /** + * Reconstructs the array index from a location node that was created as a lowering of an + * indexed access to an array. + * + * @param location a location pointing to an element in an array + * @return a node that gives the index of the element + */ + ValueNode reconstructArrayIndex(LocationNode location); +}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LoweringTool.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LoweringTool.java Fri Oct 11 17:21:14 2013 +0200 @@ -31,7 +31,13 @@ public interface LoweringTool { - GraalCodeCacheProvider getRuntime(); + MetaAccessProvider getMetaAccess(); + + CodeCacheProvider getCodeCache(); + + LoweringProvider getLowerer(); + + ConstantReflectionProvider getConstantReflection(); Replacements getReplacements();
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/NodeWithState.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/NodeWithState.java Fri Oct 11 17:21:14 2013 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/ReplacementsProvider.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/ReplacementsProvider.java Fri Oct 11 17:21:14 2013 +0200 @@ -30,5 +30,5 @@ */ public interface ReplacementsProvider { - void registerReplacements(MetaAccessProvider runtime, Replacements replacements, TargetDescription target); + void registerReplacements(MetaAccessProvider metaAccess, Replacements replacements, TargetDescription target); }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/Simplifiable.java Fri Oct 11 17:14:35 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,37 +0,0 @@ -/* - * Copyright (c) 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.nodes.spi; - -/** - * This interface allows nodes to perform more complicated simplifications, in contrast to - * {@link Canonicalizable}, which supports only replacing the current node. - * - * Implementors of this interface need to be aware that they need to call - * {@link SimplifierTool#addToWorkList(com.oracle.graal.graph.Node)} for each node that might be - * influenced (in terms of simplification and canonicalization) by the actions performed in - * simplify. - */ -public interface Simplifiable { - - void simplify(SimplifierTool tool); -}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/SimplifierTool.java Fri Oct 11 17:14:35 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,39 +0,0 @@ -/* - * Copyright (c) 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.nodes.spi; - -import com.oracle.graal.graph.*; -import com.oracle.graal.nodes.*; - -/** - * @see Simplifiable - */ -public interface SimplifierTool extends CanonicalizerTool { - - void deleteBranch(FixedNode branch); - - /** - * Adds a node to the worklist independent of whether it has already been on the worklist. - */ - void addToWorkList(Node node); -}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/Virtualizable.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/Virtualizable.java Fri Oct 11 17:21:14 2013 +0200 @@ -34,7 +34,7 @@ public interface Virtualizable { public static enum EscapeState { - Virtual, ThreadLocal, Global + Virtual, Materialized } public abstract static class State {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/VirtualizerTool.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/VirtualizerTool.java Fri Oct 11 17:21:14 2013 +0200 @@ -87,15 +87,6 @@ */ void setVirtualEntry(State state, int index, ValueNode value); - /** - * Queries the current state of the given value: if it was materialized or not. - * - * @param value the value whose state should be queried. - * @return the materialized value (usually a MaterializeObjectNode or a {@link PhiNode}) if it - * was materialized, null otherwise. - */ - ValueNode getMaterializedValue(ValueNode value); - // scalar replacement /**
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/FloatStamp.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/FloatStamp.java Fri Oct 11 17:21:14 2013 +0200 @@ -92,12 +92,6 @@ } @Override - public boolean alwaysDistinct(Stamp otherStamp) { - FloatStamp other = (FloatStamp) otherStamp; - return (nonNaN || other.nonNaN) && (lowerBound > other.upperBound || upperBound < other.lowerBound); - } - - @Override public Stamp meet(Stamp otherStamp) { if (otherStamp == this) { return this; @@ -183,4 +177,16 @@ return true; } + @Override + public Constant asConstant() { + if (nonNaN && lowerBound == upperBound) { + switch (kind()) { + case Float: + return Constant.forFloat((float) lowerBound); + case Double: + return Constant.forDouble(lowerBound); + } + } + return null; + } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/IllegalStamp.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/IllegalStamp.java Fri Oct 11 17:21:14 2013 +0200 @@ -40,11 +40,6 @@ } @Override - public boolean alwaysDistinct(Stamp other) { - return true; - } - - @Override public Stamp meet(Stamp other) { return other; }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/IntegerStamp.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/IntegerStamp.java Fri Oct 11 17:21:14 2013 +0200 @@ -145,21 +145,6 @@ return str.toString(); } - @Override - public boolean alwaysDistinct(Stamp otherStamp) { - IntegerStamp other = (IntegerStamp) otherStamp; - if (lowerBound > other.upperBound || upperBound < other.lowerBound) { - return true; - } else if ((upMask & other.upMask) == 0 && (lowerBound > 0 || upperBound < 0 || other.lowerBound > 0 || other.upperBound < 0)) { - /* - * Zero is the only common value if the masks don't overlap. If one of the two values is - * less than or greater than zero, they are always distinct. - */ - return true; - } - return false; - } - private Stamp createStamp(IntegerStamp other, long newUpperBound, long newLowerBound, long newDownMask, long newUpMask) { assert kind() == other.kind(); if (newLowerBound > newUpperBound || (newDownMask & (~newUpMask)) != 0) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampFactory.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampFactory.java Fri Oct 11 17:21:14 2013 +0200 @@ -168,10 +168,10 @@ } } - public static Stamp forConstant(Constant value, MetaAccessProvider runtime) { + public static Stamp forConstant(Constant value, MetaAccessProvider metaAccess) { assert value.getKind() == Kind.Object; if (value.getKind() == Kind.Object) { - ResolvedJavaType type = value.isNull() ? null : runtime.lookupJavaType(value); + ResolvedJavaType type = value.isNull() ? null : metaAccess.lookupJavaType(value); return new ObjectStamp(type, value.isNonNull(), value.isNonNull(), value.isNull()); } else { throw new GraalInternalError(Kind.Object + " expected, actual kind: %s", value.getKind());
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/GraphUtil.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/GraphUtil.java Fri Oct 11 17:21:14 2013 +0200 @@ -43,7 +43,7 @@ } }; - public static void killCFG(FixedNode node) { + public static void killCFG(Node node) { assert node.isAlive(); if (node instanceof AbstractEndNode) { // We reached a control flow end. @@ -58,7 +58,7 @@ * while processing one branch. */ for (Node successor : node.successors()) { - killCFG((FixedNode) successor); + killCFG(successor); } } propagateKill(node);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/CommitAllocationNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/CommitAllocationNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -26,6 +26,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -66,7 +67,7 @@ @Override public void lower(LoweringTool tool) { - tool.getRuntime().lower(this, tool); + tool.getLowerer().lower(this, tool); } @Override
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/EscapeObjectState.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/EscapeObjectState.java Fri Oct 11 17:21:14 2013 +0200 @@ -22,10 +22,9 @@ */ package com.oracle.graal.nodes.virtual; -import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; -public abstract class EscapeObjectState extends VirtualState implements IterableNodeType { +public abstract class EscapeObjectState extends VirtualState { @Input private VirtualObjectNode object;
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CanonicalizerPhase.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CanonicalizerPhase.java Fri Oct 11 17:21:14 2013 +0200 @@ -29,9 +29,9 @@ import com.oracle.graal.debug.*; import com.oracle.graal.graph.*; import com.oracle.graal.graph.Graph.NodeChangedListener; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; -import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.util.*; import com.oracle.graal.phases.*; import com.oracle.graal.phases.PhasePlan.PhasePosition; @@ -53,7 +53,7 @@ public interface CustomCanonicalizer { - ValueNode canonicalize(ValueNode node); + Node canonicalize(Node node); } public CanonicalizerPhase(boolean canonicalizeReads) { @@ -67,7 +67,7 @@ @Override protected void run(StructuredGraph graph, PhaseContext context) { - new Instance(context.getRuntime(), context.getAssumptions(), canonicalizeReads, customCanonicalizer).run(graph); + new Instance(context, canonicalizeReads, customCanonicalizer).run(graph); } /** @@ -79,7 +79,7 @@ } public void applyIncremental(StructuredGraph graph, PhaseContext context, int newNodesMark, boolean dumpGraph) { - new Instance(context.getRuntime(), context.getAssumptions(), canonicalizeReads, newNodesMark, customCanonicalizer).apply(graph, dumpGraph); + new Instance(context, canonicalizeReads, newNodesMark, customCanonicalizer).apply(graph, dumpGraph); } /** @@ -91,7 +91,7 @@ } public void applyIncremental(StructuredGraph graph, PhaseContext context, Iterable<Node> workingSet, boolean dumpGraph) { - new Instance(context.getRuntime(), context.getAssumptions(), canonicalizeReads, workingSet, customCanonicalizer).apply(graph, dumpGraph); + new Instance(context, canonicalizeReads, workingSet, customCanonicalizer).apply(graph, dumpGraph); } public void applyIncremental(StructuredGraph graph, PhaseContext context, Iterable<Node> workingSet, int newNodesMark) { @@ -99,19 +99,18 @@ } public void applyIncremental(StructuredGraph graph, PhaseContext context, Iterable<Node> workingSet, int newNodesMark, boolean dumpGraph) { - new Instance(context.getRuntime(), context.getAssumptions(), canonicalizeReads, workingSet, newNodesMark, customCanonicalizer).apply(graph, dumpGraph); + new Instance(context, canonicalizeReads, workingSet, newNodesMark, customCanonicalizer).apply(graph, dumpGraph); } @Deprecated public void addToPhasePlan(PhasePlan plan, PhaseContext context) { - plan.addPhase(PhasePosition.AFTER_PARSING, new Instance(context.getRuntime(), context.getAssumptions(), canonicalizeReads, customCanonicalizer)); + plan.addPhase(PhasePosition.AFTER_PARSING, new Instance(context, canonicalizeReads, customCanonicalizer)); } private static final class Instance extends Phase { private final int newNodesMark; - private final Assumptions assumptions; - private final MetaAccessProvider runtime; + private final PhaseContext context; private final CustomCanonicalizer customCanonicalizer; private final Iterable<Node> initWorkingSet; private final boolean canonicalizeReads; @@ -119,23 +118,22 @@ private NodeWorkList workList; private Tool tool; - private Instance(MetaAccessProvider runtime, Assumptions assumptions, boolean canonicalizeReads, CustomCanonicalizer customCanonicalizer) { - this(runtime, assumptions, canonicalizeReads, null, 0, customCanonicalizer); + private Instance(PhaseContext context, boolean canonicalizeReads, CustomCanonicalizer customCanonicalizer) { + this(context, canonicalizeReads, null, 0, customCanonicalizer); } - private Instance(MetaAccessProvider runtime, Assumptions assumptions, boolean canonicalizeReads, Iterable<Node> workingSet, CustomCanonicalizer customCanonicalizer) { - this(runtime, assumptions, canonicalizeReads, workingSet, 0, customCanonicalizer); + private Instance(PhaseContext context, boolean canonicalizeReads, Iterable<Node> workingSet, CustomCanonicalizer customCanonicalizer) { + this(context, canonicalizeReads, workingSet, 0, customCanonicalizer); } - private Instance(MetaAccessProvider runtime, Assumptions assumptions, boolean canonicalizeReads, int newNodesMark, CustomCanonicalizer customCanonicalizer) { - this(runtime, assumptions, canonicalizeReads, null, newNodesMark, customCanonicalizer); + private Instance(PhaseContext context, boolean canonicalizeReads, int newNodesMark, CustomCanonicalizer customCanonicalizer) { + this(context, canonicalizeReads, null, newNodesMark, customCanonicalizer); } - private Instance(MetaAccessProvider runtime, Assumptions assumptions, boolean canonicalizeReads, Iterable<Node> workingSet, int newNodesMark, CustomCanonicalizer customCanonicalizer) { + private Instance(PhaseContext context, boolean canonicalizeReads, Iterable<Node> workingSet, int newNodesMark, CustomCanonicalizer customCanonicalizer) { super("Canonicalizer"); this.newNodesMark = newNodesMark; - this.assumptions = assumptions; - this.runtime = runtime; + this.context = context; this.canonicalizeReads = canonicalizeReads; this.customCanonicalizer = customCanonicalizer; this.initWorkingSet = workingSet; @@ -179,22 +177,23 @@ if (node.isAlive()) { METRIC_PROCESSED_NODES.increment(); - if (tryGlobalValueNumbering(node)) { + NodeClass nodeClass = node.getNodeClass(); + if (tryGlobalValueNumbering(node, nodeClass)) { return; } StructuredGraph graph = (StructuredGraph) node.graph(); int mark = graph.getMark(); if (!tryKillUnused(node)) { - if (!tryCanonicalize(node)) { + if (!tryCanonicalize(node, nodeClass)) { if (node instanceof ValueNode) { ValueNode valueNode = (ValueNode) node; boolean improvedStamp = tryInferStamp(valueNode); Constant constant = valueNode.stamp().asConstant(); if (constant != null && !(node instanceof ConstantNode)) { - performReplacement(valueNode, ConstantNode.forConstant(constant, runtime, valueNode.graph())); + performReplacement(valueNode, ConstantNode.forConstant(constant, context.getMetaAccess(), valueNode.graph())); } else if (improvedStamp) { // the improved stamp may enable additional canonicalization - tryCanonicalize(valueNode); + tryCanonicalize(valueNode, nodeClass); } } } @@ -214,8 +213,7 @@ return false; } - public static boolean tryGlobalValueNumbering(Node node) { - NodeClass nodeClass = node.getNodeClass(); + public static boolean tryGlobalValueNumbering(Node node, NodeClass nodeClass) { if (nodeClass.valueNumberable() && !nodeClass.isLeafNode()) { Node newNode = node.graph().findDuplicate(node); if (newNode != null) { @@ -230,34 +228,33 @@ return false; } - public boolean tryCanonicalize(final Node node) { - boolean result = baseTryCanonicalize(node); - if (!result && customCanonicalizer != null && node instanceof ValueNode) { - ValueNode valueNode = (ValueNode) node; - ValueNode canonical = customCanonicalizer.canonicalize(valueNode); + public boolean tryCanonicalize(final Node node, NodeClass nodeClass) { + boolean result = baseTryCanonicalize(node, nodeClass); + if (!result && customCanonicalizer != null) { + Node canonical = customCanonicalizer.canonicalize(node); result = performReplacement(node, canonical); } return result; } - public boolean baseTryCanonicalize(final Node node) { - if (node instanceof Canonicalizable) { - assert !(node instanceof Simplifiable); + public boolean baseTryCanonicalize(final Node node, NodeClass nodeClass) { + if (nodeClass.isCanonicalizable()) { + assert !nodeClass.isSimplifiable(); METRIC_CANONICALIZATION_CONSIDERED_NODES.increment(); return Debug.scope("CanonicalizeNode", node, new Callable<Boolean>() { public Boolean call() { - ValueNode canonical = ((Canonicalizable) node).canonical(tool); + Node canonical = node.canonical(tool); return performReplacement(node, canonical); } }); - } else if (node instanceof Simplifiable) { + } else if (nodeClass.isSimplifiable()) { Debug.log("Canonicalizer: simplifying %s", node); METRIC_SIMPLIFICATION_CONSIDERED_NODES.increment(); Debug.scope("SimplifyNode", node, new Runnable() { public void run() { - ((Simplifiable) node).simplify(tool); + node.simplify(tool); } }); } @@ -280,7 +277,7 @@ // -------------------------------------------- // X: must not happen (checked with assertions) // @formatter:on - private boolean performReplacement(final Node node, ValueNode canonical) { + private boolean performReplacement(final Node node, Node canonical) { if (canonical == node) { Debug.log("Canonicalizer: work on %s", node); return false; @@ -362,7 +359,7 @@ private final class Tool implements SimplifierTool { @Override - public void deleteBranch(FixedNode branch) { + public void deleteBranch(Node branch) { branch.predecessor().replaceFirstSuccessor(branch, null); GraphUtil.killCFG(branch); } @@ -373,12 +370,17 @@ */ @Override public Assumptions assumptions() { - return assumptions; + return context.getAssumptions(); } @Override - public MetaAccessProvider runtime() { - return runtime; + public MetaAccessProvider getMetaAccess() { + return context.getMetaAccess(); + } + + @Override + public ConstantReflectionProvider getConstantReflection() { + return context.getConstantReflection(); } @Override
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java Fri Oct 11 17:21:14 2013 +0200 @@ -52,12 +52,12 @@ private static final DebugMetric metricObjectEqualsRemoved = Debug.metric("ObjectEqualsRemoved"); private static final DebugMetric metricGuardsRemoved = Debug.metric("GuardsRemoved"); - private final MetaAccessProvider metaAccessProvider; + private final MetaAccessProvider metaAccess; private StructuredGraph graph; - public ConditionalEliminationPhase(MetaAccessProvider metaAccessProvider) { - this.metaAccessProvider = metaAccessProvider; + public ConditionalEliminationPhase(MetaAccessProvider metaAccess) { + this.metaAccess = metaAccess; } @Override @@ -510,8 +510,8 @@ } PiNode piNode; if (isNull) { - ConstantNode nullObject = ConstantNode.forObject(null, metaAccessProvider, graph); - piNode = graph.unique(new PiNode(nullObject, StampFactory.forConstant(nullObject.value, metaAccessProvider), replacementAnchor.asNode())); + ConstantNode nullObject = ConstantNode.forObject(null, metaAccess, graph); + piNode = graph.unique(new PiNode(nullObject, StampFactory.forConstant(nullObject.value, metaAccess), replacementAnchor.asNode())); } else { piNode = graph.unique(new PiNode(object, StampFactory.declared(type, nonNull), replacementAnchor.asNode())); } @@ -523,6 +523,23 @@ } metricCheckCastRemoved.increment(); } + } else if (node instanceof ConditionAnchorNode) { + ConditionAnchorNode conditionAnchorNode = (ConditionAnchorNode) node; + LogicNode condition = conditionAnchorNode.condition(); + ValueNode replacementAnchor = null; + if (conditionAnchorNode.isNegated()) { + if (state.falseConditions.containsKey(condition)) { + replacementAnchor = state.falseConditions.get(condition); + } + } else { + if (state.trueConditions.containsKey(condition)) { + replacementAnchor = state.trueConditions.get(condition); + } + } + if (replacementAnchor != null) { + conditionAnchorNode.replaceAtUsages(replacementAnchor); + conditionAnchorNode.graph().removeFixed(conditionAnchorNode); + } } else if (node instanceof IfNode) { IfNode ifNode = (IfNode) node; LogicNode compare = ifNode.condition();
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/DeoptimizationGroupingPhase.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/DeoptimizationGroupingPhase.java Fri Oct 11 17:21:14 2013 +0200 @@ -24,23 +24,26 @@ import java.util.*; +import com.oracle.graal.api.meta.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.cfg.*; import com.oracle.graal.phases.*; +import com.oracle.graal.phases.tiers.*; /** - * This phase tries to find {@link DeoptimizeNode DeoptimizeNodes} which use the same + * This phase tries to find {@link AbstractDeoptimizeNode DeoptimizeNodes} which use the same * {@link FrameState} and merges them together. */ -public class DeoptimizationGroupingPhase extends Phase { +public class DeoptimizationGroupingPhase extends BasePhase<MidTierContext> { @Override - protected void run(StructuredGraph graph) { + protected void run(StructuredGraph graph, MidTierContext context) { ControlFlowGraph cfg = null; for (FrameState fs : graph.getNodes(FrameState.class)) { FixedNode target = null; - List<DeoptimizeNode> obsoletes = null; - for (DeoptimizeNode deopt : fs.usages().filter(DeoptimizeNode.class)) { + PhiNode phi = null; + List<AbstractDeoptimizeNode> obsoletes = null; + for (AbstractDeoptimizeNode deopt : fs.usages().filter(AbstractDeoptimizeNode.class)) { if (target == null) { target = deopt; } else { @@ -48,34 +51,41 @@ cfg = ControlFlowGraph.compute(graph, true, true, false, false); } MergeNode merge; - if (target instanceof DeoptimizeNode) { + if (target instanceof AbstractDeoptimizeNode) { merge = graph.add(new MergeNode()); EndNode firstEnd = graph.add(new EndNode()); + phi = graph.addWithoutUnique(new PhiNode(Kind.Int, merge)); merge.addForwardEnd(firstEnd); + phi.addInput(((AbstractDeoptimizeNode) target).getActionAndReason(context.getMetaAccess())); target.predecessor().replaceFirstSuccessor(target, firstEnd); - exitLoops((DeoptimizeNode) target, firstEnd, cfg); - merge.setNext(target); + + exitLoops((AbstractDeoptimizeNode) target, firstEnd, cfg); + + merge.setNext(graph.add(new DynamicDeoptimizeNode(phi))); obsoletes = new LinkedList<>(); + obsoletes.add((AbstractDeoptimizeNode) target); target = merge; } else { merge = (MergeNode) target; } EndNode newEnd = graph.add(new EndNode()); merge.addForwardEnd(newEnd); + phi.addInput(deopt.getActionAndReason(context.getMetaAccess())); deopt.predecessor().replaceFirstSuccessor(deopt, newEnd); exitLoops(deopt, newEnd, cfg); obsoletes.add(deopt); } } if (obsoletes != null) { - for (DeoptimizeNode obsolete : obsoletes) { + ((DynamicDeoptimizeNode) ((MergeNode) target).next()).setDeoptimizationState(fs); + for (AbstractDeoptimizeNode obsolete : obsoletes) { obsolete.safeDelete(); } } } } - private static void exitLoops(DeoptimizeNode deopt, EndNode end, ControlFlowGraph cfg) { + private static void exitLoops(AbstractDeoptimizeNode deopt, EndNode end, ControlFlowGraph cfg) { Block block = cfg.blockFor(deopt); Loop loop = block.getLoop(); while (loop != null) {
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/EliminatePartiallyRedundantGuardsPhase.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/EliminatePartiallyRedundantGuardsPhase.java Fri Oct 11 17:21:14 2013 +0200 @@ -25,7 +25,6 @@ import java.util.*; import java.util.Map.*; -import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.debug.*; import com.oracle.graal.graph.*;
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/FloatingReadPhase.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/FloatingReadPhase.java Fri Oct 11 17:21:14 2013 +0200 @@ -27,7 +27,6 @@ import java.util.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.PhiNode.PhiType; import com.oracle.graal.nodes.extended.*; @@ -42,7 +41,7 @@ ANALYSIS_ONLY, CREATE_FLOATING_READS } - public static class MemoryMapImpl implements MemoryMap<Node> { + public static class MemoryMapImpl extends MemoryMapNode { private IdentityHashMap<LocationIdentity, ValueNode> lastMemorySnapshot; @@ -74,11 +73,6 @@ } } - @Override - public String toString() { - return "Map=" + lastMemorySnapshot.toString(); - } - public boolean isEmpty() { if (lastMemorySnapshot.size() == 0) { return true; @@ -92,7 +86,7 @@ } public Set<LocationIdentity> getLocations() { - return new HashSet<>(lastMemorySnapshot.keySet()); + return lastMemorySnapshot.keySet(); } } @@ -192,7 +186,7 @@ assert MemoryCheckpoint.TypeAssertion.correctType(node) : node; if (execmode == ExecutionMode.ANALYSIS_ONLY && node instanceof ReturnNode) { - node.graph().add(new MemoryState(new MemoryMapImpl(state), node)); + ((ReturnNode) node).setMemoryMap(node.graph().unique(new MemoryMapImpl(state))); } return state; }
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/IncrementalCanonicalizerPhase.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/IncrementalCanonicalizerPhase.java Fri Oct 11 17:21:14 2013 +0200 @@ -30,6 +30,10 @@ import com.oracle.graal.phases.*; import com.oracle.graal.phases.tiers.*; +/** + * A phase suite that applies {@linkplain CanonicalizerPhase canonicalization} to a graph after all + * phases in the suite have been applied if any of the phases changed the graph. + */ public class IncrementalCanonicalizerPhase<C extends PhaseContext> extends PhaseSuite<C> { private final CanonicalizerPhase canonicalizer; @@ -58,6 +62,8 @@ graph.stopTrackingInputChange(); graph.stopTrackingUsagesDroppedZero(); - canonicalizer.applyIncremental(graph, context, changedNodes, newNodesMark, false); + if (graph.getMark() != newNodesMark || !changedNodes.isEmpty()) { + canonicalizer.applyIncremental(graph, context, changedNodes, newNodesMark, false); + } } }
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningPhase.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningPhase.java Fri Oct 11 17:21:14 2013 +0200 @@ -173,7 +173,7 @@ if (inliningPolicy.isWorthInlining(context.getReplacements(), callee, inliningDepth, calleeInfo.probability(), calleeInfo.relevance(), true)) { doInline(callerGraphInfo, calleeInfo, callerAssumptions, context); } else if (context.getOptimisticOptimizations().devirtualizeInvokes()) { - callee.tryToDevirtualizeInvoke(context.getRuntime(), callerAssumptions); + callee.tryToDevirtualizeInvoke(context.getMetaAccess(), callerAssumptions); } metricInliningConsidered.increment(); } @@ -184,7 +184,7 @@ InlineInfo callee = calleeInfo.callee(); try { List<Node> invokeUsages = callee.invoke().asNode().usages().snapshot(); - callee.inline(context.getRuntime(), callerAssumptions, context.getReplacements()); + callee.inline(context, callerAssumptions); callerAssumptions.record(calleeInfo.assumptions()); metricInliningRuns.increment(); Debug.dump(callerGraph, "after %s", callee); @@ -258,7 +258,7 @@ ValueNode arg = args.get(localNode.index()); if (arg.isConstant()) { Constant constant = arg.asConstant(); - newGraph.replaceFloating(localNode, ConstantNode.forConstant(constant, context.getRuntime(), newGraph)); + newGraph.replaceFloating(localNode, ConstantNode.forConstant(constant, context.getMetaAccess(), newGraph)); callerHasMoreInformationAboutArguments = true; } else { Stamp joinedStamp = localNode.stamp().join(arg.stamp());
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java Fri Oct 11 17:21:14 2013 +0200 @@ -22,7 +22,7 @@ */ package com.oracle.graal.phases.common; -import static com.oracle.graal.api.code.DeoptimizationAction.*; +import static com.oracle.graal.api.meta.DeoptimizationAction.*; import static com.oracle.graal.api.meta.DeoptimizationReason.*; import static com.oracle.graal.nodes.type.StampFactory.*; import static com.oracle.graal.phases.GraalOptions.*; @@ -51,6 +51,7 @@ import com.oracle.graal.phases.*; import com.oracle.graal.phases.common.InliningPhase.InliningData; import com.oracle.graal.phases.tiers.*; +import com.oracle.graal.phases.util.*; public class InliningUtil { @@ -292,13 +293,13 @@ * Performs the inlining described by this object and returns the node that represents the * return value of the inlined method (or null for void methods and methods that have no * non-exceptional exit). - **/ - void inline(MetaAccessProvider runtime, Assumptions assumptions, Replacements replacements); + */ + void inline(Providers providers, Assumptions assumptions); /** * Try to make the call static bindable to avoid interface and virtual method calls. */ - void tryToDevirtualizeInvoke(MetaAccessProvider runtime, Assumptions assumptions); + void tryToDevirtualizeInvoke(MetaAccessProvider metaAccess, Assumptions assumptions); } public abstract static class AbstractInlineInfo implements InlineInfo { @@ -367,12 +368,12 @@ } @Override - public void inline(MetaAccessProvider runtime, Assumptions assumptions, Replacements replacements) { + public void inline(Providers providers, Assumptions assumptions) { inline(invoke, concrete, inlineableElement, assumptions, !suppressNullCheck); } @Override - public void tryToDevirtualizeInvoke(MetaAccessProvider runtime, Assumptions assumptions) { + public void tryToDevirtualizeInvoke(MetaAccessProvider metaAccess, Assumptions assumptions) { // nothing todo, can already be bound statically } @@ -470,20 +471,20 @@ } @Override - public void inline(MetaAccessProvider runtime, Assumptions assumptions, Replacements replacements) { - createGuard(graph(), runtime); + public void inline(Providers providers, Assumptions assumptions) { + createGuard(graph(), providers.getMetaAccess()); inline(invoke, concrete, inlineableElement, assumptions, false); } @Override - public void tryToDevirtualizeInvoke(MetaAccessProvider runtime, Assumptions assumptions) { - createGuard(graph(), runtime); + public void tryToDevirtualizeInvoke(MetaAccessProvider metaAccess, Assumptions assumptions) { + createGuard(graph(), metaAccess); replaceInvokeCallTarget(invoke, graph(), InvokeKind.Special, concrete); } - private void createGuard(StructuredGraph graph, MetaAccessProvider runtime) { + private void createGuard(StructuredGraph graph, MetaAccessProvider metaAccess) { ValueNode nonNullReceiver = InliningUtil.nonNullReceiver(invoke); - ConstantNode typeHub = ConstantNode.forConstant(type.getEncoding(Representation.ObjectHub), runtime, graph); + ConstantNode typeHub = ConstantNode.forConstant(type.getEncoding(Representation.ObjectHub), metaAccess, graph); LoadHubNode receiverHub = graph.unique(new LoadHubNode(nonNullReceiver, typeHub.kind(), null)); CompareNode typeCheck = CompareNode.createCompareNode(Condition.EQ, receiverHub, typeHub); @@ -587,11 +588,11 @@ } @Override - public void inline(MetaAccessProvider runtime, Assumptions assumptions, Replacements replacements) { + public void inline(Providers providers, Assumptions assumptions) { if (hasSingleMethod()) { - inlineSingleMethod(graph(), runtime, assumptions); + inlineSingleMethod(graph(), providers.getMetaAccess(), assumptions); } else { - inlineMultipleMethods(graph(), runtime, assumptions, replacements); + inlineMultipleMethods(graph(), providers, assumptions); } } @@ -603,7 +604,7 @@ return notRecordedTypeProbability > 0; } - private void inlineMultipleMethods(StructuredGraph graph, MetaAccessProvider runtime, Assumptions assumptions, Replacements replacements) { + private void inlineMultipleMethods(StructuredGraph graph, Providers providers, Assumptions assumptions) { int numberOfMethods = concretes.size(); FixedNode continuation = invoke.next(); @@ -658,7 +659,7 @@ assert invoke.asNode().isAlive(); // replace the invoke with a switch on the type of the actual receiver - boolean methodDispatch = createDispatchOnTypeBeforeInvoke(graph, successors, false, runtime); + boolean methodDispatch = createDispatchOnTypeBeforeInvoke(graph, successors, false, providers.getMetaAccess()); assert invoke.next() == continuation; invoke.setNext(null); @@ -713,8 +714,9 @@ if (opportunities > 0) { metricInliningTailDuplication.increment(); Debug.log("MultiTypeGuardInlineInfo starting tail duplication (%d opportunities)", opportunities); - TailDuplicationPhase.tailDuplicate(returnMerge, TailDuplicationPhase.TRUE_DECISION, replacementNodes, new PhaseContext(runtime, assumptions, replacements), new CanonicalizerPhase( - !AOTCompilation.getValue())); + PhaseContext phaseContext = new PhaseContext(providers, assumptions); + CanonicalizerPhase canonicalizer = new CanonicalizerPhase(!AOTCompilation.getValue()); + TailDuplicationPhase.tailDuplicate(returnMerge, TailDuplicationPhase.TRUE_DECISION, replacementNodes, phaseContext, canonicalizer); } } } @@ -752,21 +754,21 @@ return result; } - private void inlineSingleMethod(StructuredGraph graph, MetaAccessProvider runtime, Assumptions assumptions) { + private void inlineSingleMethod(StructuredGraph graph, MetaAccessProvider metaAccess, Assumptions assumptions) { assert concretes.size() == 1 && inlineableElements.length == 1 && ptypes.size() > 1 && !shouldFallbackToInvoke() && notRecordedTypeProbability == 0; AbstractBeginNode calleeEntryNode = graph.add(new BeginNode()); AbstractBeginNode unknownTypeSux = createUnknownTypeSuccessor(graph); AbstractBeginNode[] successors = new AbstractBeginNode[]{calleeEntryNode, unknownTypeSux}; - createDispatchOnTypeBeforeInvoke(graph, successors, false, runtime); + createDispatchOnTypeBeforeInvoke(graph, successors, false, metaAccess); calleeEntryNode.setNext(invoke.asNode()); inline(invoke, methodAt(0), inlineableElementAt(0), assumptions, false); } - private boolean createDispatchOnTypeBeforeInvoke(StructuredGraph graph, AbstractBeginNode[] successors, boolean invokeIsOnlySuccessor, MetaAccessProvider runtime) { + private boolean createDispatchOnTypeBeforeInvoke(StructuredGraph graph, AbstractBeginNode[] successors, boolean invokeIsOnlySuccessor, MetaAccessProvider metaAccess) { assert ptypes.size() >= 1; ValueNode nonNullReceiver = nonNullReceiver(invoke); Kind hubKind = ((MethodCallTargetNode) invoke.callTarget()).targetMethod().getDeclaringClass().getEncoding(Representation.ObjectHub).getKind(); @@ -783,7 +785,7 @@ ResolvedJavaMethod firstMethod = concretes.get(i); Constant firstMethodConstant = firstMethod.getEncoding(); - ValueNode firstMethodConstantNode = ConstantNode.forConstant(firstMethodConstant, runtime, graph); + ValueNode firstMethodConstantNode = ConstantNode.forConstant(firstMethodConstant, metaAccess, graph); constantMethods[i] = firstMethodConstantNode; double concretesProbability = concretesProbabilities.get(i); assert concretesProbability >= 0.0; @@ -928,15 +930,15 @@ } @Override - public void tryToDevirtualizeInvoke(MetaAccessProvider runtime, Assumptions assumptions) { + public void tryToDevirtualizeInvoke(MetaAccessProvider metaAccess, Assumptions assumptions) { if (hasSingleMethod()) { - devirtualizeWithTypeSwitch(graph(), InvokeKind.Special, concretes.get(0), runtime); + devirtualizeWithTypeSwitch(graph(), InvokeKind.Special, concretes.get(0), metaAccess); } else { - tryToDevirtualizeMultipleMethods(graph(), runtime); + tryToDevirtualizeMultipleMethods(graph(), metaAccess); } } - private void tryToDevirtualizeMultipleMethods(StructuredGraph graph, MetaAccessProvider runtime) { + private void tryToDevirtualizeMultipleMethods(StructuredGraph graph, MetaAccessProvider metaAccess) { MethodCallTargetNode methodCallTarget = (MethodCallTargetNode) invoke.callTarget(); if (methodCallTarget.invokeKind() == InvokeKind.Interface) { ResolvedJavaMethod targetMethod = methodCallTarget.targetMethod(); @@ -947,17 +949,17 @@ if (!leastCommonType.isInterface() && targetMethod.getDeclaringClass().isAssignableFrom(leastCommonType)) { ResolvedJavaMethod baseClassTargetMethod = leastCommonType.resolveMethod(targetMethod); if (baseClassTargetMethod != null) { - devirtualizeWithTypeSwitch(graph, InvokeKind.Virtual, leastCommonType.resolveMethod(targetMethod), runtime); + devirtualizeWithTypeSwitch(graph, InvokeKind.Virtual, leastCommonType.resolveMethod(targetMethod), metaAccess); } } } } - private void devirtualizeWithTypeSwitch(StructuredGraph graph, InvokeKind kind, ResolvedJavaMethod target, MetaAccessProvider runtime) { + private void devirtualizeWithTypeSwitch(StructuredGraph graph, InvokeKind kind, ResolvedJavaMethod target, MetaAccessProvider metaAccess) { AbstractBeginNode invocationEntry = graph.add(new BeginNode()); AbstractBeginNode unknownTypeSux = createUnknownTypeSuccessor(graph); AbstractBeginNode[] successors = new AbstractBeginNode[]{invocationEntry, unknownTypeSux}; - createDispatchOnTypeBeforeInvoke(graph, successors, true, runtime); + createDispatchOnTypeBeforeInvoke(graph, successors, true, metaAccess); invocationEntry.setNext(invoke.asNode()); ValueNode receiver = ((MethodCallTargetNode) invoke.callTarget()).receiver(); @@ -1006,13 +1008,13 @@ } @Override - public void inline(MetaAccessProvider runtime, Assumptions assumptions, Replacements replacements) { + public void inline(Providers providers, Assumptions assumptions) { assumptions.record(takenAssumption); - super.inline(runtime, assumptions, replacements); + super.inline(providers, assumptions); } @Override - public void tryToDevirtualizeInvoke(MetaAccessProvider runtime, Assumptions assumptions) { + public void tryToDevirtualizeInvoke(MetaAccessProvider metaAccess, Assumptions assumptions) { assumptions.record(takenAssumption); replaceInvokeCallTarget(invoke, graph(), InvokeKind.Special, concrete); } @@ -1363,6 +1365,13 @@ } else { invokeWithException.killExceptionEdge(); } + + // get rid of memory kill + AbstractBeginNode begin = invokeWithException.next(); + if (begin instanceof KillingBeginNode) { + graph.addAfterFixed(begin, graph.add(new BeginNode())); + graph.removeFixed(begin); + } } else { if (unwindNode != null) { UnwindNode unwindDuplicate = (UnwindNode) duplicates.get(unwindNode);
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/IterativeConditionalEliminationPhase.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/IterativeConditionalEliminationPhase.java Fri Oct 11 17:21:14 2013 +0200 @@ -24,8 +24,8 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.spi.*; import com.oracle.graal.phases.*; import com.oracle.graal.phases.common.util.*; import com.oracle.graal.phases.tiers.*; @@ -42,7 +42,7 @@ @Override protected void run(StructuredGraph graph, PhaseContext context) { - ConditionalEliminationPhase eliminate = new ConditionalEliminationPhase(context.getRuntime()); + ConditionalEliminationPhase eliminate = new ConditionalEliminationPhase(context.getMetaAccess()); HashSetNodeChangeListener listener = new HashSetNodeChangeListener(); int count = 0; while (true) {
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoweringPhase.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoweringPhase.java Fri Oct 11 17:21:14 2013 +0200 @@ -63,8 +63,23 @@ } @Override - public GraalCodeCacheProvider getRuntime() { - return (GraalCodeCacheProvider) context.getRuntime(); + public CodeCacheProvider getCodeCache() { + return context.getCodeCache(); + } + + @Override + public ConstantReflectionProvider getConstantReflection() { + return context.getConstantReflection(); + } + + @Override + public MetaAccessProvider getMetaAccess() { + return context.getMetaAccess(); + } + + @Override + public LoweringProvider getLowerer() { + return context.getLowerer(); } @Override
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/PhiStampPhase.java Fri Oct 11 17:14:35 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,63 +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.phases.common; - -import com.oracle.graal.nodes.*; -import com.oracle.graal.phases.*; - -public class PhiStampPhase extends Phase { - - @Override - protected void run(StructuredGraph graph) { - // Infer phis stopping at loop phis. - for (PhiNode phi : graph.getNodes(PhiNode.class)) { - inferPhi(phi); - } - - // Start iterative inference for loop phis. - if (graph.hasLoops()) { - for (PhiNode phi : graph.getNodes(PhiNode.class)) { - if (phi.isLoopPhi()) { - iterativeInferPhi(phi); - } - } - } - } - - private void iterativeInferPhi(PhiNode phi) { - if (phi.inferPhiStamp()) { - for (PhiNode phiUsage : phi.usages().filter(PhiNode.class)) { - iterativeInferPhi(phiUsage); - } - } - } - - private void inferPhi(PhiNode phi) { - for (PhiNode phiInput : phi.values().filter(PhiNode.class)) { - if (!phiInput.isLoopPhi()) { - inferPhi(phiInput); - } - } - phi.inferPhiStamp(); - } -}
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/TailDuplicationPhase.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/TailDuplicationPhase.java Fri Oct 11 17:21:14 2013 +0200 @@ -36,6 +36,7 @@ import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; import com.oracle.graal.nodes.util.*; +import com.oracle.graal.nodes.virtual.*; import com.oracle.graal.phases.*; import com.oracle.graal.phases.graph.*; import com.oracle.graal.phases.tiers.*; @@ -172,6 +173,9 @@ int fixedCount = 0; while (fixed instanceof FixedWithNextNode) { fixed = ((FixedWithNextNode) fixed).next(); + if (fixed instanceof CommitAllocationNode) { + return false; + } fixedCount++; } if (fixedCount > 1) {
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java Fri Oct 11 17:21:14 2013 +0200 @@ -70,8 +70,6 @@ @Option(help = "") public static final OptionValue<Boolean> PartialEscapeAnalysis = new OptionValue<>(true); @Option(help = "") - public static final OptionValue<Boolean> EscapeAnalysisHistogram = new OptionValue<>(false); - @Option(help = "") public static final OptionValue<Integer> EscapeAnalysisIterations = new OptionValue<>(2); @Option(help = "") public static final OptionValue<String> EscapeAnalyzeOnly = new OptionValue<>(null); @@ -167,6 +165,8 @@ @Option(help = "") public static final OptionValue<Boolean> PrintCompilation = new OptionValue<>(false); @Option(help = "") + public static final OptionValue<Boolean> PrintAfterCompilation = new OptionValue<>(false); + @Option(help = "") public static final OptionValue<Boolean> PrintProfilingInformation = new OptionValue<>(false); @Option(help = "") public static final OptionValue<Boolean> PrintIRWithLIR = new OptionValue<>(false);
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/PhaseSuite.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/PhaseSuite.java Fri Oct 11 17:21:14 2013 +0200 @@ -26,6 +26,9 @@ import com.oracle.graal.nodes.*; +/** + * A compiler phase that can apply an ordered collection of phases to a graph. + */ public class PhaseSuite<C> extends BasePhase<C> { private final List<BasePhase<? super C>> phases;
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/ComputeProbabilityClosure.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/ComputeProbabilityClosure.java Fri Oct 11 17:21:14 2013 +0200 @@ -77,8 +77,8 @@ private void adjustControlSplitProbabilities() { HashSet<ControlSplitNode> result = new HashSet<>(); NodeBitMap visitedNodes = new NodeBitMap(graph); - for (DeoptimizeNode n : graph.getNodes(DeoptimizeNode.class)) { - if (n.action().doesInvalidateCompilation()) { + for (AbstractDeoptimizeNode n : graph.getNodes(AbstractDeoptimizeNode.class)) { + if (!(n instanceof DeoptimizeNode) || ((DeoptimizeNode) n).action().doesInvalidateCompilation()) { findParentControlSplitNodes(result, n, visitedNodes); } } @@ -90,7 +90,7 @@ } } - private static void findParentControlSplitNodes(HashSet<ControlSplitNode> result, DeoptimizeNode n, NodeBitMap visitedNodes) { + private static void findParentControlSplitNodes(HashSet<ControlSplitNode> result, AbstractDeoptimizeNode n, NodeBitMap visitedNodes) { ArrayDeque<FixedNode> nodes = new ArrayDeque<>(); nodes.push(n); @@ -142,9 +142,9 @@ private boolean verifyProbabilities() { if (doesNotAlwaysDeopt(graph)) { - for (DeoptimizeNode n : graph.getNodes(DeoptimizeNode.class)) { - if (n.action().doesInvalidateCompilation() && nodeProbabilities.get(n) > 0.01) { - throw new AssertionError(String.format("%s with reason %s and probability %f in graph %s", n, n.reason(), nodeProbabilities.get(n), graph)); + for (AbstractDeoptimizeNode n : graph.getNodes(AbstractDeoptimizeNode.class)) { + if (nodeProbabilities.get(n) > 0.01 && (!(n instanceof DeoptimizeNode) || ((DeoptimizeNode) n).action().doesInvalidateCompilation())) { + throw new AssertionError(String.format("%s with probability %f in graph %s", n, nodeProbabilities.get(n), graph)); } } }
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java Fri Oct 11 17:21:14 2013 +0200 @@ -33,6 +33,7 @@ import com.oracle.graal.graph.*; import com.oracle.graal.graph.Node.Verbosity; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.PhiNode.PhiType; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.cfg.*; import com.oracle.graal.nodes.extended.*; @@ -99,7 +100,7 @@ @Override protected HashSet<FloatingReadNode> processBlock(Block block, HashSet<FloatingReadNode> currentState) { - for (Node node : getBlockToNodesMap().get(block)) { + for (Node node : blockToNodesMap.get(block)) { if (node instanceof FloatingReadNode) { currentState.add((FloatingReadNode) node); } else if (node instanceof MemoryCheckpoint.Single) { @@ -183,37 +184,49 @@ @Override protected Map<LocationIdentity, Node> processBlock(Block block, Map<LocationIdentity, Node> currentState) { - Map<LocationIdentity, Node> initKillMap = getBlockToKillMap().get(block); - initKillMap.putAll(currentState); + + if (block.getBeginNode() instanceof MergeNode) { + MergeNode mergeNode = (MergeNode) block.getBeginNode(); + for (PhiNode phi : mergeNode.usages().filter(PhiNode.class)) { + if (phi.type() == PhiType.Memory) { + LocationIdentity identity = (LocationIdentity) phi.getIdentity(); + locationKilledBy(identity, phi, currentState); + } + } + } + currentState.putAll(blockToKillMapInit.get(block)); for (Node node : block.getNodes()) { if (node instanceof MemoryCheckpoint.Single) { LocationIdentity identity = ((MemoryCheckpoint.Single) node).getLocationIdentity(); - initKillMap.put(identity, node); + locationKilledBy(identity, node, currentState); } else if (node instanceof MemoryCheckpoint.Multi) { for (LocationIdentity identity : ((MemoryCheckpoint.Multi) node).getLocationIdentities()) { - initKillMap.put(identity, node); + locationKilledBy(identity, node, currentState); } } assert MemoryCheckpoint.TypeAssertion.correctType(node); } - return cloneState(initKillMap); + blockToKillMap.put(block, currentState); + return cloneState(currentState); + } + + private void locationKilledBy(LocationIdentity identity, Node checkpoint, Map<LocationIdentity, Node> state) { + state.put(identity, checkpoint); + if (identity == ANY_LOCATION) { + for (LocationIdentity locid : state.keySet()) { + state.put(locid, checkpoint); + } + } } @Override protected Map<LocationIdentity, Node> merge(Block merge, List<Map<LocationIdentity, Node>> states) { - return merge(merge, states, false); - } - - protected Map<LocationIdentity, Node> merge(Block merge, List<Map<LocationIdentity, Node>> states, boolean loopbegin) { assert merge.getBeginNode() instanceof MergeNode; MergeNode mergeNode = (MergeNode) merge.getBeginNode(); Map<LocationIdentity, Node> initKillMap = new HashMap<>(); - if (loopbegin) { - initKillMap.putAll(getBlockToKillMap().get(merge)); - } for (Map<LocationIdentity, Node> state : states) { for (LocationIdentity locid : state.keySet()) { if (initKillMap.containsKey(locid)) { @@ -226,10 +239,7 @@ } } - getMergeToKillMap().set(mergeNode, cloneState(initKillMap)); - if (!loopbegin) { - initKillMap.putAll(getBlockToKillMap().get(merge)); - } + mergeToKillMap.set(mergeNode, cloneState(initKillMap)); return initKillMap; } @@ -240,18 +250,27 @@ @Override protected List<Map<LocationIdentity, Node>> processLoop(Loop loop, Map<LocationIdentity, Node> state) { - LoopInfo<Map<LocationIdentity, Node>> info = ReentrantBlockIterator.processLoop(this, loop, new HashMap<>(state)); + LoopInfo<Map<LocationIdentity, Node>> info = ReentrantBlockIterator.processLoop(this, loop, cloneState(state)); assert loop.header.getBeginNode() instanceof LoopBeginNode; - Map<LocationIdentity, Node> headerState = merge(loop.header, info.endStates, true); - getBlockToKillMap().put(loop.header, headerState); + Map<LocationIdentity, Node> headerState = merge(loop.header, info.endStates); + // second iteration, for computing information at loop exits + info = ReentrantBlockIterator.processLoop(this, loop, cloneState(headerState)); + + int i = 0; + for (Block exit : loop.exits) { + Map<LocationIdentity, Node> exitState = info.exitStates.get(i++); - for (Map<LocationIdentity, Node> exitState : info.exitStates) { - for (LocationIdentity key : headerState.keySet()) { - exitState.put(key, headerState.get(key)); + Node begin = exit.getBeginNode(); + assert begin instanceof LoopExitNode; + for (Node usage : begin.usages()) { + if (usage instanceof ProxyNode && ((ProxyNode) usage).type() == PhiType.Memory) { + ProxyNode proxy = (ProxyNode) usage; + LocationIdentity identity = (LocationIdentity) proxy.getIdentity(); + locationKilledBy(identity, proxy, exitState); + } } } - return info.exitStates; } } @@ -263,6 +282,7 @@ * Map from blocks to the nodes in each block. */ private BlockMap<List<ScheduledNode>> blockToNodesMap; + private BlockMap<Map<LocationIdentity, Node>> blockToKillMapInit; private BlockMap<Map<LocationIdentity, Node>> blockToKillMap; private NodeMap<Map<LocationIdentity, Node>> mergeToKillMap; private final Map<FloatingNode, List<FixedNode>> phantomUsages = new IdentityHashMap<>(); @@ -315,8 +335,10 @@ } else if (memsched == MemoryScheduling.OPTIMAL && selectedStrategy != SchedulingStrategy.EARLIEST && graph.getNodes(FloatingReadNode.class).isNotEmpty()) { mergeToKillMap = graph.createNodeMap(); + blockToKillMapInit = new BlockMap<>(cfg); blockToKillMap = new BlockMap<>(cfg); for (Block b : cfg.getBlocks()) { + blockToKillMapInit.put(b, new HashMap<LocationIdentity, Node>()); blockToKillMap.put(b, new HashMap<LocationIdentity, Node>()); } @@ -328,7 +350,7 @@ Node first = n.lastLocationAccess(); assert first != null; - Map<LocationIdentity, Node> killMap = blockToKillMap.get(forKillLocation(first)); + Map<LocationIdentity, Node> killMap = blockToKillMapInit.get(forKillLocation(first)); killMap.put(n.location().getLocationIdentity(), first); } @@ -357,20 +379,27 @@ private void printSchedule(String desc) { Debug.printf("=== %s / %s / %s (%s) ===\n", getCFG().getStartBlock().getBeginNode().graph(), selectedStrategy, memsched, desc); for (Block b : getCFG().getBlocks()) { - Debug.printf("==== b: %s. ", b); + Debug.printf("==== b: %s (loopDepth: %s). ", b, b.getLoopDepth()); Debug.printf("dom: %s. ", b.getDominator()); Debug.printf("post-dom: %s. ", b.getPostdominator()); Debug.printf("preds: %s. ", b.getPredecessors()); Debug.printf("succs: %s ====\n", b.getSuccessors()); - BlockMap<Map<LocationIdentity, Node>> killMaps = getBlockToKillMap(); + BlockMap<Map<LocationIdentity, Node>> killMaps = blockToKillMap; if (killMaps != null) { + if (b.getBeginNode() instanceof MergeNode) { + MergeNode merge = (MergeNode) b.getBeginNode(); + Debug.printf("M merge kills: \n"); + for (LocationIdentity locId : mergeToKillMap.get(merge).keySet()) { + Debug.printf("M %s killed by %s\n", locId, mergeToKillMap.get(merge).get(locId)); + } + } Debug.printf("X block kills: \n"); for (LocationIdentity locId : killMaps.get(b).keySet()) { Debug.printf("X %s killed by %s\n", locId, killMaps.get(b).get(locId)); } } - if (getBlockToNodesMap().get(b) != null) { + if (blockToNodesMap.get(b) != null) { for (Node n : nodesFor(b)) { printNode(n); } @@ -414,14 +443,6 @@ return blockToNodesMap; } - public BlockMap<Map<LocationIdentity, Node>> getBlockToKillMap() { - return blockToKillMap; - } - - public NodeMap<Map<LocationIdentity, Node>> getMergeToKillMap() { - return mergeToKillMap; - } - /** * Gets the nodes in a given block. */ @@ -465,10 +486,11 @@ throw new SchedulingError("%s should already have been placed in a block", node); } + Block earliestBlock = earliestBlock(node); Block block; switch (strategy) { case EARLIEST: - block = earliestBlock(node); + block = earliestBlock; break; case LATEST: case LATEST_OUT_OF_LOOPS: @@ -477,23 +499,19 @@ } else { block = latestBlock(node, strategy); if (block == null) { - block = earliestBlock(node); + block = earliestBlock; } else if (strategy == SchedulingStrategy.LATEST_OUT_OF_LOOPS && !(node instanceof VirtualObjectNode)) { // schedule at the latest position possible in the outermost loop possible - Block earliestBlock = earliestBlock(node); - Block before = block; block = scheduleOutOfLoops(node, block, earliestBlock); - if (!earliestBlock.dominates(block)) { - throw new SchedulingError("%s: Graph cannot be scheduled : inconsistent for %s, %d usages, (%s needs to dominate %s (before %s))", node.graph(), node, - node.usages().count(), earliestBlock, block, before); - } } } break; default: throw new GraalInternalError("unknown scheduling strategy"); } - assert earliestBlock(node).dominates(block) : "node " + node + " in block " + block + " is not dominated by earliest " + earliestBlock(node); + if (!earliestBlock.dominates(block)) { + throw new SchedulingError("%s: Graph cannot be scheduled : inconsistent for %s, %d usages, (%s needs to dominate %s)", node.graph(), node, node.usages().count(), earliestBlock, block); + } cfg.getNodeToBlock().set(node, block); blockToNodesMap.get(block).add(node); } @@ -541,9 +559,8 @@ // iterate the dominator tree while (true) { iterations++; - assert earliestBlock.dominates(previousBlock) : "iterations: " + iterations; Node lastKill = blockToKillMap.get(currentBlock).get(locid); - boolean isAtEarliest = earliestBlock == previousBlock && previousBlock != currentBlock; + assert lastKill != null : "should be never null, due to init of killMaps: " + currentBlock + ", location: " + locid; if (lastKill.equals(upperBound)) { // assign node to the block which kills the location @@ -553,7 +570,6 @@ // schedule read out of the loop if possible, in terms of killMaps and earliest // schedule if (currentBlock != earliestBlock && previousBlock != earliestBlock) { - assert earliestBlock.dominates(currentBlock); Block t = currentBlock; while (t.getLoop() != null && t.getDominator() != null && earliestBlock.dominates(t)) { Block dom = t.getDominator(); @@ -568,17 +584,12 @@ if (!outOfLoop && previousBlock.getBeginNode() instanceof MergeNode) { // merges kill locations right at the beginning of a block. if a merge is the - // killing node, we assign it to the dominating node. + // killing node, we assign it to the dominating block. MergeNode merge = (MergeNode) previousBlock.getBeginNode(); - Node killer = getMergeToKillMap().get(merge).get(locid); + Node killer = mergeToKillMap.get(merge).get(locid); if (killer != null && killer == merge) { - // check if we violate earliest schedule condition - if (isAtEarliest) { - printIterations(iterations, "earliest bound in merge: " + earliestBlock); - return earliestBlock; - } printIterations(iterations, "kill by merge: " + currentBlock); return currentBlock; } @@ -590,11 +601,6 @@ return previousBlock; } - if (isAtEarliest) { - printIterations(iterations, "earliest bound: " + earliestBlock); - return earliestBlock; - } - if (upperBoundBlock == currentBlock) { printIterations(iterations, "upper bound: " + currentBlock + ", previous: " + previousBlock); return currentBlock;
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/HighTierContext.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/HighTierContext.java Fri Oct 11 17:21:14 2013 +0200 @@ -23,9 +23,9 @@ package com.oracle.graal.phases.tiers; import com.oracle.graal.api.code.*; -import com.oracle.graal.api.meta.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.phases.*; +import com.oracle.graal.phases.util.*; public class HighTierContext extends PhaseContext { @@ -34,8 +34,8 @@ private final GraphCache cache; private final OptimisticOptimizations optimisticOpts; - public HighTierContext(MetaAccessProvider runtime, Assumptions assumptions, Replacements replacements, GraphCache cache, PhasePlan plan, OptimisticOptimizations optimisticOpts) { - super(runtime, assumptions, replacements); + public HighTierContext(Providers copyFrom, Assumptions assumptions, GraphCache cache, PhasePlan plan, OptimisticOptimizations optimisticOpts) { + super(copyFrom, assumptions); this.plan = plan; this.cache = cache; this.optimisticOpts = optimisticOpts; @@ -54,6 +54,6 @@ } public HighTierContext replaceAssumptions(Assumptions newAssumptions) { - return new HighTierContext(getRuntime(), newAssumptions, getReplacements(), getGraphCache(), getPhasePlan(), getOptimisticOptimizations()); + return new HighTierContext(this, newAssumptions, getGraphCache(), getPhasePlan(), getOptimisticOptimizations()); } }
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/LowTierContext.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/LowTierContext.java Fri Oct 11 17:21:14 2013 +0200 @@ -23,15 +23,14 @@ package com.oracle.graal.phases.tiers; import com.oracle.graal.api.code.*; -import com.oracle.graal.api.meta.*; -import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.phases.util.*; public class LowTierContext extends PhaseContext { private final TargetDescription target; - public LowTierContext(MetaAccessProvider runtime, Assumptions assumptions, Replacements replacements, TargetDescription target) { - super(runtime, assumptions, replacements); + public LowTierContext(Providers copyFrom, Assumptions assumptions, TargetDescription target) { + super(copyFrom, assumptions); this.target = target; }
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/MidTierContext.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/MidTierContext.java Fri Oct 11 17:21:14 2013 +0200 @@ -23,17 +23,16 @@ package com.oracle.graal.phases.tiers; import com.oracle.graal.api.code.*; -import com.oracle.graal.api.meta.*; -import com.oracle.graal.nodes.spi.*; import com.oracle.graal.phases.*; +import com.oracle.graal.phases.util.*; public class MidTierContext extends PhaseContext { private final TargetDescription target; private final OptimisticOptimizations optimisticOpts; - public MidTierContext(MetaAccessProvider runtime, Assumptions assumptions, Replacements replacements, TargetDescription target, OptimisticOptimizations optimisticOpts) { - super(runtime, assumptions, replacements); + public MidTierContext(Providers copyFrom, Assumptions assumptions, TargetDescription target, OptimisticOptimizations optimisticOpts) { + super(copyFrom, assumptions); this.target = target; this.optimisticOpts = optimisticOpts; }
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/PhaseContext.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/PhaseContext.java Fri Oct 11 17:21:14 2013 +0200 @@ -25,28 +25,24 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.phases.util.*; -public class PhaseContext { +public class PhaseContext extends Providers { - private final MetaAccessProvider runtime; private final Assumptions assumptions; - private final Replacements replacements; - public PhaseContext(MetaAccessProvider runtime, Assumptions assumptions, Replacements replacements) { - this.runtime = runtime; + public PhaseContext(MetaAccessProvider metaAccess, CodeCacheProvider codeCache, ConstantReflectionProvider constantReflection, LoweringProvider lowerer, Assumptions assumptions, + Replacements replacements) { + super(metaAccess, codeCache, constantReflection, lowerer, replacements); this.assumptions = assumptions; - this.replacements = replacements; } - public MetaAccessProvider getRuntime() { - return runtime; + public PhaseContext(Providers copyFrom, Assumptions assumptions) { + super(copyFrom); + this.assumptions = assumptions; } public Assumptions getAssumptions() { return assumptions; } - - public Replacements getReplacements() { - return replacements; - } }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/util/Providers.java Fri Oct 11 17:21:14 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.phases.util; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.nodes.spi.*; + +/** + * A set of providers, some of which may not be present (i.e., null). + */ +public class Providers { + + private final MetaAccessProvider metaAccess; + private final CodeCacheProvider codeCache; + private final LoweringProvider lowerer; + private final ConstantReflectionProvider constantReflection; + private final Replacements replacements; + + public Providers(MetaAccessProvider metaAccess, CodeCacheProvider codeCache, ConstantReflectionProvider constantReflection, LoweringProvider lowerer, Replacements replacements) { + this.metaAccess = metaAccess; + this.codeCache = codeCache; + this.constantReflection = constantReflection; + this.lowerer = lowerer; + this.replacements = replacements; + } + + public Providers(Providers copyFrom) { + this.metaAccess = copyFrom.metaAccess; + this.codeCache = copyFrom.codeCache; + this.constantReflection = copyFrom.constantReflection; + this.lowerer = copyFrom.lowerer; + this.replacements = copyFrom.replacements; + } + + public MetaAccessProvider getMetaAccess() { + return metaAccess; + } + + public CodeCacheProvider getCodeCache() { + return codeCache; + } + + public LoweringProvider getLowerer() { + return lowerer; + } + + public ConstantReflectionProvider getConstantReflection() { + return constantReflection; + } + + public Replacements getReplacements() { + return replacements; + } +}
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/util/Util.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/util/Util.java Fri Oct 11 17:21:14 2013 +0200 @@ -26,9 +26,6 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.debug.*; -import com.oracle.graal.graph.*; -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.calc.*; /** * The {@code Util} class contains a motley collection of utility methods used throughout the @@ -319,14 +316,6 @@ return (short) v; } - public static boolean isFixed(Node n) { - return n instanceof FixedNode; - } - - public static boolean isFloating(Node n) { - return n instanceof FloatingNode; - } - /** * Creates an array of integers of length "size", in which each number from 0 to (size - 1) * occurs exactly once. The integers are sorted using the given comparator. This can be used to
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/verify/VerifyUsageWithEquals.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/verify/VerifyUsageWithEquals.java Fri Oct 11 17:21:14 2013 +0200 @@ -42,9 +42,9 @@ this.klass = klass; } - private boolean isAssignableType(ValueNode node, MetaAccessProvider runtime) { + private boolean isAssignableType(ValueNode node, MetaAccessProvider metaAccess) { if (node.stamp() instanceof ObjectStamp) { - ResolvedJavaType valueType = runtime.lookupJavaType(klass); + ResolvedJavaType valueType = metaAccess.lookupJavaType(klass); ResolvedJavaType nodeType = ObjectStamp.typeOrNull(node); if (nodeType != null && valueType.isAssignableFrom(nodeType)) { @@ -58,8 +58,8 @@ return node.isConstant() && node.asConstant().isNull(); } - private boolean checkUsage(ValueNode x, ValueNode y, MetaAccessProvider runtime) { - return isAssignableType(x, runtime) && !isNullConstant(y); + private boolean checkUsage(ValueNode x, ValueNode y, MetaAccessProvider metaAccess) { + return isAssignableType(x, metaAccess) && !isNullConstant(y); } private static boolean isEqualsMethod(StructuredGraph graph) { @@ -72,8 +72,8 @@ 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(), context.getRuntime()) && checkUsage(cn.y(), cn.x(), context.getRuntime())) : "Verifcation of " + klass.getName() + " usage failed: Comparing " + - cn.x() + " and " + cn.y() + " in " + graph.method() + " must use .equals() for object equality, not '==' or '!='"; + assert !(checkUsage(cn.x(), cn.y(), context.getMetaAccess()) && checkUsage(cn.y(), cn.x(), context.getMetaAccess())) : "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;
--- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CFGPrinterObserver.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CFGPrinterObserver.java Fri Oct 11 17:21:14 2013 +0200 @@ -144,9 +144,9 @@ cfgPrinter.cfg = cfgPrinter.lir.cfg; } - CodeCacheProvider runtime = Debug.contextLookup(CodeCacheProvider.class); - if (runtime != null) { - cfgPrinter.target = runtime.getTarget(); + CodeCacheProvider codeCache = Debug.contextLookup(CodeCacheProvider.class); + if (codeCache != null) { + cfgPrinter.target = codeCache.getTarget(); } if (object instanceof BciBlockMapping) { @@ -171,10 +171,10 @@ } else if (object instanceof CompilationResult) { final CompilationResult compResult = (CompilationResult) object; - cfgPrinter.printMachineCode(runtime.disassemble(compResult, null), message); + cfgPrinter.printMachineCode(codeCache.disassemble(compResult, null), message); } else if (isCompilationResultAndInstalledCode(object)) { Object[] tuple = (Object[]) object; - cfgPrinter.printMachineCode(runtime.disassemble((CompilationResult) tuple[0], (InstalledCode) tuple[1]), message); + cfgPrinter.printMachineCode(codeCache.disassemble((CompilationResult) tuple[0], (InstalledCode) tuple[1]), message); } else if (object instanceof Interval[]) { cfgPrinter.printIntervals(message, (Interval[]) object);
--- a/graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64ConvertNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64ConvertNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -22,9 +22,10 @@ */ package com.oracle.graal.replacements.amd64; +import com.oracle.graal.api.meta.*; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.calc.ConvertNode.Op; -import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -44,6 +45,12 @@ this.value = value; } + public Constant evalConst(Constant... inputs) { + // this node should never have been created if its input is constant + assert false; + return null; + } + public void generate(ArithmeticLIRGenerator gen) { gen.setResult(this, gen.emitConvert(opcode, gen.operand(value))); }
--- a/graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64ConvertSnippets.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64ConvertSnippets.java Fri Oct 11 17:21:14 2013 +0200 @@ -28,12 +28,12 @@ import java.util.*; 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.calc.*; import com.oracle.graal.nodes.calc.ConvertNode.Op; import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.phases.util.*; import com.oracle.graal.replacements.*; import com.oracle.graal.replacements.SnippetTemplate.AbstractTemplates; import com.oracle.graal.replacements.SnippetTemplate.Arguments; @@ -149,8 +149,8 @@ private final EnumMap<Op, SnippetInfo> snippets; - public Templates(MetaAccessProvider runtime, Replacements replacements, TargetDescription target) { - super(runtime, replacements, target); + public Templates(Providers providers, TargetDescription target) { + super(providers, target); snippets = new EnumMap<>(Op.class); snippets.put(Op.F2I, snippet(AMD64ConvertSnippets.class, "f2i")); @@ -180,7 +180,7 @@ SnippetTemplate template = template(args); Debug.log("Lowering %s in %s: node=%s, template=%s, arguments=%s", convert.opcode, graph, convert, template, args); - template.instantiate(runtime, replacee, DEFAULT_REPLACER, tool, args); + template.instantiate(providers.getMetaAccess(), replacee, DEFAULT_REPLACER, tool, args); graph.removeFloating(convert); } }
--- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/MethodSubstitutionTest.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/MethodSubstitutionTest.java Fri Oct 11 17:21:14 2013 +0200 @@ -44,14 +44,15 @@ public abstract class MethodSubstitutionTest extends GraalCompilerTest { protected StructuredGraph test(final String snippet) { - return Debug.scope("MethodSubstitutionTest", runtime.lookupJavaMethod(getMethod(snippet)), new Callable<StructuredGraph>() { + return Debug.scope("MethodSubstitutionTest", getMetaAccess().lookupJavaMethod(getMethod(snippet)), new Callable<StructuredGraph>() { @Override public StructuredGraph call() { StructuredGraph graph = parse(snippet); PhasePlan phasePlan = getDefaultPhasePlan(); Assumptions assumptions = new Assumptions(true); - HighTierContext context = new HighTierContext(runtime(), assumptions, replacements, null, phasePlan, OptimisticOptimizations.ALL); + HighTierContext context = new HighTierContext(getProviders(), assumptions, null, phasePlan, + OptimisticOptimizations.ALL); Debug.dump(graph, "Graph"); new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context); Debug.dump(graph, "Graph");
--- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/NewMultiArrayTest.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/NewMultiArrayTest.java Fri Oct 11 17:21:14 2013 +0200 @@ -90,7 +90,7 @@ public void test1() { for (Class clazz : new Class[]{byte.class, char.class, short.class, int.class, float.class, long.class, double.class, String.class}) { bottomClass = clazz; - bottomType = runtime.lookupJavaType(clazz); + bottomType = getMetaAccess().lookupJavaType(clazz); arrayType = bottomType; for (int rank : new int[]{1, 2, 10, 50, 100, 200, 254, 255}) { while (rank(arrayType) != rank) {
--- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/ObjectAccessTest.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/ObjectAccessTest.java Fri Oct 11 17:21:14 2013 +0200 @@ -49,15 +49,15 @@ public ObjectAccessTest() { target = Graal.getRequiredCapability(CodeCacheProvider.class).getTarget(); - installer = new ReplacementsImpl(runtime, new Assumptions(false), target); + installer = new ReplacementsImpl(getMetaAccess(), getConstantReflection(), getCodeCache(), getLowerer(), new Assumptions(false), target); } private static final ThreadLocal<SnippetInliningPolicy> inliningPolicy = new ThreadLocal<>(); @Override protected StructuredGraph parse(Method m) { - ResolvedJavaMethod resolvedMethod = runtime.lookupJavaMethod(m); - return installer.makeGraph(resolvedMethod, null, inliningPolicy.get()); + ResolvedJavaMethod resolvedMethod = getMetaAccess().lookupJavaMethod(m); + return installer.makeGraph(resolvedMethod, null, inliningPolicy.get(), false); } @Test
--- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/PointerTest.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/PointerTest.java Fri Oct 11 17:21:14 2013 +0200 @@ -53,15 +53,15 @@ public PointerTest() { target = Graal.getRequiredCapability(CodeCacheProvider.class).getTarget(); - installer = new ReplacementsImpl(runtime, new Assumptions(false), target); + installer = new ReplacementsImpl(getMetaAccess(), getConstantReflection(), getCodeCache(), getLowerer(), new Assumptions(false), target); } private static final ThreadLocal<SnippetInliningPolicy> inliningPolicy = new ThreadLocal<>(); @Override protected StructuredGraph parse(Method m) { - ResolvedJavaMethod resolvedMethod = runtime.lookupJavaMethod(m); - return installer.makeGraph(resolvedMethod, null, inliningPolicy.get()); + ResolvedJavaMethod resolvedMethod = getMetaAccess().lookupJavaMethod(m); + return installer.makeGraph(resolvedMethod, null, inliningPolicy.get(), false); } @Test @@ -404,7 +404,7 @@ private void assertNumWordCasts(String snippetName, int expectedWordCasts) { Assumptions assumptions = new Assumptions(true); - HighTierContext context = new HighTierContext(runtime(), assumptions, replacements, null, null, OptimisticOptimizations.ALL); + HighTierContext context = new HighTierContext(getProviders(), assumptions, null, null, OptimisticOptimizations.ALL); StructuredGraph graph = parse(snippetName); new CanonicalizerPhase(false).apply(graph, context);
--- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/TypeCheckTest.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/TypeCheckTest.java Fri Oct 11 17:21:14 2013 +0200 @@ -58,7 +58,7 @@ } ProfiledType[] ptypes = new ProfiledType[types.length]; for (int i = 0; i < types.length; i++) { - ptypes[i] = new ProfiledType(runtime.lookupJavaType(types[i]), 1.0D / types.length); + ptypes[i] = new ProfiledType(getMetaAccess().lookupJavaType(types[i]), 1.0D / types.length); } return new JavaTypeProfile(nullSeen, 0.0D, ptypes); }
--- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/WordTest.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/WordTest.java Fri Oct 11 17:21:14 2013 +0200 @@ -43,15 +43,15 @@ public WordTest() { TargetDescription target = Graal.getRequiredCapability(CodeCacheProvider.class).getTarget(); - installer = new ReplacementsImpl(runtime, new Assumptions(false), target); + installer = new ReplacementsImpl(getMetaAccess(), getConstantReflection(), getCodeCache(), getLowerer(), new Assumptions(false), target); } private static final ThreadLocal<SnippetInliningPolicy> inliningPolicy = new ThreadLocal<>(); @Override protected StructuredGraph parse(Method m) { - ResolvedJavaMethod resolvedMethod = runtime.lookupJavaMethod(m); - return installer.makeGraph(resolvedMethod, null, inliningPolicy.get()); + ResolvedJavaMethod resolvedMethod = getMetaAccess().lookupJavaMethod(m); + return installer.makeGraph(resolvedMethod, null, inliningPolicy.get(), false); } @LongTest
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/BoxingSnippets.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/BoxingSnippets.java Fri Oct 11 17:21:14 2013 +0200 @@ -38,6 +38,7 @@ import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; import com.oracle.graal.nodes.util.*; +import com.oracle.graal.phases.util.*; import com.oracle.graal.replacements.Snippet.Fold; import com.oracle.graal.replacements.Snippet.SnippetInliningPolicy; import com.oracle.graal.replacements.SnippetTemplate.AbstractTemplates; @@ -172,27 +173,27 @@ return value.shortValue(); } - public static FloatingNode canonicalizeBoxing(BoxNode box, MetaAccessProvider runtime) { + public static FloatingNode canonicalizeBoxing(BoxNode box, MetaAccessProvider metaAccess) { ValueNode value = box.getValue(); if (value.isConstant()) { Constant sourceConstant = value.asConstant(); switch (box.getBoxingKind()) { case Boolean: - return ConstantNode.forObject(Boolean.valueOf(sourceConstant.asInt() != 0), runtime, box.graph()); + return ConstantNode.forObject(Boolean.valueOf(sourceConstant.asInt() != 0), metaAccess, box.graph()); case Byte: - return ConstantNode.forObject(Byte.valueOf((byte) sourceConstant.asInt()), runtime, box.graph()); + return ConstantNode.forObject(Byte.valueOf((byte) sourceConstant.asInt()), metaAccess, box.graph()); case Char: - return ConstantNode.forObject(Character.valueOf((char) sourceConstant.asInt()), runtime, box.graph()); + return ConstantNode.forObject(Character.valueOf((char) sourceConstant.asInt()), metaAccess, box.graph()); case Short: - return ConstantNode.forObject(Short.valueOf((short) sourceConstant.asInt()), runtime, box.graph()); + return ConstantNode.forObject(Short.valueOf((short) sourceConstant.asInt()), metaAccess, box.graph()); case Int: - return ConstantNode.forObject(Integer.valueOf(sourceConstant.asInt()), runtime, box.graph()); + return ConstantNode.forObject(Integer.valueOf(sourceConstant.asInt()), metaAccess, box.graph()); case Long: - return ConstantNode.forObject(Long.valueOf(sourceConstant.asLong()), runtime, box.graph()); + return ConstantNode.forObject(Long.valueOf(sourceConstant.asLong()), metaAccess, box.graph()); case Float: - return ConstantNode.forObject(Float.valueOf(sourceConstant.asFloat()), runtime, box.graph()); + return ConstantNode.forObject(Float.valueOf(sourceConstant.asFloat()), metaAccess, box.graph()); case Double: - return ConstantNode.forObject(Double.valueOf(sourceConstant.asDouble()), runtime, box.graph()); + return ConstantNode.forObject(Double.valueOf(sourceConstant.asDouble()), metaAccess, box.graph()); default: assert false : "Unexpected source kind for boxing"; break; @@ -206,8 +207,8 @@ private final EnumMap<Kind, SnippetInfo> boxSnippets = new EnumMap<>(Kind.class); private final EnumMap<Kind, SnippetInfo> unboxSnippets = new EnumMap<>(Kind.class); - public Templates(MetaAccessProvider runtime, Replacements replacements, TargetDescription target) { - super(runtime, replacements, target); + public Templates(Providers providers, TargetDescription target) { + super(providers, target); for (Kind kind : new Kind[]{Kind.Boolean, Kind.Byte, Kind.Char, Kind.Double, Kind.Float, Kind.Int, Kind.Long, Kind.Short}) { boxSnippets.put(kind, snippet(BoxingSnippets.class, kind.getJavaName() + "ValueOf")); unboxSnippets.put(kind, snippet(BoxingSnippets.class, kind.getJavaName() + "Value")); @@ -215,7 +216,7 @@ } public void lower(BoxNode box, LoweringTool tool) { - FloatingNode canonical = canonicalizeBoxing(box, runtime); + FloatingNode canonical = canonicalizeBoxing(box, providers.getMetaAccess()); // if in AOT mode, we don't want to embed boxed constants. if (canonical != null && !AOTCompilation.getValue()) { box.graph().replaceFloating(box, canonical); @@ -225,7 +226,7 @@ SnippetTemplate template = template(args); Debug.log("Lowering integerValueOf in %s: node=%s, template=%s, arguments=%s", box.graph(), box, template, args); - template.instantiate(runtime, box, DEFAULT_REPLACER, tool, args); + template.instantiate(providers.getMetaAccess(), box, DEFAULT_REPLACER, tool, args); GraphUtil.killWithUnusedFloatingInputs(box); } } @@ -236,7 +237,7 @@ SnippetTemplate template = template(args); Debug.log("Lowering integerValueOf in %s: node=%s, template=%s, arguments=%s", unbox.graph(), unbox, template, args); - template.instantiate(runtime, unbox, DEFAULT_REPLACER, tool, args); + template.instantiate(providers.getMetaAccess(), unbox, DEFAULT_REPLACER, tool, args); GraphUtil.killWithUnusedFloatingInputs(unbox); } }
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/GraalMethodSubstitutions.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/GraalMethodSubstitutions.java Fri Oct 11 17:21:14 2013 +0200 @@ -35,7 +35,7 @@ @ServiceProvider(ReplacementsProvider.class) public class GraalMethodSubstitutions implements ReplacementsProvider { - public void registerReplacements(MetaAccessProvider runtime, Replacements replacements, TargetDescription target) { + public void registerReplacements(MetaAccessProvider metaAccess, Replacements replacements, TargetDescription target) { for (Class<?> clazz : BoxingSubstitutions.getClasses()) { replacements.registerSubstitutions(clazz); }
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/InstanceOfSnippetsTemplates.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/InstanceOfSnippetsTemplates.java Fri Oct 11 17:21:14 2013 +0200 @@ -27,13 +27,13 @@ import java.util.*; 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.java.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.util.*; +import com.oracle.graal.phases.util.*; import com.oracle.graal.replacements.SnippetTemplate.AbstractTemplates; import com.oracle.graal.replacements.SnippetTemplate.Arguments; import com.oracle.graal.replacements.SnippetTemplate.UsageReplacer; @@ -53,8 +53,8 @@ */ public abstract class InstanceOfSnippetsTemplates extends AbstractTemplates { - public InstanceOfSnippetsTemplates(MetaAccessProvider runtime, Replacements replacements, TargetDescription target) { - super(runtime, replacements, target); + public InstanceOfSnippetsTemplates(Providers providers, TargetDescription target) { + super(providers, target); } /** @@ -77,7 +77,7 @@ replacer.replaceUsingInstantiation(); } else { Arguments args = makeArguments(replacer, tool); - template(args).instantiate(runtime, instanceOf, replacer, tool, args); + template(args).instantiate(providers.getMetaAccess(), instanceOf, replacer, tool, args); } } @@ -206,7 +206,7 @@ } @Override - public void replace(ValueNode oldNode, ValueNode newNode, MemoryMap<Node> mmap) { + public void replace(ValueNode oldNode, ValueNode newNode, MemoryMapNode mmap) { assert newNode instanceof PhiNode; assert oldNode == instanceOf; newNode.inferStamp(); @@ -238,7 +238,7 @@ } @Override - public void replace(ValueNode oldNode, ValueNode newNode, MemoryMap<Node> mmap) { + public void replace(ValueNode oldNode, ValueNode newNode, MemoryMapNode mmap) { assert newNode instanceof PhiNode; assert oldNode == instanceOf; newNode.inferStamp();
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeClassSubstitutions.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeClassSubstitutions.java Fri Oct 11 17:21:14 2013 +0200 @@ -64,22 +64,22 @@ @MethodSubstitution private static Node getNode(Node node, long offset) { - return PiNode.piCast(UnsafeLoadNode.load(node, 0, offset, Kind.Object), Node.class, false, false); + return PiNode.piCast(UnsafeLoadNode.load(node, offset, Kind.Object), Node.class, false, false); } @MethodSubstitution private static NodeList getNodeList(Node node, long offset) { - return PiNode.piCast(UnsafeLoadNode.load(node, 0, offset, Kind.Object), NodeList.class, false, false); + return PiNode.piCast(UnsafeLoadNode.load(node, offset, Kind.Object), NodeList.class, false, false); } @MethodSubstitution private static void putNode(Node node, long offset, Node value) { - UnsafeStoreNode.store(node, 0, offset, value, Kind.Object); + UnsafeStoreNode.store(node, offset, value, Kind.Object); } @MethodSubstitution private static void putNodeList(Node node, long offset, NodeList value) { - UnsafeStoreNode.store(node, 0, offset, value, Kind.Object); + UnsafeStoreNode.store(node, offset, value, Kind.Object); } }
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationPhase.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationPhase.java Fri Oct 11 17:21:14 2013 +0200 @@ -49,10 +49,10 @@ */ public class NodeIntrinsificationPhase extends Phase { - private final MetaAccessProvider runtime; + private final MetaAccessProvider metaAccess; - public NodeIntrinsificationPhase(MetaAccessProvider runtime) { - this.runtime = runtime; + public NodeIntrinsificationPhase(MetaAccessProvider metaAccess) { + this.metaAccess = metaAccess; } @Override @@ -113,7 +113,7 @@ if (constant != null) { // Replace the invoke with the result of the call - ConstantNode node = ConstantNode.forConstant(constant, runtime, methodCallTargetNode.graph()); + ConstantNode node = ConstantNode.forConstant(constant, metaAccess, methodCallTargetNode.graph()); methodCallTargetNode.invoke().intrinsify(node); // Clean up checkcast instructions inserted by javac if the return type is generic. @@ -158,8 +158,8 @@ Constant constant = constantNode.asConstant(); Object o = constant.asBoxedValue(); if (o instanceof Class<?>) { - reflectionCallArguments[i] = Constant.forObject(runtime.lookupJavaType((Class<?>) o)); - parameterTypes[i] = runtime.lookupJavaType(ResolvedJavaType.class); + reflectionCallArguments[i] = Constant.forObject(metaAccess.lookupJavaType((Class<?>) o)); + parameterTypes[i] = metaAccess.lookupJavaType(ResolvedJavaType.class); } else { if (parameterTypes[i].getKind() == Kind.Boolean) { reflectionCallArguments[i] = Constant.forObject(Boolean.valueOf(constant.asInt() != 0)); @@ -175,7 +175,7 @@ } } else { reflectionCallArguments[i] = Constant.forObject(argument); - parameterTypes[i] = runtime.lookupJavaType(ValueNode.class); + parameterTypes[i] = metaAccess.lookupJavaType(ValueNode.class); } } return reflectionCallArguments; @@ -186,9 +186,9 @@ if (intrinsic.value() == NodeIntrinsic.class) { result = target.getDeclaringClass(); } else { - result = runtime.lookupJavaType(intrinsic.value()); + result = metaAccess.lookupJavaType(intrinsic.value()); } - assert runtime.lookupJavaType(ValueNode.class).isAssignableFrom(result) : "Node intrinsic class " + toJavaName(result, false) + " derived from @" + NodeIntrinsic.class.getSimpleName() + + assert metaAccess.lookupJavaType(ValueNode.class).isAssignableFrom(result) : "Node intrinsic class " + toJavaName(result, false) + " derived from @" + NodeIntrinsic.class.getSimpleName() + " annotation on " + format("%H.%n(%p)", target) + " is not a subclass of " + ValueNode.class; return result; } @@ -230,7 +230,7 @@ boolean needsMetaAccessProviderArgument = false; ResolvedJavaType[] signature = MetaUtil.resolveJavaTypes(MetaUtil.signatureToTypes(c.getSignature(), null), c.getDeclaringClass()); - if (signature.length != 0 && signature[0].equals(runtime.lookupJavaType(MetaAccessProvider.class))) { + if (signature.length != 0 && signature[0].equals(metaAccess.lookupJavaType(MetaAccessProvider.class))) { // Chop off the MetaAccessProvider first parameter signature = Arrays.copyOfRange(signature, 1, signature.length); needsMetaAccessProviderArgument = true; @@ -273,7 +273,7 @@ if (needsMetaAccessProviderArgument) { Constant[] copy = new Constant[arguments.length + 1]; System.arraycopy(arguments, 0, copy, 1, arguments.length); - copy[0] = Constant.forObject(runtime); + copy[0] = Constant.forObject(metaAccess); arguments = copy; } return arguments;
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java Fri Oct 11 17:21:14 2013 +0200 @@ -45,13 +45,14 @@ import com.oracle.graal.phases.*; import com.oracle.graal.phases.common.*; import com.oracle.graal.phases.tiers.*; +import com.oracle.graal.phases.util.*; import com.oracle.graal.replacements.Snippet.DefaultSnippetInliningPolicy; import com.oracle.graal.replacements.Snippet.SnippetInliningPolicy; import com.oracle.graal.word.phases.*; public class ReplacementsImpl implements Replacements { - protected final MetaAccessProvider runtime; + protected final Providers providers; protected final TargetDescription target; protected final Assumptions assumptions; @@ -67,8 +68,9 @@ private final Set<ResolvedJavaMethod> forcedSubstitutions; private final Map<Class<? extends SnippetTemplateCache>, SnippetTemplateCache> snippetTemplateCache; - public ReplacementsImpl(MetaAccessProvider runtime, Assumptions assumptions, TargetDescription target) { - this.runtime = runtime; + public ReplacementsImpl(MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection, CodeCacheProvider codeCache, LoweringProvider lowerer, Assumptions assumptions, + TargetDescription target) { + this.providers = new Providers(metaAccess, codeCache, constantReflection, lowerer, this); this.target = target; this.assumptions = assumptions; this.graphs = new ConcurrentHashMap<>(); @@ -84,7 +86,7 @@ StructuredGraph graph = graphs.get(method); if (graph == null) { - graphs.putIfAbsent(method, makeGraph(method, null, inliningPolicy(method))); + graphs.putIfAbsent(method, makeGraph(method, null, inliningPolicy(method), method.getAnnotation(Snippet.class).removeAllFrameStates())); graph = graphs.get(method); } return graph; @@ -97,7 +99,7 @@ } StructuredGraph graph = graphs.get(substitute); if (graph == null) { - graphs.putIfAbsent(substitute, makeGraph(substitute, original, inliningPolicy(substitute))); + graphs.putIfAbsent(substitute, makeGraph(substitute, original, inliningPolicy(substitute), false)); graph = graphs.get(substitute); } return graph; @@ -167,12 +169,13 @@ * @return the original method */ protected ResolvedJavaMethod registerMethodSubstitution(Member originalMember, Method substituteMethod) { - ResolvedJavaMethod substitute = runtime.lookupJavaMethod(substituteMethod); + MetaAccessProvider metaAccess = providers.getMetaAccess(); + ResolvedJavaMethod substitute = metaAccess.lookupJavaMethod(substituteMethod); ResolvedJavaMethod original; if (originalMember instanceof Method) { - original = runtime.lookupJavaMethod((Method) originalMember); + original = metaAccess.lookupJavaMethod((Method) originalMember); } else { - original = runtime.lookupJavaConstructor((Constructor) originalMember); + original = metaAccess.lookupJavaConstructor((Constructor) originalMember); } Debug.log("substitution: " + MetaUtil.format("%H.%n(%p)", original) + " --> " + MetaUtil.format("%H.%n(%p)", substitute)); @@ -189,10 +192,11 @@ */ protected ResolvedJavaMethod registerMacroSubstitution(Member originalMethod, Class<? extends FixedWithNextNode> macro) { ResolvedJavaMethod originalJavaMethod; + MetaAccessProvider metaAccess = providers.getMetaAccess(); if (originalMethod instanceof Method) { - originalJavaMethod = runtime.lookupJavaMethod((Method) originalMethod); + originalJavaMethod = metaAccess.lookupJavaMethod((Method) originalMethod); } else { - originalJavaMethod = runtime.lookupJavaConstructor((Constructor) originalMethod); + originalJavaMethod = metaAccess.lookupJavaConstructor((Constructor) originalMethod); } registeredMacroSubstitutions.put(originalJavaMethod, macro); return originalJavaMethod; @@ -205,7 +209,7 @@ policyClass = snippet.inlining(); } if (policyClass == SnippetInliningPolicy.class) { - return new DefaultSnippetInliningPolicy(runtime); + return new DefaultSnippetInliningPolicy(providers.getMetaAccess()); } try { return policyClass.getConstructor().newInstance(); @@ -221,9 +225,10 @@ * @param original the original method if {@code method} is a {@linkplain MethodSubstitution * substitution} otherwise null * @param policy the inlining policy to use during preprocessing + * @param removeAllFrameStates removes all frame states from side effecting instructions */ - public StructuredGraph makeGraph(ResolvedJavaMethod method, ResolvedJavaMethod original, SnippetInliningPolicy policy) { - return createGraphMaker(method, original).makeGraph(policy); + public StructuredGraph makeGraph(ResolvedJavaMethod method, ResolvedJavaMethod original, SnippetInliningPolicy policy, boolean removeAllFrameStates) { + return createGraphMaker(method, original).makeGraph(policy, removeAllFrameStates); } /** @@ -261,7 +266,7 @@ this.original = original; } - public StructuredGraph makeGraph(final SnippetInliningPolicy policy) { + public StructuredGraph makeGraph(final SnippetInliningPolicy policy, final boolean removeAllFrameStates) { return Debug.scope("BuildSnippetGraph", new Object[]{method}, new Callable<StructuredGraph>() { @Override @@ -271,7 +276,7 @@ // Cannot have a finalized version of a graph in the cache graph = graph.copy(); - finalizeGraph(graph); + finalizeGraph(graph, removeAllFrameStates); Debug.dump(graph, "%s: Final", method.getName()); @@ -283,15 +288,23 @@ /** * Does final processing of a snippet graph. */ - protected void finalizeGraph(StructuredGraph graph) { - new NodeIntrinsificationPhase(runtime).apply(graph); + protected void finalizeGraph(StructuredGraph graph, boolean removeAllFrameStates) { + new NodeIntrinsificationPhase(providers.getMetaAccess()).apply(graph); if (!SnippetTemplate.hasConstantParameter(method)) { NodeIntrinsificationVerificationPhase.verify(graph); } new ConvertDeoptimizeToGuardPhase().apply(graph); if (original == null) { - new SnippetFrameStateCleanupPhase().apply(graph); + if (removeAllFrameStates) { + for (Node node : graph.getNodes()) { + if (node instanceof StateSplit) { + ((StateSplit) node).setStateAfter(null); + } + } + } else { + new SnippetFrameStateCleanupPhase().apply(graph); + } } new DeadCodeEliminationPhase().apply(graph); } @@ -322,12 +335,13 @@ @Override public void run() { - new GraphBuilderPhase(runtime, GraphBuilderConfiguration.getSnippetDefault(), OptimisticOptimizations.NONE).apply(graph); - new WordTypeVerificationPhase(runtime, target.wordKind).apply(graph); - new WordTypeRewriterPhase(runtime, target.wordKind).apply(graph); + MetaAccessProvider metaAccess = providers.getMetaAccess(); + new GraphBuilderPhase(metaAccess, GraphBuilderConfiguration.getSnippetDefault(), OptimisticOptimizations.NONE).apply(graph); + new WordTypeVerificationPhase(metaAccess, target.wordKind).apply(graph); + new WordTypeRewriterPhase(metaAccess, target.wordKind).apply(graph); if (OptCanonicalizer.getValue()) { - new CanonicalizerPhase(true).apply(graph, new PhaseContext(runtime, assumptions, ReplacementsImpl.this)); + new CanonicalizerPhase(true).apply(graph, new PhaseContext(providers, assumptions)); } } }); @@ -347,7 +361,7 @@ */ protected void afterInline(StructuredGraph caller, StructuredGraph callee, Object beforeInlineData) { if (OptCanonicalizer.getValue()) { - new CanonicalizerPhase(true).apply(caller, new PhaseContext(runtime, assumptions, ReplacementsImpl.this)); + new CanonicalizerPhase(true).apply(caller, new PhaseContext(providers, assumptions)); } } @@ -355,10 +369,10 @@ * Called after all inlining for a given graph is complete. */ protected void afterInlining(StructuredGraph graph) { - new NodeIntrinsificationPhase(runtime).apply(graph); + new NodeIntrinsificationPhase(providers.getMetaAccess()).apply(graph); new DeadCodeEliminationPhase().apply(graph); if (OptCanonicalizer.getValue()) { - new CanonicalizerPhase(true).apply(graph, new PhaseContext(runtime, assumptions, ReplacementsImpl.this)); + new CanonicalizerPhase(true).apply(graph, new PhaseContext(providers, assumptions)); } } @@ -373,9 +387,10 @@ ResolvedJavaMethod callee = callTarget.targetMethod(); if (callee == method) { final StructuredGraph originalGraph = new StructuredGraph(original); - new GraphBuilderPhase(runtime, GraphBuilderConfiguration.getSnippetDefault(), OptimisticOptimizations.NONE).apply(originalGraph); - new WordTypeVerificationPhase(runtime, target.wordKind).apply(graph); - new WordTypeRewriterPhase(runtime, target.wordKind).apply(graph); + MetaAccessProvider metaAccess = providers.getMetaAccess(); + new GraphBuilderPhase(metaAccess, GraphBuilderConfiguration.getSnippetDefault(), OptimisticOptimizations.NONE).apply(originalGraph); + new WordTypeVerificationPhase(metaAccess, target.wordKind).apply(graph); + new WordTypeRewriterPhase(metaAccess, target.wordKind).apply(graph); InliningUtil.inline(callTarget.invoke(), originalGraph, true); @@ -468,7 +483,7 @@ parameters = Arrays.copyOfRange(parameters, 1, parameters.length); } } else { - Signature signature = runtime.parseMethodDescriptor(methodSubstitution); + Signature signature = providers.getMetaAccess().parseMethodDescriptor(methodSubstitution); parameters = new Class[signature.getParameterCount(false)]; for (int i = 0; i < parameters.length; i++) { parameters[i] = resolveType(signature.getParameterType(i, null));
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/Snippet.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/Snippet.java Fri Oct 11 17:21:14 2013 +0200 @@ -45,6 +45,13 @@ Class<? extends SnippetInliningPolicy> inlining() default SnippetInliningPolicy.class; /** + * Specifies whether all FrameStates within this snippet should always be removed. If this is + * false, FrameStates are only removed if there are no side-effecting instructions in the + * snippet. + */ + boolean removeAllFrameStates() default false; + + /** * Guides inlining decisions used when installing a snippet. */ public interface SnippetInliningPolicy {
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java Fri Oct 11 17:21:14 2013 +0200 @@ -34,6 +34,7 @@ import com.oracle.graal.debug.*; import com.oracle.graal.debug.internal.*; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.iterators.*; import com.oracle.graal.loop.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.StructuredGraph.GuardsStage; @@ -46,6 +47,7 @@ import com.oracle.graal.phases.common.*; import com.oracle.graal.phases.common.FloatingReadPhase.MemoryMapImpl; import com.oracle.graal.phases.tiers.*; +import com.oracle.graal.phases.util.*; import com.oracle.graal.replacements.Snippet.ConstantParameter; import com.oracle.graal.replacements.Snippet.VarargsParameter; import com.oracle.graal.replacements.nodes.*; @@ -320,14 +322,12 @@ */ public abstract static class AbstractTemplates implements SnippetTemplateCache { - protected final MetaAccessProvider runtime; - protected final Replacements replacements; + protected final Providers providers; protected final TargetDescription target; private final ConcurrentHashMap<CacheKey, SnippetTemplate> templates; - protected AbstractTemplates(MetaAccessProvider runtime, Replacements replacements, TargetDescription target) { - this.runtime = runtime; - this.replacements = replacements; + protected AbstractTemplates(Providers providers, TargetDescription target) { + this.providers = providers; this.target = target; this.templates = new ConcurrentHashMap<>(); } @@ -346,7 +346,7 @@ } } assert found != null : "did not find @" + Snippet.class.getSimpleName() + " method in " + declaringClass + (methodName == null ? "" : " named " + methodName); - return new SnippetInfo(runtime.lookupJavaMethod(found)); + return new SnippetInfo(providers.getMetaAccess().lookupJavaMethod(found)); } /** @@ -360,7 +360,7 @@ @Override public SnippetTemplate call() throws Exception { - return new SnippetTemplate(runtime, replacements, args); + return new SnippetTemplate(providers, args); } }); templates.put(args.cacheKey, template); @@ -391,20 +391,22 @@ /** * Creates a snippet template. */ - protected SnippetTemplate(final MetaAccessProvider runtime, final Replacements replacements, Arguments args) { - StructuredGraph snippetGraph = replacements.getSnippet(args.info.method); + protected SnippetTemplate(final Providers providers, Arguments args) { + StructuredGraph snippetGraph = providers.getReplacements().getSnippet(args.info.method); ResolvedJavaMethod method = snippetGraph.method(); Signature signature = method.getSignature(); - PhaseContext context = new PhaseContext(runtime, replacements.getAssumptions(), replacements); + Assumptions assumptions = providers.getReplacements().getAssumptions(); + PhaseContext phaseContext = new PhaseContext(providers, assumptions); // Copy snippet graph, replacing constant parameters with given arguments final StructuredGraph snippetCopy = new StructuredGraph(snippetGraph.name, snippetGraph.method()); IdentityHashMap<Node, Node> nodeReplacements = new IdentityHashMap<>(); nodeReplacements.put(snippetGraph.start(), snippetCopy.start()); - assert checkTemplate(runtime, args, method, signature); + MetaAccessProvider metaAccess = providers.getMetaAccess(); + assert checkTemplate(metaAccess, args, method, signature); int parameterCount = args.info.getParameterCount(); ConstantNode[] placeholders = new ConstantNode[parameterCount]; @@ -419,11 +421,11 @@ } else { constantArg = Constant.forBoxed(kind, arg); } - nodeReplacements.put(snippetGraph.getLocal(i), ConstantNode.forConstant(constantArg, runtime, snippetCopy)); + nodeReplacements.put(snippetGraph.getLocal(i), ConstantNode.forConstant(constantArg, metaAccess, snippetCopy)); } else if (args.info.isVarargsParameter(i)) { Varargs varargs = (Varargs) args.values[i]; Object array = Array.newInstance(varargs.componentType, varargs.length); - ConstantNode placeholder = ConstantNode.forObject(array, runtime, snippetCopy); + ConstantNode placeholder = ConstantNode.forObject(array, metaAccess, snippetCopy); nodeReplacements.put(snippetGraph.getLocal(i), placeholder); placeholders[i] = placeholder; } @@ -433,8 +435,8 @@ Debug.dump(snippetCopy, "Before specialization"); if (!nodeReplacements.isEmpty()) { // Do deferred intrinsification of node intrinsics - new NodeIntrinsificationPhase(runtime).apply(snippetCopy); - new CanonicalizerPhase(true).apply(snippetCopy, context); + new NodeIntrinsificationPhase(metaAccess).apply(snippetCopy); + new CanonicalizerPhase(true).apply(snippetCopy, phaseContext); } NodeIntrinsificationVerificationPhase.verify(snippetCopy); @@ -490,8 +492,8 @@ if (loopBegin != null) { LoopEx loop = new LoopsData(snippetCopy).loop(loopBegin); int mark = snippetCopy.getMark(); - LoopTransformations.fullUnroll(loop, context, new CanonicalizerPhase(true)); - new CanonicalizerPhase(true).applyIncremental(snippetCopy, context, mark); + LoopTransformations.fullUnroll(loop, phaseContext, new CanonicalizerPhase(true)); + new CanonicalizerPhase(true).applyIncremental(snippetCopy, phaseContext, mark); } FixedNode explodeLoopNext = explodeLoop.next(); explodeLoop.clearSuccessors(); @@ -507,7 +509,7 @@ Debug.scope("LoweringSnippetTemplate", snippetCopy, new Runnable() { public void run() { - PhaseContext c = new PhaseContext(runtime, new Assumptions(false), replacements); + PhaseContext c = new PhaseContext(providers, new Assumptions(false)); new LoweringPhase(new CanonicalizerPhase(true)).apply(snippetCopy, c); } }); @@ -540,7 +542,6 @@ } new DeadCodeEliminationPhase().apply(snippetCopy); - new CanonicalizerPhase(true).apply(snippetCopy, context); assert checkAllVarargPlaceholdersAreDeleted(parameterCount, placeholders); @@ -552,7 +553,7 @@ StartNode entryPointNode = snippet.start(); nodes = new ArrayList<>(snippet.getNodeCount()); boolean seenReturn = false; - boolean containsMemoryState = false; + boolean containsMemoryMap = false; for (Node node : snippet.getNodes()) { if (node == entryPointNode || node == entryPointNode.stateAfter()) { // Do nothing. @@ -560,18 +561,20 @@ nodes.add(node); if (node instanceof ReturnNode) { retNode = (ReturnNode) node; - for (MemoryState memstate : retNode.usages().filter(MemoryState.class).snapshot()) { - this.memoryMap = memstate.getMemoryMap(); - memstate.safeDelete(); - } + NodeIterable<MemoryMapNode> memstates = retNode.inputs().filter(MemoryMapNode.class); + assert memstates.count() == 1; + memoryMap = memstates.first(); + retNode.replaceFirstInput(memoryMap, null); + memoryMap.safeDelete(); + assert !seenReturn : "can handle only one ReturnNode"; seenReturn = true; - } else if (node instanceof MemoryState) { - containsMemoryState = true; + } else if (node instanceof MemoryMapNode) { + containsMemoryMap = true; } } } - assert !containsMemoryState; + assert !containsMemoryMap; this.sideEffectNodes = curSideEffectNodes; this.deoptNodes = curDeoptNodes; @@ -591,9 +594,9 @@ return true; } - private static boolean checkConstantArgument(MetaAccessProvider runtime, final ResolvedJavaMethod method, Signature signature, int i, String name, Object arg, Kind kind) { + private static boolean checkConstantArgument(MetaAccessProvider metaAccess, final ResolvedJavaMethod method, Signature signature, int i, String name, Object arg, Kind kind) { ResolvedJavaType type = signature.getParameterType(i, method.getDeclaringClass()).resolve(method.getDeclaringClass()); - if (runtime.lookupJavaType(WordBase.class).isAssignableFrom(type)) { + if (metaAccess.lookupJavaType(WordBase.class).isAssignableFrom(type)) { assert arg instanceof Constant : method + ": word constant parameters must be passed boxed in a Constant value: " + arg; return true; } @@ -606,10 +609,10 @@ return true; } - private static boolean checkVarargs(MetaAccessProvider runtime, final ResolvedJavaMethod method, Signature signature, int i, String name, Varargs varargs) { + private static boolean checkVarargs(MetaAccessProvider metaAccess, final ResolvedJavaMethod method, Signature signature, int i, String name, Varargs varargs) { ResolvedJavaType type = (ResolvedJavaType) signature.getParameterType(i, method.getDeclaringClass()); assert type.isArray() : "varargs parameter must be an array type"; - assert type.getComponentType().isAssignableFrom(runtime.lookupJavaType(varargs.componentType)) : "componentType for " + name + " not matching " + MetaUtil.toJavaName(type) + " instance: " + + assert type.getComponentType().isAssignableFrom(metaAccess.lookupJavaType(varargs.componentType)) : "componentType for " + name + " not matching " + MetaUtil.toJavaName(type) + " instance: " + varargs.componentType; return true; } @@ -657,14 +660,14 @@ /** * map of killing locations to memory checkpoints (nodes). */ - private MemoryMap<Node> memoryMap; + private MemoryMapNode memoryMap; /** * Gets the instantiation-time bindings to this template's parameters. * * @return the map that will be used to bind arguments to parameters when inlining this template */ - private IdentityHashMap<Node, Node> bind(StructuredGraph replaceeGraph, MetaAccessProvider runtime, Arguments args) { + private IdentityHashMap<Node, Node> bind(StructuredGraph replaceeGraph, MetaAccessProvider metaAccess, Arguments args) { IdentityHashMap<Node, Node> replacements = new IdentityHashMap<>(); assert args.info.getParameterCount() == parameters.length : "number of args (" + args.info.getParameterCount() + ") != number of parameters (" + parameters.length + ")"; for (int i = 0; i < parameters.length; i++) { @@ -678,7 +681,7 @@ Kind kind = ((LocalNode) parameter).kind(); assert argument != null || kind == Kind.Object : this + " cannot accept null for non-object parameter named " + args.info.names[i]; Constant constant = forBoxed(argument, kind); - replacements.put((LocalNode) parameter, ConstantNode.forConstant(constant, runtime, replaceeGraph)); + replacements.put((LocalNode) parameter, ConstantNode.forConstant(constant, metaAccess, replaceeGraph)); } } else if (parameter instanceof LocalNode[]) { LocalNode[] locals = (LocalNode[]) parameter; @@ -703,7 +706,7 @@ replacements.put(local, (ValueNode) value); } else { Constant constant = forBoxed(value, local.kind()); - ConstantNode element = ConstantNode.forConstant(constant, runtime, replaceeGraph); + ConstantNode element = ConstantNode.forConstant(constant, metaAccess, replaceeGraph); replacements.put(local, element); } } @@ -751,7 +754,7 @@ /** * Replaces all usages of {@code oldNode} with direct or indirect usages of {@code newNode}. */ - void replace(ValueNode oldNode, ValueNode newNode, MemoryMap<Node> mmap); + void replace(ValueNode oldNode, ValueNode newNode, MemoryMapNode mmap); } /** @@ -761,7 +764,7 @@ public static final UsageReplacer DEFAULT_REPLACER = new UsageReplacer() { @Override - public void replace(ValueNode oldNode, ValueNode newNode, MemoryMap<Node> mmap) { + public void replace(ValueNode oldNode, ValueNode newNode, MemoryMapNode mmap) { oldNode.replaceAtUsages(newNode); if (mmap == null || newNode == null) { return; @@ -792,7 +795,7 @@ return true; } - Set<LocationIdentity> kills = ((MemoryMapImpl) memoryMap).getLocations(); + Set<LocationIdentity> kills = new HashSet<>(((MemoryMapImpl) memoryMap).getLocations()); if (replacee instanceof MemoryCheckpoint.Single) { // check if some node in snippet graph also kills the same location @@ -828,7 +831,7 @@ return true; } - private class DuplicateMapper implements MemoryMap<Node> { + private class DuplicateMapper extends MemoryMapNode { Map<Node, Node> duplicates; StartNode replaceeStart; @@ -854,13 +857,13 @@ /** * Replaces a given fixed node with this specialized snippet. * - * @param runtime + * @param metaAccess * @param replacee the node that will be replaced * @param replacer object that replaces the usages of {@code replacee} * @param args the arguments to be bound to the flattened positional parameters of the snippet * @return the map of duplicated nodes (original -> duplicate) */ - public Map<Node, Node> instantiate(MetaAccessProvider runtime, FixedNode replacee, UsageReplacer replacer, Arguments args) { + public Map<Node, Node> instantiate(MetaAccessProvider metaAccess, FixedNode replacee, UsageReplacer replacer, Arguments args) { assert checkSnippetKills(replacee); try (TimerCloseable a = instantiationTimer.start()) { instantiationCounter.increment(); @@ -868,7 +871,7 @@ StartNode entryPointNode = snippet.start(); FixedNode firstCFGNode = entryPointNode.next(); StructuredGraph replaceeGraph = replacee.graph(); - IdentityHashMap<Node, Node> replacements = bind(replaceeGraph, runtime, args); + IdentityHashMap<Node, Node> replacements = bind(replaceeGraph, metaAccess, args); replacements.put(entryPointNode, replaceeGraph.start()); Map<Node, Node> duplicates = replaceeGraph.addDuplicates(nodes, snippet, snippet.getNodeCount(), replacements); Debug.dump(replaceeGraph, "After inlining snippet %s", snippet.method()); @@ -915,7 +918,7 @@ returnValue = (ValueNode) duplicates.get(returnNode.result()); } Node returnDuplicate = duplicates.get(returnNode); - MemoryMap<Node> mmap = new DuplicateMapper(duplicates, replaceeGraph.start()); + MemoryMapNode mmap = new DuplicateMapper(duplicates, replaceeGraph.start()); if (returnValue == null && replacee.usages().isNotEmpty() && replacee instanceof MemoryCheckpoint) { replacer.replace(replacee, (ValueNode) returnDuplicate.predecessor(), mmap); } else { @@ -948,12 +951,12 @@ /** * Replaces a given floating node with this specialized snippet. * - * @param runtime + * @param metaAccess * @param replacee the node that will be replaced * @param replacer object that replaces the usages of {@code replacee} * @param args the arguments to be bound to the flattened positional parameters of the snippet */ - public void instantiate(MetaAccessProvider runtime, FloatingNode replacee, UsageReplacer replacer, LoweringTool tool, Arguments args) { + public void instantiate(MetaAccessProvider metaAccess, FloatingNode replacee, UsageReplacer replacer, LoweringTool tool, Arguments args) { assert checkSnippetKills(replacee); try (TimerCloseable a = instantiationTimer.start()) { instantiationCounter.increment(); @@ -964,7 +967,7 @@ StartNode entryPointNode = snippet.start(); FixedNode firstCFGNode = entryPointNode.next(); StructuredGraph replaceeGraph = replacee.graph(); - IdentityHashMap<Node, Node> replacements = bind(replaceeGraph, runtime, args); + IdentityHashMap<Node, Node> replacements = bind(replaceeGraph, metaAccess, args); replacements.put(entryPointNode, replaceeGraph.start()); Map<Node, Node> duplicates = replaceeGraph.addDuplicates(nodes, snippet, snippet.getNodeCount(), replacements); Debug.dump(replaceeGraph, "After inlining snippet %s", snippetCopy.method()); @@ -1036,16 +1039,16 @@ return buf.append(')').toString(); } - private static boolean checkTemplate(MetaAccessProvider runtime, Arguments args, ResolvedJavaMethod method, Signature signature) { + private static boolean checkTemplate(MetaAccessProvider metaAccess, Arguments args, ResolvedJavaMethod method, Signature signature) { for (int i = 0; i < args.info.getParameterCount(); i++) { if (args.info.isConstantParameter(i)) { Kind kind = signature.getParameterKind(i); - assert checkConstantArgument(runtime, method, signature, i, args.info.names[i], args.values[i], kind); + assert checkConstantArgument(metaAccess, method, signature, i, args.info.names[i], args.values[i], kind); } else if (args.info.isVarargsParameter(i)) { assert args.values[i] instanceof Varargs; Varargs varargs = (Varargs) args.values[i]; - assert checkVarargs(runtime, method, signature, i, args.info.names[i], varargs); + assert checkVarargs(metaAccess, method, signature, i, args.info.names[i], varargs); } } return true;
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/UnsafeSubstitutions.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/UnsafeSubstitutions.java Fri Oct 11 17:21:14 2013 +0200 @@ -53,7 +53,7 @@ @MethodSubstitution(isStatic = false) public static Object getObject(@SuppressWarnings("unused") final Object thisObj, Object o, long offset) { - return UnsafeLoadNode.load(o, 0, offset, Kind.Object); + return UnsafeLoadNode.load(o, offset, Kind.Object); } @MethodSubstitution(isStatic = false) @@ -66,7 +66,7 @@ @MethodSubstitution(isStatic = false) public static void putObject(@SuppressWarnings("unused") final Object thisObj, Object o, long offset, Object x) { - UnsafeStoreNode.store(o, 0, offset, x, Kind.Object); + UnsafeStoreNode.store(o, offset, x, Kind.Object); } @MethodSubstitution(isStatic = false) @@ -85,7 +85,7 @@ @MethodSubstitution(isStatic = false) public static int getInt(@SuppressWarnings("unused") final Object thisObj, Object o, long offset) { - Integer value = UnsafeLoadNode.load(o, 0, offset, Kind.Int); + Integer value = UnsafeLoadNode.load(o, offset, Kind.Int); return value; } @@ -99,7 +99,7 @@ @MethodSubstitution(isStatic = false) public static void putInt(@SuppressWarnings("unused") final Object thisObj, Object o, long offset, int x) { - UnsafeStoreNode.store(o, 0, offset, x, Kind.Int); + UnsafeStoreNode.store(o, offset, x, Kind.Int); } @MethodSubstitution(isStatic = false) @@ -119,7 +119,7 @@ @MethodSubstitution(isStatic = false) public static boolean getBoolean(@SuppressWarnings("unused") final Object thisObj, Object o, long offset) { @JavacBug(id = 6995200) - Boolean result = UnsafeLoadNode.load(o, 0, offset, Kind.Boolean); + Boolean result = UnsafeLoadNode.load(o, offset, Kind.Boolean); return result; } @@ -133,7 +133,7 @@ @MethodSubstitution(isStatic = false) public static void putBoolean(@SuppressWarnings("unused") final Object thisObj, Object o, long offset, boolean x) { - UnsafeStoreNode.store(o, 0, offset, x, Kind.Boolean); + UnsafeStoreNode.store(o, offset, x, Kind.Boolean); } @MethodSubstitution(isStatic = false) @@ -146,7 +146,7 @@ @MethodSubstitution(isStatic = false) public static byte getByte(@SuppressWarnings("unused") final Object thisObj, Object o, long offset) { @JavacBug(id = 6995200) - Byte result = UnsafeLoadNode.load(o, 0, offset, Kind.Byte); + Byte result = UnsafeLoadNode.load(o, offset, Kind.Byte); return result; } @@ -160,7 +160,7 @@ @MethodSubstitution(isStatic = false) public static void putByte(@SuppressWarnings("unused") final Object thisObj, Object o, long offset, byte x) { - UnsafeStoreNode.store(o, 0, offset, x, Kind.Byte); + UnsafeStoreNode.store(o, offset, x, Kind.Byte); } @MethodSubstitution(isStatic = false) @@ -173,7 +173,7 @@ @MethodSubstitution(isStatic = false) public static short getShort(@SuppressWarnings("unused") final Object thisObj, Object o, long offset) { @JavacBug(id = 6995200) - Short result = UnsafeLoadNode.load(o, 0, offset, Kind.Short); + Short result = UnsafeLoadNode.load(o, offset, Kind.Short); return result; } @@ -187,7 +187,7 @@ @MethodSubstitution(isStatic = false) public static void putShort(@SuppressWarnings("unused") final Object thisObj, Object o, long offset, short x) { - UnsafeStoreNode.store(o, 0, offset, x, Kind.Short); + UnsafeStoreNode.store(o, offset, x, Kind.Short); } @MethodSubstitution(isStatic = false) @@ -200,7 +200,7 @@ @MethodSubstitution(isStatic = false) public static char getChar(@SuppressWarnings("unused") final Object thisObj, Object o, long offset) { @JavacBug(id = 6995200) - Character result = UnsafeLoadNode.load(o, 0, offset, Kind.Char); + Character result = UnsafeLoadNode.load(o, offset, Kind.Char); return result; } @@ -214,7 +214,7 @@ @MethodSubstitution(isStatic = false) public static void putChar(@SuppressWarnings("unused") final Object thisObj, Object o, long offset, char x) { - UnsafeStoreNode.store(o, 0, offset, x, Kind.Char); + UnsafeStoreNode.store(o, offset, x, Kind.Char); } @MethodSubstitution(isStatic = false) @@ -227,7 +227,7 @@ @MethodSubstitution(isStatic = false) public static long getLong(@SuppressWarnings("unused") final Object thisObj, Object o, long offset) { @JavacBug(id = 6995200) - Long result = UnsafeLoadNode.load(o, 0, offset, Kind.Long); + Long result = UnsafeLoadNode.load(o, offset, Kind.Long); return result; } @@ -241,7 +241,7 @@ @MethodSubstitution(isStatic = false) public static void putLong(@SuppressWarnings("unused") final Object thisObj, Object o, long offset, long x) { - UnsafeStoreNode.store(o, 0, offset, x, Kind.Long); + UnsafeStoreNode.store(o, offset, x, Kind.Long); } @MethodSubstitution(isStatic = false) @@ -261,7 +261,7 @@ @MethodSubstitution(isStatic = false) public static float getFloat(@SuppressWarnings("unused") final Object thisObj, Object o, long offset) { @JavacBug(id = 6995200) - Float result = UnsafeLoadNode.load(o, 0, offset, Kind.Float); + Float result = UnsafeLoadNode.load(o, offset, Kind.Float); return result; } @@ -275,7 +275,7 @@ @MethodSubstitution(isStatic = false) public static void putFloat(@SuppressWarnings("unused") final Object thisObj, Object o, long offset, float x) { - UnsafeStoreNode.store(o, 0, offset, x, Kind.Float); + UnsafeStoreNode.store(o, offset, x, Kind.Float); } @MethodSubstitution(isStatic = false) @@ -288,7 +288,7 @@ @MethodSubstitution(isStatic = false) public static double getDouble(@SuppressWarnings("unused") final Object thisObj, Object o, long offset) { @JavacBug(id = 6995200) - Double result = UnsafeLoadNode.load(o, 0, offset, Kind.Double); + Double result = UnsafeLoadNode.load(o, offset, Kind.Double); return result; } @@ -302,7 +302,7 @@ @MethodSubstitution(isStatic = false) public static void putDouble(@SuppressWarnings("unused") final Object thisObj, Object o, long offset, double x) { - UnsafeStoreNode.store(o, 0, offset, x, Kind.Double); + UnsafeStoreNode.store(o, offset, x, Kind.Double); } @MethodSubstitution(isStatic = false)
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BitCountNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BitCountNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -25,10 +25,11 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.gen.*; import com.oracle.graal.compiler.target.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.lir.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; -import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; public class BitCountNode extends FloatingNode implements LIRGenLowerable, Canonicalizable { @@ -41,7 +42,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (value.isConstant()) { long v = value.asConstant().asLong(); if (value.kind().getStackKind() == Kind.Int) {
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BitScanForwardNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BitScanForwardNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -25,10 +25,11 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.gen.*; import com.oracle.graal.compiler.target.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.lir.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; -import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; public class BitScanForwardNode extends FloatingNode implements LIRGenLowerable, Canonicalizable { @@ -41,7 +42,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (value.isConstant()) { long v = value.asConstant().asLong(); if (value.kind().getStackKind() == Kind.Int) {
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BitScanReverseNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BitScanReverseNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -25,10 +25,11 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.gen.*; import com.oracle.graal.compiler.target.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.lir.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; -import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; public class BitScanReverseNode extends FloatingNode implements LIRGenLowerable, Canonicalizable { @@ -41,7 +42,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (value.isConstant()) { long v = value.asConstant().asLong(); if (value.kind().getStackKind() == Kind.Int) {
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/LoadSnippetVarargParameterNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/LoadSnippetVarargParameterNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -22,8 +22,9 @@ */ package com.oracle.graal.replacements.nodes; +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; import com.oracle.graal.replacements.Snippet.*; @@ -43,7 +44,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (index.isConstant()) { return locals[index.asConstant().asInt()]; }
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MacroNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MacroNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -96,7 +96,7 @@ */ protected StructuredGraph lowerReplacement(final StructuredGraph replacementGraph, LoweringTool tool) { replacementGraph.setGuardsStage(graph().getGuardsStage()); - final PhaseContext c = new PhaseContext(tool.getRuntime(), tool.assumptions(), tool.getReplacements()); + final PhaseContext c = new PhaseContext(tool.getMetaAccess(), tool.getCodeCache(), tool.getConstantReflection(), tool.getLowerer(), tool.assumptions(), tool.getReplacements()); Debug.scope("LoweringReplacement", replacementGraph, new Runnable() { public void run() {
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MathIntrinsicNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MathIntrinsicNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -24,6 +24,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.spi.*; @@ -85,28 +86,15 @@ gen.setResult(this, result); } + public Constant evalConst(Constant... inputs) { + assert inputs.length == 1; + return Constant.forDouble(compute(inputs[0].asDouble(), operation())); + } + @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (x().isConstant()) { - double value = x().asConstant().asDouble(); - switch (operation()) { - case ABS: - return ConstantNode.forDouble(Math.abs(value), graph()); - case SQRT: - return ConstantNode.forDouble(Math.sqrt(value), graph()); - case LOG: - return ConstantNode.forDouble(Math.log(value), graph()); - case LOG10: - return ConstantNode.forDouble(Math.log10(value), graph()); - case SIN: - return ConstantNode.forDouble(Math.sin(value), graph()); - case COS: - return ConstantNode.forDouble(Math.cos(value), graph()); - case TAN: - return ConstantNode.forDouble(Math.tan(value), graph()); - default: - throw GraalInternalError.shouldNotReachHere(); - } + return ConstantNode.forPrimitive(evalConst(x().asConstant()), graph()); } return this; }
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/PureFunctionMacroNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/PureFunctionMacroNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -23,8 +23,9 @@ package com.oracle.graal.replacements.nodes; import com.oracle.graal.api.meta.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.spi.*; /** * This node class can be used to create {@link MacroNode}s for simple pure functions like @@ -42,15 +43,16 @@ */ protected abstract Constant evaluate(Constant param, MetaAccessProvider metaAccess); - public ValueNode canonical(CanonicalizerTool tool) { + @Override + public Node canonical(CanonicalizerTool tool) { if (usages().isEmpty()) { return null; } else { ValueNode param = arguments.get(0); if (param.isConstant()) { - Constant constant = evaluate(param.asConstant(), tool.runtime()); + Constant constant = evaluate(param.asConstant(), tool.getMetaAccess()); if (constant != null) { - return ConstantNode.forConstant(constant, tool.runtime(), graph()); + return ConstantNode.forConstant(constant, tool.getMetaAccess(), graph()); } } }
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/ReverseBytesNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/ReverseBytesNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -25,10 +25,11 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.gen.*; import com.oracle.graal.compiler.target.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.lir.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; -import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; public class ReverseBytesNode extends FloatingNode implements LIRGenLowerable, Canonicalizable { @@ -42,7 +43,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (value.isConstant()) { long v = value.asConstant().asLong(); if (kind().getStackKind() == Kind.Int) {
--- a/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/PartialEvaluationTest.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/PartialEvaluationTest.java Fri Oct 11 17:21:14 2013 +0200 @@ -36,10 +36,12 @@ import com.oracle.graal.loop.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.java.*; +import com.oracle.graal.nodes.spi.*; import com.oracle.graal.phases.*; import com.oracle.graal.phases.PhasePlan.PhasePosition; import com.oracle.graal.phases.common.*; import com.oracle.graal.phases.tiers.*; +import com.oracle.graal.phases.util.*; import com.oracle.graal.printer.*; import com.oracle.graal.truffle.*; import com.oracle.graal.truffle.printer.*; @@ -56,8 +58,10 @@ public PartialEvaluationTest() { // Make sure Truffle runtime is initialized. Assert.assertTrue(Truffle.getRuntime() instanceof GraalTruffleRuntime); - this.partialEvaluator = new PartialEvaluator(runtime, ((GraalTruffleRuntime) Truffle.getRuntime()).getReplacements(), new TruffleCache(runtime, GraphBuilderConfiguration.getDefault(), - TruffleCompilerImpl.Optimizations, ((GraalTruffleRuntime) Truffle.getRuntime()).getReplacements())); + Replacements truffleReplacements = ((GraalTruffleRuntime) Truffle.getRuntime()).getReplacements(); + Providers providers = new Providers(getMetaAccess(), getCodeCache(), getConstantReflection(), getLowerer(), truffleReplacements); + TruffleCache truffleCache = new TruffleCache(providers, GraphBuilderConfiguration.getDefault(), TruffleCompilerImpl.Optimizations); + this.partialEvaluator = new PartialEvaluator(providers, truffleCache); DebugEnvironment.initialize(System.out); } @@ -105,7 +109,7 @@ public StructuredGraph call() { StructuredGraph resultGraph = partialEvaluator.createGraph(compilable, assumptions); CanonicalizerPhase canonicalizer = new CanonicalizerPhase(canonicalizeReads); - PhaseContext context = new PhaseContext(runtime, assumptions, replacements); + PhaseContext context = new PhaseContext(getProviders(), assumptions); if (resultGraph.hasLoops()) { boolean unrolled; @@ -160,7 +164,7 @@ frameState.replaceAtUsages(null); frameState.safeDelete(); } - new CanonicalizerPhase(true).apply(graph, new PhaseContext(runtime, new Assumptions(false), replacements)); + new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), new Assumptions(false))); new DeadCodeEliminationPhase().apply(graph); } @@ -172,13 +176,13 @@ public StructuredGraph call() { Assumptions assumptions = new Assumptions(false); StructuredGraph graph = parse(methodName); - PhaseContext context = new PhaseContext(runtime, assumptions, replacements); + PhaseContext context = new PhaseContext(getProviders(), assumptions); CanonicalizerPhase canonicalizer = new CanonicalizerPhase(true); canonicalizer.apply(graph, context); // Additional inlining. final PhasePlan plan = new PhasePlan(); - GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(runtime, GraphBuilderConfiguration.getEagerDefault(), TruffleCompilerImpl.Optimizations); + GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(getMetaAccess(), GraphBuilderConfiguration.getEagerDefault(), TruffleCompilerImpl.Optimizations); plan.addPhase(PhasePosition.AFTER_PARSING, graphBuilderPhase); canonicalizer.addToPhasePlan(plan, context); plan.addPhase(PhasePosition.AFTER_PARSING, new DeadCodeEliminationPhase()); @@ -187,7 +191,8 @@ canonicalizer.apply(graph, context); new DeadCodeEliminationPhase().apply(graph); - HighTierContext highTierContext = new HighTierContext(runtime, assumptions, replacements, null, plan, OptimisticOptimizations.NONE); + HighTierContext highTierContext = new HighTierContext(getProviders(), assumptions, null, plan, + OptimisticOptimizations.NONE); InliningPhase inliningPhase = new InliningPhase(canonicalizer); inliningPhase.apply(graph, highTierContext); removeFrameStates(graph);
--- a/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/nodes/AbstractTestNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/nodes/AbstractTestNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -27,5 +27,9 @@ public abstract class AbstractTestNode extends Node { + protected AbstractTestNode() { + super(null); + } + public abstract int execute(VirtualFrame frame); }
--- a/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/nodes/RootTestNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/nodes/RootTestNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -31,6 +31,7 @@ @Child AbstractTestNode node; public RootTestNode(String name, AbstractTestNode node) { + super(null); this.name = name; this.node = node; }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/FrameWithoutBoxing.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/FrameWithoutBoxing.java Fri Oct 11 17:21:14 2013 +0200 @@ -57,7 +57,7 @@ @Override public <T extends Arguments> T getArguments(Class<T> clazz) { - return CompilerDirectives.unsafeCast(arguments, clazz); + return CompilerDirectives.unsafeCast(arguments, clazz, true); } @Override
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/GraalTruffleRuntime.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/GraalTruffleRuntime.java Fri Oct 11 17:21:14 2013 +0200 @@ -69,6 +69,11 @@ } @Override + public VirtualFrame createVirtualFrame(PackedFrame caller, Arguments arguments, FrameDescriptor frameDescriptor) { + return OptimizedCallTarget.createFrame(frameDescriptor, caller, arguments); + } + + @Override public MaterializedFrame createMaterializedFrame(Arguments arguments) { return createMaterializedFrame(arguments); }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java Fri Oct 11 17:21:14 2013 +0200 @@ -166,7 +166,7 @@ return rootNode.execute(frame); } - private static FrameWithoutBoxing createFrame(FrameDescriptor descriptor, PackedFrame caller, Arguments args) { + protected static FrameWithoutBoxing createFrame(FrameDescriptor descriptor, PackedFrame caller, Arguments args) { return new FrameWithoutBoxing(descriptor, caller, args); }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java Fri Oct 11 17:21:14 2013 +0200 @@ -35,6 +35,7 @@ import com.oracle.graal.debug.internal.*; import com.oracle.graal.graph.*; import com.oracle.graal.graph.Node; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.java.*; @@ -49,6 +50,7 @@ import com.oracle.graal.phases.common.*; import com.oracle.graal.phases.common.CanonicalizerPhase.CustomCanonicalizer; import com.oracle.graal.phases.tiers.*; +import com.oracle.graal.phases.util.*; import com.oracle.graal.truffle.nodes.asserts.*; import com.oracle.graal.truffle.nodes.frame.*; import com.oracle.graal.truffle.nodes.frame.NewFrameNode.VirtualOnlyInstanceNode; @@ -65,26 +67,24 @@ */ public class PartialEvaluator { - private final MetaAccessProvider metaAccessProvider; + private final Providers providers; private final ResolvedJavaMethod executeHelperMethod; private final CanonicalizerPhase canonicalizer; private final ResolvedJavaType[] skippedExceptionTypes; - private final Replacements replacements; private Set<Constant> constantReceivers; private final HotSpotGraphCache cache; private final TruffleCache truffleCache; - public PartialEvaluator(MetaAccessProvider metaAccessProvider, Replacements replacements, TruffleCache truffleCache) { - this.metaAccessProvider = metaAccessProvider; - CustomCanonicalizer customCanonicalizer = new PartialEvaluatorCanonicalizer(metaAccessProvider); + public PartialEvaluator(Providers providers, TruffleCache truffleCache) { + this.providers = providers; + CustomCanonicalizer customCanonicalizer = new PartialEvaluatorCanonicalizer(providers.getMetaAccess(), providers.getConstantReflection()); this.canonicalizer = new CanonicalizerPhase(!AOTCompilation.getValue(), customCanonicalizer); - this.skippedExceptionTypes = TruffleCompilerImpl.getSkippedExceptionTypes(metaAccessProvider); - this.replacements = replacements; + this.skippedExceptionTypes = TruffleCompilerImpl.getSkippedExceptionTypes(providers.getMetaAccess()); this.cache = HotSpotGraalRuntime.graalRuntime().getCache(); this.truffleCache = truffleCache; try { - executeHelperMethod = metaAccessProvider.lookupJavaMethod(OptimizedCallTarget.class.getDeclaredMethod("executeHelper", PackedFrame.class, Arguments.class)); + executeHelperMethod = providers.getMetaAccess().lookupJavaMethod(OptimizedCallTarget.class.getDeclaredMethod("executeHelper", PackedFrame.class, Arguments.class)); } catch (NoSuchMethodException ex) { throw new RuntimeException(ex); } @@ -115,18 +115,18 @@ @Override public void run() { - new GraphBuilderPhase(metaAccessProvider, config, TruffleCompilerImpl.Optimizations).apply(graph); + new GraphBuilderPhase(providers.getMetaAccess(), config, TruffleCompilerImpl.Optimizations).apply(graph); // Replace thisNode with constant. LocalNode thisNode = graph.getLocal(0); - thisNode.replaceAndDelete(ConstantNode.forObject(node, metaAccessProvider, graph)); + thisNode.replaceAndDelete(ConstantNode.forObject(node, providers.getMetaAccess(), graph)); // Canonicalize / constant propagate. - PhaseContext baseContext = new PhaseContext(metaAccessProvider, assumptions, replacements); + PhaseContext baseContext = new PhaseContext(providers, assumptions); canonicalizer.apply(graph, baseContext); // Intrinsify methods. - new ReplaceIntrinsicsPhase(replacements).apply(graph); + new ReplaceIntrinsicsPhase(providers.getReplacements()).apply(graph); NewFrameNode newFrameNode = graph.getNodes(NewFrameNode.class).first(); if (newFrameNode == null) { @@ -156,7 +156,7 @@ // Additional inlining. final PhasePlan plan = new PhasePlan(); canonicalizer.apply(graph, baseContext); - HighTierContext context = new HighTierContext(metaAccessProvider, assumptions, replacements, cache, plan, OptimisticOptimizations.NONE); + HighTierContext tierContext = new HighTierContext(providers, assumptions, cache, plan, OptimisticOptimizations.NONE); for (NeverPartOfCompilationNode neverPartOfCompilationNode : graph.getNodes(NeverPartOfCompilationNode.class)) { Throwable exception = new VerificationError(neverPartOfCompilationNode.getMessage()); @@ -164,7 +164,7 @@ } // EA frame and clean up. - new PartialEscapePhase(false, canonicalizer).apply(graph, context); + new PartialEscapePhase(false, canonicalizer).apply(graph, tierContext); new VerifyNoIntrinsicsLeftPhase().apply(graph, false); for (MaterializeFrameNode materializeNode : graph.getNodes(MaterializeFrameNode.class).snapshot()) { materializeNode.replaceAtUsages(materializeNode.getFrame()); @@ -189,7 +189,7 @@ } private void expandTree(StructuredGraph graph, Assumptions assumptions) { - PhaseContext context = new PhaseContext(metaAccessProvider, assumptions, replacements); + PhaseContext phaseContext = new PhaseContext(providers, assumptions); boolean changed; do { changed = false; @@ -203,6 +203,7 @@ ConstantNode constantNode = (ConstantNode) methodCallTargetNode.arguments().first(); constantReceivers.add(constantNode.asConstant()); } + Replacements replacements = providers.getReplacements(); StructuredGraph inlineGraph = replacements.getMethodSubstitution(methodCallTargetNode.targetMethod()); if (inlineGraph == null) { @@ -216,7 +217,7 @@ if (inlineGraph == null && !Modifier.isNative(methodCallTargetNode.targetMethod().getModifiers()) && methodCallTargetNode.targetMethod().getAnnotation(CompilerDirectives.SlowPath.class) == null) { - inlineGraph = parseGraph(methodCallTargetNode.targetMethod(), methodCallTargetNode.arguments(), assumptions, context); + inlineGraph = parseGraph(methodCallTargetNode.targetMethod(), methodCallTargetNode.arguments(), assumptions, phaseContext); } if (inlineGraph != null) { @@ -227,7 +228,7 @@ int nodeCountAfter = graph.getNodeCount(); Debug.dump(graph, "After inlining %s %+d (%d)", methodCallTargetNode.targetMethod().toString(), nodeCountAfter - nodeCountBefore, nodeCountAfter); } - canonicalizer.applyIncremental(graph, context, mark); + canonicalizer.applyIncremental(graph, phaseContext, mark); changed = true; } } @@ -239,7 +240,7 @@ } while (changed); } - private StructuredGraph parseGraph(final ResolvedJavaMethod targetMethod, final NodeInputList<ValueNode> arguments, final Assumptions assumptions, final PhaseContext context) { + private StructuredGraph parseGraph(final ResolvedJavaMethod targetMethod, final NodeInputList<ValueNode> arguments, final Assumptions assumptions, final PhaseContext phaseContext) { StructuredGraph graph = truffleCache.lookup(targetMethod, arguments, assumptions, canonicalizer); @@ -251,7 +252,7 @@ ValueNode arg = arguments.get(local.index()); if (arg.isConstant()) { Constant constant = arg.asConstant(); - ConstantNode constantNode = ConstantNode.forConstant(constant, metaAccessProvider, graphCopy); + ConstantNode constantNode = ConstantNode.forConstant(constant, phaseContext.getMetaAccess(), graphCopy); local.replaceAndDelete(constantNode); for (Node usage : constantNode.usages()) { if (usage instanceof Canonicalizable) { @@ -265,7 +266,7 @@ @Override public void run() { - canonicalizer.applyIncremental(graphCopy, context, modifiedNodes); + canonicalizer.applyIncremental(graphCopy, phaseContext, modifiedNodes); boolean unrolled; do { unrolled = false; @@ -274,7 +275,7 @@ for (LoopEx ex : innerLoopsFirst(loopsData.countedLoops())) { if (ex.counted().isConstantMaxTripCount()) { long constant = ex.counted().constantMaxTripCount(); - LoopTransformations.fullUnroll(ex, context, canonicalizer); + LoopTransformations.fullUnroll(ex, phaseContext, canonicalizer); Debug.dump(graphCopy, "After loop unrolling %d times", constant); unrolled = true; break;
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluatorCanonicalizer.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluatorCanonicalizer.java Fri Oct 11 17:21:14 2013 +0200 @@ -27,6 +27,7 @@ import sun.misc.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.graph.Node; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.java.*; import com.oracle.graal.phases.common.*; @@ -35,14 +36,16 @@ final class PartialEvaluatorCanonicalizer implements CanonicalizerPhase.CustomCanonicalizer { - private final MetaAccessProvider metaAccessProvider; + private final MetaAccessProvider metaAccess; + private final ConstantReflectionProvider constantReflection; - PartialEvaluatorCanonicalizer(MetaAccessProvider metaAccessProvider) { - this.metaAccessProvider = metaAccessProvider; + PartialEvaluatorCanonicalizer(MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection) { + this.metaAccess = metaAccess; + this.constantReflection = constantReflection; } @Override - public ValueNode canonicalize(ValueNode node) { + public Node canonicalize(Node node) { if (node instanceof LoadFieldNode) { LoadFieldNode loadFieldNode = (LoadFieldNode) node; if (!loadFieldNode.isStatic() && loadFieldNode.object().isConstant() && !loadFieldNode.object().isNullConstant()) { @@ -50,7 +53,7 @@ loadFieldNode.field().getAnnotation(CompilerDirectives.CompilationFinal.class) != null) { Constant constant = loadFieldNode.field().readValue(loadFieldNode.object().asConstant()); assert verifyFieldValue(loadFieldNode.field(), constant); - return ConstantNode.forConstant(constant, metaAccessProvider, node.graph()); + return ConstantNode.forConstant(constant, metaAccess, node.graph()); } } } else if (node instanceof LoadIndexedNode) { @@ -61,9 +64,9 @@ if (index >= 0 && index < Array.getLength(array)) { int arrayBaseOffset = Unsafe.getUnsafe().arrayBaseOffset(array.getClass()); int arrayIndexScale = Unsafe.getUnsafe().arrayIndexScale(array.getClass()); - Constant constant = metaAccessProvider.readUnsafeConstant(loadIndexedNode.elementKind(), array, arrayBaseOffset + index * arrayIndexScale, + Constant constant = constantReflection.readUnsafeConstant(loadIndexedNode.elementKind(), array, arrayBaseOffset + index * arrayIndexScale, loadIndexedNode.elementKind() == Kind.Object); - return ConstantNode.forConstant(constant, metaAccessProvider, loadIndexedNode.graph()); + return ConstantNode.forConstant(constant, metaAccess, loadIndexedNode.graph()); } } }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCache.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCache.java Fri Oct 11 17:21:14 2013 +0200 @@ -33,16 +33,17 @@ import com.oracle.graal.debug.*; import com.oracle.graal.graph.*; import com.oracle.graal.graph.Node; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.java.*; import com.oracle.graal.nodes.*; 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.type.*; import com.oracle.graal.nodes.util.*; import com.oracle.graal.phases.*; import com.oracle.graal.phases.common.*; import com.oracle.graal.phases.tiers.*; +import com.oracle.graal.phases.util.*; import com.oracle.graal.truffle.phases.*; import com.oracle.graal.virtual.phases.ea.*; import com.oracle.truffle.api.*; @@ -53,21 +54,19 @@ */ public final class TruffleCache { - private final MetaAccessProvider metaAccessProvider; + private final Providers providers; private final GraphBuilderConfiguration config; private final OptimisticOptimizations optimisticOptimizations; - private final Replacements replacements; private final HashMap<List<Object>, StructuredGraph> cache = new HashMap<>(); private final StructuredGraph markerGraph = new StructuredGraph(); private final ResolvedJavaType stringBuilderClass; - public TruffleCache(MetaAccessProvider metaAccessProvider, GraphBuilderConfiguration config, OptimisticOptimizations optimisticOptimizations, Replacements replacements) { - this.metaAccessProvider = metaAccessProvider; + public TruffleCache(Providers providers, GraphBuilderConfiguration config, OptimisticOptimizations optimisticOptimizations) { + this.providers = providers; this.config = config; this.optimisticOptimizations = optimisticOptimizations; - this.replacements = replacements; - this.stringBuilderClass = metaAccessProvider.lookupJavaType(StringBuilder.class); + this.stringBuilderClass = providers.getMetaAccess().lookupJavaType(StringBuilder.class); } @SuppressWarnings("unused") @@ -91,13 +90,13 @@ } cache.put(key, markerGraph); - resultGraph = Debug.scope("TruffleCache", new Object[]{metaAccessProvider, method}, new Callable<StructuredGraph>() { + resultGraph = Debug.scope("TruffleCache", new Object[]{providers.getMetaAccess(), method}, new Callable<StructuredGraph>() { public StructuredGraph call() { final StructuredGraph graph = new StructuredGraph(method); - PhaseContext context = new PhaseContext(metaAccessProvider, new Assumptions(false), replacements); - new GraphBuilderPhase(metaAccessProvider, config, optimisticOptimizations).apply(graph); + PhaseContext phaseContext = new PhaseContext(providers, new Assumptions(false)); + new GraphBuilderPhase(phaseContext.getMetaAccess(), config, optimisticOptimizations).apply(graph); for (LocalNode l : graph.getNodes(LocalNode.class)) { if (l.kind() == Kind.Object) { @@ -107,7 +106,7 @@ } // Intrinsify methods. - new ReplaceIntrinsicsPhase(replacements).apply(graph); + new ReplaceIntrinsicsPhase(providers.getReplacements()).apply(graph); // Convert deopt to guards. new ConvertDeoptimizeToGuardPhase().apply(graph); @@ -118,14 +117,14 @@ int mark = 0; while (true) { - partialEscapePhase.apply(graph, context); + partialEscapePhase.apply(graph, phaseContext); // Conditional elimination. - ConditionalEliminationPhase conditionalEliminationPhase = new ConditionalEliminationPhase(metaAccessProvider); + ConditionalEliminationPhase conditionalEliminationPhase = new ConditionalEliminationPhase(phaseContext.getMetaAccess()); conditionalEliminationPhase.apply(graph); // Canonicalize / constant propagate. - canonicalizerPhase.apply(graph, context); + canonicalizerPhase.apply(graph, phaseContext); boolean inliningProgress = false; for (MethodCallTargetNode methodCallTarget : graph.getNodes(MethodCallTargetNode.class)) { @@ -135,7 +134,7 @@ for (Node newNode : graph.getNewNodes(mark)) { if (newNode instanceof MethodCallTargetNode) { MethodCallTargetNode methodCallTargetNode = (MethodCallTargetNode) newNode; - Class<? extends FixedWithNextNode> macroSubstitution = replacements.getMacroSubstitution(methodCallTargetNode.targetMethod()); + Class<? extends FixedWithNextNode> macroSubstitution = providers.getReplacements().getMacroSubstitution(methodCallTargetNode.targetMethod()); if (macroSubstitution != null) { InliningUtil.inlineMacroNode(methodCallTargetNode.invoke(), methodCallTargetNode.targetMethod(), methodCallTargetNode.graph(), macroSubstitution); } else { @@ -165,13 +164,15 @@ } } } - canonicalizerPhase.applyIncremental(graph, context, canonicalizerUsages); + canonicalizerPhase.applyIncremental(graph, phaseContext, canonicalizerUsages); } } // Convert deopt to guards. new ConvertDeoptimizeToGuardPhase().apply(graph); + new EarlyReadEliminationPhase(canonicalizerPhase).apply(graph, phaseContext); + if (!inliningProgress) { break; } @@ -188,7 +189,7 @@ } private void expandInvoke(MethodCallTargetNode methodCallTargetNode) { - StructuredGraph inlineGraph = replacements.getMethodSubstitution(methodCallTargetNode.targetMethod()); + StructuredGraph inlineGraph = providers.getReplacements().getMethodSubstitution(methodCallTargetNode.targetMethod()); if (inlineGraph == null) { inlineGraph = TruffleCache.this.lookup(methodCallTargetNode.targetMethod(), methodCallTargetNode.arguments(), null, null); } @@ -203,8 +204,8 @@ private boolean tryCutOffRuntimeExceptions(MethodCallTargetNode methodCallTargetNode) { if (methodCallTargetNode.targetMethod().isConstructor()) { - ResolvedJavaType runtimeException = metaAccessProvider.lookupJavaType(RuntimeException.class); - ResolvedJavaType controlFlowException = metaAccessProvider.lookupJavaType(ControlFlowException.class); + ResolvedJavaType runtimeException = providers.getMetaAccess().lookupJavaType(RuntimeException.class); + ResolvedJavaType controlFlowException = providers.getMetaAccess().lookupJavaType(ControlFlowException.class); ResolvedJavaType exceptionType = Objects.requireNonNull(ObjectStamp.typeOrNull(methodCallTargetNode.receiver().stamp())); if (runtimeException.isAssignableFrom(methodCallTargetNode.targetMethod().getDeclaringClass()) && !controlFlowException.isAssignableFrom(exceptionType)) { DeoptimizeNode deoptNode = methodCallTargetNode.graph().add(new DeoptimizeNode(DeoptimizationAction.InvalidateRecompile, DeoptimizationReason.UnreachedCode));
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java Fri Oct 11 17:21:14 2013 +0200 @@ -43,6 +43,7 @@ import com.oracle.graal.phases.*; import com.oracle.graal.phases.PhasePlan.PhasePosition; import com.oracle.graal.phases.tiers.*; +import com.oracle.graal.phases.util.*; import com.oracle.graal.printer.*; import com.oracle.graal.truffle.nodes.*; import com.oracle.truffle.api.*; @@ -53,11 +54,9 @@ */ public class TruffleCompilerImpl implements TruffleCompiler { - private final GraalCodeCacheProvider runtime; + private final Providers providers; private final Suites suites; private final PartialEvaluator partialEvaluator; - private final MetaAccessProvider metaAccessProvider; - private final Replacements replacements; private final Backend backend; private final ResolvedJavaType[] skippedExceptionTypes; private final HotSpotGraalRuntime graalRuntime; @@ -69,29 +68,29 @@ OptimisticOptimizations.Optimization.RemoveNeverExecutedCode, OptimisticOptimizations.Optimization.UseTypeCheckedInlining, OptimisticOptimizations.Optimization.UseTypeCheckHints); public TruffleCompilerImpl() { - this.runtime = Graal.getRequiredCapability(GraalCodeCacheProvider.class); + this.providers = new Providers(Graal.getRequiredCapability(MetaAccessProvider.class), Graal.getRequiredCapability(CodeCacheProvider.class), + Graal.getRequiredCapability(ConstantReflectionProvider.class), Graal.getRequiredCapability(LoweringProvider.class), + ((GraalTruffleRuntime) Truffle.getRuntime()).getReplacements()); this.suites = Graal.getRequiredCapability(SuitesProvider.class).createSuites(); - this.metaAccessProvider = Graal.getRequiredCapability(MetaAccessProvider.class); this.backend = Graal.getRequiredCapability(Backend.class); - this.replacements = ((GraalTruffleRuntime) Truffle.getRuntime()).getReplacements(); this.graalRuntime = HotSpotGraalRuntime.graalRuntime(); - this.skippedExceptionTypes = getSkippedExceptionTypes(metaAccessProvider); + this.skippedExceptionTypes = getSkippedExceptionTypes(providers.getMetaAccess()); final GraphBuilderConfiguration config = GraphBuilderConfiguration.getEagerDefault(); config.setSkippedExceptionTypes(skippedExceptionTypes); - this.truffleCache = new TruffleCache(this.runtime, config, TruffleCompilerImpl.Optimizations, this.replacements); + this.truffleCache = new TruffleCache(providers, config, TruffleCompilerImpl.Optimizations); - this.partialEvaluator = new PartialEvaluator(metaAccessProvider, replacements, truffleCache); + this.partialEvaluator = new PartialEvaluator(providers, truffleCache); if (Debug.isEnabled()) { DebugEnvironment.initialize(System.out); } } - static ResolvedJavaType[] getSkippedExceptionTypes(MetaAccessProvider metaAccessProvider) { + static ResolvedJavaType[] getSkippedExceptionTypes(MetaAccessProvider metaAccess) { ResolvedJavaType[] skippedExceptionTypes = new ResolvedJavaType[SKIPPED_EXCEPTION_CLASSES.length]; for (int i = 0; i < SKIPPED_EXCEPTION_CLASSES.length; i++) { - skippedExceptionTypes[i] = metaAccessProvider.lookupJavaType(SKIPPED_EXCEPTION_CLASSES[i]); + skippedExceptionTypes[i] = metaAccess.lookupJavaType(SKIPPED_EXCEPTION_CLASSES[i]); } return skippedExceptionTypes; } @@ -150,9 +149,10 @@ @Override public CompilationResult call() { try (TimerCloseable a = CompilationTime.start()) { - CallingConvention cc = getCallingConvention(runtime, Type.JavaCallee, graph.method(), false); - return GraalCompiler.compileGraph(graph, cc, graph.method(), runtime, replacements, backend, runtime.getTarget(), null, plan, OptimisticOptimizations.ALL, new SpeculationLog(), - suites, new CompilationResult()); + CodeCacheProvider codeCache = providers.getCodeCache(); + CallingConvention cc = getCallingConvention(codeCache, Type.JavaCallee, graph.method(), false); + return GraalCompiler.compileGraph(graph, cc, graph.method(), providers, backend, codeCache.getTarget(), null, plan, OptimisticOptimizations.ALL, new SpeculationLog(), suites, + new CompilationResult()); } } }); @@ -178,7 +178,7 @@ @Override public InstalledCode call() throws Exception { try (TimerCloseable a = CodeInstallationTime.start()) { - InstalledCode installedCode = runtime.addMethod(graph.method(), result); + InstalledCode installedCode = providers.getCodeCache().addMethod(graph.method(), result); if (installedCode != null) { Debug.dump(new Object[]{result, installedCode}, "After code installation"); } @@ -192,7 +192,7 @@ } if (Debug.isLogEnabled()) { - Debug.log(runtime.disassemble(result, compiledMethod)); + Debug.log(providers.getCodeCache().disassemble(result, compiledMethod)); } if (compilable != null) { compilable.codeSize = result.getTargetCodeSize(); @@ -202,7 +202,7 @@ private PhasePlan createPhasePlan(final GraphBuilderConfiguration config) { final PhasePlan phasePlan = new PhasePlan(); - GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(metaAccessProvider, config, TruffleCompilerImpl.Optimizations); + GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(providers.getMetaAccess(), config, TruffleCompilerImpl.Optimizations); phasePlan.addPhase(PhasePosition.AFTER_PARSING, graphBuilderPhase); return phasePlan; }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerOptions.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerOptions.java Fri Oct 11 17:21:14 2013 +0200 @@ -34,7 +34,7 @@ /** * Instructs the Truffle Compiler to compile call targets only if their name contains at least one element of a comma-separated list of includes. * Excludes are prefixed with a tilde (~). - * + * * The format in EBNF: * <pre> * CompileOnly = Element, { ',', Element } ; @@ -56,10 +56,6 @@ @Option(help = "") public static final OptionValue<Boolean> TruffleFunctionInlining = new OptionValue<>(true); @Option(help = "") - public static final OptionValue<Integer> TruffleConstantUnrollLimit = new OptionValue<>(32); - @Option(help = "") - public static final OptionValue<Integer> TruffleOperationCacheMaxNodes = new OptionValue<>(350); - @Option(help = "") public static final OptionValue<Integer> TruffleGraphMaxNodes = new OptionValue<>(20000); @Option(help = "") public static final OptionValue<Integer> TruffleInliningMaxRecursiveDepth = new OptionValue<>(2); @@ -83,8 +79,6 @@ @Option(help = "") public static final OptionValue<Boolean> TraceTruffleCacheDetails = new OptionValue<>(false); @Option(help = "") - public static final OptionValue<Boolean> TraceTrufflePerformanceWarnings = new OptionValue<>(false); - @Option(help = "") public static final OptionValue<Boolean> TruffleInlinePrinter = new OptionValue<>(false); @Option(help = "") public static final OptionValue<Boolean> TraceTruffleCompilationExceptions = new OptionValue<>(true);
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleReplacements.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleReplacements.java Fri Oct 11 17:21:14 2013 +0200 @@ -41,16 +41,20 @@ private final Replacements graalReplacements; - private TruffleReplacements(MetaAccessProvider runtime, Assumptions assumptions, TargetDescription target, Replacements graalReplacements) { - super(runtime, assumptions, target); + private TruffleReplacements(MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection, CodeCacheProvider codeCache, LoweringProvider lowerer, Assumptions assumptions, + TargetDescription target, Replacements graalReplacements) { + super(metaAccess, constantReflection, codeCache, lowerer, assumptions, target); this.graalReplacements = graalReplacements; } static Replacements makeInstance() { - MetaAccessProvider metaAccessProvider = Graal.getRequiredCapability(MetaAccessProvider.class); + MetaAccessProvider metaAccess = Graal.getRequiredCapability(MetaAccessProvider.class); + CodeCacheProvider codeCache = Graal.getRequiredCapability(CodeCacheProvider.class); + ConstantReflectionProvider constantReflection = Graal.getRequiredCapability(ConstantReflectionProvider.class); + LoweringProvider lowerer = Graal.getRequiredCapability(LoweringProvider.class); TargetDescription targetDescription = Graal.getRequiredCapability(CodeCacheProvider.class).getTarget(); Replacements graalReplacements = Graal.getRequiredCapability(Replacements.class); - Replacements truffleReplacements = new TruffleReplacements(metaAccessProvider, graalReplacements.getAssumptions(), targetDescription, graalReplacements); + Replacements truffleReplacements = new TruffleReplacements(metaAccess, constantReflection, codeCache, lowerer, graalReplacements.getAssumptions(), targetDescription, graalReplacements); truffleReplacements.registerSubstitutions(CompilerAssertsSubstitutions.class); truffleReplacements.registerSubstitutions(CompilerDirectivesSubstitutions.class);
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/AssumptionNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/AssumptionNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -22,10 +22,9 @@ */ package com.oracle.graal.truffle.nodes; -import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.spi.*; import com.oracle.graal.replacements.nodes.*; import com.oracle.graal.truffle.*; @@ -40,6 +39,7 @@ return arguments.first(); } + @Override public void simplify(SimplifierTool tool) { ValueNode assumption = getAssumption(); if (tool.assumptions() != null && assumption.isConstant()) {
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/BailoutNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/BailoutNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -23,8 +23,9 @@ package com.oracle.graal.truffle.nodes; import com.oracle.graal.api.code.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.spi.*; import com.oracle.graal.replacements.nodes.*; public class BailoutNode extends MacroNode implements Canonicalizable { @@ -35,7 +36,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { ValueNode arg = arguments.get(0); String message = ""; if (arg.isConstant()) {
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/LoadIndexedFinalNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/LoadIndexedFinalNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -27,6 +27,8 @@ import sun.misc.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.spi.*; @@ -49,15 +51,15 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (array().isConstant() && !array().isNullConstant() && index().isConstant()) { Object array = array().asConstant().asObject(); long index = index().asConstant().asLong(); if (index >= 0 && index < Array.getLength(array)) { int arrayBaseOffset = Unsafe.getUnsafe().arrayBaseOffset(array.getClass()); int arrayIndexScale = Unsafe.getUnsafe().arrayIndexScale(array.getClass()); - Constant constant = tool.runtime().readUnsafeConstant(elementKind(), array, arrayBaseOffset + index * arrayIndexScale, elementKind() == Kind.Object); - return ConstantNode.forConstant(constant, tool.runtime(), graph()); + Constant constant = tool.getConstantReflection().readUnsafeConstant(elementKind(), array().asConstant(), arrayBaseOffset + index * arrayIndexScale, elementKind() == Kind.Object); + return ConstantNode.forConstant(constant, tool.getMetaAccess(), graph()); } } return this;
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerAddExactNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerAddExactNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -23,6 +23,8 @@ package com.oracle.graal.truffle.nodes.arithmetic; import com.oracle.graal.api.meta.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.spi.*; @@ -47,7 +49,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (x().isConstant() && !y().isConstant()) { return graph().unique(new IntegerAddExactNode(y(), x())); }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerExactArithmeticSplitNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerExactArithmeticSplitNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -22,7 +22,6 @@ */ package com.oracle.graal.truffle.nodes.arithmetic; -import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.gen.*; import com.oracle.graal.compiler.target.*;
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerMulExactNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerMulExactNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -23,6 +23,8 @@ package com.oracle.graal.truffle.nodes.arithmetic; import com.oracle.graal.api.meta.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.spi.*; @@ -40,7 +42,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (x().isConstant() && !y().isConstant()) { return graph().unique(new IntegerMulExactNode(y(), x())); }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerSubExactNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerSubExactNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -23,6 +23,8 @@ package com.oracle.graal.truffle.nodes.arithmetic; import com.oracle.graal.api.meta.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.spi.*; @@ -47,7 +49,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (x() == y()) { return ConstantNode.forIntegerKind(kind(), 0, graph()); }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/asserts/CompilationConstantNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/asserts/CompilationConstantNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -22,8 +22,9 @@ */ package com.oracle.graal.truffle.nodes.asserts; +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.spi.*; public class CompilationConstantNode extends NeverPartOfCompilationNode implements Canonicalizable { @@ -33,7 +34,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (arguments.get(0).isConstant()) { return arguments.get(0); }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/FrameAccessNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/FrameAccessNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -25,8 +25,8 @@ import java.lang.reflect.*; import java.util.*; -import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.java.*; @@ -95,11 +95,11 @@ } } - protected final ValueNode getSlotOffset(int scale, MetaAccessProvider metaAccessProvider) { + protected final ValueNode getSlotOffset(int scale, MetaAccessProvider metaAccess) { if (isConstantFrameSlot()) { return ConstantNode.forInt(getSlotIndex() * scale, graph()); } else { - LoadFieldNode loadFrameSlotIndex = graph().add(new LoadFieldNode(getSlot(), metaAccessProvider.lookupJavaField(getFrameSlotIndexField()))); + LoadFieldNode loadFrameSlotIndex = graph().add(new LoadFieldNode(getSlot(), metaAccess.lookupJavaField(getFrameSlotIndexField()))); graph().addBeforeFixed(this, loadFrameSlotIndex); return scale == 1 ? loadFrameSlotIndex : IntegerArithmeticNode.mul(loadFrameSlotIndex, ConstantNode.forInt(scale, graph())); }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/FrameGetNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/FrameGetNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -27,6 +27,7 @@ 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.*; import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.spi.*; @@ -78,14 +79,15 @@ structuredGraph.addBeforeFixed(this, loadFieldNode); FixedWithNextNode loadNode; if (isTagAccess()) { - ValueNode slotIndex = getSlotOffset(1, tool.getRuntime()); + ValueNode slotIndex = getSlotOffset(1, tool.getMetaAccess()); loadNode = graph().add(new LoadIndexedNode(loadFieldNode, slotIndex, getSlotKind())); } else if (!getSlotKind().isPrimitive()) { - ValueNode slotIndex = getSlotOffset(1, tool.getRuntime()); + ValueNode slotIndex = getSlotOffset(1, tool.getMetaAccess()); loadNode = graph().add(new LoadIndexedNode(loadFieldNode, slotIndex, Kind.Object)); } else { - ValueNode slotOffset = getSlotOffset(Unsafe.ARRAY_LONG_INDEX_SCALE, tool.getRuntime()); - loadNode = graph().add(new UnsafeLoadNode(loadFieldNode, Unsafe.ARRAY_LONG_BASE_OFFSET, slotOffset, getSlotKind())); + ValueNode slotOffset = graph().unique( + new IntegerAddNode(Kind.Long, getSlotOffset(Unsafe.ARRAY_LONG_INDEX_SCALE, tool.getMetaAccess()), ConstantNode.forLong(Unsafe.ARRAY_LONG_BASE_OFFSET, graph()))); + loadNode = graph().add(new UnsafeLoadNode(loadFieldNode, slotOffset, getSlotKind())); } structuredGraph.replaceFixedWithFixed(this, loadNode); loadFieldNode.lower(tool);
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/FrameSetNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/FrameSetNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -77,7 +77,7 @@ LoadFieldNode loadFieldNode = graph().add(new LoadFieldNode(getFrame(), field)); structuredGraph.addBeforeFixed(this, loadFieldNode); FixedWithNextNode storeNode; - ValueNode slotIndex = getSlotOffset(1, tool.getRuntime()); + ValueNode slotIndex = getSlotOffset(1, tool.getMetaAccess()); if (isTagAccess()) { storeNode = graph().add(new StoreIndexedNode(loadFieldNode, slotIndex, getSlotKind(), value)); } else if (!getSlotKind().isPrimitive()) {
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/NewFrameNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/NewFrameNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -27,6 +27,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.api.runtime.*; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.spi.*; @@ -205,7 +206,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (usages().isEmpty()) { return null; } else {
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomTypeCheckMacroNode.java Fri Oct 11 17:14:35 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,57 +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.truffle.nodes.typesystem; - -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.calc.*; -import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.truffle.nodes.asserts.*; -import com.oracle.truffle.api.*; - -/** - * Macro node for method {@link CompilerDirectives#customTypeCheck(boolean, Object, Object)}. - */ -public class CustomTypeCheckMacroNode extends NeverPartOfCompilationNode implements Canonicalizable { - - private static final int ARGUMENT_COUNT = 3; - private static final int CONDITION_ARGUMENT_INDEX = 0; - private static final int OBJECT_ARGUMENT_INDEX = 1; - private static final int CUSTOM_TYPE_ARGUMENT_INDEX = 2; - - public CustomTypeCheckMacroNode(Invoke invoke) { - super(invoke, "The custom type parameter could not be reduced to a compile time constant."); - assert arguments.size() == ARGUMENT_COUNT; - } - - @Override - public ValueNode canonical(CanonicalizerTool tool) { - ValueNode customTypeArgument = arguments.get(CUSTOM_TYPE_ARGUMENT_INDEX); - if (customTypeArgument.isConstant()) { - Object typeToken = customTypeArgument.asConstant().asObject(); - ValueNode conditionArgument = arguments.get(CONDITION_ARGUMENT_INDEX); - ValueNode objectArgument = arguments.get(OBJECT_ARGUMENT_INDEX); - return graph().unique(new ConditionalNode(graph().unique(new CustomTypeCheckNode(conditionArgument, objectArgument, typeToken)))); - } - return this; - } -}
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomTypeCheckNode.java Fri Oct 11 17:14:35 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,70 +0,0 @@ -/* - * Copyright (c) 2012, 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.truffle.nodes.typesystem; - -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.calc.*; -import com.oracle.graal.nodes.spi.*; - -public final class CustomTypeCheckNode extends LogicNode implements Lowerable, Virtualizable, com.oracle.graal.graph.IterableNodeType { - - @Input private ValueNode condition; - @Input private ValueNode object; - private final Object customType; - - public CustomTypeCheckNode(ValueNode condition, ValueNode object, Object customType) { - this.condition = condition; - this.object = object; - this.customType = customType; - } - - public ValueNode getObject() { - return object; - } - - public ValueNode getCondition() { - return condition; - } - - public Object getCustomType() { - return customType; - } - - public void lower(LoweringTool tool) { - if (graph().getGuardsStage() == StructuredGraph.GuardsStage.FLOATING_GUARDS) { - this.replaceAtUsages(graph().unique(new IntegerEqualsNode(condition, ConstantNode.forInt(1, graph())))); - this.safeDelete(); - } - } - - public void virtualize(VirtualizerTool tool) { - if (getObject() != null) { - State objectState = tool.getObjectState(getObject()); - if (objectState != null && objectState.getState() == EscapeState.Virtual) { - // The object is escape analyzed => cut the connection. - this.updateUsages(this.object, null); - this.object = null; - } - } - } -}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeLoadMacroNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -0,0 +1,70 @@ +/* + * 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.truffle.nodes.typesystem; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.calc.*; +import com.oracle.graal.nodes.extended.*; +import com.oracle.graal.truffle.nodes.asserts.*; +import com.oracle.truffle.api.*; + +/** + * Macro node for method {@link CompilerDirectives#unsafeCast(Object, Class, boolean)}. + */ +public class CustomizedUnsafeLoadMacroNode extends NeverPartOfCompilationNode implements Canonicalizable { + + private static final int ARGUMENT_COUNT = 4; + private static final int OBJECT_ARGUMENT_INDEX = 0; + private static final int OFFSET_ARGUMENT_INDEX = 1; + private static final int CONDITION_ARGUMENT_INDEX = 2; + private static final int LOCATION_ARGUMENT_INDEX = 3; + + public CustomizedUnsafeLoadMacroNode(Invoke invoke) { + super(invoke, "The location argument could not be resolved to a constant."); + assert arguments.size() == ARGUMENT_COUNT; + } + + @Override + public Node canonical(CanonicalizerTool tool) { + ValueNode locationArgument = arguments.get(LOCATION_ARGUMENT_INDEX); + if (locationArgument.isConstant()) { + ValueNode objectArgument = arguments.get(OBJECT_ARGUMENT_INDEX); + ValueNode offsetArgument = arguments.get(OFFSET_ARGUMENT_INDEX); + ValueNode conditionArgument = arguments.get(CONDITION_ARGUMENT_INDEX); + Object locationIdentityObject = locationArgument.asConstant().asObject(); + LocationIdentity locationIdentity; + if (locationIdentityObject == null) { + locationIdentity = LocationIdentity.ANY_LOCATION; + } else { + locationIdentity = ObjectLocationIdentity.create(locationIdentityObject); + } + return graph().add( + new UnsafeLoadNode(objectArgument, offsetArgument, this.stamp().kind(), locationIdentity, CompareNode.createCompareNode(Condition.EQ, conditionArgument, + ConstantNode.forBoolean(true, graph())))); + } + return this; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeStoreMacroNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -0,0 +1,70 @@ +/* + * 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.truffle.nodes.typesystem; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.extended.*; +import com.oracle.graal.truffle.nodes.asserts.*; +import com.oracle.truffle.api.*; + +/** + * Macro node for method {@link CompilerDirectives#unsafeCast(Object, Class, boolean)}. + */ +public class CustomizedUnsafeStoreMacroNode extends NeverPartOfCompilationNode implements Canonicalizable { + + private static final int ARGUMENT_COUNT = 4; + private static final int OBJECT_ARGUMENT_INDEX = 0; + private static final int OFFSET_ARGUMENT_INDEX = 1; + private static final int VALUE_ARGUMENT_INDEX = 2; + private static final int LOCATION_ARGUMENT_INDEX = 3; + + public CustomizedUnsafeStoreMacroNode(Invoke invoke) { + super(invoke, "The location argument could not be resolved to a constant."); + assert arguments.size() == ARGUMENT_COUNT; + } + + @Override + public Node canonical(CanonicalizerTool tool) { + ValueNode locationArgument = arguments.get(LOCATION_ARGUMENT_INDEX); + if (locationArgument.isConstant()) { + ValueNode objectArgument = arguments.get(OBJECT_ARGUMENT_INDEX); + ValueNode offsetArgument = arguments.get(OFFSET_ARGUMENT_INDEX); + ValueNode valueArgument = arguments.get(VALUE_ARGUMENT_INDEX); + Object locationIdentityObject = locationArgument.asConstant().asObject(); + LocationIdentity locationIdentity; + if (locationIdentityObject == null) { + locationIdentity = LocationIdentity.ANY_LOCATION; + } else { + locationIdentity = ObjectLocationIdentity.create(locationIdentityObject); + } + + UnsafeStoreNode unsafeStoreNode = graph().add(new UnsafeStoreNode(objectArgument, offsetArgument, valueArgument, valueArgument.kind(), locationIdentity)); + unsafeStoreNode.setStateAfter(this.stateAfter()); + return unsafeStoreNode; + } + return this; + } +}
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/TypeCastMacroNode.java Fri Oct 11 17:14:35 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.truffle.nodes.typesystem; - -import com.oracle.graal.api.meta.*; -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.truffle.nodes.asserts.*; -import com.oracle.truffle.api.*; - -/** - * Macro node for method {@link CompilerDirectives#unsafeCast(Object, Class)} and - * {@link CompilerDirectives#unsafeCast(Object, Class, Object, Object)}. - */ -public class TypeCastMacroNode extends NeverPartOfCompilationNode implements Canonicalizable { - - private static final int ARGUMENT_COUNT = 4; - private static final int OBJECT_ARGUMENT_INDEX = 0; - private static final int CLASS_ARGUMENT_INDEX = 1; - private static final int RECEIVER_ARGUMENT_INDEX = 2; - private static final int CUSTOM_TYPE_ARGUMENT_INDEX = 3; - - public TypeCastMacroNode(Invoke invoke) { - super(invoke, "The class of the unsafe cast could not be reduced to a compile time constant."); - assert arguments.size() == ARGUMENT_COUNT; - } - - @Override - public ValueNode canonical(CanonicalizerTool tool) { - ValueNode classArgument = arguments.get(CLASS_ARGUMENT_INDEX); - ValueNode customTypeArgument = arguments.get(CUSTOM_TYPE_ARGUMENT_INDEX); - if (classArgument.isConstant() && customTypeArgument.isConstant()) { - Class c = (Class) classArgument.asConstant().asObject(); - ResolvedJavaType lookupJavaType = tool.runtime().lookupJavaType(c); - ValueNode objectArgument = arguments.get(OBJECT_ARGUMENT_INDEX); - ValueNode receiverArgument = arguments.get(RECEIVER_ARGUMENT_INDEX); - Object customType = customTypeArgument.asConstant().asObject(); - return graph().add(new TypeCastNode(objectArgument, lookupJavaType, receiverArgument, customType)); - } - return this; - } -}
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/TypeCastNode.java Fri Oct 11 17:14:35 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,82 +0,0 @@ -/* - * Copyright (c) 2012, 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.truffle.nodes.typesystem; - -import com.oracle.graal.api.meta.*; -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.extended.*; -import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.nodes.type.*; - -public final class TypeCastNode extends FixedWithNextNode implements Lowerable, com.oracle.graal.graph.IterableNodeType, ValueProxy, Virtualizable { - - @Input private ValueNode receiver; - @Input private ValueNode object; - private final Object customType; - private final ResolvedJavaType castTarget; - - public TypeCastNode(ValueNode object, ResolvedJavaType castTarget, ValueNode receiver, Object customType) { - super(StampFactory.declaredNonNull(castTarget)); - this.receiver = receiver; - this.object = object; - this.customType = customType; - this.castTarget = castTarget; - } - - public ValueNode getObject() { - return object; - } - - public ValueNode getReceiver() { - return receiver; - } - - public ResolvedJavaType getCastTarget() { - return castTarget; - } - - public Object getCustomType() { - return customType; - } - - public void lower(LoweringTool tool) { - if (graph().getGuardsStage() == StructuredGraph.GuardsStage.FLOATING_GUARDS) { - ValueAnchorNode valueAnchorNode = graph().add(new ValueAnchorNode(null)); - PiNode piCast = graph().unique(new PiNode(object, this.stamp(), valueAnchorNode)); - this.replaceAtUsages(piCast); - graph().replaceFixedWithFixed(this, valueAnchorNode); - } - } - - public ValueNode getOriginalValue() { - return object; - } - - @Override - public void virtualize(VirtualizerTool tool) { - State state = tool.getObjectState(object); - if (state != null && state.getState() == EscapeState.Virtual) { - tool.replaceWithVirtual(state.getVirtualObject()); - } - } -}
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/UnsafeCustomizationMacroNode.java Fri Oct 11 17:14:35 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,57 +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.truffle.nodes.typesystem; - -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.truffle.nodes.asserts.*; -import com.oracle.truffle.api.*; - -/** - * Macro node for method {@link CompilerDirectives#unsafeCustomization(Object, Object, Object)}. - */ -public class UnsafeCustomizationMacroNode extends NeverPartOfCompilationNode implements Canonicalizable { - - private static final int ARGUMENT_COUNT = 3; - private static final int RECEIVER_ARGUMENT_INDEX = 0; - private static final int CUSTOM_TYPE_ARGUMENT_INDEX = 1; - private static final int LOCATION_IDENTITY_ARGUMENT_INDEX = 2; - - public UnsafeCustomizationMacroNode(Invoke invoke) { - super(invoke, "The custom type parameter and/or the location identity could not be reduced to a compile time constant."); - assert arguments.size() == ARGUMENT_COUNT; - } - - @Override - public ValueNode canonical(CanonicalizerTool tool) { - ValueNode customTypeArgument = this.arguments.get(CUSTOM_TYPE_ARGUMENT_INDEX); - ValueNode locationIdentityArgument = this.arguments.get(LOCATION_IDENTITY_ARGUMENT_INDEX); - if (customTypeArgument.isConstant() && locationIdentityArgument.isConstant()) { - Object customType = customTypeArgument.asConstant().asObject(); - Object locationIdentity = locationIdentityArgument.asConstant().asObject(); - ValueNode receiverArgument = this.arguments.get(RECEIVER_ARGUMENT_INDEX); - return graph().unique(new UnsafeCustomizationNode(receiverArgument, customType, locationIdentity)); - } - return this; - } -}
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/UnsafeCustomizationNode.java Fri Oct 11 17:14:35 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2012, 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.truffle.nodes.typesystem; - -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.calc.*; -import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.nodes.type.*; - -public final class UnsafeCustomizationNode extends FloatingNode implements LIRLowerable, com.oracle.graal.graph.IterableNodeType { - - @Input private ValueNode receiver; - private final Object customType; - private final Object locationIdentity; - - public UnsafeCustomizationNode(ValueNode receiver, Object customType, Object locationIdentity) { - super(StampFactory.object()); - this.receiver = receiver; - this.customType = customType; - this.locationIdentity = locationIdentity; - } - - public ValueNode getReceiver() { - return receiver; - } - - public Object getCustomType() { - return customType; - } - - public Object getLocationIdentity() { - return locationIdentity; - } - - public void generate(LIRGeneratorTool generator) { - generator.setResult(this, generator.operand(receiver)); - } -}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/UnsafeTypeCastMacroNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -0,0 +1,68 @@ +/* + * 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.truffle.nodes.typesystem; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.calc.*; +import com.oracle.graal.nodes.extended.*; +import com.oracle.graal.nodes.type.*; +import com.oracle.graal.truffle.nodes.asserts.*; +import com.oracle.truffle.api.*; + +/** + * Macro node for method {@link CompilerDirectives#unsafeCast(Object, Class, boolean)}. + */ +public class UnsafeTypeCastMacroNode extends NeverPartOfCompilationNode implements Canonicalizable { + + private static final int ARGUMENT_COUNT = 3; + private static final int OBJECT_ARGUMENT_INDEX = 0; + private static final int CLASS_ARGUMENT_INDEX = 1; + private static final int CONDITION_ARGUMENT_INDEX = 2; + + public UnsafeTypeCastMacroNode(Invoke invoke) { + super(invoke, "The class of the unsafe cast could not be reduced to a compile time constant."); + assert arguments.size() == ARGUMENT_COUNT; + } + + @Override + public Node canonical(CanonicalizerTool tool) { + ValueNode classArgument = arguments.get(CLASS_ARGUMENT_INDEX); + if (classArgument.isConstant()) { + ValueNode objectArgument = arguments.get(OBJECT_ARGUMENT_INDEX); + ValueNode conditionArgument = arguments.get(CONDITION_ARGUMENT_INDEX); + Class c = (Class) classArgument.asConstant().asObject(); + if (c == null) { + return objectArgument; + } + ResolvedJavaType lookupJavaType = tool.getMetaAccess().lookupJavaType(c); + ConditionAnchorNode valueAnchorNode = graph().add(new ConditionAnchorNode(CompareNode.createCompareNode(Condition.EQ, conditionArgument, ConstantNode.forBoolean(true, graph())))); + UnsafeCastNode piCast = graph().unique(new UnsafeCastNode(objectArgument, StampFactory.declaredNonNull(lookupJavaType), valueAnchorNode)); + this.replaceAtUsages(piCast); + return valueAnchorNode; + } + return this; + } +}
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/phases/ReplaceLoadFinalPhase.java Fri Oct 11 17:14:35 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,55 +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.truffle.phases; - -import java.lang.reflect.*; - -import com.oracle.graal.api.meta.*; -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.java.*; -import com.oracle.graal.phases.*; -import com.oracle.graal.truffle.nodes.*; -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.nodes.Node.Children; - -public class ReplaceLoadFinalPhase extends Phase { - - @Override - protected void run(StructuredGraph graph) { - for (LoadIndexedNode loadIndexedNode : graph.getNodes(LoadIndexedNode.class)) { - if (loadIndexedNode.array() instanceof LoadFieldNode) { - LoadFieldNode loadFieldNode = (LoadFieldNode) loadIndexedNode.array(); - if (!loadFieldNode.isStatic() && isCompilationFinal(loadFieldNode.field())) { - graph.replaceFixedWithFixed(loadIndexedNode, graph.add(new LoadIndexedFinalNode(loadIndexedNode.array(), loadIndexedNode.index(), loadIndexedNode.elementKind()))); - } - } else if (loadIndexedNode.array() instanceof ConstantNode) { - graph.replaceFixedWithFixed(loadIndexedNode, graph.add(new LoadIndexedFinalNode(loadIndexedNode.array(), loadIndexedNode.index(), loadIndexedNode.elementKind()))); - } - } - } - - private static boolean isCompilationFinal(ResolvedJavaField field) { - assert (field.getAnnotation(Children.class) == null && field.getAnnotation(CompilerDirectives.CompilationFinal.class) == null) || Modifier.isFinal(field.getModifiers()) : "field needs to be declared as final"; - return Modifier.isFinal(field.getModifiers()) && (field.getAnnotation(Children.class) != null || field.getAnnotation(CompilerDirectives.CompilationFinal.class) != null); - } -}
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/CompilerDirectivesSubstitutions.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/CompilerDirectivesSubstitutions.java Fri Oct 11 17:21:14 2013 +0200 @@ -24,7 +24,6 @@ import java.util.concurrent.*; -import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.api.replacements.*; import com.oracle.graal.nodes.*; @@ -64,12 +63,51 @@ @MacroSubstitution(macro = BailoutNode.class, isStatic = true) public static native void bailout(String reason); - @MacroSubstitution(macro = TypeCastMacroNode.class, isStatic = true) - public static native Object unsafeCast(Object value, Class clazz, Object receiver, Object customType); + @MacroSubstitution(macro = UnsafeTypeCastMacroNode.class, isStatic = true) + public static native Object unsafeCast(Object value, Class clazz, boolean condition); + + @MacroSubstitution(macro = CustomizedUnsafeLoadMacroNode.class, isStatic = true) + public static native boolean unsafeGetBoolean(Object receiver, long offset, boolean condition, Object locationIdentity); + + @MacroSubstitution(macro = CustomizedUnsafeLoadMacroNode.class, isStatic = true) + public static native byte unsafeGetByte(Object receiver, long offset, boolean condition, Object locationIdentity); + + @MacroSubstitution(macro = CustomizedUnsafeLoadMacroNode.class, isStatic = true) + public static native short unsafeGetShort(Object receiver, long offset, boolean condition, Object locationIdentity); + + @MacroSubstitution(macro = CustomizedUnsafeLoadMacroNode.class, isStatic = true) + public static native int unsafeGetInt(Object receiver, long offset, boolean condition, Object locationIdentity); + + @MacroSubstitution(macro = CustomizedUnsafeLoadMacroNode.class, isStatic = true) + public static native float unsafeGetFloat(Object receiver, long offset, boolean condition, Object locationIdentity); + + @MacroSubstitution(macro = CustomizedUnsafeLoadMacroNode.class, isStatic = true) + public static native double unsafeGetDouble(Object receiver, long offset, boolean condition, Object locationIdentity); + + @MacroSubstitution(macro = CustomizedUnsafeLoadMacroNode.class, isStatic = true) + public static native Object unsafeGetObject(Object receiver, long offset, boolean condition, Object locationIdentity); - @MacroSubstitution(macro = CustomTypeCheckMacroNode.class, isStatic = true) - public static native boolean customTypeCheck(boolean condition, Object value, Object customType); + @MacroSubstitution(macro = CustomizedUnsafeStoreMacroNode.class, isStatic = true) + public static native void unsafePutBoolean(Object receiver, long offset, boolean value, Object locationIdentity); + + @MacroSubstitution(macro = CustomizedUnsafeStoreMacroNode.class, isStatic = true) + public static native void unsafePutByte(Object receiver, long offset, byte value, Object locationIdentity); + + @MacroSubstitution(macro = CustomizedUnsafeStoreMacroNode.class, isStatic = true) + public static native void unsafePutShort(Object receiver, long offset, short value, Object locationIdentity); + + @MacroSubstitution(macro = CustomizedUnsafeStoreMacroNode.class, isStatic = true) + public static native void unsafePutInt(Object receiver, long offset, int value, Object locationIdentity); - @MacroSubstitution(macro = UnsafeCustomizationMacroNode.class, isStatic = true) - public static native Object unsafeCustomization(Object receiver, Object customType, Object locationIdentity); + @MacroSubstitution(macro = CustomizedUnsafeStoreMacroNode.class, isStatic = true) + public static native void unsafePutLong(Object receiver, long offset, long value, Object locationIdentity); + + @MacroSubstitution(macro = CustomizedUnsafeStoreMacroNode.class, isStatic = true) + public static native void unsafePutFloat(Object receiver, long offset, float value, Object locationIdentity); + + @MacroSubstitution(macro = CustomizedUnsafeStoreMacroNode.class, isStatic = true) + public static native void unsafePutDouble(Object receiver, long offset, double value, Object locationIdentity); + + @MacroSubstitution(macro = CustomizedUnsafeStoreMacroNode.class, isStatic = true) + public static native void unsafePutObject(Object receiver, long offset, Object value, Object locationIdentity); }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/FrameWithoutBoxingSubstitutions.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/FrameWithoutBoxingSubstitutions.java Fri Oct 11 17:21:14 2013 +0200 @@ -22,7 +22,6 @@ */ package com.oracle.graal.truffle.substitutions; -import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.api.replacements.*; import com.oracle.graal.api.runtime.*;
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/UnexpectedResultExceptionSubstitutions.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/UnexpectedResultExceptionSubstitutions.java Fri Oct 11 17:21:14 2013 +0200 @@ -22,7 +22,6 @@ */ package com.oracle.graal.truffle.substitutions; -import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.api.replacements.*; import com.oracle.graal.nodes.*;
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/nodes/MaterializedObjectState.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/nodes/MaterializedObjectState.java Fri Oct 11 17:21:14 2013 +0200 @@ -29,7 +29,7 @@ /** * This class encapsulated the materialized state of an escape analyzed object. */ -public final class MaterializedObjectState extends EscapeObjectState implements IterableNodeType, Node.ValueNumberable { +public final class MaterializedObjectState extends EscapeObjectState implements Node.ValueNumberable { @Input private ValueNode materializedValue;
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/nodes/VirtualObjectState.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/nodes/VirtualObjectState.java Fri Oct 11 17:21:14 2013 +0200 @@ -31,7 +31,7 @@ /** * This class encapsulated the virtual state of an escape analyzed object. */ -public final class VirtualObjectState extends EscapeObjectState implements IterableNodeType, Node.ValueNumberable { +public final class VirtualObjectState extends EscapeObjectState implements Node.ValueNumberable { @Input private final NodeInputList<ValueNode> fieldValues;
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectList.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectList.java Fri Oct 11 17:21:14 2013 +0200 @@ -30,8 +30,7 @@ /** * An {@link EffectList} can be used to maintain a list of {@link Effect}s and backtrack to a - * previous state by truncating the list. It can also maintain a level for each effect, which helps - * in creating a string representation for the list. + * previous state by truncating the list. */ public class EffectList implements Iterable<EffectList.Effect> {
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsBlockState.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsBlockState.java Fri Oct 11 17:21:14 2013 +0200 @@ -24,48 +24,14 @@ import java.util.*; -import com.oracle.graal.nodes.*; - public abstract class EffectsBlockState<T extends EffectsBlockState<T>> { - protected final IdentityHashMap<ValueNode, ValueNode> scalarAliases; - - protected EffectsBlockState() { - scalarAliases = new IdentityHashMap<>(); - } - - protected EffectsBlockState(EffectsBlockState<T> other) { - scalarAliases = new IdentityHashMap<>(other.scalarAliases); - } - - public void addScalarAlias(ValueNode alias, ValueNode value) { - scalarAliases.put(alias, value); - } - - public ValueNode getScalarAlias(ValueNode alias) { - ValueNode result = scalarAliases.get(alias); - return result == null ? alias : result; - } - @Override public String toString() { - return "Scalar Aliases: " + scalarAliases.toString(); + return ""; } - public void meetAliases(List<T> states) { - scalarAliases.putAll(states.get(0).scalarAliases); - for (int i = 1; i < states.size(); i++) { - EffectsBlockState<T> state = states.get(i); - meetMaps(scalarAliases, state.scalarAliases); - } - } - - public boolean equivalentTo(T other) { - if (this == other) { - return true; - } - return scalarAliases.equals(other.scalarAliases); - } + protected abstract boolean equivalentTo(T other); protected static <K, V> boolean compareMaps(Map<K, V> left, Map<K, V> right) { if (left.size() != right.size()) {
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsClosure.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsClosure.java Fri Oct 11 17:21:14 2013 +0200 @@ -30,6 +30,7 @@ import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.cfg.*; +import com.oracle.graal.nodes.virtual.*; import com.oracle.graal.phases.graph.*; import com.oracle.graal.phases.graph.ReentrantBlockIterator.BlockIteratorClosure; import com.oracle.graal.phases.graph.ReentrantBlockIterator.LoopInfo; @@ -40,6 +41,7 @@ private final SchedulePhase schedule; + protected final NodeMap<ValueNode> aliases; protected final BlockMap<GraphEffectList> blockEffects; private final IdentityHashMap<Loop, GraphEffectList> loopMergeEffects = new IdentityHashMap<>(); @@ -47,6 +49,7 @@ public EffectsClosure(SchedulePhase schedule) { this.schedule = schedule; + this.aliases = schedule.getCFG().graph.createNodeMap(); this.blockEffects = new BlockMap<>(schedule.getCFG()); for (Block block : schedule.getCFG().getBlocks()) { blockEffects.put(block, new GraphEffectList()); @@ -118,6 +121,7 @@ GraphEffectList effects = blockEffects.get(block); FixedWithNextNode lastFixedNode = null; for (Node node : schedule.getBlockToNodesMap().get(block)) { + aliases.set(node, null); changed |= processNode(node, state, effects, lastFixedNode); if (node instanceof FixedWithNextNode) { lastFixedNode = (FixedWithNextNode) node; @@ -202,9 +206,11 @@ this.afterMergeEffects = new GraphEffectList(); } + /** + * @param states the states that should be merged. + */ protected void merge(List<BlockT> states) { newState = getInitialState(); - newState.meetAliases(states); mergeEffects.clear(); afterMergeEffects.clear(); } @@ -213,4 +219,18 @@ protected void commitEnds(List<BlockT> states) { } } + + public void addScalarAlias(ValueNode node, ValueNode alias) { + assert !(alias instanceof VirtualObjectNode); + aliases.set(node, alias); + } + + public ValueNode getScalarAlias(ValueNode node) { + assert !(node instanceof VirtualObjectNode); + if (node == null || !node.isAlive() || aliases.isNew(node)) { + return node; + } + ValueNode result = aliases.get(node); + return (result == null || result instanceof VirtualObjectNode) ? node : result; + } }
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsPhase.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsPhase.java Fri Oct 11 17:21:14 2013 +0200 @@ -26,8 +26,8 @@ import com.oracle.graal.debug.*; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.spi.*; import com.oracle.graal.phases.*; import com.oracle.graal.phases.common.*; import com.oracle.graal.phases.common.util.*;
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/GraphEffectList.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/GraphEffectList.java Fri Oct 11 17:21:14 2013 +0200 @@ -24,7 +24,6 @@ import java.util.*; -import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; @@ -35,9 +34,6 @@ public class GraphEffectList extends EffectList { public void addCounterBefore(final String group, final String name, final int increment, final boolean addContext, final FixedNode position) { - if (!DynamicCounterNode.enabled) { - return; - } add(new Effect() { @Override @@ -48,28 +44,23 @@ @Override public void apply(StructuredGraph graph, ArrayList<Node> obsoleteNodes) { assert position.isAlive(); - DynamicCounterNode node = graph.add(new DynamicCounterNode(group, name, increment, addContext)); - graph.addBeforeFixed(position, node); + DynamicCounterNode.addCounterBefore(group, name, increment, addContext, position); } }); } - public void addSurvivingCounterBefore(final String group, final String name, final int increment, final boolean addContext, final ValueNode checkedValue, final FixedNode position) { - if (!DynamicCounterNode.enabled) { - return; - } + public void addWeakCounterCounterBefore(final String group, final String name, final int increment, final boolean addContext, final ValueNode checkedValue, final FixedNode position) { add(new Effect() { @Override public String name() { - return "addSurvivingCounterBefore"; + return "addWeakCounterBefore"; } @Override public void apply(StructuredGraph graph, ArrayList<Node> obsoleteNodes) { assert position.isAlive(); - DynamicCounterNode node = graph.add(new SurvivingCounterNode(group, name, increment, addContext, checkedValue)); - graph.addBeforeFixed(position, node); + WeakCounterNode.addCounterBefore(group, name, increment, addContext, checkedValue, position); } }); } @@ -368,24 +359,4 @@ } }); } - - public void addLowLevelCounterBefore(final String group, final String name, final int increment, final boolean addContext, final FixedNode position, final MetaAccessProvider runtime) { - add(new Effect() { - - @Override - public String name() { - return "addLowLevelCounterBefore"; - } - - @Override - public void apply(StructuredGraph graph, ArrayList<Node> obsoleteNodes) { - DynamicCounterNode.addLowLevel(group, name, increment, addContext, position, runtime); - } - - @Override - public boolean isVisible() { - return true; - } - }); - } }
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/ObjectState.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/ObjectState.java Fri Oct 11 17:21:14 2013 +0200 @@ -137,7 +137,7 @@ } public void escape(ValueNode materialized, EscapeState newState) { - assert state == EscapeState.Virtual || (state == EscapeState.ThreadLocal && newState == EscapeState.Global); + assert state == EscapeState.Virtual && newState == EscapeState.Materialized; state = newState; materializedValue = materialized; entries = null; @@ -146,7 +146,7 @@ @Override public ValueNode getMaterializedValue() { - assert state == EscapeState.ThreadLocal || state == EscapeState.Global; + assert state == EscapeState.Materialized; return materializedValue; }
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PEReadEliminationBlockState.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PEReadEliminationBlockState.java Fri Oct 11 17:21:14 2013 +0200 @@ -92,9 +92,9 @@ return super.equivalentTo(other); } - public void addReadCache(ValueNode object, ResolvedJavaField identity, ValueNode value) { + public void addReadCache(ValueNode object, ResolvedJavaField identity, ValueNode value, PartialEscapeClosure<?> closure) { ValueNode cacheObject; - ObjectState obj = getObjectState(object); + ObjectState obj = closure.getObjectState(this, object); if (obj != null) { assert !obj.isVirtual(); cacheObject = obj.getMaterializedValue(); @@ -104,9 +104,9 @@ readCache.put(new ReadCacheEntry(identity, cacheObject), value); } - public ValueNode getReadCache(ValueNode object, ResolvedJavaField identity) { + public ValueNode getReadCache(ValueNode object, ResolvedJavaField identity, PartialEscapeClosure<?> closure) { ValueNode cacheObject; - ObjectState obj = getObjectState(object); + ObjectState obj = closure.getObjectState(this, object); if (obj != null) { assert !obj.isVirtual(); cacheObject = obj.getMaterializedValue(); @@ -114,13 +114,13 @@ cacheObject = object; } ValueNode cacheValue = readCache.get(new ReadCacheEntry(identity, cacheObject)); - obj = getObjectState(cacheValue); + obj = closure.getObjectState(this, cacheValue); if (obj != null) { assert !obj.isVirtual(); cacheValue = obj.getMaterializedValue(); } else { // assert !scalarAliases.containsKey(cacheValue); - cacheValue = getScalarAlias(cacheValue); + cacheValue = closure.getScalarAlias(cacheValue); } return cacheValue; }
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PEReadEliminationClosure.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PEReadEliminationClosure.java Fri Oct 11 17:21:14 2013 +0200 @@ -57,13 +57,13 @@ LoadFieldNode load = (LoadFieldNode) node; if (!load.isVolatile()) { ValueNode object = GraphUtil.unproxify(load.object()); - ValueNode cachedValue = state.getReadCache(object, load.field()); + ValueNode cachedValue = state.getReadCache(object, load.field(), this); if (cachedValue != null) { effects.replaceAtUsages(load, cachedValue); - state.addScalarAlias(load, cachedValue); + addScalarAlias(load, cachedValue); deleted = true; } else { - state.addReadCache(object, load.field(), load); + state.addReadCache(object, load.field(), load, this); } } else { processIdentity(state, ANY_LOCATION); @@ -72,24 +72,24 @@ StoreFieldNode store = (StoreFieldNode) node; if (!store.isVolatile()) { ValueNode object = GraphUtil.unproxify(store.object()); - ValueNode cachedValue = state.getReadCache(object, store.field()); + ValueNode cachedValue = state.getReadCache(object, store.field(), this); - ValueNode value = state.getScalarAlias(store.value()); + ValueNode value = getScalarAlias(store.value()); if (GraphUtil.unproxify(value) == GraphUtil.unproxify(cachedValue)) { effects.deleteFixedNode(store); deleted = true; } state.killReadCache(store.field()); - state.addReadCache(object, store.field(), value); + state.addReadCache(object, store.field(), value, this); } else { processIdentity(state, ANY_LOCATION); } } else if (node instanceof MemoryCheckpoint.Single) { - METRIC_MEMORYCHECKOINT.increment(); + METRIC_MEMORYCHECKPOINT.increment(); LocationIdentity identity = ((MemoryCheckpoint.Single) node).getLocationIdentity(); processIdentity(state, identity); } else if (node instanceof MemoryCheckpoint.Multi) { - METRIC_MEMORYCHECKOINT.increment(); + METRIC_MEMORYCHECKPOINT.increment(); for (LocationIdentity identity : ((MemoryCheckpoint.Multi) node).getLocationIdentities()) { processIdentity(state, identity); } @@ -112,7 +112,7 @@ for (Map.Entry<ReadCacheEntry, ValueNode> entry : exitState.getReadCache().entrySet()) { if (initialState.getReadCache().get(entry.getKey()) != entry.getValue()) { - ValueNode value = exitState.getReadCache(entry.getKey().object, entry.getKey().identity); + ValueNode value = exitState.getReadCache(entry.getKey().object, entry.getKey().identity, this); if (!(value instanceof ProxyNode) || ((ProxyNode) value).proxyPoint() != exitNode) { ProxyNode proxy = new ProxyNode(value, exitNode, PhiType.Value, null); effects.addFloatingNode(proxy, "readCacheProxy"); @@ -165,7 +165,7 @@ PhiNode phiNode = getCachedPhi(entry, value.kind()); mergeEffects.addFloatingNode(phiNode, "mergeReadCache"); for (int i = 0; i < states.size(); i++) { - afterMergeEffects.addPhiInput(phiNode, states.get(i).getReadCache(key.object, key.identity)); + afterMergeEffects.addPhiInput(phiNode, states.get(i).getReadCache(key.object, key.identity, PEReadEliminationClosure.this)); } newState.readCache.put(key, phiNode); } else if (value != null) { @@ -187,7 +187,7 @@ private void mergeReadCachePhi(PhiNode phi, ResolvedJavaField identity, List<PEReadEliminationBlockState> 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); + ValueNode value = states.get(i).getReadCache(phi.valueAt(i), identity, PEReadEliminationClosure.this); if (value == null) { return; }
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeBlockState.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeBlockState.java Fri Oct 11 17:21:14 2013 +0200 @@ -24,7 +24,6 @@ import java.util.*; -import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.Virtualizable.EscapeState; import com.oracle.graal.nodes.virtual.*; @@ -32,7 +31,6 @@ public abstract class PartialEscapeBlockState<T extends PartialEscapeBlockState<T>> extends EffectsBlockState<T> { protected final IdentityHashMap<VirtualObjectNode, ObjectState> objectStates = new IdentityHashMap<>(); - protected final IdentityHashMap<ValueNode, VirtualObjectNode> objectAliases; /** * Final subclass of PartialEscapeBlockState, for performance and to make everything behave @@ -49,15 +47,12 @@ } protected PartialEscapeBlockState() { - objectAliases = new IdentityHashMap<>(); } protected PartialEscapeBlockState(PartialEscapeBlockState<T> other) { - super(other); for (Map.Entry<VirtualObjectNode, ObjectState> entry : other.objectStates.entrySet()) { objectStates.put(entry.getKey(), entry.getValue().cloneState()); } - objectAliases = new IdentityHashMap<>(other.objectAliases); } public ObjectState getObjectState(VirtualObjectNode object) { @@ -69,11 +64,6 @@ return objectStates.get(object); } - public ObjectState getObjectState(ValueNode value) { - VirtualObjectNode object = objectAliases.get(value); - return object == null ? null : getObjectState(object); - } - public void materializeBefore(FixedNode fixed, VirtualObjectNode virtual, EscapeState state, GraphEffectList materializeEffects) { PartialEscapeClosure.METRIC_MATERIALIZATIONS.increment(); List<AllocatedObjectNode> objects = new ArrayList<>(2); @@ -100,8 +90,8 @@ values.add(null); } for (int i = 0; i < entries.length; i++) { - ObjectState entryObj = getObjectState(entries[i]); - if (entryObj != null) { + if (entries[i] instanceof VirtualObjectNode) { + ObjectState entryObj = getObjectState((VirtualObjectNode) entries[i]); if (entryObj.isVirtual()) { materializeWithCommit(fixed, entryObj.getVirtualObject(), objects, locks, values, otherAllocations, state); } @@ -122,26 +112,6 @@ VirtualUtil.trace("materialized %s as %s with values %s", virtual, representation, values); } - void addAndMarkAlias(VirtualObjectNode virtual, ValueNode node, NodeBitMap usages) { - objectAliases.put(node, virtual); - if (node.isAlive()) { - for (Node usage : node.usages()) { - markVirtualUsages(usage, usages); - } - } - } - - private void markVirtualUsages(Node node, NodeBitMap usages) { - if (!usages.isNew(node)) { - usages.mark(node); - } - if (node instanceof VirtualState) { - for (Node usage : node.usages()) { - markVirtualUsages(usage, usages); - } - } - } - public void addObject(VirtualObjectNode virtual, ObjectState state) { objectStates.put(virtual, state); } @@ -150,30 +120,18 @@ return objectStates.values(); } - public Collection<VirtualObjectNode> getVirtualObjects() { - return objectAliases.values(); + public Set<VirtualObjectNode> getVirtualObjects() { + return objectStates.keySet(); } @Override public String toString() { - return super.toString() + ", Object Aliases: " + objectAliases + ", Object States: " + objectStates; - } - - @Override - public void meetAliases(List<T> states) { - super.meetAliases(states); - objectAliases.putAll(states.get(0).objectAliases); - for (int i = 1; i < states.size(); i++) { - meetMaps(objectAliases, states.get(i).objectAliases); - } + return super.toString() + ", Object States: " + objectStates; } @Override public boolean equivalentTo(T other) { - if (!compareMaps(objectAliases, other.objectAliases) || !compareMaps(objectStates, other.objectStates)) { - return false; - } - return super.equivalentTo(other); + return compareMaps(objectStates, other.objectStates); } protected static <K, V> boolean compareMaps(Map<K, V> left, Map<K, V> right) {
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java Fri Oct 11 17:21:14 2013 +0200 @@ -49,7 +49,7 @@ public static final DebugMetric METRIC_MATERIALIZATIONS_LOOP_END = Debug.metric("MaterializationsLoopEnd"); public static final DebugMetric METRIC_ALLOCATION_REMOVED = Debug.metric("AllocationsRemoved"); - public static final DebugMetric METRIC_MEMORYCHECKOINT = Debug.metric("MemoryCheckpoint"); + public static final DebugMetric METRIC_MEMORYCHECKPOINT = Debug.metric("MemoryCheckpoint"); private final NodeBitMap usages; private final VirtualizerToolImpl tool; @@ -79,7 +79,7 @@ public PartialEscapeClosure(SchedulePhase schedule, MetaAccessProvider metaAccess, Assumptions assumptions) { super(schedule); this.usages = schedule.getCFG().graph.createNodeBitMap(); - this.tool = new VirtualizerToolImpl(usages, metaAccess, assumptions); + this.tool = new VirtualizerToolImpl(metaAccess, assumptions, this); } public Map<Invoke, Double> getHints() { @@ -129,7 +129,7 @@ @Override public void apply(Node usage, ValueNode value) { - ObjectState valueObj = state.getObjectState(value); + ObjectState valueObj = getObjectState(state, value); if (valueObj != null) { virtual.add(valueObj); effects.replaceFirstInput(usage, value, valueObj.virtual); @@ -158,8 +158,8 @@ ObjectState obj = queue.removeLast(); if (obj.isVirtual()) { for (ValueNode field : obj.getEntries()) { - ObjectState fieldObj = state.getObjectState(field); - if (fieldObj != null) { + if (field instanceof VirtualObjectNode) { + ObjectState fieldObj = state.getObjectState((VirtualObjectNode) field); if (fieldObj.isVirtual() && !virtual.contains(fieldObj)) { virtual.add(fieldObj); queue.addLast(fieldObj); @@ -173,7 +173,7 @@ if (obj.isVirtual()) { ValueNode[] fieldState = obj.getEntries().clone(); for (int i = 0; i < fieldState.length; i++) { - ObjectState valueObj = state.getObjectState(fieldState[i]); + ObjectState valueObj = getObjectState(state, fieldState[i]); if (valueObj != null) { if (valueObj.isVirtual()) { fieldState[i] = valueObj.virtual; @@ -191,7 +191,7 @@ } } for (ValueNode input : node.inputs().filter(ValueNode.class)) { - ObjectState obj = state.getObjectState(input); + ObjectState obj = getObjectState(state, input); if (obj != null) { if (obj.isVirtual() && node instanceof MethodCallTargetNode) { Invoke invoke = ((MethodCallTargetNode) node).invoke(); @@ -205,18 +205,18 @@ return false; } - private static void ensureMaterialized(PartialEscapeBlockState state, ObjectState obj, FixedNode materializeBefore, GraphEffectList effects, DebugMetric metric) { + private void ensureMaterialized(BlockT state, ObjectState obj, FixedNode materializeBefore, GraphEffectList effects, DebugMetric metric) { assert obj != null; if (obj.getState() == EscapeState.Virtual) { metric.increment(); - state.materializeBefore(materializeBefore, obj.virtual, EscapeState.Global, effects); + state.materializeBefore(materializeBefore, obj.virtual, EscapeState.Materialized, effects); } else { - assert obj.getState() == EscapeState.Global; + assert obj.getState() == EscapeState.Materialized; } assert !obj.isVirtual(); } - private static void replaceWithMaterialized(ValueNode value, Node usage, FixedNode materializeBefore, PartialEscapeBlockState state, ObjectState obj, GraphEffectList effects, DebugMetric metric) { + private void replaceWithMaterialized(ValueNode value, Node usage, FixedNode materializeBefore, BlockT state, ObjectState obj, GraphEffectList effects, DebugMetric metric) { ensureMaterialized(state, obj, materializeBefore, effects, metric); effects.replaceFirstInput(usage, value, obj.getMaterializedValue()); } @@ -226,7 +226,7 @@ HashMap<VirtualObjectNode, ProxyNode> proxies = new HashMap<>(); for (ProxyNode proxy : exitNode.proxies()) { - ObjectState obj = exitState.getObjectState(proxy.value()); + ObjectState obj = getObjectState(exitState, proxy.value()); if (obj != null) { proxies.put(obj.virtual, proxy); } @@ -236,8 +236,7 @@ if (obj.isVirtual()) { for (int i = 0; i < obj.getEntries().length; i++) { ValueNode value = obj.getEntry(i); - ObjectState valueObj = exitState.getObjectState(value); - if (valueObj == null) { + if (!(value instanceof VirtualObjectNode)) { if (exitNode.loopBegin().isPhiAtMerge(value) || initialObj == null || !initialObj.isVirtual() || initialObj.getEntry(i) != value) { ProxyNode proxy = new ProxyNode(value, exitNode, PhiType.Value, null); obj.setEntry(i, proxy); @@ -327,16 +326,21 @@ * and so on. */ - HashSet<VirtualObjectNode> virtualObjects = new HashSet<>(newState.getVirtualObjects()); + HashSet<VirtualObjectNode> virtualObjTemp = new HashSet<>(states.get(0).getVirtualObjects()); + for (int i = 1; i < states.size(); i++) { + virtualObjTemp.retainAll(states.get(i).getVirtualObjects()); + } + boolean materialized; do { mergeEffects.clear(); afterMergeEffects.clear(); materialized = false; - for (VirtualObjectNode object : virtualObjects) { + for (VirtualObjectNode object : virtualObjTemp) { ObjectState[] objStates = new ObjectState[states.size()]; for (int i = 0; i < states.size(); i++) { - objStates[i] = states.get(i).getObjectState(object); + objStates[i] = states.get(i).getObjectStateOptional(object); + assert objStates[i] != null; } int virtual = 0; ObjectState startObj = objStates[0]; @@ -359,16 +363,16 @@ PhiNode materializedValuePhi = getCachedPhi(object, Kind.Object); mergeEffects.addFloatingNode(materializedValuePhi, "materializedPhi"); for (int i = 0; i < states.size(); i++) { - PartialEscapeBlockState state = states.get(i); + BlockT state = states.get(i); ObjectState obj = objStates[i]; materialized |= obj.isVirtual(); Block predecessor = mergeBlock.getPredecessors().get(i); ensureMaterialized(state, obj, predecessor.getEndNode(), blockEffects.get(predecessor), METRIC_MATERIALIZATIONS_MERGE); afterMergeEffects.addPhiInput(materializedValuePhi, obj.getMaterializedValue()); } - newState.addObject(object, new ObjectState(object, materializedValuePhi, EscapeState.Global, null)); + newState.addObject(object, new ObjectState(object, materializedValuePhi, EscapeState.Materialized, null)); } else { - newState.addObject(object, new ObjectState(object, singleValue, EscapeState.Global, null)); + newState.addObject(object, new ObjectState(object, singleValue, EscapeState.Materialized, null)); } } else { assert virtual == states.size(); @@ -396,8 +400,8 @@ break outer; } ValueNode[] fields = objStates[i].getEntries(); - ObjectState obj = states.get(i).getObjectState(fields[index]); - if (obj != null) { + if (fields[index] instanceof VirtualObjectNode) { + ObjectState obj = states.get(i).getObjectState((VirtualObjectNode) fields[index]); materialized |= obj.isVirtual(); Block predecessor = mergeBlock.getPredecessors().get(i); ensureMaterialized(states.get(i), obj, predecessor.getEndNode(), blockEffects.get(predecessor), METRIC_MATERIALIZATIONS_MERGE); @@ -421,6 +425,7 @@ } private boolean processPhi(PhiNode phi, List<BlockT> states) { + aliases.set(phi, null); assert states.size() == phi.valueCount(); int virtualInputs = 0; boolean materialized = false; @@ -430,7 +435,7 @@ boolean hasIdentity = false; for (int i = 0; i < phi.valueCount(); i++) { ValueNode value = phi.valueAt(i); - ObjectState obj = states.get(i).getObjectState(value); + ObjectState obj = getObjectState(states.get(i), value); if (obj != null) { if (obj.isVirtual()) { virtualInputs++; @@ -460,10 +465,10 @@ // nothing to do... } else if (virtualInputs == phi.valueCount()) { if (sameObject != null) { - newState.addAndMarkAlias(sameObject, phi, usages); + addAndMarkAlias(sameObject, phi); } else if (sameType != null && sameEntryCount != -1) { if (!hasIdentity) { - VirtualObjectNode virtual = getValueObjectVirtual(phi, states.get(0).getObjectState(phi.valueAt(0)).virtual); + VirtualObjectNode virtual = getValueObjectVirtual(phi, getObjectState(states.get(0), phi.valueAt(0)).virtual); PhiNode[] phis = getValueObjectMergePhis(phi, virtual.entryCount()); for (int i = 0; i < virtual.entryCount(); i++) { @@ -473,13 +478,13 @@ } mergeEffects.addFloatingNode(phis[i], "valueObjectPhi"); for (int i2 = 0; i2 < phi.valueCount(); i2++) { - afterMergeEffects.addPhiInput(phis[i], states.get(i2).getObjectState(phi.valueAt(i2)).getEntry(i)); + afterMergeEffects.addPhiInput(phis[i], getObjectState(states.get(i2), phi.valueAt(i2)).getEntry(i)); } } mergeEffects.addFloatingNode(virtual, "valueObjectNode"); newState.addObject(virtual, new ObjectState(virtual, Arrays.copyOf(phis, phis.length, ValueNode[].class), EscapeState.Virtual, null)); - newState.addAndMarkAlias(virtual, virtual, usages); - newState.addAndMarkAlias(virtual, phi, usages); + addAndMarkAlias(virtual, virtual); + addAndMarkAlias(virtual, phi); } else { materialize = true; } @@ -493,7 +498,7 @@ if (materialize) { for (int i = 0; i < phi.valueCount(); i++) { ValueNode value = phi.valueAt(i); - ObjectState obj = states.get(i).getObjectState(value); + ObjectState obj = getObjectState(states.get(i), value); if (obj != null) { materialized |= obj.isVirtual(); Block predecessor = mergeBlock.getPredecessors().get(i); @@ -504,4 +509,39 @@ return materialized; } } + + public ObjectState getObjectState(PartialEscapeBlockState<?> state, ValueNode value) { + if (value == null) { + return null; + } + if (value.isAlive() && !aliases.isNew(value)) { + ValueNode object = aliases.get(value); + return object instanceof VirtualObjectNode ? state.getObjectStateOptional((VirtualObjectNode) object) : null; + } else { + if (value instanceof VirtualObjectNode) { + return state.getObjectStateOptional((VirtualObjectNode) value); + } + return null; + } + } + + void addAndMarkAlias(VirtualObjectNode virtual, ValueNode node) { + if (node.isAlive()) { + aliases.set(node, virtual); + for (Node usage : node.usages()) { + markVirtualUsages(usage); + } + } + } + + private void markVirtualUsages(Node node) { + if (!usages.isNew(node)) { + usages.mark(node); + } + if (node instanceof VirtualState) { + for (Node usage : node.usages()) { + markVirtualUsages(usage); + } + } + } }
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapePhase.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapePhase.java Fri Oct 11 17:21:14 2013 +0200 @@ -72,9 +72,9 @@ @Override protected Closure<?> createEffectsClosure(PhaseContext context, SchedulePhase schedule) { if (readElimination) { - return new PEReadEliminationClosure(schedule, context.getRuntime(), context.getAssumptions()); + return new PEReadEliminationClosure(schedule, context.getMetaAccess(), context.getAssumptions()); } else { - return new PartialEscapeClosure.Final(schedule, context.getRuntime(), context.getAssumptions()); + return new PartialEscapeClosure.Final(schedule, context.getMetaAccess(), context.getAssumptions()); } }
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/ReadEliminationBlockState.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/ReadEliminationBlockState.java Fri Oct 11 17:21:14 2013 +0200 @@ -64,14 +64,14 @@ public abstract boolean conflicts(LocationIdentity other); } - static class LoadCacheEntry extends CacheEntry<ResolvedJavaField> { + static class LoadCacheEntry extends CacheEntry<LocationIdentity> { - public LoadCacheEntry(ValueNode object, ResolvedJavaField identity) { + public LoadCacheEntry(ValueNode object, LocationIdentity identity) { super(object, identity); } @Override - public CacheEntry<ResolvedJavaField> duplicateWithObject(ValueNode newObject) { + public CacheEntry<LocationIdentity> duplicateWithObject(ValueNode newObject) { return new LoadCacheEntry(newObject, identity); } @@ -103,7 +103,6 @@ } public ReadEliminationBlockState(ReadEliminationBlockState other) { - super(other); readCache = new HashMap<>(other.readCache); } @@ -114,10 +113,7 @@ @Override public boolean equivalentTo(ReadEliminationBlockState other) { - if (!compareMapsNoSize(readCache, other.readCache)) { - return false; - } - return super.equivalentTo(other); + return compareMapsNoSize(readCache, other.readCache); } public void addCacheEntry(CacheEntry<?> identifier, ValueNode value) {
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/ReadEliminationClosure.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/ReadEliminationClosure.java Fri Oct 11 17:21:14 2013 +0200 @@ -61,7 +61,7 @@ ValueNode cachedValue = state.getCacheEntry(identifier); if (cachedValue != null) { effects.replaceAtUsages(load, cachedValue); - state.addScalarAlias(load, cachedValue); + addScalarAlias(load, cachedValue); deleted = true; } else { state.addCacheEntry(identifier, load); @@ -76,12 +76,12 @@ LoadCacheEntry identifier = new LoadCacheEntry(object, store.field()); ValueNode cachedValue = state.getCacheEntry(identifier); - ValueNode value = state.getScalarAlias(store.value()); + ValueNode value = getScalarAlias(store.value()); if (GraphUtil.unproxify(value) == GraphUtil.unproxify(cachedValue)) { effects.deleteFixedNode(store); deleted = true; } - state.killReadCache((LocationIdentity) store.field()); + state.killReadCache(store.field()); state.addCacheEntry(identifier, value); } else { processIdentity(state, ANY_LOCATION); @@ -94,12 +94,26 @@ ValueNode cachedValue = state.getCacheEntry(identifier); if (cachedValue != null) { effects.replaceAtUsages(read, cachedValue); - state.addScalarAlias(read, cachedValue); + addScalarAlias(read, cachedValue); deleted = true; } else { state.addCacheEntry(identifier, read); } } + } else if (node instanceof UnsafeLoadNode) { + UnsafeLoadNode load = (UnsafeLoadNode) node; + if (load.offset().isConstant() && load.getLocationIdentity() != LocationIdentity.ANY_LOCATION) { + ValueNode object = GraphUtil.unproxify(load.object()); + LoadCacheEntry identifier = new LoadCacheEntry(object, load.getLocationIdentity()); + ValueNode cachedValue = state.getCacheEntry(identifier); + if (cachedValue != null) { + effects.replaceAtUsages(load, cachedValue); + addScalarAlias(load, cachedValue); + deleted = true; + } else { + state.addCacheEntry(identifier, load); + } + } } else if (node instanceof WriteNode) { WriteNode write = (WriteNode) node; if (write.location() instanceof ConstantLocationNode) { @@ -107,7 +121,7 @@ ReadCacheEntry identifier = new ReadCacheEntry(object, write.location()); ValueNode cachedValue = state.getCacheEntry(identifier); - ValueNode value = state.getScalarAlias(write.value()); + ValueNode value = getScalarAlias(write.value()); if (GraphUtil.unproxify(value) == GraphUtil.unproxify(cachedValue)) { effects.deleteFixedNode(write); deleted = true; @@ -117,6 +131,23 @@ } else { processIdentity(state, write.location().getLocationIdentity()); } + } else if (node instanceof UnsafeStoreNode) { + UnsafeStoreNode write = (UnsafeStoreNode) node; + if (write.offset().isConstant() && write.getLocationIdentity() != LocationIdentity.ANY_LOCATION) { + ValueNode object = GraphUtil.unproxify(write.object()); + LoadCacheEntry identifier = new LoadCacheEntry(object, write.getLocationIdentity()); + ValueNode cachedValue = state.getCacheEntry(identifier); + + ValueNode value = getScalarAlias(write.value()); + if (GraphUtil.unproxify(value) == GraphUtil.unproxify(cachedValue)) { + effects.deleteFixedNode(write); + deleted = true; + } + processIdentity(state, write.getLocationIdentity()); + state.addCacheEntry(identifier, value); + } else { + processIdentity(state, write.getLocationIdentity()); + } } else if (node instanceof MemoryCheckpoint.Single) { LocationIdentity identity = ((MemoryCheckpoint.Single) node).getLocationIdentity(); processIdentity(state, identity);
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/VirtualizerToolImpl.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/VirtualizerToolImpl.java Fri Oct 11 17:21:14 2013 +0200 @@ -36,18 +36,18 @@ class VirtualizerToolImpl implements VirtualizerTool { - private final NodeBitMap usages; private final MetaAccessProvider metaAccess; private final Assumptions assumptions; + private final PartialEscapeClosure<?> closure; - VirtualizerToolImpl(NodeBitMap usages, MetaAccessProvider metaAccess, Assumptions assumptions) { - this.usages = usages; + VirtualizerToolImpl(MetaAccessProvider metaAccess, Assumptions assumptions, PartialEscapeClosure<?> closure) { this.metaAccess = metaAccess; this.assumptions = assumptions; + this.closure = closure; } private boolean deleted; - private PartialEscapeBlockState state; + private PartialEscapeBlockState<?> state; private ValueNode current; private FixedNode position; private GraphEffectList effects; @@ -76,15 +76,15 @@ @Override public State getObjectState(ValueNode value) { - return state.getObjectState(value); + return closure.getObjectState(state, value); } @Override public void setVirtualEntry(State objectState, int index, ValueNode value) { ObjectState obj = (ObjectState) objectState; assert obj != null && obj.isVirtual() : "not virtual: " + obj; - ObjectState valueState = state.getObjectState(value); - ValueNode newValue = value; + ObjectState valueState = closure.getObjectState(state, value); + ValueNode newValue; if (valueState == null) { newValue = getReplacedValue(value); assert obj.getEntry(index) == null || obj.getEntry(index).kind() == newValue.kind() || (isObjectEntry(obj.getEntry(index)) && isObjectEntry(newValue)); @@ -105,19 +105,13 @@ } @Override - public ValueNode getMaterializedValue(ValueNode value) { - ObjectState obj = state.getObjectState(value); - return obj != null && !obj.isVirtual() ? obj.getMaterializedValue() : null; - } - - @Override public ValueNode getReplacedValue(ValueNode original) { - return state.getScalarAlias(original); + return closure.getScalarAlias(original); } @Override public void replaceWithVirtual(VirtualObjectNode virtual) { - state.addAndMarkAlias(virtual, current, usages); + closure.addAndMarkAlias(virtual, current); if (current instanceof FixedWithNextNode) { effects.deleteFixedNode((FixedWithNextNode) current); } @@ -126,8 +120,8 @@ @Override public void replaceWithValue(ValueNode replacement) { - effects.replaceAtUsages(current, state.getScalarAlias(replacement)); - state.addScalarAlias(current, replacement); + effects.replaceAtUsages(current, closure.getScalarAlias(replacement)); + closure.addScalarAlias(current, replacement); deleted = true; } @@ -154,16 +148,21 @@ @Override public void createVirtualObject(VirtualObjectNode virtualObject, ValueNode[] entryState, int[] locks) { VirtualUtil.trace("{{%s}} ", current); - if (virtualObject.isAlive()) { - state.addAndMarkAlias(virtualObject, virtualObject, usages); - } else { + if (!virtualObject.isAlive()) { effects.addFloatingNode(virtualObject, "newVirtualObject"); } for (int i = 0; i < entryState.length; i++) { - entryState[i] = state.getScalarAlias(entryState[i]); + if (!(entryState[i] instanceof VirtualObjectNode)) { + ObjectState v = closure.getObjectState(state, entryState[i]); + if (v != null) { + entryState[i] = v.isVirtual() ? v.getVirtualObject() : v.getMaterializedValue(); + } else { + entryState[i] = closure.getScalarAlias(entryState[i]); + } + } } state.addObject(virtualObject, new ObjectState(virtualObject, entryState, EscapeState.Virtual, locks)); - state.addAndMarkAlias(virtualObject, virtualObject, usages); + closure.addAndMarkAlias(virtualObject, virtualObject); PartialEscapeClosure.METRIC_ALLOCATION_REMOVED.increment(); }
--- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/nodes/WordCastNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/nodes/WordCastNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -23,6 +23,8 @@ package com.oracle.graal.word.nodes; import com.oracle.graal.api.meta.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -55,7 +57,8 @@ return input; } - public ValueNode canonical(CanonicalizerTool tool) { + @Override + public Node canonical(CanonicalizerTool tool) { if (usages().count() == 0) { /* If the cast is unused, it can be eliminated. */ return input;
--- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/TypeSystemTest.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/TypeSystemTest.java Fri Oct 11 17:21:14 2013 +0200 @@ -58,6 +58,10 @@ @TypeSystemReference(SimpleTypes.class) public abstract static class ValueNode extends Node { + public ValueNode() { + super(null); + } + public int executeInt(VirtualFrame frame) throws UnexpectedResultException { return SimpleTypesGen.SIMPLETYPES.expectInteger(execute(frame)); } @@ -105,6 +109,7 @@ @Child private E node; public TestRootNode(E node) { + super(null); this.node = adoptChild(node); }
--- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/ArgumentsTest.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/ArgumentsTest.java Fri Oct 11 17:21:14 2013 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -75,6 +75,7 @@ @Children private TestArgumentNode[] children; TestRootNode(TestArgumentNode[] children) { + super(null); this.children = adoptChildren(children); } @@ -93,6 +94,7 @@ private final int index; TestArgumentNode(int index) { + super(null); this.index = index; }
--- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/CallTest.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/CallTest.java Fri Oct 11 17:21:14 2013 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -60,6 +60,7 @@ private final CallTarget secondTarget; DualCallNode(CallTarget firstTarget, CallTarget secondTarget) { + super(null); this.firstTarget = firstTarget; this.secondTarget = secondTarget; } @@ -75,6 +76,7 @@ private final int value; public ConstantRootNode(int value) { + super(null); this.value = value; }
--- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/ChildNodeTest.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/ChildNodeTest.java Fri Oct 11 17:21:14 2013 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -78,6 +78,7 @@ @Child private TestChildNode right; public TestRootNode(TestChildNode left, TestChildNode right) { + super(null); this.left = adoptChild(left); this.right = adoptChild(right); } @@ -90,6 +91,10 @@ class TestChildNode extends Node { + public TestChildNode() { + super(null); + } + public int execute() { return 21; }
--- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/ChildrenNodesTest.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/ChildrenNodesTest.java Fri Oct 11 17:21:14 2013 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -71,6 +71,7 @@ @Children private final TestChildNode[] children; public TestRootNode(TestChildNode[] children) { + super(null); this.children = adoptChildren(children); } @@ -86,6 +87,10 @@ class TestChildNode extends Node { + public TestChildNode() { + super(null); + } + public int execute() { return 21; }
--- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/FinalFieldTest.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/FinalFieldTest.java Fri Oct 11 17:21:14 2013 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -65,6 +65,7 @@ @Children TestChildNode[] children; public TestRootNode(TestChildNode[] children) { + super(null); this.children = adoptChildren(children); } @@ -83,6 +84,7 @@ private final int value; public TestChildNode(int value) { + super(null); this.value = value; }
--- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/FrameSlotTypeSpecializationTest.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/FrameSlotTypeSpecializationTest.java Fri Oct 11 17:21:14 2013 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -63,6 +63,7 @@ @Child TestChildNode right; public TestRootNode(TestChildNode left, TestChildNode right) { + super(null); this.left = adoptChild(left); this.right = adoptChild(right); } @@ -76,6 +77,10 @@ abstract class TestChildNode extends Node { + protected TestChildNode() { + super(null); + } + abstract Object execute(VirtualFrame frame); }
--- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/FrameTest.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/FrameTest.java Fri Oct 11 17:21:14 2013 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -77,6 +77,7 @@ @Child TestChildNode right; public TestRootNode(TestChildNode left, TestChildNode right) { + super(null); this.left = adoptChild(left); this.right = adoptChild(right); } @@ -89,6 +90,10 @@ abstract class TestChildNode extends Node { + public TestChildNode() { + super(null); + } + abstract int execute(VirtualFrame frame); }
--- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/ReplaceTest.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/ReplaceTest.java Fri Oct 11 17:21:14 2013 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -84,6 +84,7 @@ @Children private final ValueNode[] children; public TestRootNode(ValueNode[] children) { + super(null); this.children = adoptChildren(children); } @@ -99,6 +100,10 @@ abstract class ValueNode extends Node { + public ValueNode() { + super(null); + } + abstract int execute(); }
--- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/ReturnTypeSpecializationTest.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/ReturnTypeSpecializationTest.java Fri Oct 11 17:21:14 2013 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -62,6 +62,7 @@ @Child TestChildNode right; public TestRootNode(TestChildNode left, TestChildNode right) { + super(null); this.left = adoptChild(left); this.right = adoptChild(right); } @@ -75,6 +76,10 @@ abstract class TestChildNode extends Node { + public TestChildNode() { + super(null); + } + abstract Object execute(VirtualFrame frame); int executeInt(VirtualFrame frame) throws UnexpectedResultException {
--- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/RootNodeTest.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/RootNodeTest.java Fri Oct 11 17:21:14 2013 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -59,6 +59,10 @@ class TestRootNode extends RootNode { + public TestRootNode() { + super(null); + } + @Override public Object execute(VirtualFrame frame) { return 42;
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/CompilerDirectives.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/CompilerDirectives.java Fri Oct 11 17:21:14 2013 +0200 @@ -25,13 +25,16 @@ package com.oracle.truffle.api; import java.lang.annotation.*; +import java.lang.reflect.*; import java.util.concurrent.*; +import sun.misc.*; + /** * Directives that influence the optimizations of the Truffle compiler. All of the operations have * no effect when executed in the Truffle interpreter. */ -public class CompilerDirectives { +public final class CompilerDirectives { public static final double LIKELY_PROBABILITY = 0.75; public static final double UNLIKELY_PROBABILITY = 1.0 - LIKELY_PROBABILITY; @@ -39,6 +42,22 @@ public static final double SLOWPATH_PROBABILITY = 0.0001; public static final double FASTPATH_PROBABILITY = 1.0 - SLOWPATH_PROBABILITY; + private static final Unsafe UNSAFE = getUnsafe(); + + private static Unsafe getUnsafe() { + try { + return Unsafe.getUnsafe(); + } catch (SecurityException e) { + } + try { + Field theUnsafeInstance = Unsafe.class.getDeclaredField("theUnsafe"); + theUnsafeInstance.setAccessible(true); + return (Unsafe) theUnsafeInstance.get(Unsafe.class); + } catch (Exception e) { + throw new RuntimeException("exception while trying to get Unsafe.theUnsafe via reflection:", e); + } + } + /** * Directive for the compiler to discontinue compilation at this code position and instead * insert a transfer to the interpreter. @@ -130,72 +149,275 @@ } /** - * Marks methods that are considered unsafe. Wrong usage of those methods can lead to unexpected - * behavior including a crash of the runtime. Therefore, special care should be taken. - */ - @Retention(RetentionPolicy.RUNTIME) - @Target({ElementType.METHOD}) - public @interface Unsafe { - } - - /** - * Treats the given value as a value of the given class. The class must evaluate to a constant. + * Casts the given value to the value of the given type without any checks. The class must + * evaluate to a constant. The condition parameter gives a hint to the compiler under which + * circumstances this cast can be moved to an earlier location in the program. * * @param value the value that is known to have the specified type - * @param clazz the specified type of the value - * @return the value - */ - @Unsafe - public static <T> T unsafeCast(Object value, Class<T> clazz) { - return unsafeCast(value, clazz, null, null); - } - - /** - * Associates the given type token with the given value for the case that condition is true. - * - * @param condition the custom type check - * @param value the value that is of the given custom type after the check - * @param customType the custom type that should be associated with the value - * @return the type check condition - */ - public static boolean customTypeCheck(boolean condition, Object value, Object customType) { - return condition; - } - - /** - * Treats the given value as a value of the given class. The class must evaluate to a constant. - * If the compiler can prove that the given value is of the given custom type, the cast is safe. - * - * @param value the value that is known to have the specified type - * @param clazz the specified type of the value - * @param receiver the receiver on which the custom type is tested - * @param customType the custom type that if present on a value makes this unsafe cast safe - * @return the value + * @param type the specified new type of the value + * @param condition the condition that makes this cast safe also at an earlier location of the + * program + * @return the value to be casted to the new type */ @SuppressWarnings("unchecked") - @Unsafe - public static <T> T unsafeCast(Object value, Class<T> clazz, Object receiver, Object customType) { + public static <T> T unsafeCast(Object value, Class<T> type, boolean condition) { return (T) value; } /** - * Proxies an object instance into an instance that adds a custom location identity on its - * accesses via sun.misc.Unsafe. This means that the accesses on these kind of location - * identities can only alias among themselves. It also allows to specify a custom type for the - * receiver values of follow-up unsafe accesses. Both the custom type and the location identity - * must evaluate to a constant. Furthermore, you should use the proxied receiver object - * immediately for one read or write access via a sun.misc.Unsafe method and not store it - * anywhere. + * Unsafe access to a boolean value within an object. The condition parameter gives a hint to + * the compiler under which circumstances this access can be moved to an earlier location in the + * program. The location identity gives a hint to the compiler for improved global value + * numbering. + * + * @param receiver the object that is accessed + * @param offset the offset at which to access the object in bytes + * @param condition the condition that makes this access safe also at an earlier location in the + * program + * @param locationIdentity the location identity token that can be used for improved global + * value numbering or null + * @return the accessed value + */ + public static boolean unsafeGetBoolean(Object receiver, long offset, boolean condition, Object locationIdentity) { + return UNSAFE.getBoolean(receiver, offset); + } + + /** + * Unsafe access to a byte value within an object. The condition parameter gives a hint to the + * compiler under which circumstances this access can be moved to an earlier location in the + * program. The location identity gives a hint to the compiler for improved global value + * numbering. + * + * @param receiver the object that is accessed + * @param offset the offset at which to access the object in bytes + * @param condition the condition that makes this access safe also at an earlier location in the + * program + * @param locationIdentity the location identity token that can be used for improved global + * value numbering or null + * @return the accessed value + */ + public static byte unsafeGetByte(Object receiver, long offset, boolean condition, Object locationIdentity) { + return UNSAFE.getByte(receiver, offset); + } + + /** + * Unsafe access to a short value within an object. The condition parameter gives a hint to the + * compiler under which circumstances this access can be moved to an earlier location in the + * program. The location identity gives a hint to the compiler for improved global value + * numbering. + * + * @param receiver the object that is accessed + * @param offset the offset at which to access the object in bytes + * @param condition the condition that makes this access safe also at an earlier location in the + * program + * @param locationIdentity the location identity token that can be used for improved global + * value numbering or null + * @return the accessed value + */ + public static short unsafeGetShort(Object receiver, long offset, boolean condition, Object locationIdentity) { + return UNSAFE.getShort(receiver, offset); + } + + /** + * Unsafe access to a int value within an object. The condition parameter gives a hint to the + * compiler under which circumstances this access can be moved to an earlier location in the + * program. The location identity gives a hint to the compiler for improved global value + * numbering. * - * @param receiver the object that is accessed via sun.misc.Unsafe - * @param customType the expected type of the receiver object of follow-up unsafe accesses + * @param receiver the object that is accessed + * @param offset the offset at which to access the object in bytes + * @param condition the condition that makes this access safe also at an earlier location in the + * program + * @param locationIdentity the location identity token that can be used for improved global + * value numbering or null + * @return the accessed value + */ + public static int unsafeGetInt(Object receiver, long offset, boolean condition, Object locationIdentity) { + return UNSAFE.getInt(receiver, offset); + } + + /** + * Unsafe access to a long value within an object. The condition parameter gives a hint to the + * compiler under which circumstances this access can be moved to an earlier location in the + * program. The location identity gives a hint to the compiler for improved global value + * numbering. + * + * @param receiver the object that is accessed + * @param offset the offset at which to access the object in bytes + * @param condition the condition that makes this access safe also at an earlier location in the + * program + * @param locationIdentity the location identity token that can be used for improved global + * value numbering or null + * @return the accessed value + */ + public static long unsafeGetLong(Object receiver, long offset, boolean condition, Object locationIdentity) { + return UNSAFE.getLong(receiver, offset); + } + + /** + * Unsafe access to a float value within an object. The condition parameter gives a hint to the + * compiler under which circumstances this access can be moved to an earlier location in the + * program. The location identity gives a hint to the compiler for improved global value + * numbering. + * + * @param receiver the object that is accessed + * @param offset the offset at which to access the object in bytes + * @param condition the condition that makes this access safe also at an earlier location in the + * program + * @param locationIdentity the location identity token that can be used for improved global + * value numbering or null + * @return the accessed value + */ + public static float unsafeGetFloat(Object receiver, long offset, boolean condition, Object locationIdentity) { + return UNSAFE.getFloat(receiver, offset); + } + + /** + * Unsafe access to a double value within an object. The condition parameter gives a hint to the + * compiler under which circumstances this access can be moved to an earlier location in the + * program. The location identity gives a hint to the compiler for improved global value + * numbering. + * + * @param receiver the object that is accessed + * @param offset the offset at which to access the object in bytes + * @param condition the condition that makes this access safe also at an earlier location in the + * program * @param locationIdentity the location identity token that can be used for improved global * value numbering or null * @return the accessed value */ - @Unsafe - public static Object unsafeCustomization(Object receiver, Object customType, Object locationIdentity) { - return receiver; + public static double unsafeGetDouble(Object receiver, long offset, boolean condition, Object locationIdentity) { + return UNSAFE.getDouble(receiver, offset); + } + + /** + * Unsafe access to a Object value within an object. The condition parameter gives a hint to the + * compiler under which circumstances this access can be moved to an earlier location in the + * program. The location identity gives a hint to the compiler for improved global value + * numbering. + * + * @param receiver the object that is accessed + * @param offset the offset at which to access the object in bytes + * @param condition the condition that makes this access safe also at an earlier location in the + * program + * @param locationIdentity the location identity token that can be used for improved global + * value numbering or null + * @return the accessed value + */ + public static Object unsafeGetObject(Object receiver, long offset, boolean condition, Object locationIdentity) { + return UNSAFE.getObject(receiver, offset); + } + + /** + * Write a boolean value within an object. The location identity gives a hint to the compiler + * for improved global value numbering. + * + * @param receiver the object that is written to + * @param offset the offset at which to write to the object in bytes + * @param value the value to be written + * @param locationIdentity the location identity token that can be used for improved global + * value numbering or null + */ + public static void unsafePutBoolean(Object receiver, long offset, boolean value, Object locationIdentity) { + UNSAFE.putBoolean(receiver, offset, value); + } + + /** + * Write a byte value within an object. The location identity gives a hint to the compiler for + * improved global value numbering. + * + * @param receiver the object that is written to + * @param offset the offset at which to write to the object in bytes + * @param value the value to be written + * @param locationIdentity the location identity token that can be used for improved global + * value numbering or null + */ + public static void unsafePutByte(Object receiver, long offset, byte value, Object locationIdentity) { + UNSAFE.putByte(receiver, offset, value); + } + + /** + * Write a short value within an object. The location identity gives a hint to the compiler for + * improved global value numbering. + * + * @param receiver the object that is written to + * @param offset the offset at which to write to the object in bytes + * @param value the value to be written + * @param locationIdentity the location identity token that can be used for improved global + * value numbering or null + */ + public static void unsafePutShort(Object receiver, long offset, short value, Object locationIdentity) { + UNSAFE.putShort(receiver, offset, value); + } + + /** + * Write a int value within an object. The location identity gives a hint to the compiler for + * improved global value numbering. + * + * @param receiver the object that is written to + * @param offset the offset at which to write to the object in bytes + * @param value the value to be written + * @param locationIdentity the location identity token that can be used for improved global + * value numbering or null + */ + public static void unsafePutInt(Object receiver, long offset, int value, Object locationIdentity) { + UNSAFE.putInt(receiver, offset, value); + } + + /** + * Write a long value within an object. The location identity gives a hint to the compiler for + * improved global value numbering. + * + * @param receiver the object that is written to + * @param offset the offset at which to write to the object in bytes + * @param value the value to be written + * @param locationIdentity the location identity token that can be used for improved global + * value numbering or null + */ + public static void unsafePutLong(Object receiver, long offset, long value, Object locationIdentity) { + UNSAFE.putLong(receiver, offset, value); + } + + /** + * Write a float value within an object. The location identity gives a hint to the compiler for + * improved global value numbering. + * + * @param receiver the object that is written to + * @param offset the offset at which to write to the object in bytes + * @param value the value to be written + * @param locationIdentity the location identity token that can be used for improved global + * value numbering or null + */ + public static void unsafePutFloat(Object receiver, long offset, float value, Object locationIdentity) { + UNSAFE.putFloat(receiver, offset, value); + } + + /** + * Write a double value within an object. The location identity gives a hint to the compiler for + * improved global value numbering. + * + * @param receiver the object that is written to + * @param offset the offset at which to write to the object in bytes + * @param value the value to be written + * @param locationIdentity the location identity token that can be used for improved global + * value numbering or null + */ + public static void unsafePutDouble(Object receiver, long offset, double value, Object locationIdentity) { + UNSAFE.putDouble(receiver, offset, value); + } + + /** + * Write a Object value within an object. The location identity gives a hint to the compiler for + * improved global value numbering. + * + * @param receiver the object that is written to + * @param offset the offset at which to write to the object in bytes + * @param value the value to be written + * @param locationIdentity the location identity token that can be used for improved global + * value numbering or null + */ + public static void unsafePutObject(Object receiver, long offset, Object value, Object locationIdentity) { + UNSAFE.putObject(receiver, offset, value); } /**
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/TruffleRuntime.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/TruffleRuntime.java Fri Oct 11 17:21:14 2013 +0200 @@ -77,6 +77,14 @@ Assumption createAssumption(String name); /** + * Creates a new virtual frame object that can be used to store values and is potentially + * optimizable by the runtime. + * + * @return the newly created virtual frame object + */ + VirtualFrame createVirtualFrame(PackedFrame caller, Arguments arguments, FrameDescriptor frameDescriptor); + + /** * Creates a new materialized frame object that can be used to store values. * * @return the newly created materialized frame object
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/Frame.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/Frame.java Fri Oct 11 17:21:14 2013 +0200 @@ -47,7 +47,6 @@ * @param clazz the known type of the arguments object as a compile time constant * @return the arguments used when calling this method */ - @CompilerDirectives.Unsafe <T extends Arguments> T getArguments(Class<T> clazz); /**
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultTruffleRuntime.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultTruffleRuntime.java Fri Oct 11 17:21:14 2013 +0200 @@ -50,6 +50,11 @@ } @Override + public VirtualFrame createVirtualFrame(PackedFrame caller, Arguments arguments, FrameDescriptor frameDescriptor) { + return new DefaultVirtualFrame(frameDescriptor, caller, arguments); + } + + @Override public MaterializedFrame createMaterializedFrame(Arguments arguments) { return createMaterializedFrame(arguments, new FrameDescriptor()); }
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java Fri Oct 11 17:21:14 2013 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -31,6 +31,7 @@ import sun.misc.*; +import com.oracle.truffle.api.*; import com.oracle.truffle.api.nodes.Node.Child; import com.oracle.truffle.api.nodes.Node.Children; @@ -346,14 +347,14 @@ return nodes; } - public static void replaceChild(Node parent, Node oldChild, Node newChild) { + public static boolean replaceChild(Node parent, Node oldChild, Node newChild) { NodeClass nodeClass = NodeClass.get(parent.getClass()); for (long fieldOffset : nodeClass.getChildOffsets()) { if (unsafe.getObject(parent, fieldOffset) == oldChild) { assert assertAssignable(nodeClass, fieldOffset, newChild); unsafe.putObject(parent, fieldOffset, newChild); - return; + return true; } } @@ -366,11 +367,12 @@ if (array[i] == oldChild) { assert assertAssignable(nodeClass, fieldOffset, newChild); array[i] = newChild; - return; + return true; } } } } + return false; } private static boolean assertAssignable(NodeClass clazz, long fieldOffset, Object newValue) { @@ -637,6 +639,66 @@ p.flush(); } + public static String printSourceAttributionTree(Node node) { + StringWriter out = new StringWriter(); + printSourceAttributionTree(new PrintWriter(out), null, node, 1); + return out.toString(); + } + + public static void printSourceAttributionTree(OutputStream out, Node node) { + printSourceAttributionTree(new PrintWriter(out), null, node, 1); + } + + private static void printSourceAttributionTree(PrintWriter p, Node parent, Node node, int level) { + if (node == null) { + return; + } + if (parent == null) { + // Add some preliminary information before starting with the root node + final SourceSection sourceSection = node.getSourceSection(); + if (sourceSection != null) { + final String txt = sourceSection.getSource().getCode(); + p.println("Full source len=(" + txt.length() + ") ___" + txt + "___"); + p.println("AST source attribution:"); + } + } + final StringBuilder sb = new StringBuilder(); + for (int i = 0; i < level; i++) { + sb.append("| "); + } + + if (parent != null) { + String childName = ""; + NodeField[] fields = NodeClass.get(parent.getClass()).fields; + for (NodeField field : fields) { + Object value = field.loadValue(parent); + if (value == node) { + childName = field.getName(); + break; + } else if (value instanceof Node[]) { + int index = 0; + for (Node arrayNode : (Node[]) value) { + if (arrayNode == node) { + childName = field.getName() + "[" + index + "]"; + break; + } + index++; + } + } + } + sb.append(childName); + } + + sb.append(" (" + node.getClass().getSimpleName() + ") "); + sb.append(displaySourceAttribution(node)); + p.println(sb.toString()); + + for (Node child : node.getChildren()) { + printSourceAttributionTree(p, node, child, level + 1); + } + p.flush(); + } + /** * Prints a human readable form of a {@link Node} AST to the given {@link PrintStream}. This * print method does not check for cycles in the node structure. @@ -724,4 +786,34 @@ private static String nodeName(Node node) { return node.getClass().getSimpleName(); } + + private static String displaySourceAttribution(Node node) { + final SourceSection section = node.getSourceSection(); + if (section != null) { + final String srcText = section.getCode(); + final StringBuilder sb = new StringBuilder(); + sb.append("source: len=" + srcText.length()); + sb.append(" (" + section.getCharIndex() + "," + (section.getCharEndIndex() - 1) + ")"); + sb.append(" ___" + srcText + "___"); + return sb.toString(); + } + return ""; + } + + public static boolean verify(Node root) { + Iterable<Node> children = root.getChildren(); + for (Node child : children) { + if (child != null) { + if (child.getParent() != root) { + throw new AssertionError(toStringWithClass(child) + ": actual parent=" + toStringWithClass(child.getParent()) + " expected parent=" + toStringWithClass(root)); + } + verify(child); + } + } + return true; + } + + private static String toStringWithClass(Object obj) { + return obj == null ? "null" : obj + "(" + obj.getClass().getName() + ")"; + } }
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/SLNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/SLNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -28,6 +28,11 @@ @TypeSystemReference(SLTypes.class) public class SLNode extends Node { + public SLNode() { + // No source attribution + super(null); + } + @Override public String toString() { return NodeUtil.printTreeToString(this);
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/FunctionDefinitionNode.java Fri Oct 11 17:14:35 2013 +0200 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/FunctionDefinitionNode.java Fri Oct 11 17:21:14 2013 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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,6 +35,7 @@ private final String name; public FunctionDefinitionNode(StatementNode body, FrameDescriptor frameDescriptor, String name, TypedNode returnValue) { + super(null); this.body = adoptChild(body); this.frameDescriptor = frameDescriptor; this.name = name;
--- a/make/bsd/makefiles/adlc.make Fri Oct 11 17:14:35 2013 +0200 +++ b/make/bsd/makefiles/adlc.make Fri Oct 11 17:21:14 2013 +0200 @@ -41,13 +41,11 @@ ifeq ("${Platform_arch_model}", "${Platform_arch}") SOURCES.AD = \ - $(call altsrc-replace,$(HS_COMMON_SRC)/cpu/$(ARCH)/vm/$(Platform_arch_model).ad) \ - $(call altsrc-replace,$(HS_COMMON_SRC)/os_cpu/$(OS)_$(ARCH)/vm/$(OS)_$(Platform_arch_model).ad) + $(call altsrc-replace,$(HS_COMMON_SRC)/cpu/$(ARCH)/vm/$(Platform_arch_model).ad) else SOURCES.AD = \ $(call altsrc-replace,$(HS_COMMON_SRC)/cpu/$(ARCH)/vm/$(Platform_arch_model).ad) \ - $(call altsrc-replace,$(HS_COMMON_SRC)/cpu/$(ARCH)/vm/$(Platform_arch).ad) \ - $(call altsrc-replace,$(HS_COMMON_SRC)/os_cpu/$(OS)_$(ARCH)/vm/$(OS)_$(Platform_arch_model).ad) + $(call altsrc-replace,$(HS_COMMON_SRC)/cpu/$(ARCH)/vm/$(Platform_arch).ad) endif EXEC = $(OUTDIR)/adlc
--- a/make/bsd/makefiles/minimal1.make Fri Oct 11 17:14:35 2013 +0200 +++ b/make/bsd/makefiles/minimal1.make Fri Oct 11 17:21:14 2013 +0200 @@ -24,16 +24,20 @@ TYPE=MINIMAL1 -INCLUDE_JVMTI ?= false -INCLUDE_FPROF ?= false -INCLUDE_VM_STRUCTS ?= false -INCLUDE_JNI_CHECK ?= false -INCLUDE_SERVICES ?= false -INCLUDE_MANAGEMENT ?= false -INCLUDE_ALL_GCS ?= false -INCLUDE_NMT ?= false -INCLUDE_TRACE ?= false -INCLUDE_CDS ?= false +# Force all variables to false, overriding any other +# setting that may have occurred in the makefiles. These +# can still be overridden by passing the variable as an +# argument to 'make' +INCLUDE_JVMTI := false +INCLUDE_FPROF := false +INCLUDE_VM_STRUCTS := false +INCLUDE_JNI_CHECK := false +INCLUDE_SERVICES := false +INCLUDE_MANAGEMENT := false +INCLUDE_ALL_GCS := false +INCLUDE_NMT := false +INCLUDE_TRACE := false +INCLUDE_CDS := false CXXFLAGS += -DMINIMAL_JVM -DCOMPILER1 -DVMTYPE=\"Minimal\" CFLAGS += -DMINIMAL_JVM -DCOMPILER1 -DVMTYPE=\"Minimal\"
--- a/make/hotspot_version Fri Oct 11 17:14:35 2013 +0200 +++ b/make/hotspot_version Fri Oct 11 17:21:14 2013 +0200 @@ -35,7 +35,7 @@ HS_MAJOR_VER=25 HS_MINOR_VER=0 -HS_BUILD_NUMBER=43 +HS_BUILD_NUMBER=46 JDK_MAJOR_VER=1 JDK_MINOR_VER=8
--- a/make/linux/makefiles/adlc.make Fri Oct 11 17:14:35 2013 +0200 +++ b/make/linux/makefiles/adlc.make Fri Oct 11 17:21:14 2013 +0200 @@ -41,13 +41,11 @@ ifeq ("${Platform_arch_model}", "${Platform_arch}") SOURCES.AD = \ - $(call altsrc-replace,$(HS_COMMON_SRC)/cpu/$(ARCH)/vm/$(Platform_arch_model).ad) \ - $(call altsrc-replace,$(HS_COMMON_SRC)/os_cpu/$(OS)_$(ARCH)/vm/$(OS)_$(Platform_arch_model).ad) + $(call altsrc-replace,$(HS_COMMON_SRC)/cpu/$(ARCH)/vm/$(Platform_arch_model).ad) else SOURCES.AD = \ $(call altsrc-replace,$(HS_COMMON_SRC)/cpu/$(ARCH)/vm/$(Platform_arch_model).ad) \ - $(call altsrc-replace,$(HS_COMMON_SRC)/cpu/$(ARCH)/vm/$(Platform_arch).ad) \ - $(call altsrc-replace,$(HS_COMMON_SRC)/os_cpu/$(OS)_$(ARCH)/vm/$(OS)_$(Platform_arch_model).ad) + $(call altsrc-replace,$(HS_COMMON_SRC)/cpu/$(ARCH)/vm/$(Platform_arch).ad) endif EXEC = $(OUTDIR)/adlc
--- a/make/linux/makefiles/minimal1.make Fri Oct 11 17:14:35 2013 +0200 +++ b/make/linux/makefiles/minimal1.make Fri Oct 11 17:21:14 2013 +0200 @@ -24,16 +24,20 @@ TYPE=MINIMAL1 -INCLUDE_JVMTI ?= false -INCLUDE_FPROF ?= false -INCLUDE_VM_STRUCTS ?= false -INCLUDE_JNI_CHECK ?= false -INCLUDE_SERVICES ?= false -INCLUDE_MANAGEMENT ?= false -INCLUDE_ALL_GCS ?= false -INCLUDE_NMT ?= false -INCLUDE_TRACE ?= false -INCLUDE_CDS ?= false +# Force all variables to false, overriding any other +# setting that may have occurred in the makefiles. These +# can still be overridden by passing the variable as an +# argument to 'make' +INCLUDE_JVMTI := false +INCLUDE_FPROF := false +INCLUDE_VM_STRUCTS := false +INCLUDE_JNI_CHECK := false +INCLUDE_SERVICES := false +INCLUDE_MANAGEMENT := false +INCLUDE_ALL_GCS := false +INCLUDE_NMT := false +INCLUDE_TRACE := false +INCLUDE_CDS := false CXXFLAGS += -DMINIMAL_JVM -DCOMPILER1 -DVMTYPE=\"Minimal\" CFLAGS += -DMINIMAL_JVM -DCOMPILER1 -DVMTYPE=\"Minimal\"
--- a/make/solaris/makefiles/adlc.make Fri Oct 11 17:14:35 2013 +0200 +++ b/make/solaris/makefiles/adlc.make Fri Oct 11 17:21:14 2013 +0200 @@ -42,13 +42,11 @@ ifeq ("${Platform_arch_model}", "${Platform_arch}") SOURCES.AD = \ - $(call altsrc-replace,$(HS_COMMON_SRC)/cpu/$(ARCH)/vm/$(Platform_arch_model).ad) \ - $(call altsrc-replace,$(HS_COMMON_SRC)/os_cpu/$(OS)_$(ARCH)/vm/$(OS)_$(Platform_arch_model).ad) + $(call altsrc-replace,$(HS_COMMON_SRC)/cpu/$(ARCH)/vm/$(Platform_arch_model).ad) else SOURCES.AD = \ $(call altsrc-replace,$(HS_COMMON_SRC)/cpu/$(ARCH)/vm/$(Platform_arch_model).ad) \ - $(call altsrc-replace,$(HS_COMMON_SRC)/cpu/$(ARCH)/vm/$(Platform_arch).ad) \ - $(call altsrc-replace,$(HS_COMMON_SRC)/os_cpu/$(OS)_$(ARCH)/vm/$(OS)_$(Platform_arch_model).ad) + $(call altsrc-replace,$(HS_COMMON_SRC)/cpu/$(ARCH)/vm/$(Platform_arch).ad) endif EXEC = $(OUTDIR)/adlc
--- a/make/solaris/makefiles/dtrace.make Fri Oct 11 17:14:35 2013 +0200 +++ b/make/solaris/makefiles/dtrace.make Fri Oct 11 17:21:14 2013 +0200 @@ -283,9 +283,9 @@ $(QUIETLY) $(DTRACE_PROG) $(DTRACE_OPTS) -C -I. -G -xlazyload -o $@ -s $(DTRACE).d \ $(DTraced_Files) ||\ STATUS=$$?;\ - if [ x"$$STATUS" = x"1" -a \ - x`uname -r` = x"5.10" -a \ - x`uname -p` = x"sparc" ]; then\ + if [ x"$$STATUS" = x"1" ]; then \ + if [ x`uname -r` = x"5.10" -a \ + x`uname -p` = x"sparc" ]; then\ echo "*****************************************************************";\ echo "* If you are building server compiler, and the error message is ";\ echo "* \"incorrect ELF machine type...\", you have run into solaris bug ";\ @@ -294,6 +294,20 @@ echo "* environment variable HOTSPOT_DISABLE_DTRACE_PROBES to disable ";\ echo "* dtrace probes for this build.";\ echo "*****************************************************************";\ + elif [ x`uname -r` = x"5.10" ]; then\ + echo "*****************************************************************";\ + echo "* If you are seeing 'syntax error near \"umpiconninfo_t\"' on Solaris";\ + echo "* 10, try doing 'cd /usr/lib/dtrace && gzip mpi.d' as root, ";\ + echo "* or set the environment variable HOTSPOT_DISABLE_DTRACE_PROBES";\ + echo "* to disable dtrace probes for this build.";\ + echo "*****************************************************************";\ + else \ + echo "*****************************************************************";\ + echo "* If you cannot fix dtrace build issues, try to ";\ + echo "* set the environment variable HOTSPOT_DISABLE_DTRACE_PROBES";\ + echo "* to disable dtrace probes for this build.";\ + echo "*****************************************************************";\ + fi; \ fi;\ exit $$STATUS # Since some DTraced_Files are in LIBJVM.o and they are touched by this
--- a/make/windows/create.bat Fri Oct 11 17:14:35 2013 +0200 +++ b/make/windows/create.bat Fri Oct 11 17:21:14 2013 +0200 @@ -1,6 +1,6 @@ @echo off REM -REM Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. +REM Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. REM DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. REM REM This code is free software; you can redistribute it and/or modify it @@ -152,7 +152,7 @@ REM This is now safe to do. :copyfiles -for /D %%i in (graal, compiler1, compiler2, tiered, core) do ( +for /D %%i in (graal, compiler1, compiler2, tiered) do ( if NOT EXIST %HotSpotBuildSpace%\%%i\generated mkdir %HotSpotBuildSpace%\%%i\generated copy %HotSpotWorkSpace%\make\windows\projectfiles\%%i\* %HotSpotBuildSpace%\%%i\generated > NUL ) @@ -160,7 +160,7 @@ REM force regneration of ProjectFile if exist %ProjectFile% del %ProjectFile% -for /D %%i in (graal, compiler1, compiler2, tiered, core) do ( +for /D %%i in (graal, compiler1, compiler2, tiered) do ( echo -- %%i -- echo # Generated file! > %HotSpotBuildSpace%\%%i\local.make echo # Changing a variable below and then deleting %ProjectFile% will cause >> %HotSpotBuildSpace%\%%i\local.make
--- a/make/windows/create_obj_files.sh Fri Oct 11 17:14:35 2013 +0200 +++ b/make/windows/create_obj_files.sh Fri Oct 11 17:21:14 2013 +0200 @@ -73,19 +73,17 @@ BASE_PATHS="${BASE_PATHS} ${GENERATED}/jvmtifiles ${GENERATED}/tracefiles" -if [ -d "${ALTSRC}/share/vm/jfr" ]; then - BASE_PATHS="${BASE_PATHS} ${ALTSRC}/share/vm/jfr" +if [ -d "${ALTSRC}/share/vm/jfr/buffers" ]; then BASE_PATHS="${BASE_PATHS} ${ALTSRC}/share/vm/jfr/buffers" fi BASE_PATHS="${BASE_PATHS} ${COMMONSRC}/share/vm/prims/wbtestmethods" -CORE_PATHS="${BASE_PATHS}" # shared is already in BASE_PATHS. Should add vm/memory but that one is also in BASE_PATHS. if [ -d "${ALTSRC}/share/vm/gc_implementation" ]; then - CORE_PATHS="${CORE_PATHS} `$FIND ${ALTSRC}/share/vm/gc_implementation ! -name gc_implementation -prune -type d \! -name shared`" + BASE_PATHS="${BASE_PATHS} `$FIND ${ALTSRC}/share/vm/gc_implementation ! -name gc_implementation -prune -type d \! -name shared`" fi -CORE_PATHS="${CORE_PATHS} `$FIND ${COMMONSRC}/share/vm/gc_implementation ! -name gc_implementation -prune -type d \! -name shared`" +BASE_PATHS="${BASE_PATHS} `$FIND ${COMMONSRC}/share/vm/gc_implementation ! -name gc_implementation -prune -type d \! -name shared`" if [ -d "${ALTSRC}/share/vm/c1" ]; then COMPILER1_PATHS="${ALTSRC}/share/vm/c1" @@ -104,12 +102,11 @@ # Include dirs per type. case "${TYPE}" in - "core") Src_Dirs="${CORE_PATHS}" ;; - "compiler1") Src_Dirs="${CORE_PATHS} ${COMPILER1_PATHS}" ;; - "compiler2") Src_Dirs="${CORE_PATHS} ${COMPILER2_PATHS}" ;; - "tiered") Src_Dirs="${CORE_PATHS} ${COMPILER1_PATHS} ${COMPILER2_PATHS}" ;; - "zero") Src_Dirs="${CORE_PATHS}" ;; - "shark") Src_Dirs="${CORE_PATHS}" ;; + "compiler1") Src_Dirs="${BASE_PATHS} ${COMPILER1_PATHS}" ;; + "compiler2") Src_Dirs="${BASE_PATHS} ${COMPILER2_PATHS}" ;; + "tiered") Src_Dirs="${BASE_PATHS} ${COMPILER1_PATHS} ${COMPILER2_PATHS}" ;; + "zero") Src_Dirs="${BASE_PATHS}" ;; + "shark") Src_Dirs="${BASE_PATHS}" ;; esac COMPILER2_SPECIFIC_FILES="opto libadt bcEscapeAnalyzer.cpp c2_* runtime_*" @@ -122,7 +119,6 @@ # Exclude per type. case "${TYPE}" in - "core") Src_Files_EXCLUDE="${Src_Files_EXCLUDE} ${COMPILER1_SPECIFIC_FILES} ${COMPILER2_SPECIFIC_FILES} ${ZERO_SPECIFIC_FILES} ${SHARK_SPECIFIC_FILES} ciTypeFlow.cpp" ;; "compiler1") Src_Files_EXCLUDE="${Src_Files_EXCLUDE} ${COMPILER2_SPECIFIC_FILES} ${ZERO_SPECIFIC_FILES} ${SHARK_SPECIFIC_FILES} ciTypeFlow.cpp" ;; "compiler2") Src_Files_EXCLUDE="${Src_Files_EXCLUDE} ${COMPILER1_SPECIFIC_FILES} ${ZERO_SPECIFIC_FILES} ${SHARK_SPECIFIC_FILES}" ;; "tiered") Src_Files_EXCLUDE="${Src_Files_EXCLUDE} ${ZERO_SPECIFIC_FILES} ${SHARK_SPECIFIC_FILES}" ;; @@ -149,9 +145,17 @@ Src_Files="${Src_Files}`findsrc ${e}` " done -Obj_Files= +Obj_Files=" " for e in ${Src_Files}; do - Obj_Files="${Obj_Files}${e%\.[!.]*}.obj " + o="${e%\.[!.]*}.obj" + set +e + chk=`expr "${Obj_Files}" : ".* $o"` + set -e + if [ "$chk" != 0 ]; then + echo "# INFO: skipping duplicate $o" + continue + fi + Obj_Files="${Obj_Files}$o " done echo Obj_Files=${Obj_Files}
--- a/make/windows/makefiles/adlc.make Fri Oct 11 17:14:35 2013 +0200 +++ b/make/windows/makefiles/adlc.make Fri Oct 11 17:21:14 2013 +0200 @@ -55,13 +55,11 @@ !if "$(Platform_arch_model)" == "$(Platform_arch)" SOURCES_AD=\ - $(WorkSpace)/src/cpu/$(Platform_arch)/vm/$(Platform_arch_model).ad \ - $(WorkSpace)/src/os_cpu/windows_$(Platform_arch)/vm/windows_$(Platform_arch_model).ad + $(WorkSpace)/src/cpu/$(Platform_arch)/vm/$(Platform_arch_model).ad !else SOURCES_AD=\ $(WorkSpace)/src/cpu/$(Platform_arch)/vm/$(Platform_arch_model).ad \ - $(WorkSpace)/src/cpu/$(Platform_arch)/vm/$(Platform_arch).ad \ - $(WorkSpace)/src/os_cpu/windows_$(Platform_arch)/vm/windows_$(Platform_arch_model).ad + $(WorkSpace)/src/cpu/$(Platform_arch)/vm/$(Platform_arch).ad !endif # NOTE! If you add any files here, you must also update GENERATED_NAMES_IN_DIR
--- a/make/windows/makefiles/projectcreator.make Fri Oct 11 17:14:35 2013 +0200 +++ b/make/windows/makefiles/projectcreator.make Fri Oct 11 17:21:14 2013 +0200 @@ -44,10 +44,11 @@ # This is only used internally ProjectCreatorIncludesPRIVATE=\ - -relativeInclude src\closed\share\vm \ - -relativeInclude src\closed\os\windows\vm \ - -relativeInclude src\closed\os_cpu\windows_$(Platform_arch)\vm \ - -relativeInclude src\closed\cpu\$(Platform_arch)\vm \ + -relativeAltSrcInclude src\closed \ + -altRelativeInclude share\vm \ + -altRelativeInclude os\windows\vm \ + -altRelativeInclude os_cpu\windows_$(Platform_arch)\vm \ + -altRelativeInclude cpu\$(Platform_arch)\vm \ -relativeInclude src\share\vm \ -relativeInclude src\share\vm\precompiled \ -relativeInclude src\share\vm\prims\wbtestmethods \ @@ -92,7 +93,7 @@ -disablePch getThread_windows_$(Platform_arch).cpp \ -disablePch_compiler2 opcodes.cpp -# Common options for the IDE builds for core, c1, and c2 +# Common options for the IDE builds for c1, and c2 ProjectCreatorIDEOptions=\ $(ProjectCreatorIDEOptions) \ -sourceBase $(HOTSPOTWORKSPACE) \ @@ -165,19 +166,11 @@ -ignoreFile_TARGET $(Platform_arch_model).ad ################################################## -# Without compiler(core) specific options -################################################## -ProjectCreatorIDEOptions=$(ProjectCreatorIDEOptions) \ -$(ProjectCreatorIDEOptionsIgnoreCompiler1:TARGET=core) \ -$(ProjectCreatorIDEOptionsIgnoreCompiler2:TARGET=core) - -################################################## # Client(C1) compiler specific options ################################################## ProjectCreatorIDEOptions=$(ProjectCreatorIDEOptions) \ -define_compiler1 COMPILER1 \ -define_compiler1 GRAAL \ - -ignorePath_compiler1 core \ -ignorePath_compiler1 graal/generated \ $(ProjectCreatorIDEOptionsIgnoreCompiler2:TARGET=compiler1) @@ -186,7 +179,6 @@ ################################################## ProjectCreatorIDEOptions=$(ProjectCreatorIDEOptions) \ -define_graal GRAAL \ - -ignorePath_graal core \ $(ProjectCreatorIDEOptionsIgnoreCompiler1:TARGET=graal) \ $(ProjectCreatorIDEOptionsIgnoreCompiler2:TARGET=graal) @@ -198,7 +190,6 @@ -define_compiler2 COMPILER2 \ -define_compiler2 GRAAL \ -define_compiler2 TIERED \ - -ignorePath_compiler2 core \ -ignorePath_compiler2 graal/generated \ -additionalFile_compiler2 $(Platform_arch_model).ad \ -additionalFile_compiler2 ad_$(Platform_arch_model).cpp \
--- a/make/windows/makefiles/trace.make Fri Oct 11 17:14:35 2013 +0200 +++ b/make/windows/makefiles/trace.make Fri Oct 11 17:21:14 2013 +0200 @@ -90,25 +90,25 @@ !if "$(OPENJDK)" == "true" $(TraceOutDir)/traceEventClasses.hpp: $(TraceSrcDir)/trace.xml $(TraceSrcDir)/traceEventClasses.xsl $(XML_DEPS) - @echo Generating $@ + @echo Generating OpenJDK $@ @$(XSLT) -IN $(TraceSrcDir)/trace.xml -XSL $(TraceSrcDir)/traceEventClasses.xsl -OUT $(TraceOutDir)/traceEventClasses.hpp !else $(TraceOutDir)/traceEventClasses.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceEventClasses.xsl $(XML_DEPS) - @echo Generating $@ + @echo Generating AltSrc $@ @$(XSLT) -IN $(TraceSrcDir)/trace.xml -XSL $(TraceAltSrcDir)/traceEventClasses.xsl -OUT $(TraceOutDir)/traceEventClasses.hpp $(TraceOutDir)/traceProducer.cpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceProducer.xsl $(XML_DEPS) - @echo Generating $@ + @echo Generating AltSrc $@ @$(XSLT) -IN $(TraceSrcDir)/trace.xml -XSL $(TraceAltSrcDir)/traceProducer.xsl -OUT $(TraceOutDir)/traceProducer.cpp $(TraceOutDir)/traceRequestables.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceRequestables.xsl $(XML_DEPS) - @echo Generating $@ + @echo Generating AltSrc $@ @$(XSLT) -IN $(TraceSrcDir)/trace.xml -XSL $(TraceAltSrcDir)/traceRequestables.xsl -OUT $(TraceOutDir)/traceRequestables.hpp $(TraceOutDir)/traceEventControl.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceEventControl.xsl $(XML_DEPS) - @echo Generating $@ + @echo Generating AltSrc $@ @$(XSLT) -IN $(TraceSrcDir)/trace.xml -XSL $(TraceAltSrcDir)/traceEventControl.xsl -OUT $(TraceOutDir)/traceEventControl.hpp !endif
--- a/make/windows/makefiles/vm.make Fri Oct 11 17:14:35 2013 +0200 +++ b/make/windows/makefiles/vm.make Fri Oct 11 17:21:14 2013 +0200 @@ -36,10 +36,6 @@ CXX_FLAGS=$(CXX_FLAGS) /D "ASSERT" !endif -!if "$(Variant)" == "core" -# No need to define anything, CORE is defined as !COMPILER1 && !COMPILER2 -!endif - !if "$(Variant)" == "compiler1" CXX_FLAGS=$(CXX_FLAGS) /D "COMPILER1" !endif
--- a/make/windows/projectfiles/common/Makefile Fri Oct 11 17:14:35 2013 +0200 +++ b/make/windows/projectfiles/common/Makefile Fri Oct 11 17:21:14 2013 +0200 @@ -112,6 +112,7 @@ ProjectCreatorIDEOptions = $(ProjectCreatorIDEOptions) $(ReleaseOptions) $(HOTSPOTBUILDSPACE)/$(ProjectFile): $(HOTSPOTBUILDSPACE)/classes/ProjectCreator.class + @if "$(MSC_VER)"=="1500" echo Make sure you have VS2008 SP1 or later, or you may see 'expanded command line too long' @$(RUN_JAVA) -Djava.class.path="$(HOTSPOTBUILDSPACE)/classes" ProjectCreator WinGammaPlatform$(VcVersion) $(ProjectCreatorIDEOptions) clean:
--- a/mx/commands.py Fri Oct 11 17:14:35 2013 +0200 +++ b/mx/commands.py Fri Oct 11 17:21:14 2013 +0200 @@ -365,9 +365,18 @@ return jdk +def _updateInstalledGraalOptionsFile(jdk): + graalOptions = join(_graal_home, 'graal.options') + jreLibDir = join(jdk, 'jre', 'lib') + if exists(graalOptions): + shutil.copy(graalOptions, join(jreLibDir, 'graal.options')) + else: + toDelete = join(jreLibDir, 'graal.options') + if exists(toDelete): + os.unlink(toDelete) + def _installGraalJarInJdks(graalDist): graalJar = graalDist.path - graalOptions = join(_graal_home, 'graal.options') jdks = _jdksDir() if exists(jdks): for e in os.listdir(jdks): @@ -379,9 +388,6 @@ os.close(fd) shutil.move(tmp, join(jreLibDir, 'graal.jar')) - if exists(graalOptions): - shutil.copy(graalOptions, join(jreLibDir, 'graal.options')) - # run a command in the windows SDK Debug Shell def _runInDebugShell(cmd, workingDir, logFile=None, findInOutput=None, respondTo=None): if respondTo is None: @@ -692,6 +698,7 @@ build = vmbuild if vmbuild is not None else _vmbuild if _vmSourcesAvailable else 'product' jdk = _jdk(build, vmToCheck=vm, installGraalJar=False) + _updateInstalledGraalOptionsFile(jdk) mx.expand_project_in_args(args) if _make_eclipse_launch: mx.make_eclipse_launch(args, 'graal-' + build, name=None, deps=mx.project('com.oracle.graal.hotspot').all_deps([], True)) @@ -944,12 +951,14 @@ with VM('graal', 'product'): t = Task('BootstrapWithGCVerification:product') - vm(['-XX:+UnlockDiagnosticVMOptions', '-XX:+VerifyBeforeGC', '-XX:+VerifyAfterGC', '-version']) + out = mx.DuplicateSuppressingStream(['VerifyAfterGC:', 'VerifyBeforeGC:']).write + vm(['-XX:+UnlockDiagnosticVMOptions', '-XX:+VerifyBeforeGC', '-XX:+VerifyAfterGC', '-version'], out=out) tasks.append(t.stop()) with VM('graal', 'product'): t = Task('BootstrapWithG1GCVerification:product') - vm(['-XX:+UnlockDiagnosticVMOptions', '-XX:-UseSerialGC', '-XX:+UseG1GC', '-XX:+UseNewCode', '-XX:+VerifyBeforeGC', '-XX:+VerifyAfterGC', '-version']) + out = mx.DuplicateSuppressingStream(['VerifyAfterGC:', 'VerifyBeforeGC:']).write + vm(['-XX:+UnlockDiagnosticVMOptions', '-XX:-UseSerialGC', '-XX:+UseG1GC', '-XX:+UseNewCode', '-XX:+VerifyBeforeGC', '-XX:+VerifyAfterGC', '-version'], out=out) tasks.append(t.stop()) with VM('graal', 'product'): @@ -1318,6 +1327,14 @@ 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 sl(args): + """run an SL program + + VM args should have a @ prefix.""" + vmArgs = [a[1:] for a in args if a[0] == '@'] + slArgs = [a for a in args if a[0] != '@'] + vm(vmArgs + ['-cp', mx.classpath("com.oracle.truffle.sl"), "com.oracle.truffle.sl.SimpleLanguage"] + slArgs) + def isGraalEnabled(vm): return vm != 'original' and not vm.endswith('nograal') @@ -1361,7 +1378,8 @@ 'vmg': [vmg, '[-options] class [args...]'], 'vmfg': [vmfg, '[-options] class [args...]'], 'deoptalot' : [deoptalot, '[n]'], - 'longtests' : [longtests, ''] + 'longtests' : [longtests, ''], + 'sl' : [sl, '[SL args|@VM options]'] } mx.add_argument('--jacoco', help='instruments com.oracle.* classes using JaCoCo', default='off', choices=['off', 'on', 'append'])
--- a/mx/projects Fri Oct 11 17:14:35 2013 +0200 +++ b/mx/projects Fri Oct 11 17:21:14 2013 +0200 @@ -186,7 +186,7 @@ # graal.graph project@com.oracle.graal.graph@subDir=graal project@com.oracle.graal.graph@sourceDirs=src -project@com.oracle.graal.graph@dependencies=com.oracle.graal.debug +project@com.oracle.graal.graph@dependencies=com.oracle.graal.debug,com.oracle.graal.api.code project@com.oracle.graal.graph@javaCompliance=1.7 project@com.oracle.graal.graph@workingSets=Graal,Graph @@ -297,7 +297,7 @@ # graal.nodes project@com.oracle.graal.nodes@subDir=graal project@com.oracle.graal.nodes@sourceDirs=src -project@com.oracle.graal.nodes@dependencies=com.oracle.graal.graph,com.oracle.graal.api.replacements,com.oracle.graal.api.code +project@com.oracle.graal.nodes@dependencies=com.oracle.graal.graph,com.oracle.graal.api.replacements project@com.oracle.graal.nodes@checkstyle=com.oracle.graal.graph project@com.oracle.graal.nodes@javaCompliance=1.7 project@com.oracle.graal.nodes@workingSets=Graal,Graph @@ -497,7 +497,7 @@ # graal.hsail project@com.oracle.graal.hsail@subDir=graal project@com.oracle.graal.hsail@sourceDirs=src -project@com.oracle.graal.hsail@dependencies=com.oracle.graal.api.code,com.oracle.graal.graph +project@com.oracle.graal.hsail@dependencies=com.oracle.graal.graph project@com.oracle.graal.hsail@checkstyle=com.oracle.graal.graph project@com.oracle.graal.hsail@javaCompliance=1.7
--- a/mxtool/mx.py Fri Oct 11 17:14:35 2013 +0200 +++ b/mxtool/mx.py Fri Oct 11 17:21:14 2013 +0200 @@ -158,7 +158,7 @@ _mainSuite = None _opts = None _java = None -_check_global_structures = True # can be set False to allow suites with duplicate definitions to load without aborting +_check_global_structures = True # can be set False to allow suites with duplicate definitions to load without aborting """ @@ -1277,6 +1277,36 @@ return name """ +Utility for filtering duplicate lines. +""" +class DuplicateSuppressingStream: + """ + Creates an object that will suppress duplicate lines sent to 'out'. + The lines considered for suppression are those that contain one of the + strings in 'restrictTo' if it is not None. + """ + def __init__(self, restrictTo=None, out=sys.stdout): + self.restrictTo = restrictTo + self.seen = set() + self.out = out + + def isSuppressionCandidate(self, line): + if self.restrictTo: + for p in self.restrictTo: + if p in line: + return True + return False + else: + return True + + def write(self, line): + if self.isSuppressionCandidate(line): + if line in self.seen: + return + self.seen.add(line) + self.out.write(line) + +""" A JavaCompliance simplifies comparing Java compliance values extracted from a JDK version string. """ class JavaCompliance: @@ -2518,7 +2548,7 @@ return if buildProcessorJars: - ## todo suite specific + # todo suite specific processorjars() projToDist = dict() @@ -2810,7 +2840,7 @@ if exists(md): return wsdir split = os.path.split(wsdir) - if split[0] == wsdir: # root directory + if split[0] == wsdir: # root directory return None else: return _find_eclipse_wsroot(split[0])
--- a/src/cpu/sparc/vm/c2_globals_sparc.hpp Fri Oct 11 17:14:35 2013 +0200 +++ b/src/cpu/sparc/vm/c2_globals_sparc.hpp Fri Oct 11 17:21:14 2013 +0200 @@ -44,7 +44,11 @@ #else define_pd_global(bool, ProfileInterpreter, true); #endif // CC_INTERP +#ifdef GRAAL define_pd_global(bool, TieredCompilation, false); +#else +define_pd_global(bool, TieredCompilation, trueInTiered); +#endif define_pd_global(intx, CompileThreshold, 10000); define_pd_global(intx, BackEdgeThreshold, 140000);
--- a/src/cpu/sparc/vm/templateInterpreter_sparc.cpp Fri Oct 11 17:14:35 2013 +0200 +++ b/src/cpu/sparc/vm/templateInterpreter_sparc.cpp Fri Oct 11 17:21:14 2013 +0200 @@ -1900,6 +1900,27 @@ if (ProfileInterpreter) { __ set_method_data_pointer_for_bcp(); } + +#if INCLUDE_JVMTI + if (EnableInvokeDynamic) { + Label L_done; + + __ ldub(Address(Lbcp, 0), G1_scratch); // Load current bytecode + __ cmp_and_br_short(G1_scratch, Bytecodes::_invokestatic, Assembler::notEqual, Assembler::pn, L_done); + + // The member name argument must be restored if _invokestatic is re-executed after a PopFrame call. + // Detect such a case in the InterpreterRuntime function and return the member name argument, or NULL. + + __ call_VM(G1_scratch, CAST_FROM_FN_PTR(address, InterpreterRuntime::member_name_arg_or_null), I0, Lmethod, Lbcp); + + __ br_null(G1_scratch, false, Assembler::pn, L_done); + __ delayed()->nop(); + + __ st_ptr(G1_scratch, Lesp, wordSize); + __ bind(L_done); + } +#endif // INCLUDE_JVMTI + // Resume bytecode interpretation at the current bcp __ dispatch_next(vtos); // end of JVMTI PopFrame support
--- a/src/cpu/x86/vm/c2_globals_x86.hpp Fri Oct 11 17:14:35 2013 +0200 +++ b/src/cpu/x86/vm/c2_globals_x86.hpp Fri Oct 11 17:21:14 2013 +0200 @@ -46,7 +46,11 @@ #else define_pd_global(bool, ProfileInterpreter, true); #endif // CC_INTERP +#ifdef GRAAL define_pd_global(bool, TieredCompilation, false); +#else +define_pd_global(bool, TieredCompilation, trueInTiered); +#endif define_pd_global(intx, CompileThreshold, 10000); define_pd_global(intx, BackEdgeThreshold, 100000);
--- a/src/cpu/x86/vm/graalCodeInstaller_x86.hpp Fri Oct 11 17:14:35 2013 +0200 +++ b/src/cpu/x86/vm/graalCodeInstaller_x86.hpp Fri Oct 11 17:21:14 2013 +0200 @@ -50,6 +50,9 @@ // the inlined vtable stub contains a "call register" instruction assert(method != NULL, "only valid for virtual calls"); return (pc_offset + ((NativeCallReg *) inst)->next_instruction_offset()); + } else if (inst->is_cond_jump()) { + address pc = (address) (inst); + return pc_offset + (jint) (Assembler::locate_next_instruction(pc) - pc); } else { fatal("unsupported type of instruction for call site"); return 0; @@ -145,21 +148,30 @@ } inline void CodeInstaller::pd_relocate_ForeignCall(NativeInstruction* inst, jlong foreign_call_destination) { + address pc = (address) inst; if (inst->is_call()) { // NOTE: for call without a mov, the offset must fit a 32-bit immediate // see also CompilerToVM.getMaxCallTargetOffset() - NativeCall* call = nativeCall_at((address) (inst)); + NativeCall* call = nativeCall_at(pc); call->set_destination((address) foreign_call_destination); _instructions->relocate(call->instruction_address(), runtime_call_Relocation::spec(), Assembler::call32_operand); } else if (inst->is_mov_literal64()) { - NativeMovConstReg* mov = nativeMovConstReg_at((address) (inst)); + NativeMovConstReg* mov = nativeMovConstReg_at(pc); mov->set_data((intptr_t) foreign_call_destination); _instructions->relocate(mov->instruction_address(), runtime_call_Relocation::spec(), Assembler::imm_operand); - } else { - NativeJump* jump = nativeJump_at((address) (inst)); + } else if (inst->is_jump()) { + NativeJump* jump = nativeJump_at(pc); jump->set_jump_destination((address) foreign_call_destination); - _instructions->relocate((address)inst, runtime_call_Relocation::spec(), Assembler::call32_operand); + _instructions->relocate(jump->instruction_address(), runtime_call_Relocation::spec(), Assembler::call32_operand); + } else if (inst->is_cond_jump()) { + address old_dest = nativeGeneralJump_at(pc)->jump_destination(); + address disp = Assembler::locate_operand(pc, Assembler::call32_operand); + *(jint*) disp += ((address) foreign_call_destination) - old_dest; + _instructions->relocate(pc, runtime_call_Relocation::spec(), Assembler::call32_operand); + } else { + fatal("unsupported relocation for foreign call"); } + TRACE_graal_3("relocating (foreign call) at %p", inst); }
--- a/src/cpu/x86/vm/templateInterpreter_x86_32.cpp Fri Oct 11 17:14:35 2013 +0200 +++ b/src/cpu/x86/vm/templateInterpreter_x86_32.cpp Fri Oct 11 17:21:14 2013 +0200 @@ -1920,6 +1920,29 @@ __ get_thread(thread); __ movl(Address(thread, JavaThread::popframe_condition_offset()), JavaThread::popframe_inactive); +#if INCLUDE_JVMTI + if (EnableInvokeDynamic) { + Label L_done; + const Register local0 = rdi; + + __ cmpb(Address(rsi, 0), Bytecodes::_invokestatic); + __ jcc(Assembler::notEqual, L_done); + + // The member name argument must be restored if _invokestatic is re-executed after a PopFrame call. + // Detect such a case in the InterpreterRuntime function and return the member name argument, or NULL. + + __ get_method(rdx); + __ movptr(rax, Address(local0, 0)); + __ call_VM(rax, CAST_FROM_FN_PTR(address, InterpreterRuntime::member_name_arg_or_null), rax, rdx, rsi); + + __ testptr(rax, rax); + __ jcc(Assembler::zero, L_done); + + __ movptr(Address(rbx, 0), rax); + __ bind(L_done); + } +#endif // INCLUDE_JVMTI + __ dispatch_next(vtos); // end of PopFrame support
--- a/src/cpu/x86/vm/templateInterpreter_x86_64.cpp Fri Oct 11 17:14:35 2013 +0200 +++ b/src/cpu/x86/vm/templateInterpreter_x86_64.cpp Fri Oct 11 17:21:14 2013 +0200 @@ -2011,6 +2011,29 @@ __ movl(Address(r15_thread, JavaThread::popframe_condition_offset()), JavaThread::popframe_inactive); +#if INCLUDE_JVMTI + if (EnableInvokeDynamic) { + Label L_done; + const Register local0 = r14; + + __ cmpb(Address(r13, 0), Bytecodes::_invokestatic); + __ jcc(Assembler::notEqual, L_done); + + // The member name argument must be restored if _invokestatic is re-executed after a PopFrame call. + // Detect such a case in the InterpreterRuntime function and return the member name argument, or NULL. + + __ get_method(rdx); + __ movptr(rax, Address(local0, 0)); + __ call_VM(rax, CAST_FROM_FN_PTR(address, InterpreterRuntime::member_name_arg_or_null), rax, rdx, r13); + + __ testptr(rax, rax); + __ jcc(Assembler::zero, L_done); + + __ movptr(Address(rbx, 0), rax); + __ bind(L_done); + } +#endif // INCLUDE_JVMTI + __ dispatch_next(vtos); // end of PopFrame support
--- a/src/cpu/zero/vm/entryFrame_zero.hpp Fri Oct 11 17:14:35 2013 +0200 +++ b/src/cpu/zero/vm/entryFrame_zero.hpp Fri Oct 11 17:21:14 2013 +0200 @@ -58,8 +58,8 @@ JavaCallWrapper* call_wrapper, TRAPS); public: - JavaCallWrapper *call_wrapper() const { - return (JavaCallWrapper *) value_of_word(call_wrapper_off); + JavaCallWrapper **call_wrapper() const { + return (JavaCallWrapper **) addr_of_word(call_wrapper_off); } public:
--- a/src/cpu/zero/vm/frame_zero.inline.hpp Fri Oct 11 17:14:35 2013 +0200 +++ b/src/cpu/zero/vm/frame_zero.inline.hpp Fri Oct 11 17:21:14 2013 +0200 @@ -141,7 +141,7 @@ return fp(); } -inline JavaCallWrapper* frame::entry_frame_call_wrapper() const { +inline JavaCallWrapper** frame::entry_frame_call_wrapper_addr() const { return zero_entryframe()->call_wrapper(); }
--- a/src/cpu/zero/vm/stubGenerator_zero.cpp Fri Oct 11 17:14:35 2013 +0200 +++ b/src/cpu/zero/vm/stubGenerator_zero.cpp Fri Oct 11 17:21:14 2013 +0200 @@ -176,6 +176,19 @@ StubRoutines::_oop_arraycopy; } + static int SafeFetch32(int *adr, int errValue) { + int value = errValue; + value = *adr; + return value; + } + + static intptr_t SafeFetchN(intptr_t *adr, intptr_t errValue) { + intptr_t value = errValue; + value = *adr; + return value; + } + + void generate_initial() { // Generates all stubs and initializes the entry points @@ -225,6 +238,15 @@ // arraycopy stubs used by compilers generate_arraycopy_stubs(); + + // Safefetch stubs. + StubRoutines::_safefetch32_entry = CAST_FROM_FN_PTR(address, StubGenerator::SafeFetch32); + StubRoutines::_safefetch32_fault_pc = NULL; + StubRoutines::_safefetch32_continuation_pc = NULL; + + StubRoutines::_safefetchN_entry = CAST_FROM_FN_PTR(address, StubGenerator::SafeFetchN); + StubRoutines::_safefetchN_fault_pc = NULL; + StubRoutines::_safefetchN_continuation_pc = NULL; } public:
--- a/src/gpu/ptx/vm/gpu_ptx.cpp Fri Oct 11 17:14:35 2013 +0200 +++ b/src/gpu/ptx/vm/gpu_ptx.cpp Fri Oct 11 17:21:14 2013 +0200 @@ -50,6 +50,28 @@ gpu::Ptx::cuda_cu_memcpy_dtoh_func_t gpu::Ptx::_cuda_cu_memcpy_dtoh; gpu::Ptx::cuda_cu_memfree_func_t gpu::Ptx::_cuda_cu_memfree; + +/* + * see http://en.wikipedia.org/wiki/CUDA#Supported_GPUs + */ +int ncores(int major, int minor) { + int device_type = (major << 4) + minor; + + switch (device_type) { + case 0x10: return 8; + case 0x11: return 8; + case 0x12: return 8; + case 0x13: return 8; + case 0x20: return 32; + case 0x21: return 48; + case 0x30: return 192; + case 0x35: return 192; + default: + tty->print_cr("[CUDA] Warning: Unhandled device %x", device_type); + return 0; + } +} + bool gpu::Ptx::initialize_gpu() { /* Initialize CUDA driver API */ @@ -95,24 +117,7 @@ } /* Get device attributes */ - int minor, major, unified_addressing; - status = _cuda_cu_device_get_attribute(&minor, GRAAL_CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MINOR, _cu_device); - - if (status != GRAAL_CUDA_SUCCESS) { - tty->print_cr("[CUDA] Failed to get minor attribute of device: %d", _cu_device); - return false; - } - - status = _cuda_cu_device_get_attribute(&major, GRAAL_CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MAJOR, _cu_device); - - if (status != GRAAL_CUDA_SUCCESS) { - tty->print_cr("[CUDA] Failed to get major attribute of device: %d", _cu_device); - return false; - } - - if (TraceGPUInteraction) { - tty->print_cr("[CUDA] Compatibility version of device %d: %d.%d", _cu_device, major, minor); - } + int unified_addressing; status = _cuda_cu_device_get_attribute(&unified_addressing, GRAAL_CU_DEVICE_ATTRIBUTE_UNIFIED_ADDRESSING, _cu_device); @@ -139,9 +144,99 @@ tty->print_cr("[CUDA] Using %s", device_name); } + return true; } +unsigned int gpu::Ptx::total_cores() { + + int minor, major, nmp; + int status = _cuda_cu_device_get_attribute(&minor, + GRAAL_CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MINOR, + _cu_device); + + if (status != GRAAL_CUDA_SUCCESS) { + tty->print_cr("[CUDA] Failed to get minor attribute of device: %d", _cu_device); + return 0; + } + + status = _cuda_cu_device_get_attribute(&major, + GRAAL_CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MAJOR, + _cu_device); + + if (status != GRAAL_CUDA_SUCCESS) { + tty->print_cr("[CUDA] Failed to get major attribute of device: %d", _cu_device); + return 0; + } + + status = _cuda_cu_device_get_attribute(&nmp, + GRAAL_CU_DEVICE_ATTRIBUTE_MULTIPROCESSOR_COUNT, + _cu_device); + + if (status != GRAAL_CUDA_SUCCESS) { + tty->print_cr("[CUDA] Failed to get numberof MPs on device: %d", _cu_device); + return 0; + } + + int total = nmp * ncores(major, minor); + + int max_threads_per_block, warp_size, async_engines, can_map_host_memory, concurrent_kernels; + + status = _cuda_cu_device_get_attribute(&max_threads_per_block, + GRAAL_CU_DEVICE_ATTRIBUTE_MAX_THREADS_PER_BLOCK, + _cu_device); + + if (status != GRAAL_CUDA_SUCCESS) { + tty->print_cr("[CUDA] Failed to get GRAAL_CU_DEVICE_ATTRIBUTE_MAX_THREADS_PER_BLOCK: %d", _cu_device); + return 0; + } + + status = _cuda_cu_device_get_attribute(&warp_size, + GRAAL_CU_DEVICE_ATTRIBUTE_WARP_SIZE, + _cu_device); + + if (status != GRAAL_CUDA_SUCCESS) { + tty->print_cr("[CUDA] Failed to get GRAAL_CU_DEVICE_ATTRIBUTE_WARP_SIZE: %d", _cu_device); + return 0; + } + + status = _cuda_cu_device_get_attribute(&async_engines, + GRAAL_CU_DEVICE_ATTRIBUTE_ASYNC_ENGINE_COUNT, + _cu_device); + + if (status != GRAAL_CUDA_SUCCESS) { + tty->print_cr("[CUDA] Failed to get GRAAL_CU_DEVICE_ATTRIBUTE_WARP_SIZE: %d", _cu_device); + return 0; + } + + status = _cuda_cu_device_get_attribute(&can_map_host_memory, + GRAAL_CU_DEVICE_ATTRIBUTE_CAN_MAP_HOST_MEMORY, + _cu_device); + + if (status != GRAAL_CUDA_SUCCESS) { + tty->print_cr("[CUDA] Failed to get GRAAL_CU_DEVICE_ATTRIBUTE_CAN_MAP_HOST_MEMORY: %d", _cu_device); + return 0; + } + + status = _cuda_cu_device_get_attribute(&concurrent_kernels, + GRAAL_CU_DEVICE_ATTRIBUTE_CONCURRENT_KERNELS, + _cu_device); + + if (status != GRAAL_CUDA_SUCCESS) { + tty->print_cr("[CUDA] Failed to get GRAAL_CU_DEVICE_ATTRIBUTE_CONCURRENT_KERNELS: %d", _cu_device); + return 0; + } + + if (TraceGPUInteraction) { + tty->print_cr("[CUDA] Compatibility version of device %d: %d.%d", _cu_device, major, minor); + tty->print_cr("[CUDA] Number of cores: %d async engines: %d can map host mem: %d concurrent kernels: %d", + total, async_engines, can_map_host_memory, concurrent_kernels); + tty->print_cr("[CUDA] Max threads per block: %d warp size: %d", max_threads_per_block, warp_size); + } + return (total); + +} + void *gpu::Ptx::generate_kernel(unsigned char *code, int code_len, const char *name) { struct CUmod_st * cu_module; @@ -228,15 +323,20 @@ } bool gpu::Ptx::execute_kernel(address kernel, PTXKernelArguments &ptxka, JavaValue &ret) { + return gpu::Ptx::execute_warp(1, 1, 1, kernel, ptxka, ret); +} + +bool gpu::Ptx::execute_warp(int dimX, int dimY, int dimZ, + address kernel, PTXKernelArguments &ptxka, JavaValue &ret) { // grid dimensionality unsigned int gridX = 1; unsigned int gridY = 1; unsigned int gridZ = 1; // thread dimensionality - unsigned int blockX = 1; - unsigned int blockY = 1; - unsigned int blockZ = 1; + unsigned int blockX = dimX; + unsigned int blockY = dimY; + unsigned int blockZ = dimZ; struct CUfunc_st* cu_function = (struct CUfunc_st*) kernel; @@ -264,7 +364,7 @@ } if (TraceGPUInteraction) { - tty->print_cr("[CUDA] Success: Kernel Launch"); + tty->print_cr("[CUDA] Success: Kernel Launch: X: %d Y: %d Z: %d", blockX, blockY, blockZ); } status = _cuda_cu_ctx_synchronize(); @@ -282,7 +382,18 @@ // Get the result. TODO: Move this code to get_return_oop() BasicType return_type = ptxka.get_ret_type(); switch (return_type) { - case T_INT : + case T_INT: + { + int return_val; + status = gpu::Ptx::_cuda_cu_memcpy_dtoh(&return_val, ptxka._return_value_ptr, T_INT_BYTE_SIZE); + if (status != GRAAL_CUDA_SUCCESS) { + tty->print_cr("[CUDA] *** Error (%d) Failed to copy value to device argument", status); + return false; + } + ret.set_jint(return_val); + } + break; + case T_BOOLEAN: { int return_val; status = gpu::Ptx::_cuda_cu_memcpy_dtoh(&return_val, ptxka._return_value_ptr, T_INT_BYTE_SIZE); @@ -293,7 +404,29 @@ ret.set_jint(return_val); } break; - case T_LONG : + case T_FLOAT: + { + float return_val; + status = gpu::Ptx::_cuda_cu_memcpy_dtoh(&return_val, ptxka._return_value_ptr, T_FLOAT_BYTE_SIZE); + if (status != GRAAL_CUDA_SUCCESS) { + tty->print_cr("[CUDA] *** Error (%d) Failed to copy value to device argument", status); + return false; + } + ret.set_jfloat(return_val); + } + break; + case T_DOUBLE: + { + double return_val; + status = gpu::Ptx::_cuda_cu_memcpy_dtoh(&return_val, ptxka._return_value_ptr, T_DOUBLE_BYTE_SIZE); + if (status != GRAAL_CUDA_SUCCESS) { + tty->print_cr("[CUDA] *** Error (%d) Failed to copy value to device argument", status); + return false; + } + ret.set_jdouble(return_val); + } + break; + case T_LONG: { long return_val; status = gpu::Ptx::_cuda_cu_memcpy_dtoh(&return_val, ptxka._return_value_ptr, T_LONG_BYTE_SIZE); @@ -304,10 +437,14 @@ ret.set_jlong(return_val); } break; + case T_VOID: + break; default: - tty->print_cr("[CUDA] TODO *** Unhandled return type"); + tty->print_cr("[CUDA] TODO *** Unhandled return type: %d", return_type); } + // handle post-invocation object and array arguemtn + ptxka.reiterate(); // Free device memory allocated for result status = gpu::Ptx::_cuda_cu_memfree(ptxka._return_value_ptr);
--- a/src/gpu/ptx/vm/gpu_ptx.hpp Fri Oct 11 17:14:35 2013 +0200 +++ b/src/gpu/ptx/vm/gpu_ptx.hpp Fri Oct 11 17:21:14 2013 +0200 @@ -31,9 +31,15 @@ */ #define GRAAL_CUDA_SUCCESS 0 /**< Device shares a unified address space with the host */ +#define GRAAL_CU_DEVICE_ATTRIBUTE_MAX_THREADS_PER_BLOCK 1 #define GRAAL_CU_DEVICE_ATTRIBUTE_UNIFIED_ADDRESSING 41 #define GRAAL_CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MAJOR 75 #define GRAAL_CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MINOR 76 +#define GRAAL_CU_DEVICE_ATTRIBUTE_MULTIPROCESSOR_COUNT 16 +#define GRAAL_CU_DEVICE_ATTRIBUTE_WARP_SIZE 10 +#define GRAAL_CU_DEVICE_ATTRIBUTE_CAN_MAP_HOST_MEMORY 19 +#define GRAAL_CU_DEVICE_ATTRIBUTE_CONCURRENT_KERNELS 31 +#define GRAAL_CU_DEVICE_ATTRIBUTE_ASYNC_ENGINE_COUNT 40 #define GRAAL_CU_JIT_MAX_REGISTERS 0 #define GRAAL_CU_JIT_THREADS_PER_BLOCK 1 #define GRAAL_CU_JIT_INFO_LOG_BUFFER 3 @@ -73,7 +79,9 @@ protected: static bool probe_linkage(); static bool initialize_gpu(); + static unsigned int total_cores(); static void * generate_kernel(unsigned char *code, int code_len, const char *name); + static bool execute_warp(int dimX, int dimY, int dimZ, address kernel, PTXKernelArguments & ka, JavaValue &ret); static bool execute_kernel(address kernel, PTXKernelArguments & ka, JavaValue &ret); public: #if defined(__x86_64) || defined(AMD64) || defined(_M_AMD64)
--- a/src/gpu/ptx/vm/ptxKernelArguments.cpp Fri Oct 11 17:14:35 2013 +0200 +++ b/src/gpu/ptx/vm/ptxKernelArguments.cpp Fri Oct 11 17:21:14 2013 +0200 @@ -32,42 +32,115 @@ // Get next java argument oop PTXKernelArguments::next_arg(BasicType expectedType) { assert(_index < _args->length(), "out of bounds"); - oop arg=((objArrayOop) (_args))->obj_at(_index++); - assert(expectedType == T_OBJECT || java_lang_boxing_object::is_instance(arg, expectedType), "arg type mismatch"); + + oop arg = ((objArrayOop) (_args))->obj_at(_index++); + assert(expectedType == T_OBJECT || + java_lang_boxing_object::is_instance(arg, expectedType), "arg type mismatch"); + return arg; } -void PTXKernelArguments::do_int() { - // If the parameter is a return value, - if (is_return_type()) { - // Allocate device memory for T_INT return value pointer on device. Size in bytes - int status = gpu::Ptx::_cuda_cu_memalloc(&_return_value_ptr, T_INT_BYTE_SIZE); - if (status != GRAAL_CUDA_SUCCESS) { - tty->print_cr("[CUDA] *** Error (%d) Failed to allocate memory for return value pointer on device", status); - _success = false; - return; +void PTXKernelArguments::do_int() { + if (is_after_invocation()) { + return; } - // Push _return_value_ptr to _kernelBuffer - *((gpu::Ptx::CUdeviceptr*) &_kernelArgBuffer[_bufferOffset]) = _return_value_ptr; - _bufferOffset += sizeof(_return_value_ptr); - } - else { - // Get the next java argument and its value which should be a T_INT - oop arg = next_arg(T_INT); - // Copy the java argument value to kernelArgBuffer - jvalue intval; - if (java_lang_boxing_object::get_value(arg, &intval) != T_INT) { - tty->print_cr("[CUDA] *** Error: Unexpected argument type; expecting T_INT"); - _success = false; - return; + // If the parameter is a return value, + if (is_return_type()) { + // Allocate device memory for T_INT return value pointer on device. Size in bytes + int status = gpu::Ptx::_cuda_cu_memalloc(&_return_value_ptr, T_INT_BYTE_SIZE); + if (status != GRAAL_CUDA_SUCCESS) { + tty->print_cr("[CUDA] *** Error (%d) Failed to allocate memory for return value pointer on device", status); + _success = false; + return; + } + // Push _return_value_ptr to _kernelBuffer + *((gpu::Ptx::CUdeviceptr*) &_kernelArgBuffer[_bufferOffset]) = _return_value_ptr; + _bufferOffset += sizeof(_return_value_ptr); + } else { + // Get the next java argument and its value which should be a T_INT + oop arg = next_arg(T_INT); + // Copy the java argument value to kernelArgBuffer + jvalue intval; + if (java_lang_boxing_object::get_value(arg, &intval) != T_INT) { + tty->print_cr("[CUDA] *** Error: Unexpected argument type; expecting T_INT"); + _success = false; + return; + } + *((gpu::Ptx::CUdeviceptr*) &_kernelArgBuffer[_bufferOffset]) = intval.i; + _bufferOffset += sizeof(intval.i); } - *((gpu::Ptx::CUdeviceptr*) &_kernelArgBuffer[_bufferOffset]) = intval.i; - _bufferOffset += sizeof(intval.i); - } - return; + return; } -void PTXKernelArguments::do_long() { +void PTXKernelArguments::do_float() { + if (is_after_invocation()) { + return; + } + // If the parameter is a return value, + if (is_return_type()) { + // Allocate device memory for T_INT return value pointer on device. Size in bytes + int status = gpu::Ptx::_cuda_cu_memalloc(&_return_value_ptr, T_FLOAT_BYTE_SIZE); + if (status != GRAAL_CUDA_SUCCESS) { + tty->print_cr("[CUDA] *** Error (%d) Failed to allocate memory for return value pointer on device", status); + _success = false; + return; + } + // Push _return_value_ptr to _kernelBuffer + *((gpu::Ptx::CUdeviceptr*) &_kernelArgBuffer[_bufferOffset]) = _return_value_ptr; + _bufferOffset += sizeof(_return_value_ptr); + } else { + // Get the next java argument and its value which should be a T_INT + oop arg = next_arg(T_FLOAT); + // Copy the java argument value to kernelArgBuffer + jvalue floatval; + if (java_lang_boxing_object::get_value(arg, &floatval) != T_FLOAT) { + tty->print_cr("[CUDA] *** Error: Unexpected argument type; expecting T_INT"); + _success = false; + return; + } + *((gpu::Ptx::CUdeviceptr*) &_kernelArgBuffer[_bufferOffset]) = floatval.f; + _bufferOffset += sizeof(floatval.f); + } + return; +} + +void PTXKernelArguments::do_double() { + if (is_after_invocation()) { + return; + } + // If the parameter is a return value, + jvalue doubleval; + if (is_return_type()) { + // Allocate device memory for T_INT return value pointer on device. Size in bytes + int status = gpu::Ptx::_cuda_cu_memalloc(&_return_value_ptr, T_DOUBLE_BYTE_SIZE); + if (status != GRAAL_CUDA_SUCCESS) { + tty->print_cr("[CUDA] *** Error (%d) Failed to allocate memory for return value pointer on device", status); + _success = false; + return; + } + // Push _return_value_ptr to _kernelBuffer + *((gpu::Ptx::CUdeviceptr*) &_kernelArgBuffer[_bufferOffset]) = _return_value_ptr; + // _bufferOffset += sizeof(_return_value_ptr); + _bufferOffset += sizeof(doubleval.d); + } else { + // Get the next java argument and its value which should be a T_INT + oop arg = next_arg(T_FLOAT); + // Copy the java argument value to kernelArgBuffer + if (java_lang_boxing_object::get_value(arg, &doubleval) != T_DOUBLE) { + tty->print_cr("[CUDA] *** Error: Unexpected argument type; expecting T_INT"); + _success = false; + return; + } + *((gpu::Ptx::CUdeviceptr*) &_kernelArgBuffer[_bufferOffset]) = doubleval.d; + _bufferOffset += sizeof(doubleval.d); + } + return; +} + +void PTXKernelArguments::do_long() { + if (is_after_invocation()) { + return; + } // If the parameter is a return value, if (is_return_type()) { // Allocate device memory for T_LONG return value pointer on device. Size in bytes @@ -80,8 +153,7 @@ // Push _return_value_ptr to _kernelBuffer *((gpu::Ptx::CUdeviceptr*) &_kernelArgBuffer[_bufferOffset]) = _return_value_ptr; _bufferOffset += sizeof(_return_value_ptr); - } - else { + } else { // Get the next java argument and its value which should be a T_LONG oop arg = next_arg(T_LONG); // Copy the java argument value to kernelArgBuffer @@ -97,34 +169,113 @@ return; } -void PTXKernelArguments::do_byte() { - // If the parameter is a return value, - if (is_return_type()) { - // Allocate device memory for T_BYTE return value pointer on device. Size in bytes - int status = gpu::Ptx::_cuda_cu_memalloc(&_return_value_ptr, T_BYTE_SIZE); +void PTXKernelArguments::do_byte() { + if (is_after_invocation()) { + return; + } + // If the parameter is a return value, + if (is_return_type()) { + // Allocate device memory for T_BYTE return value pointer on device. Size in bytes + int status = gpu::Ptx::_cuda_cu_memalloc(&_return_value_ptr, T_BYTE_SIZE); + if (status != GRAAL_CUDA_SUCCESS) { + tty->print_cr("[CUDA] *** Error (%d) Failed to allocate memory for return value pointer on device", status); + _success = false; + return; + } + // Push _return_value_ptr to _kernelBuffer + *((gpu::Ptx::CUdeviceptr*) &_kernelArgBuffer[_bufferOffset]) = _return_value_ptr; + _bufferOffset += sizeof(_return_value_ptr); + } else { + // Get the next java argument and its value which should be a T_BYTE + oop arg = next_arg(T_BYTE); + // Copy the java argument value to kernelArgBuffer + jvalue val; + if (java_lang_boxing_object::get_value(arg, &val) != T_BYTE) { + tty->print_cr("[CUDA] *** Error: Unexpected argument type; expecting T_BYTE"); + _success = false; + return; + } + *((gpu::Ptx::CUdeviceptr*) &_kernelArgBuffer[_bufferOffset]) = val.b; + _bufferOffset += sizeof(val.b); + } + return; +} + +void PTXKernelArguments::do_bool() { + if (is_after_invocation()) { + return; + } + // If the parameter is a return value, + if (is_return_type()) { + // Allocate device memory for T_BYTE return value pointer on device. Size in bytes + int status = gpu::Ptx::_cuda_cu_memalloc(&_return_value_ptr, T_BOOLEAN_SIZE); + if (status != GRAAL_CUDA_SUCCESS) { + tty->print_cr("[CUDA] *** Error (%d) Failed to allocate memory for return value pointer on device", status); + _success = false; + return; + } + // Push _return_value_ptr to _kernelBuffer + *((gpu::Ptx::CUdeviceptr*) &_kernelArgBuffer[_bufferOffset]) = _return_value_ptr; + _bufferOffset += sizeof(_return_value_ptr); + } else { + // Get the next java argument and its value which should be a T_BYTE + oop arg = next_arg(T_BYTE); + // Copy the java argument value to kernelArgBuffer + jvalue val; + if (java_lang_boxing_object::get_value(arg, &val) != T_BOOLEAN) { + tty->print_cr("[CUDA] *** Error: Unexpected argument type; expecting T_BYTE"); + _success = false; + return; + } + *((gpu::Ptx::CUdeviceptr*) &_kernelArgBuffer[_bufferOffset]) = val.z; + _bufferOffset += sizeof(val.z); + } + return; +} + +void PTXKernelArguments::do_array(int begin, int end) { + gpu::Ptx::CUdeviceptr _array_ptr; + int status; + + // Get the next java argument and its value which should be a T_ARRAY + oop arg = next_arg(T_OBJECT); + int array_size = arg->size() * HeapWordSize; + + if (is_after_invocation()) { + _array_ptr = *((gpu::Ptx::CUdeviceptr*) &_kernelArgBuffer[_bufferOffset]); + status = gpu::Ptx::_cuda_cu_memcpy_dtoh(arg, _array_ptr, array_size); + if (status != GRAAL_CUDA_SUCCESS) { + tty->print_cr("[CUDA] *** Error (%d) Failed to copy array argument to host", status); + _success = false; + return; + } else { + // tty->print_cr("device: %x host: %x size: %d", _array_ptr, arg, array_size); + } + return; + } + // Allocate device memory for T_ARRAY return value pointer on device. Size in bytes + status = gpu::Ptx::_cuda_cu_memalloc(&_return_value_ptr, array_size); if (status != GRAAL_CUDA_SUCCESS) { - tty->print_cr("[CUDA] *** Error (%d) Failed to allocate memory for return value pointer on device", status); - _success = false; - return; + tty->print_cr("[CUDA] *** Error (%d) Failed to allocate memory for return value pointer on device", status); + _success = false; + return; + } + status = gpu::Ptx::_cuda_cu_memcpy_htod(_return_value_ptr, arg, array_size); + if (status != GRAAL_CUDA_SUCCESS) { + tty->print_cr("[CUDA] *** Error (%d) Failed to copy array to device argument", status); + _success = false; + return; + } else { + // tty->print_cr("host: %x device: %x size: %d", arg, _return_value_ptr, array_size); } // Push _return_value_ptr to _kernelBuffer *((gpu::Ptx::CUdeviceptr*) &_kernelArgBuffer[_bufferOffset]) = _return_value_ptr; _bufferOffset += sizeof(_return_value_ptr); - } - else { - // Get the next java argument and its value which should be a T_BYTE - oop arg = next_arg(T_BYTE); - // Copy the java argument value to kernelArgBuffer - jvalue val; - if (java_lang_boxing_object::get_value(arg, &val) != T_BYTE) { - tty->print_cr("[CUDA] *** Error: Unexpected argument type; expecting T_BYTE"); - _success = false; - return; - } - *((gpu::Ptx::CUdeviceptr*) &_kernelArgBuffer[_bufferOffset]) = val.b; - _bufferOffset += sizeof(val.b); - } - return; + return; +} + +void PTXKernelArguments::do_void() { + return; } // TODO implement other do_*
--- a/src/gpu/ptx/vm/ptxKernelArguments.hpp Fri Oct 11 17:14:35 2013 +0200 +++ b/src/gpu/ptx/vm/ptxKernelArguments.hpp Fri Oct 11 17:21:14 2013 +0200 @@ -28,9 +28,13 @@ #include "runtime/gpu.hpp" #include "runtime/signature.hpp" -#define T_BYTE_SIZE 1 -#define T_INT_BYTE_SIZE 4 -#define T_LONG_BYTE_SIZE 8 +#define T_BYTE_SIZE 1 +#define T_BOOLEAN_SIZE 4 +#define T_INT_BYTE_SIZE 4 +#define T_FLOAT_BYTE_SIZE 4 +#define T_DOUBLE_BYTE_SIZE 8 +#define T_LONG_BYTE_SIZE 8 +#define T_ARRAY_BYTE_SIZE 8 class PTXKernelArguments : public SignatureIterator { public: @@ -46,6 +50,8 @@ int _index; // Flag to indicate successful creation of kernel argument buffer bool _success; + + bool _afterInvoocation; // Get next java argument oop next_arg(BasicType expectedType); @@ -74,6 +80,17 @@ return _bufferOffset; } + void reiterate() { + _afterInvoocation = true; + _bufferOffset = 0; + _index = 0; + iterate(); + } + + inline bool is_after_invocation() { + return _afterInvoocation; + } + // Get the return oop value oop get_return_oop(); @@ -84,46 +101,32 @@ void do_byte(); + void do_bool(); void do_int(); + void do_float(); + void do_double(); void do_long(); + void do_array(int begin, int end); + void do_void(); - inline void do_bool() { - /* TODO : To be implemented */ - guarantee(false, "NYI"); - } inline void do_char() { /* TODO : To be implemented */ - guarantee(false, "NYI"); + guarantee(false, "do_char:NYI"); } inline void do_short() { /* TODO : To be implemented */ - guarantee(false, "NYI"); - } - inline void do_float() { - /* TODO : To be implemented */ - guarantee(false, "NYI"); + guarantee(false, "do_short:NYI"); } - inline void do_double() { - /* TODO : To be implemented */ - guarantee(false, "NYI"); - } - inline void do_object() { /* TODO : To be implemented */ - guarantee(false, "NYI"); + guarantee(false, "do_object:NYI"); } + inline void do_object(int begin, int end) { /* TODO : To be implemented */ - guarantee(false, "NYI"); + guarantee(false, "do_object(II):NYI"); } - inline void do_array(int begin, int end) { - /* TODO : To be implemented */ - guarantee(false, "NYI"); - } - inline void do_void() { - /* TODO : To be implemented */ - guarantee(false, "NYI"); - } + }; #endif // KERNEL_ARGUMENTS_HPP
--- a/src/os/windows/vm/os_windows.cpp Fri Oct 11 17:14:35 2013 +0200 +++ b/src/os/windows/vm/os_windows.cpp Fri Oct 11 17:21:14 2013 +0200 @@ -1642,6 +1642,8 @@ void os::win32::print_windows_version(outputStream* st) { OSVERSIONINFOEX osvi; + SYSTEM_INFO si; + ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX)); osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); @@ -1651,6 +1653,18 @@ } int os_vers = osvi.dwMajorVersion * 1000 + osvi.dwMinorVersion; + + ZeroMemory(&si, sizeof(SYSTEM_INFO)); + if (os_vers >= 5002) { + // Retrieve SYSTEM_INFO from GetNativeSystemInfo call so that we could + // find out whether we are running on 64 bit processor or not. + if (os::Kernel32Dll::GetNativeSystemInfoAvailable()) { + os::Kernel32Dll::GetNativeSystemInfo(&si); + } else { + GetSystemInfo(&si); + } + } + if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT) { switch (os_vers) { case 3051: st->print(" Windows NT 3.51"); break; @@ -1658,57 +1672,48 @@ case 5000: st->print(" Windows 2000"); break; case 5001: st->print(" Windows XP"); break; case 5002: - case 6000: - case 6001: - case 6002: { - // Retrieve SYSTEM_INFO from GetNativeSystemInfo call so that we could - // find out whether we are running on 64 bit processor or not. - SYSTEM_INFO si; - ZeroMemory(&si, sizeof(SYSTEM_INFO)); - if (!os::Kernel32Dll::GetNativeSystemInfoAvailable()){ - GetSystemInfo(&si); + if (osvi.wProductType == VER_NT_WORKSTATION && + si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) { + st->print(" Windows XP x64 Edition"); } else { - os::Kernel32Dll::GetNativeSystemInfo(&si); + st->print(" Windows Server 2003 family"); } - if (os_vers == 5002) { - if (osvi.wProductType == VER_NT_WORKSTATION && - si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) - st->print(" Windows XP x64 Edition"); - else - st->print(" Windows Server 2003 family"); - } else if (os_vers == 6000) { - if (osvi.wProductType == VER_NT_WORKSTATION) - st->print(" Windows Vista"); - else - st->print(" Windows Server 2008"); - if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) - st->print(" , 64 bit"); - } else if (os_vers == 6001) { - if (osvi.wProductType == VER_NT_WORKSTATION) { - st->print(" Windows 7"); - } else { - // Unrecognized windows, print out its major and minor versions - st->print(" Windows NT %d.%d", osvi.dwMajorVersion, osvi.dwMinorVersion); - } - if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) - st->print(" , 64 bit"); - } else if (os_vers == 6002) { - if (osvi.wProductType == VER_NT_WORKSTATION) { - st->print(" Windows 8"); - } else { - st->print(" Windows Server 2012"); - } - if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) - st->print(" , 64 bit"); - } else { // future os - // Unrecognized windows, print out its major and minor versions - st->print(" Windows NT %d.%d", osvi.dwMajorVersion, osvi.dwMinorVersion); - if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) - st->print(" , 64 bit"); + break; + + case 6000: + if (osvi.wProductType == VER_NT_WORKSTATION) { + st->print(" Windows Vista"); + } else { + st->print(" Windows Server 2008"); } break; - } - default: // future windows, print out its major and minor versions + + case 6001: + if (osvi.wProductType == VER_NT_WORKSTATION) { + st->print(" Windows 7"); + } else { + st->print(" Windows Server 2008 R2"); + } + break; + + case 6002: + if (osvi.wProductType == VER_NT_WORKSTATION) { + st->print(" Windows 8"); + } else { + st->print(" Windows Server 2012"); + } + break; + + case 6003: + if (osvi.wProductType == VER_NT_WORKSTATION) { + st->print(" Windows 8.1"); + } else { + st->print(" Windows Server 2012 R2"); + } + break; + + default: // future os + // Unrecognized windows, print out its major and minor versions st->print(" Windows NT %d.%d", osvi.dwMajorVersion, osvi.dwMinorVersion); } } else { @@ -1720,6 +1725,11 @@ st->print(" Windows %d.%d", osvi.dwMajorVersion, osvi.dwMinorVersion); } } + + if (os_vers >= 6000 && si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) { + st->print(" , 64 bit"); + } + st->print(" Build %d", osvi.dwBuildNumber); st->print(" %s", osvi.szCSDVersion); // service pack st->cr();
--- a/src/os_cpu/bsd_x86/vm/bsd_x86_32.ad Fri Oct 11 17:14:35 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,26 +0,0 @@ -// -// Copyright (c) 1999, 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. -// -// - -// X86 Bsd Architecture Description File -
--- a/src/os_cpu/bsd_x86/vm/bsd_x86_64.ad Fri Oct 11 17:14:35 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,65 +0,0 @@ -// -// Copyright (c) 2003, 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. -// -// - -// AMD64 Bsd Architecture Description File - -//----------OS-DEPENDENT ENCODING BLOCK---------------------------------------- -// This block specifies the encoding classes used by the compiler to -// output byte streams. Encoding classes generate functions which are -// called by Machine Instruction Nodes in order to generate the bit -// encoding of the instruction. Operands specify their base encoding -// interface with the interface keyword. There are currently -// supported four interfaces, REG_INTER, CONST_INTER, MEMORY_INTER, & -// COND_INTER. REG_INTER causes an operand to generate a function -// which returns its register number when queried. CONST_INTER causes -// an operand to generate a function which returns the value of the -// constant when queried. MEMORY_INTER causes an operand to generate -// four functions which return the Base Register, the Index Register, -// the Scale Value, and the Offset Value of the operand when queried. -// COND_INTER causes an operand to generate six functions which return -// the encoding code (ie - encoding bits for the instruction) -// associated with each basic boolean condition for a conditional -// instruction. Instructions specify two basic values for encoding. -// They use the ins_encode keyword to specify their encoding class -// (which must be one of the class names specified in the encoding -// block), and they use the opcode keyword to specify, in order, their -// primary, secondary, and tertiary opcode. Only the opcode sections -// which a particular instruction needs for encoding need to be -// specified. -encode %{ - // Build emit functions for each basic byte or larger field in the intel - // encoding scheme (opcode, rm, sib, immediate), and call them from C++ - // code in the enc_class source block. Emit functions will live in the - // main source block for now. In future, we can generalize this by - // adding a syntax that specifies the sizes of fields in an order, - // so that the adlc can build the emit functions automagically - -%} - - -// Platform dependent source - -source %{ - -%}
--- a/src/os_cpu/linux_x86/vm/linux_x86_32.ad Fri Oct 11 17:14:35 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,26 +0,0 @@ -// -// Copyright (c) 1999, 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. -// -// - -// X86 Linux Architecture Description File -
--- a/src/os_cpu/linux_x86/vm/linux_x86_64.ad Fri Oct 11 17:14:35 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,65 +0,0 @@ -// -// Copyright (c) 2003, 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. -// -// - -// AMD64 Linux Architecture Description File - -//----------OS-DEPENDENT ENCODING BLOCK---------------------------------------- -// This block specifies the encoding classes used by the compiler to -// output byte streams. Encoding classes generate functions which are -// called by Machine Instruction Nodes in order to generate the bit -// encoding of the instruction. Operands specify their base encoding -// interface with the interface keyword. There are currently -// supported four interfaces, REG_INTER, CONST_INTER, MEMORY_INTER, & -// COND_INTER. REG_INTER causes an operand to generate a function -// which returns its register number when queried. CONST_INTER causes -// an operand to generate a function which returns the value of the -// constant when queried. MEMORY_INTER causes an operand to generate -// four functions which return the Base Register, the Index Register, -// the Scale Value, and the Offset Value of the operand when queried. -// COND_INTER causes an operand to generate six functions which return -// the encoding code (ie - encoding bits for the instruction) -// associated with each basic boolean condition for a conditional -// instruction. Instructions specify two basic values for encoding. -// They use the ins_encode keyword to specify their encoding class -// (which must be one of the class names specified in the encoding -// block), and they use the opcode keyword to specify, in order, their -// primary, secondary, and tertiary opcode. Only the opcode sections -// which a particular instruction needs for encoding need to be -// specified. -encode %{ - // Build emit functions for each basic byte or larger field in the intel - // encoding scheme (opcode, rm, sib, immediate), and call them from C++ - // code in the enc_class source block. Emit functions will live in the - // main source block for now. In future, we can generalize this by - // adding a syntax that specifies the sizes of fields in an order, - // so that the adlc can build the emit functions automagically - -%} - - -// Platform dependent source - -source %{ - -%}
--- a/src/os_cpu/linux_zero/vm/os_linux_zero.cpp Fri Oct 11 17:14:35 2013 +0200 +++ b/src/os_cpu/linux_zero/vm/os_linux_zero.cpp Fri Oct 11 17:21:14 2013 +0200 @@ -410,16 +410,6 @@ int SpinPause() { } - int SafeFetch32(int *adr, int errValue) { - int value = errValue; - value = *adr; - return value; - } - intptr_t SafeFetchN(intptr_t *adr, intptr_t errValue) { - intptr_t value = errValue; - value = *adr; - return value; - } void _Copy_conjoint_jshorts_atomic(jshort* from, jshort* to, size_t count) { if (from > to) {
--- a/src/os_cpu/solaris_sparc/vm/solaris_sparc.ad Fri Oct 11 17:14:35 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,27 +0,0 @@ -// -// Copyright (c) 1999, 2007, 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. -// - -// -// - -// SPARC Solaris Architecture Description File
--- a/src/os_cpu/solaris_x86/vm/solaris_x86_32.ad Fri Oct 11 17:14:35 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,26 +0,0 @@ -// -// Copyright (c) 1999, 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. -// -// - -// X86 Solaris Architecture Description File -
--- a/src/os_cpu/solaris_x86/vm/solaris_x86_64.ad Fri Oct 11 17:14:35 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,63 +0,0 @@ -// -// Copyright (c) 2004, 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. -// -// - -// AMD64 Solaris Architecture Description File - -//----------OS-DEPENDENT ENCODING BLOCK---------------------------------------- -// This block specifies the encoding classes used by the compiler to -// output byte streams. Encoding classes generate functions which are -// called by Machine Instruction Nodes in order to generate the bit -// encoding of the instruction. Operands specify their base encoding -// interface with the interface keyword. There are currently -// supported four interfaces, REG_INTER, CONST_INTER, MEMORY_INTER, & -// COND_INTER. REG_INTER causes an operand to generate a function -// which returns its register number when queried. CONST_INTER causes -// an operand to generate a function which returns the value of the -// constant when queried. MEMORY_INTER causes an operand to generate -// four functions which return the Base Register, the Index Register, -// the Scale Value, and the Offset Value of the operand when queried. -// COND_INTER causes an operand to generate six functions which return -// the encoding code (ie - encoding bits for the instruction) -// associated with each basic boolean condition for a conditional -// instruction. Instructions specify two basic values for encoding. -// They use the ins_encode keyword to specify their encoding class -// (which must be one of the class names specified in the encoding -// block), and they use the opcode keyword to specify, in order, their -// primary, secondary, and tertiary opcode. Only the opcode sections -// which a particular instruction needs for encoding need to be -// specified. -encode %{ - // Build emit functions for each basic byte or larger field in the intel - // encoding scheme (opcode, rm, sib, immediate), and call them from C++ - // code in the enc_class source block. Emit functions will live in the - // main source block for now. In future, we can generalize this by - // adding a syntax that specifies the sizes of fields in an order, - // so that the adlc can build the emit functions automagically -%} - - -// Platform dependent source - -source %{ -%}
--- a/src/os_cpu/windows_x86/vm/windows_x86_32.ad Fri Oct 11 17:14:35 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,26 +0,0 @@ -// -// Copyright (c) 1999, 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. -// -// - -// X86 Win32 Architecture Description File -
--- a/src/os_cpu/windows_x86/vm/windows_x86_64.ad Fri Oct 11 17:14:35 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,63 +0,0 @@ -// -// Copyright (c) 2003, 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. -// -// - -// AMD64 Win32 Architecture Description File - -//----------OS-DEPENDENT ENCODING BLOCK----------------------------------------------------- -// This block specifies the encoding classes used by the compiler to output -// byte streams. Encoding classes generate functions which are called by -// Machine Instruction Nodes in order to generate the bit encoding of the -// instruction. Operands specify their base encoding interface with the -// interface keyword. There are currently supported four interfaces, -// REG_INTER, CONST_INTER, MEMORY_INTER, & COND_INTER. REG_INTER causes an -// operand to generate a function which returns its register number when -// queried. CONST_INTER causes an operand to generate a function which -// returns the value of the constant when queried. MEMORY_INTER causes an -// operand to generate four functions which return the Base Register, the -// Index Register, the Scale Value, and the Offset Value of the operand when -// queried. COND_INTER causes an operand to generate six functions which -// return the encoding code (ie - encoding bits for the instruction) -// associated with each basic boolean condition for a conditional instruction. -// Instructions specify two basic values for encoding. They use the -// ins_encode keyword to specify their encoding class (which must be one of -// the class names specified in the encoding block), and they use the -// opcode keyword to specify, in order, their primary, secondary, and -// tertiary opcode. Only the opcode sections which a particular instruction -// needs for encoding need to be specified. -encode %{ - // Build emit functions for each basic byte or larger field in the intel - // encoding scheme (opcode, rm, sib, immediate), and call them from C++ - // code in the enc_class source block. Emit functions will live in the - // main source block for now. In future, we can generalize this by - // adding a syntax that specifies the sizes of fields in an order, - // so that the adlc can build the emit functions automagically - -%} - - -// Platform dependent source - -source %{ - -%}
--- a/src/share/tools/ProjectCreator/BuildConfig.java Fri Oct 11 17:14:35 2013 +0200 +++ b/src/share/tools/ProjectCreator/BuildConfig.java Fri Oct 11 17:21:14 2013 +0200 @@ -160,6 +160,69 @@ return rv; } + // Returns true if the specified path refers to a relative alternate + // source file. RelativeAltSrcInclude is usually "src\closed". + public static boolean matchesRelativeAltSrcInclude(String path) { + String relativeAltSrcInclude = + getFieldString(null, "RelativeAltSrcInclude"); + Vector<String> v = getFieldVector(null, "AltRelativeInclude"); + for (String pathPart : v) { + if (path.contains(relativeAltSrcInclude + Util.sep + pathPart)) { + return true; + } + } + return false; + } + + // Returns the relative alternate source file for the specified path. + // Null is returned if the specified path does not have a matching + // alternate source file. + public static String getMatchingRelativeAltSrcFile(String path) { + Vector<String> v = getFieldVector(null, "RelativeAltSrcFileList"); + if (v == null) { + return null; + } + for (String pathPart : v) { + if (path.endsWith(pathPart)) { + String relativeAltSrcInclude = + getFieldString(null, "RelativeAltSrcInclude"); + return relativeAltSrcInclude + Util.sep + pathPart; + } + } + return null; + } + + // Returns true if the specified path has a matching alternate + // source file. + public static boolean matchesRelativeAltSrcFile(String path) { + return getMatchingRelativeAltSrcFile(path) != null; + } + + // Track the specified alternate source file. The source file is + // tracked without the leading .*<sep><RelativeAltSrcFileList><sep> + // part to make matching regular source files easier. + public static void trackRelativeAltSrcFile(String path) { + String pattern = getFieldString(null, "RelativeAltSrcInclude") + + Util.sep; + int altSrcInd = path.indexOf(pattern); + if (altSrcInd == -1) { + // not an AltSrc path + return; + } + + altSrcInd += pattern.length(); + if (altSrcInd >= path.length()) { + // not a valid AltSrc path + return; + } + + String altSrcFile = path.substring(altSrcInd); + Vector v = getFieldVector(null, "RelativeAltSrcFileList"); + if (v == null || !v.contains(altSrcFile)) { + addFieldVector(null, "RelativeAltSrcFileList", altSrcFile); + } + } + void addTo(Hashtable ht, String key, String value) { ht.put(expandFormat(key), expandFormat(value)); } @@ -306,8 +369,19 @@ private Vector getSourceIncludes() { Vector<String> rv = new Vector<String>(); + String sourceBase = getFieldString(null, "SourceBase"); + + // add relative alternate source include values: + String relativeAltSrcInclude = + getFieldString(null, "RelativeAltSrcInclude"); + Vector<String> asri = new Vector<String>(); + collectRelevantVectors(asri, "AltRelativeInclude"); + for (String f : asri) { + rv.add(sourceBase + Util.sep + relativeAltSrcInclude + + Util.sep + f); + } + Vector<String> ri = new Vector<String>(); - String sourceBase = getFieldString(null, "SourceBase"); collectRelevantVectors(ri, "RelativeInclude"); for (String f : ri) { rv.add(sourceBase + Util.sep + f); @@ -607,35 +681,6 @@ } } -class CoreDebugConfig extends GenericDebugNonKernelConfig { - String getOptFlag() { - return getCI().getNoOptFlag(); - } - - CoreDebugConfig() { - initNames("core", "debug", "jvm.dll"); - init(getIncludes(), getDefines()); - } -} - -class CoreFastDebugConfig extends GenericDebugNonKernelConfig { - String getOptFlag() { - return getCI().getOptFlag(); - } - - CoreFastDebugConfig() { - initNames("core", "fastdebug", "jvm.dll"); - init(getIncludes(), getDefines()); - } -} - -class CoreProductConfig extends ProductConfig { - CoreProductConfig() { - initNames("core", "product", "jvm.dll"); - init(getIncludes(), getDefines()); - } -} - abstract class CompilerInterface { abstract Vector getBaseCompilerFlags(Vector defines, Vector includes, String outDir);
--- a/src/share/tools/ProjectCreator/FileTreeCreator.java Fri Oct 11 17:14:35 2013 +0200 +++ b/src/share/tools/ProjectCreator/FileTreeCreator.java Fri Oct 11 17:21:14 2013 +0200 @@ -12,11 +12,15 @@ final int startDirLength; Stack<DirAttributes> attributes = new Stack<DirAttributes>(); Vector<BuildConfig> allConfigs; - WinGammaPlatformVC10 wg; + WinGammaPlatform wg; + WinGammaPlatformVC10 wg10; - public FileTreeCreator(Path startDir, Vector<BuildConfig> allConfigs, WinGammaPlatformVC10 wg) { + public FileTreeCreator(Path startDir, Vector<BuildConfig> allConfigs, WinGammaPlatform wg) { super(); this.wg = wg; + if (wg instanceof WinGammaPlatformVC10) { + wg10 = (WinGammaPlatformVC10)wg; + } this.allConfigs = allConfigs; this.startDir = startDir; startDirLength = startDir.toAbsolutePath().toString().length();
--- a/src/share/tools/ProjectCreator/FileTreeCreatorVC10.java Fri Oct 11 17:14:35 2013 +0200 +++ b/src/share/tools/ProjectCreator/FileTreeCreatorVC10.java Fri Oct 11 17:21:14 2013 +0200 @@ -1,3 +1,27 @@ +/* + * Copyright (c) 2012, 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. + * + */ + import static java.nio.file.FileVisitResult.CONTINUE; import java.io.IOException; @@ -21,6 +45,8 @@ boolean usePch = false; boolean disablePch = false; boolean useIgnore = false; + boolean isAltSrc = false; // only needed as a debugging crumb + boolean isReplacedByAltSrc = false; String fileName = file.getFileName().toString(); // TODO hideFile @@ -30,6 +56,26 @@ usePch = true; } + String fileLoc = vcProjLocation.relativize(file).toString(); + + // isAltSrc and isReplacedByAltSrc applies to all configs for a file + if (BuildConfig.matchesRelativeAltSrcInclude( + file.toAbsolutePath().toString())) { + // current file is an alternate source file so track it + isAltSrc = true; + BuildConfig.trackRelativeAltSrcFile( + file.toAbsolutePath().toString()); + } else if (BuildConfig.matchesRelativeAltSrcFile( + file.toAbsolutePath().toString())) { + // current file is a regular file that matches an alternate + // source file so yack about replacing the regular file + isReplacedByAltSrc = true; + System.out.println("INFO: alternate source file '" + + BuildConfig.getMatchingRelativeAltSrcFile( + file.toAbsolutePath().toString()) + + "' replaces '" + fileLoc + "'"); + } + for (BuildConfig cfg : allConfigs) { if (cfg.lookupHashFieldInContext("IgnoreFile", fileName) != null) { useIgnore = true; @@ -58,10 +104,9 @@ } } - String tagName = wg.getFileTagFromSuffix(fileName); - String fileLoc = vcProjLocation.relativize(file).toString(); + String tagName = wg10.getFileTagFromSuffix(fileName); - if (!useIgnore && !disablePch && !usePch) { + if (!useIgnore && !disablePch && !usePch && !isReplacedByAltSrc) { wg.tag(tagName, new String[] { "Include", fileLoc}); } else { wg.startTag( @@ -79,12 +124,17 @@ if (disablePch) { wg.tag("PrecompiledHeader", "Condition", "'$(Configuration)|$(Platform)'=='" + cfg.get("Name") + "'"); } + if (isReplacedByAltSrc) { + wg.tagData("ExcludedFromBuild", "true", "Condition", + "'$(Configuration)|$(Platform)'=='" + + cfg.get("Name") + "'"); + } } wg.endTag(); } String filter = startDir.relativize(file.getParent().toAbsolutePath()).toString(); - wg.addFilterDependency(fileLoc, filter); + wg10.addFilterDependency(fileLoc, filter); return CONTINUE; } @@ -113,7 +163,7 @@ if (!hide) { String name = startDir.relativize(path.toAbsolutePath()).toString(); if (!"".equals(name)) { - wg.addFilter(name); + wg10.addFilter(name); } attributes.push(newAttr); @@ -138,6 +188,4 @@ public void writeFileTree() throws IOException { Files.walkFileTree(this.startDir, this); } - - - } \ No newline at end of file +}
--- a/src/share/tools/ProjectCreator/FileTreeCreatorVC7.java Fri Oct 11 17:14:35 2013 +0200 +++ b/src/share/tools/ProjectCreator/FileTreeCreatorVC7.java Fri Oct 11 17:21:14 2013 +0200 @@ -12,7 +12,7 @@ public class FileTreeCreatorVC7 extends FileTreeCreator { public FileTreeCreatorVC7(Path startDir, Vector<BuildConfig> allConfigs, WinGammaPlatform wg) { - super(startDir, allConfigs, null); + super(startDir, allConfigs, wg); } @Override
--- a/src/share/tools/ProjectCreator/ProjectCreator.java Fri Oct 11 17:14:35 2013 +0200 +++ b/src/share/tools/ProjectCreator/ProjectCreator.java Fri Oct 11 17:21:14 2013 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -39,10 +39,15 @@ + "jvm.dll; no trailing slash>"); System.err.println(" If any of the above are specified, " + "they must all be."); + System.err.println(" Note: if '-altRelativeInclude' option below is " + + "used, then the '-relativeAltSrcInclude' option must be used " + + "to specify the alternate source dir, e.g., 'src\\closed'"); System.err.println(" Additional, optional arguments, which can be " + "specified multiple times:"); System.err.println(" -absoluteInclude <string containing absolute " + "path to include directory>"); + System.err.println(" -altRelativeInclude <string containing " + + "alternate include directory relative to -envVar>"); System.err.println(" -relativeInclude <string containing include " + "directory relative to -envVar>"); System.err.println(" -define <preprocessor flag to be #defined "
--- a/src/share/tools/ProjectCreator/WinGammaPlatform.java Fri Oct 11 17:14:35 2013 +0200 +++ b/src/share/tools/ProjectCreator/WinGammaPlatform.java Fri Oct 11 17:21:14 2013 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -140,10 +140,17 @@ "already exist>"); System.err.println(" If any of the above are specified, "+ "they must all be."); + System.err.println(" Note: if '-altRelativeInclude' option below " + + "is used, then the '-relativeAltSrcInclude' " + + "option must be used to specify the alternate " + + "source dir, e.g., 'src\\closed'"); System.err.println(" Additional, optional arguments, which can be " + "specified multiple times:"); System.err.println(" -absoluteInclude <string containing absolute " + "path to include directory>"); + System.err.println(" -altRelativeInclude <string containing " + + "alternate include directory relative to " + + "-sourceBase>"); System.err.println(" -relativeInclude <string containing include " + "directory relative to -sourceBase>"); System.err.println(" -define <preprocessor flag to be #defined " + @@ -343,6 +350,12 @@ HsArgHandler.VECTOR ), + new HsArgRule("-altRelativeInclude", + "AltRelativeInclude", + null, + HsArgHandler.VECTOR + ), + new HsArgRule("-relativeInclude", "RelativeInclude", null, @@ -355,6 +368,12 @@ HsArgHandler.VECTOR ), + new HsArgRule("-relativeAltSrcInclude", + "RelativeAltSrcInclude", + null, + HsArgHandler.STRING + ), + new HsArgRule("-relativeSrcInclude", "RelativeSrcInclude", null, @@ -564,10 +583,6 @@ allConfigs.add(new TieredFastDebugConfig()); allConfigs.add(new TieredProductConfig()); - allConfigs.add(new CoreDebugConfig()); - allConfigs.add(new CoreFastDebugConfig()); - allConfigs.add(new CoreProductConfig()); - return allConfigs; }
--- a/src/share/tools/ProjectCreator/WinGammaPlatformVC10.java Fri Oct 11 17:14:35 2013 +0200 +++ b/src/share/tools/ProjectCreator/WinGammaPlatformVC10.java Fri Oct 11 17:21:14 2013 +0200 @@ -1,3 +1,27 @@ +/* + * Copyright (c) 2011, 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. + * + */ + import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; @@ -24,7 +48,7 @@ public void writeProjectFile(String projectFileName, String projectName, Vector<BuildConfig> allConfigs) throws IOException { System.out.println(); - System.out.print(" Writing .vcxproj file: " + projectFileName); + System.out.println(" Writing .vcxproj file: " + projectFileName); String projDir = Util.normalize(new File(projectFileName).getParent()); @@ -114,7 +138,7 @@ endTag(); printWriter.close(); - System.out.println(" Done."); + System.out.println(" Done writing .vcxproj file."); writeFilterFile(projectFileName, projectName, allConfigs, projDir); writeUserFile(projectFileName, allConfigs);
--- a/src/share/tools/ProjectCreator/WinGammaPlatformVC7.java Fri Oct 11 17:14:35 2013 +0200 +++ b/src/share/tools/ProjectCreator/WinGammaPlatformVC7.java Fri Oct 11 17:21:14 2013 +0200 @@ -139,19 +139,22 @@ tagV("Tool", cfg.getV("LinkerFlags")); - tag("Tool", - new String[] { - "Name", - "VCPostBuildEventTool", - "Description", - BuildConfig - .getFieldString(null, "PostbuildDescription"), - // Caution: String.replace(String,String) is available - // from JDK5 onwards only - "CommandLine", - cfg.expandFormat(BuildConfig.getFieldString(null, - "PostbuildCommand").replace("\t", - "
")) }); + String postBuildCmd = BuildConfig.getFieldString(null, + "PostbuildCommand"); + if (postBuildCmd != null) { + tag("Tool", + new String[] { + "Name", + "VCPostBuildEventTool", + "Description", + BuildConfig + .getFieldString(null, "PostbuildDescription"), + // Caution: String.replace(String,String) is available + // from JDK5 onwards only + "CommandLine", + cfg.expandFormat(postBuildCmd.replace("\t", + "
")) }); + } tag("Tool", new String[] { "Name", "VCPreBuildEventTool" });
--- a/src/share/vm/c1/c1_LIRGenerator.cpp Fri Oct 11 17:14:35 2013 +0200 +++ b/src/share/vm/c1/c1_LIRGenerator.cpp Fri Oct 11 17:21:14 2013 +0200 @@ -2295,7 +2295,7 @@ if (gen_type_check) { // We have determined that offset == referent_offset && src != null. // if (src->_klass->_reference_type == REF_NONE) -> continue - __ move(new LIR_Address(src.result(), oopDesc::klass_offset_in_bytes(), UseCompressedKlassPointers ? T_OBJECT : T_ADDRESS), src_klass); + __ move(new LIR_Address(src.result(), oopDesc::klass_offset_in_bytes(), T_ADDRESS), src_klass); LIR_Address* reference_type_addr = new LIR_Address(src_klass, in_bytes(InstanceKlass::reference_type_offset()), T_BYTE); LIR_Opr reference_type = new_register(T_INT); __ move(reference_type_addr, reference_type);
--- a/src/share/vm/ci/ciReplay.cpp Fri Oct 11 17:14:35 2013 +0200 +++ b/src/share/vm/ci/ciReplay.cpp Fri Oct 11 17:21:14 2013 +0200 @@ -299,7 +299,7 @@ Symbol* method_signature = parse_symbol(CHECK_NULL); Method* m = k->find_method(method_name, method_signature); if (m == NULL) { - report_error("can't find method"); + report_error("Can't find method"); } return m; } @@ -398,8 +398,8 @@ // compile <klass> <name> <signature> <entry_bci> <comp_level> void process_compile(TRAPS) { - // methodHandle method; Method* method = parse_method(CHECK); + if (had_error()) return; int entry_bci = parse_int("entry_bci"); const char* comp_level_label = "comp_level"; int comp_level = parse_int(comp_level_label); @@ -440,6 +440,7 @@ // void process_ciMethod(TRAPS) { Method* method = parse_method(CHECK); + if (had_error()) return; ciMethodRecord* rec = new_ciMethod(method); rec->invocation_counter = parse_int("invocation_counter"); rec->backedge_counter = parse_int("backedge_counter"); @@ -451,6 +452,7 @@ // ciMethodData <klass> <name> <signature> <state> <current mileage> orig <length> # # ... data <length> # # ... oops <length> void process_ciMethodData(TRAPS) { Method* method = parse_method(CHECK); + if (had_error()) return; /* jsut copied from Method, to build interpret data*/ if (InstanceRefKlass::owns_pending_list_lock((JavaThread*)THREAD)) { return;
--- a/src/share/vm/classfile/classLoader.cpp Fri Oct 11 17:14:35 2013 +0200 +++ b/src/share/vm/classfile/classLoader.cpp Fri Oct 11 17:21:14 2013 +0200 @@ -878,7 +878,7 @@ instanceKlassHandle ClassLoader::load_classfile(Symbol* h_name, TRAPS) { ResourceMark rm(THREAD); - EventMark m("loading class " INTPTR_FORMAT, (address)h_name); + EventMark m("loading class %s", h_name->as_C_string()); ThreadProfilerMark tpm(ThreadProfilerMark::classLoaderRegion); stringStream st;
--- a/src/share/vm/classfile/javaClasses.cpp Fri Oct 11 17:14:35 2013 +0200 +++ b/src/share/vm/classfile/javaClasses.cpp Fri Oct 11 17:21:14 2013 +0200 @@ -2563,6 +2563,26 @@ *offset = value; } +// Support for java_lang_invoke_DirectMethodHandle + +int java_lang_invoke_DirectMethodHandle::_member_offset; + +oop java_lang_invoke_DirectMethodHandle::member(oop dmh) { + oop member_name = NULL; + bool is_dmh = dmh->is_oop() && java_lang_invoke_DirectMethodHandle::is_instance(dmh); + assert(is_dmh, "a DirectMethodHandle oop is expected"); + if (is_dmh) { + member_name = dmh->obj_field(member_offset_in_bytes()); + } + return member_name; +} + +void java_lang_invoke_DirectMethodHandle::compute_offsets() { + Klass* klass_oop = SystemDictionary::DirectMethodHandle_klass(); + if (klass_oop != NULL && EnableInvokeDynamic) { + compute_offset(_member_offset, klass_oop, vmSymbols::member_name(), vmSymbols::java_lang_invoke_MemberName_signature()); + } +} // Support for java_lang_invoke_MethodHandle @@ -3214,6 +3234,7 @@ java_lang_ThreadGroup::compute_offsets(); if (EnableInvokeDynamic) { java_lang_invoke_MethodHandle::compute_offsets(); + java_lang_invoke_DirectMethodHandle::compute_offsets(); java_lang_invoke_MemberName::compute_offsets(); java_lang_invoke_LambdaForm::compute_offsets(); java_lang_invoke_MethodType::compute_offsets();
--- a/src/share/vm/classfile/javaClasses.hpp Fri Oct 11 17:14:35 2013 +0200 +++ b/src/share/vm/classfile/javaClasses.hpp Fri Oct 11 17:21:14 2013 +0200 @@ -986,6 +986,32 @@ static int form_offset_in_bytes() { return _form_offset; } }; +// Interface to java.lang.invoke.DirectMethodHandle objects + +class java_lang_invoke_DirectMethodHandle: AllStatic { + friend class JavaClasses; + + private: + static int _member_offset; // the MemberName of this DMH + + static void compute_offsets(); + + public: + // Accessors + static oop member(oop mh); + + // Testers + static bool is_subclass(Klass* klass) { + return klass->is_subclass_of(SystemDictionary::DirectMethodHandle_klass()); + } + static bool is_instance(oop obj) { + return obj != NULL && is_subclass(obj->klass()); + } + + // Accessors for code generation: + static int member_offset_in_bytes() { return _member_offset; } +}; + // Interface to java.lang.invoke.LambdaForm objects // (These are a private interface for managing adapter code generation.)
--- a/src/share/vm/classfile/systemDictionary.hpp Fri Oct 11 17:14:35 2013 +0200 +++ b/src/share/vm/classfile/systemDictionary.hpp Fri Oct 11 17:21:14 2013 +0200 @@ -151,6 +151,7 @@ do_klass(reflect_CallerSensitive_klass, sun_reflect_CallerSensitive, Opt ) \ \ /* support for dynamic typing; it's OK if these are NULL in earlier JDKs */ \ + do_klass(DirectMethodHandle_klass, java_lang_invoke_DirectMethodHandle, Opt ) \ do_klass(MethodHandle_klass, java_lang_invoke_MethodHandle, Pre_JSR292 ) \ do_klass(MemberName_klass, java_lang_invoke_MemberName, Pre_JSR292 ) \ do_klass(MethodHandleNatives_klass, java_lang_invoke_MethodHandleNatives, Pre_JSR292 ) \ @@ -202,6 +203,7 @@ do_klass(HotSpotResolvedObjectType_klass, com_oracle_graal_hotspot_meta_HotSpotResolvedObjectType, Opt) \ do_klass(HotSpotMonitorValue_klass, com_oracle_graal_hotspot_meta_HotSpotMonitorValue, Opt) \ do_klass(LocalImpl_klass, com_oracle_graal_hotspot_debug_LocalImpl, Opt) \ + do_klass(CompilerThread_klass, com_oracle_graal_hotspot_CompilerThread, Opt) \ /* graal.api.code */ \ do_klass(Assumptions_klass, com_oracle_graal_api_code_Assumptions, Opt) \ do_klass(Assumptions_ConcreteMethod_klass, com_oracle_graal_api_code_Assumptions_ConcreteMethod, Opt) \
--- a/src/share/vm/classfile/vmSymbols.hpp Fri Oct 11 17:14:35 2013 +0200 +++ b/src/share/vm/classfile/vmSymbols.hpp Fri Oct 11 17:21:14 2013 +0200 @@ -255,6 +255,7 @@ /* Support for JSR 292 & invokedynamic (JDK 1.7 and above) */ \ template(java_lang_invoke_CallSite, "java/lang/invoke/CallSite") \ template(java_lang_invoke_ConstantCallSite, "java/lang/invoke/ConstantCallSite") \ + template(java_lang_invoke_DirectMethodHandle, "java/lang/invoke/DirectMethodHandle") \ template(java_lang_invoke_MutableCallSite, "java/lang/invoke/MutableCallSite") \ template(java_lang_invoke_VolatileCallSite, "java/lang/invoke/VolatileCallSite") \ template(java_lang_invoke_MethodHandle, "java/lang/invoke/MethodHandle") \ @@ -311,6 +312,7 @@ template(com_oracle_graal_hotspot_meta_HotSpotResolvedObjectType, "com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType") \ template(com_oracle_graal_hotspot_meta_HotSpotMonitorValue, "com/oracle/graal/hotspot/meta/HotSpotMonitorValue") \ template(com_oracle_graal_hotspot_debug_LocalImpl, "com/oracle/graal/hotspot/debug/LocalImpl") \ + template(com_oracle_graal_hotspot_CompilerThread, "com/oracle/graal/hotspot/CompilerThread") \ template(com_oracle_graal_hotspot_ptx_PTXHotSpotGraalRuntime, "com/oracle/graal/hotspot/ptx/PTXHotSpotGraalRuntime")\ AMD64_ONLY(template(com_oracle_graal_hotspot_amd64_AMD64HotSpotGraalRuntime,"com/oracle/graal/hotspot/amd64/AMD64HotSpotGraalRuntime"))\ SPARC_ONLY(template(com_oracle_graal_hotspot_sparc_SPARCHotSpotGraalRuntime,"com/oracle/graal/hotspot/sparc/SPARCHotSpotGraalRuntime"))\ @@ -463,6 +465,7 @@ template(thread_id_name, "tid") \ template(newInstance0_name, "newInstance0") \ template(limit_name, "limit") \ + template(member_name, "member") \ template(forName_name, "forName") \ template(forName0_name, "forName0") \ template(isJavaIdentifierStart_name, "isJavaIdentifierStart") \
--- a/src/share/vm/gc_implementation/concurrentMarkSweep/cmsOopClosures.hpp Fri Oct 11 17:14:35 2013 +0200 +++ b/src/share/vm/gc_implementation/concurrentMarkSweep/cmsOopClosures.hpp Fri Oct 11 17:21:14 2013 +0200 @@ -122,6 +122,22 @@ } }; +class Par_MarkRefsIntoClosure: public CMSOopsInGenClosure { + private: + const MemRegion _span; + CMSBitMap* _bitMap; + protected: + DO_OOP_WORK_DEFN + public: + Par_MarkRefsIntoClosure(MemRegion span, CMSBitMap* bitMap); + virtual void do_oop(oop* p); + virtual void do_oop(narrowOop* p); + + Prefetch::style prefetch_style() { + return Prefetch::do_read; + } +}; + // A variant of the above used in certain kinds of CMS // marking verification. class MarkRefsIntoVerifyClosure: public CMSOopsInGenClosure {
--- a/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp Fri Oct 11 17:14:35 2013 +0200 +++ b/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp Fri Oct 11 17:21:14 2013 +0200 @@ -50,6 +50,7 @@ #include "memory/genMarkSweep.hpp" #include "memory/genOopClosures.inline.hpp" #include "memory/iterator.hpp" +#include "memory/padded.hpp" #include "memory/referencePolicy.hpp" #include "memory/resourceArea.hpp" #include "memory/tenuredGeneration.hpp" @@ -569,6 +570,7 @@ _restart_addr(NULL), _overflow_list(NULL), _stats(cmsGen), + _eden_chunk_lock(new Mutex(Mutex::leaf + 1, "CMS_eden_chunk_lock", true)), _eden_chunk_array(NULL), // may be set in ctor body _eden_chunk_capacity(0), // -- ditto -- _eden_chunk_index(0), // -- ditto -- @@ -732,7 +734,7 @@ assert(_eden_chunk_array != NULL || _eden_chunk_capacity == 0, "Error"); // Support for parallelizing survivor space rescan - if (CMSParallelRemarkEnabled && CMSParallelSurvivorRemarkEnabled) { + if ((CMSParallelRemarkEnabled && CMSParallelSurvivorRemarkEnabled) || CMSParallelInitialMarkEnabled) { const size_t max_plab_samples = ((DefNewGeneration*)_young_gen)->max_survivor_size()/MinTLABSize; @@ -2137,6 +2139,39 @@ } +void CMSCollector::print_eden_and_survivor_chunk_arrays() { + DefNewGeneration* dng = _young_gen->as_DefNewGeneration(); + EdenSpace* eden_space = dng->eden(); + ContiguousSpace* from_space = dng->from(); + ContiguousSpace* to_space = dng->to(); + // Eden + if (_eden_chunk_array != NULL) { + gclog_or_tty->print_cr("eden " PTR_FORMAT "-" PTR_FORMAT "-" PTR_FORMAT "(" SIZE_FORMAT ")", + eden_space->bottom(), eden_space->top(), + eden_space->end(), eden_space->capacity()); + gclog_or_tty->print_cr("_eden_chunk_index=" SIZE_FORMAT ", " + "_eden_chunk_capacity=" SIZE_FORMAT, + _eden_chunk_index, _eden_chunk_capacity); + for (size_t i = 0; i < _eden_chunk_index; i++) { + gclog_or_tty->print_cr("_eden_chunk_array[" SIZE_FORMAT "]=" PTR_FORMAT, + i, _eden_chunk_array[i]); + } + } + // Survivor + if (_survivor_chunk_array != NULL) { + gclog_or_tty->print_cr("survivor " PTR_FORMAT "-" PTR_FORMAT "-" PTR_FORMAT "(" SIZE_FORMAT ")", + from_space->bottom(), from_space->top(), + from_space->end(), from_space->capacity()); + gclog_or_tty->print_cr("_survivor_chunk_index=" SIZE_FORMAT ", " + "_survivor_chunk_capacity=" SIZE_FORMAT, + _survivor_chunk_index, _survivor_chunk_capacity); + for (size_t i = 0; i < _survivor_chunk_index; i++) { + gclog_or_tty->print_cr("_survivor_chunk_array[" SIZE_FORMAT "]=" PTR_FORMAT, + i, _survivor_chunk_array[i]); + } + } +} + void CMSCollector::getFreelistLocks() const { // Get locks for all free lists in all generations that this // collector is responsible for @@ -3549,6 +3584,31 @@ // CMS work +// The common parts of CMSParInitialMarkTask and CMSParRemarkTask. +class CMSParMarkTask : public AbstractGangTask { + protected: + CMSCollector* _collector; + int _n_workers; + CMSParMarkTask(const char* name, CMSCollector* collector, int n_workers) : + AbstractGangTask(name), + _collector(collector), + _n_workers(n_workers) {} + // Work method in support of parallel rescan ... of young gen spaces + void do_young_space_rescan(uint worker_id, OopsInGenClosure* cl, + ContiguousSpace* space, + HeapWord** chunk_array, size_t chunk_top); + void work_on_young_gen_roots(uint worker_id, OopsInGenClosure* cl); +}; + +// Parallel initial mark task +class CMSParInitialMarkTask: public CMSParMarkTask { + public: + CMSParInitialMarkTask(CMSCollector* collector, int n_workers) : + CMSParMarkTask("Scan roots and young gen for initial mark in parallel", + collector, n_workers) {} + void work(uint worker_id); +}; + // Checkpoint the roots into this generation from outside // this generation. [Note this initial checkpoint need only // be approximate -- we'll do a catch up phase subsequently.] @@ -3646,19 +3706,42 @@ // the klasses. The claimed marks need to be cleared before marking starts. ClassLoaderDataGraph::clear_claimed_marks(); - CMKlassClosure klass_closure(¬Older); + if (CMSPrintEdenSurvivorChunks) { + print_eden_and_survivor_chunk_arrays(); + } + { COMPILER2_PRESENT(DerivedPointerTableDeactivate dpt_deact;) - gch->rem_set()->prepare_for_younger_refs_iterate(false); // Not parallel. - gch->gen_process_strong_roots(_cmsGen->level(), - true, // younger gens are roots - true, // activate StrongRootsScope - false, // not scavenging - SharedHeap::ScanningOption(roots_scanning_options()), - ¬Older, - true, // walk all of code cache if (so & SO_CodeCache) - NULL, - &klass_closure); + if (CMSParallelInitialMarkEnabled && CollectedHeap::use_parallel_gc_threads()) { + // The parallel version. + FlexibleWorkGang* workers = gch->workers(); + assert(workers != NULL, "Need parallel worker threads."); + int n_workers = workers->active_workers(); + CMSParInitialMarkTask tsk(this, n_workers); + gch->set_par_threads(n_workers); + initialize_sequential_subtasks_for_young_gen_rescan(n_workers); + if (n_workers > 1) { + GenCollectedHeap::StrongRootsScope srs(gch); + workers->run_task(&tsk); + } else { + GenCollectedHeap::StrongRootsScope srs(gch); + tsk.work(0); + } + gch->set_par_threads(0); + } else { + // The serial version. + CMKlassClosure klass_closure(¬Older); + gch->rem_set()->prepare_for_younger_refs_iterate(false); // Not parallel. + gch->gen_process_strong_roots(_cmsGen->level(), + true, // younger gens are roots + true, // activate StrongRootsScope + false, // not scavenging + SharedHeap::ScanningOption(roots_scanning_options()), + ¬Older, + true, // walk all of code cache if (so & SO_CodeCache) + NULL, + &klass_closure); + } } // Clear mod-union table; it will be dirtied in the prologue of @@ -4417,7 +4500,9 @@ verify_overflow_empty(); _abort_preclean = false; if (CMSPrecleaningEnabled) { - _eden_chunk_index = 0; + if (!CMSEdenChunksRecordAlways) { + _eden_chunk_index = 0; + } size_t used = get_eden_used(); size_t capacity = get_eden_capacity(); // Don't start sampling unless we will get sufficiently @@ -4526,7 +4611,9 @@ if (!_start_sampling) { return; } - if (_eden_chunk_array) { + // When CMSEdenChunksRecordAlways is true, the eden chunk array + // is populated by the young generation. + if (_eden_chunk_array != NULL && !CMSEdenChunksRecordAlways) { if (_eden_chunk_index < _eden_chunk_capacity) { _eden_chunk_array[_eden_chunk_index] = *_top_addr; // take sample assert(_eden_chunk_array[_eden_chunk_index] <= *_end_addr, @@ -5010,6 +5097,10 @@ // Update the saved marks which may affect the root scans. gch->save_marks(); + if (CMSPrintEdenSurvivorChunks) { + print_eden_and_survivor_chunk_arrays(); + } + { COMPILER2_PRESENT(DerivedPointerTableDeactivate dpt_deact;) @@ -5116,10 +5207,53 @@ } } +void CMSParInitialMarkTask::work(uint worker_id) { + elapsedTimer _timer; + ResourceMark rm; + HandleMark hm; + + // ---------- scan from roots -------------- + _timer.start(); + GenCollectedHeap* gch = GenCollectedHeap::heap(); + Par_MarkRefsIntoClosure par_mri_cl(_collector->_span, &(_collector->_markBitMap)); + CMKlassClosure klass_closure(&par_mri_cl); + + // ---------- young gen roots -------------- + { + work_on_young_gen_roots(worker_id, &par_mri_cl); + _timer.stop(); + if (PrintCMSStatistics != 0) { + gclog_or_tty->print_cr( + "Finished young gen initial mark scan work in %dth thread: %3.3f sec", + worker_id, _timer.seconds()); + } + } + + // ---------- remaining roots -------------- + _timer.reset(); + _timer.start(); + gch->gen_process_strong_roots(_collector->_cmsGen->level(), + false, // yg was scanned above + false, // this is parallel code + false, // not scavenging + SharedHeap::ScanningOption(_collector->CMSCollector::roots_scanning_options()), + &par_mri_cl, + true, // walk all of code cache if (so & SO_CodeCache) + NULL, + &klass_closure); + assert(_collector->should_unload_classes() + || (_collector->CMSCollector::roots_scanning_options() & SharedHeap::SO_CodeCache), + "if we didn't scan the code cache, we have to be ready to drop nmethods with expired weak oops"); + _timer.stop(); + if (PrintCMSStatistics != 0) { + gclog_or_tty->print_cr( + "Finished remaining root initial mark scan work in %dth thread: %3.3f sec", + worker_id, _timer.seconds()); + } +} + // Parallel remark task -class CMSParRemarkTask: public AbstractGangTask { - CMSCollector* _collector; - int _n_workers; +class CMSParRemarkTask: public CMSParMarkTask { CompactibleFreeListSpace* _cms_space; // The per-thread work queues, available here for stealing. @@ -5133,10 +5267,9 @@ CompactibleFreeListSpace* cms_space, int n_workers, FlexibleWorkGang* workers, OopTaskQueueSet* task_queues): - AbstractGangTask("Rescan roots and grey objects in parallel"), - _collector(collector), + CMSParMarkTask("Rescan roots and grey objects in parallel", + collector, n_workers), _cms_space(cms_space), - _n_workers(n_workers), _task_queues(task_queues), _term(n_workers, task_queues) { } @@ -5150,11 +5283,6 @@ void work(uint worker_id); private: - // Work method in support of parallel rescan ... of young gen spaces - void do_young_space_rescan(int i, Par_MarkRefsIntoAndScanClosure* cl, - ContiguousSpace* space, - HeapWord** chunk_array, size_t chunk_top); - // ... of dirty cards in old space void do_dirty_card_rescan_tasks(CompactibleFreeListSpace* sp, int i, Par_MarkRefsIntoAndScanClosure* cl); @@ -5186,6 +5314,25 @@ } }; +void CMSParMarkTask::work_on_young_gen_roots(uint worker_id, OopsInGenClosure* cl) { + DefNewGeneration* dng = _collector->_young_gen->as_DefNewGeneration(); + EdenSpace* eden_space = dng->eden(); + ContiguousSpace* from_space = dng->from(); + ContiguousSpace* to_space = dng->to(); + + HeapWord** eca = _collector->_eden_chunk_array; + size_t ect = _collector->_eden_chunk_index; + HeapWord** sca = _collector->_survivor_chunk_array; + size_t sct = _collector->_survivor_chunk_index; + + assert(ect <= _collector->_eden_chunk_capacity, "out of bounds"); + assert(sct <= _collector->_survivor_chunk_capacity, "out of bounds"); + + do_young_space_rescan(worker_id, cl, to_space, NULL, 0); + do_young_space_rescan(worker_id, cl, from_space, sca, sct); + do_young_space_rescan(worker_id, cl, eden_space, eca, ect); +} + // work_queue(i) is passed to the closure // Par_MarkRefsIntoAndScanClosure. The "i" parameter // also is passed to do_dirty_card_rescan_tasks() and to @@ -5210,23 +5357,7 @@ // work first. // ---------- young gen roots -------------- { - DefNewGeneration* dng = _collector->_young_gen->as_DefNewGeneration(); - EdenSpace* eden_space = dng->eden(); - ContiguousSpace* from_space = dng->from(); - ContiguousSpace* to_space = dng->to(); - - HeapWord** eca = _collector->_eden_chunk_array; - size_t ect = _collector->_eden_chunk_index; - HeapWord** sca = _collector->_survivor_chunk_array; - size_t sct = _collector->_survivor_chunk_index; - - assert(ect <= _collector->_eden_chunk_capacity, "out of bounds"); - assert(sct <= _collector->_survivor_chunk_capacity, "out of bounds"); - - do_young_space_rescan(worker_id, &par_mrias_cl, to_space, NULL, 0); - do_young_space_rescan(worker_id, &par_mrias_cl, from_space, sca, sct); - do_young_space_rescan(worker_id, &par_mrias_cl, eden_space, eca, ect); - + work_on_young_gen_roots(worker_id, &par_mrias_cl); _timer.stop(); if (PrintCMSStatistics != 0) { gclog_or_tty->print_cr( @@ -5334,8 +5465,8 @@ // Note that parameter "i" is not used. void -CMSParRemarkTask::do_young_space_rescan(int i, - Par_MarkRefsIntoAndScanClosure* cl, ContiguousSpace* space, +CMSParMarkTask::do_young_space_rescan(uint worker_id, + OopsInGenClosure* cl, ContiguousSpace* space, HeapWord** chunk_array, size_t chunk_top) { // Until all tasks completed: // . claim an unclaimed task @@ -5530,6 +5661,32 @@ "Else our work is not yet done"); } +// Record object boundaries in _eden_chunk_array by sampling the eden +// top in the slow-path eden object allocation code path and record +// the boundaries, if CMSEdenChunksRecordAlways is true. If +// CMSEdenChunksRecordAlways is false, we use the other asynchronous +// sampling in sample_eden() that activates during the part of the +// preclean phase. +void CMSCollector::sample_eden_chunk() { + if (CMSEdenChunksRecordAlways && _eden_chunk_array != NULL) { + if (_eden_chunk_lock->try_lock()) { + // Record a sample. This is the critical section. The contents + // of the _eden_chunk_array have to be non-decreasing in the + // address order. + _eden_chunk_array[_eden_chunk_index] = *_top_addr; + assert(_eden_chunk_array[_eden_chunk_index] <= *_end_addr, + "Unexpected state of Eden"); + if (_eden_chunk_index == 0 || + ((_eden_chunk_array[_eden_chunk_index] > _eden_chunk_array[_eden_chunk_index-1]) && + (pointer_delta(_eden_chunk_array[_eden_chunk_index], + _eden_chunk_array[_eden_chunk_index-1]) >= CMSSamplingGrain))) { + _eden_chunk_index++; // commit sample + } + _eden_chunk_lock->unlock(); + } + } +} + // Return a thread-local PLAB recording array, as appropriate. void* CMSCollector::get_data_recorder(int thr_num) { if (_survivor_plab_array != NULL && @@ -5553,12 +5710,13 @@ // Merge the per-thread plab arrays into the global survivor chunk // array which will provide the partitioning of the survivor space -// for CMS rescan. +// for CMS initial scan and rescan. void CMSCollector::merge_survivor_plab_arrays(ContiguousSpace* surv, int no_of_gc_threads) { assert(_survivor_plab_array != NULL, "Error"); assert(_survivor_chunk_array != NULL, "Error"); - assert(_collectorState == FinalMarking, "Error"); + assert(_collectorState == FinalMarking || + (CMSParallelInitialMarkEnabled && _collectorState == InitialMarking), "Error"); for (int j = 0; j < no_of_gc_threads; j++) { _cursor[j] = 0; } @@ -5621,7 +5779,7 @@ } // Set up the space's par_seq_tasks structure for work claiming -// for parallel rescan of young gen. +// for parallel initial scan and rescan of young gen. // See ParRescanTask where this is currently used. void CMSCollector:: @@ -6748,6 +6906,28 @@ void MarkRefsIntoClosure::do_oop(oop* p) { MarkRefsIntoClosure::do_oop_work(p); } void MarkRefsIntoClosure::do_oop(narrowOop* p) { MarkRefsIntoClosure::do_oop_work(p); } +Par_MarkRefsIntoClosure::Par_MarkRefsIntoClosure( + MemRegion span, CMSBitMap* bitMap): + _span(span), + _bitMap(bitMap) +{ + assert(_ref_processor == NULL, "deliberately left NULL"); + assert(_bitMap->covers(_span), "_bitMap/_span mismatch"); +} + +void Par_MarkRefsIntoClosure::do_oop(oop obj) { + // if p points into _span, then mark corresponding bit in _markBitMap + assert(obj->is_oop(), "expected an oop"); + HeapWord* addr = (HeapWord*)obj; + if (_span.contains(addr)) { + // this should be made more efficient + _bitMap->par_mark(addr); + } +} + +void Par_MarkRefsIntoClosure::do_oop(oop* p) { Par_MarkRefsIntoClosure::do_oop_work(p); } +void Par_MarkRefsIntoClosure::do_oop(narrowOop* p) { Par_MarkRefsIntoClosure::do_oop_work(p); } + // A variant of the above, used for CMS marking verification. MarkRefsIntoVerifyClosure::MarkRefsIntoVerifyClosure( MemRegion span, CMSBitMap* verification_bm, CMSBitMap* cms_bm): @@ -9305,7 +9485,6 @@ return; } } - // Transfer some number of overflown objects to usual marking // stack. Return true if some objects were transferred. bool MarkRefsIntoAndScanClosure::take_from_overflow_list() { @@ -9377,4 +9556,3 @@ ShouldNotReachHere(); } } -
--- a/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp Fri Oct 11 17:14:35 2013 +0200 +++ b/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp Fri Oct 11 17:21:14 2013 +0200 @@ -515,6 +515,8 @@ friend class ConcurrentMarkSweepThread; friend class ConcurrentMarkSweepGeneration; friend class CompactibleFreeListSpace; + friend class CMSParMarkTask; + friend class CMSParInitialMarkTask; friend class CMSParRemarkTask; friend class CMSConcMarkingTask; friend class CMSRefProcTaskProxy; @@ -749,6 +751,7 @@ Generation* _young_gen; // the younger gen HeapWord** _top_addr; // ... Top of Eden HeapWord** _end_addr; // ... End of Eden + Mutex* _eden_chunk_lock; HeapWord** _eden_chunk_array; // ... Eden partitioning array size_t _eden_chunk_index; // ... top (exclusive) of array size_t _eden_chunk_capacity; // ... max entries in array @@ -950,6 +953,7 @@ // Support for parallel remark of survivor space void* get_data_recorder(int thr_num); + void sample_eden_chunk(); CMSBitMap* markBitMap() { return &_markBitMap; } void directAllocated(HeapWord* start, size_t size); @@ -1027,6 +1031,8 @@ // Initialization errors bool completed_initialization() { return _completed_initialization; } + + void print_eden_and_survivor_chunk_arrays(); }; class CMSExpansionCause : public AllStatic { @@ -1317,6 +1323,10 @@ //Delegate to collector return collector()->get_data_recorder(thr_num); } + void sample_eden_chunk() { + //Delegate to collector + return collector()->sample_eden_chunk(); + } // Printing const char* name() const;
--- a/src/share/vm/gc_implementation/g1/g1_globals.hpp Fri Oct 11 17:14:35 2013 +0200 +++ b/src/share/vm/gc_implementation/g1/g1_globals.hpp Fri Oct 11 17:21:14 2013 +0200 @@ -96,11 +96,6 @@ "the buffer will be enqueued for processing. A value of 0 " \ "specifies that mutator threads should not do such filtering.") \ \ - develop(intx, G1ExtraRegionSurvRate, 33, \ - "If the young survival rate is S, and there's room left in " \ - "to-space, we will allow regions whose survival rate is up to " \ - "S + (1 - S)*X, where X is this parameter (as a fraction.)") \ - \ develop(bool, G1SATBPrintStubs, false, \ "If true, print generated stubs for the SATB barrier") \ \ @@ -110,9 +105,6 @@ develop(bool, G1RSBarrierRegionFilter, true, \ "If true, generate region filtering code in RS barrier") \ \ - develop(bool, G1RSBarrierNullFilter, true, \ - "If true, generate null-pointer filtering code in RS barrier") \ - \ develop(bool, G1DeferredRSUpdate, true, \ "If true, use deferred RS updates") \ \ @@ -120,9 +112,6 @@ "If true, verify that no dirty cards remain after RS log " \ "processing.") \ \ - develop(bool, G1RSCountHisto, false, \ - "If true, print a histogram of RS occupancies after each pause") \ - \ diagnostic(bool, G1PrintRegionLivenessInfo, false, \ "Prints the liveness information for all regions in the heap " \ "at the end of a marking cycle.") \ @@ -169,9 +158,6 @@ product(uintx, G1ConcRSHotCardLimit, 4, \ "The threshold that defines (>=) a hot card.") \ \ - develop(bool, G1PrintOopAppls, false, \ - "When true, print applications of closures to external locs.") \ - \ develop(intx, G1RSetRegionEntriesBase, 256, \ "Max number of regions in a fine-grain table per MB.") \ \
--- a/src/share/vm/gc_implementation/g1/heapRegion.cpp Fri Oct 11 17:14:35 2013 +0200 +++ b/src/share/vm/gc_implementation/g1/heapRegion.cpp Fri Oct 11 17:21:14 2013 +0200 @@ -314,6 +314,11 @@ region_size = MAX_REGION_SIZE; } + if (region_size != G1HeapRegionSize) { + // Update the flag to make sure that PrintFlagsFinal logs the correct value + FLAG_SET_ERGO(uintx, G1HeapRegionSize, region_size); + } + // And recalculate the log. region_size_log = log2_long((jlong) region_size);
--- a/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp Fri Oct 11 17:14:35 2013 +0200 +++ b/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp Fri Oct 11 17:21:14 2013 +0200 @@ -927,11 +927,9 @@ workers->active_workers(), Threads::number_of_non_daemon_threads()); workers->set_active_workers(active_workers); - _next_gen = gch->next_gen(this); - assert(_next_gen != NULL, - "This must be the youngest gen, and not the only gen"); assert(gch->n_gens() == 2, "Par collection currently only works with single older gen."); + _next_gen = gch->next_gen(this); // Do we have to avoid promotion_undo? if (gch->collector_policy()->is_concurrent_mark_sweep_policy()) { set_avoid_promotion_undo(true);
--- a/src/share/vm/gc_implementation/parNew/parNewGeneration.hpp Fri Oct 11 17:14:35 2013 +0200 +++ b/src/share/vm/gc_implementation/parNew/parNewGeneration.hpp Fri Oct 11 17:21:14 2013 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -29,6 +29,7 @@ #include "gc_implementation/shared/parGCAllocBuffer.hpp" #include "gc_implementation/shared/copyFailedInfo.hpp" #include "memory/defNewGeneration.hpp" +#include "memory/padded.hpp" #include "utilities/taskqueue.hpp" class ChunkArray;
--- a/src/share/vm/gc_implementation/parNew/parOopClosures.hpp Fri Oct 11 17:14:35 2013 +0200 +++ b/src/share/vm/gc_implementation/parNew/parOopClosures.hpp Fri Oct 11 17:21:14 2013 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 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 @@ -26,6 +26,7 @@ #define SHARE_VM_GC_IMPLEMENTATION_PARNEW_PAROOPCLOSURES_HPP #include "memory/genOopClosures.hpp" +#include "memory/padded.hpp" // Closures for ParNewGeneration
--- a/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.cpp Fri Oct 11 17:14:35 2013 +0200 +++ b/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.cpp Fri Oct 11 17:21:14 2013 +0200 @@ -29,14 +29,16 @@ #include "gc_implementation/parallelScavenge/psScavenge.inline.hpp" #include "gc_implementation/shared/gcTrace.hpp" #include "gc_implementation/shared/mutableSpace.hpp" +#include "memory/allocation.inline.hpp" #include "memory/memRegion.hpp" +#include "memory/padded.inline.hpp" #include "oops/oop.inline.hpp" #include "oops/oop.psgc.inline.hpp" -PSPromotionManager** PSPromotionManager::_manager_array = NULL; -OopStarTaskQueueSet* PSPromotionManager::_stack_array_depth = NULL; -PSOldGen* PSPromotionManager::_old_gen = NULL; -MutableSpace* PSPromotionManager::_young_space = NULL; +PaddedEnd<PSPromotionManager>* PSPromotionManager::_manager_array = NULL; +OopStarTaskQueueSet* PSPromotionManager::_stack_array_depth = NULL; +PSOldGen* PSPromotionManager::_old_gen = NULL; +MutableSpace* PSPromotionManager::_young_space = NULL; void PSPromotionManager::initialize() { ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap(); @@ -45,8 +47,10 @@ _old_gen = heap->old_gen(); _young_space = heap->young_gen()->to_space(); + // To prevent false sharing, we pad the PSPromotionManagers + // and make sure that the first instance starts at a cache line. assert(_manager_array == NULL, "Attempt to initialize twice"); - _manager_array = NEW_C_HEAP_ARRAY(PSPromotionManager*, ParallelGCThreads+1, mtGC); + _manager_array = PaddedArray<PSPromotionManager, mtGC>::create_unfreeable(ParallelGCThreads + 1); guarantee(_manager_array != NULL, "Could not initialize promotion manager"); _stack_array_depth = new OopStarTaskQueueSet(ParallelGCThreads); @@ -54,26 +58,21 @@ // Create and register the PSPromotionManager(s) for the worker threads. for(uint i=0; i<ParallelGCThreads; i++) { - _manager_array[i] = new PSPromotionManager(); - guarantee(_manager_array[i] != NULL, "Could not create PSPromotionManager"); - stack_array_depth()->register_queue(i, _manager_array[i]->claimed_stack_depth()); + stack_array_depth()->register_queue(i, _manager_array[i].claimed_stack_depth()); } - // The VMThread gets its own PSPromotionManager, which is not available // for work stealing. - _manager_array[ParallelGCThreads] = new PSPromotionManager(); - guarantee(_manager_array[ParallelGCThreads] != NULL, "Could not create PSPromotionManager"); } PSPromotionManager* PSPromotionManager::gc_thread_promotion_manager(int index) { assert(index >= 0 && index < (int)ParallelGCThreads, "index out of range"); assert(_manager_array != NULL, "Sanity"); - return _manager_array[index]; + return &_manager_array[index]; } PSPromotionManager* PSPromotionManager::vm_thread_promotion_manager() { assert(_manager_array != NULL, "Sanity"); - return _manager_array[ParallelGCThreads]; + return &_manager_array[ParallelGCThreads]; } void PSPromotionManager::pre_scavenge() {
--- a/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.hpp Fri Oct 11 17:14:35 2013 +0200 +++ b/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.hpp Fri Oct 11 17:21:14 2013 +0200 @@ -29,6 +29,8 @@ #include "gc_implementation/shared/gcTrace.hpp" #include "gc_implementation/shared/copyFailedInfo.hpp" #include "memory/allocation.hpp" +#include "memory/padded.hpp" +#include "utilities/globalDefinitions.hpp" #include "utilities/taskqueue.hpp" // @@ -51,14 +53,14 @@ class PSOldGen; class ParCompactionManager; -class PSPromotionManager : public CHeapObj<mtGC> { +class PSPromotionManager VALUE_OBJ_CLASS_SPEC { friend class PSScavenge; friend class PSRefProcTaskExecutor; private: - static PSPromotionManager** _manager_array; - static OopStarTaskQueueSet* _stack_array_depth; - static PSOldGen* _old_gen; - static MutableSpace* _young_space; + static PaddedEnd<PSPromotionManager>* _manager_array; + static OopStarTaskQueueSet* _stack_array_depth; + static PSOldGen* _old_gen; + static MutableSpace* _young_space; #if TASKQUEUE_STATS size_t _masked_pushes;
--- a/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.inline.hpp Fri Oct 11 17:14:35 2013 +0200 +++ b/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.inline.hpp Fri Oct 11 17:21:14 2013 +0200 @@ -32,7 +32,7 @@ inline PSPromotionManager* PSPromotionManager::manager_array(int index) { assert(_manager_array != NULL, "access of NULL manager_array"); assert(index >= 0 && index <= (int)ParallelGCThreads, "out of range manager_array access"); - return _manager_array[index]; + return &_manager_array[index]; } template <class T>
--- a/src/share/vm/gc_implementation/shared/objectCountEventSender.cpp Fri Oct 11 17:14:35 2013 +0200 +++ b/src/share/vm/gc_implementation/shared/objectCountEventSender.cpp Fri Oct 11 17:21:14 2013 +0200 @@ -32,6 +32,7 @@ #if INCLUDE_SERVICES void ObjectCountEventSender::send(const KlassInfoEntry* entry, GCId gc_id, jlong timestamp) { +#if INCLUDE_TRACE assert(Tracing::is_event_enabled(EventObjectCountAfterGC::eventId), "Only call this method if the event is enabled"); @@ -42,6 +43,7 @@ event.set_totalSize(entry->words() * BytesPerWord); event.set_endtime(timestamp); event.commit(); +#endif // INCLUDE_TRACE } bool ObjectCountEventSender::should_send_event() {
--- a/src/share/vm/graal/graalCodeInstaller.cpp Fri Oct 11 17:14:35 2013 +0200 +++ b/src/share/vm/graal/graalCodeInstaller.cpp Fri Oct 11 17:21:14 2013 +0200 @@ -727,7 +727,7 @@ oop debug_info = CompilationResult_Call::debugInfo(site); - assert((hotspot_method ? 1 : 0) + (foreign_call ? 1 : 0) == 1, "Call site needs exactly one type"); + assert(!!hotspot_method ^ !!foreign_call, "Call site needs exactly one type"); NativeInstruction* inst = nativeInstruction_at(_instructions->start() + pc_offset); jint next_pc_offset = CodeInstaller::pd_next_offset(inst, pc_offset, hotspot_method);
--- a/src/share/vm/graal/graalCompilerToGPU.cpp Fri Oct 11 17:14:35 2013 +0200 +++ b/src/share/vm/graal/graalCompilerToGPU.cpp Fri Oct 11 17:21:14 2013 +0200 @@ -96,7 +96,72 @@ } else { oop o = java_lang_boxing_object::create(ptxka.get_ret_type(), (jvalue *) result.get_value_addr(), CHECK_NULL); if (TraceGPUInteraction) { - tty->print_cr("GPU execution returned %d", result.get_jint()); + switch (ptxka.get_ret_type()) { + case T_INT: + tty->print_cr("GPU execution returned %d", result.get_jint()); + break; + case T_FLOAT: + tty->print_cr("GPU execution returned %f", result.get_jfloat()); + break; + case T_DOUBLE: + tty->print_cr("GPU execution returned %f", result.get_jdouble()); + break; + default: + tty->print_cr("GPU returned unhandled"); + break; + } + } + return JNIHandles::make_local(o); + } + +C2V_END + +C2V_VMENTRY(jobject, executeParallelMethodVarargs, (JNIEnv *env, + jobject, + jint dimX, jint dimY, jint dimZ, + jobject args, jobject hotspotInstalledCode)) + ResourceMark rm; + HandleMark hm; + + if (gpu::is_available() == false || gpu::has_gpu_linkage() == false && gpu::is_initialized()) { + tty->print_cr("executeParallelMethodVarargs - not available / no linkage / not initialized"); + return NULL; + } + jlong nmethodValue = HotSpotInstalledCode::codeBlob(hotspotInstalledCode); + nmethod* nm = (nmethod*) (address) nmethodValue; + methodHandle mh = nm->method(); + Symbol* signature = mh->signature(); + + // start value is the kernel + jlong startValue = HotSpotInstalledCode::codeStart(hotspotInstalledCode); + + PTXKernelArguments ptxka(signature, (arrayOop) JNIHandles::resolve(args), mh->is_static()); + JavaValue result(ptxka.get_ret_type()); +if (!gpu::execute_warp(dimX, dimY, dimZ, (address)startValue, ptxka, result)) { + return NULL; + } + + if (ptxka.get_ret_type() == T_VOID) { + return NULL; + } else if (ptxka.get_ret_type() == T_OBJECT || ptxka.get_ret_type() == T_ARRAY) { + return JNIHandles::make_local((oop) result.get_jobject()); + } else { + oop o = java_lang_boxing_object::create(ptxka.get_ret_type(), (jvalue *) result.get_value_addr(), CHECK_NULL); + if (TraceGPUInteraction) { + switch (ptxka.get_ret_type()) { + case T_INT: + tty->print_cr("GPU execution returned %d", result.get_jint()); + break; + case T_FLOAT: + tty->print_cr("GPU execution returned %f", result.get_jfloat()); + break; + case T_DOUBLE: + tty->print_cr("GPU execution returned %g", result.get_jdouble()); + break; + default: + tty->print_cr("GPU returned unhandled"); + break; + } } return JNIHandles::make_local(o); } @@ -116,6 +181,14 @@ return gpu::is_initialized(); C2V_END +C2V_VMENTRY(jint, availableProcessors, (JNIEnv *env, jobject)) + if (gpu::is_available() == false || gpu::has_gpu_linkage() == false) { + tty->print_cr("deviceInit - not available / no linkage"); + return false; + } + return gpu::available_processors(); +C2V_END + C2V_VMENTRY(jboolean, deviceDetach, (JNIEnv *env, jobject)) return true; C2V_END @@ -157,10 +230,12 @@ #define GPUSPACE_METHOD "J" JNINativeMethod CompilerToGPU_methods[] = { - {CC"generateKernel", CC"([B" STRING ")"GPUSPACE_METHOD, FN_PTR(generateKernel)}, - {CC"deviceInit", CC"()Z", FN_PTR(deviceInit)}, - {CC"deviceDetach", CC"()Z", FN_PTR(deviceDetach)}, - {CC"executeExternalMethodVarargs", CC"(["OBJECT HS_INSTALLED_CODE")"OBJECT, FN_PTR(executeExternalMethodVarargs)}, + {CC"generateKernel", CC"([B" STRING ")"GPUSPACE_METHOD, FN_PTR(generateKernel)}, + {CC"deviceInit", CC"()Z", FN_PTR(deviceInit)}, + {CC"deviceDetach", CC"()Z", FN_PTR(deviceDetach)}, + {CC"availableProcessors", CC"()I", FN_PTR(availableProcessors)}, + {CC"executeExternalMethodVarargs", CC"(["OBJECT HS_INSTALLED_CODE")"OBJECT, FN_PTR(executeExternalMethodVarargs)}, + {CC"executeParallelMethodVarargs", CC"(III["OBJECT HS_INSTALLED_CODE")"OBJECT, FN_PTR(executeParallelMethodVarargs)}, }; int CompilerToGPU_methods_count() {
--- a/src/share/vm/graal/graalCompilerToVM.cpp Fri Oct 11 17:14:35 2013 +0200 +++ b/src/share/vm/graal/graalCompilerToVM.cpp Fri Oct 11 17:21:14 2013 +0200 @@ -875,6 +875,9 @@ set_int("arrayClassElementOffset", in_bytes(ObjArrayKlass::element_klass_offset())); + set_int("graalCountersThreadOffset", in_bytes(JavaThread::graal_counters_offset())); + set_int("graalCountersSize", (jint) GRAAL_COUNTERS_SIZE); + #undef set_boolean #undef set_int #undef set_long @@ -1145,6 +1148,12 @@ return klass; C2V_END +C2V_VMENTRY(jlongArray, collectCounters, (JNIEnv *env, jobject)) + typeArrayOop arrayOop = oopFactory::new_longArray(GRAAL_COUNTERS_SIZE, CHECK_NULL); + JavaThread::collect_counters(arrayOop); + return (jlongArray) JNIHandles::make_local(arrayOop); +C2V_END + #define CC (char*) /*cast a literal from (const char*)*/ #define FN_PTR(f) CAST_FROM_FN_PTR(void*, &(c2v_ ## f)) @@ -1224,6 +1233,7 @@ {CC"invalidateInstalledCode", CC"("HS_INSTALLED_CODE")V", FN_PTR(invalidateInstalledCode)}, {CC"readUnsafeUncompressedPointer", CC"("OBJECT"J)"OBJECT, FN_PTR(readUnsafeUncompressedPointer)}, {CC"readUnsafeKlassPointer", CC"("OBJECT")J", FN_PTR(readUnsafeKlassPointer)}, + {CC"collectCounters", CC"()[J", FN_PTR(collectCounters)}, }; int CompilerToVM_methods_count() {
--- a/src/share/vm/interpreter/interpreterRuntime.cpp Fri Oct 11 17:14:35 2013 +0200 +++ b/src/share/vm/interpreter/interpreterRuntime.cpp Fri Oct 11 17:21:14 2013 +0200 @@ -1224,3 +1224,26 @@ size_of_arguments * Interpreter::stackElementSize); IRT_END #endif + +#if INCLUDE_JVMTI +// This is a support of the JVMTI PopFrame interface. +// Make sure it is an invokestatic of a polymorphic intrinsic that has a member_name argument +// and return it as a vm_result so that it can be reloaded in the list of invokestatic parameters. +// The dmh argument is a reference to a DirectMethoHandle that has a member name field. +IRT_ENTRY(void, InterpreterRuntime::member_name_arg_or_null(JavaThread* thread, address dmh, + Method* method, address bcp)) + Bytecodes::Code code = Bytecodes::code_at(method, bcp); + if (code != Bytecodes::_invokestatic) { + return; + } + ConstantPool* cpool = method->constants(); + int cp_index = Bytes::get_native_u2(bcp + 1) + ConstantPool::CPCACHE_INDEX_TAG; + Symbol* cname = cpool->klass_name_at(cpool->klass_ref_index_at(cp_index)); + Symbol* mname = cpool->name_ref_at(cp_index); + + if (MethodHandles::has_member_arg(cname, mname)) { + oop member_name = java_lang_invoke_DirectMethodHandle::member((oop)dmh); + thread->set_vm_result(member_name); + } +IRT_END +#endif // INCLUDE_JVMTI
--- a/src/share/vm/interpreter/interpreterRuntime.hpp Fri Oct 11 17:14:35 2013 +0200 +++ b/src/share/vm/interpreter/interpreterRuntime.hpp Fri Oct 11 17:21:14 2013 +0200 @@ -96,6 +96,9 @@ static void create_exception(JavaThread* thread, char* name, char* message); static void create_klass_exception(JavaThread* thread, char* name, oopDesc* obj); static address exception_handler_for_exception(JavaThread* thread, oopDesc* exception); +#if INCLUDE_JVMTI + static void member_name_arg_or_null(JavaThread* thread, address dmh, Method* m, address bcp); +#endif static void throw_pending_exception(JavaThread* thread); // Statics & fields
--- a/src/share/vm/memory/cardTableRS.cpp Fri Oct 11 17:14:35 2013 +0200 +++ b/src/share/vm/memory/cardTableRS.cpp Fri Oct 11 17:21:14 2013 +0200 @@ -310,46 +310,31 @@ _ct_bs->non_clean_card_iterate_possibly_parallel(sp, urasm, cl, this); } -void CardTableRS::clear_into_younger(Generation* gen) { - GenCollectedHeap* gch = GenCollectedHeap::heap(); - // Generations younger than gen have been evacuated. We can clear - // card table entries for gen (we know that it has no pointers - // to younger gens) and for those below. The card tables for - // the youngest gen need never be cleared. +void CardTableRS::clear_into_younger(Generation* old_gen) { + assert(old_gen->level() == 1, "Should only be called for the old generation"); + // The card tables for the youngest gen need never be cleared. // There's a bit of subtlety in the clear() and invalidate() // methods that we exploit here and in invalidate_or_clear() // below to avoid missing cards at the fringes. If clear() or // invalidate() are changed in the future, this code should // be revisited. 20040107.ysr - Generation* g = gen; - for(Generation* prev_gen = gch->prev_gen(g); - prev_gen != NULL; - g = prev_gen, prev_gen = gch->prev_gen(g)) { - MemRegion to_be_cleared_mr = g->prev_used_region(); - clear(to_be_cleared_mr); - } + clear(old_gen->prev_used_region()); } -void CardTableRS::invalidate_or_clear(Generation* gen, bool younger) { - GenCollectedHeap* gch = GenCollectedHeap::heap(); - // For each generation gen (and younger) - // invalidate the cards for the currently occupied part - // of that generation and clear the cards for the +void CardTableRS::invalidate_or_clear(Generation* old_gen) { + assert(old_gen->level() == 1, "Should only be called for the old generation"); + // Invalidate the cards for the currently occupied part of + // the old generation and clear the cards for the // unoccupied part of the generation (if any, making use // of that generation's prev_used_region to determine that // region). No need to do anything for the youngest // generation. Also see note#20040107.ysr above. - Generation* g = gen; - for(Generation* prev_gen = gch->prev_gen(g); prev_gen != NULL; - g = prev_gen, prev_gen = gch->prev_gen(g)) { - MemRegion used_mr = g->used_region(); - MemRegion to_be_cleared_mr = g->prev_used_region().minus(used_mr); - if (!to_be_cleared_mr.is_empty()) { - clear(to_be_cleared_mr); - } - invalidate(used_mr); - if (!younger) break; + MemRegion used_mr = old_gen->used_region(); + MemRegion to_be_cleared_mr = old_gen->prev_used_region().minus(used_mr); + if (!to_be_cleared_mr.is_empty()) { + clear(to_be_cleared_mr); } + invalidate(used_mr); }
--- a/src/share/vm/memory/cardTableRS.hpp Fri Oct 11 17:14:35 2013 +0200 +++ b/src/share/vm/memory/cardTableRS.hpp Fri Oct 11 17:21:14 2013 +0200 @@ -142,12 +142,12 @@ void verify_aligned_region_empty(MemRegion mr); void clear(MemRegion mr) { _ct_bs->clear(mr); } - void clear_into_younger(Generation* gen); + void clear_into_younger(Generation* old_gen); void invalidate(MemRegion mr, bool whole_heap = false) { _ct_bs->invalidate(mr, whole_heap); } - void invalidate_or_clear(Generation* gen, bool younger); + void invalidate_or_clear(Generation* old_gen); static uintx ct_max_alignment_constraint() { return CardTableModRefBS::ct_max_alignment_constraint();
--- a/src/share/vm/memory/defNewGeneration.cpp Fri Oct 11 17:14:35 2013 +0200 +++ b/src/share/vm/memory/defNewGeneration.cpp Fri Oct 11 17:21:14 2013 +0200 @@ -567,8 +567,6 @@ gc_tracer.report_gc_start(gch->gc_cause(), _gc_timer->gc_start()); _next_gen = gch->next_gen(this); - assert(_next_gen != NULL, - "This must be the youngest gen, and not the only gen"); // If the next generation is too full to accommodate promotion // from this generation, pass on collection; let the next generation @@ -901,8 +899,6 @@ if (_next_gen == NULL) { GenCollectedHeap* gch = GenCollectedHeap::heap(); _next_gen = gch->next_gen(this); - assert(_next_gen != NULL, - "This must be the youngest gen, and not the only gen"); } return _next_gen->promotion_attempt_is_safe(used()); } @@ -1033,6 +1029,9 @@ // have to use it here, as well. HeapWord* result = eden()->par_allocate(word_size); if (result != NULL) { + if (CMSEdenChunksRecordAlways && _next_gen != NULL) { + _next_gen->sample_eden_chunk(); + } return result; } do { @@ -1063,13 +1062,19 @@ // circular dependency at compile time. if (result == NULL) { result = allocate_from_space(word_size); + } else if (CMSEdenChunksRecordAlways && _next_gen != NULL) { + _next_gen->sample_eden_chunk(); } return result; } HeapWord* DefNewGeneration::par_allocate(size_t word_size, bool is_tlab) { - return eden()->par_allocate(word_size); + HeapWord* res = eden()->par_allocate(word_size); + if (CMSEdenChunksRecordAlways && _next_gen != NULL) { + _next_gen->sample_eden_chunk(); + } + return res; } void DefNewGeneration::gc_prologue(bool full) {
--- a/src/share/vm/memory/genCollectedHeap.cpp Fri Oct 11 17:14:35 2013 +0200 +++ b/src/share/vm/memory/genCollectedHeap.cpp Fri Oct 11 17:21:14 2013 +0200 @@ -1070,13 +1070,13 @@ void GenCollectedHeap::prepare_for_compaction() { - Generation* scanning_gen = _gens[_n_gens-1]; + guarantee(_n_gens = 2, "Wrong number of generations"); + Generation* old_gen = _gens[1]; // Start by compacting into same gen. - CompactPoint cp(scanning_gen, NULL, NULL); - while (scanning_gen != NULL) { - scanning_gen->prepare_for_compaction(&cp); - scanning_gen = prev_gen(scanning_gen); - } + CompactPoint cp(old_gen, NULL, NULL); + old_gen->prepare_for_compaction(&cp); + Generation* young_gen = _gens[0]; + young_gen->prepare_for_compaction(&cp); } GCStats* GenCollectedHeap::gc_stats(int level) const { @@ -1245,27 +1245,14 @@ generation_iterate(&ep_cl, false); } -oop GenCollectedHeap::handle_failed_promotion(Generation* gen, +oop GenCollectedHeap::handle_failed_promotion(Generation* old_gen, oop obj, size_t obj_size) { + guarantee(old_gen->level() == 1, "We only get here with an old generation"); assert(obj_size == (size_t)obj->size(), "bad obj_size passed in"); HeapWord* result = NULL; - // First give each higher generation a chance to allocate the promoted object. - Generation* allocator = next_gen(gen); - if (allocator != NULL) { - do { - result = allocator->allocate(obj_size, false); - } while (result == NULL && (allocator = next_gen(allocator)) != NULL); - } - - if (result == NULL) { - // Then give gen and higher generations a chance to expand and allocate the - // object. - do { - result = gen->expand_and_allocate(obj_size, false); - } while (result == NULL && (gen = next_gen(gen)) != NULL); - } + result = old_gen->expand_and_allocate(obj_size, false); if (result != NULL) { Copy::aligned_disjoint_words((HeapWord*)obj, result, obj_size);
--- a/src/share/vm/memory/genCollectedHeap.hpp Fri Oct 11 17:14:35 2013 +0200 +++ b/src/share/vm/memory/genCollectedHeap.hpp Fri Oct 11 17:21:14 2013 +0200 @@ -368,25 +368,23 @@ // collection. virtual bool is_maximal_no_gc() const; - // Return the generation before "gen", or else NULL. + // Return the generation before "gen". Generation* prev_gen(Generation* gen) const { int l = gen->level(); - if (l == 0) return NULL; - else return _gens[l-1]; + guarantee(l > 0, "Out of bounds"); + return _gens[l-1]; } - // Return the generation after "gen", or else NULL. + // Return the generation after "gen". Generation* next_gen(Generation* gen) const { int l = gen->level() + 1; - if (l == _n_gens) return NULL; - else return _gens[l]; + guarantee(l < _n_gens, "Out of bounds"); + return _gens[l]; } Generation* get_gen(int i) const { - if (i >= 0 && i < _n_gens) - return _gens[i]; - else - return NULL; + guarantee(i >= 0 && i < _n_gens, "Out of bounds"); + return _gens[i]; } int n_gens() const { @@ -485,9 +483,9 @@ // Promotion of obj into gen failed. Try to promote obj to higher // gens in ascending order; return the new location of obj if successful. - // Otherwise, try expand-and-allocate for obj in each generation starting at - // gen; return the new location of obj if successful. Otherwise, return NULL. - oop handle_failed_promotion(Generation* gen, + // Otherwise, try expand-and-allocate for obj in both the young and old + // generation; return the new location of obj if successful. Otherwise, return NULL. + oop handle_failed_promotion(Generation* old_gen, oop obj, size_t obj_size);
--- a/src/share/vm/memory/genMarkSweep.cpp Fri Oct 11 17:14:35 2013 +0200 +++ b/src/share/vm/memory/genMarkSweep.cpp Fri Oct 11 17:21:14 2013 +0200 @@ -52,8 +52,8 @@ #include "utilities/copy.hpp" #include "utilities/events.hpp" -void GenMarkSweep::invoke_at_safepoint(int level, ReferenceProcessor* rp, - bool clear_all_softrefs) { +void GenMarkSweep::invoke_at_safepoint(int level, ReferenceProcessor* rp, bool clear_all_softrefs) { + guarantee(level == 1, "We always collect both old and young."); assert(SafepointSynchronize::is_at_safepoint(), "must be at a safepoint"); GenCollectedHeap* gch = GenCollectedHeap::heap(); @@ -84,11 +84,6 @@ // Capture heap size before collection for printing. size_t gch_prev_used = gch->used(); - // Some of the card table updates below assume that the perm gen is - // also being collected. - assert(level == gch->n_gens() - 1, - "All generations are being collected, ergo perm gen too."); - // Capture used regions for each generation that will be // subject to collection, so that card table adjustments can // be made intelligently (see clear / invalidate further below). @@ -126,17 +121,15 @@ all_empty = all_empty && gch->get_gen(i)->used() == 0; } GenRemSet* rs = gch->rem_set(); + Generation* old_gen = gch->get_gen(level); // Clear/invalidate below make use of the "prev_used_regions" saved earlier. if (all_empty) { // We've evacuated all generations below us. - Generation* g = gch->get_gen(level); - rs->clear_into_younger(g); + rs->clear_into_younger(old_gen); } else { // Invalidate the cards corresponding to the currently used - // region and clear those corresponding to the evacuated region - // of all generations just collected (i.e. level and younger). - rs->invalidate_or_clear(gch->get_gen(level), - true /* younger */); + // region and clear those corresponding to the evacuated region. + rs->invalidate_or_clear(old_gen); } Threads::gc_epilogue();
--- a/src/share/vm/memory/genRemSet.hpp Fri Oct 11 17:14:35 2013 +0200 +++ b/src/share/vm/memory/genRemSet.hpp Fri Oct 11 17:21:14 2013 +0200 @@ -135,7 +135,7 @@ // younger than gen from generations gen and older. // The parameter clear_perm indicates if the perm_gen's // remembered set should also be processed/cleared. - virtual void clear_into_younger(Generation* gen) = 0; + virtual void clear_into_younger(Generation* old_gen) = 0; // Informs the RS that refs in the given "mr" may have changed // arbitrarily, and therefore may contain old-to-young pointers. @@ -146,11 +146,8 @@ // Informs the RS that refs in this generation // may have changed arbitrarily, and therefore may contain - // old-to-young pointers in arbitrary locations. The parameter - // younger indicates if the same should be done for younger generations - // as well. The parameter perm indicates if the same should be done for - // perm gen as well. - virtual void invalidate_or_clear(Generation* gen, bool younger) = 0; + // old-to-young pointers in arbitrary locations. + virtual void invalidate_or_clear(Generation* old_gen) = 0; }; #endif // SHARE_VM_MEMORY_GENREMSET_HPP
--- a/src/share/vm/memory/generation.hpp Fri Oct 11 17:14:35 2013 +0200 +++ b/src/share/vm/memory/generation.hpp Fri Oct 11 17:21:14 2013 +0200 @@ -455,6 +455,7 @@ // expected to be GC worker thread-local, with the worker index // indicated by "thr_num". virtual void* get_data_recorder(int thr_num) { return NULL; } + virtual void sample_eden_chunk() {} // Some generations may require some cleanup actions before allowing // a verification.
--- a/src/share/vm/memory/metaspace.cpp Fri Oct 11 17:14:35 2013 +0200 +++ b/src/share/vm/memory/metaspace.cpp Fri Oct 11 17:21:14 2013 +0200 @@ -2254,10 +2254,11 @@ void SpaceManager::deallocate(MetaWord* p, size_t word_size) { assert_lock_strong(_lock); + size_t raw_word_size = get_raw_word_size(word_size); size_t min_size = TreeChunk<Metablock, FreeList>::min_size(); - assert(word_size >= min_size, + assert(raw_word_size >= min_size, err_msg("Should not deallocate dark matter " SIZE_FORMAT, word_size)); - block_freelists()->return_block(p, word_size); + block_freelists()->return_block(p, raw_word_size); } // Adds a chunk to the list of chunks in use.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/vm/memory/padded.hpp Fri Oct 11 17:21:14 2013 +0200 @@ -0,0 +1,93 @@ +/* + * 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. + * + */ + +#ifndef SHARE_VM_MEMORY_PADDED_HPP +#define SHARE_VM_MEMORY_PADDED_HPP + +#include "memory/allocation.hpp" +#include "utilities/globalDefinitions.hpp" + +// Bytes needed to pad type to avoid cache-line sharing; alignment should be the +// expected cache line size (a power of two). The first addend avoids sharing +// when the start address is not a multiple of alignment; the second maintains +// alignment of starting addresses that happen to be a multiple. +#define PADDING_SIZE(type, alignment) \ + ((alignment) + align_size_up_(sizeof(type), alignment)) + +// Templates to create a subclass padded to avoid cache line sharing. These are +// effective only when applied to derived-most (leaf) classes. + +// When no args are passed to the base ctor. +template <class T, size_t alignment = DEFAULT_CACHE_LINE_SIZE> +class Padded : public T { + private: + char _pad_buf_[PADDING_SIZE(T, alignment)]; +}; + +// When either 0 or 1 args may be passed to the base ctor. +template <class T, typename Arg1T, size_t alignment = DEFAULT_CACHE_LINE_SIZE> +class Padded01 : public T { + public: + Padded01(): T() { } + Padded01(Arg1T arg1): T(arg1) { } + private: + char _pad_buf_[PADDING_SIZE(T, alignment)]; +}; + +// Super class of PaddedEnd when pad_size != 0. +template <class T, size_t pad_size> +class PaddedEndImpl : public T { + private: + char _pad_buf[pad_size]; +}; + +// Super class of PaddedEnd when pad_size == 0. +template <class T> +class PaddedEndImpl<T, /*pad_size*/ 0> : public T { + // No padding. +}; + +#define PADDED_END_SIZE(type, alignment) (align_size_up_(sizeof(type), alignment) - sizeof(type)) + +// More memory conservative implementation of Padded. The subclass adds the +// minimal amount of padding needed to make the size of the objects be aligned. +// This will help reducing false sharing, +// if the start address is a multiple of alignment. +template <class T, size_t alignment = DEFAULT_CACHE_LINE_SIZE> +class PaddedEnd : public PaddedEndImpl<T, PADDED_END_SIZE(T, alignment)> { + // C++ don't allow zero-length arrays. The padding is put in a + // super class that is specialized for the pad_size == 0 case. +}; + +// Helper class to create an array of PaddedEnd<T> objects. All elements will +// start at a multiple of alignment and the size will be aligned to alignment. +template <class T, MEMFLAGS flags, size_t alignment = DEFAULT_CACHE_LINE_SIZE> +class PaddedArray { + public: + // Creates an aligned padded array. + // The memory can't be deleted since the raw memory chunk is not returned. + static PaddedEnd<T>* create_unfreeable(uint length); +}; + +#endif // SHARE_VM_MEMORY_PADDED_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/vm/memory/padded.inline.hpp Fri Oct 11 17:21:14 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. + * + */ + +#include "memory/allocation.inline.hpp" +#include "memory/padded.hpp" +#include "utilities/debug.hpp" +#include "utilities/globalDefinitions.hpp" + +// Creates an aligned padded array. +// The memory can't be deleted since the raw memory chunk is not returned. +template <class T, MEMFLAGS flags, size_t alignment> +PaddedEnd<T>* PaddedArray<T, flags, alignment>::create_unfreeable(uint length) { + // Check that the PaddedEnd class works as intended. + STATIC_ASSERT(is_size_aligned_(sizeof(PaddedEnd<T>), alignment)); + + // Allocate a chunk of memory large enough to allow for some alignment. + void* chunk = AllocateHeap(length * sizeof(PaddedEnd<T, alignment>) + alignment, flags); + + // Make the initial alignment. + PaddedEnd<T>* aligned_padded_array = (PaddedEnd<T>*)align_pointer_up(chunk, alignment); + + // Call the default constructor for each element. + for (uint i = 0; i < length; i++) { + ::new (&aligned_padded_array[i]) T(); + } + + return aligned_padded_array; +}
--- a/src/share/vm/memory/sharedHeap.cpp Fri Oct 11 17:14:35 2013 +0200 +++ b/src/share/vm/memory/sharedHeap.cpp Fri Oct 11 17:21:14 2013 +0200 @@ -65,7 +65,8 @@ } _sh = this; // ch is static, should be set only once. if ((UseParNewGC || - (UseConcMarkSweepGC && CMSParallelRemarkEnabled) || + (UseConcMarkSweepGC && (CMSParallelInitialMarkEnabled || + CMSParallelRemarkEnabled)) || UseG1GC) && ParallelGCThreads > 0) { _workers = new FlexibleWorkGang("Parallel GC Threads", ParallelGCThreads,
--- a/src/share/vm/memory/universe.cpp Fri Oct 11 17:14:35 2013 +0200 +++ b/src/share/vm/memory/universe.cpp Fri Oct 11 17:21:14 2013 +0200 @@ -105,10 +105,9 @@ Array<Klass*>* Universe::_the_array_interfaces_array = NULL; oop Universe::_the_null_string = NULL; oop Universe::_the_min_jint_string = NULL; -LatestMethodOopCache* Universe::_finalizer_register_cache = NULL; -LatestMethodOopCache* Universe::_loader_addClass_cache = NULL; -LatestMethodOopCache* Universe::_pd_implies_cache = NULL; -ActiveMethodOopsCache* Universe::_reflect_invoke_cache = NULL; +LatestMethodCache* Universe::_finalizer_register_cache = NULL; +LatestMethodCache* Universe::_loader_addClass_cache = NULL; +LatestMethodCache* Universe::_pd_implies_cache = NULL; oop Universe::_out_of_memory_error_java_heap = NULL; oop Universe::_out_of_memory_error_metaspace = NULL; oop Universe::_out_of_memory_error_class_metaspace = NULL; @@ -225,7 +224,6 @@ f->do_ptr((void**)&_the_empty_klass_array); _finalizer_register_cache->serialize(f); _loader_addClass_cache->serialize(f); - _reflect_invoke_cache->serialize(f); _pd_implies_cache->serialize(f); } @@ -649,10 +647,9 @@ // We have a heap so create the Method* caches before // Metaspace::initialize_shared_spaces() tries to populate them. - Universe::_finalizer_register_cache = new LatestMethodOopCache(); - Universe::_loader_addClass_cache = new LatestMethodOopCache(); - Universe::_pd_implies_cache = new LatestMethodOopCache(); - Universe::_reflect_invoke_cache = new ActiveMethodOopsCache(); + Universe::_finalizer_register_cache = new LatestMethodCache(); + Universe::_loader_addClass_cache = new LatestMethodCache(); + Universe::_pd_implies_cache = new LatestMethodCache(); if (UseSharedSpaces) { // Read the data structures supporting the shared spaces (shared @@ -1088,35 +1085,21 @@ vmSymbols::register_method_name(), vmSymbols::register_method_signature()); if (m == NULL || !m->is_static()) { - THROW_MSG_(vmSymbols::java_lang_NoSuchMethodException(), - "java.lang.ref.Finalizer.register", false); + tty->print_cr("Unable to link/verify Finalizer.register method"); + return false; // initialization failed (cannot throw exception yet) } Universe::_finalizer_register_cache->init( - SystemDictionary::Finalizer_klass(), m, CHECK_false); - - // Resolve on first use and initialize class. - // Note: No race-condition here, since a resolve will always return the same result - - // Setup method for security checks - k = SystemDictionary::resolve_or_fail(vmSymbols::java_lang_reflect_Method(), true, CHECK_false); - k_h = instanceKlassHandle(THREAD, k); - k_h->link_class(CHECK_false); - m = k_h->find_method(vmSymbols::invoke_name(), vmSymbols::object_object_array_object_signature()); - if (m == NULL || m->is_static()) { - THROW_MSG_(vmSymbols::java_lang_NoSuchMethodException(), - "java.lang.reflect.Method.invoke", false); - } - Universe::_reflect_invoke_cache->init(k_h(), m, CHECK_false); + SystemDictionary::Finalizer_klass(), m); // Setup method for registering loaded classes in class loader vector InstanceKlass::cast(SystemDictionary::ClassLoader_klass())->link_class(CHECK_false); m = InstanceKlass::cast(SystemDictionary::ClassLoader_klass())->find_method(vmSymbols::addClass_name(), vmSymbols::class_void_signature()); if (m == NULL || m->is_static()) { - THROW_MSG_(vmSymbols::java_lang_NoSuchMethodException(), - "java.lang.ClassLoader.addClass", false); + tty->print_cr("Unable to link/verify ClassLoader.addClass method"); + return false; // initialization failed (cannot throw exception yet) } Universe::_loader_addClass_cache->init( - SystemDictionary::ClassLoader_klass(), m, CHECK_false); + SystemDictionary::ClassLoader_klass(), m); // Setup method for checking protection domain InstanceKlass::cast(SystemDictionary::ProtectionDomain_klass())->link_class(CHECK_false); @@ -1132,7 +1115,7 @@ return false; // initialization failed } Universe::_pd_implies_cache->init( - SystemDictionary::ProtectionDomain_klass(), m, CHECK_false);; + SystemDictionary::ProtectionDomain_klass(), m);; } // The folowing is initializing converter functions for serialization in @@ -1455,7 +1438,7 @@ } -void CommonMethodOopCache::init(Klass* k, Method* m, TRAPS) { +void LatestMethodCache::init(Klass* k, Method* m) { if (!UseSharedSpaces) { _klass = k; } @@ -1471,88 +1454,7 @@ } -ActiveMethodOopsCache::~ActiveMethodOopsCache() { - if (_prev_methods != NULL) { - delete _prev_methods; - _prev_methods = NULL; - } -} - - -void ActiveMethodOopsCache::add_previous_version(Method* method) { - assert(Thread::current()->is_VM_thread(), - "only VMThread can add previous versions"); - - // Only append the previous method if it is executing on the stack. - if (method->on_stack()) { - - if (_prev_methods == NULL) { - // This is the first previous version so make some space. - // Start with 2 elements under the assumption that the class - // won't be redefined much. - _prev_methods = new (ResourceObj::C_HEAP, mtClass) GrowableArray<Method*>(2, true); - } - - // RC_TRACE macro has an embedded ResourceMark - RC_TRACE(0x00000100, - ("add: %s(%s): adding prev version ref for cached method @%d", - method->name()->as_C_string(), method->signature()->as_C_string(), - _prev_methods->length())); - - _prev_methods->append(method); - } - - - // Since the caller is the VMThread and we are at a safepoint, this is a good - // time to clear out unused method references. - - if (_prev_methods == NULL) return; - - for (int i = _prev_methods->length() - 1; i >= 0; i--) { - Method* method = _prev_methods->at(i); - assert(method != NULL, "weak method ref was unexpectedly cleared"); - - if (!method->on_stack()) { - // This method isn't running anymore so remove it - _prev_methods->remove_at(i); - MetadataFactory::free_metadata(method->method_holder()->class_loader_data(), method); - } else { - // RC_TRACE macro has an embedded ResourceMark - RC_TRACE(0x00000400, - ("add: %s(%s): previous cached method @%d is alive", - method->name()->as_C_string(), method->signature()->as_C_string(), i)); - } - } -} // end add_previous_version() - - -bool ActiveMethodOopsCache::is_same_method(const Method* method) const { - InstanceKlass* ik = InstanceKlass::cast(klass()); - const Method* check_method = ik->method_with_idnum(method_idnum()); - assert(check_method != NULL, "sanity check"); - if (check_method == method) { - // done with the easy case - return true; - } - - if (_prev_methods != NULL) { - // The cached method has been redefined at least once so search - // the previous versions for a match. - for (int i = 0; i < _prev_methods->length(); i++) { - check_method = _prev_methods->at(i); - if (check_method == method) { - // a previous version matches - return true; - } - } - } - - // either no previous versions or no previous version matched - return false; -} - - -Method* LatestMethodOopCache::get_Method() { +Method* LatestMethodCache::get_method() { if (klass() == NULL) return NULL; InstanceKlass* ik = InstanceKlass::cast(klass()); Method* m = ik->method_with_idnum(method_idnum());
--- a/src/share/vm/memory/universe.hpp Fri Oct 11 17:14:35 2013 +0200 +++ b/src/share/vm/memory/universe.hpp Fri Oct 11 17:21:14 2013 +0200 @@ -41,10 +41,11 @@ class DeferredObjAllocEvent; -// Common parts of a Method* cache. This cache safely interacts with -// the RedefineClasses API. -// -class CommonMethodOopCache : public CHeapObj<mtClass> { +// A helper class for caching a Method* when the user of the cache +// only cares about the latest version of the Method*. This cache safely +// interacts with the RedefineClasses API. + +class LatestMethodCache : public CHeapObj<mtClass> { // We save the Klass* and the idnum of Method* in order to get // the current cached Method*. private: @@ -52,12 +53,14 @@ int _method_idnum; public: - CommonMethodOopCache() { _klass = NULL; _method_idnum = -1; } - ~CommonMethodOopCache() { _klass = NULL; _method_idnum = -1; } + LatestMethodCache() { _klass = NULL; _method_idnum = -1; } + ~LatestMethodCache() { _klass = NULL; _method_idnum = -1; } - void init(Klass* k, Method* m, TRAPS); - Klass* klass() const { return _klass; } - int method_idnum() const { return _method_idnum; } + void init(Klass* k, Method* m); + Klass* klass() const { return _klass; } + int method_idnum() const { return _method_idnum; } + + Method* get_method(); // Enhanced Class Redefinition support void classes_do(void f(Klass*)) { @@ -72,39 +75,6 @@ }; -// A helper class for caching a Method* when the user of the cache -// cares about all versions of the Method*. -// -class ActiveMethodOopsCache : public CommonMethodOopCache { - // This subclass adds weak references to older versions of the - // Method* and a query method for a Method*. - - private: - // If the cached Method* has not been redefined, then - // _prev_methods will be NULL. If all of the previous - // versions of the method have been collected, then - // _prev_methods can have a length of zero. - GrowableArray<Method*>* _prev_methods; - - public: - ActiveMethodOopsCache() { _prev_methods = NULL; } - ~ActiveMethodOopsCache(); - - void add_previous_version(Method* method); - bool is_same_method(const Method* method) const; -}; - - -// A helper class for caching a Method* when the user of the cache -// only cares about the latest version of the Method*. -// -class LatestMethodOopCache : public CommonMethodOopCache { - // This subclass adds a getter method for the latest Method*. - - public: - Method* get_Method(); -}; - // For UseCompressedOops and UseCompressedKlassPointers. struct NarrowPtrStruct { // Base address for oop/klass-within-java-object materialization. @@ -174,10 +144,10 @@ static objArrayOop _the_empty_class_klass_array; // Canonicalized obj array of type java.lang.Class static oop _the_null_string; // A cache of "null" as a Java string static oop _the_min_jint_string; // A cache of "-2147483648" as a Java string - static LatestMethodOopCache* _finalizer_register_cache; // static method for registering finalizable objects - static LatestMethodOopCache* _loader_addClass_cache; // method for registering loaded classes in class loader vector - static LatestMethodOopCache* _pd_implies_cache; // method for checking protection domain attributes - static ActiveMethodOopsCache* _reflect_invoke_cache; // method for security checks + static LatestMethodCache* _finalizer_register_cache; // static method for registering finalizable objects + static LatestMethodCache* _loader_addClass_cache; // method for registering loaded classes in class loader vector + static LatestMethodCache* _pd_implies_cache; // method for checking protection domain attributes + // preallocated error objects (no backtrace) static oop _out_of_memory_error_java_heap; static oop _out_of_memory_error_metaspace; @@ -334,11 +304,11 @@ static Array<Klass*>* the_array_interfaces_array() { return _the_array_interfaces_array; } static oop the_null_string() { return _the_null_string; } static oop the_min_jint_string() { return _the_min_jint_string; } - static Method* finalizer_register_method() { return _finalizer_register_cache->get_Method(); } - static Method* loader_addClass_method() { return _loader_addClass_cache->get_Method(); } - static Method* protection_domain_implies_method() { return _pd_implies_cache->get_Method(); } - static ActiveMethodOopsCache* reflect_invoke_cache() { return _reflect_invoke_cache; } + static Method* finalizer_register_method() { return _finalizer_register_cache->get_method(); } + static Method* loader_addClass_method() { return _loader_addClass_cache->get_method(); } + + static Method* protection_domain_implies_method() { return _pd_implies_cache->get_method(); } static oop null_ptr_exception_instance() { return _null_ptr_exception_instance; } static oop arithmetic_exception_instance() { return _arithmetic_exception_instance; }
--- a/src/share/vm/oops/method.cpp Fri Oct 11 17:14:35 2013 +0200 +++ b/src/share/vm/oops/method.cpp Fri Oct 11 17:21:14 2013 +0200 @@ -989,7 +989,6 @@ bool Method::is_ignored_by_security_stack_walk() const { const bool use_new_reflection = JDK_Version::is_gte_jdk14x_version() && UseNewReflection; - assert(intrinsic_id() != vmIntrinsics::_invoke || Universe::reflect_invoke_cache()->is_same_method((Method*)this), "sanity"); if (intrinsic_id() == vmIntrinsics::_invoke) { // This is Method.invoke() -- ignore it return true;
--- a/src/share/vm/opto/block.cpp Fri Oct 11 17:14:35 2013 +0200 +++ b/src/share/vm/opto/block.cpp Fri Oct 11 17:21:14 2013 +0200 @@ -221,7 +221,7 @@ //------------------------------is_uncommon------------------------------------ // True if block is low enough frequency or guarded by a test which // mostly does not go here. -bool Block::is_uncommon( Block_Array &bbs ) const { +bool Block::is_uncommon(PhaseCFG* cfg) const { // Initial blocks must never be moved, so are never uncommon. if (head()->is_Root() || head()->is_Start()) return false; @@ -238,7 +238,7 @@ uint uncommon_for_freq_preds = 0; for( uint i=1; i<num_preds(); i++ ) { - Block* guard = bbs[pred(i)->_idx]; + Block* guard = cfg->get_block_for_node(pred(i)); // Check to see if this block follows its guard 1 time out of 10000 // or less. // @@ -285,11 +285,11 @@ } } -void Block::dump_pred(const Block_Array *bbs, Block* orig, outputStream* st) const { +void Block::dump_pred(const PhaseCFG* cfg, Block* orig, outputStream* st) const { if (is_connector()) { for (uint i=1; i<num_preds(); i++) { - Block *p = ((*bbs)[pred(i)->_idx]); - p->dump_pred(bbs, orig, st); + Block *p = cfg->get_block_for_node(pred(i)); + p->dump_pred(cfg, orig, st); } } else { dump_bidx(orig, st); @@ -297,7 +297,7 @@ } } -void Block::dump_head( const Block_Array *bbs, outputStream* st ) const { +void Block::dump_head(const PhaseCFG* cfg, outputStream* st) const { // Print the basic block dump_bidx(this, st); st->print(": #\t"); @@ -311,26 +311,28 @@ if( head()->is_block_start() ) { for (uint i=1; i<num_preds(); i++) { Node *s = pred(i); - if (bbs) { - Block *p = (*bbs)[s->_idx]; - p->dump_pred(bbs, p, st); + if (cfg != NULL) { + Block *p = cfg->get_block_for_node(s); + p->dump_pred(cfg, p, st); } else { while (!s->is_block_start()) s = s->in(0); st->print("N%d ", s->_idx ); } } - } else + } else { st->print("BLOCK HEAD IS JUNK "); + } // Print loop, if any const Block *bhead = this; // Head of self-loop Node *bh = bhead->head(); - if( bbs && bh->is_Loop() && !head()->is_Root() ) { + + if ((cfg != NULL) && bh->is_Loop() && !head()->is_Root()) { LoopNode *loop = bh->as_Loop(); - const Block *bx = (*bbs)[loop->in(LoopNode::LoopBackControl)->_idx]; + const Block *bx = cfg->get_block_for_node(loop->in(LoopNode::LoopBackControl)); while (bx->is_connector()) { - bx = (*bbs)[bx->pred(1)->_idx]; + bx = cfg->get_block_for_node(bx->pred(1)); } st->print("\tLoop: B%d-B%d ", bhead->_pre_order, bx->_pre_order); // Dump any loop-specific bits, especially for CountedLoops. @@ -349,29 +351,32 @@ st->print_cr(""); } -void Block::dump() const { dump(NULL); } +void Block::dump() const { + dump(NULL); +} -void Block::dump( const Block_Array *bbs ) const { - dump_head(bbs); - uint cnt = _nodes.size(); - for( uint i=0; i<cnt; i++ ) +void Block::dump(const PhaseCFG* cfg) const { + dump_head(cfg); + for (uint i=0; i< _nodes.size(); i++) { _nodes[i]->dump(); + } tty->print("\n"); } #endif //============================================================================= //------------------------------PhaseCFG--------------------------------------- -PhaseCFG::PhaseCFG( Arena *a, RootNode *r, Matcher &m ) : - Phase(CFG), - _bbs(a), - _root(r), - _node_latency(NULL) +PhaseCFG::PhaseCFG(Arena* arena, RootNode* root, Matcher& matcher) +: Phase(CFG) +, _block_arena(arena) +, _node_to_block_mapping(arena) +, _root(root) +, _node_latency(NULL) #ifndef PRODUCT - , _trace_opto_pipelining(TraceOptoPipelining || C->method_has_option("TraceOptoPipelining")) +, _trace_opto_pipelining(TraceOptoPipelining || C->method_has_option("TraceOptoPipelining")) #endif #ifdef ASSERT - , _raw_oops(a) +, _raw_oops(arena) #endif { ResourceMark rm; @@ -380,13 +385,13 @@ // Node on demand. Node *x = new (C) GotoNode(NULL); x->init_req(0, x); - _goto = m.match_tree(x); + _goto = matcher.match_tree(x); assert(_goto != NULL, ""); _goto->set_req(0,_goto); // Build the CFG in Reverse Post Order _num_blocks = build_cfg(); - _broot = _bbs[_root->_idx]; + _broot = get_block_for_node(_root); } //------------------------------build_cfg-------------------------------------- @@ -440,9 +445,9 @@ // 'p' now points to the start of this basic block // Put self in array of basic blocks - Block *bb = new (_bbs._arena) Block(_bbs._arena,p); - _bbs.map(p->_idx,bb); - _bbs.map(x->_idx,bb); + Block *bb = new (_block_arena) Block(_block_arena, p); + map_node_to_block(p, bb); + map_node_to_block(x, bb); if( x != p ) { // Only for root is x == p bb->_nodes.push((Node*)x); } @@ -473,16 +478,16 @@ // Check if it the fist node pushed on stack at the beginning. if (idx == 0) break; // end of the build // Find predecessor basic block - Block *pb = _bbs[x->_idx]; + Block *pb = get_block_for_node(x); // Insert into nodes array, if not already there - if( !_bbs.lookup(proj->_idx) ) { + if (!has_block(proj)) { assert( x != proj, "" ); // Map basic block of projection - _bbs.map(proj->_idx,pb); + map_node_to_block(proj, pb); pb->_nodes.push(proj); } // Insert self as a child of my predecessor block - pb->_succs.map(pb->_num_succs++, _bbs[np->_idx]); + pb->_succs.map(pb->_num_succs++, get_block_for_node(np)); assert( pb->_nodes[ pb->_nodes.size() - pb->_num_succs ]->is_block_proj(), "too many control users, not a CFG?" ); } @@ -511,15 +516,15 @@ RegionNode* region = new (C) RegionNode(2); region->init_req(1, proj); // setup corresponding basic block - Block* block = new (_bbs._arena) Block(_bbs._arena, region); - _bbs.map(region->_idx, block); + Block* block = new (_block_arena) Block(_block_arena, region); + map_node_to_block(region, block); C->regalloc()->set_bad(region->_idx); // add a goto node Node* gto = _goto->clone(); // get a new goto node gto->set_req(0, region); // add it to the basic block block->_nodes.push(gto); - _bbs.map(gto->_idx, block); + map_node_to_block(gto, block); C->regalloc()->set_bad(gto->_idx); // hook up successor block block->_succs.map(block->_num_succs++, out); @@ -570,7 +575,7 @@ gto->set_req(0, b->head()); Node *bp = b->_nodes[end_idx]; b->_nodes.map(end_idx,gto); // Slam over NeverBranch - _bbs.map(gto->_idx, b); + map_node_to_block(gto, b); C->regalloc()->set_bad(gto->_idx); b->_nodes.pop(); // Yank projections b->_nodes.pop(); // Yank projections @@ -613,7 +618,7 @@ // If the previous block conditionally falls into bx, return false, // because moving bx will create an extra jump. for(uint k = 1; k < bx->num_preds(); k++ ) { - Block* pred = _bbs[bx->pred(k)->_idx]; + Block* pred = get_block_for_node(bx->pred(k)); if (pred == _blocks[bx_index-1]) { if (pred->_num_succs != 1) { return false; @@ -682,7 +687,7 @@ // Look for uncommon blocks and move to end. if (!C->do_freq_based_layout()) { - if( b->is_uncommon(_bbs) ) { + if (b->is_uncommon(this)) { move_to_end(b, i); last--; // No longer check for being uncommon! if( no_flip_branch(b) ) { // Fall-thru case must follow? @@ -870,28 +875,31 @@ } while( !p->is_block_start() ); // Recursively visit - for( uint i=1; i<p->req(); i++ ) - _dump_cfg(p->in(i),visited); + for (uint i = 1; i < p->req(); i++) { + _dump_cfg(p->in(i), visited); + } // Dump the block - _bbs[p->_idx]->dump(&_bbs); + get_block_for_node(p)->dump(this); } void PhaseCFG::dump( ) const { tty->print("\n--- CFG --- %d BBs\n",_num_blocks); - if( _blocks.size() ) { // Did we do basic-block layout? - for( uint i=0; i<_num_blocks; i++ ) - _blocks[i]->dump(&_bbs); + if (_blocks.size()) { // Did we do basic-block layout? + for (uint i = 0; i < _num_blocks; i++) { + _blocks[i]->dump(this); + } } else { // Else do it with a DFS - VectorSet visited(_bbs._arena); + VectorSet visited(_block_arena); _dump_cfg(_root,visited); } } void PhaseCFG::dump_headers() { for( uint i = 0; i < _num_blocks; i++ ) { - if( _blocks[i] == NULL ) continue; - _blocks[i]->dump_head(&_bbs); + if (_blocks[i]) { + _blocks[i]->dump_head(this); + } } } @@ -904,7 +912,7 @@ uint j; for (j = 0; j < cnt; j++) { Node *n = b->_nodes[j]; - assert( _bbs[n->_idx] == b, "" ); + assert(get_block_for_node(n) == b, ""); if (j >= 1 && n->is_Mach() && n->as_Mach()->ideal_Opcode() == Op_CreateEx) { assert(j == 1 || b->_nodes[j-1]->is_Phi(), @@ -913,13 +921,12 @@ for (uint k = 0; k < n->req(); k++) { Node *def = n->in(k); if (def && def != n) { - assert(_bbs[def->_idx] || def->is_Con(), - "must have block; constants for debug info ok"); + assert(get_block_for_node(def) || def->is_Con(), "must have block; constants for debug info ok"); // Verify that instructions in the block is in correct order. // Uses must follow their definition if they are at the same block. // Mostly done to check that MachSpillCopy nodes are placed correctly // when CreateEx node is moved in build_ifg_physical(). - if (_bbs[def->_idx] == b && + if (get_block_for_node(def) == b && !(b->head()->is_Loop() && n->is_Phi()) && // See (+++) comment in reg_split.cpp !(n->jvms() != NULL && n->jvms()->is_monitor_use(k))) {
--- a/src/share/vm/opto/block.hpp Fri Oct 11 17:14:35 2013 +0200 +++ b/src/share/vm/opto/block.hpp Fri Oct 11 17:21:14 2013 +0200 @@ -48,13 +48,12 @@ friend class VMStructs; uint _size; // allocated size, as opposed to formal limit debug_only(uint _limit;) // limit to formal domain + Arena *_arena; // Arena to allocate in protected: Block **_blocks; void grow( uint i ); // Grow array node to fit public: - Arena *_arena; // Arena to allocate in - Block_Array(Arena *a) : _arena(a), _size(OptoBlockListSize) { debug_only(_limit=0); _blocks = NEW_ARENA_ARRAY( a, Block *, OptoBlockListSize ); @@ -77,7 +76,7 @@ public: uint _cnt; Block_List() : Block_Array(Thread::current()->resource_area()), _cnt(0) {} - void push( Block *b ) { map(_cnt++,b); } + void push( Block *b ) { map(_cnt++,b); } Block *pop() { return _blocks[--_cnt]; } Block *rpop() { Block *b = _blocks[0]; _blocks[0]=_blocks[--_cnt]; return b;} void remove( uint i ); @@ -284,15 +283,15 @@ // helper function that adds caller save registers to MachProjNode void add_call_kills(MachProjNode *proj, RegMask& regs, const char* save_policy, bool exclude_soe); // Schedule a call next in the block - uint sched_call(Matcher &matcher, Block_Array &bbs, uint node_cnt, Node_List &worklist, GrowableArray<int> &ready_cnt, MachCallNode *mcall, VectorSet &next_call); + uint sched_call(Matcher &matcher, PhaseCFG* cfg, uint node_cnt, Node_List &worklist, GrowableArray<int> &ready_cnt, MachCallNode *mcall, VectorSet &next_call); // Perform basic-block local scheduling Node *select(PhaseCFG *cfg, Node_List &worklist, GrowableArray<int> &ready_cnt, VectorSet &next_call, uint sched_slot); - void set_next_call( Node *n, VectorSet &next_call, Block_Array &bbs ); - void needed_for_next_call(Node *this_call, VectorSet &next_call, Block_Array &bbs); + void set_next_call( Node *n, VectorSet &next_call, PhaseCFG* cfg); + void needed_for_next_call(Node *this_call, VectorSet &next_call, PhaseCFG* cfg); bool schedule_local(PhaseCFG *cfg, Matcher &m, GrowableArray<int> &ready_cnt, VectorSet &next_call); // Cleanup if any code lands between a Call and his Catch - void call_catch_cleanup(Block_Array &bbs, Compile *C); + void call_catch_cleanup(PhaseCFG* cfg, Compile *C); // Detect implicit-null-check opportunities. Basically, find NULL checks // with suitable memory ops nearby. Use the memory op to do the NULL check. // I can generate a memory op if there is not one nearby. @@ -331,15 +330,15 @@ // Use frequency calculations and code shape to predict if the block // is uncommon. - bool is_uncommon( Block_Array &bbs ) const; + bool is_uncommon(PhaseCFG* cfg) const; #ifndef PRODUCT // Debugging print of basic block void dump_bidx(const Block* orig, outputStream* st = tty) const; - void dump_pred(const Block_Array *bbs, Block* orig, outputStream* st = tty) const; - void dump_head( const Block_Array *bbs, outputStream* st = tty ) const; + void dump_pred(const PhaseCFG* cfg, Block* orig, outputStream* st = tty) const; + void dump_head(const PhaseCFG* cfg, outputStream* st = tty) const; void dump() const; - void dump( const Block_Array *bbs ) const; + void dump(const PhaseCFG* cfg) const; #endif }; @@ -349,6 +348,12 @@ class PhaseCFG : public Phase { friend class VMStructs; private: + // Arena for the blocks to be stored in + Arena* _block_arena; + + // Map nodes to owning basic block + Block_Array _node_to_block_mapping; + // Build a proper looking cfg. Return count of basic blocks uint build_cfg(); @@ -371,22 +376,42 @@ Block* insert_anti_dependences(Block* LCA, Node* load, bool verify = false); void verify_anti_dependences(Block* LCA, Node* load) { - assert(LCA == _bbs[load->_idx], "should already be scheduled"); + assert(LCA == get_block_for_node(load), "should already be scheduled"); insert_anti_dependences(LCA, load, true); } public: - PhaseCFG( Arena *a, RootNode *r, Matcher &m ); + PhaseCFG(Arena* arena, RootNode* root, Matcher& matcher); uint _num_blocks; // Count of basic blocks Block_List _blocks; // List of basic blocks RootNode *_root; // Root of whole program - Block_Array _bbs; // Map Nodes to owning Basic Block Block *_broot; // Basic block of root uint _rpo_ctr; CFGLoop* _root_loop; float _outer_loop_freq; // Outmost loop frequency + + // set which block this node should reside in + void map_node_to_block(const Node* node, Block* block) { + _node_to_block_mapping.map(node->_idx, block); + } + + // removes the mapping from a node to a block + void unmap_node_from_block(const Node* node) { + _node_to_block_mapping.map(node->_idx, NULL); + } + + // get the block in which this node resides + Block* get_block_for_node(const Node* node) const { + return _node_to_block_mapping[node->_idx]; + } + + // does this node reside in a block; return true + bool has_block(const Node* node) const { + return (_node_to_block_mapping.lookup(node->_idx) != NULL); + } + // Per node latency estimation, valid only during GCM GrowableArray<uint> *_node_latency; @@ -405,7 +430,7 @@ void Estimate_Block_Frequency(); // Global Code Motion. See Click's PLDI95 paper. Place Nodes in specific - // basic blocks; i.e. _bbs now maps _idx for all Nodes to some Block. + // basic blocks; i.e. _node_to_block_mapping now maps _idx for all Nodes to some Block. void GlobalCodeMotion( Matcher &m, uint unique, Node_List &proj_list ); // Compute the (backwards) latency of a node from the uses @@ -454,7 +479,7 @@ // Insert a node into a block, and update the _bbs void insert( Block *b, uint idx, Node *n ) { b->_nodes.insert( idx, n ); - _bbs.map( n->_idx, b ); + map_node_to_block(n, b); } #ifndef PRODUCT @@ -543,7 +568,7 @@ _child(NULL), _exit_prob(1.0f) {} CFGLoop* parent() { return _parent; } - void push_pred(Block* blk, int i, Block_List& worklist, Block_Array& node_to_blk); + void push_pred(Block* blk, int i, Block_List& worklist, PhaseCFG* cfg); void add_member(CFGElement *s) { _members.push(s); } void add_nested_loop(CFGLoop* cl); Block* head() {
--- a/src/share/vm/opto/buildOopMap.cpp Fri Oct 11 17:14:35 2013 +0200 +++ b/src/share/vm/opto/buildOopMap.cpp Fri Oct 11 17:21:14 2013 +0200 @@ -426,14 +426,16 @@ } memset( live, 0, cfg->_num_blocks * (max_reg_ints<<LogBytesPerInt) ); // Push preds onto worklist - for( uint i=1; i<root->req(); i++ ) - worklist->push(cfg->_bbs[root->in(i)->_idx]); + for (uint i = 1; i < root->req(); i++) { + Block* block = cfg->get_block_for_node(root->in(i)); + worklist->push(block); + } // ZKM.jar includes tiny infinite loops which are unreached from below. // If we missed any blocks, we'll retry here after pushing all missed // blocks on the worklist. Normally this outer loop never trips more // than once. - while( 1 ) { + while (1) { while( worklist->size() ) { // Standard worklist algorithm Block *b = worklist->rpop(); @@ -537,8 +539,10 @@ for( l=0; l<max_reg_ints; l++ ) old_live[l] = tmp_live[l]; // Push preds onto worklist - for( l=1; l<(int)b->num_preds(); l++ ) - worklist->push(cfg->_bbs[b->pred(l)->_idx]); + for (l = 1; l < (int)b->num_preds(); l++) { + Block* block = cfg->get_block_for_node(b->pred(l)); + worklist->push(block); + } } } @@ -629,10 +633,9 @@ // pred to this block. Otherwise we have to grab a new OopFlow. OopFlow *flow = NULL; // Flag for finding optimized flow Block *pred = (Block*)0xdeadbeef; - uint j; // Scan this block's preds to find a done predecessor - for( j=1; j<b->num_preds(); j++ ) { - Block *p = _cfg->_bbs[b->pred(j)->_idx]; + for (uint j = 1; j < b->num_preds(); j++) { + Block* p = _cfg->get_block_for_node(b->pred(j)); OopFlow *p_flow = flows[p->_pre_order]; if( p_flow ) { // Predecessor is done assert( p_flow->_b == p, "cross check" );
--- a/src/share/vm/opto/c2_globals.hpp Fri Oct 11 17:14:35 2013 +0200 +++ b/src/share/vm/opto/c2_globals.hpp Fri Oct 11 17:21:14 2013 +0200 @@ -179,6 +179,9 @@ product_pd(intx, LoopUnrollLimit, \ "Unroll loop bodies with node count less than this") \ \ + product(intx, LoopMaxUnroll, 16, \ + "Maximum number of unrolls for main loop") \ + \ product(intx, LoopUnrollMin, 4, \ "Minimum number of unroll loop bodies before checking progress" \ "of rounds of unroll,optimize,..") \
--- a/src/share/vm/opto/chaitin.cpp Fri Oct 11 17:14:35 2013 +0200 +++ b/src/share/vm/opto/chaitin.cpp Fri Oct 11 17:21:14 2013 +0200 @@ -295,7 +295,7 @@ bool PhaseChaitin::clone_projs_shared(Block *b, uint idx, Node *con, Node *copy, uint max_lrg_id) { - Block *bcon = _cfg._bbs[con->_idx]; + Block* bcon = _cfg.get_block_for_node(con); uint cindex = bcon->find_node(con); Node *con_next = bcon->_nodes[cindex+1]; if (con_next->in(0) != con || !con_next->is_MachProj()) { @@ -306,7 +306,7 @@ Node *kills = con_next->clone(); kills->set_req(0, copy); b->_nodes.insert(idx, kills); - _cfg._bbs.map(kills->_idx, b); + _cfg.map_node_to_block(kills, b); new_lrg(kills, max_lrg_id); return true; } @@ -962,8 +962,7 @@ // AggressiveCoalesce. This effectively pre-virtual-splits // around uncommon uses of common defs. const RegMask &rm = n->in_RegMask(k); - if( !after_aggressive && - _cfg._bbs[n->in(k)->_idx]->_freq > 1000*b->_freq ) { + if (!after_aggressive && _cfg.get_block_for_node(n->in(k))->_freq > 1000 * b->_freq) { // Since we are BEFORE aggressive coalesce, leave the register // mask untrimmed by the call. This encourages more coalescing. // Later, AFTER aggressive, this live range will have to spill @@ -1709,16 +1708,15 @@ // set control to _root and place it into Start block // (where top() node is placed). base->init_req(0, _cfg._root); - Block *startb = _cfg._bbs[C->top()->_idx]; + Block *startb = _cfg.get_block_for_node(C->top()); startb->_nodes.insert(startb->find_node(C->top()), base ); - _cfg._bbs.map( base->_idx, startb ); + _cfg.map_node_to_block(base, startb); assert(_lrg_map.live_range_id(base) == 0, "should not have LRG yet"); } if (_lrg_map.live_range_id(base) == 0) { new_lrg(base, maxlrg++); } - assert(base->in(0) == _cfg._root && - _cfg._bbs[base->_idx] == _cfg._bbs[C->top()->_idx], "base NULL should be shared"); + assert(base->in(0) == _cfg._root && _cfg.get_block_for_node(base) == _cfg.get_block_for_node(C->top()), "base NULL should be shared"); derived_base_map[derived->_idx] = base; return base; } @@ -1754,12 +1752,12 @@ base->as_Phi()->set_type(t); // Search the current block for an existing base-Phi - Block *b = _cfg._bbs[derived->_idx]; + Block *b = _cfg.get_block_for_node(derived); for( i = 1; i <= b->end_idx(); i++ ) {// Search for matching Phi Node *phi = b->_nodes[i]; if( !phi->is_Phi() ) { // Found end of Phis with no match? b->_nodes.insert( i, base ); // Must insert created Phi here as base - _cfg._bbs.map( base->_idx, b ); + _cfg.map_node_to_block(base, b); new_lrg(base,maxlrg++); break; } @@ -1815,8 +1813,8 @@ if( n->is_Mach() && n->as_Mach()->ideal_Opcode() == Op_CmpI ) { Node *phi = n->in(1); if( phi->is_Phi() && phi->as_Phi()->region()->is_Loop() ) { - Block *phi_block = _cfg._bbs[phi->_idx]; - if( _cfg._bbs[phi_block->pred(2)->_idx] == b ) { + Block *phi_block = _cfg.get_block_for_node(phi); + if (_cfg.get_block_for_node(phi_block->pred(2)) == b) { const RegMask *mask = C->matcher()->idealreg2spillmask[Op_RegI]; Node *spill = new (C) MachSpillCopyNode( phi, *mask, *mask ); insert_proj( phi_block, 1, spill, maxlrg++ ); @@ -1870,7 +1868,7 @@ if ((_lrg_map.live_range_id(base) >= _lrg_map.max_lrg_id() || // (Brand new base (hence not live) or !liveout.member(_lrg_map.live_range_id(base))) && // not live) AND (_lrg_map.live_range_id(base) > 0) && // not a constant - _cfg._bbs[base->_idx] != b) { // base not def'd in blk) + _cfg.get_block_for_node(base) != b) { // base not def'd in blk) // Base pointer is not currently live. Since I stretched // the base pointer to here and it crosses basic-block // boundaries, the global live info is now incorrect. @@ -1993,8 +1991,8 @@ tty->print("\n"); } -void PhaseChaitin::dump( const Block * b ) const { - b->dump_head( &_cfg._bbs ); +void PhaseChaitin::dump(const Block *b) const { + b->dump_head(&_cfg); // For all instructions for( uint j = 0; j < b->_nodes.size(); j++ ) @@ -2299,7 +2297,7 @@ if (_lrg_map.find_const(n) == lidx) { if (!dump_once++) { tty->cr(); - b->dump_head( &_cfg._bbs ); + b->dump_head(&_cfg); } dump(n); continue; @@ -2314,7 +2312,7 @@ if (_lrg_map.find_const(m) == lidx) { if (!dump_once++) { tty->cr(); - b->dump_head(&_cfg._bbs); + b->dump_head(&_cfg); } dump(n); }
--- a/src/share/vm/opto/coalesce.cpp Fri Oct 11 17:14:35 2013 +0200 +++ b/src/share/vm/opto/coalesce.cpp Fri Oct 11 17:21:14 2013 +0200 @@ -52,7 +52,7 @@ // Print a nice block header tty->print("B%d: ",b->_pre_order); for( j=1; j<b->num_preds(); j++ ) - tty->print("B%d ", _phc._cfg._bbs[b->pred(j)->_idx]->_pre_order); + tty->print("B%d ", _phc._cfg.get_block_for_node(b->pred(j))->_pre_order); tty->print("-> "); for( j=0; j<b->_num_succs; j++ ) tty->print("B%d ",b->_succs[j]->_pre_order); @@ -208,7 +208,7 @@ copy->set_req(idx,tmp); // Save source in temp early, before source is killed b->_nodes.insert(kill_src_idx,tmp); - _phc._cfg._bbs.map( tmp->_idx, b ); + _phc._cfg.map_node_to_block(tmp, b); last_use_idx++; } @@ -286,7 +286,7 @@ Node *m = n->in(j); uint src_name = _phc._lrg_map.find(m); if (src_name != phi_name) { - Block *pred = _phc._cfg._bbs[b->pred(j)->_idx]; + Block *pred = _phc._cfg.get_block_for_node(b->pred(j)); Node *copy; assert(!m->is_Con() || m->is_Mach(), "all Con must be Mach"); // Rematerialize constants instead of copying them @@ -305,7 +305,7 @@ } // Insert the copy in the use-def chain n->set_req(j, copy); - _phc._cfg._bbs.map( copy->_idx, pred ); + _phc._cfg.map_node_to_block(copy, pred); // Extend ("register allocate") the names array for the copy. _phc._lrg_map.extend(copy->_idx, phi_name); } // End of if Phi names do not match @@ -343,13 +343,13 @@ n->set_req(idx, copy); // Extend ("register allocate") the names array for the copy. _phc._lrg_map.extend(copy->_idx, name); - _phc._cfg._bbs.map( copy->_idx, b ); + _phc._cfg.map_node_to_block(copy, b); } } // End of is two-adr // Insert a copy at a debug use for a lrg which has high frequency - if (b->_freq < OPTO_DEBUG_SPLIT_FREQ || b->is_uncommon(_phc._cfg._bbs)) { + if (b->_freq < OPTO_DEBUG_SPLIT_FREQ || b->is_uncommon(&_phc._cfg)) { // Walk the debug inputs to the node and check for lrg freq JVMState* jvms = n->jvms(); uint debug_start = jvms ? jvms->debug_start() : 999999; @@ -391,7 +391,7 @@ uint max_lrg_id = _phc._lrg_map.max_lrg_id(); _phc.new_lrg(copy, max_lrg_id); _phc._lrg_map.set_max_lrg_id(max_lrg_id + 1); - _phc._cfg._bbs.map(copy->_idx, b); + _phc._cfg.map_node_to_block(copy, b); //tty->print_cr("Split a debug use in Aggressive Coalesce"); } // End of if high frequency use/def } // End of for all debug inputs @@ -437,7 +437,10 @@ Block *bs = b->_succs[i]; // Find index of 'b' in 'bs' predecessors uint j=1; - while( _phc._cfg._bbs[bs->pred(j)->_idx] != b ) j++; + while (_phc._cfg.get_block_for_node(bs->pred(j)) != b) { + j++; + } + // Visit all the Phis in successor block for( uint k = 1; k<bs->_nodes.size(); k++ ) { Node *n = bs->_nodes[k]; @@ -510,9 +513,9 @@ if( bindex < b->_fhrp_index ) b->_fhrp_index--; // Stretched lr1; add it to liveness of intermediate blocks - Block *b2 = _phc._cfg._bbs[src_copy->_idx]; + Block *b2 = _phc._cfg.get_block_for_node(src_copy); while( b != b2 ) { - b = _phc._cfg._bbs[b->pred(1)->_idx]; + b = _phc._cfg.get_block_for_node(b->pred(1)); _phc._live->live(b)->insert(lr1); } } @@ -532,7 +535,7 @@ bindex2--; // Chain backwards 1 instruction while( bindex2 == 0 ) { // At block start, find prior block assert( b2->num_preds() == 2, "cannot double coalesce across c-flow" ); - b2 = _phc._cfg._bbs[b2->pred(1)->_idx]; + b2 = _phc._cfg.get_block_for_node(b2->pred(1)); bindex2 = b2->end_idx()-1; } // Get prior instruction @@ -676,8 +679,8 @@ if (UseFPUForSpilling && rm.is_AllStack() ) { // Don't coalesce when frequency difference is large - Block *dst_b = _phc._cfg._bbs[dst_copy->_idx]; - Block *src_def_b = _phc._cfg._bbs[src_def->_idx]; + Block *dst_b = _phc._cfg.get_block_for_node(dst_copy); + Block *src_def_b = _phc._cfg.get_block_for_node(src_def); if (src_def_b->_freq > 10*dst_b->_freq ) return false; } @@ -690,7 +693,7 @@ // Another early bail-out test is when we are double-coalescing and the // 2 copies are separated by some control flow. if( dst_copy != src_copy ) { - Block *src_b = _phc._cfg._bbs[src_copy->_idx]; + Block *src_b = _phc._cfg.get_block_for_node(src_copy); Block *b2 = b; while( b2 != src_b ) { if( b2->num_preds() > 2 ){// Found merge-point @@ -701,7 +704,7 @@ //record_bias( _phc._lrgs, lr1, lr2 ); return false; // To hard to find all interferences } - b2 = _phc._cfg._bbs[b2->pred(1)->_idx]; + b2 = _phc._cfg.get_block_for_node(b2->pred(1)); } } @@ -786,8 +789,9 @@ // Conservative (but pessimistic) copy coalescing of a single block void PhaseConservativeCoalesce::coalesce( Block *b ) { // Bail out on infrequent blocks - if( b->is_uncommon(_phc._cfg._bbs) ) + if (b->is_uncommon(&_phc._cfg)) { return; + } // Check this block for copies. for( uint i = 1; i<b->end_idx(); i++ ) { // Check for actual copies on inputs. Coalesce a copy into its
--- a/src/share/vm/opto/compile.cpp Fri Oct 11 17:14:35 2013 +0200 +++ b/src/share/vm/opto/compile.cpp Fri Oct 11 17:21:14 2013 +0200 @@ -2262,7 +2262,7 @@ tty->print("%3.3x ", pcs[n->_idx]); else tty->print(" "); - b->dump_head( &_cfg->_bbs ); + b->dump_head(_cfg); if (b->is_connector()) { tty->print_cr(" # Empty connector block"); } else if (b->num_preds() == 2 && b->pred(1)->is_CatchProj() && b->pred(1)->as_CatchProj()->_con == CatchProjNode::fall_through_index) { @@ -3525,7 +3525,7 @@ } Compile::Constant Compile::ConstantTable::add(MachConstantNode* n, BasicType type, jvalue value) { - Block* b = Compile::current()->cfg()->_bbs[n->_idx]; + Block* b = Compile::current()->cfg()->get_block_for_node(n); Constant con(type, value, b->_freq); add(con); return con;
--- a/src/share/vm/opto/domgraph.cpp Fri Oct 11 17:14:35 2013 +0200 +++ b/src/share/vm/opto/domgraph.cpp Fri Oct 11 17:21:14 2013 +0200 @@ -105,8 +105,8 @@ // Step 2: Node *whead = w->_block->head(); - for( uint j=1; j < whead->req(); j++ ) { - Block *b = _bbs[whead->in(j)->_idx]; + for (uint j = 1; j < whead->req(); j++) { + Block* b = get_block_for_node(whead->in(j)); Tarjan *vx = &tarjan[b->_pre_order]; Tarjan *u = vx->EVAL(); if( u->_semi < w->_semi )
--- a/src/share/vm/opto/gcm.cpp Fri Oct 11 17:14:35 2013 +0200 +++ b/src/share/vm/opto/gcm.cpp Fri Oct 11 17:21:14 2013 +0200 @@ -66,7 +66,7 @@ // are in b also. void PhaseCFG::schedule_node_into_block( Node *n, Block *b ) { // Set basic block of n, Add n to b, - _bbs.map(n->_idx, b); + map_node_to_block(n, b); b->add_inst(n); // After Matching, nearly any old Node may have projections trailing it. @@ -75,11 +75,12 @@ for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) { Node* use = n->fast_out(i); if (use->is_Proj()) { - Block* buse = _bbs[use->_idx]; + Block* buse = get_block_for_node(use); if (buse != b) { // In wrong block? - if (buse != NULL) + if (buse != NULL) { buse->find_remove(use); // Remove from wrong block - _bbs.map(use->_idx, b); // Re-insert in this block + } + map_node_to_block(use, b); b->add_inst(use); } } @@ -97,7 +98,7 @@ if (p != NULL && p != n) { // Control from a block projection? assert(!n->pinned() || n->is_MachConstantBase(), "only pinned MachConstantBase node is expected here"); // Find trailing Region - Block *pb = _bbs[in0->_idx]; // Block-projection already has basic block + Block *pb = get_block_for_node(in0); // Block-projection already has basic block uint j = 0; if (pb->_num_succs != 1) { // More then 1 successor? // Search for successor @@ -127,14 +128,15 @@ while ( spstack.is_nonempty() ) { Node *n = spstack.pop(); if( !visited.test_set(n->_idx) ) { // Test node and flag it as visited - if( n->pinned() && !_bbs.lookup(n->_idx) ) { // Pinned? Nail it down! + if( n->pinned() && !has_block(n)) { // Pinned? Nail it down! assert( n->in(0), "pinned Node must have Control" ); // Before setting block replace block_proj control edge replace_block_proj_ctrl(n); Node *input = n->in(0); - while( !input->is_block_start() ) + while (!input->is_block_start()) { input = input->in(0); - Block *b = _bbs[input->_idx]; // Basic block of controlling input + } + Block *b = get_block_for_node(input); // Basic block of controlling input schedule_node_into_block(n, b); } for( int i = n->req() - 1; i >= 0; --i ) { // For all inputs @@ -149,7 +151,7 @@ // Assert that new input b2 is dominated by all previous inputs. // Check this by by seeing that it is dominated by b1, the deepest // input observed until b2. -static void assert_dom(Block* b1, Block* b2, Node* n, Block_Array &bbs) { +static void assert_dom(Block* b1, Block* b2, Node* n, const PhaseCFG* cfg) { if (b1 == NULL) return; assert(b1->_dom_depth < b2->_dom_depth, "sanity"); Block* tmp = b2; @@ -162,7 +164,7 @@ for (uint j=0; j<n->len(); j++) { // For all inputs Node* inn = n->in(j); // Get input if (inn == NULL) continue; // Ignore NULL, missing inputs - Block* inb = bbs[inn->_idx]; + Block* inb = cfg->get_block_for_node(inn); tty->print("B%d idom=B%d depth=%2d ",inb->_pre_order, inb->_idom ? inb->_idom->_pre_order : 0, inb->_dom_depth); inn->dump(); @@ -174,20 +176,20 @@ } #endif -static Block* find_deepest_input(Node* n, Block_Array &bbs) { +static Block* find_deepest_input(Node* n, const PhaseCFG* cfg) { // Find the last input dominated by all other inputs. Block* deepb = NULL; // Deepest block so far int deepb_dom_depth = 0; for (uint k = 0; k < n->len(); k++) { // For all inputs Node* inn = n->in(k); // Get input if (inn == NULL) continue; // Ignore NULL, missing inputs - Block* inb = bbs[inn->_idx]; + Block* inb = cfg->get_block_for_node(inn); assert(inb != NULL, "must already have scheduled this input"); if (deepb_dom_depth < (int) inb->_dom_depth) { // The new inb must be dominated by the previous deepb. // The various inputs must be linearly ordered in the dom // tree, or else there will not be a unique deepest block. - DEBUG_ONLY(assert_dom(deepb, inb, n, bbs)); + DEBUG_ONLY(assert_dom(deepb, inb, n, cfg)); deepb = inb; // Save deepest block deepb_dom_depth = deepb->_dom_depth; } @@ -243,7 +245,7 @@ ++i; if (in == NULL) continue; // Ignore NULL, missing inputs int is_visited = visited.test_set(in->_idx); - if (!_bbs.lookup(in->_idx)) { // Missing block selection? + if (!has_block(in)) { // Missing block selection? if (is_visited) { // assert( !visited.test(in->_idx), "did not schedule early" ); return false; @@ -265,9 +267,9 @@ // any projections which depend on them. if (!n->pinned()) { // Set earliest legal block. - _bbs.map(n->_idx, find_deepest_input(n, _bbs)); + map_node_to_block(n, find_deepest_input(n, this)); } else { - assert(_bbs[n->_idx] == _bbs[n->in(0)->_idx], "Pinned Node should be at the same block as its control edge"); + assert(get_block_for_node(n) == get_block_for_node(n->in(0)), "Pinned Node should be at the same block as its control edge"); } if (nstack.is_empty()) { @@ -313,8 +315,8 @@ // The definition must dominate the use, so move the LCA upward in the // dominator tree to dominate the use. If the use is a phi, adjust // the LCA only with the phi input paths which actually use this def. -static Block* raise_LCA_above_use(Block* LCA, Node* use, Node* def, Block_Array &bbs) { - Block* buse = bbs[use->_idx]; +static Block* raise_LCA_above_use(Block* LCA, Node* use, Node* def, const PhaseCFG* cfg) { + Block* buse = cfg->get_block_for_node(use); if (buse == NULL) return LCA; // Unused killing Projs have no use block if (!use->is_Phi()) return buse->dom_lca(LCA); uint pmax = use->req(); // Number of Phi inputs @@ -329,7 +331,7 @@ // more than once. for (uint j=1; j<pmax; j++) { // For all inputs if (use->in(j) == def) { // Found matching input? - Block* pred = bbs[buse->pred(j)->_idx]; + Block* pred = cfg->get_block_for_node(buse->pred(j)); LCA = pred->dom_lca(LCA); } } @@ -342,8 +344,7 @@ // which are marked with the given index. Return the LCA (in the dom tree) // of all marked blocks. If there are none marked, return the original // LCA. -static Block* raise_LCA_above_marks(Block* LCA, node_idx_t mark, - Block* early, Block_Array &bbs) { +static Block* raise_LCA_above_marks(Block* LCA, node_idx_t mark, Block* early, const PhaseCFG* cfg) { Block_List worklist; worklist.push(LCA); while (worklist.size() > 0) { @@ -366,7 +367,7 @@ } else { // Keep searching through this block's predecessors. for (uint j = 1, jmax = mid->num_preds(); j < jmax; j++) { - Block* mid_parent = bbs[ mid->pred(j)->_idx ]; + Block* mid_parent = cfg->get_block_for_node(mid->pred(j)); worklist.push(mid_parent); } } @@ -384,7 +385,7 @@ // be earlier (at a shallower dom_depth) than the true schedule_early // point of the node. We compute this earlier block as a more permissive // site for anti-dependency insertion, but only if subsume_loads is enabled. -static Block* memory_early_block(Node* load, Block* early, Block_Array &bbs) { +static Block* memory_early_block(Node* load, Block* early, const PhaseCFG* cfg) { Node* base; Node* index; Node* store = load->in(MemNode::Memory); @@ -412,12 +413,12 @@ Block* deepb = NULL; // Deepest block so far int deepb_dom_depth = 0; for (int i = 0; i < mem_inputs_length; i++) { - Block* inb = bbs[mem_inputs[i]->_idx]; + Block* inb = cfg->get_block_for_node(mem_inputs[i]); if (deepb_dom_depth < (int) inb->_dom_depth) { // The new inb must be dominated by the previous deepb. // The various inputs must be linearly ordered in the dom // tree, or else there will not be a unique deepest block. - DEBUG_ONLY(assert_dom(deepb, inb, load, bbs)); + DEBUG_ONLY(assert_dom(deepb, inb, load, cfg)); deepb = inb; // Save deepest block deepb_dom_depth = deepb->_dom_depth; } @@ -488,14 +489,14 @@ // and other inputs are first available. (Computed by schedule_early.) // For normal loads, 'early' is the shallowest place (dom graph wise) // to look for anti-deps between this load and any store. - Block* early = _bbs[load_index]; + Block* early = get_block_for_node(load); // If we are subsuming loads, compute an "early" block that only considers // memory or address inputs. This block may be different than the // schedule_early block in that it could be at an even shallower depth in the // dominator tree, and allow for a broader discovery of anti-dependences. if (C->subsume_loads()) { - early = memory_early_block(load, early, _bbs); + early = memory_early_block(load, early, this); } ResourceArea *area = Thread::current()->resource_area(); @@ -619,7 +620,7 @@ // or else observe that 'store' is all the way up in the // earliest legal block for 'load'. In the latter case, // immediately insert an anti-dependence edge. - Block* store_block = _bbs[store->_idx]; + Block* store_block = get_block_for_node(store); assert(store_block != NULL, "unused killing projections skipped above"); if (store->is_Phi()) { @@ -637,7 +638,7 @@ for (uint j = PhiNode::Input, jmax = store->req(); j < jmax; j++) { if (store->in(j) == mem) { // Found matching input? DEBUG_ONLY(found_match = true); - Block* pred_block = _bbs[store_block->pred(j)->_idx]; + Block* pred_block = get_block_for_node(store_block->pred(j)); if (pred_block != early) { // If any predecessor of the Phi matches the load's "early block", // we do not need a precedence edge between the Phi and 'load' @@ -711,7 +712,7 @@ // preventing the load from sinking past any block containing // a store that may invalidate the memory state required by 'load'. if (must_raise_LCA) - LCA = raise_LCA_above_marks(LCA, load->_idx, early, _bbs); + LCA = raise_LCA_above_marks(LCA, load->_idx, early, this); if (LCA == early) return LCA; // Insert anti-dependence edges from 'load' to each store @@ -720,7 +721,7 @@ if (LCA->raise_LCA_mark() == load_index) { while (non_early_stores.size() > 0) { Node* store = non_early_stores.pop(); - Block* store_block = _bbs[store->_idx]; + Block* store_block = get_block_for_node(store); if (store_block == LCA) { // add anti_dependence from store to load in its own block assert(store != load->in(0), "dependence cycle found"); @@ -754,7 +755,7 @@ public: // Constructor for the iterator - Node_Backward_Iterator(Node *root, VectorSet &visited, Node_List &stack, Block_Array &bbs); + Node_Backward_Iterator(Node *root, VectorSet &visited, Node_List &stack, PhaseCFG &cfg); // Postincrement operator to iterate over the nodes Node *next(); @@ -762,12 +763,12 @@ private: VectorSet &_visited; Node_List &_stack; - Block_Array &_bbs; + PhaseCFG &_cfg; }; // Constructor for the Node_Backward_Iterator -Node_Backward_Iterator::Node_Backward_Iterator( Node *root, VectorSet &visited, Node_List &stack, Block_Array &bbs ) - : _visited(visited), _stack(stack), _bbs(bbs) { +Node_Backward_Iterator::Node_Backward_Iterator( Node *root, VectorSet &visited, Node_List &stack, PhaseCFG &cfg) + : _visited(visited), _stack(stack), _cfg(cfg) { // The stack should contain exactly the root stack.clear(); stack.push(root); @@ -797,8 +798,8 @@ _visited.set(self->_idx); // Now schedule all uses as late as possible. - uint src = self->is_Proj() ? self->in(0)->_idx : self->_idx; - uint src_rpo = _bbs[src]->_rpo; + const Node* src = self->is_Proj() ? self->in(0) : self; + uint src_rpo = _cfg.get_block_for_node(src)->_rpo; // Schedule all nodes in a post-order visit Node *unvisited = NULL; // Unvisited anti-dependent Node, if any @@ -814,7 +815,7 @@ // do not traverse backward control edges Node *use = n->is_Proj() ? n->in(0) : n; - uint use_rpo = _bbs[use->_idx]->_rpo; + uint use_rpo = _cfg.get_block_for_node(use)->_rpo; if ( use_rpo < src_rpo ) continue; @@ -852,7 +853,7 @@ tty->print("\n#---- ComputeLatenciesBackwards ----\n"); #endif - Node_Backward_Iterator iter((Node *)_root, visited, stack, _bbs); + Node_Backward_Iterator iter((Node *)_root, visited, stack, *this); Node *n; // Walk over all the nodes from last to first @@ -883,7 +884,7 @@ uint nlen = n->len(); uint use_latency = _node_latency->at_grow(n->_idx); - uint use_pre_order = _bbs[n->_idx]->_pre_order; + uint use_pre_order = get_block_for_node(n)->_pre_order; for ( uint j=0; j<nlen; j++ ) { Node *def = n->in(j); @@ -903,7 +904,7 @@ #endif // If the defining block is not known, assume it is ok - Block *def_block = _bbs[def->_idx]; + Block *def_block = get_block_for_node(def); uint def_pre_order = def_block ? def_block->_pre_order : 0; if ( (use_pre_order < def_pre_order) || @@ -931,10 +932,11 @@ // Compute the latency of a specific use int PhaseCFG::latency_from_use(Node *n, const Node *def, Node *use) { // If self-reference, return no latency - if (use == n || use->is_Root()) + if (use == n || use->is_Root()) { return 0; + } - uint def_pre_order = _bbs[def->_idx]->_pre_order; + uint def_pre_order = get_block_for_node(def)->_pre_order; uint latency = 0; // If the use is not a projection, then it is simple... @@ -946,7 +948,7 @@ } #endif - uint use_pre_order = _bbs[use->_idx]->_pre_order; + uint use_pre_order = get_block_for_node(use)->_pre_order; if (use_pre_order < def_pre_order) return 0; @@ -1018,7 +1020,7 @@ uint start_latency = _node_latency->at_grow(LCA->_nodes[0]->_idx); uint end_latency = _node_latency->at_grow(LCA->_nodes[LCA->end_idx()]->_idx); bool in_latency = (target <= start_latency); - const Block* root_block = _bbs[_root->_idx]; + const Block* root_block = get_block_for_node(_root); // Turn off latency scheduling if scheduling is just plain off if (!C->do_scheduling()) @@ -1126,12 +1128,12 @@ tty->print("\n#---- schedule_late ----\n"); #endif - Node_Backward_Iterator iter((Node *)_root, visited, stack, _bbs); + Node_Backward_Iterator iter((Node *)_root, visited, stack, *this); Node *self; // Walk over all the nodes from last to first while (self = iter.next()) { - Block* early = _bbs[self->_idx]; // Earliest legal placement + Block* early = get_block_for_node(self); // Earliest legal placement if (self->is_top()) { // Top node goes in bb #2 with other constants. @@ -1179,7 +1181,7 @@ for (DUIterator_Fast imax, i = self->fast_outs(imax); i < imax; i++) { // For all uses, find LCA Node* use = self->fast_out(i); - LCA = raise_LCA_above_use(LCA, use, self, _bbs); + LCA = raise_LCA_above_use(LCA, use, self, this); } } // (Hide defs of imax, i from rest of block.) @@ -1187,7 +1189,7 @@ // requirement for correctness but it reduces useless // interference between temps and other nodes. if (mach != NULL && mach->is_MachTemp()) { - _bbs.map(self->_idx, LCA); + map_node_to_block(self, LCA); LCA->add_inst(self); continue; } @@ -1262,10 +1264,10 @@ } #endif - // Initialize the bbs.map for things on the proj_list - uint i; - for( i=0; i < proj_list.size(); i++ ) - _bbs.map(proj_list[i]->_idx, NULL); + // Initialize the node to block mapping for things on the proj_list + for (uint i = 0; i < proj_list.size(); i++) { + unmap_node_from_block(proj_list[i]); + } // Set the basic block for Nodes pinned into blocks Arena *a = Thread::current()->resource_area(); @@ -1333,7 +1335,7 @@ for( int i= matcher._null_check_tests.size()-2; i>=0; i-=2 ) { Node *proj = matcher._null_check_tests[i ]; Node *val = matcher._null_check_tests[i+1]; - _bbs[proj->_idx]->implicit_null_check(this, proj, val, allowed_reasons); + get_block_for_node(proj)->implicit_null_check(this, proj, val, allowed_reasons); // The implicit_null_check will only perform the transformation // if the null branch is truly uncommon, *and* it leads to an // uncommon trap. Combined with the too_many_traps guards @@ -1353,7 +1355,7 @@ uint max_idx = C->unique(); GrowableArray<int> ready_cnt(max_idx, max_idx, -1); visited.Clear(); - for (i = 0; i < _num_blocks; i++) { + for (uint i = 0; i < _num_blocks; i++) { if (!_blocks[i]->schedule_local(this, matcher, ready_cnt, visited)) { if (!C->failure_reason_is(C2Compiler::retry_no_subsuming_loads())) { C->record_method_not_compilable("local schedule failed"); @@ -1364,8 +1366,9 @@ // If we inserted any instructions between a Call and his CatchNode, // clone the instructions on all paths below the Catch. - for( i=0; i < _num_blocks; i++ ) - _blocks[i]->call_catch_cleanup(_bbs, C); + for (uint i = 0; i < _num_blocks; i++) { + _blocks[i]->call_catch_cleanup(this, C); + } #ifndef PRODUCT if (trace_opto_pipelining()) { @@ -1392,7 +1395,7 @@ Block_List worklist; Block* root_blk = _blocks[0]; for (uint i = 1; i < root_blk->num_preds(); i++) { - Block *pb = _bbs[root_blk->pred(i)->_idx]; + Block *pb = get_block_for_node(root_blk->pred(i)); if (pb->has_uncommon_code()) { worklist.push(pb); } @@ -1401,7 +1404,7 @@ Block* uct = worklist.pop(); if (uct == _broot) continue; for (uint i = 1; i < uct->num_preds(); i++) { - Block *pb = _bbs[uct->pred(i)->_idx]; + Block *pb = get_block_for_node(uct->pred(i)); if (pb->_num_succs == 1) { worklist.push(pb); } else if (pb->num_fall_throughs() == 2) { @@ -1430,7 +1433,7 @@ Block_List worklist; Block* root_blk = _blocks[0]; for (uint i = 1; i < root_blk->num_preds(); i++) { - Block *pb = _bbs[root_blk->pred(i)->_idx]; + Block *pb = get_block_for_node(root_blk->pred(i)); if (pb->has_uncommon_code()) { worklist.push(pb); } @@ -1439,7 +1442,7 @@ Block* uct = worklist.pop(); uct->_freq = PROB_MIN; for (uint i = 1; i < uct->num_preds(); i++) { - Block *pb = _bbs[uct->pred(i)->_idx]; + Block *pb = get_block_for_node(uct->pred(i)); if (pb->_num_succs == 1 && pb->_freq > PROB_MIN) { worklist.push(pb); } @@ -1499,7 +1502,7 @@ Block* loop_head = b; assert(loop_head->num_preds() - 1 == 2, "loop must have 2 predecessors"); Node* tail_n = loop_head->pred(LoopNode::LoopBackControl); - Block* tail = _bbs[tail_n->_idx]; + Block* tail = get_block_for_node(tail_n); // Defensively filter out Loop nodes for non-single-entry loops. // For all reasonable loops, the head occurs before the tail in RPO. @@ -1514,13 +1517,13 @@ loop_head->_loop = nloop; // Add to nloop so push_pred() will skip over inner loops nloop->add_member(loop_head); - nloop->push_pred(loop_head, LoopNode::LoopBackControl, worklist, _bbs); + nloop->push_pred(loop_head, LoopNode::LoopBackControl, worklist, this); while (worklist.size() > 0) { Block* member = worklist.pop(); if (member != loop_head) { for (uint j = 1; j < member->num_preds(); j++) { - nloop->push_pred(member, j, worklist, _bbs); + nloop->push_pred(member, j, worklist, this); } } } @@ -1557,9 +1560,9 @@ } //------------------------------push_pred-------------------------------------- -void CFGLoop::push_pred(Block* blk, int i, Block_List& worklist, Block_Array& node_to_blk) { +void CFGLoop::push_pred(Block* blk, int i, Block_List& worklist, PhaseCFG* cfg) { Node* pred_n = blk->pred(i); - Block* pred = node_to_blk[pred_n->_idx]; + Block* pred = cfg->get_block_for_node(pred_n); CFGLoop *pred_loop = pred->_loop; if (pred_loop == NULL) { // Filter out blocks for non-single-entry loops. @@ -1580,7 +1583,7 @@ Block* pred_head = pred_loop->head(); assert(pred_head->num_preds() - 1 == 2, "loop must have 2 predecessors"); assert(pred_head != head(), "loop head in only one loop"); - push_pred(pred_head, LoopNode::EntryControl, worklist, node_to_blk); + push_pred(pred_head, LoopNode::EntryControl, worklist, cfg); } else { assert(pred_loop->_parent == this && _parent == NULL, "just checking"); }
--- a/src/share/vm/opto/idealGraphPrinter.cpp Fri Oct 11 17:14:35 2013 +0200 +++ b/src/share/vm/opto/idealGraphPrinter.cpp Fri Oct 11 17:21:14 2013 +0200 @@ -413,9 +413,9 @@ print_prop("debug_idx", node->_debug_idx); #endif - if(C->cfg() != NULL) { - Block *block = C->cfg()->_bbs[node->_idx]; - if(block == NULL) { + if (C->cfg() != NULL) { + Block* block = C->cfg()->get_block_for_node(node); + if (block == NULL) { print_prop("block", C->cfg()->_blocks[0]->_pre_order); } else { print_prop("block", block->_pre_order);
--- a/src/share/vm/opto/ifg.cpp Fri Oct 11 17:14:35 2013 +0200 +++ b/src/share/vm/opto/ifg.cpp Fri Oct 11 17:21:14 2013 +0200 @@ -565,7 +565,7 @@ lrgs(r)._def = 0; } n->disconnect_inputs(NULL, C); - _cfg._bbs.map(n->_idx,NULL); + _cfg.unmap_node_from_block(n); n->replace_by(C->top()); // Since yanking a Node from block, high pressure moves up one hrp_index[0]--; @@ -607,7 +607,7 @@ if( n->is_SpillCopy() && lrgs(r).is_singledef() // MultiDef live range can still split && n->outcnt() == 1 // and use must be in this block - && _cfg._bbs[n->unique_out()->_idx] == b ) { + && _cfg.get_block_for_node(n->unique_out()) == b ) { // All single-use MachSpillCopy(s) that immediately precede their // use must color early. If a longer live range steals their // color, the spill copy will split and may push another spill copy
--- a/src/share/vm/opto/lcm.cpp Fri Oct 11 17:14:35 2013 +0200 +++ b/src/share/vm/opto/lcm.cpp Fri Oct 11 17:21:14 2013 +0200 @@ -237,7 +237,7 @@ } // Check ctrl input to see if the null-check dominates the memory op - Block *cb = cfg->_bbs[mach->_idx]; + Block *cb = cfg->get_block_for_node(mach); cb = cb->_idom; // Always hoist at least 1 block if( !was_store ) { // Stores can be hoisted only one block while( cb->_dom_depth > (_dom_depth + 1)) @@ -262,7 +262,7 @@ if( is_decoden ) continue; } // Block of memory-op input - Block *inb = cfg->_bbs[mach->in(j)->_idx]; + Block *inb = cfg->get_block_for_node(mach->in(j)); Block *b = this; // Start from nul check while( b != inb && b->_dom_depth > inb->_dom_depth ) b = b->_idom; // search upwards for input @@ -272,7 +272,7 @@ } if( j > 0 ) continue; - Block *mb = cfg->_bbs[mach->_idx]; + Block *mb = cfg->get_block_for_node(mach); // Hoisting stores requires more checks for the anti-dependence case. // Give up hoisting if we have to move the store past any load. if( was_store ) { @@ -291,7 +291,7 @@ break; // Found anti-dependent load // Make sure control does not do a merge (would have to check allpaths) if( b->num_preds() != 2 ) break; - b = cfg->_bbs[b->pred(1)->_idx]; // Move up to predecessor block + b = cfg->get_block_for_node(b->pred(1)); // Move up to predecessor block } if( b != this ) continue; } @@ -303,15 +303,15 @@ // Found a candidate! Pick one with least dom depth - the highest // in the dom tree should be closest to the null check. - if( !best || - cfg->_bbs[mach->_idx]->_dom_depth < cfg->_bbs[best->_idx]->_dom_depth ) { + if (best == NULL || cfg->get_block_for_node(mach)->_dom_depth < cfg->get_block_for_node(best)->_dom_depth) { best = mach; bidx = vidx; - } } // No candidate! - if( !best ) return; + if (best == NULL) { + return; + } // ---- Found an implicit null check extern int implicit_null_checks; @@ -319,29 +319,29 @@ if( is_decoden ) { // Check if we need to hoist decodeHeapOop_not_null first. - Block *valb = cfg->_bbs[val->_idx]; + Block *valb = cfg->get_block_for_node(val); if( this != valb && this->_dom_depth < valb->_dom_depth ) { // Hoist it up to the end of the test block. valb->find_remove(val); this->add_inst(val); - cfg->_bbs.map(val->_idx,this); + cfg->map_node_to_block(val, this); // DecodeN on x86 may kill flags. Check for flag-killing projections // that also need to be hoisted. for (DUIterator_Fast jmax, j = val->fast_outs(jmax); j < jmax; j++) { Node* n = val->fast_out(j); if( n->is_MachProj() ) { - cfg->_bbs[n->_idx]->find_remove(n); + cfg->get_block_for_node(n)->find_remove(n); this->add_inst(n); - cfg->_bbs.map(n->_idx,this); + cfg->map_node_to_block(n, this); } } } } // Hoist the memory candidate up to the end of the test block. - Block *old_block = cfg->_bbs[best->_idx]; + Block *old_block = cfg->get_block_for_node(best); old_block->find_remove(best); add_inst(best); - cfg->_bbs.map(best->_idx,this); + cfg->map_node_to_block(best, this); // Move the control dependence if (best->in(0) && best->in(0) == old_block->_nodes[0]) @@ -352,9 +352,9 @@ for (DUIterator_Fast jmax, j = best->fast_outs(jmax); j < jmax; j++) { Node* n = best->fast_out(j); if( n->is_MachProj() ) { - cfg->_bbs[n->_idx]->find_remove(n); + cfg->get_block_for_node(n)->find_remove(n); add_inst(n); - cfg->_bbs.map(n->_idx,this); + cfg->map_node_to_block(n, this); } } @@ -385,7 +385,7 @@ Node *old_tst = proj->in(0); MachNode *nul_chk = new (C) MachNullCheckNode(old_tst->in(0),best,bidx); _nodes.map(end_idx(),nul_chk); - cfg->_bbs.map(nul_chk->_idx,this); + cfg->map_node_to_block(nul_chk, this); // Redirect users of old_test to nul_chk for (DUIterator_Last i2min, i2 = old_tst->last_outs(i2min); i2 >= i2min; --i2) old_tst->last_out(i2)->set_req(0, nul_chk); @@ -468,7 +468,7 @@ Node* use = n->fast_out(j); // The use is a conditional branch, make them adjacent - if (use->is_MachIf() && cfg->_bbs[use->_idx]==this ) { + if (use->is_MachIf() && cfg->get_block_for_node(use) == this) { found_machif = true; break; } @@ -529,13 +529,14 @@ //------------------------------set_next_call---------------------------------- -void Block::set_next_call( Node *n, VectorSet &next_call, Block_Array &bbs ) { +void Block::set_next_call( Node *n, VectorSet &next_call, PhaseCFG* cfg) { if( next_call.test_set(n->_idx) ) return; for( uint i=0; i<n->len(); i++ ) { Node *m = n->in(i); if( !m ) continue; // must see all nodes in block that precede call - if( bbs[m->_idx] == this ) - set_next_call( m, next_call, bbs ); + if (cfg->get_block_for_node(m) == this) { + set_next_call(m, next_call, cfg); + } } } @@ -545,12 +546,12 @@ // next subroutine call get priority - basically it moves things NOT needed // for the next call till after the call. This prevents me from trying to // carry lots of stuff live across a call. -void Block::needed_for_next_call(Node *this_call, VectorSet &next_call, Block_Array &bbs) { +void Block::needed_for_next_call(Node *this_call, VectorSet &next_call, PhaseCFG* cfg) { // Find the next control-defining Node in this block Node* call = NULL; for (DUIterator_Fast imax, i = this_call->fast_outs(imax); i < imax; i++) { Node* m = this_call->fast_out(i); - if( bbs[m->_idx] == this && // Local-block user + if(cfg->get_block_for_node(m) == this && // Local-block user m != this_call && // Not self-start node m->is_MachCall() ) call = m; @@ -558,7 +559,7 @@ } if (call == NULL) return; // No next call (e.g., block end is near) // Set next-call for all inputs to this call - set_next_call(call, next_call, bbs); + set_next_call(call, next_call, cfg); } //------------------------------add_call_kills------------------------------------- @@ -578,7 +579,7 @@ //------------------------------sched_call------------------------------------- -uint Block::sched_call( Matcher &matcher, Block_Array &bbs, uint node_cnt, Node_List &worklist, GrowableArray<int> &ready_cnt, MachCallNode *mcall, VectorSet &next_call ) { +uint Block::sched_call( Matcher &matcher, PhaseCFG* cfg, uint node_cnt, Node_List &worklist, GrowableArray<int> &ready_cnt, MachCallNode *mcall, VectorSet &next_call ) { RegMask regs; // Schedule all the users of the call right now. All the users are @@ -597,12 +598,14 @@ // Check for scheduling the next control-definer if( n->bottom_type() == Type::CONTROL ) // Warm up next pile of heuristic bits - needed_for_next_call(n, next_call, bbs); + needed_for_next_call(n, next_call, cfg); // Children of projections are now all ready for (DUIterator_Fast jmax, j = n->fast_outs(jmax); j < jmax; j++) { Node* m = n->fast_out(j); // Get user - if( bbs[m->_idx] != this ) continue; + if(cfg->get_block_for_node(m) != this) { + continue; + } if( m->is_Phi() ) continue; int m_cnt = ready_cnt.at(m->_idx)-1; ready_cnt.at_put(m->_idx, m_cnt); @@ -620,7 +623,7 @@ uint r_cnt = mcall->tf()->range()->cnt(); int op = mcall->ideal_Opcode(); MachProjNode *proj = new (matcher.C) MachProjNode( mcall, r_cnt+1, RegMask::Empty, MachProjNode::fat_proj ); - bbs.map(proj->_idx,this); + cfg->map_node_to_block(proj, this); _nodes.insert(node_cnt++, proj); // Select the right register save policy. @@ -708,7 +711,7 @@ uint local = 0; for( uint j=0; j<cnt; j++ ) { Node *m = n->in(j); - if( m && cfg->_bbs[m->_idx] == this && !m->is_top() ) + if( m && cfg->get_block_for_node(m) == this && !m->is_top() ) local++; // One more block-local input } ready_cnt.at_put(n->_idx, local); // Count em up @@ -720,7 +723,7 @@ for (uint prec = n->req(); prec < n->len(); prec++) { Node* oop_store = n->in(prec); if (oop_store != NULL) { - assert(cfg->_bbs[oop_store->_idx]->_dom_depth <= this->_dom_depth, "oop_store must dominate card-mark"); + assert(cfg->get_block_for_node(oop_store)->_dom_depth <= this->_dom_depth, "oop_store must dominate card-mark"); } } } @@ -753,7 +756,7 @@ Node *n = _nodes[i3]; // Get pre-scheduled for (DUIterator_Fast jmax, j = n->fast_outs(jmax); j < jmax; j++) { Node* m = n->fast_out(j); - if( cfg->_bbs[m->_idx] ==this ) { // Local-block user + if (cfg->get_block_for_node(m) == this) { // Local-block user int m_cnt = ready_cnt.at(m->_idx)-1; ready_cnt.at_put(m->_idx, m_cnt); // Fix ready count } @@ -786,7 +789,7 @@ } // Warm up the 'next_call' heuristic bits - needed_for_next_call(_nodes[0], next_call, cfg->_bbs); + needed_for_next_call(_nodes[0], next_call, cfg); #ifndef PRODUCT if (cfg->trace_opto_pipelining()) { @@ -837,7 +840,7 @@ #endif if( n->is_MachCall() ) { MachCallNode *mcall = n->as_MachCall(); - phi_cnt = sched_call(matcher, cfg->_bbs, phi_cnt, worklist, ready_cnt, mcall, next_call); + phi_cnt = sched_call(matcher, cfg, phi_cnt, worklist, ready_cnt, mcall, next_call); continue; } @@ -847,7 +850,7 @@ regs.OR(n->out_RegMask()); MachProjNode *proj = new (matcher.C) MachProjNode( n, 1, RegMask::Empty, MachProjNode::fat_proj ); - cfg->_bbs.map(proj->_idx,this); + cfg->map_node_to_block(proj, this); _nodes.insert(phi_cnt++, proj); add_call_kills(proj, regs, matcher._c_reg_save_policy, false); @@ -856,7 +859,9 @@ // Children are now all ready for (DUIterator_Fast i5max, i5 = n->fast_outs(i5max); i5 < i5max; i5++) { Node* m = n->fast_out(i5); // Get user - if( cfg->_bbs[m->_idx] != this ) continue; + if (cfg->get_block_for_node(m) != this) { + continue; + } if( m->is_Phi() ) continue; if (m->_idx >= max_idx) { // new node, skip it assert(m->is_MachProj() && n->is_Mach() && n->as_Mach()->has_call(), "unexpected node types"); @@ -914,7 +919,7 @@ } //------------------------------catch_cleanup_find_cloned_def------------------ -static Node *catch_cleanup_find_cloned_def(Block *use_blk, Node *def, Block *def_blk, Block_Array &bbs, int n_clone_idx) { +static Node *catch_cleanup_find_cloned_def(Block *use_blk, Node *def, Block *def_blk, PhaseCFG* cfg, int n_clone_idx) { assert( use_blk != def_blk, "Inter-block cleanup only"); // The use is some block below the Catch. Find and return the clone of the def @@ -940,7 +945,8 @@ // PhiNode, the PhiNode uses from the def and IT's uses need fixup. Node_Array inputs = new Node_List(Thread::current()->resource_area()); for(uint k = 1; k < use_blk->num_preds(); k++) { - inputs.map(k, catch_cleanup_find_cloned_def(bbs[use_blk->pred(k)->_idx], def, def_blk, bbs, n_clone_idx)); + Block* block = cfg->get_block_for_node(use_blk->pred(k)); + inputs.map(k, catch_cleanup_find_cloned_def(block, def, def_blk, cfg, n_clone_idx)); } // Check to see if the use_blk already has an identical phi inserted. @@ -962,7 +968,7 @@ if (fixup == NULL) { Node *new_phi = PhiNode::make(use_blk->head(), def); use_blk->_nodes.insert(1, new_phi); - bbs.map(new_phi->_idx, use_blk); + cfg->map_node_to_block(new_phi, use_blk); for (uint k = 1; k < use_blk->num_preds(); k++) { new_phi->set_req(k, inputs[k]); } @@ -1002,17 +1008,17 @@ //------------------------------catch_cleanup_inter_block--------------------- // Fix all input edges in use that reference "def". The use is in a different // block than the def. -static void catch_cleanup_inter_block(Node *use, Block *use_blk, Node *def, Block *def_blk, Block_Array &bbs, int n_clone_idx) { +static void catch_cleanup_inter_block(Node *use, Block *use_blk, Node *def, Block *def_blk, PhaseCFG* cfg, int n_clone_idx) { if( !use_blk ) return; // Can happen if the use is a precedence edge - Node *new_def = catch_cleanup_find_cloned_def(use_blk, def, def_blk, bbs, n_clone_idx); + Node *new_def = catch_cleanup_find_cloned_def(use_blk, def, def_blk, cfg, n_clone_idx); catch_cleanup_fix_all_inputs(use, def, new_def); } //------------------------------call_catch_cleanup----------------------------- // If we inserted any instructions between a Call and his CatchNode, // clone the instructions on all paths below the Catch. -void Block::call_catch_cleanup(Block_Array &bbs, Compile* C) { +void Block::call_catch_cleanup(PhaseCFG* cfg, Compile* C) { // End of region to clone uint end = end_idx(); @@ -1037,7 +1043,7 @@ // since clones dominate on each path. Node *clone = _nodes[j-1]->clone(); sb->_nodes.insert( 1, clone ); - bbs.map(clone->_idx,sb); + cfg->map_node_to_block(clone, sb); } } @@ -1054,18 +1060,19 @@ uint max = out->size(); for (uint j = 0; j < max; j++) {// For all users Node *use = out->pop(); - Block *buse = bbs[use->_idx]; + Block *buse = cfg->get_block_for_node(use); if( use->is_Phi() ) { for( uint k = 1; k < use->req(); k++ ) if( use->in(k) == n ) { - Node *fixup = catch_cleanup_find_cloned_def(bbs[buse->pred(k)->_idx], n, this, bbs, n_clone_idx); + Block* block = cfg->get_block_for_node(buse->pred(k)); + Node *fixup = catch_cleanup_find_cloned_def(block, n, this, cfg, n_clone_idx); use->set_req(k, fixup); } } else { if (this == buse) { catch_cleanup_intra_block(use, n, this, beg, n_clone_idx); } else { - catch_cleanup_inter_block(use, buse, n, this, bbs, n_clone_idx); + catch_cleanup_inter_block(use, buse, n, this, cfg, n_clone_idx); } } } // End for all users
--- a/src/share/vm/opto/live.cpp Fri Oct 11 17:14:35 2013 +0200 +++ b/src/share/vm/opto/live.cpp Fri Oct 11 17:21:14 2013 +0200 @@ -101,7 +101,7 @@ for( uint k=1; k<cnt; k++ ) { Node *nk = n->in(k); uint nkidx = nk->_idx; - if( _cfg._bbs[nkidx] != b ) { + if (_cfg.get_block_for_node(nk) != b) { uint u = _names[nkidx]; use->insert( u ); DEBUG_ONLY(def_outside->insert( u );) @@ -121,7 +121,7 @@ // Push these live-in things to predecessors for( uint l=1; l<b->num_preds(); l++ ) { - Block *p = _cfg._bbs[b->pred(l)->_idx]; + Block *p = _cfg.get_block_for_node(b->pred(l)); add_liveout( p, use, first_pass ); // PhiNode uses go in the live-out set of prior blocks. @@ -142,8 +142,10 @@ assert( delta->count(), "missing delta set" ); // Add new-live-in to predecessors live-out sets - for( uint l=1; l<b->num_preds(); l++ ) - add_liveout( _cfg._bbs[b->pred(l)->_idx], delta, first_pass ); + for (uint l = 1; l < b->num_preds(); l++) { + Block* block = _cfg.get_block_for_node(b->pred(l)); + add_liveout(block, delta, first_pass); + } freeset(b); } // End of while-worklist-not-empty
--- a/src/share/vm/opto/loopTransform.cpp Fri Oct 11 17:14:35 2013 +0200 +++ b/src/share/vm/opto/loopTransform.cpp Fri Oct 11 17:21:14 2013 +0200 @@ -624,8 +624,6 @@ } -#define MAX_UNROLL 16 // maximum number of unrolls for main loop - //------------------------------policy_unroll---------------------------------- // Return TRUE or FALSE if the loop should be unrolled or not. Unroll if // the loop is a CountedLoop and the body is small enough. @@ -642,7 +640,7 @@ if (cl->trip_count() <= (uint)(cl->is_normal_loop() ? 2 : 1)) return false; int future_unroll_ct = cl->unrolled_count() * 2; - if (future_unroll_ct > MAX_UNROLL) return false; + if (future_unroll_ct > LoopMaxUnroll) return false; // Check for initial stride being a small enough constant if (abs(cl->stride_con()) > (1<<2)*future_unroll_ct) return false;
--- a/src/share/vm/opto/node.hpp Fri Oct 11 17:14:35 2013 +0200 +++ b/src/share/vm/opto/node.hpp Fri Oct 11 17:21:14 2013 +0200 @@ -42,7 +42,6 @@ class AllocateArrayNode; class AllocateNode; class Block; -class Block_Array; class BoolNode; class BoxLockNode; class CMoveNode;
--- a/src/share/vm/opto/output.cpp Fri Oct 11 17:14:35 2013 +0200 +++ b/src/share/vm/opto/output.cpp Fri Oct 11 17:21:14 2013 +0200 @@ -68,7 +68,6 @@ return; } // Make sure I can find the Start Node - Block_Array& bbs = _cfg->_bbs; Block *entry = _cfg->_blocks[1]; Block *broot = _cfg->_broot; @@ -77,8 +76,8 @@ // Replace StartNode with prolog MachPrologNode *prolog = new (this) MachPrologNode(); entry->_nodes.map( 0, prolog ); - bbs.map( prolog->_idx, entry ); - bbs.map( start->_idx, NULL ); // start is no longer in any block + _cfg->map_node_to_block(prolog, entry); + _cfg->unmap_node_from_block(start); // start is no longer in any block // Virtual methods need an unverified entry point @@ -117,8 +116,7 @@ if( m->is_Mach() && m->as_Mach()->ideal_Opcode() != Op_Halt ) { MachEpilogNode *epilog = new (this) MachEpilogNode(m->as_Mach()->ideal_Opcode() == Op_Return); b->add_inst( epilog ); - bbs.map(epilog->_idx, b); - //_regalloc->set_bad(epilog->_idx); // Already initialized this way. + _cfg->map_node_to_block(epilog, b); } } } @@ -252,7 +250,7 @@ if (insert) { Node *zap = call_zap_node(n->as_MachSafePoint(), i); b->_nodes.insert( j, zap ); - _cfg->_bbs.map( zap->_idx, b ); + _cfg->map_node_to_block(zap, b); ++j; } } @@ -1237,7 +1235,7 @@ #ifdef ASSERT if (!b->is_connector()) { stringStream st; - b->dump_head(&_cfg->_bbs, &st); + b->dump_head(_cfg, &st); MacroAssembler(cb).block_comment(st.as_string()); } jmp_target[i] = 0; @@ -1313,7 +1311,7 @@ MachNode *nop = new (this) MachNopNode(nops_cnt); b->_nodes.insert(j++, nop); last_inst++; - _cfg->_bbs.map( nop->_idx, b ); + _cfg->map_node_to_block(nop, b); nop->emit(*cb, _regalloc); cb->flush_bundle(true); current_offset = cb->insts_size(); @@ -1398,7 +1396,7 @@ if (needs_padding && replacement->avoid_back_to_back()) { MachNode *nop = new (this) MachNopNode(); b->_nodes.insert(j++, nop); - _cfg->_bbs.map(nop->_idx, b); + _cfg->map_node_to_block(nop, b); last_inst++; nop->emit(*cb, _regalloc); cb->flush_bundle(true); @@ -1552,7 +1550,7 @@ if( padding > 0 ) { MachNode *nop = new (this) MachNopNode(padding / nop_size); b->_nodes.insert( b->_nodes.size(), nop ); - _cfg->_bbs.map( nop->_idx, b ); + _cfg->map_node_to_block(nop, b); nop->emit(*cb, _regalloc); current_offset = cb->insts_size(); } @@ -1740,7 +1738,6 @@ Scheduling::Scheduling(Arena *arena, Compile &compile) : _arena(arena), _cfg(compile.cfg()), - _bbs(compile.cfg()->_bbs), _regalloc(compile.regalloc()), _reg_node(arena), _bundle_instr_count(0), @@ -2088,8 +2085,9 @@ if( def->is_Proj() ) // If this is a machine projection, then def = def->in(0); // propagate usage thru to the base instruction - if( _bbs[def->_idx] != bb ) // Ignore if not block-local + if(_cfg->get_block_for_node(def) != bb) { // Ignore if not block-local continue; + } // Compute the latency uint l = _bundle_cycle_number + n->latency(i); @@ -2361,9 +2359,10 @@ Node *inp = n->in(k); if (!inp) continue; assert(inp != n, "no cycles allowed" ); - if( _bbs[inp->_idx] == bb ) { // Block-local use? - if( inp->is_Proj() ) // Skip through Proj's + if (_cfg->get_block_for_node(inp) == bb) { // Block-local use? + if (inp->is_Proj()) { // Skip through Proj's inp = inp->in(0); + } ++_uses[inp->_idx]; // Count 1 block-local use } } @@ -2646,7 +2645,7 @@ return; Node *pinch = _reg_node[def_reg]; // Get pinch point - if( !pinch || _bbs[pinch->_idx] != b || // No pinch-point yet? + if ((pinch == NULL) || _cfg->get_block_for_node(pinch) != b || // No pinch-point yet? is_def ) { // Check for a true def (not a kill) _reg_node.map(def_reg,def); // Record def/kill as the optimistic pinch-point return; @@ -2672,7 +2671,7 @@ _cfg->C->record_method_not_compilable("too many D-U pinch points"); return; } - _bbs.map(pinch->_idx,b); // Pretend it's valid in this block (lazy init) + _cfg->map_node_to_block(pinch, b); // Pretend it's valid in this block (lazy init) _reg_node.map(def_reg,pinch); // Record pinch-point //_regalloc->set_bad(pinch->_idx); // Already initialized this way. if( later_def->outcnt() == 0 || later_def->ideal_reg() == MachProjNode::fat_proj ) { // Distinguish def from kill @@ -2716,9 +2715,9 @@ return; Node *pinch = _reg_node[use_reg]; // Get pinch point // Check for no later def_reg/kill in block - if( pinch && _bbs[pinch->_idx] == b && + if ((pinch != NULL) && _cfg->get_block_for_node(pinch) == b && // Use has to be block-local as well - _bbs[use->_idx] == b ) { + _cfg->get_block_for_node(use) == b) { if( pinch->Opcode() == Op_Node && // Real pinch-point (not optimistic?) pinch->req() == 1 ) { // pinch not yet in block? pinch->del_req(0); // yank pointer to later-def, also set flag @@ -2898,7 +2897,7 @@ int trace_cnt = 0; for (uint k = 0; k < _reg_node.Size(); k++) { Node* pinch = _reg_node[k]; - if (pinch != NULL && pinch->Opcode() == Op_Node && + if ((pinch != NULL) && pinch->Opcode() == Op_Node && // no predecence input edges (pinch->req() == pinch->len() || pinch->in(pinch->req()) == NULL) ) { cleanup_pinch(pinch);
--- a/src/share/vm/opto/output.hpp Fri Oct 11 17:14:35 2013 +0200 +++ b/src/share/vm/opto/output.hpp Fri Oct 11 17:21:14 2013 +0200 @@ -96,9 +96,6 @@ // List of nodes currently available for choosing for scheduling Node_List _available; - // Mapping from node (index) to basic block - Block_Array& _bbs; - // For each instruction beginning a bundle, the number of following // nodes to be bundled with it. Bundle *_node_bundling_base;
--- a/src/share/vm/opto/postaloc.cpp Fri Oct 11 17:14:35 2013 +0200 +++ b/src/share/vm/opto/postaloc.cpp Fri Oct 11 17:21:14 2013 +0200 @@ -78,11 +78,13 @@ // Helper function for yank_if_dead int PhaseChaitin::yank( Node *old, Block *current_block, Node_List *value, Node_List *regnd ) { int blk_adjust=0; - Block *oldb = _cfg._bbs[old->_idx]; + Block *oldb = _cfg.get_block_for_node(old); oldb->find_remove(old); // Count 1 if deleting an instruction from the current block - if( oldb == current_block ) blk_adjust++; - _cfg._bbs.map(old->_idx,NULL); + if (oldb == current_block) { + blk_adjust++; + } + _cfg.unmap_node_from_block(old); OptoReg::Name old_reg = lrgs(_lrg_map.live_range_id(old)).reg(); if( regnd && (*regnd)[old_reg]==old ) { // Instruction is currently available? value->map(old_reg,NULL); // Yank from value/regnd maps @@ -433,7 +435,7 @@ bool missing_some_inputs = false; Block *freed = NULL; for( j = 1; j < b->num_preds(); j++ ) { - Block *pb = _cfg._bbs[b->pred(j)->_idx]; + Block *pb = _cfg.get_block_for_node(b->pred(j)); // Remove copies along phi edges for( uint k=1; k<phi_dex; k++ ) elide_copy( b->_nodes[k], j, b, *blk2value[pb->_pre_order], *blk2regnd[pb->_pre_order], false ); @@ -478,7 +480,7 @@ } else { if( !freed ) { // Didn't get a freebie prior block // Must clone some data - freed = _cfg._bbs[b->pred(1)->_idx]; + freed = _cfg.get_block_for_node(b->pred(1)); Node_List &f_value = *blk2value[freed->_pre_order]; Node_List &f_regnd = *blk2regnd[freed->_pre_order]; for( uint k = 0; k < (uint)_max_reg; k++ ) { @@ -488,7 +490,7 @@ } // Merge all inputs together, setting to NULL any conflicts. for( j = 1; j < b->num_preds(); j++ ) { - Block *pb = _cfg._bbs[b->pred(j)->_idx]; + Block *pb = _cfg.get_block_for_node(b->pred(j)); if( pb == freed ) continue; // Did self already via freelist Node_List &p_regnd = *blk2regnd[pb->_pre_order]; for( uint k = 0; k < (uint)_max_reg; k++ ) { @@ -515,8 +517,9 @@ u = u ? NodeSentinel : x; // Capture unique input, or NodeSentinel for 2nd input } if( u != NodeSentinel ) { // Junk Phi. Remove - b->_nodes.remove(j--); phi_dex--; - _cfg._bbs.map(phi->_idx,NULL); + b->_nodes.remove(j--); + phi_dex--; + _cfg.unmap_node_from_block(phi); phi->replace_by(u); phi->disconnect_inputs(NULL, C); continue;
--- a/src/share/vm/opto/reg_split.cpp Fri Oct 11 17:14:35 2013 +0200 +++ b/src/share/vm/opto/reg_split.cpp Fri Oct 11 17:21:14 2013 +0200 @@ -132,7 +132,7 @@ } b->_nodes.insert(i,spill); // Insert node in block - _cfg._bbs.map(spill->_idx,b); // Update node->block mapping to reflect + _cfg.map_node_to_block(spill, b); // Update node->block mapping to reflect // Adjust the point where we go hi-pressure if( i <= b->_ihrp_index ) b->_ihrp_index++; if( i <= b->_fhrp_index ) b->_fhrp_index++; @@ -219,7 +219,7 @@ use->set_req(useidx, def); } else { // Block and index where the use occurs. - Block *b = _cfg._bbs[use->_idx]; + Block *b = _cfg.get_block_for_node(use); // Put the clone just prior to use int bindex = b->find_node(use); // DEF is UP, so must copy it DOWN and hook in USE @@ -270,7 +270,7 @@ int bindex; // Phi input spill-copys belong at the end of the prior block if( use->is_Phi() ) { - b = _cfg._bbs[b->pred(useidx)->_idx]; + b = _cfg.get_block_for_node(b->pred(useidx)); bindex = b->end_idx(); } else { // Put the clone just prior to use @@ -335,7 +335,7 @@ continue; } - Block *b_def = _cfg._bbs[def->_idx]; + Block *b_def = _cfg.get_block_for_node(def); int idx_def = b_def->find_node(def); Node *in_spill = get_spillcopy_wide( in, def, i ); if( !in_spill ) return 0; // Bailed out @@ -589,7 +589,7 @@ UPblock[slidx] = true; // Record following instruction in case 'n' rematerializes and // kills flags - Block *pred1 = _cfg._bbs[b->pred(1)->_idx]; + Block *pred1 = _cfg.get_block_for_node(b->pred(1)); continue; } @@ -601,7 +601,7 @@ // Grab predecessor block header n1 = b->pred(1); // Grab the appropriate reaching def info for inpidx - pred = _cfg._bbs[n1->_idx]; + pred = _cfg.get_block_for_node(n1); pidx = pred->_pre_order; Node **Ltmp = Reaches[pidx]; bool *Utmp = UP[pidx]; @@ -616,7 +616,7 @@ // Grab predecessor block headers n2 = b->pred(inpidx); // Grab the appropriate reaching def info for inpidx - pred = _cfg._bbs[n2->_idx]; + pred = _cfg.get_block_for_node(n2); pidx = pred->_pre_order; Ltmp = Reaches[pidx]; Utmp = UP[pidx]; @@ -701,7 +701,7 @@ // Grab predecessor block header n1 = b->pred(1); // Grab the appropriate reaching def info for k - pred = _cfg._bbs[n1->_idx]; + pred = _cfg.get_block_for_node(n1); pidx = pred->_pre_order; Node **Ltmp = Reaches[pidx]; bool *Utmp = UP[pidx]; @@ -919,7 +919,7 @@ return 0; } _lrg_map.extend(def->_idx, 0); - _cfg._bbs.map(def->_idx,b); + _cfg.map_node_to_block(def, b); n->set_req(inpidx, def); continue; } @@ -1291,7 +1291,7 @@ for( insidx = 0; insidx < phis->size(); insidx++ ) { Node *phi = phis->at(insidx); assert(phi->is_Phi(),"This list must only contain Phi Nodes"); - Block *b = _cfg._bbs[phi->_idx]; + Block *b = _cfg.get_block_for_node(phi); // Grab the live range number uint lidx = _lrg_map.find_id(phi); uint slidx = lrg2reach[lidx]; @@ -1315,7 +1315,7 @@ // DEF has the wrong UP/DOWN value. for( uint i = 1; i < b->num_preds(); i++ ) { // Get predecessor block pre-order number - Block *pred = _cfg._bbs[b->pred(i)->_idx]; + Block *pred = _cfg.get_block_for_node(b->pred(i)); pidx = pred->_pre_order; // Grab reaching def Node *def = Reaches[pidx][slidx];
--- a/src/share/vm/prims/jvmtiRedefineClasses.cpp Fri Oct 11 17:14:35 2013 +0200 +++ b/src/share/vm/prims/jvmtiRedefineClasses.cpp Fri Oct 11 17:21:14 2013 +0200 @@ -3217,15 +3217,6 @@ JvmtiBreakpoints& jvmti_breakpoints = JvmtiCurrentBreakpoints::get_jvmti_breakpoints(); jvmti_breakpoints.clearall_in_class_at_safepoint(the_class_oop); - if (the_class_oop == Universe::reflect_invoke_cache()->klass()) { - // We are redefining java.lang.reflect.Method. Method.invoke() is - // cached and users of the cache care about each active version of - // the method so we have to track this previous version. - // Do this before methods get switched - Universe::reflect_invoke_cache()->add_previous_version( - the_class->method_with_idnum(Universe::reflect_invoke_cache()->method_idnum())); - } - // Deoptimize all compiled code that depends on this class flush_dependent_code(the_class, THREAD);
--- a/src/share/vm/runtime/arguments.cpp Fri Oct 11 17:14:35 2013 +0200 +++ b/src/share/vm/runtime/arguments.cpp Fri Oct 11 17:21:14 2013 +0200 @@ -60,6 +60,28 @@ #define DEFAULT_VENDOR_URL_BUG "http://bugreport.sun.com/bugreport/crash.jsp" #define DEFAULT_JAVA_LAUNCHER "generic" +// Disable options not supported in this release, with a warning if they +// were explicitly requested on the command-line +#define UNSUPPORTED_OPTION(opt, description) \ +do { \ + if (opt) { \ + if (FLAG_IS_CMDLINE(opt)) { \ + warning(description " is disabled in this release."); \ + } \ + FLAG_SET_DEFAULT(opt, false); \ + } \ +} while(0) + +#define UNSUPPORTED_GC_OPTION(gc) \ +do { \ + if (gc) { \ + if (FLAG_IS_CMDLINE(gc)) { \ + warning(#gc " is not supported in this VM. Using Serial GC."); \ + } \ + FLAG_SET_DEFAULT(gc, false); \ + } \ +} while(0) + char** Arguments::_jvm_flags_array = NULL; int Arguments::_num_jvm_flags = 0; char** Arguments::_jvm_args_array = NULL; @@ -1900,6 +1922,10 @@ warning("Using MaxGCMinorPauseMillis as minor pause goal is deprecated" "and will likely be removed in future release"); } + if (FLAG_IS_CMDLINE(DefaultMaxRAMFraction)) { + warning("DefaultMaxRAMFraction is deprecated and will likely be removed in a future release. " + "Use MaxRAMFraction instead."); + } } // Check stack pages settings @@ -3162,14 +3188,17 @@ FLAG_SET_DEFAULT(UseLargePages, false); } - // Tiered compilation is undefined with C1. - TieredCompilation = false; #else if (!FLAG_IS_DEFAULT(OptoLoopAlignment) && FLAG_IS_DEFAULT(MaxLoopPad)) { FLAG_SET_DEFAULT(MaxLoopPad, OptoLoopAlignment-1); } #endif +#ifndef TIERED + // Tiered compilation is undefined. + UNSUPPORTED_OPTION(TieredCompilation, "TieredCompilation"); +#endif + // If we are running in a headless jre, force java.awt.headless property // to be true unless the property has already been set. // Also allow the OS environment variable JAVA_AWT_HEADLESS to set headless state. @@ -3312,29 +3341,6 @@ } } -// Disable options not supported in this release, with a warning if they -// were explicitly requested on the command-line -#define UNSUPPORTED_OPTION(opt, description) \ -do { \ - if (opt) { \ - if (FLAG_IS_CMDLINE(opt)) { \ - warning(description " is disabled in this release."); \ - } \ - FLAG_SET_DEFAULT(opt, false); \ - } \ -} while(0) - - -#define UNSUPPORTED_GC_OPTION(gc) \ -do { \ - if (gc) { \ - if (FLAG_IS_CMDLINE(gc)) { \ - warning(#gc " is not supported in this VM. Using Serial GC."); \ - } \ - FLAG_SET_DEFAULT(gc, false); \ - } \ -} while(0) - #if !INCLUDE_ALL_GCS static void force_serial_gc() { FLAG_SET_DEFAULT(UseSerialGC, true);
--- a/src/share/vm/runtime/globals.hpp Fri Oct 11 17:14:35 2013 +0200 +++ b/src/share/vm/runtime/globals.hpp Fri Oct 11 17:21:14 2013 +0200 @@ -1706,6 +1706,9 @@ product(bool, CMSAbortSemantics, false, \ "Whether abort-on-overflow semantics is implemented") \ \ + product(bool, CMSParallelInitialMarkEnabled, true, \ + "Use the parallel initial mark.") \ + \ product(bool, CMSParallelRemarkEnabled, true, \ "Whether parallel remark enabled (only if ParNewGC)") \ \ @@ -1717,6 +1720,14 @@ "Whether to always record survivor space PLAB bdries" \ " (effective only if CMSParallelSurvivorRemarkEnabled)") \ \ + product(bool, CMSEdenChunksRecordAlways, true, \ + "Whether to always record eden chunks used for " \ + "the parallel initial mark or remark of eden" ) \ + \ + product(bool, CMSPrintEdenSurvivorChunks, false, \ + "Print the eden and the survivor chunks used for the parallel " \ + "initial mark or remark of the eden/survivor spaces") \ + \ product(bool, CMSConcurrentMTEnabled, true, \ "Whether multi-threaded concurrent work enabled (if ParNewGC)") \ \
--- a/src/share/vm/runtime/gpu.cpp Fri Oct 11 17:14:35 2013 +0200 +++ b/src/share/vm/runtime/gpu.cpp Fri Oct 11 17:21:14 2013 +0200 @@ -61,12 +61,33 @@ } bool gpu::execute_kernel(address kernel, PTXKernelArguments & ptxka, JavaValue& ret) { - if (gpu::has_gpu_linkage()) { - if (gpu::get_target_il_type() == gpu::PTX) { - return (gpu::Ptx::execute_kernel(kernel, ptxka, ret)); + if (gpu::has_gpu_linkage()) { + if (gpu::get_target_il_type() == gpu::PTX) { + return (gpu::Ptx::execute_kernel(kernel, ptxka, ret)); + } + // Add kernel execution functionality of other GPUs here } - // Add kernel execution functionality of other GPUs here - } - return false; + return false; } +bool gpu::execute_warp(int dimX, int dimY, int dimZ, + address kernel, PTXKernelArguments & ptxka, JavaValue& ret) { + if (gpu::has_gpu_linkage()) { + if (gpu::get_target_il_type() == gpu::PTX) { + return (gpu::Ptx::execute_warp(dimX, dimY, dimZ, kernel, ptxka, ret)); + } + // Add kernel execution functionality of other GPUs here + } + return false; +} + +int gpu::available_processors() { + if (gpu::has_gpu_linkage()) { + if (gpu::get_target_il_type() == gpu::PTX) { + return (gpu::Ptx::total_cores()); + } + // Add kernel execution functionality of other GPUs here + } + return 0; +} +
--- a/src/share/vm/runtime/gpu.hpp Fri Oct 11 17:14:35 2013 +0200 +++ b/src/share/vm/runtime/gpu.hpp Fri Oct 11 17:21:14 2013 +0200 @@ -43,9 +43,14 @@ static void probe_gpu(); static void initialize_gpu(); + + static int available_processors(); static void * generate_kernel(unsigned char *code, int code_len, const char *name); + static bool execute_warp(int dimX, int dimY, int dimZ, + address kernel, PTXKernelArguments & ptxka, JavaValue & ret); + static bool execute_kernel(address kernel, PTXKernelArguments & ptxka, JavaValue & ret); static void set_available(bool value) {
--- a/src/share/vm/runtime/thread.cpp Fri Oct 11 17:14:35 2013 +0200 +++ b/src/share/vm/runtime/thread.cpp Fri Oct 11 17:21:14 2013 +0200 @@ -1411,6 +1411,36 @@ // ======= JavaThread ======== +#ifdef GRAAL + +#if GRAAL_COUNTERS_SIZE > 0 +jlong JavaThread::_graal_old_thread_counters[GRAAL_COUNTERS_SIZE]; + +bool graal_counters_include(oop threadObj) { + return !GRAAL_COUNTERS_EXCLUDE_COMPILER_THREADS || threadObj == NULL || threadObj->klass() != SystemDictionary::CompilerThread_klass(); +} + +void JavaThread::collect_counters(typeArrayOop array) { + MutexLocker tl(Threads_lock); + for (int i = 0; i < array->length(); i++) { + array->long_at_put(i, _graal_old_thread_counters[i]); + } + for (JavaThread* tp = Threads::first(); tp != NULL; tp = tp->next()) { + if (graal_counters_include(tp->threadObj())) { + for (int i = 0; i < array->length(); i++) { + array->long_at_put(i, array->long_at(i) + tp->_graal_counters[i]); + } + } + } +} +#else +void JavaThread::collect_counters(typeArrayOop array) { + // empty +} +#endif // GRAAL_COUNTERS_SIZE > 0 + +#endif // GRAAL + // A JavaThread is a normal Java thread void JavaThread::initialize() { @@ -1449,7 +1479,12 @@ _stack_guard_state = stack_guard_unused; #ifdef GRAAL _graal_alternate_call_target = NULL; -#endif +#if GRAAL_COUNTERS_SIZE > 0 + for (int i = 0; i < GRAAL_COUNTERS_SIZE; i++) { + _graal_counters[i] = 0; + } +#endif // GRAAL_COUNTER_SIZE > 0 +#endif // GRAAL _exception_oop = NULL; _exception_pc = 0; _exception_handler_pc = 0; @@ -1638,6 +1673,14 @@ ThreadSafepointState::destroy(this); if (_thread_profiler != NULL) delete _thread_profiler; if (_thread_stat != NULL) delete _thread_stat; + +#if defined(GRAAL) && (GRAAL_COUNTERS_SIZE > 0) + if (graal_counters_include(threadObj())) { + for (int i = 0; i < GRAAL_COUNTERS_SIZE; i++) { + _graal_old_thread_counters[i] += _graal_counters[i]; + } + } +#endif }
--- a/src/share/vm/runtime/thread.hpp Fri Oct 11 17:14:35 2013 +0200 +++ b/src/share/vm/runtime/thread.hpp Fri Oct 11 17:21:14 2013 +0200 @@ -919,7 +919,20 @@ #ifdef GRAAL address _graal_alternate_call_target; address _graal_implicit_exception_pc; // pc at which the most recent implicit exception occurred -#endif + + // number of counters, increase as needed. 0 == disabled +#define GRAAL_COUNTERS_SIZE (0) +#define GRAAL_COUNTERS_EXCLUDE_COMPILER_THREADS (true) + +#if GRAAL_COUNTERS_SIZE > 0 + jlong _graal_counters[GRAAL_COUNTERS_SIZE]; + static jlong _graal_old_thread_counters[GRAAL_COUNTERS_SIZE]; +#endif // GRAAL_COUNTERS_SIZE > 0 + + public: + static void collect_counters(typeArrayOop array); + private: +#endif // GRAAL StackGuardState _stack_guard_state; nmethod* _scanned_nmethod; // nmethod being scanned by the sweeper @@ -1379,7 +1392,12 @@ #ifdef GRAAL static ByteSize graal_alternate_call_target_offset() { return byte_offset_of(JavaThread, _graal_alternate_call_target); } static ByteSize graal_implicit_exception_pc_offset() { return byte_offset_of(JavaThread, _graal_implicit_exception_pc); } -#endif +#if GRAAL_COUNTERS_SIZE > 0 + static ByteSize graal_counters_offset() { return byte_offset_of(JavaThread, _graal_counters ); } +#else + static ByteSize graal_counters_offset() { return in_ByteSize(0); } +#endif // GRAAL_COUNTERS_SIZE > 0 +#endif // GRAAL static ByteSize exception_oop_offset() { return byte_offset_of(JavaThread, _exception_oop ); } static ByteSize exception_pc_offset() { return byte_offset_of(JavaThread, _exception_pc ); } static ByteSize exception_handler_pc_offset() { return byte_offset_of(JavaThread, _exception_handler_pc); }
--- a/src/share/vm/runtime/vmStructs.cpp Fri Oct 11 17:14:35 2013 +0200 +++ b/src/share/vm/runtime/vmStructs.cpp Fri Oct 11 17:21:14 2013 +0200 @@ -1098,7 +1098,7 @@ \ c2_nonstatic_field(PhaseCFG, _num_blocks, uint) \ c2_nonstatic_field(PhaseCFG, _blocks, Block_List) \ - c2_nonstatic_field(PhaseCFG, _bbs, Block_Array) \ + c2_nonstatic_field(PhaseCFG, _node_to_block_mapping, Block_Array) \ c2_nonstatic_field(PhaseCFG, _broot, Block*) \ \ c2_nonstatic_field(PhaseRegAlloc, _node_regs, OptoRegPair*) \
--- a/src/share/vm/services/gcNotifier.cpp Fri Oct 11 17:14:35 2013 +0200 +++ b/src/share/vm/services/gcNotifier.cpp Fri Oct 11 17:21:14 2013 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -211,9 +211,9 @@ NotificationMark nm(request); Handle objGcInfo = createGcInfo(request->gcManager, request->gcStatInfo, THREAD); - Handle objName = java_lang_String::create_from_platform_dependent_str(request->gcManager->name(), CHECK); - Handle objAction = java_lang_String::create_from_platform_dependent_str(request->gcAction, CHECK); - Handle objCause = java_lang_String::create_from_platform_dependent_str(request->gcCause, CHECK); + Handle objName = java_lang_String::create_from_str(request->gcManager->name(), CHECK); + Handle objAction = java_lang_String::create_from_str(request->gcAction, CHECK); + Handle objCause = java_lang_String::create_from_str(request->gcCause, CHECK); Klass* k = Management::sun_management_GarbageCollectorImpl_klass(CHECK); instanceKlassHandle gc_mbean_klass(THREAD, k);
--- a/src/share/vm/services/management.cpp Fri Oct 11 17:14:35 2013 +0200 +++ b/src/share/vm/services/management.cpp Fri Oct 11 17:21:14 2013 +0200 @@ -1831,13 +1831,13 @@ private: objArrayHandle _names_strings; char **_names_chars; - typeArrayOop _times; + typeArrayHandle _times; int _names_len; int _times_len; int _count; public: - ThreadTimesClosure(objArrayHandle names, typeArrayOop times); + ThreadTimesClosure(objArrayHandle names, typeArrayHandle times); ~ThreadTimesClosure(); virtual void do_thread(Thread* thread); void do_unlocked(); @@ -1845,9 +1845,9 @@ }; ThreadTimesClosure::ThreadTimesClosure(objArrayHandle names, - typeArrayOop times) { + typeArrayHandle times) { assert(names() != NULL, "names was NULL"); - assert(times != NULL, "times was NULL"); + assert(times() != NULL, "times was NULL"); _names_strings = names; _names_len = names->length(); _names_chars = NEW_C_HEAP_ARRAY(char*, _names_len, mtInternal); @@ -1925,7 +1925,7 @@ typeArrayOop ta = typeArrayOop(JNIHandles::resolve_non_null(times)); typeArrayHandle times_ah(THREAD, ta); - ThreadTimesClosure ttc(names_ah, times_ah()); + ThreadTimesClosure ttc(names_ah, times_ah); { MutexLockerEx ml(Threads_lock); Threads::threads_do(&ttc);
--- a/src/share/vm/utilities/debug.hpp Fri Oct 11 17:14:35 2013 +0200 +++ b/src/share/vm/utilities/debug.hpp Fri Oct 11 17:21:14 2013 +0200 @@ -225,6 +225,22 @@ void warning(const char* format, ...); +#ifdef ASSERT +// Compile-time asserts. +template <bool> struct StaticAssert; +template <> struct StaticAssert<true> {}; + +// Only StaticAssert<true> is defined, so if cond evaluates to false we get +// a compile time exception when trying to use StaticAssert<false>. +#define STATIC_ASSERT(cond) \ + do { \ + StaticAssert<(cond)> DUMMY_STATIC_ASSERT; \ + (void)DUMMY_STATIC_ASSERT; /* ignore */ \ + } while (false) +#else +#define STATIC_ASSERT(cond) +#endif + // out of shared space reporting enum SharedSpaceType { SharedPermGen,
--- a/src/share/vm/utilities/exceptions.cpp Fri Oct 11 17:14:35 2013 +0200 +++ b/src/share/vm/utilities/exceptions.cpp Fri Oct 11 17:21:14 2013 +0200 @@ -125,13 +125,13 @@ } void Exceptions::_throw(Thread* thread, const char* file, int line, Handle h_exception, const char* message) { + ResourceMark rm; assert(h_exception() != NULL, "exception should not be NULL"); // tracing (do this up front - so it works during boot strapping) if (TraceExceptions) { ttyLocker ttyl; - ResourceMark rm; - tty->print_cr("Exception <%s>%s%s (" INTPTR_FORMAT " ) \n" + tty->print_cr("Exception <%s%s%s> (" INTPTR_FORMAT ") \n" "thrown [%s, line %d]\nfor thread " INTPTR_FORMAT, h_exception->print_value_string(), message ? ": " : "", message ? message : "", @@ -141,7 +141,9 @@ NOT_PRODUCT(Exceptions::debug_check_abort(h_exception, message)); // Check for special boot-strapping/vm-thread handling - if (special_exception(thread, file, line, h_exception)) return; + if (special_exception(thread, file, line, h_exception)) { + return; + } assert(h_exception->is_a(SystemDictionary::Throwable_klass()), "exception is not a subclass of java/lang/Throwable"); @@ -149,7 +151,9 @@ thread->set_pending_exception(h_exception(), file, line); // vm log - Events::log_exception(thread, "Threw " INTPTR_FORMAT " at %s:%d", (address)h_exception(), file, line); + Events::log_exception(thread, "Exception <%s%s%s> (" INTPTR_FORMAT ") thrown at [%s, line %d]", + h_exception->print_value_string(), message ? ": " : "", message ? message : "", + (address)h_exception(), file, line); }
--- a/src/share/vm/utilities/exceptions.hpp Fri Oct 11 17:14:35 2013 +0200 +++ b/src/share/vm/utilities/exceptions.hpp Fri Oct 11 17:21:14 2013 +0200 @@ -315,6 +315,6 @@ // which preserves pre-existing exceptions and does not allow new // exceptions. -#define EXCEPTION_MARK Thread* THREAD; ExceptionMark __em(THREAD); +#define EXCEPTION_MARK Thread* THREAD = NULL; ExceptionMark __em(THREAD); #endif // SHARE_VM_UTILITIES_EXCEPTIONS_HPP
--- a/src/share/vm/utilities/globalDefinitions.hpp Fri Oct 11 17:14:35 2013 +0200 +++ b/src/share/vm/utilities/globalDefinitions.hpp Fri Oct 11 17:21:14 2013 +0200 @@ -410,6 +410,8 @@ return align_size_down_(size, alignment); } +#define is_size_aligned_(size, alignment) ((size) == (align_size_up_(size, alignment))) + // Align objects by rounding up their size, in HeapWord units. #define align_object_size_(size) align_size_up_(size, MinObjAlignment) @@ -428,6 +430,10 @@ return align_size_up(offset, HeapWordsPerLong); } +inline void* align_pointer_up(const void* addr, size_t size) { + return (void*) align_size_up_((uintptr_t)addr, size); +} + // Clamp an address to be within a specific page // 1. If addr is on the page it is returned as is // 2. If addr is above the page_address the start of the *next* page will be returned @@ -449,32 +455,6 @@ // The expected size in bytes of a cache line, used to pad data structures. #define DEFAULT_CACHE_LINE_SIZE 64 -// Bytes needed to pad type to avoid cache-line sharing; alignment should be the -// expected cache line size (a power of two). The first addend avoids sharing -// when the start address is not a multiple of alignment; the second maintains -// alignment of starting addresses that happen to be a multiple. -#define PADDING_SIZE(type, alignment) \ - ((alignment) + align_size_up_(sizeof(type), alignment)) - -// Templates to create a subclass padded to avoid cache line sharing. These are -// effective only when applied to derived-most (leaf) classes. - -// When no args are passed to the base ctor. -template <class T, size_t alignment = DEFAULT_CACHE_LINE_SIZE> -class Padded: public T { -private: - char _pad_buf_[PADDING_SIZE(T, alignment)]; -}; - -// When either 0 or 1 args may be passed to the base ctor. -template <class T, typename Arg1T, size_t alignment = DEFAULT_CACHE_LINE_SIZE> -class Padded01: public T { -public: - Padded01(): T() { } - Padded01(Arg1T arg1): T(arg1) { } -private: - char _pad_buf_[PADDING_SIZE(T, alignment)]; -}; //---------------------------------------------------------------------------------------------------- // Utility macros for compilers
--- a/src/share/vm/utilities/taskqueue.hpp Fri Oct 11 17:14:35 2013 +0200 +++ b/src/share/vm/utilities/taskqueue.hpp Fri Oct 11 17:21:14 2013 +0200 @@ -395,7 +395,13 @@ template<class E, MEMFLAGS F, unsigned int N> bool GenericTaskQueue<E, F, N>::pop_global(E& t) { Age oldAge = _age.get(); - uint localBot = _bottom; + // Architectures with weak memory model require a barrier here + // to guarantee that bottom is not older than age, + // which is crucial for the correctness of the algorithm. +#if !(defined SPARC || defined IA32 || defined AMD64) + OrderAccess::fence(); +#endif + uint localBot = OrderAccess::load_acquire((volatile juint*)&_bottom); uint n_elems = size(localBot, oldAge.top()); if (n_elems == 0) { return false; @@ -644,7 +650,7 @@ template<class E, MEMFLAGS F, unsigned int N> inline bool GenericTaskQueue<E, F, N>::push(E t) { uint localBot = _bottom; - assert((localBot >= 0) && (localBot < N), "_bottom out of range."); + assert(localBot < N, "_bottom out of range."); idx_t top = _age.top(); uint dirty_n_elems = dirty_size(localBot, top); assert(dirty_n_elems < N, "n_elems out of range.");
--- a/test/compiler/codecache/CheckUpperLimit.java Fri Oct 11 17:14:35 2013 +0200 +++ b/test/compiler/codecache/CheckUpperLimit.java Fri Oct 11 17:21:14 2013 +0200 @@ -35,10 +35,6 @@ ProcessBuilder pb; OutputAnalyzer out; - pb = ProcessTools.createJavaProcessBuilder("-XX:ReservedCodeCacheSize=2048m", "-version"); - out = new OutputAnalyzer(pb.start()); - out.shouldHaveExitValue(0); - pb = ProcessTools.createJavaProcessBuilder("-XX:ReservedCodeCacheSize=2049m", "-version"); out = new OutputAnalyzer(pb.start()); out.shouldContain("Invalid ReservedCodeCacheSize=");
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/compiler/unsafe/GetUnsafeObjectG1PreBarrier.java Fri Oct 11 17:21:14 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. + */ + +/* + * @test + * @bug 8016474 + * @summary The bug only happens with C1 and G1 using a different ObjectAlignmentInBytes than KlassAlignmentInBytes (which is 8) + * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:ObjectAlignmentInBytes=32 GetUnsafeObjectG1PreBarrier + */ + +import java.lang.reflect.Field; + +import sun.misc.Unsafe; + +public class GetUnsafeObjectG1PreBarrier { + private static final Unsafe unsafe; + private static final int N = 100_000; + + static { + try { + Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe"); + theUnsafe.setAccessible(true); + unsafe = (Unsafe) theUnsafe.get(null); + } catch (NoSuchFieldException | IllegalAccessException e) { + throw new IllegalStateException(e); + } + } + + public Object a; + + public static void main(String[] args) throws Throwable { + new GetUnsafeObjectG1PreBarrier(); + } + + public GetUnsafeObjectG1PreBarrier() throws Throwable { + doit(); + } + + private void doit() throws Throwable { + Field field = GetUnsafeObjectG1PreBarrier.class.getField("a"); + long fieldOffset = unsafe.objectFieldOffset(field); + + for (int i = 0; i < N; i++) { + readField(this, fieldOffset); + } + } + + private void readField(Object o, long fieldOffset) { + unsafe.getObject(o, fieldOffset); + } +}
--- a/test/compiler/whitebox/ClearMethodStateTest.java Fri Oct 11 17:14:35 2013 +0200 +++ b/test/compiler/whitebox/ClearMethodStateTest.java Fri Oct 11 17:21:14 2013 +0200 @@ -26,7 +26,7 @@ * @library /testlibrary /testlibrary/whitebox * @build ClearMethodStateTest * @run main ClassFileInstaller sun.hotspot.WhiteBox - * @run main/othervm -Xbootclasspath/a:. -Xmixed -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI ClearMethodStateTest + * @run main/othervm -Xbootclasspath/a:. -Xmixed -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:CompileCommand=compileonly,TestCase$Helper::* ClearMethodStateTest * @summary testing of WB::clearMethodState() * @author igor.ignatyev@oracle.com */
--- a/test/compiler/whitebox/CompilerWhiteBoxTest.java Fri Oct 11 17:14:35 2013 +0200 +++ b/test/compiler/whitebox/CompilerWhiteBoxTest.java Fri Oct 11 17:21:14 2013 +0200 @@ -61,6 +61,9 @@ /** Value of {@code -XX:TieredStopAtLevel} */ protected static final int TIERED_STOP_AT_LEVEL = Integer.parseInt(getVMOption("TieredStopAtLevel", "0")); + /** Flag for verbose output, true if {@code -Dverbose} specified */ + protected static final boolean IS_VERBOSE + = System.getProperty("verbose") != null; /** * Returns value of VM option. @@ -268,7 +271,9 @@ } result += tmp == null ? 0 : tmp; } - System.out.println("method was invoked " + count + " times"); + if (IS_VERBOSE) { + System.out.println("method was invoked " + count + " times"); + } return result; } }
--- a/test/compiler/whitebox/DeoptimizeAllTest.java Fri Oct 11 17:14:35 2013 +0200 +++ b/test/compiler/whitebox/DeoptimizeAllTest.java Fri Oct 11 17:21:14 2013 +0200 @@ -26,7 +26,7 @@ * @library /testlibrary /testlibrary/whitebox * @build DeoptimizeAllTest * @run main ClassFileInstaller sun.hotspot.WhiteBox - * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI DeoptimizeAllTest + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:CompileCommand=compileonly,TestCase$Helper::* DeoptimizeAllTest * @summary testing of WB::deoptimizeAll() * @author igor.ignatyev@oracle.com */
--- a/test/compiler/whitebox/DeoptimizeMethodTest.java Fri Oct 11 17:14:35 2013 +0200 +++ b/test/compiler/whitebox/DeoptimizeMethodTest.java Fri Oct 11 17:21:14 2013 +0200 @@ -26,7 +26,7 @@ * @library /testlibrary /testlibrary/whitebox * @build DeoptimizeMethodTest * @run main ClassFileInstaller sun.hotspot.WhiteBox - * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI DeoptimizeMethodTest + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:CompileCommand=compileonly,TestCase$Helper::* DeoptimizeMethodTest * @summary testing of WB::deoptimizeMethod() * @author igor.ignatyev@oracle.com */
--- a/test/compiler/whitebox/EnqueueMethodForCompilationTest.java Fri Oct 11 17:14:35 2013 +0200 +++ b/test/compiler/whitebox/EnqueueMethodForCompilationTest.java Fri Oct 11 17:21:14 2013 +0200 @@ -26,7 +26,7 @@ * @library /testlibrary /testlibrary/whitebox * @build EnqueueMethodForCompilationTest * @run main ClassFileInstaller sun.hotspot.WhiteBox - * @run main/othervm -Xbootclasspath/a:. -Xmixed -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI EnqueueMethodForCompilationTest + * @run main/othervm -Xbootclasspath/a:. -Xmixed -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:CompileCommand=compileonly,TestCase$Helper::* EnqueueMethodForCompilationTest * @summary testing of WB::enqueueMethodForCompilation() * @author igor.ignatyev@oracle.com */
--- a/test/compiler/whitebox/IsMethodCompilableTest.java Fri Oct 11 17:14:35 2013 +0200 +++ b/test/compiler/whitebox/IsMethodCompilableTest.java Fri Oct 11 17:21:14 2013 +0200 @@ -27,7 +27,7 @@ * @library /testlibrary /testlibrary/whitebox * @build IsMethodCompilableTest * @run main ClassFileInstaller sun.hotspot.WhiteBox - * @run main/othervm/timeout=600 -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI IsMethodCompilableTest + * @run main/othervm/timeout=600 -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:CompileCommand=compileonly,TestCase$Helper::* IsMethodCompilableTest * @summary testing of WB::isMethodCompilable() * @author igor.ignatyev@oracle.com */
--- a/test/compiler/whitebox/MakeMethodNotCompilableTest.java Fri Oct 11 17:14:35 2013 +0200 +++ b/test/compiler/whitebox/MakeMethodNotCompilableTest.java Fri Oct 11 17:21:14 2013 +0200 @@ -27,7 +27,7 @@ * @library /testlibrary /testlibrary/whitebox * @build MakeMethodNotCompilableTest * @run main ClassFileInstaller sun.hotspot.WhiteBox - * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI MakeMethodNotCompilableTest + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:CompileCommand=compileonly,TestCase$Helper::* MakeMethodNotCompilableTest * @summary testing of WB::makeMethodNotCompilable() * @author igor.ignatyev@oracle.com */
--- a/test/compiler/whitebox/SetDontInlineMethodTest.java Fri Oct 11 17:14:35 2013 +0200 +++ b/test/compiler/whitebox/SetDontInlineMethodTest.java Fri Oct 11 17:21:14 2013 +0200 @@ -26,7 +26,7 @@ * @library /testlibrary /testlibrary/whitebox * @build SetDontInlineMethodTest * @run main ClassFileInstaller sun.hotspot.WhiteBox - * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI SetDontInlineMethodTest + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:CompileCommand=compileonly,TestCase$Helper::* SetDontInlineMethodTest * @summary testing of WB::testSetDontInlineMethod() * @author igor.ignatyev@oracle.com */
--- a/test/compiler/whitebox/SetForceInlineMethodTest.java Fri Oct 11 17:14:35 2013 +0200 +++ b/test/compiler/whitebox/SetForceInlineMethodTest.java Fri Oct 11 17:21:14 2013 +0200 @@ -26,7 +26,7 @@ * @library /testlibrary /testlibrary/whitebox * @build SetForceInlineMethodTest * @run main ClassFileInstaller sun.hotspot.WhiteBox - * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI SetForceInlineMethodTest + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:CompileCommand=compileonly,TestCase$Helper::* SetForceInlineMethodTest * @summary testing of WB::testSetForceInlineMethod() * @author igor.ignatyev@oracle.com */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/gc/arguments/TestG1HeapRegionSize.java Fri Oct 11 17:21:14 2013 +0200 @@ -0,0 +1,64 @@ +/* +* 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. +*/ + +/* + * @test TestG1HeapRegionSize + * @key gc + * @bug 8021879 + * @summary Verify that the flag G1HeapRegionSize is updated properly + * @run main/othervm -Xmx64m TestG1HeapRegionSize 1048576 + * @run main/othervm -XX:G1HeapRegionSize=2m -Xmx64m TestG1HeapRegionSize 2097152 + * @run main/othervm -XX:G1HeapRegionSize=3m -Xmx64m TestG1HeapRegionSize 2097152 + * @run main/othervm -XX:G1HeapRegionSize=64m -Xmx256m TestG1HeapRegionSize 33554432 + */ + +import sun.management.ManagementFactoryHelper; +import com.sun.management.HotSpotDiagnosticMXBean; +import com.sun.management.VMOption; + +public class TestG1HeapRegionSize { + + public static void main(String[] args) { + HotSpotDiagnosticMXBean diagnostic = ManagementFactoryHelper.getDiagnosticMXBean(); + + VMOption option = diagnostic.getVMOption("UseG1GC"); + if (option.getValue().equals("false")) { + System.out.println("Skipping this test. It is only a G1 test."); + return; + } + + String expectedValue = getExpectedValue(args); + option = diagnostic.getVMOption("G1HeapRegionSize"); + if (!expectedValue.equals(option.getValue())) { + throw new RuntimeException("Wrong value for G1HeapRegionSize. Expected " + expectedValue + " but got " + option.getValue()); + } + } + + private static String getExpectedValue(String[] args) { + if (args.length != 1) { + throw new RuntimeException("Wrong number of arguments. Expected 1 but got " + args.length); + } + return args[0]; + } + +}
--- a/test/gc/g1/TestPrintRegionRememberedSetInfo.java Fri Oct 11 17:14:35 2013 +0200 +++ b/test/gc/g1/TestPrintRegionRememberedSetInfo.java Fri Oct 11 17:21:14 2013 +0200 @@ -27,7 +27,7 @@ * @bug 8014240 * @summary Test output of G1PrintRegionRememberedSetInfo * @library /testlibrary - * @build TestPrintRegionRememberedSetInfo + * @run main TestPrintRegionRememberedSetInfo * @author thomas.schatzl@oracle.com */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/gc/startup_warnings/TestDefaultMaxRAMFraction.java Fri Oct 11 17:21:14 2013 +0200 @@ -0,0 +1,44 @@ +/* +* 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. +*/ + +/* +* @test TestDefaultMaxRAMFraction +* @key gc +* @bug 8021967 +* @summary Test that the deprecated TestDefaultMaxRAMFraction flag print a warning message +* @library /testlibrary +*/ + +import com.oracle.java.testlibrary.OutputAnalyzer; +import com.oracle.java.testlibrary.ProcessTools; + +public class TestDefaultMaxRAMFraction { + public static void main(String[] args) throws Exception { + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-XX:DefaultMaxRAMFraction=4", "-version"); + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + output.shouldContain("warning: DefaultMaxRAMFraction is deprecated and will likely be removed in a future release. Use MaxRAMFraction instead."); + output.shouldNotContain("error"); + output.shouldHaveExitValue(0); + } + +}
--- a/test/runtime/6929067/Test6929067.sh Fri Oct 11 17:14:35 2013 +0200 +++ b/test/runtime/6929067/Test6929067.sh Fri Oct 11 17:21:14 2013 +0200 @@ -3,6 +3,7 @@ ## ## @test Test6929067.sh ## @bug 6929067 +## @bug 8021296 ## @summary Stack guard pages should be removed when thread is detached ## @compile T.java ## @run shell Test6929067.sh @@ -21,6 +22,11 @@ OS=`uname -s` case "$OS" in Linux) + gcc_cmd=`which gcc` + if [ "x$gcc_cmd" == "x" ]; then + echo "WARNING: gcc not found. Cannot execute test." 2>&1 + exit 0; + fi NULL=/dev/null PS=":" FS="/" @@ -119,10 +125,10 @@ # Check to ensure you have a /usr/lib/libpthread.so if you don't please look # for /usr/lib/`uname -m`-linux-gnu version ensure to add that path to below compilation. -gcc -DLINUX ${COMP_FLAG} -o invoke \ - -I${COMPILEJAVA}/include -I${COMPILEJAVA}/include/linux \ - -L${COMPILEJAVA}/jre/lib/${ARCH}/${VMTYPE} \ - -ljvm -lpthread invoke.c +$gcc_cmd -DLINUX ${COMP_FLAG} -o invoke \ + -I${COMPILEJAVA}/include -I${COMPILEJAVA}/include/linux \ + -L${COMPILEJAVA}/jre/lib/${ARCH}/${VMTYPE} \ + -ljvm -lpthread invoke.c ./invoke exit $?
--- a/test/runtime/7107135/Test7107135.sh Fri Oct 11 17:14:35 2013 +0200 +++ b/test/runtime/7107135/Test7107135.sh Fri Oct 11 17:21:14 2013 +0200 @@ -27,6 +27,7 @@ ## ## @test Test7107135.sh ## @bug 7107135 +## @bug 8021296 ## @summary Stack guard pages lost after loading library with executable stack. ## @run shell Test7107135.sh ## @@ -45,11 +46,13 @@ case "$OS" in Linux) echo "Testing on Linux" + gcc_cmd=`which gcc` + if [ "x$gcc_cmd" == "x" ]; then + echo "WARNING: gcc not found. Cannot execute test." 2>&1 + exit 0; + fi ;; *) - NULL=NUL - PS=";" - FS="\\" echo "Test passed; only valid for Linux" exit 0; ;; @@ -62,7 +65,10 @@ cp ${TESTSRC}${FS}*.java ${THIS_DIR} ${TESTJAVA}${FS}bin${FS}javac *.java -gcc -fPIC -shared -c -o test.o -I${TESTJAVA}${FS}include -I${TESTJAVA}${FS}include${FS}linux ${TESTSRC}${FS}test.c +$gcc_cmd -fPIC -shared -c -o test.o \ + -I${TESTJAVA}${FS}include -I${TESTJAVA}${FS}include${FS}linux \ + ${TESTSRC}${FS}test.c + ld -shared -z execstack -o libtest-rwx.so test.o ld -shared -z noexecstack -o libtest-rw.so test.o @@ -78,14 +84,16 @@ echo echo Test changing of stack protection: -echo ${TESTJAVA}${FS}bin${FS}java -cp ${THIS_DIR} Test test-rw +echo ${TESTJAVA}${FS}bin${FS}java -cp ${THIS_DIR} Test test-rwx ${TESTJAVA}${FS}bin${FS}java -cp ${THIS_DIR} Test test-rwx +JAVA_RETVAL=$? -if [ "$?" == "0" ] +if [ "$JAVA_RETVAL" == "0" ] then echo echo ${TESTJAVA}${FS}bin${FS}java -cp ${THIS_DIR} TestMT test-rwx ${TESTJAVA}${FS}bin${FS}java -cp ${THIS_DIR} TestMT test-rwx + JAVA_RETVAL=$? fi -exit $? +exit $JAVA_RETVAL
--- a/test/runtime/7196045/Test7196045.java Fri Oct 11 17:14:35 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,78 +0,0 @@ -/* - * Copyright (c) 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. - * - */ - -/* - * @test - * @bug 7196045 - * @summary Possible JVM deadlock in ThreadTimesClosure when using HotspotInternal non-public API. - * @run main/othervm -XX:+UsePerfData Test7196045 - */ - -import java.lang.management.ManagementFactory; -import javax.management.JMException; -import javax.management.MBeanServer; -import javax.management.MalformedObjectNameException; -import javax.management.ObjectName; - -public class Test7196045 { - - public static long duration = 1000 * 60 * 2; - private static final String HOTSPOT_INTERNAL = "sun.management:type=HotspotInternal"; - - public static void main(String[] args) { - - MBeanServer server = ManagementFactory.getPlatformMBeanServer(); - ObjectName objName= null; - try { - ObjectName hotspotInternal = new ObjectName(HOTSPOT_INTERNAL); - try { - server.registerMBean(new sun.management.HotspotInternal(), hotspotInternal); - } catch (JMException e) { - throw new RuntimeException("HotSpotWatcher: Failed to register the HotspotInternal MBean" + e); - } - objName= new ObjectName("sun.management:type=HotspotThreading"); - - } catch (MalformedObjectNameException e1) { - throw new RuntimeException("Bad object name" + e1); - } - - long endTime = System.currentTimeMillis() + duration; - long i = 0; - while (true) { - try { - server.getAttribute(objName, "InternalThreadCpuTimes"); - } catch (Exception ex) { - System.err.println("Exception while getting attribute: " + ex); - } - i++; - if (i % 10000 == 0) { - System.out.println("Successful iterations: " + i); - } - if (System.currentTimeMillis() > endTime) { - break; - } - } - System.out.println("PASSED."); - } -}
--- a/test/runtime/8000968/Test8000968.sh Fri Oct 11 17:14:35 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,99 +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. -# - - -# @test Test8000968.sh -# @bug 8000968 -# @summary NPG: UseCompressedKlassPointers asserts with ObjectAlignmentInBytes=32 -# @run shell Test8000968.sh -# - -if [ "${TESTJAVA}" = "" ] -then - PARENT=`dirname \`which java\`` - TESTJAVA=`dirname ${PARENT}` - printf "TESTJAVA not set, selecting " ${TESTJAVA} - printf " If this is incorrect, try setting the variable manually.\n" -fi - - -# set platform-dependent variables -OS=`uname -s` -case "$OS" in - Windows_* ) - FS="\\" - NULL=NUL - ;; - * ) - FS="/" - NULL=/dev/null - ;; -esac - -JAVA=${TESTJAVA}${FS}bin${FS}java - -# -# See if platform has 64 bit java. -# -${JAVA} ${TESTVMOPTS} -d64 -version 2>&1 | grep -i "does not support" > ${NULL} -if [ "$?" != "1" ] -then - printf "Platform is 32 bit, does not support -XX:ObjectAlignmentInBytes= option.\n" - printf "Passed.\n" - exit 0 -fi - -# -# Test -XX:ObjectAlignmentInBytes with -XX:+UseCompressedKlassPointers -XX:+UseCompressedOops. -# -${JAVA} ${TESTVMOPTS} -d64 -XX:+UseCompressedKlassPointers -XX:+UseCompressedOops -XX:ObjectAlignmentInBytes=16 -version 2>&1 > ${NULL} -if [ "$?" != "0" ] -then - printf "FAILED: -XX:ObjectAlignmentInBytes=16 option did not work.\n" - exit 1 -fi - -${JAVA} ${TESTVMOPTS} -d64 -XX:+UseCompressedKlassPointers -XX:+UseCompressedOops -XX:ObjectAlignmentInBytes=32 -version 2>&1 > ${NULL} -if [ "$?" != "0" ] -then - printf "FAILED: -XX:ObjectAlignmentInBytes=32 option did not work.\n" - exit 1 -fi - -${JAVA} ${TESTVMOPTS} -d64 -XX:+UseCompressedKlassPointers -XX:+UseCompressedOops -XX:ObjectAlignmentInBytes=64 -version 2>&1 > ${NULL} -if [ "$?" != "0" ] -then - printf "FAILED: -XX:ObjectAlignmentInBytes=64 option did not work.\n" - exit 1 -fi - -${JAVA} ${TESTVMOPTS} -d64 -XX:+UseCompressedKlassPointers -XX:+UseCompressedOops -XX:ObjectAlignmentInBytes=128 -version 2>&1 > ${NULL} -if [ "$?" != "0" ] -then - printf "FAILED: -XX:ObjectAlignmentInBytes=128 option did not work.\n" - exit 1 -fi - - -printf "Passed.\n" -exit 0
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/runtime/CompressedOops/CompressedKlassPointerAndOops.java Fri Oct 11 17:21:14 2013 +0200 @@ -0,0 +1,63 @@ +/* + * 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. + */ + +/* + * @test + * @bug 8000968 + * @key regression + * @summary NPG: UseCompressedKlassPointers asserts with ObjectAlignmentInBytes=32 + * @library /testlibrary + */ + +import com.oracle.java.testlibrary.*; + +public class CompressedKlassPointerAndOops { + + public static void main(String[] args) throws Exception { + + if (!Platform.is64bit()) { + // Can't test this on 32 bit, just pass + System.out.println("Skipping test on 32bit"); + return; + } + + runWithAlignment(16); + runWithAlignment(32); + runWithAlignment(64); + runWithAlignment(128); + } + + private static void runWithAlignment(int alignment) throws Exception { + ProcessBuilder pb; + OutputAnalyzer output; + + pb = ProcessTools.createJavaProcessBuilder( + "-XX:+UseCompressedKlassPointers", + "-XX:+UseCompressedOops", + "-XX:ObjectAlignmentInBytes=" + alignment, + "-version"); + + output = new OutputAnalyzer(pb.start()); + output.shouldHaveExitValue(0); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/runtime/InternalApi/ThreadCpuTimesDeadlock.java Fri Oct 11 17:21:14 2013 +0200 @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2012, 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. + * + */ + +/* + * @test + * @bug 7196045 + * @bug 8014294 + * @summary Possible JVM deadlock in ThreadTimesClosure when using HotspotInternal non-public API. + * @run main/othervm -XX:+UsePerfData -Xmx32m ThreadCpuTimesDeadlock + */ + +import java.lang.management.ManagementFactory; +import javax.management.JMException; +import javax.management.MBeanServer; +import javax.management.MalformedObjectNameException; +import javax.management.ObjectName; + +public class ThreadCpuTimesDeadlock { + + public static byte[] dummy; + public static long duration = 10 * 1000; + private static final String HOTSPOT_INTERNAL = "sun.management:type=HotspotInternal"; + + public static void main(String[] args) { + + MBeanServer server = ManagementFactory.getPlatformMBeanServer(); + ObjectName objName= null; + try { + ObjectName hotspotInternal = new ObjectName(HOTSPOT_INTERNAL); + try { + server.registerMBean(new sun.management.HotspotInternal(), hotspotInternal); + } catch (JMException e) { + throw new RuntimeException("HotSpotWatcher: Failed to register the HotspotInternal MBean" + e); + } + objName= new ObjectName("sun.management:type=HotspotThreading"); + + } catch (MalformedObjectNameException e1) { + throw new RuntimeException("Bad object name" + e1); + } + + // Thread that allocs memory to generate GC's + Thread allocThread = new Thread() { + public void run() { + while (true) { + dummy = new byte[4096]; + } + } + }; + + allocThread.setDaemon(true); + allocThread.start(); + + long endTime = System.currentTimeMillis() + duration; + long i = 0; + while (true) { + try { + server.getAttribute(objName, "InternalThreadCpuTimes"); + } catch (Exception ex) { + System.err.println("Exception while getting attribute: " + ex); + } + i++; + if (i % 10000 == 0) { + System.out.println("Successful iterations: " + i); + } + if (System.currentTimeMillis() > endTime) { + break; + } + } + System.out.println("PASSED."); + } +}
--- a/test/runtime/RedefineObject/Agent.java Fri Oct 11 17:14:35 2013 +0200 +++ b/test/runtime/RedefineObject/Agent.java Fri Oct 11 17:21:14 2013 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -22,6 +22,7 @@ */ import java.security.*; import java.lang.instrument.*; +import java.lang.reflect.*; public class Agent implements ClassFileTransformer { public synchronized byte[] transform(final ClassLoader classLoader, @@ -29,22 +30,34 @@ Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) { - //System.out.println("Transforming class " + className); + System.out.println("Transforming class " + className); return classfileBuffer; } + public static void redefine(String agentArgs, Instrumentation instrumentation, Class to_redefine) { + + try { + instrumentation.retransformClasses(to_redefine); + } catch (Exception e) { + e.printStackTrace(); + } + + } + public static void premain(String agentArgs, Instrumentation instrumentation) { - Agent transformer = new Agent(); - instrumentation.addTransformer(transformer, true); - Class c = Object.class; - try { - instrumentation.retransformClasses(c); - } catch (Exception e) { - e.printStackTrace(); - } + // Redefine java/lang/Object and java/lang/reflect/Method.invoke and + // java/lang/ClassLoader + Class object_class = Object.class; + redefine(agentArgs, instrumentation, object_class); + + Class method_class = Method.class; + redefine(agentArgs, instrumentation, method_class); + + Class loader_class = ClassLoader.class; + redefine(agentArgs, instrumentation, loader_class); instrumentation.removeTransformer(transformer); } @@ -57,5 +70,14 @@ System.gc(); ba.clone(); } + try { + // Use java/lang/reflect/Method.invoke to call + WalkThroughInvoke a = new WalkThroughInvoke(); + Class aclass = WalkThroughInvoke.class; + Method m = aclass.getMethod("stackWalk"); + m.invoke(a); + } catch (Exception x) { + x.printStackTrace(); + } } }
--- a/test/runtime/RedefineObject/TestRedefineObject.java Fri Oct 11 17:14:35 2013 +0200 +++ b/test/runtime/RedefineObject/TestRedefineObject.java Fri Oct 11 17:21:14 2013 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -26,14 +26,17 @@ /* * Test to redefine java/lang/Object and verify that it doesn't crash on vtable * call on basic array type. + * Test to redefine java/lang/ClassLoader and java/lang/reflect/Method to make + * sure cached versions used afterward are the current version. * * @test * @bug 8005056 + * @bug 8009728 * @library /testlibrary * @build Agent * @run main ClassFileInstaller Agent * @run main TestRedefineObject - * @run main/othervm -javaagent:agent.jar Agent + * @run main/othervm -javaagent:agent.jar -XX:TraceRedefineClasses=5 Agent */ public class TestRedefineObject { public static void main(String[] args) throws Exception {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/runtime/RedefineObject/WalkThroughInvoke.java Fri Oct 11 17:21:14 2013 +0200 @@ -0,0 +1,38 @@ +/* + * 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. + */ +import java.lang.reflect.*; + +public class WalkThroughInvoke { + public void stackWalk() { + try { + Class b = Object.class; + SecurityManager sm = new SecurityManager(); + // Walks the stack with Method.invoke in the stack (which is the + // purpose of the test) before it gets an AccessControlException. + sm.checkMemberAccess(b, Member.DECLARED); + } catch (java.security.AccessControlException e) { + // Ignoring an 'AccessControlException' exception since + // it is expected as part of this test. + } + } +};
--- a/test/runtime/jsig/Test8017498.sh Fri Oct 11 17:14:35 2013 +0200 +++ b/test/runtime/jsig/Test8017498.sh Fri Oct 11 17:21:14 2013 +0200 @@ -27,6 +27,7 @@ ## @test Test8017498.sh ## @bug 8017498 ## @bug 8020791 +## @bug 8021296 ## @summary sigaction(sig) results in process hang/timed-out if sig is much greater than SIGRTMAX ## @run shell/timeout=30 Test8017498.sh ## @@ -45,6 +46,11 @@ case "$OS" in Linux) echo "Testing on Linux" + gcc_cmd=`which gcc` + if [ "x$gcc_cmd" == "x" ]; then + echo "WARNING: gcc not found. Cannot execute test." 2>&1 + exit 0; + fi if [ "$VM_BITS" = "64" ] then MY_LD_PRELOAD=${TESTJAVA}${FS}jre${FS}lib${FS}amd64${FS}libjsig.so @@ -64,15 +70,11 @@ cp ${TESTSRC}${FS}*.java ${THIS_DIR} ${TESTJAVA}${FS}bin${FS}javac *.java -gcc -DLINUX -fPIC -shared \ +$gcc_cmd -DLINUX -fPIC -shared \ -o ${TESTSRC}${FS}libTestJNI.so \ -I${TESTJAVA}${FS}include \ -I${TESTJAVA}${FS}include${FS}linux \ ${TESTSRC}${FS}TestJNI.c -if [ $? != 0 ] -then - echo "WARNING: the gcc command failed." 2>&1 -fi # run the java test in the background cmd="LD_PRELOAD=$MY_LD_PRELOAD \
--- a/test/runtime/jsig/TestJNI.c Fri Oct 11 17:14:35 2013 +0200 +++ b/test/runtime/jsig/TestJNI.c Fri Oct 11 17:21:14 2013 +0200 @@ -21,7 +21,6 @@ * questions. */ -#define _GNU_SOURCE // for the definition of REG_RIP in ucontext.h #include <stdio.h> #include <jni.h> #include <signal.h> @@ -32,11 +31,8 @@ #endif void sig_handler(int sig, siginfo_t *info, ucontext_t *context) { - int thrNum; printf( " HANDLER (1) " ); - // Move forward RIP to skip failing instruction - context->uc_mcontext.gregs[REG_RIP] += 6; } JNIEXPORT void JNICALL Java_TestJNI_doSomething(JNIEnv *env, jclass klass, jint val) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/testlibrary/OutputAnalyzerReportingTest.java Fri Oct 11 17:21:14 2013 +0200 @@ -0,0 +1,124 @@ +/* + * 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. + */ + + +/* + * @test + * @summary Test the OutputAnalyzer reporting functionality, + * such as printing additional diagnostic info + * (exit code, stdout, stderr, command line, etc.) + * @library /testlibrary + */ + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; + +import com.oracle.java.testlibrary.OutputAnalyzer; +import com.oracle.java.testlibrary.ProcessTools; + + +public class OutputAnalyzerReportingTest { + + public static void main(String[] args) throws Exception { + // Create the output analyzer under test + String stdout = "aaaaaa"; + String stderr = "bbbbbb"; + OutputAnalyzer output = new OutputAnalyzer(stdout, stderr); + + // Expected summary values should be the same for all cases, + // since the outputAnalyzer object is the same + String expectedExitValue = "-1"; + String expectedSummary = + " stdout: [" + stdout + "];\n" + + " stderr: [" + stderr + "]\n" + + " exitValue = " + expectedExitValue + "\n"; + + + DiagnosticSummaryTestRunner testRunner = + new DiagnosticSummaryTestRunner(); + + // should have exit value + testRunner.init(expectedSummary); + int unexpectedExitValue = 2; + try { + output.shouldHaveExitValue(unexpectedExitValue); + } catch (RuntimeException e) { } + testRunner.closeAndCheckResults(); + + // should not contain + testRunner.init(expectedSummary); + try { + output.shouldNotContain(stdout); + } catch (RuntimeException e) { } + testRunner.closeAndCheckResults(); + + // should contain + testRunner.init(expectedSummary); + try { + output.shouldContain("unexpected-stuff"); + } catch (RuntimeException e) { } + testRunner.closeAndCheckResults(); + + // should not match + testRunner.init(expectedSummary); + try { + output.shouldNotMatch("[a]"); + } catch (RuntimeException e) { } + testRunner.closeAndCheckResults(); + + // should match + testRunner.init(expectedSummary); + try { + output.shouldMatch("[qwerty]"); + } catch (RuntimeException e) { } + testRunner.closeAndCheckResults(); + + } + + private static class DiagnosticSummaryTestRunner { + private ByteArrayOutputStream byteStream = + new ByteArrayOutputStream(10000); + + private String expectedSummary = ""; + private PrintStream errStream; + + + public void init(String expectedSummary) { + this.expectedSummary = expectedSummary; + byteStream.reset(); + errStream = new PrintStream(byteStream); + System.setErr(errStream); + } + + public void closeAndCheckResults() { + // check results + errStream.close(); + String stdErrStr = byteStream.toString(); + if (!stdErrStr.contains(expectedSummary)) { + throw new RuntimeException("The output does not contain " + + "the diagnostic message, or the message is incorrect"); + } + } + } + +}
--- a/test/testlibrary/com/oracle/java/testlibrary/OutputAnalyzer.java Fri Oct 11 17:14:35 2013 +0200 +++ b/test/testlibrary/com/oracle/java/testlibrary/OutputAnalyzer.java Fri Oct 11 17:21:14 2013 +0200 @@ -76,7 +76,8 @@ */ public void shouldContain(String expectedString) { if (!stdout.contains(expectedString) && !stderr.contains(expectedString)) { - throw new RuntimeException("'" + expectedString + "' missing from stdout/stderr: [" + stdout + stderr + "]\n"); + reportDiagnosticSummary(); + throw new RuntimeException("'" + expectedString + "' missing from stdout/stderr \n"); } } @@ -88,7 +89,8 @@ */ public void stdoutShouldContain(String expectedString) { if (!stdout.contains(expectedString)) { - throw new RuntimeException("'" + expectedString + "' missing from stdout: [" + stdout + "]\n"); + reportDiagnosticSummary(); + throw new RuntimeException("'" + expectedString + "' missing from stdout \n"); } } @@ -100,7 +102,8 @@ */ public void stderrShouldContain(String expectedString) { if (!stderr.contains(expectedString)) { - throw new RuntimeException("'" + expectedString + "' missing from stderr: [" + stderr + "]\n"); + reportDiagnosticSummary(); + throw new RuntimeException("'" + expectedString + "' missing from stderr \n"); } } @@ -112,10 +115,12 @@ */ public void shouldNotContain(String notExpectedString) { if (stdout.contains(notExpectedString)) { - throw new RuntimeException("'" + notExpectedString + "' found in stdout: [" + stdout + "]\n"); + reportDiagnosticSummary(); + throw new RuntimeException("'" + notExpectedString + "' found in stdout \n"); } if (stderr.contains(notExpectedString)) { - throw new RuntimeException("'" + notExpectedString + "' found in stderr: [" + stderr + "]\n"); + reportDiagnosticSummary(); + throw new RuntimeException("'" + notExpectedString + "' found in stderr \n"); } } @@ -127,7 +132,8 @@ */ public void stdoutShouldNotContain(String notExpectedString) { if (stdout.contains(notExpectedString)) { - throw new RuntimeException("'" + notExpectedString + "' found in stdout: [" + stdout + "]\n"); + reportDiagnosticSummary(); + throw new RuntimeException("'" + notExpectedString + "' found in stdout \n"); } } @@ -139,7 +145,8 @@ */ public void stderrShouldNotContain(String notExpectedString) { if (stderr.contains(notExpectedString)) { - throw new RuntimeException("'" + notExpectedString + "' found in stderr: [" + stderr + "]\n"); + reportDiagnosticSummary(); + throw new RuntimeException("'" + notExpectedString + "' found in stderr \n"); } } @@ -154,9 +161,9 @@ Matcher stdoutMatcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stdout); Matcher stderrMatcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stderr); if (!stdoutMatcher.find() && !stderrMatcher.find()) { + reportDiagnosticSummary(); throw new RuntimeException("'" + pattern - + "' missing from stdout/stderr: [" + stdout + stderr - + "]\n"); + + "' missing from stdout/stderr \n"); } } @@ -170,8 +177,9 @@ public void stdoutShouldMatch(String pattern) { Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stdout); if (!matcher.find()) { + reportDiagnosticSummary(); throw new RuntimeException("'" + pattern - + "' missing from stdout: [" + stdout + "]\n"); + + "' missing from stdout \n"); } } @@ -185,8 +193,9 @@ public void stderrShouldMatch(String pattern) { Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stderr); if (!matcher.find()) { + reportDiagnosticSummary(); throw new RuntimeException("'" + pattern - + "' missing from stderr: [" + stderr + "]\n"); + + "' missing from stderr \n"); } } @@ -200,13 +209,15 @@ public void shouldNotMatch(String pattern) { Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stdout); if (matcher.find()) { + reportDiagnosticSummary(); throw new RuntimeException("'" + pattern - + "' found in stdout: [" + stdout + "]\n"); + + "' found in stdout \n"); } matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stderr); if (matcher.find()) { + reportDiagnosticSummary(); throw new RuntimeException("'" + pattern - + "' found in stderr: [" + stderr + "]\n"); + + "' found in stderr \n"); } } @@ -220,8 +231,9 @@ public void stdoutShouldNotMatch(String pattern) { Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stdout); if (matcher.find()) { + reportDiagnosticSummary(); throw new RuntimeException("'" + pattern - + "' found in stdout: [" + stdout + "]\n"); + + "' found in stdout \n"); } } @@ -235,23 +247,45 @@ public void stderrShouldNotMatch(String pattern) { Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stderr); if (matcher.find()) { + reportDiagnosticSummary(); throw new RuntimeException("'" + pattern - + "' found in stderr: [" + stderr + "]\n"); + + "' found in stderr \n"); } } /** - * Verifiy the exit value of the process + * Verify the exit value of the process * * @param expectedExitValue Expected exit value from process * @throws RuntimeException If the exit value from the process did not match the expected value */ public void shouldHaveExitValue(int expectedExitValue) { if (getExitValue() != expectedExitValue) { - throw new RuntimeException("Exit value " + getExitValue() + " , expected to get " + expectedExitValue); + reportDiagnosticSummary(); + throw new RuntimeException("Expected to get exit value of [" + + expectedExitValue + "]\n"); } } + + /** + * Report summary that will help to diagnose the problem + * Currently includes: + * - standard input produced by the process under test + * - standard output + * - exit code + * Note: the command line is printed by the ProcessTools + */ + private void reportDiagnosticSummary() { + String msg = + " stdout: [" + stdout + "];\n" + + " stderr: [" + stderr + "]\n" + + " exitValue = " + getExitValue() + "\n"; + + System.err.println(msg); + } + + /** * Get the contents of the output buffer (stdout and stderr) *
--- a/test/testlibrary/com/oracle/java/testlibrary/Platform.java Fri Oct 11 17:14:35 2013 +0200 +++ b/test/testlibrary/com/oracle/java/testlibrary/Platform.java Fri Oct 11 17:21:14 2013 +0200 @@ -27,6 +27,7 @@ private static final String osName = System.getProperty("os.name"); private static final String dataModel = System.getProperty("sun.arch.data.model"); private static final String vmVersion = System.getProperty("java.vm.version"); + private static final String osArch = System.getProperty("os.arch"); public static boolean is64bit() { return dataModel.equals("64"); @@ -59,4 +60,14 @@ public static String getVMVersion() { return vmVersion; } + + // Returns true for sparc and sparcv9. + public static boolean isSparc() { + return osArch.toLowerCase().startsWith("sparc"); + } + + public static String getOsArch() { + return osArch; + } + }
--- a/test/testlibrary/com/oracle/java/testlibrary/ProcessTools.java Fri Oct 11 17:14:35 2013 +0200 +++ b/test/testlibrary/com/oracle/java/testlibrary/ProcessTools.java Fri Oct 11 17:21:14 2013 +0200 @@ -31,6 +31,7 @@ import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Collections; +import java.util.List; import sun.management.VMManagement; @@ -107,6 +108,22 @@ } /** + * Get the string containing input arguments passed to the VM + * + * @return arguments + */ + public static String getVmInputArguments() { + RuntimeMXBean runtime = ManagementFactory.getRuntimeMXBean(); + + List<String> args = runtime.getInputArguments(); + StringBuilder result = new StringBuilder(); + for (String arg : args) + result.append(arg).append(' '); + + return result.toString(); + } + + /** * Get platform specific VM arguments (e.g. -d64 on 64bit Solaris) * * @return String[] with platform specific arguments, empty if there are none @@ -132,8 +149,13 @@ Collections.addAll(args, getPlatformSpecificVMArgs()); Collections.addAll(args, command); + // Reporting + StringBuilder cmdLine = new StringBuilder(); + for (String cmd : args) + cmdLine.append(cmd).append(' '); + System.out.println("Command line: [" + cmdLine.toString() + "]"); + return new ProcessBuilder(args.toArray(new String[args.size()])); - } }