# HG changeset patch # User Doug Simon # Date 1341432063 -7200 # Node ID 66ec0bc36a379698a06097cef9521ef05c680c9d # Parent a3d71693e0ce645488aa4ccbfa5436437cd84dbf# Parent f043ecb70d3ef1a3720b16fc3b24c001e9f2fc05 Merge. diff -r f043ecb70d3e -r 66ec0bc36a37 graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CodeCacheProvider.java --- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CodeCacheProvider.java Wed Jul 04 14:57:12 2012 +0200 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CodeCacheProvider.java Wed Jul 04 22:01:03 2012 +0200 @@ -44,14 +44,6 @@ String disassemble(CodeInfo code, CompilationResult tm); /** - * Returns the disassembly of the given method in a {@code javap}-like format. - * - * @param method the method that should be disassembled - * @return the disassembly. This will be of length 0 if the runtime does not support disassembling. - */ - String disassemble(ResolvedJavaMethod method); - - /** * Gets the register configuration to use when compiling a given method. * * @param method the top level method of a compilation diff -r f043ecb70d3e -r 66ec0bc36a37 graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/JavaType.java --- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/JavaType.java Wed Jul 04 14:57:12 2012 +0200 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/JavaType.java Wed Jul 04 22:01:03 2012 +0200 @@ -65,7 +65,9 @@ /** * For array types, gets the type of the components. - * @return the component type of this array type + * This will be null if this is not an array type. + * + * @return the component type of this type if it is an array type otherwise null */ JavaType componentType(); diff -r f043ecb70d3e -r 66ec0bc36a37 graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/MetaUtil.java --- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/MetaUtil.java Wed Jul 04 14:57:12 2012 +0200 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/MetaUtil.java Wed Jul 04 22:01:03 2012 +0200 @@ -25,6 +25,7 @@ import static java.lang.reflect.Modifier.*; import java.lang.annotation.*; +import java.lang.reflect.*; import java.util.*; import com.oracle.graal.api.meta.JavaTypeProfile.ProfiledType; @@ -308,6 +309,27 @@ /** + * Gets the annotations of a particular type for the formal parameters of a given method. + * + * @param annotationClass the Class object corresponding to the annotation type + * @param method the method for which a parameter annotations are being requested + * @return the annotation of type {@code annotationClass} (if any) for each formal parameter present + */ + public static T[] getParameterAnnotations(Class annotationClass, ResolvedJavaMethod method) { + Annotation[][] parameterAnnotations = method.getParameterAnnotations(); + @SuppressWarnings("unchecked") + T[] result = (T[]) Array.newInstance(annotationClass, parameterAnnotations.length); + for (int i = 0; i < parameterAnnotations.length; i++) { + for (Annotation a : parameterAnnotations[i]) { + if (a.annotationType() == annotationClass) { + result[i] = annotationClass.cast(a); + } + } + } + return result; + } + + /** * Gets the annotation of a particular type for a formal parameter of a given method. * * @param annotationClass the Class object corresponding to the annotation type @@ -328,7 +350,6 @@ return null; } - /** * Convenient shortcut for calling {@link #appendLocation(StringBuilder, ResolvedJavaMethod, int)} without having to supply a * a {@link StringBuilder} instance and convert the result to a string. diff -r f043ecb70d3e -r 66ec0bc36a37 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalOptions.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalOptions.java Wed Jul 04 14:57:12 2012 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalOptions.java Wed Jul 04 22:01:03 2012 +0200 @@ -264,6 +264,7 @@ */ public static String HIRLowerCheckcast = ""; public static String HIRLowerNewInstance = ""; + public static String HIRLowerNewArray = ""; static { // turn detailed assertions on when the general assertions are on (misusing the assert keyword for this) diff -r f043ecb70d3e -r 66ec0bc36a37 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java Wed Jul 04 14:57:12 2012 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java Wed Jul 04 22:01:03 2012 +0200 @@ -31,9 +31,9 @@ import java.util.Map.Entry; import com.oracle.graal.api.code.*; -import com.oracle.graal.api.code.CompilationResult.*; +import com.oracle.graal.api.code.CompilationResult.Mark; import com.oracle.graal.api.meta.*; -import com.oracle.graal.api.meta.JavaType.*; +import com.oracle.graal.api.meta.JavaType.Representation; import com.oracle.graal.compiler.*; import com.oracle.graal.compiler.util.*; import com.oracle.graal.debug.*; @@ -590,7 +590,7 @@ } @Override - public void visitNewTypeArray(NewTypeArrayNode x) { + public void visitNewPrimitiveArray(NewPrimitiveArrayNode x) { XirArgument length = toXirArgument(x.length()); XirSnippet snippet = xir.genNewArray(site(x), length, x.elementType().kind(), null, null); emitXir(snippet, x, state(), true); diff -r f043ecb70d3e -r 66ec0bc36a37 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java Wed Jul 04 14:57:12 2012 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java Wed Jul 04 22:01:03 2012 +0200 @@ -22,8 +22,6 @@ */ package com.oracle.graal.hotspot; -import com.oracle.graal.api.meta.*; - /** * Used to communicate configuration details, runtime offsets, etc. to graal upon compileMethod. */ @@ -46,19 +44,66 @@ // offsets, ... public int vmPageSize; public int stackShadowPages; + + /** + * The offset of the mark word in an object's header. + */ + public int markOffset; + + /** + * The offset of the hub/klassOop word in an object's header. + */ public int hubOffset; + + /** + * The offset of an the array length in an array's header. + */ + public int arrayLengthOffset; + + /** + * The offset of the _super_check_offset field in a Klass. + */ public int superCheckOffsetOffset; + + /** + * The offset of the _secondary_super_cache field in a Klass. + */ public int secondarySuperCacheOffset; + + /** + * The offset of the _secondary_supers field in a Klass. + */ public int secondarySupersOffset; - public int arrayLengthOffset; + + /** + * The offset of the _init_state field in an instanceKlass. + */ public int klassStateOffset; + + /** + * The value of instanceKlass::fully_initialized. + */ public int klassStateFullyInitialized; - public int[] arrayOffsets; + + /** + * The value of objArrayKlass::element_klass_offset(). + */ public int arrayClassElementOffset; + + /** + * The value of JavaThread::tlab_top_offset(). + */ public int threadTlabTopOffset; + + /** + * The value of JavaThread::tlab_end_offset(). + */ public int threadTlabEndOffset; + public int threadObjectOffset; + public int instanceHeaderPrototypeOffset; + public int threadExceptionOopOffset; public int threadExceptionPcOffset; public int threadMultiNewArrayStorageOffset; @@ -110,8 +155,4 @@ assert codeEntryAlignment > 0; assert stackShadowPages > 0; } - - public int getArrayOffset(Kind kind) { - return arrayOffsets[kind.ordinal()]; - } } diff -r f043ecb70d3e -r 66ec0bc36a37 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java Wed Jul 04 14:57:12 2012 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java Wed Jul 04 22:01:03 2012 +0200 @@ -105,8 +105,6 @@ String disassembleNative(byte[] code, long address); - String disassembleJava(HotSpotResolvedJavaMethod method); - StackTraceElement JavaMethod_toStackTraceElement(HotSpotResolvedJavaMethod method, int bci); Object executeCompiledMethod(HotSpotCompiledMethod method, Object arg1, Object arg2, Object arg3); diff -r f043ecb70d3e -r 66ec0bc36a37 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java Wed Jul 04 14:57:12 2012 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java Wed Jul 04 22:01:03 2012 +0200 @@ -150,9 +150,6 @@ public native String disassembleNative(byte[] code, long address); @Override - public native String disassembleJava(HotSpotResolvedJavaMethod method); - - @Override public native StackTraceElement JavaMethod_toStackTraceElement(HotSpotResolvedJavaMethod method, int bci); @Override diff -r f043ecb70d3e -r 66ec0bc36a37 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java Wed Jul 04 14:57:12 2012 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java Wed Jul 04 22:01:03 2012 +0200 @@ -48,7 +48,7 @@ */ public class VMToCompilerImpl implements VMToCompiler { - private final HotSpotGraalRuntime compiler; + private final HotSpotGraalRuntime graalRuntime; private IntrinsifyArrayCopyPhase intrinsifyArrayCopy; public final HotSpotTypePrimitive typeBoolean; @@ -68,7 +68,7 @@ private PrintStream log = System.out; public VMToCompilerImpl(HotSpotGraalRuntime compiler) { - this.compiler = compiler; + this.graalRuntime = compiler; typeBoolean = new HotSpotTypePrimitive(Kind.Boolean); typeChar = new HotSpotTypePrimitive(Kind.Char); @@ -105,9 +105,10 @@ Debug.setConfig(hotspotDebugConfig); } // Install intrinsics. - final HotSpotRuntime runtime = (HotSpotRuntime) compiler.getCompiler().runtime; + GraalCompiler compiler = graalRuntime.getCompiler(); + final HotSpotRuntime runtime = (HotSpotRuntime) compiler.runtime; if (GraalOptions.Intrinsify) { - Debug.scope("InstallSnippets", new DebugDumpScope("InstallSnippets"), new Runnable() { + Debug.scope("InstallSnippets", new Object[] {new DebugDumpScope("InstallSnippets"), compiler}, new Runnable() { @Override public void run() { @@ -214,16 +215,16 @@ CompilationStatistics.clear("bootstrap"); TTY.println(" in %d ms", System.currentTimeMillis() - startTime); - if (compiler.getCache() != null) { - compiler.getCache().clear(); + if (graalRuntime.getCache() != null) { + graalRuntime.getCache().clear(); } System.gc(); CompilationStatistics.clear("bootstrap2"); - MethodEntryCounters.printCounters(compiler); + MethodEntryCounters.printCounters(graalRuntime); } private void enqueue(Method m) throws Throwable { - JavaMethod javaMethod = compiler.getRuntime().getResolvedJavaMethod(m); + JavaMethod javaMethod = graalRuntime.getRuntime().getResolvedJavaMethod(m); assert !Modifier.isAbstract(((HotSpotResolvedJavaMethod) javaMethod).accessFlags()) && !Modifier.isNative(((HotSpotResolvedJavaMethod) javaMethod).accessFlags()) : javaMethod; compileMethod((HotSpotResolvedJavaMethod) javaMethod, 0, false, 10); } @@ -285,7 +286,7 @@ } } CompilationStatistics.clear("final"); - MethodEntryCounters.printCounters(compiler); + MethodEntryCounters.printCounters(graalRuntime); HotSpotXirGenerator.printCounters(TTY.out().out()); CheckCastSnippets.printCounters(TTY.out().out()); } @@ -374,7 +375,7 @@ final OptimisticOptimizations optimisticOpts = new OptimisticOptimizations(method); int id = compileTaskIds.incrementAndGet(); - CompilationTask task = CompilationTask.create(compiler, createPhasePlan(optimisticOpts), optimisticOpts, method, id, priority); + CompilationTask task = CompilationTask.create(graalRuntime, createPhasePlan(optimisticOpts), optimisticOpts, method, id, priority); if (blocking) { task.runCompilation(); } else { @@ -483,7 +484,7 @@ public PhasePlan createPhasePlan(OptimisticOptimizations optimisticOpts) { PhasePlan phasePlan = new PhasePlan(); - GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(compiler.getRuntime(), GraphBuilderConfiguration.getDefault(), optimisticOpts); + GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(graalRuntime.getRuntime(), GraphBuilderConfiguration.getDefault(), optimisticOpts); phasePlan.addPhase(PhasePosition.AFTER_PARSING, graphBuilderPhase); if (GraalOptions.Intrinsify) { phasePlan.addPhase(PhasePosition.HIGH_LEVEL, intrinsifyArrayCopy); diff -r f043ecb70d3e -r 66ec0bc36a37 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaType.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaType.java Wed Jul 04 14:57:12 2012 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaType.java Wed Jul 04 22:01:03 2012 +0200 @@ -54,7 +54,11 @@ private ConstantPool constantPool; private boolean isInitialized; private ResolvedJavaType arrayOfType; - private long prototypeHeader; + + /** + * Initial value for the mark word in a new object of this type. + */ + private long initialMarkWord; private HotSpotResolvedJavaType() { throw new GraalInternalError(HotSpotResolvedJavaType.class + " should only be created from C++ code"); @@ -285,7 +289,7 @@ return superCheckOffset; } - public long prototypeHeader() { - return prototypeHeader; + public long initialMarkWord() { + return initialMarkWord; } } diff -r f043ecb70d3e -r 66ec0bc36a37 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java Wed Jul 04 14:57:12 2012 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java Wed Jul 04 22:01:03 2012 +0200 @@ -28,10 +28,13 @@ import java.util.*; import com.oracle.graal.api.code.*; -import com.oracle.graal.api.code.CompilationResult.*; -import com.oracle.graal.api.code.CodeUtil.*; +import com.oracle.graal.api.code.CodeUtil.RefMapFormatter; +import com.oracle.graal.api.code.CompilationResult.Call; +import com.oracle.graal.api.code.CompilationResult.DataPatch; +import com.oracle.graal.api.code.CompilationResult.Mark; +import com.oracle.graal.api.code.CompilationResult.Safepoint; import com.oracle.graal.api.meta.*; -import com.oracle.graal.api.meta.JavaType.*; +import com.oracle.graal.api.meta.JavaType.Representation; import com.oracle.graal.compiler.*; import com.oracle.graal.compiler.target.*; import com.oracle.graal.graph.*; @@ -57,7 +60,7 @@ private final HotSpotRegisterConfig globalStubRegConfig; private final HotSpotGraalRuntime compiler; private CheckCastSnippets.Templates checkcastSnippets; - private NewInstanceSnippets.Templates newInstanceSnippets; + private NewObjectSnippets.Templates newObjectSnippets; public HotSpotRuntime(HotSpotVMConfig config, HotSpotGraalRuntime compiler) { this.config = config; @@ -73,9 +76,9 @@ installer.install(UnsafeSnippets.class); installer.install(ArrayCopySnippets.class); installer.install(CheckCastSnippets.class); - installer.install(NewInstanceSnippets.class); + installer.install(NewObjectSnippets.class); checkcastSnippets = new CheckCastSnippets.Templates(this); - newInstanceSnippets = new NewInstanceSnippets.Templates(this, config.useTLAB); + newObjectSnippets = new NewObjectSnippets.Templates(this, compiler.getTarget(), config.useTLAB); } @@ -177,11 +180,6 @@ } @Override - public String disassemble(ResolvedJavaMethod method) { - return compiler.getCompilerToVM().disassembleJava((HotSpotResolvedJavaMethod) method); - } - - @Override public ResolvedJavaType getResolvedJavaType(Kind kind) { return (ResolvedJavaType) compiler.getCompilerToVM().getType(kind.toJavaClass()); } @@ -373,12 +371,18 @@ } } else if (n instanceof NewInstanceNode) { if (shouldLower(graph, GraalOptions.HIRLowerNewInstance)) { - newInstanceSnippets.lower((NewInstanceNode) n, tool); + newObjectSnippets.lower((NewInstanceNode) n, tool); + } + } else if (n instanceof NewArrayNode) { + if (shouldLower(graph, GraalOptions.HIRLowerNewArray)) { + newObjectSnippets.lower((NewArrayNode) n, tool); } } else if (n instanceof TLABAllocateNode) { - newInstanceSnippets.lower((TLABAllocateNode) n, tool); - } else if (n instanceof InitializeNode) { - newInstanceSnippets.lower((InitializeNode) n, tool); + newObjectSnippets.lower((TLABAllocateNode) n, tool); + } else if (n instanceof InitializeObjectNode) { + newObjectSnippets.lower((InitializeObjectNode) n, tool); + } else if (n instanceof InitializeArrayNode) { + newObjectSnippets.lower((InitializeArrayNode) n, tool); } else { assert false : "Node implementing Lowerable not handled: " + n; } @@ -395,8 +399,8 @@ return false; } - private IndexedLocationNode createArrayLocation(Graph graph, Kind elementKind, ValueNode index) { - return IndexedLocationNode.create(LocationNode.getArrayLocation(elementKind), elementKind, config.getArrayOffset(elementKind), index, graph, true); + private static IndexedLocationNode createArrayLocation(Graph graph, Kind elementKind, ValueNode index) { + return IndexedLocationNode.create(LocationNode.getArrayLocation(elementKind), elementKind, elementKind.arrayBaseOffset(), index, graph, true); } private SafeReadNode safeReadArrayLength(ValueNode array, long leafGraphId) { @@ -528,6 +532,7 @@ @Override public int convertDeoptAction(DeoptimizationAction action) { + // This must be kept in sync with the DeoptAction enum defined in deoptimization.hpp switch(action) { case None: return 0; case RecompileIfTooManyDeopts: return 1; @@ -540,6 +545,7 @@ @Override public int convertDeoptReason(DeoptimizationReason reason) { + // This must be kept in sync with the DeoptReason enum defined in deoptimization.hpp switch(reason) { case None: return 0; case NullCheckException: return 1; diff -r f043ecb70d3e -r 66ec0bc36a37 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotXirGenerator.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotXirGenerator.java Wed Jul 04 14:57:12 2012 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotXirGenerator.java Wed Jul 04 22:01:03 2012 +0200 @@ -315,7 +315,7 @@ asm.bindInline(resume); asm.pload(target.wordKind, temp1, hub, asm.i(config.instanceHeaderPrototypeOffset), false); - asm.pstore(target.wordKind, result, temp1, false); + asm.pstore(target.wordKind, result, asm.i(config.markOffset), temp1, false); asm.mov(temp1o, hub); // need a temporary register since Intel cannot store 64-bit constants to memory asm.pstore(Kind.Object, result, asm.i(config.hubOffset), temp1o, false); @@ -378,7 +378,7 @@ final int aligning = target.wordSize; final int arrayLengthOffset = target.wordSize * 2; - final int arrayElementOffset = config.getArrayOffset(kind); + final int arrayElementOffset = kind.arrayBaseOffset(); // Calculate aligned size asm.mov(size, length); @@ -401,7 +401,7 @@ // Now the new object is in result, store mark word and klass asm.pload(target.wordKind, temp1, hub, asm.i(config.instanceHeaderPrototypeOffset), false); - asm.pstore(target.wordKind, result, temp1, false); + asm.pstore(target.wordKind, result, asm.i(config.markOffset), temp1, false); asm.mov(temp1o, hub); // need a temporary register since Intel cannot store 64-bit constants to memory asm.pstore(Kind.Object, result, asm.i(config.hubOffset), temp1o, false); diff -r f043ecb70d3e -r 66ec0bc36a37 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CastFromHub.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CastFromHub.java Wed Jul 04 14:57:12 2012 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CastFromHub.java Wed Jul 04 22:01:03 2012 +0200 @@ -32,7 +32,7 @@ import com.oracle.graal.nodes.type.*; /** - * This node is used by the {@link NewInstanceSnippets} to give a formatted new instance its exact type. + * This node is used by the {@link NewObjectSnippets} to give a formatted new instance or object its exact type. */ public final class CastFromHub extends FloatingNode implements Canonicalizable { diff -r f043ecb70d3e -r 66ec0bc36a37 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/InitializeArrayNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/InitializeArrayNode.java Wed Jul 04 22:01:03 2012 +0200 @@ -0,0 +1,77 @@ +/* + * 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.hotspot.nodes; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.nodes.type.*; + +/** + * Initializes the header and body of an uninitialized array cell. + * This node calls out to a stub to do both the allocation and formatting + * if the memory address it is given is zero/null (e.g. due to + * {@linkplain TLABAllocateNode TLAB allocation} failing). + */ +public final class InitializeArrayNode extends FixedWithNextNode implements Lowerable { + + @Input private final ValueNode memory; + @Input private final ValueNode length; + @Input private final ValueNode size; + private final ResolvedJavaType type; + + public InitializeArrayNode(ValueNode memory, ValueNode length, ValueNode size, ResolvedJavaType type) { + super(StampFactory.exactNonNull(type)); + this.memory = memory; + this.type = type; + this.length = length; + this.size = size; + } + + public ValueNode memory() { + return memory; + } + + public ValueNode length() { + return length; + } + + public ValueNode size() { + return size; + } + + public ResolvedJavaType type() { + return type; + } + + @Override + public void lower(LoweringTool tool) { + tool.getRuntime().lower(this, tool); + } + + @SuppressWarnings("unused") + @NodeIntrinsic + public static Object initialize(Object memory, int length, int size, @ConstantNodeParameter ResolvedJavaType type) { + throw new UnsupportedOperationException(); + } +} diff -r f043ecb70d3e -r 66ec0bc36a37 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/InitializeNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/InitializeNode.java Wed Jul 04 14:57:12 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,65 +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.hotspot.nodes; - -import com.oracle.graal.api.meta.*; -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.nodes.type.*; - -/** - * Initializes the header and body of an uninitialized object cell. - * This node calls out to a stub to do both the allocation and formatting - * if the memory address it is given is zero/null (e.g. due to - * {@linkplain TLABAllocateNode TLAB allocation} failing). - */ -public final class InitializeNode extends FixedWithNextNode implements Lowerable { - - @Input private final ValueNode memory; - private final ResolvedJavaType type; - - public InitializeNode(ValueNode memory, ResolvedJavaType type) { - super(StampFactory.exactNonNull(type)); - this.memory = memory; - this.type = type; - } - - public ValueNode memory() { - return memory; - } - - public ResolvedJavaType type() { - return type; - } - - @Override - public void lower(LoweringTool tool) { - tool.getRuntime().lower(this, tool); - } - - @SuppressWarnings("unused") - @NodeIntrinsic - public static Object initialize(Object memory, @ConstantNodeParameter ResolvedJavaType type) { - throw new UnsupportedOperationException(); - } -} diff -r f043ecb70d3e -r 66ec0bc36a37 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/InitializeObjectNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/InitializeObjectNode.java Wed Jul 04 22:01:03 2012 +0200 @@ -0,0 +1,59 @@ +/* + * 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.hotspot.nodes; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.nodes.type.*; + +/** + * Initializes the header and body of an uninitialized object cell. + * This node calls out to a stub to do both the allocation and formatting + * if the memory address it is given is zero/null (e.g. due to + * {@linkplain TLABAllocateNode TLAB allocation} failing). + */ +public final class InitializeObjectNode extends FixedWithNextNode implements Lowerable { + + @Input private final ValueNode memory; + private final ResolvedJavaType type; + + public InitializeObjectNode(ValueNode memory, ResolvedJavaType type) { + super(StampFactory.exactNonNull(type)); + this.memory = memory; + this.type = type; + } + + public ValueNode memory() { + return memory; + } + + public ResolvedJavaType type() { + return type; + } + + @Override + public void lower(LoweringTool tool) { + tool.getRuntime().lower(this, tool); + } +} diff -r f043ecb70d3e -r 66ec0bc36a37 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewArrayStubCall.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewArrayStubCall.java Wed Jul 04 22:01:03 2012 +0200 @@ -0,0 +1,85 @@ +/* + * 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.hotspot.nodes; + +import static com.oracle.graal.hotspot.target.amd64.AMD64NewArrayStubCallOp.*; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.gen.*; +import com.oracle.graal.compiler.target.*; +import com.oracle.graal.hotspot.*; +import com.oracle.graal.hotspot.target.amd64.*; +import com.oracle.graal.lir.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.type.*; + +/** + * Node implementing a call to HotSpot's {@code new_[object|type]_array} stub. + * + * @see AMD64NewArrayStubCallOp + */ +public class NewArrayStubCall extends FixedWithNextNode implements LIRGenLowerable { + + private static final Stamp defaultStamp = StampFactory.objectNonNull(); + + @Input private final ValueNode hub; + @Input private final ValueNode length; + private final boolean isObjectArray; + + public NewArrayStubCall(boolean isObjectArray, ValueNode hub, ValueNode length) { + super(defaultStamp); + this.isObjectArray = isObjectArray; + this.hub = hub; + this.length = length; + } + + @Override + public boolean inferStamp() { + if (stamp() == defaultStamp && hub.isConstant()) { + HotSpotKlassOop klassOop = (HotSpotKlassOop) this.hub.asConstant().asObject(); + updateStamp(StampFactory.exactNonNull(klassOop.type)); + return true; + } + return false; + } + + @Override + public void generate(LIRGenerator gen) { + RegisterValue hubFixed = HUB.asValue(Kind.Object); + RegisterValue lengthFixed = LENGTH.asValue(Kind.Int); + RegisterValue resultFixed = RESULT.asValue(Kind.Object); + gen.emitMove(gen.operand(length), lengthFixed); + gen.emitMove(gen.operand(hub), hubFixed); + LIRFrameState info = gen.state(); + gen.append(new AMD64NewArrayStubCallOp(isObjectArray, resultFixed, hubFixed, lengthFixed, info)); + Variable result = gen.emitMove(resultFixed); + gen.setResult(this, result); + } + + @SuppressWarnings("unused") + @NodeIntrinsic + public static Object call(@ConstantNodeParameter boolean isObjectArray, Object hub, int length) { + throw new UnsupportedOperationException(); + } +} diff -r f043ecb70d3e -r 66ec0bc36a37 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewInstanceStubCall.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewInstanceStubCall.java Wed Jul 04 14:57:12 2012 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewInstanceStubCall.java Wed Jul 04 22:01:03 2012 +0200 @@ -22,15 +22,17 @@ */ package com.oracle.graal.hotspot.nodes; +import static com.oracle.graal.hotspot.target.amd64.AMD64NewInstanceStubCallOp.*; + +import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.gen.*; import com.oracle.graal.compiler.target.*; import com.oracle.graal.hotspot.*; -import com.oracle.graal.hotspot.target.*; +import com.oracle.graal.hotspot.target.amd64.*; import com.oracle.graal.lir.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.type.*; -import com.oracle.max.asm.target.amd64.*; /** * Node implementing a call to HotSpot's {@code new_instance} stub. @@ -60,11 +62,12 @@ @Override public void generate(LIRGenerator gen) { - Variable result = gen.newVariable(Kind.Object); - gen.emitMove(gen.operand(hub), AMD64.rdx.asValue(Kind.Object)); + RegisterValue hubFixed = HUB.asValue(Kind.Object); + RegisterValue resultFixed = RESULT.asValue(Kind.Object); + gen.emitMove(gen.operand(hub), hubFixed); LIRFrameState info = gen.state(); - AMD64NewInstanceStubCallOp op = new AMD64NewInstanceStubCallOp(result, AMD64.rdx.asValue(Kind.Object), info); - gen.append(op); + gen.append(new AMD64NewInstanceStubCallOp(resultFixed, hubFixed, info)); + Variable result = gen.emitMove(resultFixed); gen.setResult(this, result); } diff -r f043ecb70d3e -r 66ec0bc36a37 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/TLABAllocateNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/TLABAllocateNode.java Wed Jul 04 14:57:12 2012 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/TLABAllocateNode.java Wed Jul 04 22:01:03 2012 +0200 @@ -22,6 +22,8 @@ */ package com.oracle.graal.hotspot.nodes; +import java.util.*; + import com.oracle.graal.api.meta.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; @@ -35,27 +37,61 @@ public final class TLABAllocateNode extends FixedWithNextNode implements Lowerable { private final int size; + @Input private ValueNode sizeNode; public TLABAllocateNode(int size, Kind wordKind) { super(StampFactory.forWord(wordKind, true)); this.size = size; + this.sizeNode = null; + } + + public TLABAllocateNode(Kind wordKind, ValueNode size) { + super(StampFactory.forWord(wordKind, true)); + this.size = -1; + this.sizeNode = size; } - public int size() { + public boolean isSizeConstant() { + return sizeNode == null; + } + + public int constantSize() { + assert isSizeConstant(); return size; } + public ValueNode variableSize() { + assert !isSizeConstant(); + return sizeNode; + } + @Override public void lower(LoweringTool tool) { tool.getRuntime().lower(this, tool); } + @Override + public Map getDebugProperties() { + Map debugProperties = super.getDebugProperties(); + debugProperties.put("size", String.valueOf(size)); + return debugProperties; + } + /** * @return null if allocation fails */ @SuppressWarnings("unused") @NodeIntrinsic - public static Word allocate(@ConstantNodeParameter int size, @ConstantNodeParameter Kind wordKind) { + public static Word allocateConstantSize(@ConstantNodeParameter int size, @ConstantNodeParameter Kind wordKind) { + throw new UnsupportedOperationException(); + } + + /** + * @return null if allocation fails + */ + @SuppressWarnings("unused") + @NodeIntrinsic + public static Word allocateVariableSize(@ConstantNodeParameter Kind wordKind, int size) { throw new UnsupportedOperationException(); } } diff -r f043ecb70d3e -r 66ec0bc36a37 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/VerifyOopStubCall.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/VerifyOopStubCall.java Wed Jul 04 14:57:12 2012 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/VerifyOopStubCall.java Wed Jul 04 22:01:03 2012 +0200 @@ -22,9 +22,13 @@ */ package com.oracle.graal.hotspot.nodes; +import static com.oracle.graal.hotspot.target.amd64.AMD64VerifyOopStubCallOp.*; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.gen.*; import com.oracle.graal.compiler.target.*; -import com.oracle.graal.hotspot.target.*; +import com.oracle.graal.hotspot.target.amd64.*; import com.oracle.graal.lir.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.type.*; @@ -45,9 +49,10 @@ @Override public void generate(LIRGenerator gen) { + RegisterValue objectFixed = OBJECT.asValue(Kind.Object); + gen.emitMove(gen.operand(object), objectFixed); LIRFrameState info = gen.state(); - AMD64VerifyOopStubCallOp op = new AMD64VerifyOopStubCallOp(gen.operand(object), info); - gen.append(op); + gen.append(new AMD64VerifyOopStubCallOp(gen.operand(object), info)); } @SuppressWarnings("unused") diff -r f043ecb70d3e -r 66ec0bc36a37 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/ArrayCopySnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/ArrayCopySnippets.java Wed Jul 04 14:57:12 2012 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/ArrayCopySnippets.java Wed Jul 04 22:01:03 2012 +0200 @@ -312,12 +312,12 @@ if (src == dest && srcPos < destPos) { // bad aliased case for (long i = (length - 1) * scale; i >= 0; i -= scale) { Object a = UnsafeLoadNode.load(src, header, i + (long) srcPos * scale, Kind.Object); - DirectObjectStoreNode.store(dest, header, i + (long) destPos * scale, a); + DirectObjectStoreNode.storeObject(dest, header, i + (long) destPos * scale, a); } } else { for (long i = 0; i < length * scale; i += scale) { Object a = UnsafeLoadNode.load(src, header, i + (long) srcPos * scale, Kind.Object); - DirectObjectStoreNode.store(dest, header, i + (long) destPos * scale, a); + DirectObjectStoreNode.storeObject(dest, header, i + (long) destPos * scale, a); } } if (length > 0) { diff -r f043ecb70d3e -r 66ec0bc36a37 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/CheckCastSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/CheckCastSnippets.java Wed Jul 04 14:57:12 2012 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/CheckCastSnippets.java Wed Jul 04 22:01:03 2012 +0200 @@ -174,7 +174,7 @@ for (int i = 0; i < secondarySupers.length; i++) { if (t == loadNonNullObjectElement(secondarySupers, i)) { - DirectObjectStoreNode.store(s, secondarySuperCacheOffset(), 0, t); + DirectObjectStoreNode.storeObject(s, secondarySuperCacheOffset(), 0, t); secondariesHit.inc(); return true; } @@ -214,7 +214,7 @@ Object[] secondarySupers = UnsafeCastNode.cast(UnsafeLoadNode.loadObject(s, 0, secondarySupersOffset(), true), Object[].class); for (int i = 0; i < secondarySupers.length; i++) { if (t == loadNonNullObjectElement(secondarySupers, i)) { - DirectObjectStoreNode.store(s, secondarySuperCacheOffset(), 0, t); + DirectObjectStoreNode.storeObject(s, secondarySuperCacheOffset(), 0, t); secondariesHit.inc(); return true; } @@ -264,7 +264,7 @@ */ void inc() { if (ENABLED) { - DirectObjectStoreNode.store(this, countOffset(), 0, count + 1); + DirectObjectStoreNode.storeLong(this, countOffset(), 0, count + 1); } } diff -r f043ecb70d3e -r 66ec0bc36a37 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/DirectObjectStoreNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/DirectObjectStoreNode.java Wed Jul 04 14:57:12 2012 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/DirectObjectStoreNode.java Wed Jul 04 22:01:03 2012 +0200 @@ -26,6 +26,7 @@ import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; +import com.oracle.graal.snippets.*; /** * A special purpose store node that differs from {@link UnsafeStoreNode} in that @@ -47,13 +48,25 @@ @SuppressWarnings("unused") @NodeIntrinsic - public static void store(Object obj, @ConstantNodeParameter int displacement, long offset, Object value) { + public static void storeObject(Object obj, @ConstantNodeParameter int displacement, long offset, Object value) { throw new UnsupportedOperationException(); } @SuppressWarnings("unused") @NodeIntrinsic - public static void store(Object obj, @ConstantNodeParameter int displacement, long offset, long value) { + public static void storeLong(Object obj, @ConstantNodeParameter int displacement, long offset, long value) { + throw new UnsupportedOperationException(); + } + + @SuppressWarnings("unused") + @NodeIntrinsic + public static void storeWord(Object obj, @ConstantNodeParameter int displacement, long offset, Word value) { + throw new UnsupportedOperationException(); + } + + @SuppressWarnings("unused") + @NodeIntrinsic + public static void storeInt(Object obj, @ConstantNodeParameter int displacement, long offset, int value) { throw new UnsupportedOperationException(); } diff -r f043ecb70d3e -r 66ec0bc36a37 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/NewInstanceSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/NewInstanceSnippets.java Wed Jul 04 14:57:12 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,229 +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.hotspot.snippets; - -import static com.oracle.graal.hotspot.nodes.CastFromHub.*; -import static com.oracle.graal.hotspot.nodes.RegisterNode.*; -import static com.oracle.graal.hotspot.snippets.DirectObjectStoreNode.*; -import static com.oracle.graal.nodes.extended.UnsafeLoadNode.*; -import static com.oracle.graal.snippets.SnippetTemplate.Arguments.*; -import static com.oracle.graal.snippets.nodes.ExplodeLoopNode.*; -import static com.oracle.max.asm.target.amd64.AMD64.*; - -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.hotspot.*; -import com.oracle.graal.hotspot.meta.*; -import com.oracle.graal.hotspot.nodes.*; -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.java.*; -import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.snippets.*; -import com.oracle.graal.snippets.Snippet.ConstantParameter; -import com.oracle.graal.snippets.Snippet.Fold; -import com.oracle.graal.snippets.Snippet.Parameter; -import com.oracle.graal.snippets.SnippetTemplate.Arguments; -import com.oracle.graal.snippets.SnippetTemplate.Cache; -import com.oracle.graal.snippets.SnippetTemplate.Key; - -/** - * Snippets used for implementing NEW. - */ -public class NewInstanceSnippets implements SnippetsInterface { - - @Snippet - public static Word allocate(@ConstantParameter("size") int size) { - Word thread = asWord(register(r15, wordKind())); - Word top = loadWord(thread, threadTlabTopOffset()); - Word end = loadWord(thread, threadTlabEndOffset()); - Word newTop = top.plus(size); - if (newTop.belowOrEqual(end)) { - store(thread, 0, threadTlabTopOffset(), newTop); - return top; - } - return Word.zero(); - } - - @Snippet - public static Object initialize( - @Parameter("memory") Word memory, - @Parameter("hub") Object hub, - @Parameter("prototypeHeader") Word headerPrototype, - @ConstantParameter("size") int size) { - - if (memory == Word.zero()) { - return NewInstanceStubCall.call(hub); - } - formatObject(hub, size, memory, headerPrototype); - Object instance = memory.toObject(); - return castFromHub(verifyOop(instance), hub); - } - - private static Object verifyOop(Object object) { - if (verifyOops()) { - VerifyOopStubCall.call(object); - } - return object; - } - - private static Word asWord(Object object) { - return Word.fromObject(object); - } - - private static Word loadWord(Word address, int offset) { - Object value = loadObject(address, 0, offset, true); - return asWord(value); - } - - /** - * Maximum size of an object whose body is initialized by a sequence of - * zero-stores to its fields. Larger objects have their bodies initialized - * in a loop. - */ - private static final int MAX_UNROLLED_OBJECT_INITIALIZATION_SIZE = 10 * wordSize(); - - /** - * Formats some allocated memory with an object header zeroes out the rest. - */ - private static void formatObject(Object hub, int size, Word memory, Word headerPrototype) { - store(memory, 0, 0, headerPrototype); - store(memory, 0, hubOffset(), hub); - if (size <= MAX_UNROLLED_OBJECT_INITIALIZATION_SIZE) { - explodeLoop(); - for (int offset = 2 * wordSize(); offset < size; offset += wordSize()) { - store(memory, 0, offset, 0); - } - } else { - for (int offset = 2 * wordSize(); offset < size; offset += wordSize()) { - store(memory, 0, offset, 0); - } - } - } - - @Fold - private static boolean verifyOops() { - return HotSpotGraalRuntime.getInstance().getConfig().verifyOops; - } - - @Fold - private static int threadTlabTopOffset() { - return HotSpotGraalRuntime.getInstance().getConfig().threadTlabTopOffset; - } - - @Fold - private static int threadTlabEndOffset() { - return HotSpotGraalRuntime.getInstance().getConfig().threadTlabEndOffset; - } - - @Fold - private static Kind wordKind() { - return HotSpotGraalRuntime.getInstance().getTarget().wordKind; - } - - @Fold - private static int wordSize() { - return HotSpotGraalRuntime.getInstance().getTarget().wordSize; - } - - @Fold - private static int hubOffset() { - return HotSpotGraalRuntime.getInstance().getConfig().hubOffset; - } - - public static class Templates { - - private final Cache cache; - private final ResolvedJavaMethod allocate; - private final ResolvedJavaMethod initialize; - private final CodeCacheProvider runtime; - private final boolean useTLAB; - - public Templates(CodeCacheProvider runtime, boolean useTLAB) { - this.runtime = runtime; - this.cache = new Cache(runtime); - this.useTLAB = useTLAB; - try { - allocate = runtime.getResolvedJavaMethod(NewInstanceSnippets.class.getDeclaredMethod("allocate", int.class)); - initialize = runtime.getResolvedJavaMethod(NewInstanceSnippets.class.getDeclaredMethod("initialize", Word.class, Object.class, Word.class, int.class)); - } catch (NoSuchMethodException e) { - throw new GraalInternalError(e); - } - } - - /** - * Lowers a {@link NewInstanceNode}. - */ - @SuppressWarnings("unused") - public void lower(NewInstanceNode newInstanceNode, LoweringTool tool) { - StructuredGraph graph = (StructuredGraph) newInstanceNode.graph(); - HotSpotResolvedJavaType type = (HotSpotResolvedJavaType) newInstanceNode.instanceClass(); - HotSpotKlassOop hub = type.klassOop(); - int size = type.instanceSize(); - assert (size % wordSize()) == 0; - assert size >= 0; - - ValueNode memory; - if (!useTLAB) { - memory = ConstantNode.forObject(null, runtime, graph); - } else { - TLABAllocateNode tlabAllocateNode = graph.add(new TLABAllocateNode(size, wordKind())); - graph.addBeforeFixed(newInstanceNode, tlabAllocateNode); - memory = tlabAllocateNode; - } - InitializeNode initializeNode = graph.add(new InitializeNode(memory, type)); - graph.replaceFixedWithFixed(newInstanceNode, initializeNode); - } - - @SuppressWarnings("unused") - public void lower(TLABAllocateNode tlabAllocateNode, LoweringTool tool) { - StructuredGraph graph = (StructuredGraph) tlabAllocateNode.graph(); - int size = tlabAllocateNode.size(); - assert (size % wordSize()) == 0; - assert size >= 0; - Key key = new Key(allocate).add("size", size); - Arguments arguments = new Arguments(); - SnippetTemplate template = cache.get(key); - Debug.log("Lowering fastAllocate in %s: node=%s, template=%s, arguments=%s", graph, tlabAllocateNode, template, arguments); - template.instantiate(runtime, tlabAllocateNode, tlabAllocateNode, arguments); - } - - @SuppressWarnings("unused") - public void lower(InitializeNode initializeNode, LoweringTool tool) { - StructuredGraph graph = (StructuredGraph) initializeNode.graph(); - HotSpotResolvedJavaType type = (HotSpotResolvedJavaType) initializeNode.type(); - HotSpotKlassOop hub = type.klassOop(); - int size = type.instanceSize(); - assert (size % wordSize()) == 0; - assert size >= 0; - Key key = new Key(initialize).add("size", size); - ValueNode memory = initializeNode.memory(); - //assert memory instanceof AllocateNode || memory instanceof ConstantNode : memory; - Arguments arguments = arguments("memory", memory).add("hub", hub).add("prototypeHeader", type.prototypeHeader()); - SnippetTemplate template = cache.get(key); - Debug.log("Lowering initialize in %s: node=%s, template=%s, arguments=%s", graph, initializeNode, template, arguments); - template.instantiate(runtime, initializeNode, initializeNode, arguments); - } - } -} diff -r f043ecb70d3e -r 66ec0bc36a37 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/NewObjectSnippets.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/NewObjectSnippets.java Wed Jul 04 22:01:03 2012 +0200 @@ -0,0 +1,383 @@ +/* + * 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.hotspot.snippets; + +import static com.oracle.graal.hotspot.nodes.CastFromHub.*; +import static com.oracle.graal.hotspot.nodes.RegisterNode.*; +import static com.oracle.graal.hotspot.snippets.DirectObjectStoreNode.*; +import static com.oracle.graal.nodes.extended.UnsafeLoadNode.*; +import static com.oracle.graal.snippets.SnippetTemplate.Arguments.*; +import static com.oracle.graal.snippets.nodes.ExplodeLoopNode.*; +import static com.oracle.max.asm.target.amd64.AMD64.*; +import static com.oracle.max.criutils.UnsignedMath.*; + +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.hotspot.*; +import com.oracle.graal.hotspot.meta.*; +import com.oracle.graal.hotspot.nodes.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.java.*; +import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.snippets.*; +import com.oracle.graal.snippets.Snippet.ConstantParameter; +import com.oracle.graal.snippets.Snippet.Fold; +import com.oracle.graal.snippets.Snippet.Parameter; +import com.oracle.graal.snippets.SnippetTemplate.Arguments; +import com.oracle.graal.snippets.SnippetTemplate.Cache; +import com.oracle.graal.snippets.SnippetTemplate.Key; + +/** + * Snippets used for implementing NEW, ANEWARRAY and NEWARRAY. + */ +public class NewObjectSnippets implements SnippetsInterface { + + @Snippet + public static Word allocate(@Parameter("size") int size) { + Word thread = asWord(register(r15, wordKind())); + Word top = loadWord(thread, threadTlabTopOffset()); + Word end = loadWord(thread, threadTlabEndOffset()); + Word newTop = top.plus(size); + if (newTop.belowOrEqual(end)) { + storeObject(thread, 0, threadTlabTopOffset(), newTop); + return top; + } + return Word.zero(); + } + + @Snippet + public static Object initializeObject( + @Parameter("memory") Word memory, + @Parameter("hub") Object hub, + @Parameter("initialMarkWord") Word initialMarkWord, + @ConstantParameter("size") int size) { + + if (memory == Word.zero()) { + return NewInstanceStubCall.call(hub); + } + formatObject(hub, size, memory, initialMarkWord); + Object instance = memory.toObject(); + return castFromHub(verifyOop(instance), hub); + } + + @Snippet + public static Object initializeObjectArray( + @Parameter("memory") Word memory, + @Parameter("hub") Object hub, + @Parameter("length") int length, + @Parameter("size") int size, + @Parameter("initialMarkWord") Word initialMarkWord, + @ConstantParameter("headerSize") int headerSize) { + return initializeArray(memory, hub, length, size, initialMarkWord, headerSize, true); + } + + @Snippet + public static Object initializePrimitiveArray( + @Parameter("memory") Word memory, + @Parameter("hub") Object hub, + @Parameter("length") int length, + @Parameter("size") int size, + @Parameter("initialMarkWord") Word initialMarkWord, + @ConstantParameter("headerSize") int headerSize) { + return initializeArray(memory, hub, length, size, initialMarkWord, headerSize, false); + } + + private static Object initializeArray(Word memory, Object hub, int length, int size, Word initialMarkWord, int headerSize, boolean isObjectArray) { + if (memory == Word.zero()) { + return NewArrayStubCall.call(isObjectArray, hub, length); + } + formatArray(hub, size, length, headerSize, memory, initialMarkWord); + Object instance = memory.toObject(); + return castFromHub(verifyOop(instance), hub); + } + + /** + * Maximum array length for which fast path allocation is used. + */ + private static final int MAX_ARRAY_FAST_PATH_ALLOCATION_LENGTH = 0x00FFFFFF; + + @Snippet + public static Object allocateArrayAndInitialize( + @Parameter("length") int length, + @ConstantParameter("alignment") int alignment, + @ConstantParameter("headerSize") int headerSize, + @ConstantParameter("log2ElementSize") int log2ElementSize, + @ConstantParameter("type") ResolvedJavaType type, + @ConstantParameter("wordKind") Kind wordKind) { + if (!belowThan(length, MAX_ARRAY_FAST_PATH_ALLOCATION_LENGTH)) { + // This handles both negative array sizes and very large array sizes + DeoptimizeNode.deopt(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.RuntimeConstraint); + } + int size = getArraySize(length, alignment, headerSize, log2ElementSize); + Word memory = TLABAllocateNode.allocateVariableSize(wordKind, size); + return InitializeArrayNode.initialize(memory, length, size, type); + } + + public static int getArraySize(int length, int alignment, int headerSize, int log2ElementSize) { + int size = (length << log2ElementSize) + headerSize + (alignment - 1); + int mask = ~(alignment - 1); + return size & mask; + } + + private static Object verifyOop(Object object) { + if (verifyOops()) { + VerifyOopStubCall.call(object); + } + return object; + } + + private static Word asWord(Object object) { + return Word.fromObject(object); + } + + private static Word loadWord(Word address, int offset) { + Object value = loadObject(address, 0, offset, true); + return asWord(value); + } + + /** + * Maximum size of an object whose body is initialized by a sequence of + * zero-stores to its fields. Larger objects have their bodies initialized + * in a loop. + */ + private static final int MAX_UNROLLED_OBJECT_ZEROING_SIZE = 10 * wordSize(); + + /** + * Formats some allocated memory with an object header zeroes out the rest. + */ + private static void formatObject(Object hub, int size, Word memory, Word headerPrototype) { + storeObject(memory, 0, markOffset(), headerPrototype); + storeObject(memory, 0, hubOffset(), hub); + if (size <= MAX_UNROLLED_OBJECT_ZEROING_SIZE) { + explodeLoop(); + for (int offset = 2 * wordSize(); offset < size; offset += wordSize()) { + storeWord(memory, 0, offset, Word.zero()); + } + } else { + for (int offset = 2 * wordSize(); offset < size; offset += wordSize()) { + storeWord(memory, 0, offset, Word.zero()); + } + } + } + + /** + * Formats some allocated memory with an object header zeroes out the rest. + */ + private static void formatArray(Object hub, int size, int length, int headerSize, Word memory, Word headerPrototype) { + storeObject(memory, 0, markOffset(), headerPrototype); + storeObject(memory, 0, hubOffset(), hub); + storeInt(memory, 0, arrayLengthOffset(), length); + for (int offset = headerSize; offset < size; offset += wordSize()) { + storeWord(memory, 0, offset, Word.zero()); + } + } + + public static class Templates { + + private final Cache cache; + private final ResolvedJavaMethod allocate; + private final ResolvedJavaMethod initializeObject; + private final ResolvedJavaMethod initializeObjectArray; + private final ResolvedJavaMethod initializePrimitiveArray; + private final ResolvedJavaMethod allocateArrayAndInitialize; + private final TargetDescription target; + private final CodeCacheProvider runtime; + private final boolean useTLAB; + + public Templates(CodeCacheProvider runtime, TargetDescription target, boolean useTLAB) { + this.runtime = runtime; + this.target = target; + this.cache = new Cache(runtime); + this.useTLAB = useTLAB; + try { + allocate = runtime.getResolvedJavaMethod(NewObjectSnippets.class.getDeclaredMethod("allocate", int.class)); + initializeObject = runtime.getResolvedJavaMethod(NewObjectSnippets.class.getDeclaredMethod("initializeObject", Word.class, Object.class, Word.class, int.class)); + initializeObjectArray = runtime.getResolvedJavaMethod(NewObjectSnippets.class.getDeclaredMethod("initializeObjectArray", Word.class, Object.class, int.class, int.class, Word.class, int.class)); + initializePrimitiveArray = runtime.getResolvedJavaMethod(NewObjectSnippets.class.getDeclaredMethod("initializePrimitiveArray", Word.class, Object.class, int.class, int.class, Word.class, int.class)); + allocateArrayAndInitialize = runtime.getResolvedJavaMethod(NewObjectSnippets.class.getDeclaredMethod("allocateArrayAndInitialize", int.class, int.class, int.class, int.class, ResolvedJavaType.class, Kind.class)); + } catch (NoSuchMethodException e) { + throw new GraalInternalError(e); + } + } + + /** + * Lowers a {@link NewInstanceNode}. + */ + @SuppressWarnings("unused") + public void lower(NewInstanceNode newInstanceNode, LoweringTool tool) { + StructuredGraph graph = (StructuredGraph) newInstanceNode.graph(); + HotSpotResolvedJavaType type = (HotSpotResolvedJavaType) newInstanceNode.instanceClass(); + HotSpotKlassOop hub = type.klassOop(); + int size = type.instanceSize(); + assert (size % wordSize()) == 0; + assert size >= 0; + + ValueNode memory; + if (!useTLAB) { + memory = ConstantNode.forConstant(new Constant(target.wordKind, 0L), runtime, graph); + } else { + TLABAllocateNode tlabAllocateNode = graph.add(new TLABAllocateNode(size, wordKind())); + graph.addBeforeFixed(newInstanceNode, tlabAllocateNode); + memory = tlabAllocateNode; + } + InitializeObjectNode initializeNode = graph.add(new InitializeObjectNode(memory, type)); + graph.replaceFixedWithFixed(newInstanceNode, initializeNode); + } + + /** + * Lowers a {@link NewArrayNode}. + */ + @SuppressWarnings("unused") + public void lower(NewArrayNode newArrayNode, LoweringTool tool) { + StructuredGraph graph = (StructuredGraph) newArrayNode.graph(); + ValueNode lengthNode = newArrayNode.length(); + TLABAllocateNode tlabAllocateNode; + ResolvedJavaType elementType = newArrayNode.elementType(); + ResolvedJavaType arrayType = elementType.arrayOf(); + Kind elementKind = elementType.kind(); + final int alignment = target.wordSize; + final int headerSize = elementKind.arrayBaseOffset(); + final Integer length = lengthNode.isConstant() ? Integer.valueOf(lengthNode.asConstant().asInt()) : null; + int log2ElementSize = CodeUtil.log2(target.sizeInBytes(elementKind)); + if (!useTLAB) { + ConstantNode zero = ConstantNode.forConstant(new Constant(target.wordKind, 0L), runtime, graph); + // value for 'size' doesn't matter as it isn't used since a stub call will be made anyway + // for both allocation and initialization - it just needs to be non-null + ConstantNode size = ConstantNode.forInt(-1, graph); + InitializeArrayNode initializeNode = graph.add(new InitializeArrayNode(zero, lengthNode, size, arrayType)); + graph.replaceFixedWithFixed(newArrayNode, initializeNode); + } else if (length != null && belowThan(length, MAX_ARRAY_FAST_PATH_ALLOCATION_LENGTH)) { + // Calculate aligned size + int size = getArraySize(length, alignment, headerSize, log2ElementSize); + ConstantNode sizeNode = ConstantNode.forInt(size, graph); + tlabAllocateNode = graph.add(new TLABAllocateNode(size, target.wordKind)); + graph.addBeforeFixed(newArrayNode, tlabAllocateNode); + InitializeArrayNode initializeNode = graph.add(new InitializeArrayNode(tlabAllocateNode, lengthNode, sizeNode, arrayType)); + graph.replaceFixedWithFixed(newArrayNode, initializeNode); + } else { + Key key = new Key(allocateArrayAndInitialize). + add("alignment", alignment). + add("headerSize", headerSize). + add("log2ElementSize", log2ElementSize). + add("wordKind", target.wordKind). + add("type", arrayType); + Arguments arguments = new Arguments().add("length", lengthNode); + SnippetTemplate template = cache.get(key); + Debug.log("Lowering allocateArrayAndInitialize in %s: node=%s, template=%s, arguments=%s", graph, newArrayNode, template, arguments); + template.instantiate(runtime, newArrayNode, newArrayNode, arguments); + } + } + + @SuppressWarnings("unused") + public void lower(TLABAllocateNode tlabAllocateNode, LoweringTool tool) { + StructuredGraph graph = (StructuredGraph) tlabAllocateNode.graph(); + ValueNode size; + if (tlabAllocateNode.isSizeConstant()) { + size = ConstantNode.forInt(tlabAllocateNode.constantSize(), graph); + } else { + size = tlabAllocateNode.variableSize(); + } + Key key = new Key(allocate); + Arguments arguments = arguments("size", size); + SnippetTemplate template = cache.get(key); + Debug.log("Lowering fastAllocate in %s: node=%s, template=%s, arguments=%s", graph, tlabAllocateNode, template, arguments); + template.instantiate(runtime, tlabAllocateNode, tlabAllocateNode, arguments); + } + + @SuppressWarnings("unused") + public void lower(InitializeObjectNode initializeNode, LoweringTool tool) { + StructuredGraph graph = (StructuredGraph) initializeNode.graph(); + HotSpotResolvedJavaType type = (HotSpotResolvedJavaType) initializeNode.type(); + assert !type.isArrayClass(); + HotSpotKlassOop hub = type.klassOop(); + int size = type.instanceSize(); + assert (size % wordSize()) == 0; + assert size >= 0; + Key key = new Key(initializeObject).add("size", size); + ValueNode memory = initializeNode.memory(); + Arguments arguments = arguments("memory", memory).add("hub", hub).add("initialMarkWord", type.initialMarkWord()); + SnippetTemplate template = cache.get(key); + Debug.log("Lowering initializeObject in %s: node=%s, template=%s, arguments=%s", graph, initializeNode, template, arguments); + template.instantiate(runtime, initializeNode, initializeNode, arguments); + } + + @SuppressWarnings("unused") + public void lower(InitializeArrayNode initializeNode, LoweringTool tool) { + StructuredGraph graph = (StructuredGraph) initializeNode.graph(); + HotSpotResolvedJavaType type = (HotSpotResolvedJavaType) initializeNode.type(); + ResolvedJavaType elementType = type.componentType(); + assert elementType != null; + HotSpotKlassOop hub = type.klassOop(); + Kind elementKind = elementType.kind(); + final int headerSize = elementKind.arrayBaseOffset(); + Key key = new Key(elementKind.isObject() ? initializeObjectArray : initializePrimitiveArray).add("headerSize", headerSize); + ValueNode memory = initializeNode.memory(); + Arguments arguments = arguments("memory", memory).add("hub", hub).add("initialMarkWord", type.initialMarkWord()).add("size", initializeNode.size()).add("length", initializeNode.length()); + SnippetTemplate template = cache.get(key); + Debug.log("Lowering initializeObjectArray in %s: node=%s, template=%s, arguments=%s", graph, initializeNode, template, arguments); + template.instantiate(runtime, initializeNode, initializeNode, arguments); + } + } + + @Fold + private static boolean verifyOops() { + return HotSpotGraalRuntime.getInstance().getConfig().verifyOops; + } + + @Fold + private static int threadTlabTopOffset() { + return HotSpotGraalRuntime.getInstance().getConfig().threadTlabTopOffset; + } + + @Fold + private static int threadTlabEndOffset() { + return HotSpotGraalRuntime.getInstance().getConfig().threadTlabEndOffset; + } + + @Fold + private static Kind wordKind() { + return HotSpotGraalRuntime.getInstance().getTarget().wordKind; + } + + @Fold + private static int wordSize() { + return HotSpotGraalRuntime.getInstance().getTarget().wordSize; + } + + @Fold + private static int markOffset() { + return HotSpotGraalRuntime.getInstance().getConfig().markOffset; + } + + @Fold + private static int hubOffset() { + return HotSpotGraalRuntime.getInstance().getConfig().hubOffset; + } + + @Fold + private static int arrayLengthOffset() { + return HotSpotGraalRuntime.getInstance().getConfig().arrayLengthOffset; + } +} diff -r f043ecb70d3e -r 66ec0bc36a37 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/UnsignedMathSnippets.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/UnsignedMathSnippets.java Wed Jul 04 22:01:03 2012 +0200 @@ -0,0 +1,86 @@ +/* + * 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.snippets; + +import static com.oracle.graal.nodes.MaterializeNode.*; +import static com.oracle.graal.nodes.calc.Condition.*; + +import com.oracle.graal.snippets.*; +import com.oracle.max.criutils.*; + +/** + * Snippets for {@link UnsignedMath}. + */ +@ClassSubstitution(UnsignedMath.class) +public class UnsignedMathSnippets implements SnippetsInterface { + + public static boolean aboveThan(int a, int b) { + return materialize(BT, b, a); + } + + public static boolean aboveOrEqual(int a, int b) { + return !materialize(BT, a, b); + } + + /** + * Unsigned comparison belowThan for two numbers. + */ + public static boolean belowThan(int a, int b) { + return materialize(BT, a, b); + } + + /** + * Unsigned comparison belowOrEqual for two numbers. + */ + public static boolean belowOrEqual(int a, int b) { + return !materialize(BT, b, a); + } + + /** + * Unsigned comparison aboveThan for two numbers. + */ + public static boolean aboveThan(long a, long b) { + return materialize(BT, b, a); + } + + /** + * Unsigned comparison aboveOrEqual for two numbers. + */ + public static boolean aboveOrEqual(long a, long b) { + return !materialize(BT, a, b); + } + + /** + * Unsigned comparison belowThan for two numbers. + */ + public static boolean belowThan(long a, long b) { + return materialize(BT, a, b); + } + + /** + * Unsigned comparison belowOrEqual for two numbers. + */ + public static boolean belowOrEqual(long a, long b) { + return !materialize(BT, b, a); + } +} diff -r f043ecb70d3e -r 66ec0bc36a37 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/target/AMD64NewInstanceStubCallOp.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/target/AMD64NewInstanceStubCallOp.java Wed Jul 04 14:57:12 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,68 +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.hotspot.target; - -import static com.oracle.graal.api.code.ValueUtil.*; - -import com.oracle.graal.api.meta.*; -import com.oracle.graal.hotspot.*; -import com.oracle.graal.lir.*; -import com.oracle.graal.lir.amd64.*; -import com.oracle.graal.lir.asm.*; -import com.oracle.max.asm.target.amd64.*; -import com.oracle.graal.lir.LIRInstruction.Opcode; - -/** - * LIR instruction for calling HotSpot's {@code new_instance} stub. This stub is declared in c1_Runtime1.hpp - * and implemented in Runtime1::generate_code_for() which is located in c1_Runtime1_x86.cpp. - */ -@Opcode("NEW_INSTANCE") -public class AMD64NewInstanceStubCallOp extends AMD64LIRInstruction { - @Def protected Value result; - @Use protected Value hub; - @Temp protected Value temp; - @State protected LIRFrameState state; - - public AMD64NewInstanceStubCallOp(Value result, Value hub, LIRFrameState state) { - this.result = result; - this.hub = hub; - this.temp = AMD64.rax.asValue(Kind.Object); - this.state = state; - } - - @Override - public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) { - // rdx: (in) hub - // rax: (out) result - AMD64Call.directCall(tasm, masm, HotSpotGraalRuntime.getInstance().getConfig().newInstanceStub, state); - if (asRegister(result) != AMD64.rax) { - masm.movq(asRegister(result), AMD64.rax); - } - } - - @Override - protected void verify() { - super.verify(); - assert asRegister(hub) == AMD64.rdx; - } -} diff -r f043ecb70d3e -r 66ec0bc36a37 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/target/AMD64VerifyOopStubCallOp.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/target/AMD64VerifyOopStubCallOp.java Wed Jul 04 14:57:12 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,60 +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.hotspot.target; - -import static com.oracle.graal.api.code.ValueUtil.*; - -import com.oracle.graal.api.meta.*; -import com.oracle.graal.hotspot.*; -import com.oracle.graal.lir.*; -import com.oracle.graal.lir.LIRInstruction.Opcode; -import com.oracle.graal.lir.amd64.*; -import com.oracle.graal.lir.asm.*; -import com.oracle.max.asm.target.amd64.*; - -/** - * A call to HotSpot's object pointer verification stub. - */ -@Opcode("VERIFY_OOP") -public class AMD64VerifyOopStubCallOp extends AMD64LIRInstruction { - @Use protected Value object; - @State protected LIRFrameState state; - - public AMD64VerifyOopStubCallOp(Value object, LIRFrameState state) { - this.object = object; - this.state = state; - } - - @Override - public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) { - // r13: (in) object - if (asRegister(object) != AMD64.r13) { - masm.push(AMD64.r13); - masm.movq(AMD64.r13, asRegister(object)); - } - AMD64Call.directCall(tasm, masm, HotSpotGraalRuntime.getInstance().getConfig().verifyOopStub, state); - if (asRegister(object) != AMD64.r13) { - masm.pop(AMD64.r13); - } - } -} diff -r f043ecb70d3e -r 66ec0bc36a37 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/target/amd64/AMD64NewArrayStubCallOp.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/target/amd64/AMD64NewArrayStubCallOp.java Wed Jul 04 22:01:03 2012 +0200 @@ -0,0 +1,98 @@ +/* + * 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.hotspot.target.amd64; + +import static com.oracle.graal.api.code.ValueUtil.*; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.hotspot.*; +import com.oracle.graal.lir.*; +import com.oracle.graal.lir.LIRInstruction.Opcode; +import com.oracle.graal.lir.amd64.*; +import com.oracle.graal.lir.asm.*; +import com.oracle.max.asm.target.amd64.*; + +/** + * LIR instruction for calling HotSpot's {@code new_[object|type]_array} stub. This stub is declared in c1_Runtime1.hpp + * and implemented in Runtime1::generate_code_for() which is located in c1_Runtime1_x86.cpp. + */ +@Opcode("NEW_ARRAY") +public class AMD64NewArrayStubCallOp extends AMD64LIRInstruction { + + /** + * The stub places the result in RAX. + */ + public static final Register RESULT = AMD64.rax; + + /** + * The stub expects the hub in RDX. + */ + public static final Register HUB = AMD64.rdx; + + /** + * The stub expects the length in RBX. + */ + public static final Register LENGTH = AMD64.rbx; + + /** + * The stub uses RCX, RSI, and RDI as temps. + */ + public static final Register[] TEMPS = {AMD64.rcx, AMD64.rdi, AMD64.rsi}; + + private final boolean isObjectArray; + + @Def protected Value result; + @Use protected Value hub; + @Use protected Value length; + @Temp protected Value[] temps; + + @State protected LIRFrameState state; + + public AMD64NewArrayStubCallOp(boolean isObjectArray, Value result, Value hub, Value length, LIRFrameState state) { + this.isObjectArray = isObjectArray; + this.result = result; + this.hub = hub; + this.length = length; + this.temps = new Value[TEMPS.length]; + for (int i = 0; i < temps.length; i++) { + temps[i] = TEMPS[i].asValue(Kind.Long); + } + this.state = state; + } + + @Override + public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) { + HotSpotVMConfig config = HotSpotGraalRuntime.getInstance().getConfig(); + long stub = isObjectArray ? config.newObjectArrayStub : config.newTypeArrayStub; + AMD64Call.directCall(tasm, masm, stub, state); + } + + @Override + protected void verify() { + super.verify(); + assert asRegister(hub) == HUB : "stub expects hub in " + HUB; + assert asRegister(length) == LENGTH : "stub expect length in " + LENGTH; + assert asRegister(result) == RESULT : "stub places result in " + RESULT; + } +} diff -r f043ecb70d3e -r 66ec0bc36a37 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/target/amd64/AMD64NewInstanceStubCallOp.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/target/amd64/AMD64NewInstanceStubCallOp.java Wed Jul 04 22:01:03 2012 +0200 @@ -0,0 +1,74 @@ +/* + * 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.hotspot.target.amd64; + +import static com.oracle.graal.api.code.ValueUtil.*; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.hotspot.*; +import com.oracle.graal.lir.*; +import com.oracle.graal.lir.LIRInstruction.Opcode; +import com.oracle.graal.lir.amd64.*; +import com.oracle.graal.lir.asm.*; +import com.oracle.max.asm.target.amd64.*; + +/** + * LIR instruction for calling HotSpot's {@code new_instance} stub. This stub is declared in c1_Runtime1.hpp + * and implemented in Runtime1::generate_code_for() which is located in c1_Runtime1_x86.cpp. + */ +@Opcode("NEW_INSTANCE") +public class AMD64NewInstanceStubCallOp extends AMD64LIRInstruction { + + /** + * The stub expects the hub in RDX. + */ + public static final Register HUB = AMD64.rdx; + + /** + * The stub places the result in RAX. + */ + public static final Register RESULT = AMD64.rax; + + @Def protected Value result; + @Use protected Value hub; + @State protected LIRFrameState state; + + public AMD64NewInstanceStubCallOp(Value result, Value hub, LIRFrameState state) { + this.hub = hub; + this.result = result; + this.state = state; + } + + @Override + public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) { + AMD64Call.directCall(tasm, masm, HotSpotGraalRuntime.getInstance().getConfig().newInstanceStub, state); + } + + @Override + protected void verify() { + super.verify(); + assert asRegister(hub) == HUB : "expects hub in " + HUB; + assert asRegister(result) == RESULT : "expects result in " + RESULT; + } +} diff -r f043ecb70d3e -r 66ec0bc36a37 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/target/amd64/AMD64VerifyOopStubCallOp.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/target/amd64/AMD64VerifyOopStubCallOp.java Wed Jul 04 22:01:03 2012 +0200 @@ -0,0 +1,65 @@ +/* + * 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.hotspot.target.amd64; + +import static com.oracle.graal.api.code.ValueUtil.*; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.hotspot.*; +import com.oracle.graal.lir.*; +import com.oracle.graal.lir.LIRInstruction.Opcode; +import com.oracle.graal.lir.amd64.*; +import com.oracle.graal.lir.asm.*; +import com.oracle.max.asm.target.amd64.*; + +/** + * A call to HotSpot's object pointer verification stub. + */ +@Opcode("VERIFY_OOP") +public class AMD64VerifyOopStubCallOp extends AMD64LIRInstruction { + + /** + * The stub expects the object pointer in R13. + */ + public static final Register OBJECT = AMD64.r13; + + @Use protected Value object; + @State protected LIRFrameState state; + + public AMD64VerifyOopStubCallOp(Value object, LIRFrameState state) { + this.object = object; + this.state = state; + } + + @Override + public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) { + AMD64Call.directCall(tasm, masm, HotSpotGraalRuntime.getInstance().getConfig().verifyOopStub, state); + } + + @Override + protected void verify() { + super.verify(); + assert asRegister(object) == OBJECT : "expects object in " + OBJECT; + } +} diff -r f043ecb70d3e -r 66ec0bc36a37 graal/com.oracle.graal.java/src/com/oracle/graal/java/BytecodeDisassembler.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/BytecodeDisassembler.java Wed Jul 04 22:01:03 2012 +0200 @@ -0,0 +1,231 @@ +/* + * 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.java; + +import static com.oracle.graal.bytecode.Bytecodes.*; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.bytecode.*; + +/** + * Utility for producing a {@code javap}-like disassembly of bytecode. + */ +public class BytecodeDisassembler { + + /** + * Specifies if the disassembly for a single instruction can span multiple lines. + */ + private final boolean multiline; + + public BytecodeDisassembler(boolean multiline) { + this.multiline = multiline; + } + + public BytecodeDisassembler() { + this(true); + } + + /** + * Disassembles the bytecode of a given method in a {@code javap}-like format. + * + * @return {@code null} if {@code method} has no bytecode (e.g., it is native or abstract) + */ + public String disassemble(ResolvedJavaMethod method) { + if (method.code() == null) { + return null; + } + ConstantPool cp = method.getConstantPool(); + BytecodeStream stream = new BytecodeStream(method.code()); + StringBuilder buf = new StringBuilder(); + int opcode = stream.currentBC(); + while (opcode != Bytecodes.END) { + int bci = stream.currentBCI(); + String mnemonic = Bytecodes.nameOf(opcode); + buf.append(String.format("%4d: %-14s", bci, mnemonic)); + if (stream.nextBCI() > bci + 1) { + switch (opcode) { + case BIPUSH : buf.append(stream.readByte()); break; + case SIPUSH : buf.append(stream.readShort()); break; + case NEW : + case CHECKCAST : + case INSTANCEOF : + case ANEWARRAY : { + int cpi = stream.readCPI(); + JavaType type = cp.lookupType(cpi, opcode); + buf.append(String.format("#%-10d // %s", cpi, MetaUtil.toJavaName(type))); + break; + } + case GETSTATIC : + case PUTSTATIC : + case GETFIELD : + case PUTFIELD : { + int cpi = stream.readCPI(); + JavaField field = cp.lookupField(cpi, opcode); + String fieldDesc = field.holder().name().equals(method.holder().name()) ? MetaUtil.format("%n:%T", field) : MetaUtil.format("%H.%n:%T", field); + buf.append(String.format("#%-10d // %s", cpi, fieldDesc)); + break; + } + case INVOKEVIRTUAL : + case INVOKESPECIAL : + case INVOKESTATIC : { + int cpi = stream.readCPI(); + JavaMethod callee = cp.lookupMethod(cpi, opcode); + String calleeDesc = callee.holder().name().equals(method.holder().name()) ? MetaUtil.format("%n:(%P)%R", callee) : MetaUtil.format("%H.%n:(%P)%R", callee); + buf.append(String.format("#%-10d // %s", cpi, calleeDesc)); + break; + } + case INVOKEINTERFACE: { + int cpi = stream.readCPI(); + JavaMethod callee = cp.lookupMethod(cpi, opcode); + String calleeDesc = callee.holder().name().equals(method.holder().name()) ? MetaUtil.format("%n:(%P)%R", callee) : MetaUtil.format("%H.%n:(%P)%R", callee); + buf.append(String.format("#%-10s // %s", cpi + ", " + stream.readUByte(bci + 3), calleeDesc)); + break; + } + case LDC : + case LDC_W : + case LDC2_W : { + int cpi = stream.readCPI(); + Object constant = cp.lookupConstant(cpi); + String desc = null; + if (constant instanceof Constant) { + Constant c = ((Constant) constant); + switch (c.kind) { + case Int : + desc = String.valueOf(c.asInt()); + break; + case Float: + desc = String.valueOf(c.asFloat()); + break; + case Object: + desc = Kind.Object.format(c.asObject()); + break; + case Double : + desc = String.valueOf(c.asDouble()); + break; + case Long : + desc = String.valueOf(c.asLong()); + break; + default: + desc = c.toString(); + break; + } + } else { + desc = constant.toString(); + } + if (!multiline) { + desc.replaceAll("\\n", ""); + } + buf.append(String.format("#%-10d // %s", cpi, desc)); + break; + } + case RET : + case ILOAD : + case LLOAD : + case FLOAD : + case DLOAD : + case ALOAD : + case ISTORE : + case LSTORE : + case FSTORE : + case DSTORE : + case ASTORE : { + buf.append(String.format("%d", stream.readLocalIndex())); + break; + } + case IFEQ : + case IFNE : + case IFLT : + case IFGE : + case IFGT : + case IFLE : + case IF_ICMPEQ : + case IF_ICMPNE : + case IF_ICMPLT : + case IF_ICMPGE : + case IF_ICMPGT : + case IF_ICMPLE : + case IF_ACMPEQ : + case IF_ACMPNE : + case GOTO : + case JSR : + case IFNULL : + case IFNONNULL : + case GOTO_W : + case JSR_W : { + buf.append(String.format("%d", stream.readBranchDest())); + break; + } + case LOOKUPSWITCH : + case TABLESWITCH : { + BytecodeSwitch bswitch = opcode == LOOKUPSWITCH ? new BytecodeLookupSwitch(stream, bci) : new BytecodeTableSwitch(stream, bci); + if (multiline) { + buf.append("{ // " + bswitch.numberOfCases()); + for (int i = 0; i < bswitch.numberOfCases(); i++) { + buf.append(String.format("%n %7d: %d", bswitch.keyAt(i), bswitch.targetAt(i))); + } + buf.append(String.format("%n default: %d", bswitch.defaultTarget())); + buf.append(String.format("%n }")); + } else { + buf.append("[" + bswitch.numberOfCases()).append("] {"); + for (int i = 0; i < bswitch.numberOfCases(); i++) { + buf.append(String.format("%d: %d", bswitch.keyAt(i), bswitch.targetAt(i))); + if (i != bswitch.numberOfCases() - 1) { + buf.append(", "); + } + } + buf.append(String.format("} default: %d", bswitch.defaultTarget())); + } + break; + } + case NEWARRAY : { + int code = stream.readLocalIndex(); + // Checkstyle: stop + switch (code) { + case 4: buf.append("boolean"); break; + case 5: buf.append("char"); break; + case 6: buf.append("float"); break; + case 7: buf.append("double"); break; + case 8: buf.append("byte"); break; + case 9: buf.append("short"); break; + case 10: buf.append("int"); break; + case 11: buf.append("long"); break; + } + // Checkstyle: resume + + break; + } + case MULTIANEWARRAY : { + int cpi = stream.readCPI(); + JavaType type = cp.lookupType(cpi, opcode); + buf.append(String.format("#%-10s // %s", cpi + ", " + stream.readUByte(bci + 3), MetaUtil.toJavaName(type))); + break; + } + } + } + buf.append(String.format("%n")); + stream.next(); + opcode = stream.currentBC(); + } + return buf.toString(); + } +} diff -r f043ecb70d3e -r 66ec0bc36a37 graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Wed Jul 04 14:57:12 2012 +0200 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Wed Jul 04 22:01:03 2012 +0200 @@ -30,8 +30,8 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.api.meta.JavaType.*; -import com.oracle.graal.api.meta.JavaTypeProfile.*; +import com.oracle.graal.api.meta.JavaType.Representation; +import com.oracle.graal.api.meta.JavaTypeProfile.ProfiledType; import com.oracle.graal.bytecode.*; import com.oracle.graal.compiler.*; import com.oracle.graal.compiler.phases.*; @@ -649,7 +649,7 @@ ResolvedJavaType resolvedType = (ResolvedJavaType) type; ConstantNode hub = appendConstant(resolvedType.getEncoding(JavaType.Representation.ObjectHub)); InstanceOfNode instanceOfNode = new InstanceOfNode(hub, (ResolvedJavaType) type, object, getProfileForTypeCheck(resolvedType)); - frameState.ipush(append(MaterializeNode.create(currentGraph.unique(instanceOfNode), currentGraph))); + frameState.ipush(append(MaterializeNode.create(currentGraph.unique(instanceOfNode)))); } else { BlockPlaceholderNode successor = currentGraph.add(new BlockPlaceholderNode()); DeoptimizeNode deopt = currentGraph.add(new DeoptimizeNode(DeoptimizationAction.InvalidateRecompile, DeoptimizationReason.Unresolved, graphId)); @@ -693,10 +693,10 @@ // Checkstyle: resume } - private void genNewTypeArray(int typeCode) { + private void genNewPrimitiveArray(int typeCode) { Kind kind = arrayTypeCodeToKind(typeCode); ResolvedJavaType elementType = runtime.getResolvedJavaType(kind); - NewTypeArrayNode nta = currentGraph.add(new NewTypeArrayNode(frameState.ipop(), elementType)); + NewPrimitiveArrayNode nta = currentGraph.add(new NewPrimitiveArrayNode(frameState.ipop(), elementType)); frameState.apush(append(nta)); } @@ -1709,7 +1709,7 @@ case INVOKESTATIC : cpi = stream.readCPI(); genInvokeStatic(lookupMethod(cpi, opcode)); break; case INVOKEINTERFACE: cpi = stream.readCPI(); genInvokeInterface(lookupMethod(cpi, opcode)); break; case NEW : genNewInstance(stream.readCPI()); break; - case NEWARRAY : genNewTypeArray(stream.readLocalIndex()); break; + case NEWARRAY : genNewPrimitiveArray(stream.readLocalIndex()); break; case ANEWARRAY : genNewObjectArray(stream.readCPI()); break; case ARRAYLENGTH : genArrayLength(); break; case ATHROW : genThrow(); break; diff -r f043ecb70d3e -r 66ec0bc36a37 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java Wed Jul 04 14:57:12 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java Wed Jul 04 22:01:03 2012 +0200 @@ -146,7 +146,7 @@ return; } if (trueValue.isConstant() && falseValue.isConstant()) { - MaterializeNode materialize = MaterializeNode.create(compare(), graph(), trueValue, falseValue); + MaterializeNode materialize = MaterializeNode.create(compare(), trueValue, falseValue); ((StructuredGraph) graph()).replaceFloating(singlePhi, materialize); removeEmptyIf(tool); return; diff -r f043ecb70d3e -r 66ec0bc36a37 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MaterializeNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MaterializeNode.java Wed Jul 04 14:57:12 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MaterializeNode.java Wed Jul 04 22:01:03 2012 +0200 @@ -27,18 +27,59 @@ public final class MaterializeNode extends ConditionalNode { + private static CompareNode createCompareNode(Condition condition, ValueNode x, ValueNode y) { + assert x.kind() == y.kind(); + assert condition.isCanonical() : "condition is not canonical: " + condition; + + assert !x.kind().isFloatOrDouble(); + CompareNode comparison; + if (condition == Condition.EQ) { + if (x.kind().isObject()) { + comparison = new ObjectEqualsNode(x, y); + } else { + assert x.kind().stackKind().isInt() || x.kind().isLong(); + comparison = new IntegerEqualsNode(x, y); + } + } else if (condition == Condition.LT) { + assert x.kind().stackKind().isInt() || x.kind().isLong(); + comparison = new IntegerLessThanNode(x, y); + } else { + assert condition == Condition.BT; + assert x.kind().stackKind().isInt() || x.kind().isLong(); + comparison = new IntegerBelowThanNode(x, y); + } + + return x.graph().unique(comparison); + } + + private MaterializeNode(Condition condition, ValueNode x, ValueNode y) { + this(createCompareNode(condition, x, y), ConstantNode.forInt(1, x.graph()), ConstantNode.forInt(0, x.graph())); + } + private MaterializeNode(BooleanNode condition, ValueNode trueValue, ValueNode falseValue) { super(condition, trueValue, falseValue); } - public static MaterializeNode create(BooleanNode condition, Graph graph, ValueNode trueValue, ValueNode falseValue) { + public static MaterializeNode create(BooleanNode condition, ValueNode trueValue, ValueNode falseValue) { + Graph graph = condition.graph(); MaterializeNode result = new MaterializeNode(condition, trueValue, falseValue); return graph.unique(result); } - public static MaterializeNode create(BooleanNode condition, Graph graph) { - return create(condition, graph, ConstantNode.forInt(1, graph), ConstantNode.forInt(0, graph)); + public static MaterializeNode create(BooleanNode condition) { + return create(condition, ConstantNode.forInt(1, condition.graph()), ConstantNode.forInt(0, condition.graph())); } + @NodeIntrinsic + @SuppressWarnings("unused") + public static boolean materialize(@ConstantNodeParameter Condition condition, int x, int y) { + throw new UnsupportedOperationException("This method may only be compiled with the Graal compiler"); + } + + @NodeIntrinsic + @SuppressWarnings("unused") + public static boolean materialize(@ConstantNodeParameter Condition condition, long x, long y) { + throw new UnsupportedOperationException("This method may only be compiled with the Graal compiler"); + } } diff -r f043ecb70d3e -r 66ec0bc36a37 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NormalizeCompareNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NormalizeCompareNode.java Wed Jul 04 14:57:12 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NormalizeCompareNode.java Wed Jul 04 22:01:03 2012 +0200 @@ -58,8 +58,8 @@ lessComp = graph.unique(new IntegerLessThanNode(x(), y())); } - MaterializeNode equalValue = MaterializeNode.create(equalComp, graph, ConstantNode.forInt(0, graph), ConstantNode.forInt(1, graph)); - MaterializeNode value = MaterializeNode.create(lessComp, graph, ConstantNode.forInt(-1, graph), equalValue); + MaterializeNode equalValue = MaterializeNode.create(equalComp, ConstantNode.forInt(0, graph), ConstantNode.forInt(1, graph)); + MaterializeNode value = MaterializeNode.create(lessComp, ConstantNode.forInt(-1, graph), equalValue); graph.replaceFloating(this, value); } diff -r f043ecb70d3e -r 66ec0bc36a37 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewArrayNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewArrayNode.java Wed Jul 04 14:57:12 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewArrayNode.java Wed Jul 04 22:01:03 2012 +0200 @@ -36,7 +36,7 @@ /** * The {@code NewArrayNode} class is the base of all instructions that allocate arrays. */ -public abstract class NewArrayNode extends FixedWithNextNode implements EscapeAnalyzable, TypeFeedbackProvider { +public abstract class NewArrayNode extends FixedWithNextNode implements Lowerable, EscapeAnalyzable, TypeFeedbackProvider { @Input private ValueNode length; @@ -86,6 +86,11 @@ return ESCAPE; } + @Override + public void lower(LoweringTool tool) { + tool.getRuntime().lower(this, tool); + } + private static final EscapeOp ESCAPE = new EscapeOp() { @Override diff -r f043ecb70d3e -r 66ec0bc36a37 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewPrimitiveArrayNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewPrimitiveArrayNode.java Wed Jul 04 22:01:03 2012 +0200 @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2009, 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.java; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.nodes.type.*; + +/** + * The {@code NewPrimitiveArrayNode} class definition. + */ +public final class NewPrimitiveArrayNode extends NewArrayNode implements LIRLowerable { + + private final ResolvedJavaType elementType; + + public NewPrimitiveArrayNode(ValueNode length, ResolvedJavaType elementType) { + super(StampFactory.exactNonNull(elementType.arrayOf()), length); + this.elementType = elementType; + } + + @Override + public ResolvedJavaType elementType() { + return elementType; + } + + @Override + public void generate(LIRGeneratorTool gen) { + gen.visitNewPrimitiveArray(this); + } +} diff -r f043ecb70d3e -r 66ec0bc36a37 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewTypeArrayNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewTypeArrayNode.java Wed Jul 04 14:57:12 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2009, 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.java; - -import com.oracle.graal.api.meta.*; -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.nodes.type.*; - -/** - * The {@code NewTypeArrayNode} class definition. - */ -public final class NewTypeArrayNode extends NewArrayNode implements LIRLowerable { - - private final ResolvedJavaType elementType; - - public NewTypeArrayNode(ValueNode length, ResolvedJavaType elementType) { - super(StampFactory.exactNonNull(elementType.arrayOf()), length); - this.elementType = elementType; - } - - @Override - public ResolvedJavaType elementType() { - return elementType; - } - - @Override - public void generate(LIRGeneratorTool gen) { - gen.visitNewTypeArray(this); - } -} diff -r f043ecb70d3e -r 66ec0bc36a37 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LIRGeneratorTool.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LIRGeneratorTool.java Wed Jul 04 14:57:12 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LIRGeneratorTool.java Wed Jul 04 22:01:03 2012 +0200 @@ -112,7 +112,7 @@ public abstract void visitMonitorEnter(MonitorEnterNode i); public abstract void visitMonitorExit(MonitorExitNode i); public abstract void visitNewInstance(NewInstanceNode i); - public abstract void visitNewTypeArray(NewTypeArrayNode i); + public abstract void visitNewPrimitiveArray(NewPrimitiveArrayNode i); public abstract void visitNewObjectArray(NewObjectArrayNode i); public abstract void visitNewMultiArray(NewMultiArrayNode i); public abstract void visitExceptionObject(ExceptionObjectNode i); diff -r f043ecb70d3e -r 66ec0bc36a37 graal/com.oracle.graal.printer/src/com/oracle/graal/printer/BasicIdealGraphPrinter.java --- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/BasicIdealGraphPrinter.java Wed Jul 04 14:57:12 2012 +0200 +++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/BasicIdealGraphPrinter.java Wed Jul 04 22:01:03 2012 +0200 @@ -134,6 +134,12 @@ stream.println(" ]]>"); } + protected void printBytecodes(String disassembly) { + beginBytecodes(); + stream.println(disassembly); + endBytecodes(); + } + protected void endMethod() { stream.println(" "); } diff -r f043ecb70d3e -r 66ec0bc36a37 graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CFGPrinterObserver.java --- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CFGPrinterObserver.java Wed Jul 04 14:57:12 2012 +0200 +++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CFGPrinterObserver.java Wed Jul 04 22:01:03 2012 +0200 @@ -24,6 +24,7 @@ import java.io.*; import java.util.*; +import java.util.concurrent.atomic.*; import com.oracle.graal.alloc.util.*; import com.oracle.graal.api.code.*; @@ -46,6 +47,7 @@ public class CFGPrinterObserver implements DebugDumpHandler { private CFGPrinter cfgPrinter; + private File cfgFile; private ResolvedJavaMethod curMethod; private List curDecorators = Collections.emptyList(); @@ -63,7 +65,7 @@ * in the current debug scope and opens a new compilation scope if this pair * does not match the current method and decorator pair. */ - private void checkMethodScope() { + private boolean checkMethodScope() { ResolvedJavaMethod method = null; ArrayList decorators = new ArrayList<>(); for (Object o : Debug.context()) { @@ -83,14 +85,22 @@ } } + if (method == null) { + return false; + } + if (method != curMethod || !curDecorators.equals(decorators)) { cfgPrinter.printCompilation(method); - TTY.println("CFGPrinter: Dumping method %s", method); + TTY.println("CFGPrinter: Dumping method %s to %s", method, cfgFile); curMethod = method; curDecorators = decorators; } + return true; } + private static final long timestamp = System.currentTimeMillis(); + private static final AtomicInteger uniqueId = new AtomicInteger(); + public void dumpSandboxed(Object object, String message) { GraalCompiler compiler = Debug.contextLookup(GraalCompiler.class); if (compiler == null) { @@ -98,17 +108,19 @@ } if (cfgPrinter == null) { - File file = new File("compilations-" + System.currentTimeMillis() + ".cfg"); + cfgFile = new File("compilations-" + timestamp + "_" + uniqueId.incrementAndGet() + ".cfg"); try { - OutputStream out = new BufferedOutputStream(new FileOutputStream(file)); + OutputStream out = new BufferedOutputStream(new FileOutputStream(cfgFile)); cfgPrinter = new CFGPrinter(out); } catch (FileNotFoundException e) { - throw new GraalInternalError("Could not open " + file.getAbsolutePath()); + throw new GraalInternalError("Could not open " + cfgFile.getAbsolutePath()); } - TTY.println("CFGPrinter: Output to file %s", file); + TTY.println("CFGPrinter: Output to file %s", cfgFile); } - checkMethodScope(); + if (!checkMethodScope()) { + return; + } cfgPrinter.target = compiler.target; if (object instanceof LIR) { @@ -126,7 +138,9 @@ if (object instanceof BciBlockMapping) { BciBlockMapping blockMap = (BciBlockMapping) object; cfgPrinter.printCFG(message, blockMap); - cfgPrinter.printBytecodes(runtime.disassemble(blockMap.method)); + if (blockMap.method.code() != null) { + cfgPrinter.printBytecodes(new BytecodeDisassembler(false).disassemble(blockMap.method)); + } } else if (object instanceof LIR) { cfgPrinter.printCFG(message, cfgPrinter.lir.codeEmittingOrder()); diff -r f043ecb70d3e -r 66ec0bc36a37 graal/com.oracle.graal.printer/src/com/oracle/graal/printer/IdealGraphPrinter.java --- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/IdealGraphPrinter.java Wed Jul 04 14:57:12 2012 +0200 +++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/IdealGraphPrinter.java Wed Jul 04 22:01:03 2012 +0200 @@ -27,12 +27,12 @@ import java.util.Map.Entry; import com.oracle.graal.api.meta.*; -import com.oracle.graal.bytecode.*; import com.oracle.graal.compiler.schedule.*; import com.oracle.graal.graph.*; import com.oracle.graal.graph.Node.Verbosity; import com.oracle.graal.graph.NodeClass.NodeClassIterator; import com.oracle.graal.graph.NodeClass.Position; +import com.oracle.graal.java.*; import com.oracle.graal.lir.cfg.*; import com.oracle.graal.nodes.*; @@ -57,23 +57,8 @@ printProperty("name", name); endProperties(); beginMethod(name, shortName, bci); - if (method != null) { - beginBytecodes(); - BytecodeStream bytecodes = new BytecodeStream(method.code()); - while (bytecodes.currentBC() != Bytecodes.END) { - int startBCI = bytecodes.currentBCI(); - String mnemonic = Bytecodes.nameOf(bytecodes.currentBC()); - int[] extra = null; - if (bytecodes.nextBCI() > startBCI + 1) { - extra = new int[bytecodes.nextBCI() - (startBCI + 1)]; - for (int i = 0; i < extra.length; i++) { - extra[i] = bytecodes.readUByte(startBCI + 1 + i); - } - } - printBytecode(startBCI, mnemonic, extra); - bytecodes.next(); - } - endBytecodes(); + if (method != null && method.code() != null) { + printBytecodes(new BytecodeDisassembler(false).disassemble(method)); } endMethod(); } diff -r f043ecb70d3e -r 66ec0bc36a37 graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/Snippet.java --- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/Snippet.java Wed Jul 04 14:57:12 2012 +0200 +++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/Snippet.java Wed Jul 04 22:01:03 2012 +0200 @@ -58,11 +58,26 @@ boolean shouldInline(ResolvedJavaMethod method, ResolvedJavaMethod caller); /** - * The default inlining policy which inlines everything except for - * constructors of {@link Throwable} classes. + * The default inlining policy which inlines everything except for methods + * in any of the following categories. + *
    + *
  • {@linkplain Fold foldable} methods
  • + *
  • {@linkplain NodeIntrinsic node intrinsics}
  • + *
  • native methods
  • + *
  • constructors of {@link Throwable} classes
  • + *
*/ InliningPolicy Default = new InliningPolicy() { public boolean shouldInline(ResolvedJavaMethod method, ResolvedJavaMethod caller) { + if (Modifier.isNative(method.accessFlags())) { + return false; + } + if (method.getAnnotation(Fold.class) != null) { + return false; + } + if (method.getAnnotation(NodeIntrinsic.class) != null) { + return false; + } if (Throwable.class.isAssignableFrom(method.holder().toJava())) { if (method.name().equals("")) { return false; diff -r f043ecb70d3e -r 66ec0bc36a37 graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetInstaller.java --- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetInstaller.java Wed Jul 04 14:57:12 2012 +0200 +++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetInstaller.java Wed Jul 04 22:01:03 2012 +0200 @@ -136,6 +136,8 @@ public StructuredGraph makeGraph(final ResolvedJavaMethod method, final InliningPolicy policy) { StructuredGraph graph = parseGraph(method, policy); + new SnippetIntrinsificationPhase(runtime, pool, SnippetTemplate.hasConstantParameter(method)).apply(graph); + Debug.dump(graph, "%s: Final", method.name()); return graph; @@ -164,7 +166,7 @@ new SnippetVerificationPhase().apply(graph); - new SnippetIntrinsificationPhase(runtime, pool).apply(graph); + new SnippetIntrinsificationPhase(runtime, pool, true).apply(graph); for (Invoke invoke : graph.getInvokes()) { MethodCallTargetNode callTarget = invoke.callTarget(); @@ -180,7 +182,7 @@ } } - new SnippetIntrinsificationPhase(runtime, pool).apply(graph); + new SnippetIntrinsificationPhase(runtime, pool, true).apply(graph); new WordTypeRewriterPhase(target.wordKind, runtime.getResolvedJavaType(target.wordKind)).apply(graph); diff -r f043ecb70d3e -r 66ec0bc36a37 graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetIntrinsificationPhase.java --- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetIntrinsificationPhase.java Wed Jul 04 14:57:12 2012 +0200 +++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetIntrinsificationPhase.java Wed Jul 04 22:01:03 2012 +0200 @@ -40,16 +40,39 @@ private final MetaAccessProvider runtime; private final BoxingMethodPool pool; + private final boolean intrinsificationOrFoldingCanBeDeferred; - public SnippetIntrinsificationPhase(MetaAccessProvider runtime, BoxingMethodPool pool) { + /** + * @param intrinsificationOrFoldingCanBeDeferred if true, then {@link NonConstantParameterError}s are not fatal + */ + public SnippetIntrinsificationPhase(MetaAccessProvider runtime, BoxingMethodPool pool, boolean intrinsificationOrFoldingCanBeDeferred) { this.runtime = runtime; this.pool = pool; + this.intrinsificationOrFoldingCanBeDeferred = intrinsificationOrFoldingCanBeDeferred; } @Override protected void run(StructuredGraph graph) { for (Invoke i : graph.getInvokes()) { - tryIntrinsify(i); + try { + tryIntrinsify(i); + } catch (NonConstantParameterError t) { + if (!intrinsificationOrFoldingCanBeDeferred) { + throw t; + } + } + } + } + + /** + * Exception raised when an argument to a {@linkplain Fold foldable} or + * {@link NodeIntrinsic} method is not a constant. + */ + @SuppressWarnings("serial") + public static class NonConstantParameterError extends Error { + + public NonConstantParameterError(String message) { + super(message); } } @@ -118,7 +141,9 @@ } ValueNode argument = tryBoxingElimination(parameterIndex, target, arguments.get(i)); if (folding || MetaUtil.getParameterAnnotation(ConstantNodeParameter.class, parameterIndex, target) != null) { - assert argument instanceof ConstantNode : "parameter " + parameterIndex + " must be a compile time constant for calling " + invoke.callTarget().targetMethod() + " at " + sourceLocation(invoke.node()) + ": " + argument; + if (!(argument instanceof ConstantNode)) { + throw new NonConstantParameterError("parameter " + parameterIndex + " must be a compile time constant for calling " + invoke.callTarget().targetMethod() + " at " + sourceLocation(invoke.node()) + ": " + argument); + } ConstantNode constantNode = (ConstantNode) argument; Constant constant = constantNode.asConstant(); Object o = constant.boxedValue(); diff -r f043ecb70d3e -r 66ec0bc36a37 graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetTemplate.java --- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetTemplate.java Wed Jul 04 14:57:12 2012 +0200 +++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetTemplate.java Wed Jul 04 22:01:03 2012 +0200 @@ -35,6 +35,7 @@ import com.oracle.graal.graph.*; import com.oracle.graal.graph.Node.Verbosity; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.type.*; import com.oracle.graal.nodes.util.*; @@ -175,6 +176,18 @@ } /** + * Determines if any parameter of a given method is annotated with {@link ConstantParameter}. + */ + public static boolean hasConstantParameter(ResolvedJavaMethod method) { + for (ConstantParameter p : MetaUtil.getParameterAnnotations(ConstantParameter.class, method)) { + if (p != null) { + return true; + } + } + return false; + } + + /** * Creates a snippet template. */ public SnippetTemplate(CodeCacheProvider runtime, SnippetTemplate.Key key) { @@ -182,7 +195,7 @@ assert Modifier.isStatic(method.accessFlags()) : "snippet method must be static: " + method; Signature signature = method.signature(); - // Copy snippet graph, replacing @Constant parameters with given arguments + // Copy snippet graph, replacing constant parameters with given arguments StructuredGraph snippetGraph = (StructuredGraph) method.compilerStorage().get(Graph.class); StructuredGraph snippetCopy = new StructuredGraph(snippetGraph.name, snippetGraph.method()); IdentityHashMap replacements = new IdentityHashMap<>(); @@ -201,7 +214,8 @@ replacements.put(snippetGraph.getLocal(i), ConstantNode.forConstant(Constant.forBoxed(kind, arg), runtime, snippetCopy)); } else { Parameter p = MetaUtil.getParameterAnnotation(Parameter.class, i, method); - assert p != null : method + ": parameter " + i + " must be annotated with either @Constant or @Parameter"; + assert p != null : method + ": parameter " + i + " must be annotated with either @" + ConstantParameter.class.getSimpleName() + + " or @" + Parameter.class.getSimpleName(); String name = p.value(); if (p.multiple()) { Object multiple = key.get(name); @@ -219,6 +233,9 @@ Debug.dump(snippetCopy, "Before specialization"); if (!replacements.isEmpty()) { + // Do deferred intrinsification of node intrinsics + new SnippetIntrinsificationPhase(runtime, new BoxingMethodPool(runtime), false).apply(snippetCopy); + new CanonicalizerPhase(null, runtime, null, 0, null).apply(snippetCopy); } @@ -386,6 +403,7 @@ replacements.put((LocalNode) parameter, (ValueNode) argument); } else { Kind kind = ((LocalNode) parameter).kind(); + assert argument != null || kind.isObject() : this + " cannot accept null for non-object parameter named " + name; Constant constant = Constant.forBoxed(kind, argument); replacements.put((LocalNode) parameter, ConstantNode.forConstant(constant, runtime, replaceeGraph)); } @@ -478,10 +496,10 @@ sep = ", "; if (value instanceof LocalNode) { LocalNode local = (LocalNode) value; - buf.append(local.kind().name()).append(' ').append(name); + buf.append(local.kind().javaName).append(' ').append(name); } else { LocalNode[] locals = (LocalNode[]) value; - String kind = locals.length == 0 ? "?" : locals[0].kind().name(); + String kind = locals.length == 0 ? "?" : locals[0].kind().javaName; buf.append(kind).append('[').append(locals.length).append("] ").append(name); } } diff -r f043ecb70d3e -r 66ec0bc36a37 graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetVerificationPhase.java --- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetVerificationPhase.java Wed Jul 04 14:57:12 2012 +0200 +++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetVerificationPhase.java Wed Jul 04 22:01:03 2012 +0200 @@ -31,6 +31,7 @@ import com.oracle.graal.graph.*; import com.oracle.graal.graph.Node.NodeIntrinsic; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.util.*; import com.oracle.graal.snippets.Word.*; @@ -87,6 +88,11 @@ argc++; } } + } else if (usage instanceof ObjectEqualsNode) { + ObjectEqualsNode compare = (ObjectEqualsNode) usage; + if (compare.x() == node || compare.y() == node) { + verify(isWord(compare.x()) == isWord(compare.y()), node, compare.usages().first(), "cannot mixed word and now-word type in use of '==' or '!='"); + } } else if (usage instanceof ArrayLengthNode) { verify(!isWord(node) || ((ArrayLengthNode) usage).array() != node, node, usage, "cannot get array length from word value"); } else if (usage instanceof PhiNode) { diff -r f043ecb70d3e -r 66ec0bc36a37 graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/WordTypeRewriterPhase.java --- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/WordTypeRewriterPhase.java Wed Jul 04 14:57:12 2012 +0200 +++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/WordTypeRewriterPhase.java Wed Jul 04 22:01:03 2012 +0200 @@ -68,6 +68,17 @@ } } + // Replace ObjectEqualsNodes with IntegerEqualsNodes where the values being compared are words + for (ObjectEqualsNode objectEqualsNode : graph.getNodes().filter(ObjectEqualsNode.class).snapshot()) { + ValueNode x = objectEqualsNode.x(); + ValueNode y = objectEqualsNode.y(); + if (x.kind() == wordKind || y.kind() == wordKind) { + assert x.kind() == wordKind; + assert y.kind() == wordKind; + graph.replaceFloating(objectEqualsNode, graph.unique(new IntegerEqualsNode(x, y))); + } + } + for (MethodCallTargetNode callTargetNode : graph.getNodes(MethodCallTargetNode.class).snapshot()) { ResolvedJavaMethod targetMethod = callTargetNode.targetMethod(); Operation operation = targetMethod.getAnnotation(Word.Operation.class); @@ -188,7 +199,7 @@ ValueNode a = mirror ? right : left; ValueNode b = mirror ? left : right; - MaterializeNode materialize = MaterializeNode.create(graph.unique(new IntegerBelowThanNode(a, b)), graph); + MaterializeNode materialize = MaterializeNode.create(graph.unique(new IntegerBelowThanNode(a, b))); ValueNode op; if (condition.canonicalNegate()) { diff -r f043ecb70d3e -r 66ec0bc36a37 graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/NewArrayTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/NewArrayTest.java Wed Jul 04 22:01:03 2012 +0200 @@ -0,0 +1,165 @@ +/* + * 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.compiler.tests; + +import org.junit.*; + +/** + * Tests the implementation of {@code [A]NEWARRAY}. + */ +public class NewArrayTest extends GraalCompilerTest { + + @Override + protected void assertEquals(Object expected, Object actual) { + Assert.assertTrue(expected != null); + Assert.assertTrue(actual != null); + super.assertEquals(expected.getClass(), actual.getClass()); + if (expected instanceof int[]) { + Assert.assertArrayEquals((int[]) expected, (int[]) actual); + } else if (expected instanceof byte[]) { + Assert.assertArrayEquals((byte[]) expected, (byte[]) actual); + } else if (expected instanceof char[]) { + Assert.assertArrayEquals((char[]) expected, (char[]) actual); + } else if (expected instanceof short[]) { + Assert.assertArrayEquals((short[]) expected, (short[]) actual); + } else if (expected instanceof float[]) { + Assert.assertArrayEquals((float[]) expected, (float[]) actual, 0.0f); + } else if (expected instanceof long[]) { + Assert.assertArrayEquals((long[]) expected, (long[]) actual); + } else if (expected instanceof double[]) { + Assert.assertArrayEquals((double[]) expected, (double[]) actual, 0.0d); + } else if (expected instanceof Object[]) { + Assert.assertArrayEquals((Object[]) expected, (Object[]) actual); + } else { + Assert.fail("non-array value encountered: " + expected); + } + } + + @Test + public void test1() { + for (String type : new String[] {"Byte", "Char", "Short", "Int", "Float", "Long", "Double", "String"}) { + test("new" + type + "Array7"); + test("new" + type + "ArrayMinus7"); + test("new" + type + "Array", 7); + test("new" + type + "Array", -7); + test("new" + type + "Array", Integer.MAX_VALUE); + test("new" + type + "Array", Integer.MIN_VALUE); + } + } + + public static Object newCharArray7() { + return new char[7]; + } + + public static Object newCharArrayMinus7() { + return new char[-7]; + } + + public static Object newCharArray(int length) { + return new char[length]; + } + + public static Object newShortArray7() { + return new short[7]; + } + + public static Object newShortArrayMinus7() { + return new short[-7]; + } + + public static Object newShortArray(int length) { + return new short[length]; + } + + public static Object newFloatArray7() { + return new float[7]; + } + + public static Object newFloatArrayMinus7() { + return new float[-7]; + } + + public static Object newFloatArray(int length) { + return new float[length]; + } + + public static Object newLongArray7() { + return new long[7]; + } + + public static Object newLongArrayMinus7() { + return new long[-7]; + } + + public static Object newLongArray(int length) { + return new long[length]; + } + + public static Object newDoubleArray7() { + return new double[7]; + } + + public static Object newDoubleArrayMinus7() { + return new double[-7]; + } + + public static Object newDoubleArray(int length) { + return new double[length]; + } + + public static Object newIntArray7() { + return new int[7]; + } + + public static Object newIntArrayMinus7() { + return new int[-7]; + } + + public static Object newIntArray(int length) { + return new int[length]; + } + + public static Object newByteArray7() { + return new byte[7]; + } + + public static Object newByteArrayMinus7() { + return new byte[-7]; + } + + public static Object newByteArray(int length) { + return new byte[length]; + } + + public static Object newStringArray7() { + return new String[7]; + } + + public static Object newStringArrayMinus7() { + return new String[-7]; + } + + public static Object newStringArray(int length) { + return new String[length]; + } +} diff -r f043ecb70d3e -r 66ec0bc36a37 graal/com.oracle.max.criutils/src/com/oracle/max/criutils/UnsignedMath.java --- a/graal/com.oracle.max.criutils/src/com/oracle/max/criutils/UnsignedMath.java Wed Jul 04 14:57:12 2012 +0200 +++ b/graal/com.oracle.max.criutils/src/com/oracle/max/criutils/UnsignedMath.java Wed Jul 04 22:01:03 2012 +0200 @@ -22,6 +22,8 @@ */ package com.oracle.max.criutils; +//JaCoCo Exclude + /** * Utilities for unsigned comparisons. * All methods have correct, but slow, standard Java implementations so that diff -r f043ecb70d3e -r 66ec0bc36a37 mx/commands.py --- a/mx/commands.py Wed Jul 04 14:57:12 2012 +0200 +++ b/mx/commands.py Wed Jul 04 22:01:03 2012 +0200 @@ -587,7 +587,9 @@ # Exclude all compiler tests and snippets excludes = ['com.oracle.graal.compiler.tests.*'] for p in mx.projects(): - _find_classes_with_annotations(excludes, p, None, ['@Snippet', '@ClassSubstitution'], includeInnerClasses=True) + excludes += _find_classes_with_annotations(p, None, ['@Snippet', '@ClassSubstitution'], includeInnerClasses=True) + excludes += p.find_classes_with_matching_source_line(None, lambda line: 'JaCoCo Exclude' in line, includeInnerClasses=True) + agentOptions = { 'append' : 'true' if _jacoco == 'append' else 'false', 'bootclasspath' : 'true', @@ -598,47 +600,15 @@ exe = join(jdk, 'bin', mx.exe_suffix('java')) return mx.run([exe, '-' + vm] + args, nonZeroIsFatal=nonZeroIsFatal, out=out, err=err, cwd=cwd, timeout=timeout) -def _find_classes_with_annotations(classes, p, pkgRoot, annotations, includeInnerClasses=False): +def _find_classes_with_annotations(p, pkgRoot, annotations, includeInnerClasses=False): """ Scan the sources of project 'p' for Java source files containing a line starting with 'annotation' - (ignoring preceding whitespace) and add the fully qualified class name - to 'classes' for each Java source file matched. + (ignoring preceding whitespace) and return the fully qualified class name for each Java + source file matched in a list. """ - for a in annotations: - assert a.startswith('@') - pkgDecl = re.compile(r"^package\s+([a-zA-Z_][\w\.]*)\s*;$") - for srcDir in p.source_dirs(): - outputDir = p.output_dir() - for root, _, files in os.walk(srcDir): - for name in files: - if name.endswith('.java') and name != 'package-info.java': - annotationFound = False - with open(join(root, name)) as f: - pkg = None - for line in f: - if line.startswith("package "): - match = pkgDecl.match(line) - if match: - pkg = match.group(1) - else: - stripped = line.strip() - for a in annotations: - if stripped == a or stripped.startswith(a + '('): - annotationFound = True - break - if annotationFound: - break - if annotationFound: - basename = name[:-len('.java')] - assert pkg is not None - if pkgRoot is None or pkg.startswith(pkgRoot): - pkgOutputDir = join(outputDir, pkg.replace('.', os.path.sep)) - for e in os.listdir(pkgOutputDir): - if includeInnerClasses: - if e.endswith('.class') and (e.startswith(basename) or e.startswith(basename + '$')): - classes.append(pkg + '.' + e[:-len('.class')]) - elif e == basename + '.class': - classes.append(pkg + '.' + basename) + + matches = lambda line : len([a for a in annotations if line == a or line.startswith(a + '(')]) != 0 + return p.find_classes_with_matching_source_line(pkgRoot, matches, includeInnerClasses) def _run_tests(args, harnessName, harness): pos = [a for a in args if a[0] != '-' and a[0] != '@' ] @@ -653,8 +623,7 @@ for p in mx.projects(): if getattr(p, 'testHarness', None) == harnessName: - classes = [] - _find_classes_with_annotations(classes, p, None, ['@Test']) + classes = _find_classes_with_annotations(p, None, ['@Test']) if len(pos) != 0: classes = [c for c in classes if containsAny(c, pos)] diff -r f043ecb70d3e -r 66ec0bc36a37 mxtool/mx.py --- a/mxtool/mx.py Wed Jul 04 14:57:12 2012 +0200 +++ b/mxtool/mx.py Wed Jul 04 22:01:03 2012 +0200 @@ -261,6 +261,46 @@ if not self.native: cp.append(self.output_dir()) + def find_classes_with_matching_source_line(self, pkgRoot, function, includeInnerClasses=False): + """ + Scan the sources of this project for Java source files containing a line for which + 'function' returns true. The fully qualified class name of each existing class + corresponding to a matched source file is returned in a list. + """ + classes = [] + pkgDecl = re.compile(r"^package\s+([a-zA-Z_][\w\.]*)\s*;$") + for srcDir in self.source_dirs(): + outputDir = self.output_dir() + for root, _, files in os.walk(srcDir): + for name in files: + if name.endswith('.java') and name != 'package-info.java': + matchFound = False + with open(join(root, name)) as f: + pkg = None + for line in f: + if line.startswith("package "): + match = pkgDecl.match(line) + if match: + pkg = match.group(1) + if function(line.strip()): + matchFound = True + if pkg and matchFound: + break + + if matchFound: + basename = name[:-len('.java')] + assert pkg is not None + if pkgRoot is None or pkg.startswith(pkgRoot): + pkgOutputDir = join(outputDir, pkg.replace('.', os.path.sep)) + for e in os.listdir(pkgOutputDir): + if includeInnerClasses: + if e.endswith('.class') and (e.startswith(basename) or e.startswith(basename + '$')): + classes.append(pkg + '.' + e[:-len('.class')]) + elif e == basename + '.class': + classes.append(pkg + '.' + basename) + return classes + + class Library(Dependency): def __init__(self, suite, name, path, mustExist, urls): Dependency.__init__(self, suite, name) diff -r f043ecb70d3e -r 66ec0bc36a37 src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/BytecodeNode.java --- a/src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/BytecodeNode.java Wed Jul 04 14:57:12 2012 +0200 +++ b/src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/BytecodeNode.java Wed Jul 04 22:01:03 2012 +0200 @@ -49,7 +49,7 @@ public BytecodeNode(InputBytecode bytecode, InputGraph graph, String bciValue) { super(Children.LEAF); - this.setDisplayName(bytecode.getBci() + " " + bytecode.getName()); + String displayName = bytecode.getBci() + " " + bytecode.getName() + " " + bytecode.getOperands(); bciValue = bytecode.getBci() + " " + bciValue; bciValue = bciValue.trim(); @@ -62,8 +62,14 @@ for (InputNode n : nodeList) { nodes.add(n); } - this.setDisplayName(this.getDisplayName() + " (" + nodes.size() + " nodes)"); + displayName += " (" + nodes.size() + " nodes)"; } + + if (bytecode.getComment() != null) { + displayName += " // " + bytecode.getComment(); + } + + this.setDisplayName(displayName); } @Override diff -r f043ecb70d3e -r 66ec0bc36a37 src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputBytecode.java --- a/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputBytecode.java Wed Jul 04 14:57:12 2012 +0200 +++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputBytecode.java Wed Jul 04 22:01:03 2012 +0200 @@ -31,11 +31,15 @@ private int bci; private String name; + private String operands; + private String comment; private InputMethod inlined; - public InputBytecode(int bci, String name) { + public InputBytecode(int bci, String name, String operands, String comment) { this.bci = bci; this.name = name; + this.operands = operands; + this.comment = comment; } public InputMethod getInlined() { @@ -53,4 +57,12 @@ public String getName() { return name; } + + public String getOperands() { + return operands; + } + + public String getComment() { + return comment; + } } diff -r f043ecb70d3e -r 66ec0bc36a37 src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputMethod.java --- a/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputMethod.java Wed Jul 04 14:57:12 2012 +0200 +++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputMethod.java Wed Jul 04 22:01:03 2012 +0200 @@ -26,6 +26,8 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * @@ -109,31 +111,38 @@ } public void setBytecodes(String text) { - + Pattern instruction = Pattern.compile("\\s*(\\d+)\\s*:?\\s*(\\w+)\\s*(.*)(?://(.*))?"); String[] strings = text.split("\n"); - int oldNumber = -1; + int oldBci = -1; for (String s : strings) { - - if (s.length() > 0 && Character.isDigit(s.charAt(0))) { - s = s.trim(); - int spaceIndex = s.indexOf(' '); - String numberString = s.substring(0, spaceIndex); - String tmpName = s.substring(spaceIndex + 1, s.length()); + s = s.trim(); + if (s.length() != 0) { + final Matcher matcher = instruction.matcher(s); + if (matcher.matches()) { + String bciString = matcher.group(1); + String opcode = matcher.group(2); + String operands = matcher.group(3).trim(); + String comment = matcher.group(4); + if (comment != null) { + comment = comment.trim(); + } - int number = -1; - number = Integer.parseInt(numberString); + int bci = Integer.parseInt(bciString); - // assert correct order of bytecodes - assert number > oldNumber; + // assert correct order of bytecodes + assert bci > oldBci; + + InputBytecode bc = new InputBytecode(bci, opcode, operands, comment); + bytecodes.add(bc); - InputBytecode bc = new InputBytecode(number, tmpName); - bytecodes.add(bc); - - for (InputMethod m : inlined) { - if (m.getBci() == number) { - bc.setInlined(m); - break; + for (InputMethod m : inlined) { + if (m.getBci() == bci) { + bc.setInlined(m); + break; + } } + } else { + System.out.println("no match: " + s); } } } diff -r f043ecb70d3e -r 66ec0bc36a37 src/share/vm/graal/graalCompiler.cpp --- a/src/share/vm/graal/graalCompiler.cpp Wed Jul 04 14:57:12 2012 +0200 +++ b/src/share/vm/graal/graalCompiler.cpp Wed Jul 04 22:01:03 2012 +0200 @@ -273,7 +273,7 @@ HotSpotResolvedJavaType::set_accessFlags(obj, klass->access_flags().as_int()); HotSpotResolvedJavaType::set_isInterface(obj, klass->is_interface()); HotSpotResolvedJavaType::set_superCheckOffset(obj, klass->super_check_offset()); - HotSpotResolvedJavaType::set_prototypeHeader(obj, (jlong) klass->prototype_header()); + HotSpotResolvedJavaType::set_initialMarkWord(obj, (jlong) klass->prototype_header()); HotSpotResolvedJavaType::set_isInstanceClass(obj, klass->oop_is_instance()); if (klass->oop_is_javaArray()) { diff -r f043ecb70d3e -r 66ec0bc36a37 src/share/vm/graal/graalCompilerToVM.cpp --- a/src/share/vm/graal/graalCompilerToVM.cpp Wed Jul 04 14:57:12 2012 +0200 +++ b/src/share/vm/graal/graalCompilerToVM.cpp Wed Jul 04 22:01:03 2012 +0200 @@ -790,6 +790,7 @@ set_int(env, config, "vmPageSize", os::vm_page_size()); set_int(env, config, "stackShadowPages", StackShadowPages); set_int(env, config, "hubOffset", oopDesc::klass_offset_in_bytes()); + set_int(env, config, "markOffset", oopDesc::mark_offset_in_bytes()); set_int(env, config, "superCheckOffsetOffset", in_bytes(Klass::super_check_offset_offset())); set_int(env, config, "secondarySuperCacheOffset", in_bytes(Klass::secondary_super_cache_offset())); set_int(env, config, "secondarySupersOffset", in_bytes(Klass::secondary_supers_offset())); @@ -874,12 +875,6 @@ break; } - jintArray arrayOffsets = env->NewIntArray(basicTypeCount); - for (int i=0; iSetIntArrayRegion(arrayOffsets, i, 1, &offset); - } - set_int_array(env, config, "arrayOffsets", arrayOffsets); set_int(env, config, "arrayClassElementOffset", in_bytes(objArrayKlass::element_klass_offset())); return config; } @@ -934,25 +929,6 @@ return JNIHandles::make_local(result()); } -// public String disassembleJava(HotSpotResolvedJavaMethod method); -JNIEXPORT jobject JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_disassembleJava(JNIEnv *env, jobject, jobject hotspot_method) { - TRACE_graal_3("CompilerToVM::disassembleJava"); - - // Important: The bytecode printing functions are all NOT PRODUCT code, so this method returns an empty string for a product VM build. - - VM_ENTRY_MARK; - ResourceMark rm; - HandleMark hm; - - methodHandle method = getMethodFromHotSpotMethod(hotspot_method); - // Note: cannot use resource-allocated stringStream because print_code_on has its own ResourceMark. - bufferedStream(st); - method->print_codes_on(&st); - - Handle result = java_lang_String::create_from_platform_dependent_str(st.as_string(), CHECK_NULL); - return JNIHandles::make_local(result()); -} - // public StackTraceElement JavaMethod_toStackTraceElement(HotSpotResolvedJavaMethod method, int bci); JNIEXPORT jobject JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_JavaMethod_1toStackTraceElement(JNIEnv *env, jobject, jobject hotspot_method, int bci) { TRACE_graal_3("CompilerToVM::JavaMethod_toStackTraceElement"); @@ -1140,7 +1116,6 @@ {CC"getConfiguration", CC"()"CONFIG, FN_PTR(getConfiguration)}, {CC"installMethod", CC"("TARGET_METHOD"Z"HS_CODE_INFO")"HS_COMP_METHOD, FN_PTR(installMethod)}, {CC"disassembleNative", CC"([BJ)"STRING, FN_PTR(disassembleNative)}, - {CC"disassembleJava", CC"("RESOLVED_METHOD")"STRING, FN_PTR(disassembleJava)}, {CC"JavaMethod_toStackTraceElement", CC"("RESOLVED_METHOD"I)"STACK_TRACE_ELEMENT, FN_PTR(JavaMethod_1toStackTraceElement)}, {CC"executeCompiledMethod", CC"("HS_COMP_METHOD OBJECT OBJECT OBJECT")"OBJECT, FN_PTR(executeCompiledMethod)}, {CC"executeCompiledMethodVarargs", CC"("HS_COMP_METHOD "["OBJECT")"OBJECT, FN_PTR(executeCompiledMethodVarargs)}, diff -r f043ecb70d3e -r 66ec0bc36a37 src/share/vm/graal/graalJavaAccess.hpp --- a/src/share/vm/graal/graalJavaAccess.hpp Wed Jul 04 14:57:12 2012 +0200 +++ b/src/share/vm/graal/graalJavaAccess.hpp Wed Jul 04 22:01:03 2012 +0200 @@ -52,7 +52,7 @@ oop_field(HotSpotResolvedJavaType, javaMirror, "Ljava/lang/Class;") \ oop_field(HotSpotResolvedJavaType, simpleName, "Ljava/lang/String;") \ int_field(HotSpotResolvedJavaType, accessFlags) \ - long_field(HotSpotResolvedJavaType, prototypeHeader) \ + long_field(HotSpotResolvedJavaType, initialMarkWord) \ boolean_field(HotSpotResolvedJavaType, hasFinalizer) \ boolean_field(HotSpotResolvedJavaType, hasFinalizableSubclass) \ int_field(HotSpotResolvedJavaType, superCheckOffset) \