# HG changeset patch # User Roland Schatz # Date 1398260918 -7200 # Node ID 9363fffa8b07c4b1dbfcc8862477cc521ff8e793 # Parent 7f5c9079e24a23dc1d0029ec24340bb2304af994# Parent 518a7f487c4f59eba994481aa76ebdb7c015d536 Merge. diff -r 518a7f487c4f -r 9363fffa8b07 .hgignore --- a/.hgignore Wed Apr 23 15:22:20 2014 +0200 +++ b/.hgignore Wed Apr 23 15:48:38 2014 +0200 @@ -5,6 +5,7 @@ ^mx/netbeans-config.zip ^mx/netbeans-config-libs.zip ^mx/eclipse-launches +^mx/jmh ^mx/currentAnnotationProcessors ^mx/ecj.jar ^mx/includes diff -r 518a7f487c4f -r 9363fffa8b07 CHANGELOG.md --- a/CHANGELOG.md Wed Apr 23 15:22:20 2014 +0200 +++ b/CHANGELOG.md Wed Apr 23 15:48:38 2014 +0200 @@ -5,9 +5,19 @@ * Explicit support for oop compression/uncompression in high level graph. * LIRGenerator refactoring. * Explicit types for inputs (InputType enum). +* Added graal.version system property to Graal enabled VM builds. +* Transitioned to JDK 8 as minimum JDK level for Graal. +* Added support for stack introspection. * ... ### Truffle +* The method CallTarget#call takes now a variable number of Object arguments. +* Support for collecting stack traces and for accessing the current frame in slow paths. +* Renamed CallNode to DirectCallNode. +* Renamed TruffleRuntime#createCallNode to TruffleRuntime#createDirectCallNode. +* Added IndirectCallNode for calls with a changing CallTarget. +* Added TruffleRuntime#createIndirectCallNode to create an IndirectCallNode. +* DirectCallNode#inline was renamed to DirectCallNode#forceInlining(). * ... ## Version 0.2 @@ -21,7 +31,8 @@ * New (tested) invariant that equality comparisons for `JavaType`/`JavaMethod`/`JavaField` values use `.equals()` instead of `==`. * Made graph caching compilation-local. * Added AllocSpy tool for analyzing allocation in Graal using the [Java Allocation Instrumenter](https://code.google.com/p/java-allocation-instrumenter/). -* Initial support for memory arithmetic operations on x86 +* Initial support for memory arithmetic operations on x86. +* Expanded Debug logging/dumping API to avoid allocation when this Debug facilities are not enabled. ### Truffle * New API `TruffleRuntime#createCallNode` to create call nodes and to give the runtime system control over its implementation. diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.alloc/src/com/oracle/graal/alloc/ComputeBlockOrder.java --- a/graal/com.oracle.graal.alloc/src/com/oracle/graal/alloc/ComputeBlockOrder.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.alloc/src/com/oracle/graal/alloc/ComputeBlockOrder.java Wed Apr 23 15:48:38 2014 +0200 @@ -25,6 +25,7 @@ import java.util.*; +import com.oracle.graal.compiler.common.cfg.*; import com.oracle.graal.nodes.cfg.*; /** @@ -34,12 +35,12 @@ * with the most likely path that was left out during this process. The process iteratively * continues until all blocks are scheduled. Additionally, it is guaranteed that all blocks of a * loop are scheduled before any block following the loop is scheduled. - * + * * The machine code generator order includes reordering of loop headers such that the backward jump * is a conditional jump if there is only one loop end block. Additionally, the target of loop * backward jumps are always marked as aligned. Aligning the target of conditional jumps does not * bring a measurable benefit and is therefore avoided to keep the code size small. - * + * * The linear scan register allocator order has an additional mechanism that prevents merge nodes * from being scheduled if there is at least one highly likely predecessor still unscheduled. This * increases the probability that the merge node and the corresponding predecessor are more closely @@ -63,7 +64,7 @@ /** * Computes the block order used for the linear scan register allocator. - * + * * @return sorted list of blocks */ public static > List computeLinearScanOrder(int blockCount, T startBlock, BlocksToDoubles blockProbabilities) { @@ -77,7 +78,7 @@ /** * Computes the block order used for code emission. - * + * * @return sorted list of blocks */ public static > List computeCodeEmittingOrder(int blockCount, T startBlock, BlocksToDoubles blockProbabilities) { @@ -151,7 +152,6 @@ /** * Add a linear path to the code emission order greedily following the most likely successor. */ - @SuppressWarnings("unchecked") private static > void addPathToCodeEmittingOrder(T initialBlock, List order, PriorityQueue worklist, BitSet visitedBlocks, BlocksToDoubles blockProbabilities) { T block = initialBlock; while (block != null) { @@ -166,17 +166,17 @@ addBlock(block, order); } - Loop loop = block.getLoop(); + Loop loop = block.getLoop(); if (block.isLoopEnd() && skipLoopHeader(loop.header)) { // This is the only loop end of a skipped loop header. // Add the header immediately afterwards. - addBlock((T) loop.header, order); + addBlock(loop.header, order); // Make sure the loop successors of the loop header are aligned // as they are the target // of the backward jump. - for (Block successor : loop.header.getSuccessors()) { + for (T successor : loop.header.getSuccessors()) { if (successor.getLoopDepth() == block.getLoopDepth()) { successor.setAlign(true); } @@ -230,8 +230,8 @@ * Skip the loop header block if the loop consists of more than one block and it has only a * single loop end block. */ - private static boolean skipLoopHeader(AbstractBlock block) { - return (block.isLoopHeader() && !block.isLoopEnd() && block.getLoop().loopBegin().loopEnds().count() == 1); + private static > boolean skipLoopHeader(AbstractBlock block) { + return (block.isLoopHeader() && !block.isLoopEnd() && block.getLoop().numBackedges() == 1); } /** diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/BytecodeFrame.java --- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/BytecodeFrame.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/BytecodeFrame.java Wed Apr 23 15:48:38 2014 +0200 @@ -94,6 +94,43 @@ public final boolean duringCall; /** + * This BCI should be used for frame states that are built for code with no meaningful BCI. + */ + public static final int UNKNOWN_BCI = -5; + + /** + * The BCI for exception unwind. This is synthetic code and has no representation in bytecode. + * In contrast with {@link #AFTER_EXCEPTION_BCI}, at this point, if the method is synchronized, + * the monitor is still held. + */ + public static final int UNWIND_BCI = -1; + + /** + * The BCI for the state before starting to execute a method. Note that if the method is + * synchronized, the monitor is not yet held. + */ + public static final int BEFORE_BCI = -2; + + /** + * The BCI for the state after finishing the execution of a method and returning normally. Note + * that if the method was synchronized the monitor is already released. + */ + public static final int AFTER_BCI = -3; + + /** + * The BCI for exception unwind. This is synthetic code and has no representation in bytecode. + * In contrast with {@link #UNWIND_BCI}, at this point, if the method is synchronized, the + * monitor is already released. + */ + public static final int AFTER_EXCEPTION_BCI = -4; + + /** + * This BCI should be used for states that cannot be the target of a deoptimization, like + * snippet frame states. + */ + public static final int INVALID_FRAMESTATE_BCI = -6; + + /** * Creates a new frame object. * * @param caller the caller frame (which may be {@code null}) diff -r 518a7f487c4f -r 9363fffa8b07 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 Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CodeCacheProvider.java Wed Apr 23 15:48:38 2014 +0200 @@ -34,18 +34,18 @@ /** * Adds the given compilation result as an implementation of the given method without making it * the default implementation. - * + * * @param method a method to which the executable code is begin added * @param compResult the compilation result to be added * @param speculationLog the speculation log to be used - * @return a reference to the compiled and ready-to-run code or null if the code installation - * failed + * @return a reference to the compiled and ready-to-run code or throws a + * {@link BailoutException} if the code installation failed */ - InstalledCode addMethod(ResolvedJavaMethod method, CompilationResult compResult, SpeculationLog speculationLog); + InstalledCode addMethod(ResolvedJavaMethod method, CompilationResult compResult, SpeculationLog speculationLog, InstalledCode predefinedInstalledCode); /** * Sets the given compilation result as the default implementation of the given method. - * + * * @param method a method to which the executable code is begin added * @param compResult the compilation result to be added * @return a reference to the compiled and ready-to-run code or null if the code installation @@ -55,11 +55,11 @@ /** * Returns a disassembly of some compiled code. - * + * * @param compResult some compiled code * @param installedCode the result of installing the code in {@code compResult} or null if the * code has not yet been installed - * + * * @return a disassembly. This will be of length 0 if the runtime does not support * disassembling. */ @@ -73,15 +73,14 @@ /** * Minimum size of the stack area reserved for outgoing parameters. This area is reserved in all * cases, even when the compiled method has no regular call instructions. - * + * * @return the minimum size of the outgoing parameter area in bytes */ int getMinimumOutgoingSize(); /** - * Determines if a {@link DataPatch} should be created for a given - * {@linkplain Constant#getPrimitiveAnnotation() annotated} primitive constant that part of a - * {@link CompilationResult}. A data patch is always created for an object constant. + * Determines if a {@link DataPatch} should be created for a given primitive constant that is + * part of a {@link CompilationResult}. A data patch is always created for an object constant. */ boolean needsDataPatch(Constant constant); diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CodeUtil.java --- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CodeUtil.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CodeUtil.java Wed Apr 23 15:48:38 2014 +0200 @@ -22,7 +22,6 @@ */ package com.oracle.graal.api.code; -import java.lang.reflect.*; import java.util.*; import com.oracle.graal.api.meta.*; @@ -342,7 +341,7 @@ int sigCount = sig.getParameterCount(false); JavaType[] argTypes; int argIndex = 0; - if (!Modifier.isStatic(method.getModifiers())) { + if (!method.isStatic()) { argTypes = new JavaType[sigCount + 1]; argTypes[argIndex++] = method.getDeclaringClass(); } else { diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CompilationResult.java --- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CompilationResult.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CompilationResult.java Wed Apr 23 15:48:38 2014 +0200 @@ -368,7 +368,7 @@ * starting address of the table. This type of table maybe generated when translating a * multi-way branch based on a key value from a dense value set (e.g. the {@code tableswitch} * JVM instruction). - * + * * The table is indexed by the contiguous range of integers from {@link #low} to {@link #high} * inclusive. */ @@ -460,7 +460,7 @@ private final List exceptionHandlers = new ArrayList<>(); private final List marks = new ArrayList<>(); - private int frameSize = -1; + private int totalFrameSize = -1; private int customStackAreaOffset = -1; private int registerRestoreEpilogueOffset = -1; @@ -525,18 +525,29 @@ } /** - * Sets the frame size in bytes. Does not include the return address pushed onto the stack, if - * any. - * + * The total frame size of the method in bytes. This includes the return address pushed onto the + * stack, if any. + * + * @return the frame size + */ + public int getTotalFrameSize() { + assert totalFrameSize != -1 : "frame size not yet initialized!"; + return totalFrameSize; + } + + /** + * Sets the total frame size in bytes. This includes the return address pushed onto the stack, + * if any. + * * @param size the size of the frame in bytes */ - public void setFrameSize(int size) { - frameSize = size; + public void setTotalFrameSize(int size) { + totalFrameSize = size; } /** * Sets the machine that has been generated by the compiler. - * + * * @param code the machine code generated * @param size the size of the machine code */ @@ -548,7 +559,7 @@ /** * Records a reference to the data section in the code section (e.g. to load an integer or * floating point constant). - * + * * @param codePos the position in the code where the data reference occurs * @param data the data that is referenced */ @@ -559,7 +570,7 @@ /** * Records a reference to an inlined constant in the code section (e.g. to load a constant oop). - * + * * @param codePos the position in the code where the inlined constant occurs * @param data the data that is referenced */ @@ -570,7 +581,7 @@ /** * Records a call in the code array. - * + * * @param codePos the position of the call in the code array * @param size the size of the call instruction * @param target the being called @@ -584,7 +595,7 @@ /** * Records an exception handler for this method. - * + * * @param codePos the position in the code that is covered by the handler * @param handlerPos the position of the handler */ @@ -594,7 +605,7 @@ /** * Records an infopoint in the code array. - * + * * @param codePos the position of the infopoint in the code array * @param debugInfo the debug info for the infopoint */ @@ -604,10 +615,10 @@ /** * Records a custom infopoint in the code section. - * + * * Compiler implementations can use this method to record non-standard infopoints, which are not * handled by the dedicated methods like {@link #recordCall}. - * + * * @param infopoint the infopoint to record, usually a derived class from {@link Infopoint} */ public void addInfopoint(Infopoint infopoint) { @@ -621,7 +632,7 @@ /** * Records an instruction mark within this method. - * + * * @param codePos the position in the code that is covered by the handler * @param markId the identifier for this mark * @param references an array of other marks that this mark references @@ -636,7 +647,7 @@ * Allows a method to specify the offset of the epilogue that restores the callee saved * registers. Must be called iff the method is a callee saved method and stores callee registers * on the stack. - * + * * @param registerRestoreEpilogueOffset the offset in the machine code where the epilogue begins */ public void setRegisterRestoreEpilogueOffset(int registerRestoreEpilogueOffset) { @@ -645,16 +656,6 @@ } /** - * The frame size of the method in bytes. - * - * @return the frame size - */ - public int getFrameSize() { - assert frameSize != -1 : "frame size not yet initialized!"; - return frameSize; - } - - /** * @return the code offset of the start of the epilogue that restores all callee saved * registers, or -1 if this is not a callee saved method */ @@ -664,7 +665,7 @@ /** * Offset in bytes for the custom stack area (relative to sp). - * + * * @return the offset in bytes */ public int getCustomStackAreaOffset() { diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/InstalledCode.java --- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/InstalledCode.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/InstalledCode.java Wed Apr 23 15:48:38 2014 +0200 @@ -22,41 +22,66 @@ */ package com.oracle.graal.api.code; -import com.oracle.graal.api.meta.*; - /** * Represents a compiled instance of a method. It may have been invalidated or removed in the * meantime. */ -public interface InstalledCode { +public class InstalledCode { + + /** + * Raw address of this code blob. + */ + private long address; + + /** + * Counts how often the address field was reassigned. + */ + private long version; /** - * Returns the method (if any) to which the installed code belongs. + * @return the address of this code blob */ - ResolvedJavaMethod getMethod(); + public final long getAddress() { + return address; + } + + /** + * @return the address of this code blob + */ + public final long getVersion() { + return version; + } /** * Returns the start address of this installed code if it is {@linkplain #isValid() valid}, 0 * otherwise. */ - long getStart(); + public long getStart() { + return 0; + } /** * Returns a copy of this installed code if it is {@linkplain #isValid() valid}, null otherwise. */ - byte[] getCode(); + public byte[] getCode() { + return null; + } /** * @return true if the code represented by this object is still valid, false otherwise (may * happen due to deopt, etc.) */ - boolean isValid(); + public boolean isValid() { + return address != 0; + } /** * Invalidates this installed code such that any subsequent invocation will throw an * {@link InvalidInstalledCodeException}. */ - void invalidate(); + public void invalidate() { + throw new UnsupportedOperationException(); + } /** * Executes the installed code with a variable number of arguments. @@ -64,5 +89,8 @@ * @param args the array of object arguments * @return the value returned by the executed code */ - Object executeVarargs(Object... args) throws InvalidInstalledCodeException; + @SuppressWarnings("unused") + public Object executeVarargs(Object... args) throws InvalidInstalledCodeException { + throw new UnsupportedOperationException(); + } } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/NativeFunctionInterface.java --- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/NativeFunctionInterface.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/NativeFunctionInterface.java Wed Apr 23 15:48:38 2014 +0200 @@ -32,7 +32,7 @@ /** * Resolves and returns a handle to an open native library. This method will open the library * only if it is not already open. - * + * * @param libPath the absolute path to the library * @return the resolved library handle * @throws UnsatisfiedLinkError if the library could not be found or opened @@ -48,7 +48,7 @@ /** * Resolves the function pointer {@code NativeFunctionPointer} of a native function. - * + * * @param libraries the ordered list of libraries to search for the function * @param name the name of the function to be resolved * @return a pointer to the native function @@ -60,7 +60,7 @@ * Resolves a function name to a {@linkplain NativeFunctionHandle handle} that can be called * with a given signature. The signature contains the types of the arguments that will be passed * to the handle when it is {@linkplain NativeFunctionHandle#call(Object...) called}. - * + * * @param library the handle to a resolved library * @param name the name of the function to be resolved * @param returnType the type of the return value @@ -68,26 +68,26 @@ * @return the function handle of the native function * @throws UnsatisfiedLinkError if the function handle could not be resolved */ - NativeFunctionHandle getFunctionHandle(NativeLibraryHandle library, String name, Class returnType, Class... argumentTypes); + NativeFunctionHandle getFunctionHandle(NativeLibraryHandle library, String name, Class returnType, Class... argumentTypes); /** * Resolves a function pointer to a {@linkplain NativeFunctionHandle handle} that can be called * with a given signature. The signature contains the types of the arguments that will be passed * to the handle when it is {@linkplain NativeFunctionHandle#call(Object...) called}. - * + * * @param functionPointer a function pointer * @param returnType the type of the return value * @param argumentTypes the types of the arguments * @return the function handle of the native function * @throws UnsatisfiedLinkError the function handle could not be created */ - NativeFunctionHandle getFunctionHandle(NativeFunctionPointer functionPointer, Class returnType, Class... argumentTypes); + NativeFunctionHandle getFunctionHandle(NativeFunctionPointer functionPointer, Class returnType, Class... argumentTypes); /** * Resolves a function name to a {@linkplain NativeFunctionHandle handle} that can be called * with a given signature. The signature contains the types of the arguments that will be passed * to the handle when it is {@linkplain NativeFunctionHandle#call(Object...) called}. - * + * * @param libraries the ordered list of libraries to search for the function * @param name the name of the function to be resolved * @param returnType the type of the return value @@ -95,13 +95,13 @@ * @return the function handle of the native function * @throws UnsatisfiedLinkError if the function handle could not be created */ - NativeFunctionHandle getFunctionHandle(NativeLibraryHandle[] libraries, String name, Class returnType, Class... argumentTypes); + NativeFunctionHandle getFunctionHandle(NativeLibraryHandle[] libraries, String name, Class returnType, Class... argumentTypes); /** * Resolves a function name to a {@linkplain NativeFunctionHandle handle} that can be called * with a given signature. The signature contains the types of the arguments that will be passed * to the handle when it is {@linkplain NativeFunctionHandle#call(Object...) called}. - * + * * @param name the name of the function to be resolved * @param returnType the type of the return value * @param argumentTypes the types of the arguments @@ -110,11 +110,11 @@ * {@linkplain #isDefaultLibrarySearchSupported() supported} or if the function * could not be resolved */ - NativeFunctionHandle getFunctionHandle(String name, Class returnType, Class... argumentTypes); + NativeFunctionHandle getFunctionHandle(String name, Class returnType, Class... argumentTypes); /** * Creates a {@link NativeFunctionPointer} from a raw value. - * + * * @param rawValue raw function pointer * @return {@code NativeFunctionPointer} for {@code rawValue} */ diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/SpeculationLog.java --- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/SpeculationLog.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/SpeculationLog.java Wed Apr 23 15:48:38 2014 +0200 @@ -31,7 +31,7 @@ * Manages a list of unique deoptimization reasons. * */ -public final class SpeculationLog { +public abstract class SpeculationLog { private volatile Object lastFailed; private volatile Collection speculations; private Set failedSpeculations; @@ -54,7 +54,7 @@ return true; } - public Constant speculate(Object reason) { + protected void addSpeculation(Object reason) { assert maySpeculate(reason); if (speculations == null) { synchronized (this) { @@ -64,6 +64,7 @@ } } speculations.add(reason); - return Constant.forObject(reason); } + + public abstract Constant speculate(Object reason); } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/TypeCheckHints.java --- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/TypeCheckHints.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/TypeCheckHints.java Wed Apr 23 15:48:38 2014 +0200 @@ -23,8 +23,6 @@ package com.oracle.graal.api.code; import static com.oracle.graal.api.meta.MetaUtil.*; -import static java.lang.reflect.Modifier.*; - import java.util.*; import com.oracle.graal.api.meta.*; @@ -83,7 +81,7 @@ /** * Derives hint information for use when generating the code for a type check instruction. - * + * * @param targetType the target type of the type check * @param profile the profiling information available for the instruction (if any) * @param assumptions the object in which speculations are recorded. This is null if @@ -151,10 +149,10 @@ /** * Determines if a given type can have subtypes other than itself. This analysis is purely * static; no assumptions are made. - * + * * @return true if {@code type} can have subtypes */ public static boolean canHaveSubtype(ResolvedJavaType type) { - return !isFinal(getElementalType(type).getModifiers()); + return !getElementalType(type).isFinal(); } } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/package-info.java --- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/package-info.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/package-info.java Wed Apr 23 15:48:38 2014 +0200 @@ -23,7 +23,7 @@ /** * Package that defines the interface between a Java application that wants to install code and the runtime. * The runtime provides in implementation of the {@link com.oracle.graal.api.code.CodeCacheProvider} interface. - * The method {@link com.oracle.graal.api.code.CodeCacheProvider#addMethod(com.oracle.graal.api.meta.ResolvedJavaMethod, CompilationResult, SpeculationLog)} + * The method {@link com.oracle.graal.api.code.CodeCacheProvider#addMethod(com.oracle.graal.api.meta.ResolvedJavaMethod, CompilationResult, SpeculationLog, InstalledCode)} * can be used to install code for a given method. */ package com.oracle.graal.api.code; diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/stack/InspectedFrame.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/stack/InspectedFrame.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.api.code.stack; + +import com.oracle.graal.api.meta.*; + +public interface InspectedFrame { + + /** + * Returns the value of the local at the given index. Currently only works for object values. + * This value is a copy iff {@link #isVirtual(int)} is true. + */ + Object getLocal(int index); + + /** + * Returns whether the local at the given index is a virtual object, and therefore the object + * returned by {@link #getLocal(int)} is a copy. + */ + boolean isVirtual(int index); + + /** + * Returns true if the stack frame is a compiled stack frame and there are virtual objects + * anywhere in the current state of the compiled method. This can return true even if + * {@link #isVirtual(int)} return false for all locals. + */ + boolean hasVirtualObjects(); + + /** + * This method will materialize all virtual objects, deoptimize the stack frame and make sure + * that subsequent execution of the deoptimized frame uses the materialized values. + */ + void materializeVirtualObjects(boolean invalidateCode); + + /** + * @return the current bytecode index + */ + int getBytecodeIndex(); + + /** + * @return the current method + */ + ResolvedJavaMethod getMethod(); +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/stack/StackIntrospection.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/stack/StackIntrospection.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.api.code.stack; + +import com.oracle.graal.api.meta.*; + +public interface StackIntrospection { + + /** + * Accesses the current stack, returning a collection of {@long InspectedFrame}s that can be + * used to inspect the stack frames' contents. + * + * @param initialMethods if this is non-{@code null}, then the stack trace will start at these + * methods + * @param matchingMethods if this is non-{@code null}, then only matching stack frames are + * returned + */ + Iterable getStackTrace(ResolvedJavaMethod[] initialMethods, ResolvedJavaMethod[] matchingMethods, int initialSkip); +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/FieldUniverse.java --- a/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/FieldUniverse.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/FieldUniverse.java Wed Apr 23 15:48:38 2014 +0200 @@ -35,7 +35,7 @@ public final Map fields = new HashMap<>(); public FieldUniverse() { - for (Class c : classes) { + for (Class c : classes) { for (Field f : c.getDeclaredFields()) { ResolvedJavaField field = metaAccess.lookupJavaField(f); fields.put(f, field); diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/MethodUniverse.java --- a/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/MethodUniverse.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/MethodUniverse.java Wed Apr 23 15:48:38 2014 +0200 @@ -36,12 +36,12 @@ public final Map, ResolvedJavaMethod> constructors = new HashMap<>(); public MethodUniverse() { - for (Class c : classes) { + for (Class c : classes) { for (Method m : c.getDeclaredMethods()) { ResolvedJavaMethod method = metaAccess.lookupJavaMethod(m); methods.put(m, method); } - for (Constructor m : c.getDeclaredConstructors()) { + for (Constructor m : c.getDeclaredConstructors()) { constructors.put(m, metaAccess.lookupJavaConstructor(m)); } } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/NameAndSignature.java --- a/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/NameAndSignature.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/NameAndSignature.java Wed Apr 23 15:48:38 2014 +0200 @@ -34,8 +34,8 @@ public static final MetaAccessProvider metaAccess = Graal.getRequiredCapability(RuntimeProvider.class).getHostBackend().getProviders().getMetaAccess(); final String name; - final Class returnType; - final Class[] parameterTypes; + final Class returnType; + final Class[] parameterTypes; public NameAndSignature(Method m) { this.name = m.getName(); @@ -61,7 +61,7 @@ public String toString() { StringBuilder sb = new StringBuilder(name + "("); String sep = ""; - for (Class p : parameterTypes) { + for (Class p : parameterTypes) { sb.append(sep); sep = ", "; sb.append(p.getName()); diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestConstantReflectionProvider.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestConstantReflectionProvider.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.api.meta.test; + +import static org.junit.Assert.*; + +import java.lang.reflect.*; + +import org.junit.*; + +import com.oracle.graal.api.meta.*; + +/** + * Tests for {@link ConstantReflectionProvider}. It assumes an implementation of the interface that + * actually returns non-null results for access operations that are possible, i.e., the tests will + * fail for an implementation that spuriously returns null (which is allowed by the specification). + */ +public class TestConstantReflectionProvider extends TypeUniverse { + + @Test + public void constantEqualsTest() { + for (Constant c1 : constants) { + for (Constant c2 : constants) { + // test symmetry + assertEquals(constantReflection.constantEquals(c1, c2), constantReflection.constantEquals(c2, c1)); + if (c1.getKind() != Kind.Object && c2.getKind() != Kind.Object) { + assertEquals(c1.equals(c2), constantReflection.constantEquals(c2, c1)); + } + } + } + } + + @Test + public void readArrayLengthTest() { + for (Constant c : constants) { + Integer actual = constantReflection.readArrayLength(c); + if (c.getKind() != Kind.Object || c.isNull() || !snippetReflection.asObject(c).getClass().isArray()) { + assertNull(actual); + } else { + assertNotNull(actual); + int actualInt = actual; + assertEquals(Array.getLength(snippetReflection.asObject(c)), actualInt); + } + } + } + + @Test + public void boxTest() { + for (Constant c : constants) { + Constant boxed = constantReflection.boxPrimitive(c); + if (c.getKind().isPrimitive()) { + assertTrue(boxed.getKind().isObject()); + assertFalse(boxed.isNull()); + } + } + + assertEquals(Long.valueOf(42), snippetReflection.asObject(constantReflection.boxPrimitive(Constant.forLong(42)))); + assertEquals(Integer.valueOf(666), snippetReflection.asObject(constantReflection.boxPrimitive(Constant.forInt(666)))); + assertEquals(Byte.valueOf((byte) 123), snippetReflection.asObject(constantReflection.boxPrimitive(Constant.forByte((byte) 123)))); + assertSame(Boolean.TRUE, snippetReflection.asObject(constantReflection.boxPrimitive(Constant.forBoolean(true)))); + + assertNull(constantReflection.boxPrimitive(Constant.NULL_OBJECT)); + assertNull(constantReflection.boxPrimitive(snippetReflection.forObject("abc"))); + } + + @Test + public void unboxTest() { + for (Constant c : constants) { + Constant unboxed = constantReflection.unboxPrimitive(c); + if (unboxed != null) { + assertFalse(unboxed.getKind().isObject()); + } + } + + assertEquals(Constant.forLong(42), constantReflection.unboxPrimitive(snippetReflection.forObject(Long.valueOf(42)))); + assertEquals(Constant.forInt(666), constantReflection.unboxPrimitive(snippetReflection.forObject(Integer.valueOf(666)))); + assertEquals(Constant.forByte((byte) 123), constantReflection.unboxPrimitive(snippetReflection.forObject(Byte.valueOf((byte) 123)))); + assertSame(Constant.forBoolean(true), constantReflection.unboxPrimitive(snippetReflection.forObject(Boolean.TRUE))); + + assertNull(constantReflection.unboxPrimitive(Constant.NULL_OBJECT)); + assertNull(constantReflection.unboxPrimitive(snippetReflection.forObject("abc"))); + } + + @Test + public void testAsJavaType() { + for (Constant c : constants) { + ResolvedJavaType type = constantReflection.asJavaType(c); + + Object o = snippetReflection.asBoxedValue(c); + if (o instanceof Class) { + assertEquals(metaAccess.lookupJavaType((Class) o), type); + } else { + assertNull(type); + } + } + + } +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestJavaField.java --- a/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestJavaField.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestJavaField.java Wed Apr 23 15:48:38 2014 +0200 @@ -68,7 +68,7 @@ @Test public void getDeclaringClassTest() { for (Map.Entry e : fields.entrySet()) { - Class expected = e.getKey().getDeclaringClass(); + Class expected = e.getKey().getDeclaringClass(); ResolvedJavaType actual = e.getValue().getDeclaringClass(); assertTrue(actual.equals(metaAccess.lookupJavaType(expected))); } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestJavaMethod.java --- a/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestJavaMethod.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestJavaMethod.java Wed Apr 23 15:48:38 2014 +0200 @@ -48,7 +48,7 @@ @Test public void getDeclaringClassTest() { for (Map.Entry e : methods.entrySet()) { - Class expected = e.getKey().getDeclaringClass(); + Class expected = e.getKey().getDeclaringClass(); ResolvedJavaType actual = e.getValue().getDeclaringClass(); assertTrue(actual.equals(metaAccess.lookupJavaType(expected))); } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestJavaType.java --- a/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestJavaType.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestJavaType.java Wed Apr 23 15:48:38 2014 +0200 @@ -38,7 +38,7 @@ @Test public void getKindTest() { - for (Class c : classes) { + for (Class c : classes) { JavaType type = metaAccess.lookupJavaType(c); Kind expected = Kind.fromJavaClass(c); Kind actual = type.getKind(); diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestMetaAccessProvider.java --- a/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestMetaAccessProvider.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestMetaAccessProvider.java Wed Apr 23 15:48:38 2014 +0200 @@ -38,7 +38,7 @@ @Test public void lookupJavaTypeTest() { - for (Class c : classes) { + for (Class c : classes) { ResolvedJavaType type = metaAccess.lookupJavaType(c); assertNotNull(type); assertEquals(c.getModifiers(), type.getModifiers()); @@ -51,7 +51,7 @@ @Test public void lookupJavaMethodTest() { - for (Class c : classes) { + for (Class c : classes) { for (Method reflect : c.getDeclaredMethods()) { ResolvedJavaMethod method = metaAccess.lookupJavaMethod(reflect); assertNotNull(method); @@ -65,7 +65,7 @@ @Test public void lookupJavaFieldTest() { - for (Class c : classes) { + for (Class c : classes) { for (Field reflect : c.getDeclaredFields()) { ResolvedJavaField field = metaAccess.lookupJavaField(reflect); assertNotNull(field); @@ -81,7 +81,7 @@ public void lookupJavaTypeConstantTest() { for (Constant c : constants) { if (c.getKind() == Kind.Object && !c.isNull()) { - Object o = c.asObject(); + Object o = snippetReflection.asObject(c); ResolvedJavaType type = metaAccess.lookupJavaType(c); assertNotNull(type); assertTrue(type.equals(metaAccess.lookupJavaType(o.getClass()))); @@ -90,31 +90,4 @@ } } } - - @Test - public void constantEqualsTest() { - for (Constant c1 : constants) { - for (Constant c2 : constants) { - // test symmetry - assertEquals(constantReflection.constantEquals(c1, c2), constantReflection.constantEquals(c2, c1)); - if (c1.getKind() != Kind.Object && c2.getKind() != Kind.Object) { - assertEquals(c1.equals(c2), constantReflection.constantEquals(c2, c1)); - } - } - } - } - - @Test - public void lookupArrayLengthTest() { - for (Constant c : constants) { - Integer actual = constantReflection.lookupArrayLength(c); - if (c.getKind() != Kind.Object || c.isNull() || !c.asObject().getClass().isArray()) { - assertNull(actual); - } else { - assertNotNull(actual); - int actualInt = actual; - assertEquals(Array.getLength(c.asObject()), actualInt); - } - } - } } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaField.java --- a/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaField.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaField.java Wed Apr 23 15:48:38 2014 +0200 @@ -78,7 +78,7 @@ if (isStatic(field.getModifiers())) { try { Object expected = field.get(null); - Object actual = e.getValue().readConstantValue(null).asBoxedValue(); + Object actual = snippetReflection.asBoxedValue(e.getValue().readConstantValue(null)); assertEquals(expected, actual); } catch (IllegalArgumentException | IllegalAccessException e1) { } @@ -86,7 +86,7 @@ try { Object receiver = field.getDeclaringClass().newInstance(); Object expected = field.get(receiver); - Object actual = e.getValue().readConstantValue(Constant.forObject(receiver)).asBoxedValue(); + Object actual = snippetReflection.asBoxedValue(e.getValue().readConstantValue(snippetReflection.forObject(receiver))); assertEquals(expected, actual); } catch (InstantiationException | IllegalArgumentException | IllegalAccessException e1) { } @@ -95,16 +95,16 @@ ResolvedJavaField field = metaAccess.lookupJavaField(getClass().getDeclaredField("stringField")); for (Object receiver : new Object[]{this, null, new String()}) { - Constant value = field.readConstantValue(Constant.forObject(receiver)); + Constant value = field.readConstantValue(snippetReflection.forObject(receiver)); assertNull(value); } ResolvedJavaField constField = metaAccess.lookupJavaField(getClass().getDeclaredField("constantStringField")); for (Object receiver : new Object[]{this, null, new String()}) { - Constant value = constField.readConstantValue(Constant.forObject(receiver)); + Constant value = constField.readConstantValue(snippetReflection.forObject(receiver)); if (value != null) { Object expected = "constantField"; - assertTrue(value.asObject() == expected); + assertTrue(snippetReflection.asObject(value) == expected); } } } @@ -117,7 +117,7 @@ if (isStatic(field.getModifiers())) { try { Object expected = field.get(null); - Object actual = e.getValue().readValue(null).asBoxedValue(); + Object actual = snippetReflection.asBoxedValue(e.getValue().readValue(null)); assertEquals(expected, actual); } catch (IllegalArgumentException | IllegalAccessException e1) { } @@ -131,7 +131,7 @@ ResolvedJavaField rf = metaAccess.lookupJavaField(f); Object receiver = isStatic(f.getModifiers()) ? null : testString; Object expected = f.get(receiver); - Object actual = rf.readValue(receiver == null ? null : Constant.forObject(receiver)).asBoxedValue(); + Object actual = snippetReflection.asBoxedValue(rf.readValue(receiver == null ? null : snippetReflection.forObject(receiver))); assertEquals(expected, actual); } } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaMethod.java --- a/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaMethod.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaMethod.java Wed Apr 23 15:48:38 2014 +0200 @@ -22,7 +22,6 @@ */ package com.oracle.graal.api.meta.test; -import static java.lang.reflect.Modifier.*; import static org.junit.Assert.*; import java.lang.annotation.*; @@ -52,9 +51,9 @@ if (code == null) { assertTrue(m.getCodeSize() == 0); } else { - if (isAbstract(m.getModifiers())) { + if (m.isAbstract()) { assertTrue(code.length == 0); - } else if (!isNative(m.getModifiers())) { + } else if (!m.isNative()) { assertTrue(code.length > 0); } } @@ -69,9 +68,9 @@ for (Map.Entry e : methods.entrySet()) { ResolvedJavaMethod m = e.getValue(); int codeSize = m.getCodeSize(); - if (isAbstract(m.getModifiers())) { + if (m.isAbstract()) { assertTrue(codeSize == 0); - } else if (!isNative(m.getModifiers())) { + } else if (!m.isNative()) { assertTrue(codeSize > 0); } } @@ -128,19 +127,33 @@ } @Test - public void canBeStaticallyBoundTest() { + public void isSynchronizedTest() { for (Map.Entry e : methods.entrySet()) { ResolvedJavaMethod m = e.getValue(); - assertEquals(m.canBeStaticallyBound(), canBeStaticallyBound(e.getKey().getModifiers())); + assertEquals(Modifier.isSynchronized(e.getKey().getModifiers()), m.isSynchronized()); } for (Map.Entry, ResolvedJavaMethod> e : constructors.entrySet()) { ResolvedJavaMethod m = e.getValue(); - assertEquals(m.canBeStaticallyBound(), canBeStaticallyBound(e.getKey().getModifiers())); + assertEquals(Modifier.isSynchronized(e.getKey().getModifiers()), m.isSynchronized()); } } - private static boolean canBeStaticallyBound(int modifiers) { - return (Modifier.isFinal(modifiers) || Modifier.isPrivate(modifiers) || Modifier.isStatic(modifiers)) && !Modifier.isAbstract(modifiers); + @Test + public void canBeStaticallyBoundTest() { + for (Map.Entry e : methods.entrySet()) { + ResolvedJavaMethod m = e.getValue(); + assertEquals(m.canBeStaticallyBound(), canBeStaticallyBound(e.getKey())); + } + for (Map.Entry, ResolvedJavaMethod> e : constructors.entrySet()) { + ResolvedJavaMethod m = e.getValue(); + assertEquals(m.canBeStaticallyBound(), canBeStaticallyBound(e.getKey())); + } + } + + private static boolean canBeStaticallyBound(Member method) { + int modifiers = method.getModifiers(); + return (Modifier.isFinal(modifiers) || Modifier.isPrivate(modifiers) || Modifier.isStatic(modifiers) || Modifier.isFinal(method.getDeclaringClass().getModifiers())) && + !Modifier.isAbstract(modifiers); } private static String methodWithExceptionHandlers(String p1, Object o2) { diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaType.java --- a/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaType.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaType.java Wed Apr 23 15:48:38 2014 +0200 @@ -46,7 +46,7 @@ @Test public void findInstanceFieldWithOffsetTest() { - for (Class c : classes) { + for (Class c : classes) { ResolvedJavaType type = metaAccess.lookupJavaType(c); Set reflectionFields = getInstanceFields(c, true); for (Field f : reflectionFields) { @@ -62,7 +62,7 @@ @Test public void isInterfaceTest() { - for (Class c : classes) { + for (Class c : classes) { ResolvedJavaType type = metaAccess.lookupJavaType(c); boolean expected = c.isInterface(); boolean actual = type.isInterface(); @@ -72,7 +72,7 @@ @Test public void isInstanceClassTest() { - for (Class c : classes) { + for (Class c : classes) { ResolvedJavaType type = metaAccess.lookupJavaType(c); boolean expected = !c.isArray() && !c.isPrimitive() && !c.isInterface(); boolean actual = type.isInstanceClass(); @@ -82,7 +82,7 @@ @Test public void isArrayTest() { - for (Class c : classes) { + for (Class c : classes) { ResolvedJavaType type = metaAccess.lookupJavaType(c); boolean expected = c.isArray(); boolean actual = type.isArray(); @@ -92,7 +92,7 @@ @Test public void getModifiersTest() { - for (Class c : classes) { + for (Class c : classes) { ResolvedJavaType type = metaAccess.lookupJavaType(c); int expected = c.getModifiers(); int actual = type.getModifiers(); @@ -102,7 +102,7 @@ @Test public void isAssignableFromTest() { - Class[] all = classes.toArray(new Class[classes.size()]); + Class[] all = classes.toArray(new Class[classes.size()]); for (int i = 0; i < all.length; i++) { Class c1 = all[i]; for (int j = i; j < all.length; j++) { @@ -123,7 +123,7 @@ public void isInstanceTest() { for (Constant c : constants) { if (c.getKind() == Kind.Object && !c.isNull()) { - Object o = c.asObject(); + Object o = snippetReflection.asObject(c); Class cls = o.getClass(); while (cls != null) { ResolvedJavaType type = metaAccess.lookupJavaType(cls); @@ -136,7 +136,7 @@ } } - private static Class asExactClass(Class c) { + private static Class asExactClass(Class c) { if (c.isArray()) { if (asExactClass(c.getComponentType()) != null) { return c; @@ -151,10 +151,10 @@ @Test public void asExactTypeTest() { - for (Class c : classes) { + for (Class c : classes) { ResolvedJavaType type = metaAccess.lookupJavaType(c); ResolvedJavaType exactType = type.asExactType(); - Class expected = asExactClass(c); + Class expected = asExactClass(c); if (expected == null) { assertTrue("exact(" + c.getName() + ") != null", exactType == null); } else { @@ -166,9 +166,9 @@ @Test public void getSuperclassTest() { - for (Class c : classes) { + for (Class c : classes) { ResolvedJavaType type = metaAccess.lookupJavaType(c); - Class expected = c.getSuperclass(); + Class expected = c.getSuperclass(); ResolvedJavaType actual = type.getSuperclass(); if (expected == null) { assertTrue(actual == null); @@ -181,9 +181,9 @@ @Test public void getInterfacesTest() { - for (Class c : classes) { + for (Class c : classes) { ResolvedJavaType type = metaAccess.lookupJavaType(c); - Class[] expected = c.getInterfaces(); + Class[] expected = c.getInterfaces(); ResolvedJavaType[] actual = type.getInterfaces(); assertEquals(expected.length, actual.length); for (int i = 0; i < expected.length; i++) { @@ -192,10 +192,10 @@ } } - public Class getSupertype(Class c) { + public Class getSupertype(Class c) { assert !c.isPrimitive(); if (c.isArray()) { - Class componentType = c.getComponentType(); + Class componentType = c.getComponentType(); if (componentType.isPrimitive() || componentType == Object.class) { return Object.class; } @@ -207,7 +207,7 @@ return c.getSuperclass(); } - public Class findLeastCommonAncestor(Class c1Initial, Class c2Initial) { + public Class findLeastCommonAncestor(Class c1Initial, Class c2Initial) { if (c1Initial.isPrimitive() || c2Initial.isPrimitive()) { return null; } else { @@ -228,14 +228,14 @@ @Test public void findLeastCommonAncestorTest() { - Class[] all = classes.toArray(new Class[classes.size()]); + Class[] all = classes.toArray(new Class[classes.size()]); for (int i = 0; i < all.length; i++) { Class c1 = all[i]; for (int j = i; j < all.length; j++) { Class c2 = all[j]; ResolvedJavaType t1 = metaAccess.lookupJavaType(c1); ResolvedJavaType t2 = metaAccess.lookupJavaType(c2); - Class expected = findLeastCommonAncestor(c1, c2); + Class expected = findLeastCommonAncestor(c1, c2); ResolvedJavaType actual = t1.findLeastCommonAncestor(t2); if (expected == null) { assertTrue(actual == null); @@ -268,7 +268,7 @@ abstract static class Abstract4 extends Concrete3 { } - void checkConcreteSubtype(ResolvedJavaType type, Class expected) { + void checkConcreteSubtype(ResolvedJavaType type, Class expected) { ResolvedJavaType subtype = type.findUniqueConcreteSubtype(); if (subtype == null) { // findUniqueConcreteSubtype() is conservative @@ -323,9 +323,9 @@ @Test public void getComponentTypeTest() { - for (Class c : classes) { + for (Class c : classes) { ResolvedJavaType type = metaAccess.lookupJavaType(c); - Class expected = c.getComponentType(); + Class expected = c.getComponentType(); ResolvedJavaType actual = type.getComponentType(); if (expected == null) { assertNull(actual); @@ -337,10 +337,10 @@ @Test public void getArrayClassTest() { - for (Class c : classes) { + for (Class c : classes) { if (c != void.class) { ResolvedJavaType type = metaAccess.lookupJavaType(c); - Class expected = getArrayClass(c); + Class expected = getArrayClass(c); ResolvedJavaType actual = type.getArrayClass(); assertTrue(actual.equals(metaAccess.lookupJavaType(expected))); } @@ -381,14 +381,14 @@ return false; } - static final Map vtables = new HashMap<>(); + static final Map, VTable> vtables = new HashMap<>(); static class VTable { final Map methods = new HashMap<>(); } - static synchronized VTable getVTable(Class c) { + static synchronized VTable getVTable(Class c) { VTable vtable = vtables.get(c); if (vtable == null) { vtable = new VTable(); @@ -411,7 +411,7 @@ return vtable; } - static Set findDeclarations(Method impl, Class c) { + static Set findDeclarations(Method impl, Class c) { Set declarations = new HashSet<>(); NameAndSignature implSig = new NameAndSignature(impl); if (c != null) { @@ -424,7 +424,7 @@ if (!c.isInterface()) { declarations.addAll(findDeclarations(impl, c.getSuperclass())); } - for (Class i : c.getInterfaces()) { + for (Class i : c.getInterfaces()) { declarations.addAll(findDeclarations(impl, i)); } } @@ -438,7 +438,7 @@ @Test public void resolveMethodTest() { - for (Class c : classes) { + for (Class c : classes) { if (c.isInterface() || c.isPrimitive()) { ResolvedJavaType type = metaAccess.lookupJavaType(c); for (Method m : c.getDeclaredMethods()) { @@ -478,7 +478,7 @@ assertEquals(thisMethod, ucm); } - public static Set getInstanceFields(Class c, boolean includeSuperclasses) { + public static Set getInstanceFields(Class c, boolean includeSuperclasses) { if (c.isArray() || c.isPrimitive() || c.isInterface()) { return Collections.emptySet(); } @@ -529,7 +529,7 @@ @Test public void getInstanceFieldsTest() { - for (Class c : classes) { + for (Class c : classes) { ResolvedJavaType type = metaAccess.lookupJavaType(c); for (boolean includeSuperclasses : new boolean[]{true, false}) { Set expected = getInstanceFields(c, includeSuperclasses); @@ -552,7 +552,7 @@ @Test public void getDeclaredMethodsTest() { - for (Class c : classes) { + for (Class c : classes) { ResolvedJavaType type = metaAccess.lookupJavaType(c); Method[] raw = c.getDeclaredMethods(); Set expected = new HashSet<>(); @@ -595,7 +595,7 @@ @Test public void getAnnotationTest() { - for (Class c : classes) { + for (Class c : classes) { ResolvedJavaType type = metaAccess.lookupJavaType(c); for (Annotation a : c.getAnnotations()) { assertEquals(a, type.getAnnotation(a.annotationType())); @@ -605,11 +605,11 @@ @Test public void memberClassesTest() { - for (Class c : classes) { + for (Class c : classes) { ResolvedJavaType type = metaAccess.lookupJavaType(c); assertEquals(c.isLocalClass(), type.isLocal()); assertEquals(c.isMemberClass(), type.isMember()); - Class enclc = c.getEnclosingClass(); + Class enclc = c.getEnclosingClass(); ResolvedJavaType enclt = type.getEnclosingType(); assertFalse(enclc == null ^ enclt == null); if (enclc != null) { @@ -620,7 +620,7 @@ @Test public void classFilePathTest() { - for (Class c : classes) { + for (Class c : classes) { ResolvedJavaType type = metaAccess.lookupJavaType(c); URL path = type.getClassFilePath(); if (type.isPrimitive() || type.isArray()) { diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TypeUniverse.java --- a/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TypeUniverse.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TypeUniverse.java Wed Apr 23 15:48:38 2014 +0200 @@ -32,6 +32,7 @@ import sun.misc.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.api.replacements.*; import com.oracle.graal.api.runtime.*; import com.oracle.graal.phases.util.*; import com.oracle.graal.runtime.*; @@ -46,6 +47,7 @@ public final MetaAccessProvider metaAccess; public final ConstantReflectionProvider constantReflection; + public final SnippetReflectionProvider snippetReflection; public final Collection> classes = new HashSet<>(); public final Map, Class> arrayClasses = new HashMap<>(); public final List constants = new ArrayList<>(); @@ -54,6 +56,7 @@ Providers providers = Graal.getRequiredCapability(RuntimeProvider.class).getHostBackend().getProviders(); metaAccess = providers.getMetaAccess(); constantReflection = providers.getConstantReflection(); + snippetReflection = Graal.getRequiredCapability(SnippetReflectionProvider.class); Unsafe theUnsafe = null; try { theUnsafe = Unsafe.getUnsafe(); @@ -68,10 +71,10 @@ } unsafe = theUnsafe; - Class[] initialClasses = {void.class, boolean.class, byte.class, short.class, char.class, int.class, float.class, long.class, double.class, Object.class, Class.class, ClassLoader.class, + Class[] initialClasses = {void.class, boolean.class, byte.class, short.class, char.class, int.class, float.class, long.class, double.class, Object.class, Class.class, ClassLoader.class, String.class, Serializable.class, Cloneable.class, Test.class, TestMetaAccessProvider.class, List.class, Collection.class, Map.class, Queue.class, HashMap.class, LinkedHashMap.class, IdentityHashMap.class, AbstractCollection.class, AbstractList.class, ArrayList.class}; - for (Class c : initialClasses) { + for (Class c : initialClasses) { addClass(c); } for (Field f : Constant.class.getDeclaredFields()) { @@ -86,22 +89,24 @@ } } } - for (Class c : classes) { + for (Class c : classes) { if (c != void.class && !c.isArray()) { - constants.add(Constant.forObject(Array.newInstance(c, 42))); + constants.add(snippetReflection.forObject(Array.newInstance(c, 42))); } } - constants.add(Constant.forObject(new ArrayList<>())); - constants.add(Constant.forObject(new IdentityHashMap<>())); - constants.add(Constant.forObject(new LinkedHashMap<>())); - constants.add(Constant.forObject(new TreeMap<>())); - constants.add(Constant.forObject(new ArrayDeque<>())); - constants.add(Constant.forObject(new LinkedList<>())); - constants.add(Constant.forObject("a string")); - constants.add(Constant.forObject(42)); + constants.add(snippetReflection.forObject(new ArrayList<>())); + constants.add(snippetReflection.forObject(new IdentityHashMap<>())); + constants.add(snippetReflection.forObject(new LinkedHashMap<>())); + constants.add(snippetReflection.forObject(new TreeMap<>())); + constants.add(snippetReflection.forObject(new ArrayDeque<>())); + constants.add(snippetReflection.forObject(new LinkedList<>())); + constants.add(snippetReflection.forObject("a string")); + constants.add(snippetReflection.forObject(42)); + constants.add(snippetReflection.forObject(String.class)); + constants.add(snippetReflection.forObject(String[].class)); } - public synchronized Class getArrayClass(Class componentType) { + public synchronized Class getArrayClass(Class componentType) { Class arrayClass = arrayClasses.get(componentType); if (arrayClass == null) { arrayClass = Array.newInstance(componentType, 0).getClass(); @@ -110,27 +115,27 @@ return arrayClass; } - public static int dimensions(Class c) { + public static int dimensions(Class c) { if (c.getComponentType() != null) { return 1 + dimensions(c.getComponentType()); } return 0; } - private void addClass(Class c) { + private void addClass(Class c) { if (classes.add(c)) { if (c.getSuperclass() != null) { addClass(c.getSuperclass()); } - for (Class sc : c.getInterfaces()) { + for (Class sc : c.getInterfaces()) { addClass(sc); } - for (Class dc : c.getDeclaredClasses()) { + for (Class dc : c.getDeclaredClasses()) { addClass(dc); } for (Method m : c.getDeclaredMethods()) { addClass(m.getReturnType()); - for (Class p : m.getParameterTypes()) { + for (Class p : m.getParameterTypes()) { addClass(p); } } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/AbstractJavaProfile.java --- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/AbstractJavaProfile.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/AbstractJavaProfile.java Wed Apr 23 15:48:38 2014 +0200 @@ -131,7 +131,7 @@ if (!(obj instanceof AbstractJavaProfile)) { return false; } - AbstractJavaProfile that = (AbstractJavaProfile) obj; + AbstractJavaProfile that = (AbstractJavaProfile) obj; if (that.notRecordedProbability != notRecordedProbability) { return false; } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/AbstractProfiledItem.java --- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/AbstractProfiledItem.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/AbstractProfiledItem.java Wed Apr 23 15:48:38 2014 +0200 @@ -28,7 +28,7 @@ * A profiled type that has a probability. Profiled types are naturally sorted in descending order * of their probabilities. */ -public abstract class AbstractProfiledItem implements Comparable, Serializable { +public abstract class AbstractProfiledItem implements Comparable>, Serializable { private static final long serialVersionUID = 7838575753661305744L; @@ -56,7 +56,7 @@ } @Override - public int compareTo(AbstractProfiledItem o) { + public int compareTo(AbstractProfiledItem o) { if (getProbability() > o.getProbability()) { return -1; } else if (getProbability() < o.getProbability()) { @@ -87,7 +87,7 @@ if (getClass() != obj.getClass()) { return false; } - AbstractProfiledItem other = (AbstractProfiledItem) obj; + AbstractProfiledItem other = (AbstractProfiledItem) obj; if (Double.doubleToLongBits(probability) != Double.doubleToLongBits(other.probability)) { return false; } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Constant.java --- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Constant.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Constant.java Wed Apr 23 15:48:38 2014 +0200 @@ -22,42 +22,40 @@ */ package com.oracle.graal.api.meta; -import static com.oracle.graal.api.meta.MetaUtil.*; - /** * Represents a constant (boxed) value, such as an integer, floating point number, or object * reference, within the compiler and across the compiler/runtime interface. Exports a set of * {@code Constant} instances that represent frequently used constant values, such as * {@link #NULL_OBJECT}. */ -public final class Constant extends Value { +public abstract class Constant extends Value { private static final long serialVersionUID = -6355452536852663986L; private static final Constant[] INT_CONSTANT_CACHE = new Constant[100]; static { for (int i = 0; i < INT_CONSTANT_CACHE.length; ++i) { - INT_CONSTANT_CACHE[i] = new Constant(Kind.Int, null, i); + INT_CONSTANT_CACHE[i] = new PrimitiveConstant(Kind.Int, i); } } - public static final Constant NULL_OBJECT = new Constant(Kind.Object, null, 0); - public static final Constant INT_MINUS_1 = new Constant(Kind.Int, null, -1); + public static final Constant NULL_OBJECT = new NullConstant(); + public static final Constant INT_MINUS_1 = new PrimitiveConstant(Kind.Int, -1); public static final Constant INT_0 = forInt(0); public static final Constant INT_1 = forInt(1); public static final Constant INT_2 = forInt(2); public static final Constant INT_3 = forInt(3); public static final Constant INT_4 = forInt(4); public static final Constant INT_5 = forInt(5); - public static final Constant LONG_0 = new Constant(Kind.Long, null, 0L); - public static final Constant LONG_1 = new Constant(Kind.Long, null, 1L); - public static final Constant FLOAT_0 = new Constant(Kind.Float, null, Float.floatToRawIntBits(0.0F)); - public static final Constant FLOAT_1 = new Constant(Kind.Float, null, Float.floatToRawIntBits(1.0F)); - public static final Constant FLOAT_2 = new Constant(Kind.Float, null, Float.floatToRawIntBits(2.0F)); - public static final Constant DOUBLE_0 = new Constant(Kind.Double, null, Double.doubleToRawLongBits(0.0D)); - public static final Constant DOUBLE_1 = new Constant(Kind.Double, null, Double.doubleToRawLongBits(1.0D)); - public static final Constant TRUE = new Constant(Kind.Boolean, null, 1L); - public static final Constant FALSE = new Constant(Kind.Boolean, null, 0L); + public static final Constant LONG_0 = new PrimitiveConstant(Kind.Long, 0L); + public static final Constant LONG_1 = new PrimitiveConstant(Kind.Long, 1L); + public static final Constant FLOAT_0 = new PrimitiveConstant(Kind.Float, Float.floatToRawIntBits(0.0F)); + public static final Constant FLOAT_1 = new PrimitiveConstant(Kind.Float, Float.floatToRawIntBits(1.0F)); + public static final Constant FLOAT_2 = new PrimitiveConstant(Kind.Float, Float.floatToRawIntBits(2.0F)); + public static final Constant DOUBLE_0 = new PrimitiveConstant(Kind.Double, Double.doubleToRawLongBits(0.0D)); + public static final Constant DOUBLE_1 = new PrimitiveConstant(Kind.Double, Double.doubleToRawLongBits(1.0D)); + public static final Constant TRUE = new PrimitiveConstant(Kind.Boolean, 1L); + public static final Constant FALSE = new PrimitiveConstant(Kind.Boolean, 0L); static { assert FLOAT_0 != forFloat(-0.0F) : "Constant for 0.0f must be different from -0.0f"; @@ -65,56 +63,86 @@ assert NULL_OBJECT.isNull(); } - /** - * The boxed object value if {@code !kind.isObject()} otherwise the (possibly null) - * {@link #getPrimitiveAnnotation() annotation} for a primitive value. - */ - private final Object object; - - /** - * The boxed primitive value as a {@code long}. This is ignored iff {@code kind.isObject()}. For - * {@code float} and {@code double} values, this value is the result of - * {@link Float#floatToRawIntBits(float)} and {@link Double#doubleToRawLongBits(double)} - * respectively. - */ - private final long primitive; - - private Constant(Kind kind, Object object, long primitive) { + protected Constant(Kind kind) { super(kind); - this.object = object; - this.primitive = primitive; - } - - /** - * Checks whether this constant is non-null. - * - * @return {@code true} if this constant is a primitive, or an object constant that is not null - */ - public boolean isNonNull() { - return getKind() != Kind.Object || object != null; } /** * Checks whether this constant is null. - * + * * @return {@code true} if this constant is the null constant */ - public boolean isNull() { - return getKind() == Kind.Object && object == null; + public abstract boolean isNull(); + + /** + * Checks whether this constant is non-null. + * + * @return {@code true} if this constant is a primitive, or an object constant that is not null + */ + public final boolean isNonNull() { + return !isNull(); } /** * Checks whether this constant is the default value for its kind (null, 0, 0.0, false). - * + * * @return {@code true} if this constant is the default value for its kind */ - public boolean isDefaultForKind() { - return object == null && primitive == 0; - } + public abstract boolean isDefaultForKind(); + + /** + * Returns the value of this constant as a boxed Java value. + * + * @return the value of this constant + */ + public abstract Object asBoxedPrimitive(); + + /** + * Returns the primitive int value this constant represents. The constant must have a + * {@link Kind#getStackKind()} of {@link Kind#Int}. + * + * @return the constant value + */ + public abstract int asInt(); + + /** + * Returns the primitive boolean value this constant represents. The constant must have kind + * {@link Kind#Boolean}. + * + * @return the constant value + */ + public abstract boolean asBoolean(); - public long getPrimitive() { - assert getKind().isPrimitive(); - return primitive; + /** + * Returns the primitive long value this constant represents. The constant must have kind + * {@link Kind#Long}, a {@link Kind#getStackKind()} of {@link Kind#Int}. + * + * @return the constant value + */ + public abstract long asLong(); + + /** + * Returns the primitive float value this constant represents. The constant must have kind + * {@link Kind#Float}. + * + * @return the constant value + */ + public abstract float asFloat(); + + /** + * Returns the primitive double value this constant represents. The constant must have kind + * {@link Kind#Double}. + * + * @return the constant value + */ + public abstract double asDouble(); + + public String toValueString() { + if (getKind() == Kind.Illegal) { + return "illegal"; + } else { + return getKind().format(asBoxedPrimitive()); + } } @Override @@ -122,165 +150,13 @@ if (getKind() == Kind.Illegal) { return "illegal"; } else { - String annotationSuffix = ""; - Object primitiveAnnotation = getPrimitiveAnnotation(); - if (getKind() != Kind.Object && primitiveAnnotation != null) { - try { - annotationSuffix = "{" + primitiveAnnotation + "}"; - } catch (Throwable t) { - annotationSuffix = "{" + getSimpleName(primitiveAnnotation.getClass(), true) + "@" + System.identityHashCode(primitiveAnnotation) + "}"; - } - } - return getKind().getJavaName() + "[" + getKind().format(asBoxedValue()) + (getKind() != Kind.Object ? "|0x" + Long.toHexString(primitive) : "") + "]" + annotationSuffix; + return getKind().getJavaName() + "[" + toValueString() + "]"; } } /** - * Returns the value of this constant as a boxed Java value. - * - * @return the value of this constant - */ - public Object asBoxedValue() { - switch (getKind()) { - case Byte: - return (byte) asInt(); - case Boolean: - return asInt() == 0 ? Boolean.FALSE : Boolean.TRUE; - case Short: - return (short) primitive; - case Char: - return (char) primitive; - case Int: - return (int) primitive; - case Long: - return primitive; - case Float: - return asFloat(); - case Double: - return asDouble(); - case Object: - return object; - case Illegal: - return this; - } - throw new IllegalArgumentException(); - } - - private boolean valueEqual(Constant other, boolean ignoreKind) { - // must have equivalent kinds to be equal - if (!ignoreKind && getKind() != other.getKind()) { - return false; - } - if (getKind() == Kind.Object) { - return object == other.object; - } - return primitive == other.primitive && getPrimitiveAnnotation() == other.getPrimitiveAnnotation(); - } - - /** - * Returns the primitive int value this constant represents. The constant must have a - * {@link Kind#getStackKind()} of {@link Kind#Int}. - * - * @return the constant value - */ - public int asInt() { - assert getKind().getStackKind() == Kind.Int; - return (int) primitive; - } - - /** - * Returns the primitive boolean value this constant represents. The constant must have kind - * {@link Kind#Boolean}. - * - * @return the constant value - */ - public boolean asBoolean() { - assert getKind() == Kind.Boolean; - return primitive != 0L; - } - - /** - * Returns the primitive long value this constant represents. The constant must have kind - * {@link Kind#Long}, a {@link Kind#getStackKind()} of {@link Kind#Int}. - * - * @return the constant value - */ - public long asLong() { - assert getKind().isNumericInteger(); - return primitive; - } - - /** - * Returns the primitive float value this constant represents. The constant must have kind - * {@link Kind#Float}. - * - * @return the constant value - */ - public float asFloat() { - assert getKind() == Kind.Float; - return Float.intBitsToFloat((int) primitive); - } - - /** - * Returns the primitive double value this constant represents. The constant must have kind - * {@link Kind#Double}. - * - * @return the constant value - */ - public double asDouble() { - assert getKind() == Kind.Double; - return Double.longBitsToDouble(primitive); - } - - /** - * Returns the object reference this constant represents. The constant must have kind - * {@link Kind#Object}. - * - * @return the constant value - */ - public Object asObject() { - assert getKind() == Kind.Object; - return object; - } - - /** - * Gets the annotation (if any) associated with this constant. - * - * @return null if this constant is not primitive or has no annotation - */ - public Object getPrimitiveAnnotation() { - return getKind() == Kind.Object ? null : object; - } - - /** - * Computes the hashcode of this constant. - * - * @return a suitable hashcode for this constant - */ - @Override - public int hashCode() { - if (getKind() == Kind.Object) { - return System.identityHashCode(object); - } - return (int) primitive * getKind().ordinal(); - } - - /** - * Checks whether this constant equals another object. This is only true if the other object is - * a constant that has the same {@linkplain #getKind() kind}, value and - * {@link #getPrimitiveAnnotation() annotation}. - * - * @param o the object to compare equality - * @return {@code true} if this constant is equivalent to the specified object - */ - @Override - public boolean equals(Object o) { - return o == this || o instanceof Constant && valueEqual((Constant) o, false); - } - - /** * Creates a boxed double constant. - * + * * @param d the double value to box * @return a boxed copy of {@code value} */ @@ -291,12 +167,12 @@ if (Double.compare(d, 1.0D) == 0) { return DOUBLE_1; } - return new Constant(Kind.Double, null, Double.doubleToRawLongBits(d)); + return new PrimitiveConstant(Kind.Double, Double.doubleToRawLongBits(d)); } /** * Creates a boxed float constant. - * + * * @param f the float value to box * @return a boxed copy of {@code value} */ @@ -310,22 +186,22 @@ if (Float.compare(f, 2.0F) == 0) { return FLOAT_2; } - return new Constant(Kind.Float, null, Float.floatToRawIntBits(f)); + return new PrimitiveConstant(Kind.Float, Float.floatToRawIntBits(f)); } /** * Creates a boxed long constant. - * + * * @param i the long value to box * @return a boxed copy of {@code value} */ public static Constant forLong(long i) { - return i == 0 ? LONG_0 : i == 1 ? LONG_1 : new Constant(Kind.Long, null, i); + return i == 0 ? LONG_0 : i == 1 ? LONG_1 : new PrimitiveConstant(Kind.Long, i); } /** * Creates a boxed integer constant. - * + * * @param i the integer value to box * @return a boxed copy of {@code value} */ @@ -336,22 +212,22 @@ if (i >= 0 && i < INT_CONSTANT_CACHE.length) { return INT_CONSTANT_CACHE[i]; } - return new Constant(Kind.Int, null, i); + return new PrimitiveConstant(Kind.Int, i); } /** * Creates a boxed byte constant. - * + * * @param i the byte value to box * @return a boxed copy of {@code value} */ public static Constant forByte(byte i) { - return new Constant(Kind.Byte, null, i); + return new PrimitiveConstant(Kind.Byte, i); } /** * Creates a boxed boolean constant. - * + * * @param i the boolean value to box * @return a boxed copy of {@code value} */ @@ -361,52 +237,33 @@ /** * Creates a boxed char constant. - * + * * @param i the char value to box * @return a boxed copy of {@code value} */ public static Constant forChar(char i) { - return new Constant(Kind.Char, null, i); + return new PrimitiveConstant(Kind.Char, i); } /** * Creates a boxed short constant. - * + * * @param i the short value to box * @return a boxed copy of {@code value} */ public static Constant forShort(short i) { - return new Constant(Kind.Short, null, i); + return new PrimitiveConstant(Kind.Short, i); } /** - * Creates a boxed object constant. - * - * @param o the object value to box - * @return a boxed copy of {@code value} + * Creates a {@link Constant} from a primitive integer of a certain kind. */ - public static Constant forObject(Object o) { - if (o == null) { - return NULL_OBJECT; - } - return new Constant(Kind.Object, o, 0L); - } - - /** - * Creates an annotated int or long constant. An annotation enables a client to associate some - * extra semantic or debugging information with a primitive. An annotated primitive constant is - * never {@linkplain #equals(Object) equal} to a non-annotated constant. - * - * @param kind the type of this constant - * @param i the value of this constant - * @param annotation an arbitrary non-null object - */ - public static Constant forIntegerKind(Kind kind, long i, Object annotation) { + public static Constant forIntegerKind(Kind kind, long i) { switch (kind) { case Int: - return new Constant(kind, annotation, (int) i); + return new PrimitiveConstant(kind, (int) i); case Long: - return new Constant(kind, annotation, i); + return new PrimitiveConstant(kind, i); default: throw new IllegalArgumentException("not an integer kind: " + kind); } @@ -418,47 +275,42 @@ public static Constant forPrimitiveInt(int bits, long i) { assert bits <= 64; if (bits > 32) { - return new Constant(Kind.Long, null, i); + return new PrimitiveConstant(Kind.Long, i); } else { - return new Constant(Kind.Int, null, (int) i); + return new PrimitiveConstant(Kind.Int, (int) i); } } /** - * Creates a boxed constant for the given kind from an Object. The object needs to be of the - * Java boxed type corresponding to the kind. - * - * @param kind the kind of the constant to create - * @param value the Java boxed value: a {@link Byte} instance for {@link Kind#Byte}, etc. - * @return the boxed copy of {@code value} + * Creates a boxed constant for the given boxed primitive value. + * + * @param value the Java boxed value + * @return the primitive constant holding the {@code value} */ - public static Constant forBoxed(Kind kind, Object value) { - switch (kind) { - case Boolean: - return forBoolean((Boolean) value); - case Byte: - return forByte((Byte) value); - case Char: - return forChar((Character) value); - case Short: - return forShort((Short) value); - case Int: - return forInt((Integer) value); - case Long: - return forLong((Long) value); - case Float: - return forFloat((Float) value); - case Double: - return forDouble((Double) value); - case Object: - return forObject(value); - default: - throw new RuntimeException("cannot create Constant for boxed " + kind + " value"); + public static Constant forBoxedPrimitive(Object value) { + if (value instanceof Boolean) { + return forBoolean((Boolean) value); + } else if (value instanceof Byte) { + return forByte((Byte) value); + } else if (value instanceof Character) { + return forChar((Character) value); + } else if (value instanceof Short) { + return forShort((Short) value); + } else if (value instanceof Integer) { + return forInt((Integer) value); + } else if (value instanceof Long) { + return forLong((Long) value); + } else if (value instanceof Float) { + return forFloat((Float) value); + } else if (value instanceof Double) { + return forDouble((Double) value); + } else { + return null; } } public static Constant forIllegal() { - return new Constant(Kind.Illegal, null, 0); + return new PrimitiveConstant(Kind.Illegal, 0); } /** diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ConstantPool.java --- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ConstantPool.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ConstantPool.java Wed Apr 23 15:48:38 2014 +0200 @@ -117,5 +117,5 @@ * {@code -1} * @return the appendix if it exists and is resolved or {@code null} */ - Object lookupAppendix(int cpi, int opcode); + Constant lookupAppendix(int cpi, int opcode); } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ConstantReflectionProvider.java --- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ConstantReflectionProvider.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ConstantReflectionProvider.java Wed Apr 23 15:48:38 2014 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,34 +23,78 @@ package com.oracle.graal.api.meta; /** - * Reflection operations on values represented as {@linkplain Constant constants}. + * Reflection operations on values represented as {@linkplain Constant constants}. All methods in + * this interface require the VM to access the actual object encapsulated in {@link Kind#Object + * object} constants. This access is not always possible, depending on kind of VM and the state that + * the VM is in. Therefore, all methods can return {@code null} at any time, to indicate that the + * result is not available at this point. The caller is responsible to check for {@code null} + * results and handle them properly, e.g., not perform an optimization. */ public interface ConstantReflectionProvider { /** - * Compares two constants for equality. The equality relationship is symmetric. If the constants - * cannot be compared at this point, the return value is {@code null}; - * - * @return {@code true} if the two parameters represent the same runtime object, {@code false} - * if they are different, or {@code null} if the parameters cannot be compared. + * Compares two constants for equality. The equality relationship is symmetric. Returns + * {@link Boolean#TRUE true} if the two constants represent the same run time value, + * {@link Boolean#FALSE false} if they are different. Returns {@code null} if the constants + * cannot be compared at this point. */ Boolean constantEquals(Constant x, Constant y); /** - * Returns the length of an array that is wrapped in a {@link Constant} object. If {@code array} - * is not an array, or the array length is not available at this point, the return value is - * {@code null}. + * Returns the length of the array constant. Returns {@code null} if the constant is not an + * array, or if the array length is not available at this point. */ - Integer lookupArrayLength(Constant array); + Integer readArrayLength(Constant array); /** - * Reads a value of this kind using a base address and a displacement. - * - * @param base the base address from which the value is read + * Reads a value from the given array at the given index. Returns {@code null} if the constant + * is not an array, if the index is out of bounds, or if the value is not available at this + * point. + */ + Constant readArrayElement(Constant array, int index); + + /** + * Reads a value of this kind using a base address and a displacement. No bounds checking or + * type checking is performed. Returns {@code null} if the value is not available at this point. + * + * @param base the base address from which the value is read. * @param displacement the displacement within the object in bytes - * @param compressible whether this is a read of a compressed or an uncompressed pointer * @return the read value encapsulated in a {@link Constant} object, or {@code null} if the * value cannot be read. */ - Constant readUnsafeConstant(Kind kind, Object base, long displacement, boolean compressible); + Constant readUnsafeConstant(Kind kind, Constant base, long displacement); + + /** + * Reads a primitive value using a base address and a displacement. + * + * @param kind the {@link Kind} of the returned {@link Constant} object + * @param base the base address from which the value is read + * @param displacement the displacement within the object in bytes + * @param bits the number of bits to read from memory + * @return the read value encapsulated in a {@link Constant} object of {@link Kind} kind + */ + Constant readRawConstant(Kind kind, Constant base, long displacement, int bits); + + /** + * Converts the given {@link Kind#isPrimitive() primitive} constant to a boxed + * {@link Kind#Object object} constant, according to the Java boxing rules. Returns {@code null} + * if the source is is not a primitive constant, or the boxed value is not available at this + * point. + */ + Constant boxPrimitive(Constant source); + + /** + * Converts the given {@link Kind#Object object} constant to a {@link Kind#isPrimitive() + * primitive} constant, according to the Java unboxing rules. Returns {@code null} if the source + * is is not an object constant that can be unboxed, or the unboxed value is not available at + * this point. + */ + Constant unboxPrimitive(Constant source); + + /** + * Returns the {@link ResolvedJavaType} for a {@link Class} object (or any other object regarded + * as a class by the VM) encapsulated in the given constant. Returns {@code null} if the + * constant does not encapsulate a class, or if the type is not available at this point. + */ + ResolvedJavaType asJavaType(Constant constant); } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ForeignCallDescriptor.java --- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ForeignCallDescriptor.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ForeignCallDescriptor.java Wed Apr 23 15:48:38 2014 +0200 @@ -41,10 +41,10 @@ public class ForeignCallDescriptor { private final String name; - private final Class resultType; - private final Class[] argumentTypes; + private final Class resultType; + private final Class[] argumentTypes; - public ForeignCallDescriptor(String name, Class resultType, Class... argumentTypes) { + public ForeignCallDescriptor(String name, Class resultType, Class... argumentTypes) { this.name = name; this.resultType = resultType; this.argumentTypes = argumentTypes; @@ -89,7 +89,7 @@ public String toString() { StringBuilder sb = new StringBuilder(name).append('('); String sep = ""; - for (Class arg : argumentTypes) { + for (Class arg : argumentTypes) { sb.append(sep).append(arg.getSimpleName()); sep = ","; } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/JavaTypeProfile.java --- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/JavaTypeProfile.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/JavaTypeProfile.java Wed Apr 23 15:48:38 2014 +0200 @@ -22,8 +22,6 @@ */ package com.oracle.graal.api.meta; -import static java.lang.reflect.Modifier.*; - import java.util.*; import com.oracle.graal.api.meta.JavaTypeProfile.ProfiledType; @@ -146,7 +144,7 @@ public ProfiledType(ResolvedJavaType type, double probability) { super(type, probability); - assert type.isArray() || !isAbstract(type.getModifiers()) : type; + assert type.isArray() || !type.isAbstract() : type; } /** diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Kind.java --- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Kind.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Kind.java Wed Apr 23 15:48:38 2014 +0200 @@ -66,10 +66,10 @@ private final char typeChar; private final String javaName; private final boolean isStackInt; - private final Class primitiveJavaClass; - private final Class boxedJavaClass; + private final Class primitiveJavaClass; + private final Class boxedJavaClass; - private Kind(char typeChar, String javaName, boolean isStackInt, Class primitiveJavaClass, Class boxedJavaClass) { + private Kind(char typeChar, String javaName, boolean isStackInt, Class primitiveJavaClass, Class boxedJavaClass) { this.typeChar = typeChar; this.javaName = javaName; this.isStackInt = isStackInt; @@ -95,7 +95,7 @@ /** * Checks whether this type is a Java primitive type. - * + * * @return {@code true} if this is {@link #Boolean}, {@link #Byte}, {@link #Char}, * {@link #Short}, {@link #Int}, {@link #Long}, {@link #Float}, {@link #Double}, or * {@link #Void}. @@ -106,7 +106,7 @@ /** * Returns the kind that represents this kind when on the Java operand stack. - * + * * @return the kind used on the operand stack */ public Kind getStackKind() { @@ -118,7 +118,7 @@ /** * Checks whether this type is a Java primitive type representing an integer number. - * + * * @return {@code true} if the stack kind is {@link #Int} or {@link #Long}. */ public boolean isNumericInteger() { @@ -127,7 +127,7 @@ /** * Checks whether this type is a Java primitive type representing an unsigned number. - * + * * @return {@code true} if the kind is {@link #Boolean} or {@link #Char}. */ public boolean isUnsigned() { @@ -136,7 +136,7 @@ /** * Checks whether this type is a Java primitive type representing a floating point number. - * + * * @return {@code true} if this is {@link #Float} or {@link #Double}. */ public boolean isNumericFloat() { @@ -145,7 +145,7 @@ /** * Checks whether this represent an Object of some sort. - * + * * @return {@code true} if this is {@link #Object}. */ public boolean isObject() { @@ -154,7 +154,7 @@ /** * Returns the kind corresponding to the Java type string. - * + * * @param typeString the Java type string * @return the kind */ @@ -169,7 +169,7 @@ /** * Returns the kind of a word given the size of a word in bytes. - * + * * @param wordSizeInBytes the size of a word in bytes * @return the kind representing a word value */ @@ -184,7 +184,7 @@ /** * Returns the kind from the character describing a primitive or void. - * + * * @param ch the character * @return the kind */ @@ -214,7 +214,7 @@ /** * Returns the Kind representing the given Java class. - * + * * @param klass the class * @return the kind */ @@ -244,7 +244,7 @@ /** * Returns the Java class representing this kind. - * + * * @return the Java class */ public Class toJavaClass() { @@ -253,7 +253,7 @@ /** * Returns the Java class for instances of boxed values of this kind. - * + * * @return the Java class */ public Class toBoxedJavaClass() { @@ -279,13 +279,13 @@ /** * Classes for which invoking {@link Object#toString()} does not run user code. */ - private static boolean isToStringSafe(Class c) { + private static boolean isToStringSafe(Class c) { return c == Boolean.class || c == Byte.class || c == Character.class || c == Short.class || c == Integer.class || c == Float.class || c == Long.class || c == Double.class; } /** * Gets a formatted string for a given value of this kind. - * + * * @param value a value of this kind * @return a formatted string for {@code value} based on this kind */ @@ -307,7 +307,7 @@ } else if (value instanceof JavaType) { return "JavaType:" + MetaUtil.toJavaName((JavaType) value); } else if (value instanceof Enum) { - return MetaUtil.getSimpleName(value.getClass(), true) + ":" + ((Enum) value).name(); + return MetaUtil.getSimpleName(value.getClass(), true) + ":" + ((Enum) value).name(); } else if (value instanceof FormatWithToString) { return MetaUtil.getSimpleName(value.getClass(), true) + ":" + String.valueOf(value); } else if (value instanceof Class) { @@ -351,7 +351,7 @@ /** * The minimum value that can be represented as a value of this kind. - * + * * @return the minimum value */ public long getMinValue() { @@ -375,7 +375,7 @@ /** * The maximum value that can be represented as a value of this kind. - * + * * @return the maximum value */ public long getMaxValue() { @@ -399,7 +399,7 @@ /** * Number of bytes that are necessary to represent a value of this kind. - * + * * @return the number of bytes */ public int getByteCount() { @@ -412,7 +412,7 @@ /** * Number of bits that are necessary to represent a value of this kind. - * + * * @return the number of bits */ public int getBitCount() { diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/MetaAccessProvider.java --- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/MetaAccessProvider.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/MetaAccessProvider.java Wed Apr 23 15:48:38 2014 +0200 @@ -45,7 +45,7 @@ /** * Provides the {@link ResolvedJavaMethod} for a {@link Constructor} obtained via reflection. */ - ResolvedJavaMethod lookupJavaConstructor(Constructor reflectionConstructor); + ResolvedJavaMethod lookupJavaConstructor(Constructor reflectionConstructor); /** * Provides the {@link ResolvedJavaField} for a {@link Field} obtained via reflection. diff -r 518a7f487c4f -r 9363fffa8b07 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 Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/MetaUtil.java Wed Apr 23 15:48:38 2014 +0200 @@ -22,8 +22,6 @@ */ package com.oracle.graal.api.meta; -import static java.lang.reflect.Modifier.*; - import java.io.*; import java.lang.annotation.*; import java.lang.reflect.*; @@ -50,18 +48,18 @@ /** * Returns the number of bytes occupied by this constant value or constant object and * recursively all values reachable from this value. - * + * * @param constant the constant whose bytes should be measured * @param printTopN print total size and instance count of the top n classes is desired * @return the number of bytes occupied by this constant */ - public static long getMemorySizeRecursive(MetaAccessProvider access, Constant constant, PrintStream out, int printTopN) { - IdentityHashMap marked = new IdentityHashMap<>(); + public static long getMemorySizeRecursive(MetaAccessProvider access, ConstantReflectionProvider constantReflection, Constant constant, PrintStream out, int printTopN) { + Set marked = new HashSet<>(); Stack stack = new Stack<>(); if (constant.getKind() == Kind.Object && constant.isNonNull()) { - marked.put(constant.asObject(), Boolean.TRUE); + marked.add(constant); } - final HashMap histogram = new HashMap<>(); + final HashMap histogram = new HashMap<>(); stack.push(constant); long sum = 0; while (!stack.isEmpty()) { @@ -69,7 +67,7 @@ long memorySize = access.getMemorySize(constant); sum += memorySize; if (c.getKind() == Kind.Object && c.isNonNull()) { - Class clazz = c.asObject().getClass(); + ResolvedJavaType clazz = access.lookupJavaType(c); if (!histogram.containsKey(clazz)) { histogram.put(clazz, new ClassInfo()); } @@ -79,10 +77,10 @@ ResolvedJavaType type = access.lookupJavaType(c); if (type.isArray()) { if (!type.getComponentType().isPrimitive()) { - Object[] array = (Object[]) c.asObject(); - for (Object value : array) { - Constant forObject = Constant.forObject(value); - pushConstant(marked, stack, forObject); + int length = constantReflection.readArrayLength(c); + for (int i = 0; i < length; i++) { + Constant value = constantReflection.readArrayElement(c, i); + pushConstant(marked, stack, value); } } } else { @@ -96,12 +94,12 @@ } } } - ArrayList clazzes = new ArrayList<>(); + ArrayList clazzes = new ArrayList<>(); clazzes.addAll(histogram.keySet()); - Collections.sort(clazzes, new Comparator() { + Collections.sort(clazzes, new Comparator() { @Override - public int compare(Class o1, Class o2) { + public int compare(ResolvedJavaType o1, ResolvedJavaType o2) { long l1 = histogram.get(o1).totalSize; long l2 = histogram.get(o2).totalSize; if (l1 > l2) { @@ -115,7 +113,7 @@ }); int z = 0; - for (Class c : clazzes) { + for (ResolvedJavaType c : clazzes) { if (z > printTopN) { break; } @@ -126,10 +124,10 @@ return sum; } - private static void pushConstant(IdentityHashMap marked, Stack stack, Constant value) { + private static void pushConstant(Set marked, Stack stack, Constant value) { if (value.isNonNull()) { - if (!marked.containsKey(value.asObject())) { - marked.put(value.asObject(), Boolean.TRUE); + if (!marked.contains(value)) { + marked.add(value); stack.push(value); } } @@ -158,7 +156,7 @@ /** * Calls {@link MetaAccessProvider#lookupJavaType(Class)} on an array of classes. */ - public static ResolvedJavaType[] lookupJavaTypes(MetaAccessProvider metaAccess, Class[] classes) { + public static ResolvedJavaType[] lookupJavaTypes(MetaAccessProvider metaAccess, Class[] classes) { ResolvedJavaType[] result = new ResolvedJavaType[classes.length]; for (int i = 0; i < result.length; i++) { result[i] = metaAccess.lookupJavaType(classes[i]); @@ -182,7 +180,7 @@ /** * Extends the functionality of {@link Class#getSimpleName()} to include a non-empty string for * anonymous and local classes. - * + * * @param clazz the class for which the simple name is being requested * @param withEnclosingClass specifies if the returned name should be qualified with the name(s) * of the enclosing class/classes of {@code clazz} (if any). This option is ignored @@ -218,7 +216,7 @@ /** * Converts a given type to its Java programming language name. The following are examples of * strings returned by this method: - * + * *
      *     qualified == true:
      *         java.lang.Object
@@ -229,7 +227,7 @@
      *         int
      *         boolean[][]
      * 
- * + * * @param type the type to be converted to a Java name * @param qualified specifies if the package prefix of the type should be included in the * returned name @@ -246,13 +244,13 @@ /** * Converts a given type to its Java programming language name. The following are examples of * strings returned by this method: - * + * *
      *      java.lang.Object
      *      int
      *      boolean[][]
      * 
- * + * * @param type the type to be converted to a Java name * @return the Java name corresponding to {@code type} */ @@ -308,7 +306,7 @@ * and specifiers that denote an attribute of the method that is to be copied to the result. A * specifier is a single character preceded by a '%' character. The accepted specifiers and the * method attributes they denote are described below: - * + * *
      *     Specifier | Description                                          | Example(s)
      *     ----------+------------------------------------------------------------------------------------------
@@ -322,7 +320,7 @@
      *     'f'       | Indicator if method is unresolved, static or virtual | "unresolved" "static" "virtual"
      *     '%'       | A '%' character                                      | "%"
      * 
- * + * * @param format a format specification * @param method the method to be formatted * @return the result of formatting this method according to {@code format} @@ -378,7 +376,7 @@ break; } case 'f': { - sb.append(!(method instanceof ResolvedJavaMethod) ? "unresolved" : isStatic(((ResolvedJavaMethod) method).getModifiers()) ? "static" : "virtual"); + sb.append(!(method instanceof ResolvedJavaMethod) ? "unresolved" : ((ResolvedJavaMethod) method).isStatic() ? "static" : "virtual"); break; } case '%': { @@ -402,7 +400,7 @@ * specifiers that denote an attribute of the field that is to be copied to the result. A * specifier is a single character preceded by a '%' character. The accepted specifiers and the * field attributes they denote are described below: - * + * *
      *     Specifier | Description                                          | Example(s)
      *     ----------+------------------------------------------------------------------------------------------
@@ -414,7 +412,7 @@
      *     'f'       | Indicator if field is unresolved, static or instance | "unresolved" "static" "instance"
      *     '%'       | A '%' character                                      | "%"
      * 
- * + * * @param format a format specification * @param field the field to be formatted * @return the result of formatting this field according to {@code format} @@ -452,7 +450,7 @@ break; } case 'f': { - sb.append(!(field instanceof ResolvedJavaField) ? "unresolved" : isStatic(((ResolvedJavaField) field).getModifiers()) ? "static" : "instance"); + sb.append(!(field instanceof ResolvedJavaField) ? "unresolved" : ((ResolvedJavaField) field).isStatic() ? "static" : "instance"); break; } case '%': { @@ -472,7 +470,7 @@ /** * 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 @@ -494,7 +492,7 @@ /** * 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 * @param parameterIndex the index of a formal parameter of {@code method} * @param method the method for which a parameter annotation is being requested @@ -530,18 +528,18 @@ * line number is {@linkplain ResolvedJavaMethod#asStackTraceElement(int) available} for the * given method, then the string returned is the {@link StackTraceElement#toString()} value of * the stack trace element, suffixed by the bci location. For example: - * + * *
      *     java.lang.String.valueOf(String.java:2930) [bci: 12]
      * 
- * + * * Otherwise, the string returned is the value of applying {@link #format(String, JavaMethod)} * with the format string {@code "%H.%n(%p)"}, suffixed by the bci location. For example: - * + * *
      *     java.lang.String.valueOf(int) [bci: 12]
      * 
- * + * * @param sb * @param method * @param bci @@ -561,7 +559,7 @@ } public static JavaType[] signatureToTypes(ResolvedJavaMethod method) { - JavaType receiver = isStatic(method.getModifiers()) ? null : method.getDeclaringClass(); + JavaType receiver = method.isStatic() ? null : method.getDeclaringClass(); return signatureToTypes(method.getSignature(), receiver); } @@ -586,13 +584,13 @@ * Gets the method * descriptor corresponding to this signature. For example: - * + * *
      * (ILjava/lang/String;D)V
      * 
- * + * * . - * + * * @param sig the {@link Signature} to be converted. * @return the signature as a string */ @@ -607,7 +605,7 @@ /** * Formats some profiling information associated as a string. - * + * * @param info the profiling info to format * @param method an optional method that augments the profile string returned * @param sep the separator to use for each separate profile record @@ -669,13 +667,13 @@ return s.substring(0, s.length() - sep.length()); } - private static void appendProfile(StringBuilder buf, AbstractJavaProfile profile, int bci, String type, String sep) { + private static void appendProfile(StringBuilder buf, AbstractJavaProfile profile, int bci, String type, String sep) { if (profile != null) { - AbstractProfiledItem[] pitems = profile.getItems(); + AbstractProfiledItem[] pitems = profile.getItems(); if (pitems != null) { buf.append(String.format("%s@%d:", type, bci)); for (int j = 0; j < pitems.length; j++) { - AbstractProfiledItem pitem = pitems[j]; + AbstractProfiledItem pitem = pitems[j]; buf.append(String.format(" %.6f (%s)%s", pitem.getProbability(), pitem.getItem(), sep)); } if (profile.getNotRecordedProbability() != 0) { @@ -689,7 +687,7 @@ /** * Converts a Java source-language class name into the internal form. - * + * * @param className the class name * @return the internal name form of the class name */ diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ModifiersProvider.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ModifiersProvider.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.api.meta; + +import static java.lang.reflect.Modifier.*; + +import java.lang.reflect.*; + +/** + * A Java element (i.e., a class, interface, field or method) that is described by a set of Java + * language {@linkplain #getModifiers() modifiers}. + */ +public interface ModifiersProvider { + + /** + * Returns the Java language modifiers for this element. + */ + int getModifiers(); + + /** + * see {@link Modifier#isInterface(int)} + */ + default boolean isInterface() { + return Modifier.isInterface(getModifiers()); + } + + /** + * see {@link Modifier#isSynchronized(int)} + */ + default boolean isSynchronized() { + return Modifier.isSynchronized(getModifiers()); + } + + /** + * see {@link Modifier#isStatic(int)} + */ + default boolean isStatic() { + return Modifier.isStatic(getModifiers()); + } + + /** + * see {@link Modifier#isFinal(int)} + */ + default boolean isFinal() { + return Modifier.isFinal(getModifiers()); + } + + /** + * see {@link Modifier#isPublic(int)} + */ + default boolean isPublic() { + return Modifier.isPublic(getModifiers()); + } + + /** + * Determines if this element is neither {@linkplain #isPublic() public}, + * {@linkplain #isProtected() protected} nor {@linkplain #isPrivate() private}. + */ + default boolean isPackagePrivate() { + return ((PUBLIC | PROTECTED | PRIVATE) & getModifiers()) == 0; + } + + /** + * see {@link Modifier#isPrivate(int)} + */ + default boolean isPrivate() { + return Modifier.isPrivate(getModifiers()); + } + + /** + * see {@link Modifier#isProtected(int)} + */ + default boolean isProtected() { + return Modifier.isProtected(getModifiers()); + } + + /** + * see {@link Modifier#isTransient(int)} + */ + default boolean isTransient() { + return Modifier.isTransient(getModifiers()); + } + + /** + * see {@link Modifier#isStrict(int)} + */ + default boolean isStrict() { + return Modifier.isStrict(getModifiers()); + } + + /** + * see {@link Modifier#isVolatile(int)} + */ + default boolean isVolatile() { + return Modifier.isVolatile(getModifiers()); + } + + /** + * see {@link Modifier#isNative(int)} + */ + default boolean isNative() { + return Modifier.isNative(getModifiers()); + } + + /** + * see {@link Modifier#isAbstract(int)} + */ + default boolean isAbstract() { + return Modifier.isAbstract(getModifiers()); + } +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/NullConstant.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/NullConstant.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2014, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.api.meta; + +/** + * The implementation type of the {@link Constant#NULL_OBJECT null constant}. + */ +final class NullConstant extends Constant { + + private static final long serialVersionUID = 8906209595800783961L; + + protected NullConstant() { + super(Kind.Object); + } + + @Override + public boolean isNull() { + return true; + } + + @Override + public boolean isDefaultForKind() { + return true; + } + + @Override + public Object asBoxedPrimitive() { + throw new IllegalArgumentException(); + } + + @Override + public int asInt() { + throw new IllegalArgumentException(); + } + + @Override + public boolean asBoolean() { + throw new IllegalArgumentException(); + } + + @Override + public long asLong() { + throw new IllegalArgumentException(); + } + + @Override + public float asFloat() { + throw new IllegalArgumentException(); + } + + @Override + public double asDouble() { + throw new IllegalArgumentException(); + } + + @Override + public String toValueString() { + return "null"; + } + + @Override + public int hashCode() { + return System.identityHashCode(this); + } + + @Override + public boolean equals(Object o) { + assert o == this || !(o instanceof NullConstant) : "null constant is a singleton"; + return o == this; + } +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ObjectLocationIdentity.java --- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ObjectLocationIdentity.java Wed Apr 23 15:22:20 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2013, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.api.meta; - -import java.util.*; - -/** - * A {@link LocationIdentity} wrapping an object. - */ -public final class ObjectLocationIdentity implements LocationIdentity { - - private static IdentityHashMap map = new IdentityHashMap<>(); - - private Object object; - - public static LocationIdentity create(Object object) { - synchronized (map) { - if (map.containsKey(object)) { - return map.get(object); - } else { - ObjectLocationIdentity locationIdentity = new ObjectLocationIdentity(object); - map.put(object, locationIdentity); - return locationIdentity; - } - } - } - - private ObjectLocationIdentity(Object object) { - this.object = object; - } - - @Override - public String toString() { - return "Identity(" + object + ")"; - } -} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/PrimitiveConstant.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/PrimitiveConstant.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.api.meta; + +/** + * Represents a primitive constant value, such as an integer or floating point number, within the + * compiler and across the compiler/runtime interface. + */ +public class PrimitiveConstant extends Constant { + + private static final long serialVersionUID = 8787949721295655376L; + + /** + * The boxed primitive value as a {@code long}. For {@code float} and {@code double} values, + * this value is the result of {@link Float#floatToRawIntBits(float)} and + * {@link Double#doubleToRawLongBits(double)} respectively. + */ + private final long primitive; + + protected PrimitiveConstant(Kind kind, long primitive) { + super(kind); + this.primitive = primitive; + + assert kind.isPrimitive() || kind == Kind.Illegal; + } + + @Override + public boolean isNull() { + return false; + } + + @Override + public boolean isDefaultForKind() { + return primitive == 0; + } + + @Override + public boolean asBoolean() { + assert getKind() == Kind.Boolean; + return primitive != 0L; + } + + @Override + public int asInt() { + assert getKind().getStackKind() == Kind.Int; + return (int) primitive; + } + + @Override + public long asLong() { + assert getKind().isNumericInteger(); + return primitive; + } + + @Override + public float asFloat() { + assert getKind() == Kind.Float; + return Float.intBitsToFloat((int) primitive); + } + + @Override + public double asDouble() { + assert getKind() == Kind.Double; + return Double.longBitsToDouble(primitive); + } + + @Override + public Object asBoxedPrimitive() { + switch (getKind()) { + case Byte: + return Byte.valueOf((byte) primitive); + case Boolean: + return Boolean.valueOf(asBoolean()); + case Short: + return Short.valueOf((short) primitive); + case Char: + return Character.valueOf((char) primitive); + case Int: + return Integer.valueOf(asInt()); + case Long: + return Long.valueOf(asLong()); + case Float: + return Float.valueOf(asFloat()); + case Double: + return Double.valueOf(asDouble()); + default: + throw new IllegalArgumentException("unexpected kind " + getKind()); + } + } + + @Override + public int hashCode() { + return (int) (primitive ^ (primitive >>> 32)) * (getKind().ordinal() + 31); + } + + @Override + public boolean equals(Object o) { + return o == this || (o instanceof PrimitiveConstant && super.equals(o) && primitive == ((PrimitiveConstant) o).primitive); + } + + @Override + public String toString() { + if (getKind() == Kind.Illegal) { + return "illegal"; + } else { + return getKind().getJavaName() + "[" + getKind().format(asBoxedPrimitive()) + "|0x" + Long.toHexString(primitive) + "]"; + } + } +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaField.java --- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaField.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaField.java Wed Apr 23 15:48:38 2014 +0200 @@ -29,12 +29,13 @@ * Represents a reference to a resolved Java field. Fields, like methods and types, are resolved * through {@link ConstantPool constant pools}. */ -public interface ResolvedJavaField extends JavaField, LocationIdentity { +public interface ResolvedJavaField extends JavaField, LocationIdentity, ModifiersProvider { /** - * Returns the Java language modifiers for this field, as an integer. The {@link Modifier} class - * should be used to decode the modifiers. Only the {@linkplain Modifier#fieldModifiers() field - * flags} specified in the JVM specification will be included in the returned mask. + * {@inheritDoc} + *

+ * Only the {@linkplain Modifier#fieldModifiers() field flags} specified in the JVM + * specification will be included in the returned mask. */ int getModifiers(); @@ -53,7 +54,7 @@ * Gets the constant value of this field. Note that a {@code static final} field may not be * considered constant if its declaring class is not yet initialized or if it is a well known * field that can be updated via other means (e.g., {@link System#setOut(java.io.PrintStream)}). - * + * * @param receiver object from which this field's value is to be read. This value is ignored if * this field is static. * @return the constant value of this field or {@code null} if this field is not considered @@ -65,7 +66,7 @@ * Gets the current value of this field for a given object, if available. There is no guarantee * that the same value will be returned by this method for a field unless the field is * considered to be {@linkplain #readConstantValue(Constant) constant} by the runtime. - * + * * @param receiver object from which this field's value is to be read. This value is ignored if * this field is static. * @return the value of this field or {@code null} if the value is not available (e.g., because @@ -82,7 +83,7 @@ /** * Returns the annotation for the specified type of this field, if such an annotation is * present. - * + * * @param annotationClass the Class object corresponding to the annotation type * @return this element's annotation for the specified annotation type if present on this field, * else {@code null} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaMethod.java --- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaMethod.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaMethod.java Wed Apr 23 15:48:38 2014 +0200 @@ -29,16 +29,16 @@ * Represents a resolved Java method. Methods, like fields and types, are resolved through * {@link ConstantPool constant pools}. */ -public interface ResolvedJavaMethod extends JavaMethod, InvokeTarget { +public interface ResolvedJavaMethod extends JavaMethod, InvokeTarget, ModifiersProvider { /** * Returns the bytecode of this method, if the method has code. The returned byte array does not * contain breakpoints or non-Java bytecodes. This may return null if the * {@link #getDeclaringClass() holder} is not {@link ResolvedJavaType#isLinked() linked}. - * + * * The contained constant pool indices may not be the ones found in the original class file but * they can be used with the Graal API (e.g. methods in {@link ConstantPool}). - * + * * @return the bytecode of the method, or {@code null} if {@code getCodeSize() == 0} or if the * code is not ready. */ @@ -47,7 +47,7 @@ /** * Returns the size of the bytecode of this method, if the method has code. This is equivalent * to {@link #getCode()}. {@code length} if the method has code. - * + * * @return the size of the bytecode in bytes, or 0 if no bytecode is available */ int getCodeSize(); @@ -69,10 +69,10 @@ int getMaxStackSize(); /** - * Returns the Java language modifiers for this method, as an integer. The {@link Modifier} - * class should be used to decode the modifiers. Only the - * {@linkplain Modifier#methodModifiers() method flags} specified in the JVM specification will - * be included in the returned mask. + * {@inheritDoc} + *

+ * Only the {@linkplain Modifier#methodModifiers() method flags} specified in the JVM + * specification will be included in the returned mask. */ int getModifiers(); @@ -84,10 +84,10 @@ /** * Returns {@code true} if this method is a default method; returns {@code false} otherwise. - * + * * A default method is a public non-abstract instance method, that is, a non-static method with * a body, declared in an interface type. - * + * * @return true if and only if this method is a default method as defined by the Java Language * Specification. */ @@ -95,22 +95,22 @@ /** * Checks whether this method is a class initializer. - * + * * @return {@code true} if the method is a class initializer */ boolean isClassInitializer(); /** * Checks whether this method is a constructor. - * + * * @return {@code true} if the method is a constructor */ boolean isConstructor(); /** * Checks whether this method can be statically bound (usually, that means it is final or - * private or static, but not abstract). - * + * private or static, but not abstract, or the declaring class is final) + * * @return {@code true} if this method can be statically bound */ boolean canBeStaticallyBound(); @@ -143,7 +143,7 @@ /** * Returns the annotation for the specified type of this method, if such an annotation is * present. - * + * * @param annotationClass the Class object corresponding to the annotation type * @return this element's annotation for the specified annotation type if present on this * method, else {@code null} @@ -153,7 +153,7 @@ /** * Returns an array of arrays that represent the annotations on the formal parameters, in * declaration order, of this method. - * + * * @see Method#getParameterAnnotations() */ Annotation[][] getParameterAnnotations(); @@ -161,7 +161,7 @@ /** * Returns an array of {@link Type} objects that represent the formal parameter types, in * declaration order, of this method. - * + * * @see Method#getGenericParameterTypes() */ Type[] getGenericParameterTypes(); @@ -192,7 +192,7 @@ * Invokes the underlying method represented by this object, on the specified object with the * specified parameters. This method is similar to a reflective method invocation by * {@link Method#invoke}. - * + * * @param receiver The receiver for the invocation, or {@code null} if it is a static method. * @param arguments The arguments for the invocation. * @return The value returned by the method invocation, or {@code null} if the return type is @@ -204,7 +204,7 @@ * Uses the constructor represented by this object to create and initialize a new instance of * the constructor's declaring class, with the specified initialization parameters. This method * is similar to a reflective instantiation by {@link Constructor#newInstance}. - * + * * @param arguments The arguments for the constructor. * @return The newly created and initialized object. */ @@ -212,14 +212,14 @@ /** * Gets the encoding of (that is, a constant representing the value of) this method. - * + * * @return a constant representing a reference to this method */ Constant getEncoding(); /** * Checks if this method is present in the virtual table. - * + * * @return true is this method is present in the virtual table */ boolean isInVirtualMethodTable(); diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaType.java --- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaType.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaType.java Wed Apr 23 15:48:38 2014 +0200 @@ -31,7 +31,7 @@ * thereof. Types, like fields and methods, are resolved through {@link ConstantPool constant pools} * . */ -public interface ResolvedJavaType extends JavaType { +public interface ResolvedJavaType extends JavaType, ModifiersProvider { /** * Represents each of the several different parts of the runtime representation of a type which @@ -54,7 +54,7 @@ /** * Gets the encoding of (that is, a constant representing the value of) the specified part of * this type. - * + * * @param r the part of this type * @return a constant representing a reference to the specified part of this type */ @@ -62,7 +62,7 @@ /** * Checks whether this type has a finalizer method. - * + * * @return {@code true} if this class has a finalizer */ boolean hasFinalizer(); @@ -70,51 +70,52 @@ /** * Checks whether this type has any finalizable subclasses so far. Any decisions based on this * information require the registration of a dependency, since this information may change. - * + * * @return {@code true} if this class has any subclasses with finalizers */ boolean hasFinalizableSubclass(); /** * Checks whether this type is an interface. - * + * * @return {@code true} if this type is an interface */ boolean isInterface(); /** * Checks whether this type is an instance class. - * + * * @return {@code true} if this type is an instance class */ boolean isInstanceClass(); /** * Checks whether this type is an array class. - * + * * @return {@code true} if this type is an array class */ boolean isArray(); /** * Checks whether this type is primitive. - * + * * @return {@code true} if this type is primitive */ boolean isPrimitive(); /** - * Returns the Java language modifiers for this type, as an integer. The {@link Modifier} class - * should be used to decode the modifiers. Only the flags specified in the JVM specification - * will be included in the returned mask. This method is identical to - * {@link Class#getModifiers()} in terms of the value return for this type. + * {@inheritDoc} + *

+ * Only the flags specified in the JVM specification will be included in the returned mask. This + * method is identical to {@link Class#getModifiers()} in terms of the value return for this + * type. */ int getModifiers(); /** * Checks whether this type is initialized. If a type is initialized it implies that it was * {@link #isLinked() linked} and that the static initializer has run. - * + * * @return {@code true} if this type is initialized */ boolean isInitialized(); @@ -127,7 +128,7 @@ /** * Checks whether this type is linked and verified. When a type is linked the static initializer * has not necessarily run. An {@link #isInitialized() initialized} type is always linked. - * + * * @return {@code true} if this type is linked */ boolean isLinked(); @@ -141,7 +142,7 @@ /** * Checks whether the specified object is an instance of this type. - * + * * @param obj the object to test * @return {@code true} if the object is an instance of this type */ @@ -150,7 +151,7 @@ /** * Returns this type if it is an exact type otherwise returns null. This type is exact if it is * void, primitive, final, or an array of a final or primitive type. - * + * * @return this type if it is exact; {@code null} otherwise */ ResolvedJavaType asExactType(); @@ -172,7 +173,7 @@ /** * Walks the class hierarchy upwards and returns the least common class that is a superclass of * both the current and the given type. - * + * * @return the least common type that is a super type of both the current and the given type, or * {@code null} if primitive types are involved. */ @@ -194,7 +195,7 @@ *

* If the compiler uses the result of this method for its compilation, it must register an * assumption because dynamic class loading can invalidate the result of this method. - * + * * @return the unique concrete subclass for this type as described above */ ResolvedJavaType findUniqueConcreteSubtype(); @@ -208,7 +209,7 @@ * This resolution process only searches "up" the class hierarchy of this type. A broader search * that also walks "down" the hierarchy is implemented by * {@link #findUniqueConcreteMethod(ResolvedJavaMethod)}. - * + * * @param method the method to select the implementation of * @return the concrete method that would be selected at runtime, or {@code null} if there is no * concrete implementation of {@code method} in this type or any of its superclasses @@ -223,7 +224,7 @@ *

* If the compiler uses the result of this method for its compilation, it must register an * assumption because dynamic class loading can invalidate the result of this method. - * + * * @param method the method A for which a unique concrete target is searched * @return the unique concrete target or {@code null} if no such target exists or assumptions * are not supported by this runtime @@ -237,7 +238,7 @@ * is, for a single JVM execution the same order is returned each time this method is called. It * is also the "natural" order, which means that the JVM would expect the fields in this order * if no specific order is given. - * + * * @param includeSuperclasses if true, then instance fields for the complete hierarchy of this * type are included in the result * @return an array of instance fields @@ -247,7 +248,7 @@ /** * Returns the annotation for the specified type of this class, if such an annotation is * present. - * + * * @param annotationClass the Class object corresponding to the annotation type * @return this element's annotation for the specified annotation type if present on this class, * else {@code null} @@ -257,7 +258,7 @@ /** * Returns the instance field of this class (or one of its super classes) at the given offset, * or {@code null} if there is no such field. - * + * * @param offset the offset of the field to look for * @return the field with the given offset, or {@code null} if there is no such field. */ diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.api.replacements/src/com/oracle/graal/api/replacements/SnippetReflectionProvider.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.api.replacements/src/com/oracle/graal/api/replacements/SnippetReflectionProvider.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2014, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.api.replacements; + +import com.oracle.graal.api.meta.*; + +/** + * Reflection operations on values represented as {@linkplain Constant constants} for the processing + * of snippets. Snippets need a direct access to the value of object constants, which is not allowed + * in other parts of Graal to enforce compiler-VM separation. + *

+ * This interface must not be used in Graal code that is not related to snippet processing. + */ +public interface SnippetReflectionProvider { + + /** + * Creates a boxed {@link Kind#Object object} constant. + * + * @param object the object value to box + * @return a constant containing {@code object} + */ + Constant forObject(Object object); + + /** + * Returns the object reference the given constant represents. The constant must have kind + * {@link Kind#Object}. + * + * @param constant the to access + * @return the object value of the constant + */ + Object asObject(Constant constant); + + /** + * Creates a boxed constant for the given kind from an Object. The object needs to be of the + * Java boxed type corresponding to the kind. + * + * @param kind the kind of the constant to create + * @param value the Java boxed value: a {@link Byte} instance for {@link Kind#Byte}, etc. + * @return the boxed copy of {@code value} + */ + Constant forBoxed(Kind kind, Object value); + + /** + * Returns the value of this constant as a boxed Java value. + * + * @param constant the constant to box + * @return the value of the constant + */ + Object asBoxedValue(Constant constant); +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.api.runtime/src/com/oracle/graal/api/runtime/Graal.java --- a/graal/com.oracle.graal.api.runtime/src/com/oracle/graal/api/runtime/Graal.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.api.runtime/src/com/oracle/graal/api/runtime/Graal.java Wed Apr 23 15:48:38 2014 +0200 @@ -38,7 +38,7 @@ public static GraalRuntime getRuntime() { SecurityManager sm = System.getSecurityManager(); if (sm != null) { - Class cc = Reflection.getCallerClass(); + Class cc = Reflection.getCallerClass(); if (cc.getClassLoader() != null) { sm.checkPermission(ACCESS_PERMISSION); } @@ -60,7 +60,7 @@ public static T getRequiredCapability(Class clazz) { SecurityManager sm = System.getSecurityManager(); if (sm != null) { - Class cc = Reflection.getCallerClass(); + Class cc = Reflection.getCallerClass(); if (cc.getClassLoader() != null) { sm.checkPermission(ACCESS_PERMISSION); } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Assembler.java --- a/graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Assembler.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Assembler.java Wed Apr 23 15:48:38 2014 +0200 @@ -1647,9 +1647,14 @@ public final void shrl(Register dst, int imm8) { assert isShiftCount(imm8) : "illegal shift count"; int encode = prefixAndEncode(dst.encoding); - emitByte(0xC1); - emitByte(0xE8 | encode); - emitByte(imm8); + if (imm8 == 1) { + emitByte(0xD1); + emitByte(0xE8 | encode); + } else { + emitByte(0xC1); + emitByte(0xE8 | encode); + emitByte(imm8); + } } public final void shrl(Register dst) { @@ -1658,6 +1663,82 @@ emitByte(0xE8 | encode); } + public final void roll(Register dst, int imm8) { + assert isShiftCount(imm8) : "illegal shift count"; + int encode = prefixAndEncode(dst.encoding); + if (imm8 == 1) { + emitByte(0xD1); + emitByte(0xC0 | encode); + } else { + emitByte(0xC1); + emitByte(0xC0 | encode); + emitByte(imm8); + } + } + + public final void roll(Register dst) { + int encode = prefixAndEncode(dst.encoding); + emitByte(0xD3); + emitByte(0xC0 | encode); + } + + public final void rorl(Register dst, int imm8) { + assert isShiftCount(imm8) : "illegal shift count"; + int encode = prefixAndEncode(dst.encoding); + if (imm8 == 1) { + emitByte(0xD1); + emitByte(0xC8 | encode); + } else { + emitByte(0xC1); + emitByte(0xC8 | encode); + emitByte(imm8); + } + } + + public final void rorl(Register dst) { + int encode = prefixAndEncode(dst.encoding); + emitByte(0xD3); + emitByte(0xC8 | encode); + } + + public final void rolq(Register dst, int imm8) { + assert isShiftCount(imm8) : "illegal shift count"; + int encode = prefixqAndEncode(dst.encoding); + if (imm8 == 1) { + emitByte(0xD1); + emitByte(0xC0 | encode); + } else { + emitByte(0xC1); + emitByte(0xC0 | encode); + emitByte(imm8); + } + } + + public final void rolq(Register dst) { + int encode = prefixqAndEncode(dst.encoding); + emitByte(0xD3); + emitByte(0xC0 | encode); + } + + public final void rorq(Register dst, int imm8) { + assert isShiftCount(imm8) : "illegal shift count"; + int encode = prefixqAndEncode(dst.encoding); + if (imm8 == 1) { + emitByte(0xD1); + emitByte(0xC8 | encode); + } else { + emitByte(0xC1); + emitByte(0xC8 | encode); + emitByte(imm8); + } + } + + public final void rorq(Register dst) { + int encode = prefixqAndEncode(dst.encoding); + emitByte(0xD3); + emitByte(0xC8 | encode); + } + public final void sqrtsd(Register dst, AMD64Address src) { assert dst.getRegisterCategory() == AMD64.XMM; emitByte(0xF2); @@ -2442,9 +2523,14 @@ public final void shrq(Register dst, int imm8) { assert isShiftCount(imm8 >> 1) : "illegal shift count"; int encode = prefixqAndEncode(dst.encoding); - emitByte(0xC1); - emitByte(0xE8 | encode); - emitByte(imm8); + if (imm8 == 1) { + emitByte(0xD1); + emitByte(0xE8 | encode); + } else { + emitByte(0xC1); + emitByte(0xE8 | encode); + emitByte(imm8); + } } public final void shrq(Register dst) { @@ -2512,6 +2598,32 @@ emitInt(imm32); } + public final void xaddl(AMD64Address dst, Register src) { + prefix(dst, src); + emitByte(0x0F); + emitByte(0xC1); + emitOperandHelper(src, dst); + } + + public final void xaddq(AMD64Address dst, Register src) { + prefixq(dst, src); + emitByte(0x0F); + emitByte(0xC1); + emitOperandHelper(src, dst); + } + + public final void xchgl(Register dst, AMD64Address src) { + prefix(src, dst); + emitByte(0x87); + emitOperandHelper(dst, src); + } + + public final void xchgq(Register dst, AMD64Address src) { + prefixq(src, dst); + emitByte(0x87); + emitOperandHelper(dst, src); + } + public final void xorq(Register dst, int imm32) { emitArithImm32q(6, dst, imm32); } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.asm.hsail/src/com/oracle/graal/asm/hsail/HSAILAssembler.java --- a/graal/com.oracle.graal.asm.hsail/src/com/oracle/graal/asm/hsail/HSAILAssembler.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.asm.hsail/src/com/oracle/graal/asm/hsail/HSAILAssembler.java Wed Apr 23 15:48:38 2014 +0200 @@ -25,18 +25,15 @@ import static com.oracle.graal.api.code.MemoryBarriers.*; import static com.oracle.graal.api.code.ValueUtil.*; -import java.lang.reflect.*; - -import com.amd.okra.*; import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.graph.*; +import com.oracle.graal.compiler.common.*; import com.oracle.graal.hsail.*; /** * This class contains routines to emit HSAIL assembly code. */ -public class HSAILAssembler extends AbstractHSAILAssembler { +public abstract class HSAILAssembler extends AbstractHSAILAssembler { /** * Stack size in bytes (used to keep track of spilling). @@ -87,35 +84,13 @@ * references get updated by the GC whenever the GC moves an Object. * * @param a the destination register - * @param obj the Object being moved + * @param src the Object Constant being moved */ - public final void mov(Register a, Object obj) { - String regName = "$d" + a.encoding(); - // For a null object simply move 0x0 into the destination register. - if (obj == null) { - emitString("mov_b64 " + regName + ", 0x0; // null object"); - } else { - // Get a JNI reference handle to the object. - long refHandle = OkraUtil.getRefHandle(obj); - // Get the clasname of the object for emitting a comment. - Class clazz = obj.getClass(); - String className = clazz.getName(); - String comment = "// handle for object of type " + className; - // If the object is an array note the array length in the comment. - if (className.startsWith("[")) { - comment += ", length " + Array.getLength(obj); - } - // First move the reference handle into a register. - emitString("mov_b64 " + regName + ", 0x" + Long.toHexString(refHandle) + "; " + comment); - // Next load the Object addressed by this reference handle into the destination reg. - emitString("ld_global_u64 " + regName + ", [" + regName + "];"); - } - - } + public abstract void mov(Register a, Constant src); public final void emitMov(Kind kind, Value dst, Value src) { if (isRegister(dst) && isConstant(src) && kind.getStackKind() == Kind.Object) { - mov(asRegister(dst), (asConstant(src)).asObject()); + mov(asRegister(dst), asConstant(src)); } else { String argtype = getArgTypeFromKind(kind).substring(1); emitString("mov_b" + argtype + " " + mapRegOrConstToString(dst) + ", " + mapRegOrConstToString(src) + ";"); @@ -127,7 +102,7 @@ if (reg instanceof RegisterValue) { storeValue = HSAIL.mapRegister(reg); } else if (reg instanceof Constant) { - storeValue = ((Constant) reg).asBoxedValue().toString(); + storeValue = ((Constant) reg).toValueString(); } emitString(instr + " " + storeValue + ", " + mapAddress(addr) + ";"); } @@ -313,14 +288,14 @@ * float compares. * @param isUnsignedCompare - flag specifying if this is a compare of unsigned values. */ - public void emitCompare(Value src0, Value src1, String condition, boolean unordered, boolean isUnsignedCompare) { + public void emitCompare(Kind compareKind, Value src0, Value src1, String condition, boolean unordered, boolean isUnsignedCompare) { // Formulate the prefix of the instruction. // if unordered is true, it should be ignored unless the src type is f32 or f64 - String argType = getArgTypeFromKind(src1.getKind().getStackKind()); + String argType = getArgTypeFromKind(compareKind); String unorderedPrefix = (argType.startsWith("f") && unordered ? "u" : ""); String prefix = "cmp_" + condition + unorderedPrefix + "_b1_" + (isUnsignedCompare ? getArgTypeForceUnsigned(src1) : argType); // Generate a comment for debugging purposes - String comment = (isConstant(src1) && (src1.getKind() == Kind.Object) && (asConstant(src1).asObject() == null) ? " // null test " : ""); + String comment = (isConstant(src1) && (src1.getKind() == Kind.Object) && (asConstant(src1).isNull()) ? " // null test " : ""); // Emit the instruction. emitString(prefix + " $c0, " + mapRegOrConstToString(src0) + ", " + mapRegOrConstToString(src1) + ";" + comment); } @@ -367,8 +342,7 @@ case Long: return "0x" + Long.toHexString(consrc.asLong()); case Object: - Object obj = consrc.asObject(); - if (obj == null) { + if (consrc.isNull()) { return "0"; } else { throw GraalInternalError.shouldNotReachHere("unknown type: " + src); @@ -533,7 +507,7 @@ */ private void emitWithOptionalTestForNull(boolean testForNull, String mnemonic, Value result, Value... sources) { if (testForNull) { - emitCompare(result, Constant.forLong(0), "eq", false, true); + emitCompare(Kind.Long, result, Constant.forLong(0), "eq", false, true); } emitForceUnsigned(mnemonic, result, sources); if (testForNull) { @@ -550,8 +524,8 @@ * @param newValue the new value that will be written to the memory location if the cmpValue * comparison matches */ - public void emitAtomicCas(AllocatableValue result, HSAILAddress address, Value cmpValue, Value newValue) { - emitString(String.format("atomic_cas_global_b%d %s, %s, %s, %s;", getArgSize(cmpValue), HSAIL.mapRegister(result), mapAddress(address), mapRegOrConstToString(cmpValue), + public void emitAtomicCas(Kind accessKind, AllocatableValue result, HSAILAddress address, Value cmpValue, Value newValue) { + emitString(String.format("atomic_cas_global_b%d %s, %s, %s, %s;", getArgSizeFromKind(accessKind), HSAIL.mapRegister(result), mapAddress(address), mapRegOrConstToString(cmpValue), mapRegOrConstToString(newValue))); } @@ -560,10 +534,17 @@ * * @param result result operand that gets the original contents of the memory location * @param address the memory location - * @param deltaValue the amount to add + * @param delta the amount to add */ - public void emitAtomicAdd(AllocatableValue result, HSAILAddress address, Value deltaValue) { - emitString(String.format("atomic_add_global_u%d %s, %s, %s;", getArgSize(result), HSAIL.mapRegister(result), mapAddress(address), mapRegOrConstToString(deltaValue))); + public void emitAtomicAdd(AllocatableValue result, HSAILAddress address, Value delta) { + // ensure result and delta agree (this should probably be at some higher level) + Value mydelta = delta; + if (!isConstant(delta) && (getArgSize(result) != getArgSize(delta))) { + emitConvert(result, delta, result.getKind(), delta.getKind()); + mydelta = result; + } + String prefix = getArgTypeForceUnsigned(result); + emitString(String.format("atomic_add_global_%s %s, %s, %s;", prefix, HSAIL.mapRegister(result), mapAddress(address), mapRegOrConstToString(mydelta))); } /** diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.asm.ptx/src/com/oracle/graal/asm/ptx/PTXAssembler.java --- a/graal/com.oracle.graal.asm.ptx/src/com/oracle/graal/asm/ptx/PTXAssembler.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.asm.ptx/src/com/oracle/graal/asm/ptx/PTXAssembler.java Wed Apr 23 15:48:38 2014 +0200 @@ -27,9 +27,9 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.*; -import com.oracle.graal.graph.*; +import com.oracle.graal.compiler.common.*; +import com.oracle.graal.compiler.common.calc.*; import com.oracle.graal.lir.*; -import com.oracle.graal.nodes.calc.*; public class PTXAssembler extends AbstractPTXAssembler { @@ -370,7 +370,7 @@ assert var instanceof Variable; assert val instanceof Constant; Constant constant = (Constant) val; - return ("[" + ((space == PTXStateSpace.Parameter) ? emitParameter((Variable) var) : emitRegister((Variable) var, false)) + " + " + constant.asBoxedValue() + "]"); + return ("[" + ((space == PTXStateSpace.Parameter) ? emitParameter((Variable) var) : emitRegister((Variable) var, false)) + " + " + constant.toValueString() + "]"); } @Override diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.asm.ptx/src/com/oracle/graal/asm/ptx/PTXMacroAssembler.java --- a/graal/com.oracle.graal.asm.ptx/src/com/oracle/graal/asm/ptx/PTXMacroAssembler.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.asm.ptx/src/com/oracle/graal/asm/ptx/PTXMacroAssembler.java Wed Apr 23 15:48:38 2014 +0200 @@ -26,7 +26,7 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.graph.*; +import com.oracle.graal.compiler.common.*; import com.oracle.graal.lir.*; public class PTXMacroAssembler extends PTXAssembler { diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAddress.java --- a/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAddress.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAddress.java Wed Apr 23 15:48:38 2014 +0200 @@ -25,7 +25,7 @@ import static com.oracle.graal.sparc.SPARC.*; import com.oracle.graal.api.code.*; -import com.oracle.graal.graph.*; +import com.oracle.graal.compiler.common.*; import com.oracle.graal.sparc.*; public class SPARCAddress extends AbstractAddress { diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.asm.test/src/com/oracle/graal/asm/test/AssemblerTest.java --- a/graal/com.oracle.graal.asm.test/src/com/oracle/graal/asm/test/AssemblerTest.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.asm.test/src/com/oracle/graal/asm/test/AssemblerTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -61,7 +61,7 @@ byte[] targetCode = test.generateCode(compResult, codeCache.getTarget(), registerConfig, cc); compResult.setTargetCode(targetCode, targetCode.length); - InstalledCode code = codeCache.addMethod(method, compResult, null); + InstalledCode code = codeCache.addMethod(method, compResult, null, null); DisassemblerProvider dis = Graal.getRequiredCapability(RuntimeProvider.class).getHostBackend().getDisassembler(); if (dis != null) { diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.baseline/src/com/oracle/graal/baseline/BaselineBytecodeParser.java --- a/graal/com.oracle.graal.baseline/src/com/oracle/graal/baseline/BaselineBytecodeParser.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.baseline/src/com/oracle/graal/baseline/BaselineBytecodeParser.java Wed Apr 23 15:48:38 2014 +0200 @@ -22,8 +22,7 @@ */ package com.oracle.graal.baseline; -import static com.oracle.graal.phases.GraalOptions.*; -import static java.lang.reflect.Modifier.*; +import static com.oracle.graal.compiler.common.GraalOptions.*; import java.util.*; @@ -33,27 +32,49 @@ import com.oracle.graal.api.meta.ResolvedJavaType.Representation; import com.oracle.graal.bytecode.*; import com.oracle.graal.compiler.alloc.*; +import com.oracle.graal.compiler.common.*; +import com.oracle.graal.compiler.common.calc.*; +import com.oracle.graal.compiler.common.cfg.*; import com.oracle.graal.compiler.gen.*; import com.oracle.graal.compiler.target.*; import com.oracle.graal.debug.*; import com.oracle.graal.debug.Debug.Scope; -import com.oracle.graal.graph.*; import com.oracle.graal.java.*; import com.oracle.graal.java.BciBlockMapping.BciBlock; +import com.oracle.graal.java.BciBlockMapping.LocalLiveness; import com.oracle.graal.lir.*; -import com.oracle.graal.nodes.calc.*; -import com.oracle.graal.nodes.calc.FloatConvertNode.FloatConvert; +import com.oracle.graal.lir.StandardOp.BlockEndOp; +import com.oracle.graal.lir.gen.*; import com.oracle.graal.nodes.cfg.*; import com.oracle.graal.phases.*; -public class BaselineBytecodeParser extends AbstractBytecodeParser implements BytecodeParserTool { +public class BaselineBytecodeParser extends AbstractBytecodeParser implements BytecodeParserTool { private Backend backend; protected LIRGenerator gen; private LIRGenerationResult lirGenRes; private BytecodeLIRBuilder lirBuilder; + @SuppressWarnings("unused") private BciBlock[] loopHeaders; + private LocalLiveness liveness; + private BciBlockBitMap blockVisited; + + private static class BciBlockBitMap { + BitSet bitSet; + + public BciBlockBitMap(BciBlockMapping blockMap) { + bitSet = new BitSet(blockMap.blocks.size()); + } + + public boolean get(BciBlock block) { + return bitSet.get(block.getId()); + } + + public void set(BciBlock block) { + bitSet.set(block.getId()); + } + } public BaselineBytecodeParser(MetaAccessProvider metaAccess, ResolvedJavaMethod method, GraphBuilderConfiguration graphBuilderConfig, OptimisticOptimizations optimisticOpts, - LIRFrameStateBuilder frameState, BytecodeStream stream, ProfilingInfo profilingInfo, ConstantPool constantPool, int entryBCI, Backend backend) { + BaselineFrameStateBuilder frameState, BytecodeStream stream, ProfilingInfo profilingInfo, ConstantPool constantPool, int entryBCI, Backend backend) { super(metaAccess, method, graphBuilderConfig, optimisticOpts, frameState, stream, profilingInfo, constantPool, entryBCI); this.backend = backend; @@ -74,6 +95,9 @@ // compute the block map, setup exception handlers and get the entrypoint(s) BciBlockMapping blockMap = BciBlockMapping.create(method); + loopHeaders = blockMap.loopHeaders; + liveness = blockMap.liveness; + blockVisited = new BciBlockBitMap(blockMap); // add predecessors for (BciBlock block : blockMap.blocks) { for (BciBlock successor : block.getSuccessors()) { @@ -81,13 +105,15 @@ } } - if (isSynchronized(method.getModifiers())) { + if (method.isSynchronized()) { throw GraalInternalError.unimplemented("Handle synchronized methods"); } - // TODO: clear non live locals + frameState = new BaselineFrameStateBuilder(method); + frameState.clearNonLiveLocals(blockMap.startBlock, liveness, true); currentBlock = blockMap.startBlock; + blockMap.startBlock.entryState = frameState; if (blockMap.startBlock.isLoopHeader) { throw GraalInternalError.unimplemented("Handle start block as loop header"); } @@ -95,7 +121,7 @@ // add loops ? how do we add looks when we haven't parsed the bytecode? // create the control flow graph - LIRControlFlowGraph cfg = new LIRControlFlowGraph(blockMap.blocks.toArray(new BciBlock[0]), new Loop[0]); + BaselineControlFlowGraph cfg = new BaselineControlFlowGraph(blockMap); BlocksToDoubles blockProbabilities = new BlocksToDoubles(blockMap.blocks.size()); for (BciBlock b : blockMap.blocks) { @@ -235,8 +261,7 @@ @Override protected Value genIntegerMul(Kind kind, Value x, Value y) { - // TODO Auto-generated method stub - throw GraalInternalError.unimplemented("Auto-generated method stub"); + return gen.emitMul(x, y); } @Override @@ -354,12 +379,6 @@ } @Override - protected void genGoto() { - assert currentBlock.numNormalSuccessors() == 1; - gen.emitJump(LabelRef.forSuccessor(lirGenRes.getLIR(), currentBlock, 0)); - } - - @Override protected Value genObjectEquals(Value x, Value y) { // TODO Auto-generated method stub throw GraalInternalError.unimplemented("Auto-generated method stub"); @@ -377,7 +396,7 @@ BciBlock trueBlock = currentBlock.getSuccessors().get(0); BciBlock falseBlock = currentBlock.getSuccessors().get(1); if (trueBlock == falseBlock) { - gen.emitJump(LabelRef.forSuccessor(lirGenRes.getLIR(), currentBlock, 0)); + genGoto(); return; } @@ -396,8 +415,8 @@ } } - LabelRef trueDestination = LabelRef.forSuccessor(lirGenRes.getLIR(), currentBlock, 0); - LabelRef falseDestination = LabelRef.forSuccessor(lirGenRes.getLIR(), currentBlock, 1); + LabelRef trueDestination = getSuccessor(0); + LabelRef falseDestination = getSuccessor(1); gen.emitCompareBranch(x.getKind(), x, y, cond, false, trueDestination, falseDestination, probability); } @@ -546,13 +565,7 @@ } @Override - protected void setBlockSuccessor(Value switchNode, int i, Value createBlockTarget) { - // TODO Auto-generated method stub - throw GraalInternalError.unimplemented("Auto-generated method stub"); - } - - @Override - protected Value genIntegerSwitch(Value value, int size, int[] keys, double[] keyProbabilities, int[] keySuccessors) { + protected void genIntegerSwitch(Value value, ArrayList actualSuccessors, int[] keys, double[] keyProbabilities, int[] keySuccessors) { // TODO Auto-generated method stub throw GraalInternalError.unimplemented("Auto-generated method stub"); } @@ -570,28 +583,127 @@ return v; } - @Override - protected Value genDeoptimization() { - // TODO Auto-generated method stub - throw GraalInternalError.unimplemented("Auto-generated method stub"); + private void createTarget(BciBlock block) { + assert block != null && frameState != null; + assert !block.isExceptionEntry || frameState.stackSize() == 1; + + if (!blockVisited.get(block)) { + /* + * This is the first time we see this block as a branch target. Create and return a + * placeholder that later can be replaced with a MergeNode when we see this block again. + */ + blockVisited.set(block); + if (block.getPredecessorCount() > 1) { + /* + * If there are more than one predecessors we have to ensure that we are not passing + * constants to the new framestate otherwise we will get interfacing problems. + */ + moveConstantsToVariables(); + } + block.entryState = frameState.copy(); + block.entryState.clearNonLiveLocals(block, liveness, true); + + Debug.log("createTarget %s: first visit", block); + return; + } + + // We already saw this block before, so we have to merge states. + if (!((BaselineFrameStateBuilder) block.entryState).isCompatibleWith(frameState)) { + throw new BailoutException("stacks do not match; bytecodes would not verify"); + } + + if (block.isLoopHeader) { + assert currentBlock == null || currentBlock.getId() >= block.getId() : "must be backward branch"; + if (currentBlock != null && currentBlock.numNormalSuccessors() == 1) { + // this is the only successor of the current block so we can adjust + adaptFramestate((BaselineFrameStateBuilder) block.entryState); + return; + } + GraalInternalError.unimplemented("Loops not yet supported"); + } + assert currentBlock == null || currentBlock.getId() < block.getId() : "must not be backward branch"; + + /* + * This is the second time we see this block. Create the actual MergeNode and the End Node + * for the already existing edge. For simplicity, we leave the placeholder in the graph and + * just append the new nodes after the placeholder. + */ + if (currentBlock != null && currentBlock.numNormalSuccessors() == 1) { + // this is the only successor of the current block so we can adjust + adaptFramestate((BaselineFrameStateBuilder) block.entryState); + return; + } + GraalInternalError.unimplemented("second block visit not yet implemented"); + + // merge frame states e.g. block.entryState.merge(mergeNode, target.state); + + Debug.log("createTarget %s: merging state", block); } - @Override - protected Value createBlockTarget(double probability, BciBlock bciBlock, AbstractFrameStateBuilder stateAfter) { - // TODO Auto-generated method stub - throw GraalInternalError.unimplemented("Auto-generated method stub"); + private void moveConstantsToVariables() { + Debug.log("moveConstantsToVariables: framestate before: %s", frameState); + for (int i = 0; i < frameState.stackSize(); i++) { + Value src = frameState.stackAt(i); + if (src instanceof Constant) { + AllocatableValue dst = gen.newVariable(src.getPlatformKind()); + gen.emitMove(dst, src); + frameState.storeStack(i, dst); + Debug.log("introduce new variabe %s for stackslot %d (end of block %s", dst, i, currentBlock); + } + } + for (int i = 0; i < frameState.localsSize(); i++) { + Value src = frameState.localAt(i); + if (src instanceof Constant) { + AllocatableValue dst = gen.newVariable(src.getPlatformKind()); + gen.emitMove(dst, src); + frameState.storeLocal(i, dst); + Debug.log("introduce new variabe %s for local %d (end of block %s", dst, i, currentBlock); + } + } + Debug.log("moveConstantsToVariables: framestate after: %s", frameState); + } + + private static void adaptValues(Value dst, Value src, PhiResolver resolver) { + if (dst == null) { + return; + } + assert src != null : "Source is null but Destination is not!"; + + if (!dst.equals(src)) { + resolver.move(dst, src); + } + } + + private void adaptFramestate(BaselineFrameStateBuilder other) { + assert frameState.isCompatibleWith(other) : "framestates not compatible!"; + PhiResolver resolver = new PhiResolver(gen); + for (int i = 0; i < frameState.stackSize(); i++) { + Value src = frameState.stackAt(i); + Value dst = other.stackAt(i); + adaptValues(dst, src, resolver); + } + for (int i = 0; i < frameState.localsSize(); i++) { + Value src = frameState.localAt(i); + Value dst = other.localAt(i); + adaptValues(dst, src, resolver); + } + resolver.dispose(); } @Override protected void processBlock(BciBlock block) { + frameState = (BaselineFrameStateBuilder) block.entryState; + setCurrentFrameState(frameState); currentBlock = block; iterateBytecodesForBlock(block); } - @Override - protected void appendGoto(Value target) { - // TODO Auto-generated method stub - throw GraalInternalError.unimplemented("Auto-generated method stub"); + private boolean isBlockEnd() { + List l = gen.getResult().getLIR().getLIRforBlock(currentBlock); + if (l.isEmpty()) { + return false; + } + return l.get(l.size() - 1) instanceof BlockEndOp; } @Override @@ -605,6 +717,14 @@ assert block.getPredecessorCount() > 0; } + if (block.isLoopHeader) { + /* + * We need to preserve the frame state builder of the loop header so that we can merge + * values for phi functions, so make a copy of it. + */ + block.entryState = frameState.copy(); + + } int endBCI = stream.endBCI(); stream.setBCI(block.startBci); @@ -620,19 +740,20 @@ processBytecode(bci, opcode); - if (gen.hasBlockEnd(currentBlock)) { - break; - } - stream.next(); bci = stream.currentBCI(); + if (isBlockEnd()) { + break; + } + if (bci < endBCI) { if (bci > block.endBci) { - assert block.numNormalSuccessors() == 1; - assert !block.getSuccessor(0).isExceptionEntry; - // we fell through to the next block, add a goto and break - genGoto(); + if (block.numNormalSuccessors() == 1) { + assert !block.getSuccessor(0).isExceptionEntry; + // we fell through to the next block, add a goto and break + genGoto(); + } break; } } @@ -646,4 +767,14 @@ frameState.storeLocal(i, x); } + LabelRef getSuccessor(int index) { + createTarget(currentBlock.getSuccessor(index)); + return LabelRef.forSuccessor(lirGenRes.getLIR(), currentBlock, index); + } + + @Override + protected void genGoto() { + gen.emitJump(getSuccessor(0)); + } + } \ No newline at end of file diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.baseline/src/com/oracle/graal/baseline/BaselineCompiler.java --- a/graal/com.oracle.graal.baseline/src/com/oracle/graal/baseline/BaselineCompiler.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.baseline/src/com/oracle/graal/baseline/BaselineCompiler.java Wed Apr 23 15:48:38 2014 +0200 @@ -22,7 +22,7 @@ */ package com.oracle.graal.baseline; -import static com.oracle.graal.phases.GraalOptions.*; +import static com.oracle.graal.compiler.common.GraalOptions.*; import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; @@ -57,7 +57,7 @@ ConstantPool constantPool = method.getConstantPool(); TTY.Filter filter = new TTY.Filter(PrintFilter.getValue(), method); - LIRFrameStateBuilder frameState = new LIRFrameStateBuilder(method); + BaselineFrameStateBuilder frameState = new BaselineFrameStateBuilder(method); BaselineBytecodeParser parser = new BaselineBytecodeParser(metaAccess, method, graphBuilderConfig, optimisticOpts, frameState, stream, profilingInfo, constantPool, entryBCI, backend); diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.baseline/src/com/oracle/graal/baseline/BaselineControlFlowGraph.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.baseline/src/com/oracle/graal/baseline/BaselineControlFlowGraph.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2014, 2014, 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.baseline; + +import java.util.*; + +import com.oracle.graal.compiler.common.*; +import com.oracle.graal.compiler.common.cfg.*; +import com.oracle.graal.java.*; +import com.oracle.graal.java.BciBlockMapping.BciBlock; + +public class BaselineControlFlowGraph implements AbstractControlFlowGraph { + + private BciBlock[] blocks; + private Collection> loops; + private BitSet visited; + + public BaselineControlFlowGraph(BciBlockMapping blockMap) { + blocks = blockMap.blocks.toArray(new BciBlock[0]); + loops = new ArrayList<>(); + computeLoopInformation(); + } + + public BciBlock[] getBlocks() { + return blocks; + } + + public Collection> getLoops() { + return loops; + } + + public BciBlock getStartBlock() { + if (blocks.length > 0) { + return blocks[0]; + } + return null; + } + + private void computeLoopInformation() { + visited = new BitSet(blocks.length); + Deque stack = new ArrayDeque<>(); + for (int i = blocks.length - 1; i >= 0; i--) { + BciBlock block = blocks[i]; + calcLoop(block, stack); + } + } + + private void calcLoop(BciBlock block, Deque stack) { + if (visited.get(block.getId())) { + return; + } + visited.set(block.getId()); + if (block.isLoopEnd()) { + BciBlock loopHeader = getLoopHeader(block); + BaselineLoop l = new BaselineLoop(stack.peek(), loops.size(), loopHeader); + loops.add(l); + stack.push(l); + } + block.loop = stack.peek(); + if (block.isLoopHeader()) { + assert block.loop.header.equals(block); + stack.pop(); + } + for (BciBlock pred : block.getPredecessors()) { + calcLoop(pred, stack); + } + } + + private static BciBlock getLoopHeader(BciBlock block) { + assert block.isLoopEnd(); + for (BciBlock sux : block.getSuccessors()) { + if (sux.isLoopHeader() && sux.getId() <= block.getId() && block.loops == sux.loops) { + return sux; + } + } + throw GraalInternalError.shouldNotReachHere("No loop header found for " + block); + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.baseline/src/com/oracle/graal/baseline/BaselineFrameStateBuilder.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.baseline/src/com/oracle/graal/baseline/BaselineFrameStateBuilder.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2014, 2014, 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.baseline; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.java.*; + +public class BaselineFrameStateBuilder extends AbstractFrameStateBuilder { + + private static final Value[] EMPTY_ARRAY = new Value[0]; + + public BaselineFrameStateBuilder(ResolvedJavaMethod method) { + // we always need at least one stack slot (for exceptions) + super(method, new Value[method.getMaxLocals()], new Value[Math.max(1, method.getMaxStackSize())], EMPTY_ARRAY); + } + + protected BaselineFrameStateBuilder(BaselineFrameStateBuilder other) { + super(other); + } + + @Override + protected Value[] getEmtpyArray() { + return EMPTY_ARRAY; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("[locals: ["); + for (int i = 0; i < locals.length; i++) { + sb.append(i == 0 ? "" : ",").append(locals[i] == null ? "_" : locals[i].toString()); + } + sb.append("] stack: ["); + for (int i = 0; i < stackSize; i++) { + sb.append(i == 0 ? "" : ",").append(stack[i] == null ? "_" : stack[i].toString()); + } + sb.append("] locks: ["); + for (int i = 0; i < lockedObjects.length; i++) { + sb.append(i == 0 ? "" : ",").append(lockedObjects[i].toString()); + } + sb.append("]"); + if (rethrowException) { + sb.append(" rethrowException"); + } + sb.append("]"); + return sb.toString(); + } + + @Override + public BaselineFrameStateBuilder copy() { + return new BaselineFrameStateBuilder(this); + } + + private static boolean isCompatible(Value x, Value y) { + if (x == null && y == null) { + return true; + } + if ((x == null || y == null) || (x.getKind() != y.getKind())) { + return false; + } + return true; + + } + + @Override + public boolean isCompatibleWith(BaselineFrameStateBuilder other) { + assert method.equals(other.method) && localsSize() == other.localsSize() : "Can only compare frame states of the same method"; + + if (stackSize() != other.stackSize()) { + return false; + } + for (int i = 0; i < stackSize(); i++) { + if (!isCompatible(stackAt(i), other.stackAt(i))) { + return false; + } + } + if (lockedObjects.length != other.lockedObjects.length) { + return false; + } + return true; + } +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.baseline/src/com/oracle/graal/baseline/BaselineLoop.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.baseline/src/com/oracle/graal/baseline/BaselineLoop.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2014, 2014, 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.baseline; + +import com.oracle.graal.compiler.common.cfg.*; +import com.oracle.graal.java.BciBlockMapping.BciBlock; + +public class BaselineLoop extends Loop { + + protected BaselineLoop(Loop parent, int index, BciBlock header) { + super(parent, index, header); + } + + @Override + public long numBackedges() { + // currently only loops with one backedge are supported + return 1; + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.baseline/src/com/oracle/graal/baseline/LIRBlock.java --- a/graal/com.oracle.graal.baseline/src/com/oracle/graal/baseline/LIRBlock.java Wed Apr 23 15:22:20 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2014, 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.baseline; - -import java.util.*; - -import com.oracle.graal.nodes.cfg.*; - -public class LIRBlock extends AbstractBlockBase { - - public LIRBlock(int id) { - this.id = id; - predecessors = Collections.emptyList(); - successors = Collections.emptyList(); - } - - public Loop getLoop() { - // TODO Auto-generated method stub - return null; - } - - public int getLoopDepth() { - // TODO Auto-generated method stub - return 0; - } - - public boolean isLoopEnd() { - // TODO Auto-generated method stub - return false; - } - - public boolean isLoopHeader() { - // TODO Auto-generated method stub - return false; - } - - public boolean isExceptionEntry() { - // TODO Auto-generated method stub - return false; - } - -} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.baseline/src/com/oracle/graal/baseline/LIRControlFlowGraph.java --- a/graal/com.oracle.graal.baseline/src/com/oracle/graal/baseline/LIRControlFlowGraph.java Wed Apr 23 15:22:20 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2014, 2014, 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.baseline; - -import com.oracle.graal.java.BciBlockMapping.BciBlock; -import com.oracle.graal.nodes.cfg.*; - -public class LIRControlFlowGraph implements AbstractControlFlowGraph { - - private BciBlock[] blocks; - private Loop[] loops; - - public LIRControlFlowGraph(BciBlock[] blocks, Loop[] loops) { - this.blocks = blocks; - this.loops = loops; - } - - public BciBlock[] getBlocks() { - return blocks; - } - - public Loop[] getLoops() { - return loops; - } - - public BciBlock getStartBlock() { - if (blocks.length > 0) { - return blocks[0]; - } - return null; - } - -} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.baseline/src/com/oracle/graal/baseline/LIRFrameStateBuilder.java --- a/graal/com.oracle.graal.baseline/src/com/oracle/graal/baseline/LIRFrameStateBuilder.java Wed Apr 23 15:22:20 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,249 +0,0 @@ -/* - * Copyright (c) 2014, 2014, 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.baseline; - -import com.oracle.graal.api.meta.*; -import com.oracle.graal.java.*; - -public class LIRFrameStateBuilder extends AbstractFrameStateBuilder { - - private final Value[] locals; - private final Value[] stack; - private Value[] lockedObjects; - - public LIRFrameStateBuilder(ResolvedJavaMethod method) { - super(method); - - this.locals = new Value[method.getMaxLocals()]; - // we always need at least one stack slot (for exceptions) - this.stack = new Value[Math.max(1, method.getMaxStackSize())]; - } - - protected LIRFrameStateBuilder(LIRFrameStateBuilder other) { - super(other); - // TODO Auto-generated constructor stub - locals = other.locals; - stack = other.stack; - lockedObjects = other.lockedObjects; - } - - @Override - public int localsSize() { - return locals.length; - } - - @Override - public Value localAt(int i) { - return locals[i]; - } - - @Override - public Value stackAt(int i) { - return stack[i]; - } - - @Override - public Value loadLocal(int i) { - Value x = locals[i]; - assert !isTwoSlot(x.getKind()) || locals[i + 1] == null; - assert i == 0 || locals[i - 1] == null || !isTwoSlot(locals[i - 1].getKind()); - return x; - } - - @Override - public void storeLocal(int i, Value x) { - assert x == null || x.getKind() != Kind.Void && x.getKind() != Kind.Illegal : "unexpected value: " + x; - locals[i] = x; - if (x != null && isTwoSlot(x.getKind())) { - // if this is a double word, then kill i+1 - locals[i + 1] = null; - } - if (x != null && i > 0) { - Value p = locals[i - 1]; - if (p != null && isTwoSlot(p.getKind())) { - // if there was a double word at i - 1, then kill it - locals[i - 1] = null; - } - } - } - - @Override - public void storeStack(int i, Value x) { - assert x == null || (stack[i] == null || x.getKind() == stack[i].getKind()) : "Method does not handle changes from one-slot to two-slot values or non-alive values"; - stack[i] = x; - } - - @Override - public void push(Kind kind, Value x) { - assert x.getKind() != Kind.Void && x.getKind() != Kind.Illegal; - xpush(assertKind(kind, x)); - if (isTwoSlot(kind)) { - xpush(null); - } - } - - @Override - public void xpush(Value x) { - assert x == null || (x.getKind() != Kind.Void && x.getKind() != Kind.Illegal); - stack[stackSize++] = x; - } - - @Override - public void ipush(Value x) { - xpush(assertInt(x)); - } - - @Override - public void fpush(Value x) { - xpush(assertFloat(x)); - } - - @Override - public void apush(Value x) { - xpush(assertObject(x)); - } - - @Override - public void lpush(Value x) { - xpush(assertLong(x)); - } - - @Override - public void dpush(Value x) { - xpush(assertDouble(x)); - - } - - @Override - public void pushReturn(Kind kind, Value x) { - if (kind != Kind.Void) { - push(kind.getStackKind(), x); - } - } - - @Override - public Value pop(Kind kind) { - assert kind != Kind.Void; - if (isTwoSlot(kind)) { - xpop(); - } - return assertKind(kind, xpop()); - } - - @Override - public Value xpop() { - Value result = stack[--stackSize]; - return result; - } - - @Override - public Value ipop() { - return assertInt(xpop()); - } - - @Override - public Value fpop() { - return assertFloat(xpop()); - } - - @Override - public Value apop() { - return assertObject(xpop()); - } - - @Override - public Value lpop() { - assertHigh(xpop()); - return assertLong(xpop()); - } - - @Override - public Value dpop() { - assertHigh(xpop()); - return assertDouble(xpop()); - } - - @Override - public Value[] popArguments(int slotSize, int argSize) { - int base = stackSize - slotSize; - Value[] r = new Value[argSize]; - int argIndex = 0; - int stackindex = 0; - while (stackindex < slotSize) { - Value element = stack[base + stackindex]; - assert element != null; - r[argIndex++] = element; - stackindex += stackSlots(element.getKind()); - } - stackSize = base; - return r; - } - - @Override - public Value peek(int argumentNumber) { - int idx = stackSize() - 1; - for (int i = 0; i < argumentNumber; i++) { - if (stackAt(idx) == null) { - idx--; - assert isTwoSlot(stackAt(idx).getKind()); - } - idx--; - } - return stackAt(idx); - } - - private static Value assertKind(Kind kind, Value x) { - assert x != null && x.getKind() == kind : "kind=" + kind + ", value=" + x + ((x == null) ? "" : ", value.kind=" + x.getKind()); - return x; - } - - private static Value assertLong(Value x) { - assert x != null && (x.getKind() == Kind.Long); - return x; - } - - private static Value assertInt(Value x) { - assert x != null && (x.getKind() == Kind.Int); - return x; - } - - private static Value assertFloat(Value x) { - assert x != null && (x.getKind() == Kind.Float); - return x; - } - - private static Value assertObject(Value x) { - assert x != null && (x.getKind() == Kind.Object); - return x; - } - - private static Value assertDouble(Value x) { - assert x != null && (x.getKind() == Kind.Double); - return x; - } - - private static void assertHigh(Value x) { - assert x == null; - } -} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java --- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java Wed Apr 23 15:48:38 2014 +0200 @@ -35,8 +35,9 @@ import com.oracle.graal.asm.*; import com.oracle.graal.asm.amd64.AMD64Address.Scale; import com.oracle.graal.asm.amd64.AMD64Assembler.ConditionFlag; -import com.oracle.graal.compiler.gen.*; -import com.oracle.graal.graph.*; +import com.oracle.graal.compiler.common.*; +import com.oracle.graal.compiler.common.calc.*; +import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.lir.*; import com.oracle.graal.lir.StandardOp.JumpOp; import com.oracle.graal.lir.amd64.*; @@ -51,6 +52,7 @@ import com.oracle.graal.lir.amd64.AMD64Arithmetic.Unary1Op; import com.oracle.graal.lir.amd64.AMD64Arithmetic.Unary2MemoryOp; import com.oracle.graal.lir.amd64.AMD64Arithmetic.Unary2Op; +import com.oracle.graal.lir.amd64.AMD64Arithmetic.Unary2RegOp; import com.oracle.graal.lir.amd64.AMD64Compare.CompareMemoryOp; import com.oracle.graal.lir.amd64.AMD64Compare.CompareOp; import com.oracle.graal.lir.amd64.AMD64ControlFlow.BranchOp; @@ -67,10 +69,7 @@ import com.oracle.graal.lir.amd64.AMD64Move.MoveToRegOp; import com.oracle.graal.lir.amd64.AMD64Move.StackLeaOp; import com.oracle.graal.lir.amd64.AMD64Move.ZeroExtendLoadOp; -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.calc.*; -import com.oracle.graal.nodes.calc.FloatConvertNode.FloatConvert; -import com.oracle.graal.nodes.type.*; +import com.oracle.graal.lir.gen.*; import com.oracle.graal.phases.util.*; /** @@ -589,8 +588,7 @@ append(new DivRemOp(op, rax, asAllocatable(b), state)); } - public Value[] emitIntegerDivRem(Value a, Value b, DeoptimizingNode deopting) { - LIRFrameState state = state(deopting); + public Value[] emitIntegerDivRem(Value a, Value b, LIRFrameState state) { switch (a.getKind().getStackKind()) { case Int: emitDivRem(IDIVREM, a, b, state); @@ -604,13 +602,13 @@ } @Override - public Value emitDiv(Value a, Value b, DeoptimizingNode deopting) { + public Value emitDiv(Value a, Value b, LIRFrameState state) { switch (a.getKind().getStackKind()) { case Int: - emitDivRem(IDIV, a, b, state(deopting)); + emitDivRem(IDIV, a, b, state); return emitMove(RAX_I); case Long: - emitDivRem(LDIV, a, b, state(deopting)); + emitDivRem(LDIV, a, b, state); return emitMove(RAX_L); case Float: { Variable result = newVariable(a.getPlatformKind()); @@ -628,13 +626,13 @@ } @Override - public Value emitRem(Value a, Value b, DeoptimizingNode deopting) { + public Value emitRem(Value a, Value b, LIRFrameState state) { switch (a.getKind().getStackKind()) { case Int: - emitDivRem(IREM, a, b, state(deopting)); + emitDivRem(IREM, a, b, state); return emitMove(RDX_I); case Long: - emitDivRem(LREM, a, b, state(deopting)); + emitDivRem(LREM, a, b, state); return emitMove(RDX_L); case Float: { Variable result = newVariable(a.getPlatformKind()); @@ -652,8 +650,7 @@ } @Override - public Variable emitUDiv(Value a, Value b, DeoptimizingNode deopting) { - LIRFrameState state = state(deopting); + public Variable emitUDiv(Value a, Value b, LIRFrameState state) { switch (a.getKind().getStackKind()) { case Int: emitDivRem(IUDIV, a, b, state); @@ -667,8 +664,7 @@ } @Override - public Variable emitURem(Value a, Value b, DeoptimizingNode deopting) { - LIRFrameState state = state(deopting); + public Variable emitURem(Value a, Value b, LIRFrameState state) { switch (a.getKind().getStackKind()) { case Int: emitDivRem(IUREM, a, b, state); @@ -765,9 +761,9 @@ } } - private AllocatableValue emitConvert1Op(PlatformKind kind, AMD64Arithmetic op, AllocatableValue input) { + private AllocatableValue emitConvert2RegOp(PlatformKind kind, AMD64Arithmetic op, AllocatableValue input) { Variable result = newVariable(kind); - append(new Unary1Op(op, result, input)); + append(new Unary2RegOp(op, result, input)); return result; } @@ -850,7 +846,7 @@ public Value emitNarrow(Value inputVal, int bits) { if (inputVal.getKind() == Kind.Long && bits <= 32) { // TODO make it possible to reinterpret Long as Int in LIR without move - return emitConvert1Op(Kind.Int, L2I, asAllocatable(inputVal)); + return emitConvert2RegOp(Kind.Int, L2I, asAllocatable(inputVal)); } else { return inputVal; } @@ -1020,7 +1016,7 @@ } @Override - protected void emitStrategySwitch(SwitchStrategy strategy, Variable key, LabelRef[] keyTargets, LabelRef defaultTarget) { + public void emitStrategySwitch(SwitchStrategy strategy, Variable key, LabelRef[] keyTargets, LabelRef defaultTarget) { // a temp is needed for loading object constants boolean needsTemp = key.getKind() == Kind.Object; append(new StrategySwitchOp(strategy, keyTargets, defaultTarget, key, needsTemp ? newVariable(key.getKind()) : Value.ILLEGAL)); diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64MemoryPeephole.java --- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64MemoryPeephole.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64MemoryPeephole.java Wed Apr 23 15:48:38 2014 +0200 @@ -23,26 +23,26 @@ package com.oracle.graal.compiler.amd64; +import static com.oracle.graal.compiler.common.GraalOptions.*; import static com.oracle.graal.lir.amd64.AMD64Arithmetic.*; import static com.oracle.graal.nodes.ConstantNode.*; -import static com.oracle.graal.phases.GraalOptions.*; import java.util.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.*; +import com.oracle.graal.compiler.common.*; +import com.oracle.graal.compiler.common.calc.*; +import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.debug.*; -import com.oracle.graal.graph.*; import com.oracle.graal.lir.*; import com.oracle.graal.lir.amd64.*; import com.oracle.graal.lir.amd64.AMD64ControlFlow.BranchOp; import com.oracle.graal.lir.amd64.AMD64ControlFlow.FloatBranchOp; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; -import com.oracle.graal.nodes.calc.FloatConvertNode.FloatConvert; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.nodes.type.*; public class AMD64MemoryPeephole implements MemoryArithmeticLIRLowerer { protected final AMD64NodeLIRBuilder gen; @@ -71,13 +71,17 @@ protected LIRFrameState getState(Access access) { if (access instanceof DeoptimizingNode) { - return gen.getLIRGenerator().state((DeoptimizingNode) access); + return gen.state((DeoptimizingNode) access); } return null; } + protected Kind getMemoryKind(Access access) { + return (Kind) gen.getLIRGenerator().getPlatformKind(access.asNode().stamp()); + } + protected AMD64AddressValue makeAddress(Access access) { - return (AMD64AddressValue) access.accessLocation().generateAddress(gen, gen.operand(access.object())); + return (AMD64AddressValue) access.accessLocation().generateAddress(gen, gen.getLIRGeneratorTool(), gen.operand(access.object())); } protected Value emitBinaryMemory(AMD64Arithmetic op, boolean commutative, ValueNode x, ValueNode y, Access access) { @@ -90,7 +94,7 @@ } } ensureEvaluated(other); - return gen.getLIRGenerator().emitBinaryMemory(op, access.accessLocation().getValueKind(), gen.getLIRGeneratorTool().asAllocatable(gen.operand(other)), makeAddress(access), getState(access)); + return gen.getLIRGenerator().emitBinaryMemory(op, getMemoryKind(access), gen.getLIRGeneratorTool().asAllocatable(gen.operand(other)), makeAddress(access), getState(access)); } /** @@ -129,7 +133,7 @@ @Override public Value emitAddMemory(ValueNode x, ValueNode y, Access access) { - switch (access.accessLocation().getValueKind()) { + switch (getMemoryKind(access)) { case Int: return emitBinaryMemory(IADD, true, x, y, access); case Long: @@ -145,7 +149,7 @@ @Override public Value emitSubMemory(ValueNode x, ValueNode y, Access access) { - switch (access.accessLocation().getValueKind()) { + switch (getMemoryKind(access)) { case Int: return emitBinaryMemory(ISUB, false, x, y, access); case Long: @@ -161,7 +165,7 @@ @Override public Value emitMulMemory(ValueNode x, ValueNode y, Access access) { - switch (access.accessLocation().getValueKind()) { + switch (getMemoryKind(access)) { case Int: return emitBinaryMemory(IMUL, true, x, y, access); case Long: @@ -187,7 +191,7 @@ @Override public Value emitAndMemory(ValueNode x, ValueNode y, Access access) { - Kind kind = access.accessLocation().getValueKind(); + Kind kind = getMemoryKind(access); switch (kind) { case Int: return emitBinaryMemory(IAND, true, x, y, access); @@ -224,7 +228,7 @@ @Override public Value emitOrMemory(ValueNode x, ValueNode y, Access access) { - switch (access.accessLocation().getValueKind()) { + switch (getMemoryKind(access)) { case Int: return emitBinaryMemory(IOR, true, x, y, access); case Long: @@ -236,7 +240,7 @@ @Override public Value emitXorMemory(ValueNode x, ValueNode y, Access access) { - switch (access.accessLocation().getValueKind()) { + switch (getMemoryKind(access)) { case Int: return emitBinaryMemory(IXOR, true, x, y, access); case Long: @@ -249,7 +253,7 @@ @Override public Value emitReinterpretMemory(Stamp stamp, Access access) { PlatformKind to = gen.getLIRGenerator().getPlatformKind(stamp); - Kind from = access.accessLocation().getValueKind(); + Kind from = getMemoryKind(access); assert to != from : "should have been eliminated"; /* @@ -353,10 +357,10 @@ } @Override - public Value emitZeroExtendMemory(int inputBits, int resultBits, Access access) { - assert resultBits == 32 || resultBits == 64; - Kind memoryKind = access.accessLocation().getValueKind(); - if (memoryKind.getBitCount() != inputBits && !memoryKind.isUnsigned()) { + public Value emitZeroExtendMemory(int fromBits, int toBits, Access access) { + assert fromBits != toBits; + Kind memoryKind = getMemoryKind(access); + if (memoryKind.getBitCount() != fromBits && !memoryKind.isUnsigned()) { // The memory being read from is signed and smaller than the result size so // this is a sign extension to inputBits followed by a zero extension to resultBits // which can't be expressed in a memory operation. @@ -366,7 +370,7 @@ memoryKind = Kind.Char; } evaluateDeferred(); - return gen.getLIRGenerator().emitZeroExtendMemory(memoryKind, resultBits, makeAddress(access), getState(access)); + return gen.getLIRGenerator().emitZeroExtendMemory(memoryKind, toBits, makeAddress(access), getState(access)); } public boolean emitIfMemory(IfNode x, Access access) { @@ -399,7 +403,7 @@ private boolean emitIntegerTestBranchMemory(ValueNode left, ValueNode right, Access access, LabelRef trueLabel, LabelRef falseLabel, double trueLabelProbability) { ValueNode other = selectOtherInput(left, right, access); - Kind kind = access.accessLocation().getValueKind(); + Kind kind = getMemoryKind(access); if (other.isConstant()) { if (kind != kind.getStackKind()) { return false; @@ -439,7 +443,7 @@ protected boolean emitCompareBranchMemory(ValueNode left, ValueNode right, Access access, Condition cond, boolean unorderedIsTrue, LabelRef trueLabel, LabelRef falseLabel, double trueLabelProbability) { ValueNode other = selectOtherInput(left, right, access); - Kind kind = access.accessLocation().getValueKind(); + Kind kind = getMemoryKind(access); boolean mirrored = false; if (other.isConstant()) { diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64NodeLIRBuilder.java --- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64NodeLIRBuilder.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64NodeLIRBuilder.java Wed Apr 23 15:48:38 2014 +0200 @@ -29,6 +29,7 @@ import com.oracle.graal.compiler.gen.*; import com.oracle.graal.lir.*; import com.oracle.graal.lir.amd64.*; +import com.oracle.graal.lir.gen.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.spi.*; @@ -60,7 +61,7 @@ @Override public void emitNullCheck(ValueNode v, DeoptimizingNode deopt) { assert v.getKind() == Kind.Object : v + " - " + v.stamp() + " @ " + deopt; - append(new AMD64Move.NullCheckOp(gen.load(operand(v)), gen.state(deopt))); + append(new AMD64Move.NullCheckOp(gen.load(operand(v)), state(deopt))); } @Override @@ -73,7 +74,7 @@ if (((fixedWithNextNode instanceof IntegerDivNode) || (fixedWithNextNode instanceof IntegerRemNode)) && fixedWithNextNode.getClass() != divRem.getClass()) { FixedBinaryNode otherDivRem = (FixedBinaryNode) fixedWithNextNode; if (otherDivRem.x() == divRem.x() && otherDivRem.y() == divRem.y() && !hasOperand(otherDivRem)) { - Value[] results = ((AMD64LIRGenerator) gen).emitIntegerDivRem(operand(divRem.x()), operand(divRem.y()), (DeoptimizingNode) valueNode); + Value[] results = ((AMD64LIRGenerator) gen).emitIntegerDivRem(operand(divRem.x()), operand(divRem.y()), state((DeoptimizingNode) valueNode)); if (divRem instanceof IntegerDivNode) { setResult(divRem, results[0]); setResult(otherDivRem, results[1]); @@ -103,7 +104,7 @@ @Override public void visitInfopointNode(InfopointNode i) { - append(new InfopointOp(gen.stateFor(i.getState()), i.reason)); + append(new InfopointOp(stateFor(i.getState()), i.reason)); } @Override diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/FieldIntrospection.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/FieldIntrospection.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.compiler.common; + +import java.lang.reflect.*; +import java.util.*; +import java.util.concurrent.*; + +public abstract class FieldIntrospection extends UnsafeAccess { + + /** + * Interface used by {@link #rescanAllFieldOffsets(CalcOffset)} to determine the offset (in + * bytes) of a field. + */ + public interface CalcOffset { + + long getOffset(Field field); + } + + public static class DefaultCalcOffset implements CalcOffset { + + @Override + public long getOffset(Field field) { + return unsafe.objectFieldOffset(field); + } + } + + protected static final ConcurrentHashMap, FieldIntrospection> allClasses = new ConcurrentHashMap<>(); + + private final Class clazz; + protected long[] dataOffsets; + protected Map fieldNames; + protected Map> fieldTypes; + + public FieldIntrospection(Class clazz) { + this.clazz = clazz; + } + + public Class getClazz() { + return clazz; + } + + public static void rescanAllFieldOffsets(CalcOffset calc) { + for (FieldIntrospection nodeClass : allClasses.values()) { + nodeClass.rescanFieldOffsets(calc); + } + } + + protected abstract void rescanFieldOffsets(CalcOffset calc); + + public abstract static class BaseFieldScanner { + + private final CalcOffset calc; + + /** The offsets of fields that are not specially handled by subclasses. */ + public final ArrayList dataOffsets = new ArrayList<>(); + + public final Map fieldNames = new HashMap<>(); + public final Map> fieldTypes = new HashMap<>(); + + protected BaseFieldScanner(CalcOffset calc) { + this.calc = calc; + } + + public void scan(Class clazz) { + Class currentClazz = clazz; + do { + for (Field field : currentClazz.getDeclaredFields()) { + if (Modifier.isStatic(field.getModifiers())) { + continue; + } + Class type = field.getType(); + long offset = calc.getOffset(field); + + // scanField() may overwrite the name with a customized name. + fieldNames.put(offset, field.getName()); + fieldTypes.put(offset, type); + + scanField(field, type, offset); + } + currentClazz = currentClazz.getSuperclass(); + } while (currentClazz.getSuperclass() != Object.class); + } + + protected abstract void scanField(Field field, Class type, long offset); + } + + protected static void copyInto(long[] dest, long[] src) { + assert dest.length == src.length; + for (int i = 0; i < dest.length; i++) { + dest[i] = src[i]; + } + } + + protected static void copyInto(T[] dest, T[] src) { + assert dest.length == src.length; + for (int i = 0; i < dest.length; i++) { + dest[i] = src[i]; + } + } + + protected static void copyInto(T[] dest, List src) { + assert dest.length == src.size(); + for (int i = 0; i < dest.length; i++) { + dest[i] = src.get(i); + } + } + + protected static T[] arrayUsingSortedOffsets(Map map, long[] sortedOffsets, T[] result) { + for (int i = 0; i < sortedOffsets.length; i++) { + result[i] = map.get(sortedOffsets[i]); + } + return result; + } + + protected static long[] sortedLongCopy(ArrayList list1) { + Collections.sort(list1); + long[] result = new long[list1.size()]; + for (int i = 0; i < list1.size(); i++) { + result[i] = list1.get(i); + } + return result; + } + + protected static long[] sortedLongCopy(ArrayList list1, ArrayList list2) { + Collections.sort(list1); + Collections.sort(list2); + long[] result = new long[list1.size() + list2.size()]; + for (int i = 0; i < list1.size(); i++) { + result[i] = list1.get(i); + } + for (int i = 0; i < list2.size(); i++) { + result[list1.size() + i] = list2.get(i); + } + return result; + } +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/GraalInternalError.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/GraalInternalError.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2011, 2014, 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.common; + +import java.util.*; + +/** + * This error represents a conditions that should never occur during normal operation. + */ +public class GraalInternalError extends Error { + + private static final long serialVersionUID = 531632331813456233L; + private final ArrayList context = new ArrayList<>(); + + public static RuntimeException unimplemented() { + throw new GraalInternalError("unimplemented"); + } + + public static RuntimeException unimplemented(String msg) { + throw new GraalInternalError("unimplemented: %s", msg); + } + + public static RuntimeException shouldNotReachHere() { + throw new GraalInternalError("should not reach here"); + } + + public static RuntimeException shouldNotReachHere(String msg) { + throw new GraalInternalError("should not reach here: %s", msg); + } + + /** + * Checks a given condition and throws a {@link GraalInternalError} if it is false. Guarantees + * are stronger than assertions in that they are always checked. Error messages for guarantee + * violations should clearly indicate the nature of the problem as well as a suggested solution + * if possible. + * + * @param condition the condition to check + * @param msg the message that will be associated with the error, in + * {@link String#format(String, Object...)} syntax + * @param args arguments to the format string + */ + public static void guarantee(boolean condition, String msg, Object... args) { + if (!condition) { + throw new GraalInternalError("failed guarantee: " + msg, args); + } + } + + /** + * This constructor creates a {@link GraalInternalError} with a message assembled via + * {@link String#format(String, Object...)}. It always uses the ENGLISH locale in order to + * always generate the same output. + * + * @param msg the message that will be associated with the error, in String.format syntax + * @param args parameters to String.format - parameters that implement {@link Iterable} will be + * expanded into a [x, x, ...] representation. + */ + public GraalInternalError(String msg, Object... args) { + super(format(msg, args)); + } + + /** + * This constructor creates a {@link GraalInternalError} for a given causing Throwable instance. + * + * @param cause the original exception that contains additional information on this error + */ + public GraalInternalError(Throwable cause) { + super(cause); + } + + /** + * This constructor creates a {@link GraalInternalError} from a given GraalInternalError + * instance. + * + * @param e the original GraalInternalError + */ + public GraalInternalError(GraalInternalError e) { + super(e); + context.addAll(e.context); + } + + @Override + public String toString() { + StringBuilder str = new StringBuilder(); + str.append(super.toString()); + for (String s : context) { + str.append("\n\tat ").append(s); + } + return str.toString(); + } + + private static String format(String msg, Object... args) { + if (args != null) { + // expand Iterable parameters into a list representation + for (int i = 0; i < args.length; i++) { + if (args[i] instanceof Iterable) { + ArrayList list = new ArrayList<>(); + for (Object o : (Iterable) args[i]) { + list.add(o); + } + args[i] = list.toString(); + } + } + } + return String.format(Locale.ENGLISH, msg, args); + } + + public GraalInternalError addContext(String newContext) { + this.context.add(newContext); + return this; + } + + public GraalInternalError addContext(String name, Object obj) { + return addContext(format("%s: %s", name, obj)); + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/GraalOptions.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/GraalOptions.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,283 @@ +/* + * Copyright (c) 2009, 2014, 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.common; + +import com.oracle.graal.options.*; + +/** + * This class encapsulates options that control the behavior of the Graal compiler. + */ +// @formatter:off +public final class GraalOptions { + + @Option(help = "Use baseline compiler configuration") + public static final OptionValue UseBaselineCompiler = new OptionValue<>(false); + @Option(help = "Enable use of compiler intrinsics") + public static final OptionValue Intrinsify = new OptionValue<>(true); + @Option(help = "Enable inlining of monomorphic calls") + public static final OptionValue InlineMonomorphicCalls = new OptionValue<>(true); + @Option(help = "Enable inlining of polymorphic calls") + public static final OptionValue InlinePolymorphicCalls = new OptionValue<>(true); + @Option(help = "Enable inlining of megamorphic calls") + public static final OptionValue InlineMegamorphicCalls = new OptionValue<>(true); + @Option(help = "") + public static final OptionValue MegamorphicInliningMinMethodProbability = new OptionValue<>(0.33D); + @Option(help = "") + public static final OptionValue MaximumDesiredSize = new OptionValue<>(20000); + @Option(help = "") + public static final OptionValue MaximumRecursiveInlining = new OptionValue<>(5); + + // inlining settings + @Option(help = "") + public static final OptionValue BoostInliningForEscapeAnalysis = new OptionValue<>(2f); + @Option(help = "") + public static final OptionValue RelevanceCapForInlining = new OptionValue<>(1f); + @Option(help = "") + public static final OptionValue CapInheritedRelevance = new OptionValue<>(1f); + @Option(help = "") + public static final OptionValue IterativeInlining = new OptionValue<>(false); + + @Option(help = "") + public static final OptionValue TrivialInliningSize = new OptionValue<>(10); + @Option(help = "") + public static final OptionValue MaximumInliningSize = new OptionValue<>(300); + @Option(help = "") + public static final OptionValue SmallCompiledLowLevelGraphSize = new OptionValue<>(300); + @Option(help = "") + public static final OptionValue LimitInlinedInvokes = new OptionValue<>(5.0); + @Option(help = "") + public static final OptionValue InlineEverything = new OptionValue<>(false); + + // escape analysis settings + @Option(help = "") + public static final OptionValue PartialEscapeAnalysis = new OptionValue<>(true); + @Option(help = "") + public static final OptionValue EscapeAnalysisIterations = new OptionValue<>(2); + @Option(help = "") + public static final OptionValue EscapeAnalyzeOnly = new OptionValue<>(null); + @Option(help = "") + public static final OptionValue MaximumEscapeAnalysisArrayLength = new OptionValue<>(32); + @Option(help = "") + public static final OptionValue PEAInliningHints = new OptionValue<>(false); + + @Option(help = "") + public static final OptionValue TailDuplicationProbability = new OptionValue<>(0.5); + @Option(help = "") + public static final OptionValue TailDuplicationTrivialSize = new OptionValue<>(1); + + // profiling information + @Option(help = "") + public static final OptionValue DeoptsToDisableOptimisticOptimization = new OptionValue<>(40); + + // graph caching + @Option(help = "") + public static final OptionValue CacheGraphs = new OptionValue<>(true); + + //loop transform settings TODO (gd) tune + @Option(help = "") + public static final OptionValue LoopPeeling = new OptionValue<>(true); + @Option(help = "") + public static final OptionValue ReassociateInvariants = new OptionValue<>(true); + @Option(help = "") + public static final OptionValue FullUnroll = new OptionValue<>(true); + @Option(help = "") + public static final OptionValue LoopUnswitch = new OptionValue<>(true); + @Option(help = "") + public static final OptionValue FullUnrollMaxNodes = new OptionValue<>(300); + @Option(help = "") + public static final OptionValue ExactFullUnrollMaxNodes = new OptionValue<>(1200); + @Option(help = "") + public static final OptionValue MinimumPeelProbability = new OptionValue<>(0.35f); + @Option(help = "") + public static final OptionValue LoopMaxUnswitch = new OptionValue<>(3); + @Option(help = "") + public static final OptionValue LoopUnswitchMaxIncrease = new OptionValue<>(50); + @Option(help = "") + public static final OptionValue LoopUnswitchUncertaintyBoost = new OptionValue<>(5); + @Option(help = "") + public static final OptionValue UseLoopLimitChecks = new OptionValue<>(true); + + // debugging settings + @Option(help = "") + public static final OptionValue ZapStackOnMethodEntry = new OptionValue<>(false); + @Option(help = "") + public static final OptionValue DeoptALot = new OptionValue<>(false); + @Option(help = "") + public static final OptionValue VerifyPhases = new OptionValue<>(false); + + @Option(help = "") + public static final OptionValue PrintFilter = new OptionValue<>(null); + + // Debug settings: + @Option(help = "") + public static final OptionValue BootstrapReplacements = new OptionValue<>(false); + @Option(help = "") + public static final OptionValue GCDebugStartCycle = new OptionValue<>(-1); + // Ideal graph visualizer output settings + @Option(help = "Dump IdealGraphVisualizer output in binary format") + public static final OptionValue PrintBinaryGraphs = new OptionValue<>(true); + @Option(help = "Output probabilities for fixed nodes during binary graph dumping") + public static final OptionValue PrintGraphProbabilities = new OptionValue<>(false); + @Option(help = "Enable dumping to the C1Visualizer. Enabling this option implies PrintBackendCFG.") + public static final OptionValue PrintCFG = new OptionValue<>(false); + @Option(help = "Enable dumping LIR, register allocation and code generation info to the C1Visualizer.") + public static final OptionValue PrintBackendCFG = new OptionValue<>(true); + @Option(help = "") + public static final OptionValue PrintIdealGraphFile = new OptionValue<>(false); + @Option(help = "") + public static final OptionValue PrintIdealGraphAddress = new OptionValue<>("127.0.0.1"); + @Option(help = "") + public static final OptionValue PrintIdealGraphPort = new OptionValue<>(4444); + @Option(help = "") + public static final OptionValue PrintBinaryGraphPort = new OptionValue<>(4445); + + // Other printing settings + @Option(help = "") + public static final OptionValue PrintCompilation = new OptionValue<>(false); + @Option(help = "") + public static final OptionValue PrintAfterCompilation = new OptionValue<>(false); + @Option(help = "Print profiling information when parsing a method's bytecode") + public static final OptionValue PrintProfilingInformation = new OptionValue<>(false); + @Option(help = "") + public static final OptionValue PrintCodeBytes = new OptionValue<>(false); + @Option(help = "") + public static final OptionValue PrintBailout = new OptionValue<>(false); + @Option(help = "") + public static final OptionValue TraceEscapeAnalysis = new OptionValue<>(false); + @Option(help = "") + public static final OptionValue ExitVMOnBailout = new OptionValue<>(false); + @Option(help = "") + public static final OptionValue ExitVMOnException = new OptionValue<>(true); + @Option(help = "") + public static final OptionValue PrintStackTraceOnException = new OptionValue<>(false); + @Option(help = "Set a phase after which the decompiler dumps the graph, -G:Dump= required") + public static final OptionValue DecompileAfterPhase = new OptionValue<>(null); + + // HotSpot command line options + @Option(help = "") + public static final OptionValue HotSpotPrintCompilation = new OptionValue<>(false); + @Option(help = "") + public static final OptionValue HotSpotCIPrintCompilerName = new OptionValue<>(false); + @Option(help = "") + public static final OptionValue HotSpotPrintInlining = new OptionValue<>(false); + + // Register allocator debugging + @Option(help = "") + public static final OptionValue RegisterPressure = new OptionValue<>(null); + + // Code generator settings + @Option(help = "") + public static final OptionValue ConditionalElimination = new OptionValue<>(true); + @Option(help = "") + public static final OptionValue UseProfilingInformation = new OptionValue<>(true); + @Option(help = "") + public static final OptionValue RemoveNeverExecutedCode = new OptionValue<>(true); + @Option(help = "") + public static final OptionValue UseExceptionProbability = new OptionValue<>(true); + @Option(help = "") + public static final OptionValue UseExceptionProbabilityForOperations = new OptionValue<>(true); + @Option(help = "") + public static final OptionValue OmitHotExceptionStacktrace = new OptionValue<>(false); + @Option(help = "") + public static final OptionValue GenSafepoints = new OptionValue<>(true); + @Option(help = "") + public static final OptionValue GenLoopSafepoints = new OptionValue<>(true); + @Option(help = "") + public static final OptionValue UseTypeCheckHints = new OptionValue<>(true); + @Option(help = "") + public static final OptionValue InlineVTableStubs = new OptionValue<>(true); + @Option(help = "") + public static final OptionValue AlwaysInlineVTableStubs = new OptionValue<>(false); + @Option(help = "") + public static final OptionValue GenAssertionCode = new OptionValue<>(false); + @Option(help = "") + public static final OptionValue AlignCallsForPatching = new OptionValue<>(true); + @Option(help = "") + public static final OptionValue ResolveClassBeforeStaticInvoke = new OptionValue<>(false); + @Option(help = "") + public static final OptionValue CanOmitFrame = new OptionValue<>(true); + + @Option(help = "") + public static final OptionValue MemoryAwareScheduling = new OptionValue<>(true); + + // Translating tableswitch instructions + @Option(help = "") + public static final OptionValue MinimumJumpTableSize = new OptionValue<>(5); + @Option(help = "") + public static final OptionValue RangeTestsSwitchDensity = new OptionValue<>(5); + @Option(help = "") + public static final OptionValue MinTableSwitchDensity = new OptionValue<>(0.5); + + // Ahead of time compilation + @Option(help = "Try to avoid emitting code where patching is required") + public static final OptionValue ImmutableCode = new OptionValue<>(false); + + @Option(help = "") + public static final OptionValue CallArrayCopy = new OptionValue<>(true); + + // Runtime settings + @Option(help = "") + public static final OptionValue SupportJsrBytecodes = new OptionValue<>(true); + + @Option(help = "") + public static final OptionValue OptAssumptions = new OptionValue<>(true); + @Option(help = "") + public static final OptionValue OptConvertDeoptsToGuards = new OptionValue<>(true); + @Option(help = "") + public static final OptionValue OptReadElimination = new OptionValue<>(true); + @Option(help = "") + public static final OptionValue OptCanonicalizer = new OptionValue<>(true); + @Option(help = "") + public static final OptionValue OptDeoptimizationGrouping = new OptionValue<>(true); + @Option(help = "") + public static final OptionValue OptScheduleOutOfLoops = new OptionValue<>(true); + @Option(help = "") + public static final OptionValue OptEliminateGuards = new OptionValue<>(true); + @Option(help = "") + public static final OptionValue OptImplicitNullChecks = new OptionValue<>(true); + @Option(help = "") + public static final OptionValue OptLivenessAnalysis = new OptionValue<>(true); + @Option(help = "") + public static final OptionValue OptLoopTransform = new OptionValue<>(true); + @Option(help = "") + public static final OptionValue OptFloatingReads = new OptionValue<>(true); + @Option(help = "") + public static final OptionValue OptTailDuplication = new OptionValue<>(true); + @Option(help = "") + public static final OptionValue OptEliminatePartiallyRedundantGuards = new OptionValue<>(true); + @Option(help = "") + public static final OptionValue OptFilterProfiledTypes = new OptionValue<>(true); + @Option(help = "") + public static final OptionValue OptDevirtualizeInvokesOptimistically = new OptionValue<>(true); + @Option(help = "") + public static final OptionValue OptPushThroughPi = new OptionValue<>(true); + @Option(help = "Allow backend to emit arithmetic and compares directly against memory.") + public static final OptionValue OptFoldMemory = new OptionValue<>(true); + + + /** + * Counts the various paths taken through snippets. + */ + @Option(help = "") + public static final OptionValue SnippetCounters = new OptionValue<>(false); +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/UnsafeAccess.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/UnsafeAccess.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.compiler.common; + +import java.lang.reflect.*; + +import sun.misc.*; + +public class UnsafeAccess { + + /** + * An instance of {@link Unsafe} for use within Graal. + */ + public static final Unsafe unsafe = getUnsafe(); + + private static Unsafe getUnsafe() { + try { + // this will fail if Graal is not part of the boot class path + return Unsafe.getUnsafe(); + } catch (SecurityException e) { + // nothing to do + } + try { + Field theUnsafeInstance = Unsafe.class.getDeclaredField("theUnsafe"); + theUnsafeInstance.setAccessible(true); + return (Unsafe) theUnsafeInstance.get(Unsafe.class); + } catch (Exception e) { + // currently we rely on being able to use Unsafe... + throw new RuntimeException("exception while trying to get Unsafe.theUnsafe via reflection:", e); + } + } + + /** + * Copies the contents of a {@link String} to a native memory buffer as a {@code '\0'} + * terminated C string. The native memory buffer is allocated via + * {@link Unsafe#allocateMemory(long)}. The caller is responsible for releasing the buffer when + * it is no longer needed via {@link Unsafe#freeMemory(long)}. + * + * @return the native memory pointer of the C string created from {@code s} + */ + public static long createCString(String s) { + return writeCString(s, unsafe.allocateMemory(s.length() + 1)); + } + + /** + * Reads a {@code '\0'} terminated C string from native memory and converts it to a + * {@link String}. + * + * @return a Java string + */ + public static String readCString(long address) { + if (address == 0) { + return null; + } + StringBuffer sb = new StringBuffer(); + for (int i = 0;; i++) { + char c = (char) unsafe.getByte(address + i); + if (c == 0) { + break; + } + sb.append(c); + } + return sb.toString(); + } + + /** + * Writes the contents of a {@link String} to a native memory buffer as a {@code '\0'} + * terminated C string. The caller is responsible for ensuring the buffer is at least + * {@code s.length() + 1} bytes long. The caller is also responsible for releasing the buffer + * when it is no longer. + * + * @return the value of {@code buf} + */ + public static long writeCString(String s, long buf) { + int size = s.length(); + for (int i = 0; i < size; i++) { + unsafe.putByte(buf + i, (byte) s.charAt(i)); + } + unsafe.putByte(buf + size, (byte) '\0'); + return buf; + } +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/calc/Condition.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/calc/Condition.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,634 @@ +/* + * Copyright (c) 2009, 2014, 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.common.calc; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.common.*; + +/** + * Condition codes used in conditionals. + */ +public enum Condition { + /** + * Equal. + */ + EQ("=="), + + /** + * Not equal. + */ + NE("!="), + + /** + * Signed less than. + */ + LT("<"), + + /** + * Signed less than or equal. + */ + LE("<="), + + /** + * Signed greater than. + */ + GT(">"), + + /** + * Signed greater than or equal. + */ + GE(">="), + + /** + * Unsigned greater than or equal ("above than or equal"). + */ + AE("|>=|"), + + /** + * Unsigned less than or equal ("below than or equal"). + */ + BE("|<=|"), + + /** + * Unsigned greater than ("above than"). + */ + AT("|>|"), + + /** + * Unsigned less than ("below than"). + */ + BT("|<|"); + + public final String operator; + + private Condition(String operator) { + this.operator = operator; + } + + public boolean check(int left, int right) { + switch (this) { + case EQ: + return left == right; + case NE: + return left != right; + case LT: + return left < right; + case LE: + return left <= right; + case GT: + return left > right; + case GE: + return left >= right; + case AE: + return UnsignedMath.aboveOrEqual(left, right); + case BE: + return UnsignedMath.belowOrEqual(left, right); + case AT: + return UnsignedMath.aboveThan(left, right); + case BT: + return UnsignedMath.belowThan(left, right); + } + throw new IllegalArgumentException(this.toString()); + } + + /** + * Given a condition and its negation, this method returns true for one of the two and false for + * the other one. This can be used to keep comparisons in a canonical form. + * + * @return true if this condition is considered to be the canonical form, false otherwise. + */ + public boolean isCanonical() { + switch (this) { + case EQ: + return true; + case NE: + return false; + case LT: + return true; + case LE: + return false; + case GT: + return false; + case GE: + return false; + case BT: + return true; + case BE: + return false; + case AT: + return false; + case AE: + return false; + } + throw new IllegalArgumentException(this.toString()); + } + + /** + * Returns true if the condition needs to be mirrored to get to a canonical condition. The + * result of the mirroring operation might still need to be negated to achieve a canonical form. + */ + public boolean canonicalMirror() { + switch (this) { + case EQ: + return false; + case NE: + return false; + case LT: + return false; + case LE: + return true; + case GT: + return true; + case GE: + return false; + case BT: + return false; + case BE: + return true; + case AT: + return true; + case AE: + return false; + } + throw new IllegalArgumentException(this.toString()); + } + + /** + * Returns true if the condition needs to be negated to get to a canonical condition. The result + * of the negation might still need to be mirrored to achieve a canonical form. + */ + public boolean canonicalNegate() { + switch (this) { + case EQ: + return false; + case NE: + return true; + case LT: + return false; + case LE: + return true; + case GT: + return false; + case GE: + return true; + case BT: + return false; + case BE: + return true; + case AT: + return false; + case AE: + return true; + } + throw new IllegalArgumentException(this.toString()); + } + + /** + * Negate this conditional. + * + * @return the condition that represents the negation + */ + public final Condition negate() { + switch (this) { + case EQ: + return NE; + case NE: + return EQ; + case LT: + return GE; + case LE: + return GT; + case GT: + return LE; + case GE: + return LT; + case BT: + return AE; + case BE: + return AT; + case AT: + return BE; + case AE: + return BT; + } + throw new IllegalArgumentException(this.toString()); + } + + public boolean implies(Condition other) { + if (other == this) { + return true; + } + switch (this) { + case EQ: + return other == LE || other == GE || other == BE || other == AE; + case NE: + return false; + case LT: + return other == LE || other == NE; + case LE: + return false; + case GT: + return other == GE || other == NE; + case GE: + return false; + case BT: + return other == BE || other == NE; + case BE: + return false; + case AT: + return other == AE || other == NE; + case AE: + return false; + } + throw new IllegalArgumentException(this.toString()); + } + + /** + * Mirror this conditional (i.e. commute "a op b" to "b op' a") + * + * @return the condition representing the equivalent commuted operation + */ + public final Condition mirror() { + switch (this) { + case EQ: + return EQ; + case NE: + return NE; + case LT: + return GT; + case LE: + return GE; + case GT: + return LT; + case GE: + return LE; + case BT: + return AT; + case BE: + return AE; + case AT: + return BT; + case AE: + return BE; + } + throw new IllegalArgumentException(); + } + + /** + * Returns true if this condition represents an unsigned comparison. EQ and NE are not + * considered to be unsigned. + */ + public final boolean isUnsigned() { + return this == Condition.BT || this == Condition.BE || this == Condition.AT || this == Condition.AE; + } + + /** + * Checks if this conditional operation is commutative. + * + * @return {@code true} if this operation is commutative + */ + public final boolean isCommutative() { + return this == EQ || this == NE; + } + + /** + * Attempts to fold a comparison between two constants and return the result. + * + * @param lt the constant on the left side of the comparison + * @param rt the constant on the right side of the comparison + * @param constantReflection needed to compare constants + * @return {@link Boolean#TRUE} if the comparison is known to be true, {@link Boolean#FALSE} if + * the comparison is known to be false + */ + public boolean foldCondition(Constant lt, Constant rt, ConstantReflectionProvider constantReflection) { + assert !lt.getKind().isNumericFloat() && !rt.getKind().isNumericFloat(); + return foldCondition(lt, rt, constantReflection, false); + } + + /** + * Attempts to fold a comparison between two constants and return the result. + * + * @param lt the constant on the left side of the comparison + * @param rt the constant on the right side of the comparison + * @param constantReflection needed to compare constants + * @param unorderedIsTrue true if an undecided float comparison should result in "true" + * @return true if the comparison is known to be true, false if the comparison is known to be + * false + */ + public boolean foldCondition(Constant lt, Constant rt, ConstantReflectionProvider constantReflection, boolean unorderedIsTrue) { + switch (lt.getKind()) { + case Boolean: + case Byte: + case Char: + case Short: + case Int: { + int x = lt.asInt(); + int y = rt.asInt(); + switch (this) { + case EQ: + return x == y; + case NE: + return x != y; + case LT: + return x < y; + case LE: + return x <= y; + case GT: + return x > y; + case GE: + return x >= y; + case AE: + return UnsignedMath.aboveOrEqual(x, y); + case BE: + return UnsignedMath.belowOrEqual(x, y); + case AT: + return UnsignedMath.aboveThan(x, y); + case BT: + return UnsignedMath.belowThan(x, y); + default: + throw new GraalInternalError("expected condition: %s", this); + } + } + case Long: { + long x = lt.asLong(); + long y = rt.asLong(); + switch (this) { + case EQ: + return x == y; + case NE: + return x != y; + case LT: + return x < y; + case LE: + return x <= y; + case GT: + return x > y; + case GE: + return x >= y; + case AE: + return UnsignedMath.aboveOrEqual(x, y); + case BE: + return UnsignedMath.belowOrEqual(x, y); + case AT: + return UnsignedMath.aboveThan(x, y); + case BT: + return UnsignedMath.belowThan(x, y); + default: + throw new GraalInternalError("expected condition: %s", this); + } + } + case Object: { + Boolean equal = constantReflection.constantEquals(lt, rt); + if (equal != null) { + switch (this) { + case EQ: + return equal.booleanValue(); + case NE: + return !equal.booleanValue(); + default: + throw new GraalInternalError("expected condition: %s", this); + } + } + } + case Float: { + float x = lt.asFloat(); + float y = rt.asFloat(); + if (Float.isNaN(x) || Float.isNaN(y)) { + return unorderedIsTrue; + } + switch (this) { + case EQ: + return x == y; + case NE: + return x != y; + case LT: + return x < y; + case LE: + return x <= y; + case GT: + return x > y; + case GE: + return x >= y; + default: + throw new GraalInternalError("expected condition: %s", this); + } + } + case Double: { + double x = lt.asDouble(); + double y = rt.asDouble(); + if (Double.isNaN(x) || Double.isNaN(y)) { + return unorderedIsTrue; + } + switch (this) { + case EQ: + return x == y; + case NE: + return x != y; + case LT: + return x < y; + case LE: + return x <= y; + case GT: + return x > y; + case GE: + return x >= y; + default: + throw new GraalInternalError("expected condition: %s", this); + } + } + default: + throw new GraalInternalError("expected value kind %s while folding condition: %s", lt.getKind(), this); + } + } + + public Condition join(Condition other) { + if (other == this) { + return this; + } + switch (this) { + case EQ: + if (other == LE || other == GE || other == BE || other == AE) { + return EQ; + } else { + return null; + } + case NE: + if (other == LT || other == GT || other == BT || other == AT) { + return other; + } else if (other == LE) { + return LT; + } else if (other == GE) { + return GT; + } else if (other == BE) { + return BT; + } else if (other == AE) { + return AT; + } else { + return null; + } + case LE: + if (other == GE || other == EQ) { + return EQ; + } else if (other == NE || other == LT) { + return LT; + } else { + return null; + } + case LT: + if (other == NE || other == LE) { + return LT; + } else { + return null; + } + case GE: + if (other == LE || other == EQ) { + return EQ; + } else if (other == NE || other == GT) { + return GT; + } else { + return null; + } + case GT: + if (other == NE || other == GE) { + return GT; + } else { + return null; + } + case BE: + if (other == AE || other == EQ) { + return EQ; + } else if (other == NE || other == BT) { + return BT; + } else { + return null; + } + case BT: + if (other == NE || other == BE) { + return BT; + } else { + return null; + } + case AE: + if (other == BE || other == EQ) { + return EQ; + } else if (other == NE || other == AT) { + return AT; + } else { + return null; + } + case AT: + if (other == NE || other == AE) { + return AT; + } else { + return null; + } + } + throw new IllegalArgumentException(this.toString()); + } + + public Condition meet(Condition other) { + if (other == this) { + return this; + } + switch (this) { + case EQ: + if (other == LE || other == GE || other == BE || other == AE) { + return other; + } else if (other == LT) { + return LE; + } else if (other == GT) { + return GE; + } else if (other == BT) { + return BE; + } else if (other == AT) { + return AE; + } else { + return null; + } + case NE: + if (other == LT || other == GT || other == BT || other == AT) { + return NE; + } else { + return null; + } + case LE: + if (other == EQ || other == LT) { + return LE; + } else { + return null; + } + case LT: + if (other == EQ || other == LE) { + return LE; + } else if (other == NE || other == GT) { + return NE; + } else { + return null; + } + case GE: + if (other == EQ || other == GT) { + return GE; + } else { + return null; + } + case GT: + if (other == EQ || other == GE) { + return GE; + } else if (other == NE || other == LT) { + return NE; + } else { + return null; + } + case BE: + if (other == EQ || other == BT) { + return BE; + } else { + return null; + } + case BT: + if (other == EQ || other == BE) { + return BE; + } else if (other == NE || other == AT) { + return NE; + } else { + return null; + } + case AE: + if (other == EQ || other == AT) { + return AE; + } else { + return null; + } + case AT: + if (other == EQ || other == AE) { + return AE; + } else if (other == NE || other == BT) { + return NE; + } else { + return null; + } + } + throw new IllegalArgumentException(this.toString()); + } +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/calc/FloatConvert.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/calc/FloatConvert.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2014, 2014, 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.common.calc; + +import com.oracle.graal.compiler.common.*; + +public enum FloatConvert { + F2I, + D2I, + F2L, + D2L, + I2F, + L2F, + D2F, + I2D, + L2D, + F2D; + + public FloatConvert reverse() { + switch (this) { + case D2F: + return F2D; + case D2I: + return I2D; + case D2L: + return L2D; + case F2D: + return D2F; + case F2I: + return I2F; + case F2L: + return L2F; + case I2D: + return D2I; + case I2F: + return F2I; + case L2D: + return D2L; + case L2F: + return F2L; + default: + throw GraalInternalError.shouldNotReachHere(); + } + } +} \ No newline at end of file diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/cfg/AbstractBlock.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/cfg/AbstractBlock.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2014, 2014, 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.common.cfg; + +import java.util.*; + +public interface AbstractBlock> { + + int getId(); + + Loop getLoop(); + + int getLoopDepth(); + + boolean isLoopHeader(); + + boolean isLoopEnd(); + + boolean isExceptionEntry(); + + List getPredecessors(); + + int getPredecessorCount(); + + List getSuccessors(); + + int getSuccessorCount(); + + int getLinearScanNumber(); + + void setLinearScanNumber(int linearScanNumber); + + boolean isAligned(); + + void setAlign(boolean align); + + T getDominator(); +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/cfg/AbstractBlockBase.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/cfg/AbstractBlockBase.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2009, 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.compiler.common.cfg; + +import java.util.*; + +public abstract class AbstractBlockBase> implements AbstractBlock { + + protected int id; + + protected List predecessors; + protected List successors; + + private T dominator; + + private boolean align; + private int linearScanNumber; + + protected AbstractBlockBase() { + this.id = AbstractControlFlowGraph.BLOCK_ID_INITIAL; + this.linearScanNumber = -1; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public List getPredecessors() { + return predecessors; + } + + public void setPredecessors(List predecessors) { + this.predecessors = predecessors; + } + + public List getSuccessors() { + return successors; + } + + public void setSuccessors(List successors) { + this.successors = successors; + } + + public T getDominator() { + return dominator; + } + + public void setDominator(T dominator) { + this.dominator = dominator; + } + + @Override + public String toString() { + return "B" + id; + } + + public int getPredecessorCount() { + return getPredecessors().size(); + } + + public int getSuccessorCount() { + return getSuccessors().size(); + } + + public int getLinearScanNumber() { + return linearScanNumber; + } + + public void setLinearScanNumber(int linearScanNumber) { + this.linearScanNumber = linearScanNumber; + } + + public boolean isAligned() { + return align; + } + + public void setAlign(boolean align) { + this.align = align; + } +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/cfg/AbstractControlFlowGraph.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/cfg/AbstractControlFlowGraph.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2014, 2014, 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.common.cfg; + +import java.util.*; + +public interface AbstractControlFlowGraph> { + + static final int BLOCK_ID_INITIAL = -1; + static final int BLOCK_ID_VISITED = -2; + + T[] getBlocks(); + + Collection> getLoops(); + + T getStartBlock(); +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/cfg/BlockMap.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/cfg/BlockMap.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.compiler.common.cfg; + +public class BlockMap { + + private final T[] data; + + @SuppressWarnings("unchecked") + public BlockMap(AbstractControlFlowGraph cfg) { + data = (T[]) new Object[cfg.getBlocks().length]; + } + + public T get(AbstractBlock block) { + return data[block.getId()]; + } + + public void put(AbstractBlock block, T value) { + data[block.getId()] = value; + } +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/cfg/Loop.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/cfg/Loop.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.oracle.graal.compiler.common.cfg; + +import java.util.*; + +public abstract class Loop> { + + public final Loop parent; + public final List> children; + + public final int depth; + public final int index; + public final T header; + public final List blocks; + public final List exits; + + protected Loop(Loop parent, int index, T header) { + this.parent = parent; + if (parent != null) { + this.depth = parent.depth + 1; + parent.children.add(this); + } else { + this.depth = 1; + } + this.index = index; + this.header = header; + this.blocks = new ArrayList<>(); + this.children = new ArrayList<>(); + this.exits = new ArrayList<>(); + } + + public abstract long numBackedges(); + + @Override + public String toString() { + return "loop " + index + " depth " + depth + (parent != null ? " outer " + parent.index : ""); + } +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/spi/CodeGenProviders.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/spi/CodeGenProviders.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2013, 2014, 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.common.spi; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; + +/** + * A set of providers which are required for LIR and/or code generation. Some may not be present + * (i.e., null). + */ +public interface CodeGenProviders { + + MetaAccessProvider getMetaAccess(); + + CodeCacheProvider getCodeCache(); + + ForeignCallsProvider getForeignCalls(); + + ConstantReflectionProvider getConstantReflection(); + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/spi/PlatformKindTool.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/spi/PlatformKindTool.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2014, 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.common.spi; + +import com.oracle.graal.api.meta.*; + +/** + * This interface can be used to access platform and VM specific kinds. + */ +public interface PlatformKindTool { + + PlatformKind getIntegerKind(int bits); + + PlatformKind getFloatingKind(int bits); + + PlatformKind getObjectKind(); +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/FloatStamp.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/FloatStamp.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,234 @@ +/* + * Copyright (c) 2012, 2014, 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.common.type; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.common.*; +import com.oracle.graal.compiler.common.spi.*; + +public class FloatStamp extends PrimitiveStamp { + + private final double lowerBound; + private final double upperBound; + private final boolean nonNaN; + + protected FloatStamp(int bits) { + this(bits, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, false); + } + + public FloatStamp(int bits, double lowerBound, double upperBound, boolean nonNaN) { + super(bits); + this.lowerBound = lowerBound; + this.upperBound = upperBound; + this.nonNaN = nonNaN; + } + + @Override + public Stamp unrestricted() { + return new FloatStamp(getBits()); + } + + @Override + public Stamp illegal() { + return new FloatStamp(getBits(), Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY, true); + } + + @Override + public boolean isLegal() { + return lowerBound <= upperBound || !nonNaN; + } + + @Override + public Kind getStackKind() { + if (getBits() > 32) { + return Kind.Double; + } else { + return Kind.Float; + } + } + + @Override + public PlatformKind getPlatformKind(PlatformKindTool tool) { + return tool.getFloatingKind(getBits()); + } + + @Override + public ResolvedJavaType javaType(MetaAccessProvider metaAccess) { + switch (getBits()) { + case 32: + return metaAccess.lookupJavaType(Float.TYPE); + case 64: + return metaAccess.lookupJavaType(Double.TYPE); + default: + throw GraalInternalError.shouldNotReachHere(); + } + } + + /** + * The (inclusive) lower bound on the value described by this stamp. + */ + public double lowerBound() { + return lowerBound; + } + + /** + * The (inclusive) upper bound on the value described by this stamp. + */ + public double upperBound() { + return upperBound; + } + + public boolean isNonNaN() { + return nonNaN; + } + + public boolean isUnrestricted() { + return lowerBound == Double.NEGATIVE_INFINITY && upperBound == Double.POSITIVE_INFINITY && !nonNaN; + } + + public boolean contains(double value) { + if (Double.isNaN(value)) { + return !nonNaN; + } else { + return value >= lowerBound && value <= upperBound; + } + } + + @Override + public String toString() { + StringBuilder str = new StringBuilder(); + str.append('f'); + str.append(getBits()); + str.append(nonNaN ? "!" : ""); + if (lowerBound == upperBound) { + str.append(" [").append(lowerBound).append(']'); + } else if (lowerBound != Double.NEGATIVE_INFINITY || upperBound != Double.POSITIVE_INFINITY) { + str.append(" [").append(lowerBound).append(" - ").append(upperBound).append(']'); + } + return str.toString(); + } + + @Override + public Stamp meet(Stamp otherStamp) { + if (otherStamp == this) { + return this; + } + if (!(otherStamp instanceof FloatStamp)) { + return StampFactory.illegal(Kind.Illegal); + } + FloatStamp other = (FloatStamp) otherStamp; + assert getBits() == other.getBits(); + double meetUpperBound = Math.max(upperBound, other.upperBound); + double meetLowerBound = Math.min(lowerBound, other.lowerBound); + boolean meetNonNaN = nonNaN && other.nonNaN; + if (meetLowerBound == lowerBound && meetUpperBound == upperBound && meetNonNaN == nonNaN) { + return this; + } else if (meetLowerBound == other.lowerBound && meetUpperBound == other.upperBound && meetNonNaN == other.nonNaN) { + return other; + } else { + return new FloatStamp(getBits(), meetLowerBound, meetUpperBound, meetNonNaN); + } + } + + @Override + public Stamp join(Stamp otherStamp) { + if (otherStamp == this) { + return this; + } + if (!(otherStamp instanceof FloatStamp)) { + return StampFactory.illegal(Kind.Illegal); + } + FloatStamp other = (FloatStamp) otherStamp; + assert getBits() == other.getBits(); + double joinUpperBound = Math.min(upperBound, other.upperBound); + double joinLowerBound = Math.max(lowerBound, other.lowerBound); + boolean joinNonNaN = nonNaN || other.nonNaN; + if (joinLowerBound == lowerBound && joinUpperBound == upperBound && joinNonNaN == nonNaN) { + return this; + } else if (joinLowerBound == other.lowerBound && joinUpperBound == other.upperBound && joinNonNaN == other.nonNaN) { + return other; + } else { + return new FloatStamp(getBits(), joinLowerBound, joinUpperBound, joinNonNaN); + } + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + long temp; + result = prime * result + super.hashCode(); + temp = Double.doubleToLongBits(lowerBound); + result = prime * result + (int) (temp ^ (temp >>> 32)); + result = prime * result + (nonNaN ? 1231 : 1237); + temp = Double.doubleToLongBits(upperBound); + result = prime * result + (int) (temp ^ (temp >>> 32)); + return result; + } + + @Override + public boolean isCompatible(Stamp stamp) { + if (this == stamp) { + return true; + } + if (stamp instanceof FloatStamp) { + FloatStamp other = (FloatStamp) stamp; + return getBits() == other.getBits(); + } + return false; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null || getClass() != obj.getClass() || !super.equals(obj)) { + return false; + } + FloatStamp other = (FloatStamp) obj; + if (Double.doubleToLongBits(lowerBound) != Double.doubleToLongBits(other.lowerBound)) { + return false; + } + if (Double.doubleToLongBits(upperBound) != Double.doubleToLongBits(other.upperBound)) { + return false; + } + if (nonNaN != other.nonNaN) { + return false; + } + return true; + } + + @Override + public Constant asConstant() { + if (nonNaN && lowerBound == upperBound) { + switch (getBits()) { + case 32: + return Constant.forFloat((float) lowerBound); + case 64: + return Constant.forDouble(lowerBound); + } + } + return null; + } +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/IllegalStamp.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/IllegalStamp.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2012, 2014, 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.common.type; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.common.*; +import com.oracle.graal.compiler.common.spi.*; + +/** + * This stamp represents the illegal type. Values with this type can not exist at run time. + */ +public final class IllegalStamp extends Stamp { + + private IllegalStamp() { + } + + @Override + public Kind getStackKind() { + return Kind.Illegal; + } + + @Override + public PlatformKind getPlatformKind(PlatformKindTool tool) { + throw GraalInternalError.shouldNotReachHere("illegal stamp should not reach backend"); + } + + @Override + public Stamp unrestricted() { + return this; + } + + @Override + public Stamp illegal() { + return this; + } + + @Override + public ResolvedJavaType javaType(MetaAccessProvider metaAccess) { + throw GraalInternalError.shouldNotReachHere("illegal stamp has no Java type"); + } + + @Override + public Stamp meet(Stamp other) { + return this; + } + + @Override + public Stamp join(Stamp other) { + return this; + } + + @Override + public boolean isCompatible(Stamp stamp) { + return false; + } + + @Override + public String toString() { + return "ILLEGAL"; + } + + @Override + public boolean isLegal() { + return false; + } + + private static IllegalStamp instance = new IllegalStamp(); + + static IllegalStamp getInstance() { + return instance; + } +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/IntegerStamp.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/IntegerStamp.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,318 @@ +/* + * Copyright (c) 2012, 2014, 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.common.type; + +import java.util.*; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.common.*; +import com.oracle.graal.compiler.common.spi.*; + +/** + * Describes the possible values of a {@link ValueNode} that produces an int or long result. + * + * The description consists of (inclusive) lower and upper bounds and up (may be set) and down + * (always set) bit-masks. + */ +@SuppressWarnings("javadoc") +public class IntegerStamp extends PrimitiveStamp { + + private final long lowerBound; + private final long upperBound; + private final long downMask; + private final long upMask; + + public IntegerStamp(int bits, long lowerBound, long upperBound, long downMask, long upMask) { + super(bits); + this.lowerBound = lowerBound; + this.upperBound = upperBound; + this.downMask = downMask; + this.upMask = upMask; + assert lowerBound >= defaultMinValue(bits) : this; + assert upperBound <= defaultMaxValue(bits) : this; + assert (downMask & defaultMask(bits)) == downMask : this; + assert (upMask & defaultMask(bits)) == upMask : this; + } + + @Override + public Stamp unrestricted() { + return new IntegerStamp(getBits(), defaultMinValue(getBits()), defaultMaxValue(getBits()), 0, defaultMask(getBits())); + } + + @Override + public Stamp illegal() { + return new IntegerStamp(getBits(), defaultMaxValue(getBits()), defaultMinValue(getBits()), defaultMask(getBits()), 0); + } + + @Override + public boolean isLegal() { + return lowerBound <= upperBound; + } + + @Override + public Kind getStackKind() { + if (getBits() > 32) { + return Kind.Long; + } else { + return Kind.Int; + } + } + + @Override + public PlatformKind getPlatformKind(PlatformKindTool tool) { + return tool.getIntegerKind(getBits()); + } + + @Override + public ResolvedJavaType javaType(MetaAccessProvider metaAccess) { + switch (getBits()) { + case 1: + return metaAccess.lookupJavaType(Boolean.TYPE); + case 8: + return metaAccess.lookupJavaType(Byte.TYPE); + case 16: + return metaAccess.lookupJavaType(Short.TYPE); + case 32: + return metaAccess.lookupJavaType(Integer.TYPE); + case 64: + return metaAccess.lookupJavaType(Long.TYPE); + default: + throw GraalInternalError.shouldNotReachHere(); + } + } + + /** + * The signed inclusive lower bound on the value described by this stamp. + */ + public long lowerBound() { + return lowerBound; + } + + /** + * The signed inclusive upper bound on the value described by this stamp. + */ + public long upperBound() { + return upperBound; + } + + /** + * This bit-mask describes the bits that are always set in the value described by this stamp. + */ + public long downMask() { + return downMask; + } + + /** + * This bit-mask describes the bits that can be set in the value described by this stamp. + */ + public long upMask() { + return upMask; + } + + public boolean isUnrestricted() { + return lowerBound == defaultMinValue(getBits()) && upperBound == defaultMaxValue(getBits()) && downMask == 0 && upMask == defaultMask(getBits()); + } + + public boolean contains(long value) { + return value >= lowerBound && value <= upperBound && (value & downMask) == downMask && (value & upMask) == (value & defaultMask(getBits())); + } + + public boolean isPositive() { + return lowerBound() >= 0; + } + + public boolean isNegative() { + return upperBound() <= 0; + } + + public boolean isStrictlyPositive() { + return lowerBound() > 0; + } + + public boolean isStrictlyNegative() { + return upperBound() < 0; + } + + public boolean canBePositive() { + return upperBound() > 0; + } + + public boolean canBeNegative() { + return lowerBound() < 0; + } + + @Override + public String toString() { + StringBuilder str = new StringBuilder(); + str.append('i'); + str.append(getBits()); + if (lowerBound == upperBound) { + str.append(" [").append(lowerBound).append(']'); + } else if (lowerBound != defaultMinValue(getBits()) || upperBound != defaultMaxValue(getBits())) { + str.append(" [").append(lowerBound).append(" - ").append(upperBound).append(']'); + } + if (downMask != 0) { + str.append(" \u21ca"); + new Formatter(str).format("%016x", downMask); + } + if (upMask != defaultMask(getBits())) { + str.append(" \u21c8"); + new Formatter(str).format("%016x", upMask); + } + return str.toString(); + } + + private Stamp createStamp(IntegerStamp other, long newUpperBound, long newLowerBound, long newDownMask, long newUpMask) { + assert getBits() == other.getBits(); + if (newLowerBound > newUpperBound || (newDownMask & (~newUpMask)) != 0) { + return illegal(); + } else if (newLowerBound == lowerBound && newUpperBound == upperBound && newDownMask == downMask && newUpMask == upMask) { + return this; + } else if (newLowerBound == other.lowerBound && newUpperBound == other.upperBound && newDownMask == other.downMask && newUpMask == other.upMask) { + return other; + } else { + return new IntegerStamp(getBits(), newLowerBound, newUpperBound, newDownMask, newUpMask); + } + } + + @Override + public Stamp meet(Stamp otherStamp) { + if (otherStamp == this) { + return this; + } + if (!(otherStamp instanceof IntegerStamp)) { + return StampFactory.illegal(Kind.Illegal); + } + IntegerStamp other = (IntegerStamp) otherStamp; + return createStamp(other, Math.max(upperBound, other.upperBound), Math.min(lowerBound, other.lowerBound), downMask & other.downMask, upMask | other.upMask); + } + + @Override + public Stamp join(Stamp otherStamp) { + if (otherStamp == this) { + return this; + } + if (!(otherStamp instanceof IntegerStamp)) { + return StampFactory.illegal(Kind.Illegal); + } + IntegerStamp other = (IntegerStamp) otherStamp; + long newDownMask = downMask | other.downMask; + long newLowerBound = Math.max(lowerBound, other.lowerBound) | newDownMask; + return createStamp(other, Math.min(upperBound, other.upperBound), newLowerBound, newDownMask, upMask & other.upMask); + } + + @Override + public boolean isCompatible(Stamp stamp) { + if (this == stamp) { + return true; + } + if (stamp instanceof IntegerStamp) { + IntegerStamp other = (IntegerStamp) stamp; + return getBits() == other.getBits(); + } + return false; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + super.hashCode(); + result = prime * result + (int) (lowerBound ^ (lowerBound >>> 32)); + result = prime * result + (int) (upperBound ^ (upperBound >>> 32)); + result = prime * result + (int) (downMask ^ (downMask >>> 32)); + result = prime * result + (int) (upMask ^ (upMask >>> 32)); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null || getClass() != obj.getClass() || !super.equals(obj)) { + return false; + } + IntegerStamp other = (IntegerStamp) obj; + if (lowerBound != other.lowerBound || upperBound != other.upperBound || downMask != other.downMask || upMask != other.upMask) { + return false; + } + return true; + } + + public static long defaultMask(int bits) { + assert 0 <= bits && bits <= 64; + if (bits == 64) { + return 0xffffffffffffffffL; + } else { + return (1L << bits) - 1; + } + } + + public static long defaultMinValue(int bits) { + return -1L << (bits - 1); + } + + public static long defaultMaxValue(int bits) { + return defaultMask(bits - 1); + } + + public static long upMaskFor(int bits, long lowerBound, long upperBound) { + long mask = lowerBound | upperBound; + if (mask == 0) { + return 0; + } else { + return ((-1L) >>> Long.numberOfLeadingZeros(mask)) & defaultMask(bits); + } + } + + /** + * Checks if the 2 stamps represent values of the same sign. Returns true if the two stamps are + * both positive of null or if they are both strictly negative + * + * @return true if the two stamps are both positive of null or if they are both strictly + * negative + */ + public static boolean sameSign(IntegerStamp s1, IntegerStamp s2) { + return s1.isPositive() && s2.isPositive() || s1.isStrictlyNegative() && s2.isStrictlyNegative(); + } + + @Override + public Constant asConstant() { + if (lowerBound == upperBound) { + switch (getBits()) { + case 1: + return Constant.forBoolean(lowerBound != 0); + case 8: + return Constant.forByte((byte) lowerBound); + case 16: + return Constant.forShort((short) lowerBound); + case 32: + return Constant.forInt((int) lowerBound); + case 64: + return Constant.forLong(lowerBound); + } + } + return null; + } +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/ObjectStamp.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/ObjectStamp.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,297 @@ +/* + * Copyright (c) 2012, 2014, 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.common.type; + +import java.util.*; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.common.spi.*; + +public class ObjectStamp extends Stamp { + + private final ResolvedJavaType type; + private final boolean exactType; + private final boolean nonNull; + private final boolean alwaysNull; + + public ObjectStamp(ResolvedJavaType type, boolean exactType, boolean nonNull, boolean alwaysNull) { + this.type = type; + this.exactType = exactType; + this.nonNull = nonNull; + this.alwaysNull = alwaysNull; + } + + @Override + public Stamp unrestricted() { + return StampFactory.object(); + } + + @Override + public Stamp illegal() { + return new ObjectStamp(null, true, true, false); + } + + @Override + public boolean isLegal() { + return !exactType || (type != null && (isConcreteType(type))); + } + + @Override + public Kind getStackKind() { + return Kind.Object; + } + + @Override + public PlatformKind getPlatformKind(PlatformKindTool tool) { + return tool.getObjectKind(); + } + + @Override + public ResolvedJavaType javaType(MetaAccessProvider metaAccess) { + if (type != null) { + return type; + } + return metaAccess.lookupJavaType(Object.class); + } + + public boolean nonNull() { + return nonNull; + } + + public boolean alwaysNull() { + return alwaysNull; + } + + public ResolvedJavaType type() { + return type; + } + + public boolean isExactType() { + return exactType; + } + + @Override + public String toString() { + StringBuilder str = new StringBuilder(); + str.append('a'); + str.append(nonNull ? "!" : "").append(exactType ? "#" : "").append(' ').append(type == null ? "-" : type.getName()).append(alwaysNull ? " NULL" : ""); + return str.toString(); + } + + @Override + public Stamp meet(Stamp otherStamp) { + if (this == otherStamp) { + return this; + } + if (!(otherStamp instanceof ObjectStamp)) { + return StampFactory.illegal(Kind.Illegal); + } + ObjectStamp other = (ObjectStamp) otherStamp; + ResolvedJavaType meetType; + boolean meetExactType; + boolean meetNonNull; + boolean meetAlwaysNull; + if (other.alwaysNull) { + meetType = type(); + meetExactType = exactType; + meetNonNull = false; + meetAlwaysNull = alwaysNull; + } else if (alwaysNull) { + meetType = other.type(); + meetExactType = other.exactType; + meetNonNull = false; + meetAlwaysNull = other.alwaysNull; + } else { + meetType = meetTypes(type(), other.type()); + meetExactType = exactType && other.exactType; + if (meetExactType && type != null && other.type != null) { + // meeting two valid exact types may result in a non-exact type + meetExactType = Objects.equals(meetType, type) && Objects.equals(meetType, other.type); + } + meetNonNull = nonNull && other.nonNull; + meetAlwaysNull = false; + } + + if (Objects.equals(meetType, type) && meetExactType == exactType && meetNonNull == nonNull && meetAlwaysNull == alwaysNull) { + return this; + } else if (Objects.equals(meetType, other.type) && meetExactType == other.exactType && meetNonNull == other.nonNull && meetAlwaysNull == other.alwaysNull) { + return other; + } else { + return new ObjectStamp(meetType, meetExactType, meetNonNull, meetAlwaysNull); + } + } + + @Override + public Stamp join(Stamp otherStamp) { + return join0(otherStamp, false); + } + + @Override + public boolean isCompatible(Stamp other) { + if (this == other) { + return true; + } + if (other instanceof ObjectStamp) { + return true; + } + return false; + } + + /** + * Returns the stamp representing the type of this stamp after a cast to the type represented by + * the {@code to} stamp. While this is very similar to a {@link #join} operation, in the case + * where both types are not obviously related, the cast operation will prefer the type of the + * {@code to} stamp. This is necessary as long as ObjectStamps are not able to accurately + * represent intersection types. + * + * For example when joining the {@link RandomAccess} type with the {@link AbstractList} type, + * without intersection types, this would result in the most generic type ({@link Object} ). For + * this reason, in some cases a {@code castTo} operation is preferable in order to keep at least + * the {@link AbstractList} type. + * + * @param to the stamp this stamp should be casted to + * @return This stamp casted to the {@code to} stamp + */ + public Stamp castTo(ObjectStamp to) { + return join0(to, true); + } + + private Stamp join0(Stamp otherStamp, boolean castToOther) { + if (this == otherStamp) { + return this; + } + if (!(otherStamp instanceof ObjectStamp)) { + return StampFactory.illegal(Kind.Illegal); + } + ObjectStamp other = (ObjectStamp) otherStamp; + if (!isLegal()) { + return this; + } else if (!other.isLegal()) { + return other; + } + + ResolvedJavaType joinType; + boolean joinAlwaysNull = alwaysNull || other.alwaysNull; + boolean joinNonNull = nonNull || other.nonNull; + boolean joinExactType = exactType || other.exactType; + if (Objects.equals(type, other.type)) { + joinType = type; + } else if (type == null && other.type == null) { + joinType = null; + } else if (type == null) { + joinType = other.type; + } else if (other.type == null) { + joinType = type; + } else { + // both types are != null and different + if (type.isAssignableFrom(other.type)) { + joinType = other.type; + if (exactType) { + joinAlwaysNull = true; + } + } else if (other.type.isAssignableFrom(type)) { + joinType = type; + if (other.exactType) { + joinAlwaysNull = true; + } + } else { + if (castToOther) { + joinType = other.type; + joinExactType = other.exactType; + } else { + joinType = null; + } + if (joinExactType || (!type.isInterface() && !other.type.isInterface())) { + joinAlwaysNull = true; + } + } + } + if (joinAlwaysNull) { + joinType = null; + joinExactType = false; + } + if (joinExactType && joinType == null) { + return StampFactory.illegal(Kind.Object); + } + if (joinAlwaysNull && joinNonNull) { + return StampFactory.illegal(Kind.Object); + } else if (joinExactType && !isConcreteType(joinType)) { + return StampFactory.illegal(Kind.Object); + } + if (Objects.equals(joinType, type) && joinExactType == exactType && joinNonNull == nonNull && joinAlwaysNull == alwaysNull) { + return this; + } else if (Objects.equals(joinType, other.type) && joinExactType == other.exactType && joinNonNull == other.nonNull && joinAlwaysNull == other.alwaysNull) { + return other; + } else { + return new ObjectStamp(joinType, joinExactType, joinNonNull, joinAlwaysNull); + } + } + + public static boolean isConcreteType(ResolvedJavaType type) { + return !(type.isAbstract() && !type.isArray()); + } + + private static ResolvedJavaType meetTypes(ResolvedJavaType a, ResolvedJavaType b) { + if (Objects.equals(a, b)) { + return a; + } else if (a == null || b == null) { + return null; + } else { + return a.findLeastCommonAncestor(b); + } + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + (exactType ? 1231 : 1237); + result = prime * result + (nonNull ? 1231 : 1237); + result = prime * result + (alwaysNull ? 1231 : 1237); + result = prime * result + ((type == null) ? 0 : type.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null || getClass() != obj.getClass()) { + return false; + } + ObjectStamp other = (ObjectStamp) obj; + if (exactType != other.exactType || nonNull != other.nonNull || alwaysNull != other.alwaysNull) { + return false; + } + if (type == null) { + if (other.type != null) { + return false; + } + } else if (!type.equals(other.type)) { + return false; + } + return true; + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/PrimitiveStamp.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/PrimitiveStamp.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2014, 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.common.type; + +/** + * Describes the possible values of a {@link ValueNode} that produces a primitive value as result. + */ +@SuppressWarnings("javadoc") +public abstract class PrimitiveStamp extends Stamp { + + private final int bits; + + protected PrimitiveStamp(int bits) { + this.bits = bits; + } + + /** + * The width in bits of the value described by this stamp. + */ + public int getBits() { + return bits; + } + + public static int getBits(Stamp stamp) { + if (stamp instanceof PrimitiveStamp) { + return ((PrimitiveStamp) stamp).getBits(); + } else { + return 0; + } + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + bits; + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof PrimitiveStamp) { + PrimitiveStamp other = (PrimitiveStamp) obj; + return bits == other.bits; + } + return false; + } +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/Stamp.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/Stamp.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2011, 2014, 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.common.type; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.common.spi.*; + +/** + * A stamp is the basis for a type system over the nodes in a graph. + */ +public abstract class Stamp { + + protected Stamp() { + } + + /** + * Returns the type of the stamp, guaranteed to be non-null. In some cases, this requires the + * lookup of class meta data, therefore the {@link MetaAccessProvider} is mandatory. + */ + public abstract ResolvedJavaType javaType(MetaAccessProvider metaAccess); + + public boolean alwaysDistinct(Stamp other) { + return !join(other).isLegal(); + } + + /** + * Gets a Java {@link Kind} that can be used to store a value of this stamp on the Java bytecode + * stack. Returns {@link Kind#Illegal} if a value of this stamp can not be stored on the + * bytecode stack. + */ + public abstract Kind getStackKind(); + + /** + * Gets a platform dependent {@link PlatformKind} that can be used to store a value of this + * stamp. + */ + public abstract PlatformKind getPlatformKind(PlatformKindTool tool); + + /** + * Returns the union of this stamp and the given stamp. Typically used to create stamps for + * {@link ValuePhiNode}s. + * + * @param other The stamp that will enlarge this stamp. + * @return The union of this stamp and the given stamp. + */ + @SuppressWarnings("javadoc") + public abstract Stamp meet(Stamp other); + + /** + * Returns the intersection of this stamp and the given stamp. + * + * @param other The stamp that will tighten this stamp. + * @return The intersection of this stamp and the given stamp. + */ + public abstract Stamp join(Stamp other); + + /** + * Returns a stamp of the same kind, but allowing the full value range of the kind. + * + * {@link #unrestricted()} is the neutral element of the {@link #join(Stamp)} operation. + */ + public abstract Stamp unrestricted(); + + /** + * Returns a stamp of the same kind, but with no allowed values. + * + * {@link #illegal()} is the neutral element of the {@link #meet(Stamp)} operation. + */ + public abstract Stamp illegal(); + + /** + * Test whether two stamps have the same base type. + */ + public abstract boolean isCompatible(Stamp other); + + /** + * Test whether this stamp has legal values. + */ + public abstract boolean isLegal(); + + /** + * If this stamp represents a single value, the methods returns this single value. It returns + * null otherwise. + * + * @return the constant corresponding to the single value of this stamp and null if this stamp + * can represent less or more than one value. + */ + public Constant asConstant() { + return null; + } +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/StampFactory.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/StampFactory.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,254 @@ +/* + * 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.common.type; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.common.*; + +public class StampFactory { + + // JaCoCo Exclude + + private static final Stamp[] stampCache = new Stamp[Kind.values().length]; + private static final Stamp[] illegalStampCache = new Stamp[Kind.values().length]; + private static final Stamp objectStamp = new ObjectStamp(null, false, false, false); + private static final Stamp objectNonNullStamp = new ObjectStamp(null, false, true, false); + private static final Stamp objectAlwaysNullStamp = new ObjectStamp(null, false, false, true); + private static final Stamp nodeIntrinsicStamp = new ObjectStamp(null, false, false, false); + private static final Stamp positiveInt = forInteger(Kind.Int, 0, Integer.MAX_VALUE, 0, Integer.MAX_VALUE); + + private static void setCache(Kind kind, Stamp stamp) { + stampCache[kind.ordinal()] = stamp; + } + + private static void setIntCache(Kind kind) { + int bits = kind.getStackKind().getBitCount(); + long mask; + if (kind.isUnsigned()) { + mask = IntegerStamp.defaultMask(kind.getBitCount()); + } else { + mask = IntegerStamp.defaultMask(bits); + } + setCache(kind, new IntegerStamp(bits, kind.getMinValue(), kind.getMaxValue(), 0, mask)); + } + + private static void setFloatCache(Kind kind) { + setCache(kind, new FloatStamp(kind.getBitCount())); + } + + static { + setIntCache(Kind.Boolean); + setIntCache(Kind.Byte); + setIntCache(Kind.Short); + setIntCache(Kind.Char); + setIntCache(Kind.Int); + setIntCache(Kind.Long); + + setFloatCache(Kind.Float); + setFloatCache(Kind.Double); + + setCache(Kind.Object, objectStamp); + setCache(Kind.Void, VoidStamp.getInstance()); + + for (Kind k : Kind.values()) { + if (stampCache[k.ordinal()] != null) { + illegalStampCache[k.ordinal()] = stampCache[k.ordinal()].illegal(); + } else { + illegalStampCache[k.ordinal()] = IllegalStamp.getInstance(); + } + } + } + + /** + * Return a stamp for a Java kind, as it would be represented on the bytecode stack. + */ + public static Stamp forKind(Kind kind) { + assert stampCache[kind.ordinal()] != null : "unexpected forKind(" + kind + ")"; + return stampCache[kind.ordinal()]; + } + + /** + * Return the stamp for the {@code void} type. This will return a singleton instance than can be + * compared using {@code ==}. + */ + public static Stamp forVoid() { + return VoidStamp.getInstance(); + } + + /** + * A stamp used only in the graph of intrinsics, e.g., snippets. It is then replaced by an + * actual stamp when the intrinsic is used, i.e., when the snippet template is instantiated. + */ + public static Stamp forNodeIntrinsic() { + return nodeIntrinsicStamp; + } + + public static Stamp intValue() { + return forKind(Kind.Int); + } + + public static Stamp positiveInt() { + return positiveInt; + } + + public static Stamp illegal() { + return illegal(Kind.Illegal); + } + + public static Stamp illegal(Kind kind) { + return illegalStampCache[kind.ordinal()]; + } + + public static IntegerStamp forInteger(Kind kind, long lowerBound, long upperBound, long downMask, long upMask) { + return new IntegerStamp(kind.getBitCount(), lowerBound, upperBound, downMask, upMask); + } + + public static IntegerStamp forInteger(Kind kind, long lowerBound, long upperBound) { + return forInteger(kind.getBitCount(), lowerBound, upperBound); + } + + public static IntegerStamp forInteger(int bits) { + return new IntegerStamp(bits, IntegerStamp.defaultMinValue(bits), IntegerStamp.defaultMaxValue(bits), 0, IntegerStamp.defaultMask(bits)); + } + + public static IntegerStamp forInteger(int bits, long lowerBound, long upperBound) { + long defaultMask = IntegerStamp.defaultMask(bits); + if (lowerBound == upperBound) { + return new IntegerStamp(bits, lowerBound, lowerBound, lowerBound & defaultMask, lowerBound & defaultMask); + } + final long downMask; + final long upMask; + if (lowerBound >= 0) { + int upperBoundLeadingZeros = Long.numberOfLeadingZeros(upperBound); + long differentBits = lowerBound ^ upperBound; + int sameBitCount = Long.numberOfLeadingZeros(differentBits << upperBoundLeadingZeros); + + upMask = upperBound | -1L >>> (upperBoundLeadingZeros + sameBitCount); + downMask = upperBound & ~(-1L >>> (upperBoundLeadingZeros + sameBitCount)); + } else { + if (upperBound >= 0) { + upMask = defaultMask; + downMask = 0; + } else { + int lowerBoundLeadingOnes = Long.numberOfLeadingZeros(~lowerBound); + long differentBits = lowerBound ^ upperBound; + int sameBitCount = Long.numberOfLeadingZeros(differentBits << lowerBoundLeadingOnes); + + upMask = lowerBound | -1L >>> (lowerBoundLeadingOnes + sameBitCount) | ~(-1L >>> lowerBoundLeadingOnes); + downMask = lowerBound & ~(-1L >>> (lowerBoundLeadingOnes + sameBitCount)) | ~(-1L >>> lowerBoundLeadingOnes); + } + } + return new IntegerStamp(bits, lowerBound, upperBound, downMask & defaultMask, upMask & defaultMask); + } + + public static FloatStamp forFloat(Kind kind, double lowerBound, double upperBound, boolean nonNaN) { + assert kind.isNumericFloat(); + return new FloatStamp(kind.getBitCount(), lowerBound, upperBound, nonNaN); + } + + public static Stamp forConstant(Constant value) { + Kind kind = value.getKind(); + switch (kind) { + case Boolean: + case Byte: + case Char: + case Short: + case Int: + case Long: + long mask = value.asLong() & IntegerStamp.defaultMask(kind.getBitCount()); + return forInteger(kind.getStackKind(), value.asLong(), value.asLong(), mask, mask); + case Float: + return forFloat(kind, value.asFloat(), value.asFloat(), !Float.isNaN(value.asFloat())); + case Double: + return forFloat(kind, value.asDouble(), value.asDouble(), !Double.isNaN(value.asDouble())); + case Illegal: + return illegal(Kind.Illegal); + case Object: + if (value.isNull()) { + return alwaysNull(); + } else { + return objectNonNull(); + } + default: + throw new GraalInternalError("unexpected kind: %s", kind); + } + } + + public static Stamp forConstant(Constant value, MetaAccessProvider metaAccess) { + assert value.getKind() == Kind.Object; + if (value.getKind() == Kind.Object) { + ResolvedJavaType type = value.isNull() ? null : metaAccess.lookupJavaType(value); + return new ObjectStamp(type, value.isNonNull(), value.isNonNull(), value.isNull()); + } else { + throw new GraalInternalError(Kind.Object + " expected, actual kind: %s", value.getKind()); + } + } + + public static Stamp object() { + return objectStamp; + } + + public static Stamp objectNonNull() { + return objectNonNullStamp; + } + + public static Stamp alwaysNull() { + return objectAlwaysNullStamp; + } + + public static Stamp declared(ResolvedJavaType type) { + return declared(type, false); + } + + public static Stamp declaredNonNull(ResolvedJavaType type) { + return declared(type, true); + } + + public static Stamp declared(ResolvedJavaType type, boolean nonNull) { + return object(type, false, nonNull); + } + + public static Stamp object(ResolvedJavaType type, boolean exactType, boolean nonNull) { + assert type != null; + assert type.getKind() == Kind.Object; + ResolvedJavaType exact = type.asExactType(); + if (exact != null) { + assert !exactType || type.equals(exact); + return new ObjectStamp(exact, true, nonNull, false); + } else { + return new ObjectStamp(type, exactType, nonNull, false); + } + } + + public static Stamp exactNonNull(ResolvedJavaType type) { + if (ObjectStamp.isConcreteType(type)) { + return new ObjectStamp(type, true, true, false); + } else { + return illegal(Kind.Object); + } + } + + public static Stamp exact(ResolvedJavaType type) { + return new ObjectStamp(type, true, false, false); + } +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/StampProvider.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/StampProvider.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,28 @@ +/* + * 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.common.type; + +public interface StampProvider { + + Stamp stamp(); +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/VoidStamp.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/VoidStamp.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2014, 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.common.type; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.common.*; +import com.oracle.graal.compiler.common.spi.*; + +/** + * Singleton stamp representing the value of type {@code void}. + */ +public final class VoidStamp extends Stamp { + + private VoidStamp() { + } + + @Override + public Stamp unrestricted() { + return this; + } + + @Override + public Kind getStackKind() { + return Kind.Void; + } + + @Override + public PlatformKind getPlatformKind(PlatformKindTool tool) { + throw GraalInternalError.shouldNotReachHere("void stamp has no value"); + } + + @Override + public ResolvedJavaType javaType(MetaAccessProvider metaAccess) { + return metaAccess.lookupJavaType(Void.TYPE); + } + + @Override + public String toString() { + return "void"; + } + + @Override + public boolean alwaysDistinct(Stamp other) { + return this != other; + } + + @Override + public Stamp meet(Stamp other) { + if (other instanceof IllegalStamp) { + return other.join(this); + } + if (this == other) { + return this; + } + return StampFactory.illegal(Kind.Illegal); + } + + @Override + public Stamp join(Stamp other) { + if (other instanceof IllegalStamp) { + return other.join(this); + } + if (this == other) { + return this; + } + return StampFactory.illegal(Kind.Illegal); + } + + @Override + public boolean isCompatible(Stamp stamp) { + return this == stamp; + } + + @Override + public Stamp illegal() { + // there is no illegal void stamp + return this; + } + + @Override + public boolean isLegal() { + return true; + } + + private static VoidStamp instance = new VoidStamp(); + + static VoidStamp getInstance() { + return instance; + } +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test.infra/src/com/oracle/graal/compiler/hsail/test/infra/GraalKernelTester.java --- a/graal/com.oracle.graal.compiler.hsail.test.infra/src/com/oracle/graal/compiler/hsail/test/infra/GraalKernelTester.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.compiler.hsail.test.infra/src/com/oracle/graal/compiler/hsail/test/infra/GraalKernelTester.java Wed Apr 23 15:48:38 2014 +0200 @@ -27,8 +27,8 @@ * This class extends KernelTester and provides a base class * for which the HSAIL code comes from the Graal compiler. */ +import static com.oracle.graal.compiler.common.GraalOptions.*; import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; -import static com.oracle.graal.phases.GraalOptions.*; import static org.junit.Assume.*; import java.io.*; @@ -38,16 +38,15 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.common.*; import com.oracle.graal.compiler.target.*; import com.oracle.graal.debug.*; import com.oracle.graal.gpu.*; -import com.oracle.graal.graph.*; import com.oracle.graal.hotspot.hsail.*; import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.hsail.*; import com.oracle.graal.options.*; import com.oracle.graal.options.OptionValue.OverrideScope; -import com.oracle.graal.phases.*; public abstract class GraalKernelTester extends KernelTester { @@ -103,6 +102,40 @@ return (canGenerateCalls && canExecuteCalls); } + private static boolean supportsObjectAllocation() { + return true; + } + + /** + * Determines if the runtime supports object allocation in HSAIL code. + */ + public boolean canHandleObjectAllocation() { + return supportsObjectAllocation() && canDeoptimize(); + } + + /** + * Determines if the runtime supports deoptimization in HSAIL code. + */ + public boolean canDeoptimize() { + return getHSAILBackend().getRuntime().getConfig().useHSAILDeoptimization; + } + + /** + * Determines if the runtime supports {@link VirtualObject}s in {@link DebugInfo} associated + * with HSAIL code. + */ + public boolean canHandleDeoptVirtualObjects() { + return false; + } + + /** + * Determines if the runtime supports {@link StackSlot}s in {@link DebugInfo} associated with + * HSAIL code. + */ + public boolean canHandleDeoptStackSlots() { + return false; + } + /** * Determines if the runtime has the capabilities required by this test. */ @@ -126,7 +159,7 @@ } } - public static OptionValue getOptionFromField(Class declaringClass, String fieldName) { + public static OptionValue getOptionFromField(Class declaringClass, String fieldName) { try { Field f = declaringClass.getDeclaredField(fieldName); f.setAccessible(true); @@ -156,8 +189,8 @@ @Override public void testGeneratedHsailUsingLambdaMethod() { try (OverrideScope s = getOverrideScope()) { + assumeTrue(supportsRequiredCapabilities()); super.testGeneratedHsailUsingLambdaMethod(); } } - } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test.infra/src/com/oracle/graal/compiler/hsail/test/infra/KernelTester.java --- a/graal/com.oracle.graal.compiler.hsail.test.infra/src/com/oracle/graal/compiler/hsail/test/infra/KernelTester.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.compiler.hsail.test.infra/src/com/oracle/graal/compiler/hsail/test/infra/KernelTester.java Wed Apr 23 15:48:38 2014 +0200 @@ -416,9 +416,9 @@ } /** - * The dispatchLambdaKernel dispatches the lambda version of a kernel where the "kernel" is for - * the xxx$$Lambda.accept method in the wrapper for the lambda. Note that the useLambdaMethod - * boolean provides a way of actually invoking dispatchLambdaMethodKernel from this API. + * Dispatches the lambda version of a kernel where the "kernel" is for the xxx$$Lambda.accept + * method in the wrapper for the lambda. Note that the useLambdaMethod boolean provides a way of + * actually invoking dispatchLambdaMethodKernel from this API. */ public void dispatchLambdaKernel(int range, MyIntConsumer consumer) { if (useLambdaMethod) { diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/AtomicReferenceGetAndSetTest.java --- a/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/AtomicReferenceGetAndSetTest.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/AtomicReferenceGetAndSetTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -96,6 +96,7 @@ } @Test + @Ignore public void test() { testGeneratedHsail(); } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/BasicHSAILTest.java --- a/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/BasicHSAILTest.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/BasicHSAILTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -22,6 +22,8 @@ */ package com.oracle.graal.compiler.hsail.test; +import static com.oracle.graal.debug.DelegatingDebugConfig.Feature.*; + import java.lang.reflect.*; import org.junit.*; @@ -343,12 +345,14 @@ } private void test(final String snippet) { - try (Scope s = Debug.scope("HSAILCodeGen")) { - Method method = getMethod(snippet); - ExternalCompilationResult hsailCode = getBackend().compileKernel(getMetaAccess().lookupJavaMethod(method), false); - Debug.log("HSAIL code generated for %s:%n%s", snippet, hsailCode.getCodeString()); - } catch (Throwable e) { - throw Debug.handle(e); + try (DebugConfigScope dcs = Debug.setConfig(new DelegatingDebugConfig().disable(INTERCEPT))) { + try (Scope s = Debug.scope("HSAILCodeGen")) { + Method method = getMethod(snippet); + ExternalCompilationResult hsailCode = getBackend().compileKernel(getMetaAccess().lookupJavaMethod(method), false); + Debug.log("HSAIL code generated for %s:%n%s", snippet, hsailCode.getCodeString()); + } catch (Throwable e) { + throw Debug.handle(e); + } } } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/BoundsCatchBase.java --- a/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/BoundsCatchBase.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/BoundsCatchBase.java Wed Apr 23 15:48:38 2014 +0200 @@ -56,7 +56,7 @@ @Override protected boolean supportsRequiredCapabilities() { - return getHSAILBackend().getRuntime().getConfig().useHSAILDeoptimization; + return canDeoptimize(); } @Override diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/EscapingNewBase.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/EscapingNewBase.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2014, 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.hsail.test; + +import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester; +import java.util.Arrays; + +/** + * Base Class for tests that allocate escaping objects. + */ + +public class EscapingNewBase extends GraalKernelTester { + + final int NUM = getRange(); + + int getRange() { + return 24; + } + + @Result public Object[] outArray = new Object[NUM]; + public Object[] savedOutArray; + @Result public boolean savedOutArrayMatch1; + @Result public boolean savedOutArrayMatch2; + @Result public boolean savedOutArrayMatch3; + + void setupArrays() { + for (int i = 0; i < NUM; i++) { + outArray[i] = null; + } + } + + int getDispatches() { + return 1; + } + + @Override + protected boolean supportsRequiredCapabilities() { + return canHandleObjectAllocation(); + } + + @Override + public void runTest() { + setupArrays(); + + dispatchMethodKernel(NUM); + // use System.gc() to ensure new objects are in form that gc likes + System.gc(); + savedOutArray = Arrays.copyOf(outArray, NUM); + savedOutArrayMatch1 = Arrays.equals(outArray, savedOutArray); + if (getDispatches() > 1) { + // redispatch kernel without gc + dispatchMethodKernel(NUM); + savedOutArrayMatch2 = Arrays.equals(outArray, savedOutArray); + // and one more time with gc + dispatchMethodKernel(NUM); + savedOutArrayMatch3 = Arrays.equals(outArray, savedOutArray); + System.gc(); + } + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/EscapingNewFloatStringTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/EscapingNewFloatStringTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2014, 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.hsail.test; + +import org.junit.*; + +/** + * Tests creating a new String from a float. + */ + +public class EscapingNewFloatStringTest extends EscapingNewBase { + + @Result public String[] myOutArray = new String[NUM]; + + public void run(int gid) { + outArray[gid] = Float.toString(gid * 1.11f); + myOutArray[gid] = Float.toString(gid * 2.22f); + } + + @Ignore("problems runs out of memory space while inlining") + @Test + public void test() { + testGeneratedHsail(); + } +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/EscapingNewFloatTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/EscapingNewFloatTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2014, 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.hsail.test; + +import org.junit.Test; + +public class EscapingNewFloatTest extends EscapingNewBase { + @Result Float[] myOutArray = new Float[NUM]; + + public void run(int gid) { + outArray[gid] = (gid + 1) * 1.11f; + myOutArray[gid] = (gid + 1) * 2.22f; + } + + @Test + public void test() { + testGeneratedHsail(); + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/EscapingNewIntArrayTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/EscapingNewIntArrayTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2014, 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.hsail.test; + +import org.junit.Test; + +/** + * Tests allocation of an integer array per workitem. + */ + +public class EscapingNewIntArrayTest extends EscapingNewBase { + + public void run(int gid) { + int size = gid + 1; + int[] ary = new int[size]; + for (int i = 0; i < ary.length; i++) { + ary[i] = i * 3; + } + outArray[gid] = ary; + } + + private static final boolean DEBUG = Boolean.getBoolean("hsail.debug"); + + @Override + public void runTest() { + super.runTest(); + if (DEBUG) { + for (int i = 0; i < NUM; i++) { + int[] ary = (int[]) outArray[i]; + System.out.print("ary len " + ary.length + ": "); + for (int val : ary) { + System.out.print(val + ","); + } + System.out.println(); + } + } + } + + @Test + public void test() { + testGeneratedHsail(); + } +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/EscapingNewIntegerTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/EscapingNewIntegerTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2014, 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.hsail.test; + +import org.junit.Test; + +/** + * Tests allocation of a java.lang.Integer per workitem. + */ + +public class EscapingNewIntegerTest extends EscapingNewBase { + @Result Integer[] myOutArray = new Integer[NUM]; + + public void run(int gid) { + outArray[gid] = (gid + 1) * 111; + myOutArray[gid] = (gid + 1) * 222; + } + + @Test + public void test() { + testGeneratedHsail(); + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/EscapingNewStoreFieldTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/EscapingNewStoreFieldTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2014, 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.hsail.test; + +import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester; +import org.junit.Test; + +/** + * Tests allocation of a Vec3 object stored in a field by workitem #1. + */ + +public class EscapingNewStoreFieldTest extends GraalKernelTester { + + static final int NUM = 20; + public float[] inArray = new float[NUM]; + @Result public Vec3 outField; + + void setupArrays() { + for (int i = 0; i < NUM; i++) { + inArray[i] = i; + } + } + + public void run(int gid) { + if (gid == 1) { + float inval = inArray[gid]; + outField = new Vec3(inval + 1, inval + 2, inval + 3); + } + } + + @Override + public void runTest() { + setupArrays(); + + dispatchMethodKernel(NUM); + + // see what happens if we do it again + dispatchMethodKernel(NUM); + System.gc(); + } + + @Override + protected boolean supportsRequiredCapabilities() { + return canHandleObjectAllocation(); + } + + @Test + public void test() { + testGeneratedHsail(); + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/EscapingNewStringConcatTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/EscapingNewStringConcatTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2014, 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.hsail.test; + +import static com.oracle.graal.debug.Debug.*; + +import org.junit.Test; + +import com.oracle.graal.debug.*; + +/** + * Tests allocation of a new String based on string concatenation. + */ + +public class EscapingNewStringConcatTest extends EscapingNewBase { + + @Result public String[] myOutArray = new String[NUM]; + public String[] inArray = new String[NUM]; + + @Override + void setupArrays() { + super.setupArrays(); + for (int i = 0; i < NUM; i++) { + inArray[i] = Integer.toString(i + 100); + } + } + + public void run(int gid) { + outArray[gid] = inArray[gid] + inArray[(gid + NUM / 2) % NUM]; + myOutArray[gid] = inArray[(gid + NUM / 2) % NUM] + inArray[gid]; + } + + // Node implementing Lowerable not handled in HSAIL Backend: 6274|MonitorEnter + @Test(expected = com.oracle.graal.compiler.common.GraalInternalError.class) + public void test() { + try (DebugConfigScope s = disableIntercept()) { + testGeneratedHsail(); + } + } +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/EscapingNewStringInternTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/EscapingNewStringInternTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2014, 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.hsail.test; + +import static com.oracle.graal.debug.Debug.*; + +import org.junit.Test; + +import com.oracle.graal.debug.*; + +/** + * Tests allocation of a new String based on string interning. + */ + +public class EscapingNewStringInternTest extends EscapingNewBase { + + public void run(int gid) { + outArray[gid] = Integer.toString(gid * 111).intern(); + } + + // at node: 12|Invoke#Direct#intern + @Test(expected = com.oracle.graal.compiler.common.GraalInternalError.class) + public void test() { + try (DebugConfigScope s = disableIntercept()) { + testGeneratedHsail(); + } + } +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/EscapingNewStringLargeRangeTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/EscapingNewStringLargeRangeTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2014, 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.hsail.test; + +import org.junit.Test; + +/** + * Tests allocation of a new String from integer with a large range of workitems. + */ + +public class EscapingNewStringLargeRangeTest extends EscapingNewStringTest { + + @Override + int getRange() { + return 125000; + } + + @Override + @Test + public void test() { + testGeneratedHsail(); + } +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/EscapingNewStringTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/EscapingNewStringTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2014, 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.hsail.test; + +import org.junit.Test; + +/** + * Tests allocation of a new String from an integer per workitem. + */ + +public class EscapingNewStringTest extends EscapingNewBase { + + @Result public String[] myOutArray = new String[NUM]; + + public void run(int gid) { + outArray[gid] = Integer.toString(gid * 111); + myOutArray[gid] = Integer.toString(gid * 222); + } + + @Test + public void test() { + testGeneratedHsail(); + } +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/EscapingNewVec3ArrayTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/EscapingNewVec3ArrayTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2014, 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.hsail.test; + +import org.junit.Test; + +/** + * Tests allocation of an array of Vec3 objects per workitem. + */ + +public class EscapingNewVec3ArrayTest extends EscapingNewBase { + + public void run(int gid) { + int size = gid + 1; + Vec3[] vec3ary = new Vec3[size]; + for (int i = 0; i < vec3ary.length; i++) { + vec3ary[i] = new Vec3(size + i + 1.1f, size + i + 2.2f, size + i + 3.3f); + } + outArray[gid] = vec3ary; + } + + private static final boolean DEBUG = Boolean.getBoolean("hsail.debug"); + + @Override + public void runTest() { + super.runTest(); + if (DEBUG) { + System.out.println("dumping results"); + for (int i = 0; i < NUM; i++) { + Vec3[] ary = (Vec3[]) outArray[i]; + System.out.print("ary len " + ary.length + ": "); + for (Vec3 val : ary) { + System.out.print(val + ", "); + } + System.out.println(); + } + } + } + + @Test + public void test() { + testGeneratedHsail(); + } +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/EscapingNewVec3Base.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/EscapingNewVec3Base.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2014, 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.hsail.test; + +/** + * Base class for Vec3 object allocation tests. + */ + +public class EscapingNewVec3Base extends EscapingNewBase { + + float[] inArray = new float[NUM]; + @Result Vec3[] myOutArray = new Vec3[NUM]; + + @Override + void setupArrays() { + super.setupArrays(); + for (int i = 0; i < NUM; i++) { + inArray[i] = i; + myOutArray[i] = null; + } + } + + public void run(int gid) { + float inval = inArray[gid]; + // allocate and store in Object array + outArray[gid] = new Vec3(inval + 1.1f, inval + 2.1f, inval + 3.1f); + // allocate and store in Vec3 array + myOutArray[gid] = new Vec3(inval + 4.1f, inval + 5.1f, inval + 6.1f); + } +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/EscapingNewVec3LargeRangeDisp3Test.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/EscapingNewVec3LargeRangeDisp3Test.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2014, 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.hsail.test; + +import org.junit.Test; + +/** + * Tests allocation of a new Vec3 object with a large range of workitems with 3 dispatches. + */ + +public class EscapingNewVec3LargeRangeDisp3Test extends EscapingNewVec3Test { + + @Override + int getRange() { + return 250000; + } + + @Override + int getDispatches() { + return 3; + } + + @Override + @Test + public void test() { + testGeneratedHsail(); + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/EscapingNewVec3LargeRangeTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/EscapingNewVec3LargeRangeTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2014, 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.hsail.test; + +import org.junit.Test; + +/** + * Tests allocation of a new Vec3 object with a large range of workitems. + */ + +public class EscapingNewVec3LargeRangeTest extends EscapingNewVec3Test { + + @Override + int getRange() { + return 250000; + } + + @Override + @Test + public void test() { + testGeneratedHsail(); + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/EscapingNewVec3MediumRangeTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/EscapingNewVec3MediumRangeTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2014, 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.hsail.test; + +import org.junit.Test; + +/** + * Tests allocation of a new Vec3 object with a medium range of workitems. + */ + +public class EscapingNewVec3MediumRangeTest extends EscapingNewVec3Test { + + @Override + int getRange() { + return 100000; + } + + @Override + @Test + public void test() { + testGeneratedHsail(); + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/EscapingNewVec3Partial2Test.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/EscapingNewVec3Partial2Test.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2014, 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.hsail.test; + +import org.junit.Test; + +/** + * Tests allocation of a new Vec3 object but skipping one workitem. + */ + +public class EscapingNewVec3Partial2Test extends EscapingNewVec3Base { + + int testGid = NUM / 2; + + @Override + public void run(int gid) { + float inval = inArray[gid]; + if (gid != testGid) { + outArray[gid] = new Vec3(inval + 1.1f, inval + 2.1f, inval + 3.1f); + myOutArray[gid] = new Vec3(inval + 4.1f, inval + 5.1f, inval + 6.1f); + } + } + + @Test + public void test() { + testGeneratedHsail(); + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/EscapingNewVec3PartialTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/EscapingNewVec3PartialTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2014, 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.hsail.test; + +import org.junit.Test; + +/** + * Tests allocation of a new Vec3 object but only for half of the workitems. + */ + +public class EscapingNewVec3PartialTest extends EscapingNewVec3Base { + + @Override + public void run(int gid) { + float inval = inArray[gid]; + outArray[gid] = (gid % 2 == 0 ? new Vec3(inval + 1.1f, inval + 2.1f, inval + 3.1f) : null); + myOutArray[gid] = (gid % 2 != 0 ? new Vec3(inval + 4.1f, inval + 5.1f, inval + 6.1f) : null); + } + + @Test + public void test() { + testGeneratedHsail(); + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/EscapingNewVec3Test.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/EscapingNewVec3Test.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2014, 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.hsail.test; + +import org.junit.Test; + +/** + * Tests allocation of a new Vec3 object per workitem. + */ + +public class EscapingNewVec3Test extends EscapingNewVec3Base { + + @Test + public void test() { + testGeneratedHsail(); + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/FloatSqrtTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/FloatSqrtTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2009, 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.compiler.hsail.test; + +import org.junit.*; + +import com.oracle.graal.compiler.hsail.test.infra.*; + +/** + * Tests floating point square root. + */ +public class FloatSqrtTest extends GraalKernelTester { + + static final int size = 64; + float[] input = new float[size]; + @Result float[] output = new float[size]; + { + for (int i = 0; i < size; i++) { + input[i] = i; + output[i] = -1.0f; + } + + } + + public static void run(float[] input1, float[] output1, int gid) { + output1[gid] = (float) Math.sqrt(input1[gid]); + } + + @Override + public void runTest() { + dispatchMethodKernel(size, input, output); + } + + @Test + public void test() { + testGeneratedHsail(); + } +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/InstanceOfTwoLevelTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/InstanceOfTwoLevelTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2009, 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.compiler.hsail.test; + +import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester; +import org.junit.Test; + +public class InstanceOfTwoLevelTest extends GraalKernelTester { + + static final int NUM = 20; + + static abstract class Shape { + abstract public float getArea(); + } + + static class Ellipse extends Shape { + private float major; + private float minor; + + Ellipse(float major, float minor) { + this.major = major; + this.minor = minor; + } + + public float getEccentricity() { + float a = major / 2; + float b = minor / 2; + return (float) Math.sqrt(1 - (b / a) * (b / a)); + } + + @Override + public float getArea() { + float a = major / 2; + float b = minor / 2; + return (float) (Math.PI * a * b); + } + } + + static class Circle extends Ellipse { + Circle(float r) { + super(2 * r, 2 * r); + } + } + + static class Square extends Shape { + private float len; + + Square(float _len) { + len = _len; + } + + @Override + public float getArea() { + return len * len; + } + } + + @Result public float[] outArray = new float[NUM]; + public Object[] inShapeArray = new Object[NUM]; + + void setupArrays() { + for (int i = 0; i < NUM; i++) { + switch (i % 4) { + case 0: + inShapeArray[i] = new Circle(i + 1); + break; + case 1: + inShapeArray[i] = new Square(i + 1); + break; + case 2: + inShapeArray[i] = new Ellipse(i + 1, i + 2); + break; + case 3: + inShapeArray[i] = new Object(); + break; + } + outArray[i] = -i; + } + } + + public void run(int gid) { + outArray[gid] = (inShapeArray[gid] instanceof Shape ? 1.0f : 2.0f); + } + + @Override + public void runTest() { + setupArrays(); + + dispatchMethodKernel(NUM); + } + + @Test + public void test() { + testGeneratedHsail(); + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/IntTestBranchTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/IntTestBranchTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2009, 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.compiler.hsail.test; + +import org.junit.Test; + +/** + * Tests code generation for IntegerTestNode for HSAIL backend. + */ +public class IntTestBranchTest extends StaticMethodTwoIntArrays { + + /** + * The static "kernel" method we will be testing. By convention the gid is the last parameter. + * + * @param out + * @param in + * @param gid + */ + public static void run(int[] out, int[] in, int gid) { + if ((in[gid] & 3) != 0) { + out[gid] = in[gid] * 2; + } else { + out[gid] = in[gid] * 3; + } + } + + @Test + public void test() { + super.testGeneratedHsail(); + } +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/NestedStaticCallTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/NestedStaticCallTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2009, 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.compiler.hsail.test; + +import org.junit.*; + +import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester; + +/** + * Tests direct method calls. + */ +public class NestedStaticCallTest extends GraalKernelTester { + + static final int width = 768; + static final int height = width; + private int iterations = 100; + static final int range = width * height; + @Result public float[] outArray = new float[range]; + + public static int a(int i) { + if (i < 2) { + return b(i); + } else { + return i; + } + } + + public static int b(int i) { + if (i < 90) { + return c(i) + i; + } else { + return d(i) - i; + } + } + + public static int c(int i) { + + return d(i) + 5; + } + + public static int d(int i) { + + return e(i) + 10; + } + + public static int e(int i) { + return 52 + i; + } + + public void run(int gid) { + for (int i = 0; i < iterations; i++) { + outArray[gid] = a(gid) + i; + } + } + + @Override + public void runTest() { + dispatchMethodKernel(range); + } + + @Test + public void test() { + testGeneratedHsail(); + } +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/NestedVirtualCallTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/NestedVirtualCallTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2009, 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.compiler.hsail.test; + +import org.junit.*; + +import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester; + +/** + * Tests direct method calls. + */ +public class NestedVirtualCallTest extends GraalKernelTester { + + static final int width = 768; + static final int height = width; + private int iterations = 100; + static final int range = width * height; + @Result public float[] outArray = new float[range]; + + public int a(int i) { + if (i < 2) { + return b(i); + } else { + return i; + } + } + + public int b(int i) { + if (i < 90) { + return c(i) + i; + } else { + return d(i) - i; + } + } + + public int c(int i) { + + return d(i) + 5; + } + + public int d(int i) { + + return e(i) + 10; + } + + public int e(int i) { + return 52 + i; + } + + public void run(int gid) { + for (int i = 0; i < iterations; i++) { + outArray[gid] = a(gid) + i; + } + } + + @Override + public void runTest() { + dispatchMethodKernel(range); + } + + @Test + public void test() { + super.testGeneratedHsail(); + } +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/SingleExceptionTestBase.java --- a/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/SingleExceptionTestBase.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/SingleExceptionTestBase.java Wed Apr 23 15:48:38 2014 +0200 @@ -37,7 +37,7 @@ @Override protected boolean supportsRequiredCapabilities() { - return getHSAILBackend().getRuntime().getConfig().useHSAILDeoptimization; + return canDeoptimize(); } void recordException(Exception e) { diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/StaticCallTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/StaticCallTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2009, 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.compiler.hsail.test; + +import org.junit.*; + +import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester; + +/** + * Tests direct method calls. + */ +public class StaticCallTest extends GraalKernelTester { + + static final int width = 768; + static final int height = width; + private int iterations = 100; + static final int range = width * height; + @Result public float[] outArray = new float[range]; + + public static int foo(int gid, int i) { + if (gid < 2) { + return bar(gid, i); + } else { + return gid + i; + } + } + + public static int bar(int gid, int i) { + if (gid < 90) { + return gid + i; + } else { + return gid - i; + } + } + + public void run(int gid) { + for (int i = 0; i < iterations; i++) { + outArray[gid] = bar(gid, i); + } + } + + @Override + public void runTest() { + dispatchMethodKernel(range); + } + + @Test + public void test() { + super.testGeneratedHsail(); + } +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/StaticMandelBoundsCheckTest.java --- a/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/StaticMandelBoundsCheckTest.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/StaticMandelBoundsCheckTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -23,8 +23,6 @@ package com.oracle.graal.compiler.hsail.test; -import static org.junit.Assume.*; - import org.junit.*; /** @@ -84,7 +82,6 @@ @Test public void test() { - assumeTrue(runningOnSimulator()); testGeneratedHsail(); } } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/StaticMandelTest.java --- a/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/StaticMandelTest.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/StaticMandelTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -23,10 +23,7 @@ package com.oracle.graal.compiler.hsail.test; -import static org.junit.Assume.*; - import org.junit.*; - import com.oracle.graal.compiler.hsail.test.infra.*; /** @@ -82,7 +79,6 @@ @Test public void test() { - assumeTrue(runningOnSimulator()); testGeneratedHsail(); } } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/StaticMethod16InArraysTest.java --- a/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/StaticMethod16InArraysTest.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/StaticMethod16InArraysTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -23,10 +23,11 @@ package com.oracle.graal.compiler.hsail.test; +import static com.oracle.graal.debug.DelegatingDebugConfig.Feature.*; + import org.junit.*; import com.oracle.graal.debug.*; -import com.oracle.graal.debug.internal.*; /** * Tests the addition of elements from sixteen input arrays. @@ -64,15 +65,7 @@ @Test(expected = java.lang.ClassCastException.class) @Ignore("until GPU backends can co-exist") public void test() { - DebugConfig debugConfig = DebugScope.getConfig(); - DebugConfig noInterceptConfig = new DelegatingDebugConfig(debugConfig) { - @Override - public RuntimeException interceptException(Throwable e) { - return null; - } - }; - - try (DebugConfigScope s = Debug.setConfig(noInterceptConfig)) { + try (DebugConfigScope s = Debug.setConfig(new DelegatingDebugConfig().disable(INTERCEPT))) { testGeneratedHsail(); } } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/StaticNBodyCallTest.java --- a/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/StaticNBodyCallTest.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/StaticNBodyCallTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -23,8 +23,6 @@ package com.oracle.graal.compiler.hsail.test; -import static org.junit.Assume.*; - import org.junit.*; /** @@ -39,7 +37,6 @@ @Override public void runTest() { - assumeTrue(aggressiveInliningEnabled() || canHandleHSAILMethodCalls()); super.runTest(); } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/StringContainsAcceptTest.java --- a/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/StringContainsAcceptTest.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/StringContainsAcceptTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -23,8 +23,6 @@ package com.oracle.graal.compiler.hsail.test; -import static org.junit.Assume.*; - import org.junit.*; /** @@ -42,7 +40,6 @@ @Override public void runTest() { - assumeTrue(aggressiveInliningEnabled() || canHandleHSAILMethodCalls()); setupArrays(); dispatchMethodKernel(NUM); diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/StringSwitchTest.java --- a/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/StringSwitchTest.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/StringSwitchTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -23,11 +23,9 @@ package com.oracle.graal.compiler.hsail.test; -import static org.junit.Assume.*; - import org.junit.*; -import com.oracle.graal.compiler.hsail.test.infra.*; +import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester; /** * Tests switch statement with String literal keys. @@ -121,14 +119,8 @@ } } - /** - * Tests the HSAIL code generated for this unit test by comparing the result of executing this - * code with the result of executing a sequential Java version of this unit test. - */ @Test public void test() { - // This test is only run if inlining is enabled since it requires method call support. - assumeTrue(aggressiveInliningEnabled() || canHandleHSAILMethodCalls()); super.testGeneratedHsail(); } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/VolatileIntTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/VolatileIntTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2009, 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.compiler.hsail.test; + +import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester; +import org.junit.Test; + +/** + * + * @author ecaspole + */ +public class VolatileIntTest extends GraalKernelTester { + + static final int num = 20; + @Result protected int[] outArray = new int[num]; + + volatile int theVolatileInt = 42; + + /** + * The static "kernel" method we will be testing. By convention the gid is the last parameter. + * + */ + public void run(int[] out, int[] ina, int[] inb, int gid) { + + // Note these array ops are not really part of the test results + int x = theVolatileInt; + + out[gid] = ina[gid] + inb[gid]; + + theVolatileInt = x; + } + + @Test + public void test() { + super.testGeneratedHsail(); + } + + void setupArrays(int[] in, int[] in2) { + for (int i = 0; i < num; i++) { + in[i] = 1; + in2[i] = 2; + outArray[i] = 0; + } + } + + @Override + public void runTest() { + int[] inArray = new int[num]; + int[] inArray2 = new int[num]; + setupArrays(inArray, inArray2); + + dispatchMethodKernel(num, outArray, inArray, inArray2); + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/ArrayFieldAccessTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/ArrayFieldAccessTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2009, 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.compiler.hsail.test.lambda; + +import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester; +import org.junit.Test; + +/** + * Tests accessing a field which is an array. + */ +public class ArrayFieldAccessTest extends GraalKernelTester { + + static final int NUM = 20; + @Result public int[] outArray = new int[NUM]; + public int[] inArray = new int[NUM]; + + void setupArrays() { + for (int i = 0; i < NUM; i++) { + inArray[i] = i; + outArray[i] = -i; + } + } + + @Override + public void runTest() { + setupArrays(); + + dispatchLambdaKernel(NUM, (gid) -> { + outArray[gid] = inArray[gid] * 3; + }); + } + + @Test + public void test() { + testGeneratedHsail(); + } + + @Test + public void testUsingLambdaMethod() { + testGeneratedHsailUsingLambdaMethod(); + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/ArrayListGetTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/ArrayListGetTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2009, 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.compiler.hsail.test.lambda; + +import static com.oracle.graal.debug.Debug.*; + +import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester; +import com.oracle.graal.debug.*; + +import org.junit.Test; + +import java.util.ArrayList; + +/** + * Tests calling ArrayList.get(). + */ +public class ArrayListGetTest extends GraalKernelTester { + + static final int NUM = 20; + @Result public int[] outArray = new int[NUM]; + public ArrayList inList = new ArrayList<>(); + + void setupArrays() { + for (int i = 0; i < NUM; i++) { + inList.add(i); + outArray[i] = -i; + } + } + + @Override + public void runTest() { + setupArrays(); + + dispatchLambdaKernel(NUM, (gid) -> { + int val = inList.get(gid); + outArray[gid] = val * val + 1; + }); + } + + // NYI emitForeignCall charAlignedDisjointArraycopy + @Test(expected = com.oracle.graal.compiler.common.GraalInternalError.class) + public void testUsingLambdaMethod() { + try (DebugConfigScope s = disableIntercept()) { + testGeneratedHsailUsingLambdaMethod(); + } + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/ArrayListStreamTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/ArrayListStreamTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,190 @@ +/* + * Copyright (c) 2009, 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.compiler.hsail.test.lambda; + +import java.util.ArrayList; +import java.util.stream.Stream; +import static org.junit.Assert.assertTrue; +import org.junit.Test; + +/** + * Tests using ArrayLists as streams. + */ +public class ArrayListStreamTest { + + // Static and instance fields to test codegen for + // each type of variable + static int staticSize = 16; + final int size = staticSize; + + static int staticFactor = 3; + final int factor = staticFactor; + + class MyPoint { + + int x; + int y; + + public MyPoint(int _x, int _y) { + x = _x; + y = _y; + } + } + + public ArrayList buildMyPointInputArray() { + ArrayList inputs = new ArrayList<>(size); + + for (int i = 0; i < size; i++) { + inputs.add(new MyPoint(i, i + 1)); + } + return inputs; + } + + public int[] buildIntInputArray() { + int[] inputs = new int[size]; + + for (int i = 0; i < size; i++) { + inputs[i] = i * 4; + } + return inputs; + } + + @Test + public void testForEachObjectStreamNoCaptures() { + ArrayList inputs = buildMyPointInputArray(); + + Stream s = inputs.stream(); + s = s.parallel(); + s.forEach(p -> { + // Swap the values + int tmp = p.x; + p.x = p.y + factor; + p.y = tmp; + }); + + for (int k = 0; k < size; k++) { + MyPoint p = inputs.get(k); + // System.out.println( k + " ... p.x=" + p.x ); + assertTrue(p.x == (p.y + 1 + factor)); + } + } + + @Test + public void testForEachObjectStreamNoCapturesUseStatic() { + ArrayList inputs = buildMyPointInputArray(); + + Stream s = inputs.stream(); + s = s.parallel(); + s.forEach(p -> { + // Swap the values + int tmp = p.x; + p.x = p.y + staticFactor; + p.y = tmp; + }); + + for (int k = 0; k < size; k++) { + MyPoint p = inputs.get(k); + // System.out.println( k + " ... p.x=" + p.x ); + assertTrue(p.x == (p.y + 1 + staticFactor)); + } + } + + @Test + public void testForEachObjectStreamOneCapture() { + int[] data = buildIntInputArray(); + ArrayList inputs = buildMyPointInputArray(); + + Stream s = inputs.stream(); + s = s.parallel(); + s.forEach(p -> { + p.y = data[p.x]; + }); + + for (int k = 0; k < size; k++) { + MyPoint p = inputs.get(k); + // System.out.println( k + " ... p.x=" + p.x ); + assertTrue(p.y == data[p.x]); + } + + } + + @Test + public void testForEachObjectStreamOneCaptureUseStatic() { + int[] data = buildIntInputArray(); + ArrayList inputs = buildMyPointInputArray(); + + Stream s = inputs.stream(); + s = s.parallel(); + s.forEach(p -> { + p.y = data[p.x] + staticFactor; + }); + + for (int k = 0; k < size; k++) { + MyPoint p = inputs.get(k); + // System.out.println( k + " ... p.x=" + p.x ); + assertTrue(p.y == (data[p.x] + +staticFactor)); + } + + } + + @Test + public void testForEachObjectStreamTwoCaptures() { + int[] data = buildIntInputArray(); + int[] data2 = buildIntInputArray(); + ArrayList inputs = buildMyPointInputArray(); + + Stream s = inputs.stream(); + s = s.parallel(); + s.forEach(p -> { + p.y = data[p.x] + data2[p.x]; + }); + + for (int k = 0; k < size; k++) { + MyPoint p = inputs.get(k); + // System.out.println( k + " ... p.x=" + p.x ); + assertTrue(p.y == data[p.x] + data2[p.x]); + } + + } + + @Test + public void testForEachObjectStreamTwoCapturesUseStatic() { + int[] data = buildIntInputArray(); + int[] data2 = buildIntInputArray(); + ArrayList inputs = buildMyPointInputArray(); + + Stream s = inputs.stream(); + s = s.parallel(); + s.forEach(p -> { + p.y = data[p.x] + data2[p.x] + staticFactor; + }); + + for (int k = 0; k < size; k++) { + MyPoint p = inputs.get(k); + // System.out.println( k + " ... p.x=" + p.x ); + assertTrue(p.y == data[p.x] + data2[p.x] + staticFactor); + } + + } +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/AtomicIntAddAndGetGidTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/AtomicIntAddAndGetGidTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2009, 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.compiler.hsail.test.lambda; + +import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester; +import org.junit.Test; + +import java.util.concurrent.atomic.AtomicInteger; +import java.util.Arrays; + +/** + * Tests {@link AtomicInteger#addAndGet(int)} with a variable delta. + */ +public class AtomicIntAddAndGetGidTest extends GraalKernelTester { + + static final int NUM = 20; + public int[] outArray = new int[NUM]; + @Result public int[] gaps = new int[NUM]; + AtomicInteger atomicInt; + + void setupArrays() { + for (int i = 0; i < NUM; i++) { + outArray[i] = -i; + } + atomicInt = new AtomicInteger(0); + } + + @Override + public void runTest() { + setupArrays(); + + dispatchLambdaKernel(NUM, (gid) -> { + outArray[gid] = atomicInt.addAndGet(gid); + }); + + // note: the actual order of entries in outArray is not predictable + // thus we sort before we compare results + Arrays.sort(outArray); + // System.out.print("outArray: "); + // for (int val : outArray) { + // System.out.print(val + ", "); + // } + // System.out.println(); + // create array of gaps + gaps[0] = outArray[0] - 0; + for (int i = 1; i < NUM; i++) { + gaps[i] = outArray[i] - outArray[i - 1]; + } + Arrays.sort(gaps); + + } + + @Test + public void test() { + testGeneratedHsail(); + } + + @Test + public void testUsingLambdaMethod() { + testGeneratedHsailUsingLambdaMethod(); + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/AtomicIntAddAndGetTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/AtomicIntAddAndGetTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2009, 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.compiler.hsail.test.lambda; + +import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester; +import org.junit.Test; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.Arrays; + +/** + * Tests {@link AtomicInteger#addAndGet(int)} with the delta being a constant. + */ +public class AtomicIntAddAndGetTest extends GraalKernelTester { + + static final int NUM = 20; + @Result public int[] outArray = new int[NUM]; + AtomicInteger atomicInt = new AtomicInteger(); + + void setupArrays() { + for (int i = 0; i < NUM; i++) { + outArray[i] = -i; + } + } + + @Override + public void runTest() { + setupArrays(); + + dispatchLambdaKernel(NUM, (gid) -> { + outArray[gid] = atomicInt.addAndGet(0x7); + }); + + // note: the actual order of entries in outArray is not predictable + // thus we sort before we compare results + Arrays.sort(outArray); + } + + @Test + public void test() { + testGeneratedHsail(); + } + + @Test + public void testUsingLambdaMethod() { + testGeneratedHsailUsingLambdaMethod(); + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/AtomicIntDecAndGetTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/AtomicIntDecAndGetTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2009, 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.compiler.hsail.test.lambda; + +import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester; +import org.junit.Test; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.Arrays; + +/** + * Tests {@link AtomicInteger#decrementAndGet()}. + */ +public class AtomicIntDecAndGetTest extends GraalKernelTester { + + static final int NUM = 20; + @Result public int[] outArray = new int[NUM]; + AtomicInteger atomicInt = new AtomicInteger(); + + void setupArrays() { + for (int i = 0; i < NUM; i++) { + outArray[i] = -i; + } + } + + @Override + public void runTest() { + setupArrays(); + + dispatchLambdaKernel(NUM, (gid) -> { + outArray[gid] = atomicInt.decrementAndGet(); + }); + + // note: the actual order of entries in outArray is not predictable + // thus we sort before we compare results + Arrays.sort(outArray); + } + + @Test + public void test() { + testGeneratedHsail(); + } + + @Test + public void testUsingLambdaMethod() { + testGeneratedHsailUsingLambdaMethod(); + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/AtomicIntGetAndAddTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/AtomicIntGetAndAddTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2009, 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.compiler.hsail.test.lambda; + +import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester; +import org.junit.Test; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.Arrays; + +/** + * Tests {@link AtomicInteger#getAndAdd(int)} with the delta being a constant. + */ +public class AtomicIntGetAndAddTest extends GraalKernelTester { + + static final int NUM = 20; + @Result public int[] outArray = new int[NUM]; + AtomicInteger atomicInt = new AtomicInteger(); + + void setupArrays() { + for (int i = 0; i < NUM; i++) { + outArray[i] = -i; + } + } + + @Override + public void runTest() { + setupArrays(); + + dispatchLambdaKernel(NUM, (gid) -> { + outArray[gid] = atomicInt.getAndAdd(0x7); + }); + + // note: the actual order of entries in outArray is not predictable + // thus we sort before we compare results + Arrays.sort(outArray); + } + + @Test + public void test() { + testGeneratedHsail(); + } + + @Test + public void testUsingLambdaMethod() { + testGeneratedHsailUsingLambdaMethod(); + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/AtomicIntGetAndDecTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/AtomicIntGetAndDecTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2009, 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.compiler.hsail.test.lambda; + +import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester; +import org.junit.Test; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.Arrays; + +/** + * Tests {@link AtomicInteger#getAndDecrement()}. + */ +public class AtomicIntGetAndDecTest extends GraalKernelTester { + + static final int NUM = 20; + @Result public int[] outArray = new int[NUM]; + AtomicInteger atomicInt = new AtomicInteger(); + + void setupArrays() { + for (int i = 0; i < NUM; i++) { + outArray[i] = -i; + } + } + + @Override + public void runTest() { + setupArrays(); + + dispatchLambdaKernel(NUM, (gid) -> { + outArray[gid] = atomicInt.getAndDecrement(); + }); + + // note: the actual order of entries in outArray is not predictable + // thus we sort before we compare results + Arrays.sort(outArray); + } + + @Test + public void test() { + testGeneratedHsail(); + } + + @Test + public void testUsingLambdaMethod() { + testGeneratedHsailUsingLambdaMethod(); + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/AtomicIntGetAndIncTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/AtomicIntGetAndIncTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2009, 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.compiler.hsail.test.lambda; + +import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester; +import org.junit.Test; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.Arrays; + +/** + * Tests {@link AtomicInteger#getAndIncrement()}. + */ +public class AtomicIntGetAndIncTest extends GraalKernelTester { + + static final int NUM = 20; + @Result public int[] outArray = new int[NUM]; + AtomicInteger atomicInt = new AtomicInteger(); + + void setupArrays() { + for (int i = 0; i < NUM; i++) { + outArray[i] = -i; + } + } + + @Override + public void runTest() { + setupArrays(); + + dispatchLambdaKernel(NUM, (gid) -> { + outArray[gid] = atomicInt.getAndIncrement(); + }); + + // note: the actual order of entries in outArray is not predictable + // thus we sort before we compare results + Arrays.sort(outArray); + } + + @Test + public void test() { + testGeneratedHsail(); + } + + @Test + public void testUsingLambdaMethod() { + testGeneratedHsailUsingLambdaMethod(); + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/AtomicIntIncAndGetTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/AtomicIntIncAndGetTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2009, 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.compiler.hsail.test.lambda; + +import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester; +import org.junit.Test; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.Arrays; + +/** + * Tests {@link AtomicInteger#incrementAndGet()}. + */ +public class AtomicIntIncAndGetTest extends GraalKernelTester { + + static final int NUM = 20; + @Result public int[] outArray = new int[NUM]; + AtomicInteger atomicInt = new AtomicInteger(); + + void setupArrays() { + for (int i = 0; i < NUM; i++) { + outArray[i] = -i; + } + } + + @Override + public void runTest() { + setupArrays(); + + dispatchLambdaKernel(NUM, (gid) -> { + outArray[gid] = atomicInt.incrementAndGet(); + }); + + // note: the actual order of entries in outArray is not predictable + // thus we sort before we compare results + Arrays.sort(outArray); + } + + @Test + public void test() { + testGeneratedHsail(); + } + + @Test + public void testUsingLambdaMethod() { + testGeneratedHsailUsingLambdaMethod(); + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/AtomicLongAddAndGetTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/AtomicLongAddAndGetTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2009, 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.compiler.hsail.test.lambda; + +import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester; + +import org.junit.Test; + +import java.util.concurrent.atomic.*; +import java.util.Arrays; + +/** + * Tests {@link AtomicLong#addAndGet(long)} with the delta being a constant. + */ +public class AtomicLongAddAndGetTest extends GraalKernelTester { + + static final int NUM = 20; + @Result public long[] outArray = new long[NUM]; + AtomicLong atomicLong = new AtomicLong(); + + void setupArrays() { + for (int i = 0; i < NUM; i++) { + outArray[i] = -i; + } + } + + @Override + public void runTest() { + setupArrays(); + + dispatchLambdaKernel(NUM, (gid) -> { + outArray[gid] = atomicLong.addAndGet(0x7); + }); + + // note: the actual order of entries in outArray is not predictable + // thus we sort before we compare results + Arrays.sort(outArray); + } + + @Test + public void test() { + testGeneratedHsail(); + } + + @Test + public void testUsingLambdaMethod() { + testGeneratedHsailUsingLambdaMethod(); + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/AtomicLongGetAndAddTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/AtomicLongGetAndAddTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2009, 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.compiler.hsail.test.lambda; + +import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester; +import org.junit.Test; +import java.util.concurrent.atomic.AtomicLong; +import java.util.Arrays; + +/** + * Tests {@link AtomicLong#getAndAdd(long)} with the delta being a constant. + */ +public class AtomicLongGetAndAddTest extends GraalKernelTester { + + static final int NUM = 20; + @Result public long[] outArray = new long[NUM]; + AtomicLong atomicLong = new AtomicLong(); + + void setupArrays() { + for (int i = 0; i < NUM; i++) { + outArray[i] = -i; + } + } + + @Override + public void runTest() { + setupArrays(); + + dispatchLambdaKernel(NUM, (gid) -> { + outArray[gid] = atomicLong.getAndAdd(0x7); + }); + + // note: the actual order of entries in outArray is not predictable + // thus we sort before we compare results + Arrays.sort(outArray); + } + + @Test + public void test() { + testGeneratedHsail(); + } + + @Test + public void testUsingLambdaMethod() { + testGeneratedHsailUsingLambdaMethod(); + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/AtomicLongGetAndIncTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/AtomicLongGetAndIncTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2009, 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.compiler.hsail.test.lambda; + +import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester; +import org.junit.Test; +import java.util.concurrent.atomic.AtomicLong; +import java.util.Arrays; + +/** + * Tests {@link AtomicLong#getAndIncrement()}. + */ +public class AtomicLongGetAndIncTest extends GraalKernelTester { + + static final int NUM = 20; + @Result public long[] outArray = new long[NUM]; + AtomicLong atomicLong = new AtomicLong(); + + void setupArrays() { + for (int i = 0; i < NUM; i++) { + outArray[i] = -i; + } + } + + @Override + public void runTest() { + setupArrays(); + + dispatchLambdaKernel(NUM, (gid) -> { + outArray[gid] = atomicLong.getAndIncrement(); + }); + + // note: the actual order of entries in outArray is not predictable + // thus we sort before we compare results + Arrays.sort(outArray); + } + + @Test + public void test() { + testGeneratedHsail(); + } + + @Test + public void testUsingLambdaMethod() { + testGeneratedHsailUsingLambdaMethod(); + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/AtomicLongIncAndGetTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/AtomicLongIncAndGetTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2009, 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.compiler.hsail.test.lambda; + +import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester; +import org.junit.Test; +import java.util.concurrent.atomic.AtomicLong; +import java.util.Arrays; + +/** + * Tests {@link AtomicLong#incrementAndGet()}. + */ +public class AtomicLongIncAndGetTest extends GraalKernelTester { + + static final int NUM = 20; + @Result public long[] outArray = new long[NUM]; + AtomicLong atomicLong = new AtomicLong(); + + void setupArrays() { + for (int i = 0; i < NUM; i++) { + outArray[i] = -i; + } + } + + @Override + public void runTest() { + setupArrays(); + + dispatchLambdaKernel(NUM, (gid) -> { + outArray[gid] = atomicLong.incrementAndGet(); + }); + + // note: the actual order of entries in outArray is not predictable + // thus we sort before we compare results + Arrays.sort(outArray); + } + + @Test + public void test() { + testGeneratedHsail(); + } + + @Test + public void testUsingLambdaMethod() { + testGeneratedHsailUsingLambdaMethod(); + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/BigIntegerSquaredTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/BigIntegerSquaredTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2009, 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.compiler.hsail.test.lambda; + +import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester; +import org.junit.Test; +import java.math.BigInteger; + +/** + * Tests squaring a BigInteger. + */ +public class BigIntegerSquaredTest extends GraalKernelTester { + + static final int NUM = 20; + @Result public int[] outArray = new int[NUM]; + public BigInteger[] inArray = new BigInteger[NUM]; + + void setupArrays() { + for (int i = 0; i < NUM; i++) { + inArray[i] = new BigInteger(Integer.toString(i)); + outArray[i] = -i; + } + } + + @Override + public void runTest() { + setupArrays(); + + dispatchLambdaKernel(NUM, (gid) -> { + outArray[gid] = inArray[gid].multiply(inArray[gid]).intValue(); + }); + } + + @Override + protected boolean supportsRequiredCapabilities() { + // recursive calls + return (canHandleHSAILMethodCalls()); + } + + @Test + public void test() { + testGeneratedHsail(); + } + + @Test + public void testUsingLambdaMethod() { + testGeneratedHsailUsingLambdaMethod(); + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/Body.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/Body.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2009, 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.compiler.hsail.test.lambda; + +import com.oracle.graal.compiler.hsail.test.Vec3; + +/** + * A Body object derived from Vec3 used in NBody tests. + */ +public class Body extends Vec3 { + + public Body(float _x, float _y, float _z, float _m) { + super(_x, _y, _z); + m = _m; + v = new Vec3(0, 0, 0); + } + + float m; + Vec3 v; + + public float getX() { + return x; + } + + public float getY() { + return y; + } + + public float getZ() { + return z; + } + + public float getVx() { + return v.x; + } + + public float getVy() { + return v.y; + } + + public float getVz() { + return v.z; + } + + public float getM() { + return m; + } + + public void setM(float _m) { + m = _m; + } + + public void setX(float _x) { + x = _x; + } + + public void setY(float _y) { + y = _y; + } + + public void setZ(float _z) { + z = _z; + } + + public void setVx(float _vx) { + v.x = _vx; + } + + public void setVy(float _vy) { + v.y = _vy; + } + + public void setVz(float _vz) { + v.z = _vz; + } + + @Override + public boolean equals(Object other) { + if (!(other instanceof Body)) { + return false; + } + Body oth = (Body) other; + return (oth.x == x && oth.y == y && oth.z == z && oth.m == m && v.equals(oth.v)); + } + + @Override + public int hashCode() { + // TODO Auto-generated method stub + return super.hashCode(); + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/ByteArrayTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/ByteArrayTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2009, 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.compiler.hsail.test.lambda; + +import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester; +import org.junit.Test; + +/** + * Tests reading from a byte array. + */ +public class ByteArrayTest extends GraalKernelTester { + + static final int NUM = 20; + @Result public int[] outArray = new int[NUM]; + public byte[] inArray = new byte[NUM]; + + void setupArrays() { + for (int i = 0; i < NUM; i++) { + inArray[i] = (byte) ((i + 1) * (i % 3 == 0 ? 1 : -1)); + outArray[i] = 99; + } + } + + @Override + public void runTest() { + setupArrays(); + + dispatchLambdaKernel(NUM, (gid) -> { + outArray[gid] = inArray[gid]; + }); + } + + @Test + public void test() { + testGeneratedHsail(); + } + + @Test + public void testUsingLambdaMethod() { + testGeneratedHsailUsingLambdaMethod(); + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/CountMatchesBase.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/CountMatchesBase.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2009, 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.compiler.hsail.test.lambda; + +import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester; + +/** + * Base class for tests that use Apache StringUtils.countMatches(). + */ +public abstract class CountMatchesBase extends GraalKernelTester { + + static final int NUM = 20; + @Result public int[] outArray = new int[NUM]; + public String[] inArray = new String[NUM]; + + void setupArrays() { + char[] chars = new char[100]; + for (int i = 0; i < chars.length; i++) { + chars[i] = (char) ('A' + (i % 10)); + } + for (int i = 0; i < NUM; i++) { + inArray[i] = new String(chars, i, 40); + } + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/DoubleFieldAccessTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/DoubleFieldAccessTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2009, 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.compiler.hsail.test.lambda; + +import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester; +import org.junit.Test; + +/** + * Tests accessing a double field. + */ +public class DoubleFieldAccessTest extends GraalKernelTester { + + static final int NUM = 20; + @Result public double[] outArray = new double[NUM]; + public double[] inArray = new double[NUM]; + + double doubleField = 7.0; + + void setupArrays() { + for (int i = 0; i < NUM; i++) { + inArray[i] = i; + outArray[i] = -i; + } + } + + @Override + public void runTest() { + setupArrays(); + + double[] out = outArray; + double[] in = inArray; + dispatchLambdaKernel(NUM, (gid) -> { + out[gid] = in[gid] + doubleField; + }); + } + + @Test + public void test() { + testGeneratedHsail(); + } + + @Test + public void testUsingLambdaMethod() { + testGeneratedHsailUsingLambdaMethod(); + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/FibRecursionTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/FibRecursionTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2009, 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.compiler.hsail.test.lambda; + +import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester; +import org.junit.Test; + +/** + * Tests a recursive method invocation. + */ +public class FibRecursionTest extends GraalKernelTester { + + static final int NUM = 20; + @Result public int[] outArray = new int[NUM]; + public int[] inArray = new int[NUM]; + + void setupArrays() { + for (int i = 0; i < NUM; i++) { + inArray[i] = i; + outArray[i] = -i; + } + } + + int fib(int n) { + return (n <= 2 ? 1 : fib(n - 2) + fib(n - 1)); + } + + @Override + public void runTest() { + setupArrays(); + + dispatchLambdaKernel(NUM, (gid) -> { + outArray[gid] = fib(inArray[gid]); + }); + } + + @Override + protected boolean supportsRequiredCapabilities() { + // recursive calls + return (canHandleHSAILMethodCalls()); + } + + @Test + public void test() { + testGeneratedHsail(); + } + + @Test + public void testUsingLambdaMethod() { + testGeneratedHsailUsingLambdaMethod(); + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/Float2DMatrixBase.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/Float2DMatrixBase.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2009, 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.compiler.hsail.test.lambda; + +import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester; + +/** + * Base class for 2D float matrix tests. + */ +public abstract class Float2DMatrixBase extends GraalKernelTester { + + float[][] matrixA; + float[][] matrixB; + @Result float[][] outMatrix; + + public void setupArrays(int range) { + matrixA = new float[range][]; + matrixB = new float[range][]; + outMatrix = new float[range][]; + for (int j = 0; j < range; j++) { + matrixA[j] = new float[range]; + matrixB[j] = new float[range]; + outMatrix[j] = new float[range]; + for (int k = 0; k < range; k++) { + matrixA[j][k] = (j + k) % 7; + matrixB[j][k] = (j + k + 1) % 8; + } + } + } +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/Float2DMatrixMultiplyRangeFinalTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/Float2DMatrixMultiplyRangeFinalTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2009, 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.compiler.hsail.test.lambda; + +import org.junit.Test; + +/** + * Tests 2D float matrix multiply with range being final. + */ +public class Float2DMatrixMultiplyRangeFinalTest extends Float2DMatrixBase { + + static final int range = 6; + + @Override + public void runTest() { + setupArrays(range); + + dispatchLambdaKernel(range, (gid) -> { + for (int j = 0; j < range; j++) { + float sum = 0; + for (int k = 0; k < range; k++) { + sum += (matrixA[gid][k] * matrixB[k][j]); + } + outMatrix[gid][j] = sum; + } + }); + } + + @Test + public void test() { + testGeneratedHsail(); + } + + @Test + public void testUsingLambdaMethod() { + testGeneratedHsailUsingLambdaMethod(); + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/Float2DMatrixMultiplySingleOutTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/Float2DMatrixMultiplySingleOutTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2009, 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.compiler.hsail.test.lambda; + +import org.junit.Test; + +/** + * Tests 2D float matrix multiply with each workitem outputting one entry of the result matrix. + */ +public class Float2DMatrixMultiplySingleOutTest extends Float2DMatrixBase { + + @Override + public void runTest() { + int range = 20; + setupArrays(range); + + dispatchLambdaKernel(range * range, (gid) -> { + int i = gid % range; + int j = gid / range; + float sum = 0; + for (int k = 0; k < range; k++) { + sum += (matrixA[i][k] * matrixB[k][j]); + } + outMatrix[i][j] = sum; + }); + } + + @Test + public void test() { + testGeneratedHsail(); + } + + @Test + public void testUsingLambdaMethod() { + testGeneratedHsailUsingLambdaMethod(); + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/Float2DMatrixMultiplyTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/Float2DMatrixMultiplyTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2009, 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.compiler.hsail.test.lambda; + +import org.junit.Test; + +/** + * Tests 2D float matrix multiply with each workitem outputting one row of the result matrix. + */ +public class Float2DMatrixMultiplyTest extends Float2DMatrixBase { + + @Override + public void runTest() { + int range = 20; + setupArrays(range); + + dispatchLambdaKernel(range, (gid) -> { + for (int j = 0; j < range; j++) { + float sum = 0; + for (int k = 0; k < range; k++) { + sum += (matrixA[gid][k] * matrixB[k][j]); + } + outMatrix[gid][j] = sum; + } + }); + } + + @Test + public void test() { + testGeneratedHsail(); + } + + @Test + public void testUsingLambdaMethod() { + testGeneratedHsailUsingLambdaMethod(); + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/FloatCondMoveTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/FloatCondMoveTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2009, 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.compiler.hsail.test.lambda; + +import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester; +import org.junit.Test; + +/** + * Tests conditional move of a float value. + */ +public class FloatCondMoveTest extends GraalKernelTester { + + static final int NUM = 20; + @Result public float[] outArray = new float[NUM]; + public float[] inArray = new float[NUM]; + + void setupArrays() { + for (int i = 0; i < NUM; i++) { + inArray[i] = i; + outArray[i] = -i; + } + } + + @Override + public void runTest() { + setupArrays(); + + dispatchLambdaKernel(NUM, (gid) -> { + outArray[gid] = (gid > 9 ? 2.0f : 3.0f); + }); + } + + @Test + public void test() { + testGeneratedHsail(); + } + + @Test + public void testUsingLambdaMethod() { + testGeneratedHsailUsingLambdaMethod(); + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/FloatFieldAccessTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/FloatFieldAccessTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2009, 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.compiler.hsail.test.lambda; + +import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester; +import org.junit.Test; + +/** + * Tests accessing a float field. + */ +public class FloatFieldAccessTest extends GraalKernelTester { + + static final int NUM = 20; + @Result public float[] outArray = new float[NUM]; + public int[] inArray = new int[NUM]; + + float floatField = 7f; + + void setupArrays() { + for (int i = 0; i < NUM; i++) { + inArray[i] = i; + outArray[i] = -i; + } + } + + @Override + public void runTest() { + setupArrays(); + + float[] out = outArray; + int[] in = inArray; + dispatchLambdaKernel(NUM, (gid) -> { + out[gid] = in[gid] + floatField; + }); + } + + @Test + public void test() { + testGeneratedHsail(); + } + + @Test + public void testUsingLambdaMethod() { + testGeneratedHsailUsingLambdaMethod(); + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/FloatFieldWriteTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/FloatFieldWriteTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2009, 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.compiler.hsail.test.lambda; + +import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester; +import org.junit.Test; + +/** + * Tests writing a float field. + */ +public class FloatFieldWriteTest extends GraalKernelTester { + + static final int NUM = 20; + + @Result public Body[] bodyArray = new Body[NUM]; + + void setupArrays() { + for (int i = 0; i < NUM; i++) { + Body b = new Body(i, i + 1, -i, 0); + bodyArray[i] = b; + } + } + + @Override + public void runTest() { + setupArrays(); + + dispatchLambdaKernel(NUM, (gid) -> { + Body b = bodyArray[gid]; + b.z = b.x * b.y; + }); + } + + @Test + public void test() { + testGeneratedHsail(); + } + + @Test + public void testUsingLambdaMethod() { + testGeneratedHsailUsingLambdaMethod(); + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/ForEachToGraalTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/ForEachToGraalTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,311 @@ +/* + * Copyright (c) 2009, 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.compiler.hsail.test.lambda; + +import java.util.stream.IntStream; + +import static org.junit.Assert.*; +import org.junit.Test; +import java.util.Arrays; +import java.util.ArrayList; + +/** + * Several tests for the Sumatra APIs. + */ +public class ForEachToGraalTest { + + // Static and instance fields to test codegen for + // each type of variable + static int staticSize = 16; + final int size = staticSize; + + static int printSize = 4; + + static int staticFactor = 3; + final int factor = staticFactor; + + class MyPoint { + + int x; + int y; + + public MyPoint(int _x, int _y) { + x = _x; + y = _y; + } + + public int getX() { + return x; + } + + public int getY() { + return y; + } + } + + public MyPoint[] buildMyPointInputArray() { + MyPoint[] inputs = new MyPoint[size]; + + for (int i = 0; i < size; i++) { + inputs[i] = new MyPoint(i, i + 1); + } + return inputs; + } + + public int[] buildIntInputArray() { + int[] inputs = new int[size]; + + for (int i = 0; i < size; i++) { + inputs[i] = i * 4; + } + return inputs; + } + + @Test + public void testForEachIntRangeNoCaptures() { + int[] dest = new int[size]; + IntStream range = IntStream.range(0, dest.length).parallel(); + + // System.out.println("testForEachIntRangeNoCaptures"); + + range.forEach(p -> { + dest[p] = p * factor; + }); + + for (int k = 0; k < dest.length; k++) { + if (k < printSize) { + // System.out.println(k + " ... " + dest[k]); + } + assertTrue(dest[k] == k * factor); + } + } + + @Test + public void testForEachIntRangeNoCapturesUseStatic() { + int[] dest = new int[size]; + IntStream range = IntStream.range(0, dest.length).parallel(); + + // System.out.println("testForEachIntRangeNoCapturesUseStatic"); + + range.forEach(p -> { + dest[p] = p * staticFactor; + }); + + for (int k = 0; k < dest.length; k++) { + if (k < printSize) { + // System.out.println(k + " ... " + dest[k]); + } + assertTrue(dest[k] == k * staticFactor); + } + } + + @Test + public void testForEachIntRangeOneCapture() { + int[] dest = new int[size]; + IntStream range = IntStream.range(0, dest.length).parallel(); + int[] data = buildIntInputArray(); + + range.forEach(p -> { + dest[p] = p * factor + data[p]; + }); + + for (int k = 0; k < dest.length; k++) { + if (k < printSize) { + // System.out.println(k + " ... " + dest[k]); + } + assertTrue(dest[k] == k * 3 + data[k]); + } + + } + + @Test + public void testForEachIntRangeOneCaptureUseStatic() { + int[] dest = new int[size]; + IntStream range = IntStream.range(0, dest.length).parallel(); + int[] data = buildIntInputArray(); + + range.forEach(p -> { + dest[p] = p * staticFactor + data[p]; + }); + + for (int k = 0; k < dest.length; k++) { + // System.out.println( k + " ... " + dest[k] ); + assertTrue(dest[k] == k * staticFactor + data[k]); + } + + } + + @Test + public void testForEachObjectStreamNoCaptures() { + MyPoint[] inputs = buildMyPointInputArray(); + + Arrays.stream(inputs).parallel().forEach(p -> { + // Swap the values + int tmp = p.x; + p.x = p.y + factor; + p.y = tmp; + }); + + for (int k = 0; k < size; k++) { + MyPoint p = inputs[k]; + // System.out.println( k + " ... p.x=" + p.x ); + assertTrue(p.x == (p.y + 1 + factor)); + } + } + + @Test + public void testForEachObjectStreamNoCapturesUseStatic() { + MyPoint[] inputs = buildMyPointInputArray(); + + Arrays.stream(inputs).parallel().forEach(p -> { + // Swap the values + int tmp = p.x; + p.x = p.y + staticFactor; + p.y = tmp; + }); + + for (int k = 0; k < size; k++) { + MyPoint p = inputs[k]; + // System.out.println( k + " ... p.x=" + p.x ); + assertTrue(p.x == (p.y + 1 + staticFactor)); + } + } + + @Test + public void testForEachObjectStreamOneCapture() { + MyPoint[] inputs = buildMyPointInputArray(); + int[] data = buildIntInputArray(); + + Arrays.stream(inputs).parallel().forEach(p -> { + p.y = data[p.x]; + }); + + for (int k = 0; k < size; k++) { + MyPoint p = inputs[k]; + // System.out.println( k + " ... p.x=" + p.x ); + assertTrue(p.y == data[p.x]); + } + + } + + @Test + public void testForEachObjectStreamOneCaptureUseStatic() { + MyPoint[] inputs = buildMyPointInputArray(); + int[] data = buildIntInputArray(); + + Arrays.stream(inputs).parallel().forEach(p -> { + p.y = data[p.x] + staticFactor; + }); + + for (int k = 0; k < size; k++) { + MyPoint p = inputs[k]; + // System.out.println( k + " ... p.x=" + p.x ); + assertTrue(p.y == (data[p.x] + +staticFactor)); + } + + } + + @Test + public void testForEachObjectStreamTwoCaptures() { + MyPoint[] inputs = buildMyPointInputArray(); + int[] data = buildIntInputArray(); + int[] data2 = buildIntInputArray(); + + Arrays.stream(inputs).parallel().forEach(p -> { + p.y = data[p.x] + data2[p.x]; + }); + + for (int k = 0; k < size; k++) { + MyPoint p = inputs[k]; + // System.out.println( k + " ... p.x=" + p.x ); + assertTrue(p.y == data[p.x] + data2[p.x]); + } + + } + + @Test + public void testForEachObjectStreamTwoCapturesUseStatic() { + MyPoint[] inputs = buildMyPointInputArray(); + int[] data = buildIntInputArray(); + int[] data2 = buildIntInputArray(); + + Arrays.stream(inputs).parallel().forEach(p -> { + p.y = data[p.x] + data2[p.x] + staticFactor; + }); + + for (int k = 0; k < size; k++) { + MyPoint p = inputs[k]; + // System.out.println( k + " ... p.x=" + p.x ); + assertTrue(p.y == data[p.x] + data2[p.x] + staticFactor); + } + + } + + // This test should fall back to the regular Java path if + // Graal throws NYI + @Test + public void testForEachIntRangeNoCapturesUseEscapingNew() { + MyPoint[] dest = new MyPoint[size]; + IntStream range = IntStream.range(0, dest.length).parallel(); + + range.forEach(p -> { + dest[p] = new MyPoint(p + p, p); + }); + + for (int k = 0; k < dest.length; k++) { + if (k < printSize) { + // System.out.println(k + " ... " + dest[k]); + } + assertTrue(dest[k].getX() == (k + k)); + } + } + + // This test should fall back to the regular Java path if + // Graal throws NYI + @Test + public void testForEachIntRangeNoCapturesUseCall() { + MyPoint[] dest = new MyPoint[size]; + ArrayList list = new ArrayList<>(size); + IntStream range = IntStream.range(0, dest.length).parallel(); + + for (int i = 0; i < dest.length; i++) { + list.add(new MyPoint(i + i, i)); + } + + range.forEach(p -> { + dest[p] = list.get(p); + }); + + for (int k = 0; k < dest.length; k++) { + if (k < printSize) { + // System.out.println(k + " ... " + dest[k]); + } + assertTrue(dest[k].getX() == (k + k)); + } + } + // public static void main(String args[]) { + // (new ForEachToGraalTest()).testForEachIntRange(); + // } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/HashMapGetTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/HashMapGetTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2009, 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.compiler.hsail.test.lambda; + +import static com.oracle.graal.debug.Debug.*; + +import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester; +import com.oracle.graal.debug.*; + +import java.util.HashMap; + +import org.junit.Test; + +/** + * Tests calling HashMap.get(). + */ +public class HashMapGetTest extends GraalKernelTester { + + static final int NUM = 20; + + static class MyObj { + public MyObj(int id) { + this.id = id; + } + + int id; + + public int getId() { + return id; + } + + @Override + public boolean equals(Object other) { + if (!(other instanceof MyObj)) { + return false; + } + MyObj othobj = (MyObj) other; + return (othobj.id == this.id); + } + + @Override + public int hashCode() { + return 43 * (id % 7); + } + + } + + @Result public MyObj[] outArray = new MyObj[NUM]; + MyObj[] inArray = new MyObj[NUM]; + public HashMap inMap = new HashMap<>(); + + void setupArrays() { + for (int i = 0; i < NUM; i++) { + MyObj myobj = new MyObj(i); + inMap.put(myobj, new MyObj(i * 3)); + inArray[NUM - 1 - i] = myobj; + outArray[i] = null; + } + } + + @Override + public void runTest() { + setupArrays(); + + dispatchLambdaKernel(NUM, (gid) -> { + outArray[gid] = inMap.get(inArray[gid]); + }); + } + + // ForeignCall to Invoke#Direct#get + // not inlining HashMapGetTest.lambda$38@15: java.util.HashMap.get(Object):Object (20 bytes): no + // type profile exists + @Test(expected = com.oracle.graal.compiler.common.GraalInternalError.class) + public void test() { + try (DebugConfigScope s = disableIntercept()) { + testGeneratedHsail(); + } + } + + @Test(expected = com.oracle.graal.compiler.common.GraalInternalError.class) + public void testUsingLambdaMethod() { + try (DebugConfigScope s = disableIntercept()) { + testGeneratedHsailUsingLambdaMethod(); + } + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/InstanceNBodyTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/InstanceNBodyTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2009, 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.compiler.hsail.test.lambda; + +import java.util.*; +import org.junit.*; +import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester; + +/** + * Test intstream lambda version of nbody. + */ +public class InstanceNBodyTest extends GraalKernelTester { + + static final int bodies = 1024; + static final float delT = .005f; + static final float espSqr = 1.0f; + static final float mass = 5f; + static final int width = 768; + static final int height = 768; + + @Result float[] in_xyz = new float[bodies * 3]; // positions xy and z of bodies + + @Result float[] out_xyz = new float[bodies * 3]; // positions xy and z of bodies + + @Result float[] in_vxyz = new float[bodies * 3]; // velocity component of x,y and z of + // bodies + + @Result float[] out_vxyz = new float[bodies * 3]; + + static float[] seed_xyz = new float[bodies * 3]; + static { + final float maxDist = width / 4; + for (int body = 0; body < (bodies * 3); body += 3) { + final float theta = (float) (Math.random() * Math.PI * 2); + final float phi = (float) (Math.random() * Math.PI * 2); + final float radius = (float) (Math.random() * maxDist); + seed_xyz[body + 0] = (float) (radius * Math.cos(theta) * Math.sin(phi)) + width / 2; + seed_xyz[body + 1] = (float) (radius * Math.sin(theta) * Math.sin(phi)) + height / 2; + seed_xyz[body + 2] = (float) (radius * Math.cos(phi)); + } + } + + @Override + public void runTest() { + System.arraycopy(seed_xyz, 0, in_xyz, 0, seed_xyz.length); + Arrays.fill(out_xyz, 0f); + Arrays.fill(out_vxyz, 0f); + Arrays.fill(in_vxyz, 0f); + + // no local copies to make it an instance lambda + + dispatchLambdaKernel(bodies, (gid) -> { + final int count = bodies * 3; + final int globalId = gid * 3; + + float accx = 0.f; + float accy = 0.f; + float accz = 0.f; + for (int i = 0; i < count; i += 3) { + final float dx = in_xyz[i + 0] - in_xyz[globalId + 0]; + final float dy = in_xyz[i + 1] - in_xyz[globalId + 1]; + final float dz = in_xyz[i + 2] - in_xyz[globalId + 2]; + final float invDist = (float) (1.0 / (Math.sqrt((dx * dx) + (dy * dy) + (dz * dz) + espSqr))); + accx += mass * invDist * invDist * invDist * dx; + accy += mass * invDist * invDist * invDist * dy; + accz += mass * invDist * invDist * invDist * dz; + } + accx *= delT; + accy *= delT; + accz *= delT; + out_xyz[globalId + 0] = in_xyz[globalId + 0] + (in_vxyz[globalId + 0] * delT) + (accx * .5f * delT); + out_xyz[globalId + 1] = in_xyz[globalId + 1] + (in_vxyz[globalId + 1] * delT) + (accy * .5f * delT); + out_xyz[globalId + 2] = in_xyz[globalId + 2] + (in_vxyz[globalId + 2] * delT) + (accz * .5f * delT); + + out_vxyz[globalId + 0] = in_vxyz[globalId + 0] + accx; + out_vxyz[globalId + 1] = in_vxyz[globalId + 1] + accy; + out_vxyz[globalId + 2] = in_vxyz[globalId + 2] + accz; + }); + } + + @Test + public void test() { + testGeneratedHsail(); + } + + @Test + public void testUsingLambdaMethod() { + testGeneratedHsailUsingLambdaMethod(); + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/InstanceOfNullTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/InstanceOfNullTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2009, 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.compiler.hsail.test.lambda; + +import org.junit.Test; + +/** + * Tests instanceof operator on a null object. + */ +public class InstanceOfNullTest extends VirtualCallTest { + + @Override + public void runTest() { + setupArrays(); + // change some of the inShapes to null + for (int i = 0; i < NUM; i++) { + if (i % 3 == 0) + inShapeArray[i] = null; + } + + dispatchLambdaKernel(NUM, (gid) -> { + outArray[gid] = (inShapeArray[gid] instanceof Circle ? 1.0f : 2.0f); + }); + } + + @Override + @Test + public void test() { + testGeneratedHsail(); + } + + @Override + @Test + public void testUsingLambdaMethod() { + testGeneratedHsailUsingLambdaMethod(); + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/InstanceOfTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/InstanceOfTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2009, 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.compiler.hsail.test.lambda; + +import org.junit.Test; + +/** + * Tests instanceof operator. + */ +public class InstanceOfTest extends VirtualCallTest { + + @Override + public void runTest() { + setupArrays(); + + dispatchLambdaKernel(NUM, (gid) -> { + outArray[gid] = (inShapeArray[gid] instanceof Circle ? 1.0f : 2.0f); + }); + } + + @Override + @Test + public void test() { + testGeneratedHsail(); + } + + @Override + @Test + public void testUsingLambdaMethod() { + testGeneratedHsailUsingLambdaMethod(); + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/InstanceOopNBodyAccTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/InstanceOopNBodyAccTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2009, 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.compiler.hsail.test.lambda; + +import org.junit.*; +import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester; +import com.oracle.graal.compiler.hsail.test.Vec3; + +/** + * Tests Oop NBody calling a method that returns acceleration. + */ +public class InstanceOopNBodyAccTest extends GraalKernelTester { + + static final int bodies = 1024; + static final float delT = .005f; + static final float espSqr = 1.0f; + static final float mass = 5f; + static final int width = 768; + static final int height = 768; + + static class Body extends com.oracle.graal.compiler.hsail.test.lambda.Body { + + public Body(float x, float y, float z, float m) { + super(x, y, z, m); + } + + public Vec3 computeAcc(Body[] in_bodies, float espSqr1, float delT1) { + float accx = 0.f; + float accy = 0.f; + float accz = 0.f; + float myPosx = x; + float myPosy = y; + float myPosz = z; + + for (int b = 0; b < in_bodies.length; b++) { + float dx = in_bodies[b].getX() - myPosx; + float dy = in_bodies[b].getY() - myPosy; + float dz = in_bodies[b].getZ() - myPosz; + float invDist = 1.0f / (float) Math.sqrt((dx * dx) + (dy * dy) + (dz * dz) + espSqr1); + float s = in_bodies[b].getM() * invDist * invDist * invDist; + accx = accx + (s * dx); + accy = accy + (s * dy); + accz = accz + (s * dz); + } + + // now return acc as a Vec3 + return new Vec3(accx * delT1, accy * delT1, accz * delT1); + } + } + + @Result Body[] in_bodies = new Body[bodies]; + @Result Body[] out_bodies = new Body[bodies]; + + static Body[] seed_bodies = new Body[bodies]; + static { + final float maxDist = width / 4; + for (int body = 0; body < bodies; body++) { + final float theta = (float) (Math.random() * Math.PI * 2); + final float phi = (float) (Math.random() * Math.PI * 2); + final float radius = (float) (Math.random() * maxDist); + float x = (float) (radius * Math.cos(theta) * Math.sin(phi)) + width / 2; + float y = (float) (radius * Math.sin(theta) * Math.sin(phi)) + height / 2; + float z = (float) (radius * Math.cos(phi)); + seed_bodies[body] = new Body(x, y, z, mass); + } + } + + @Override + public void runTest() { + System.arraycopy(seed_bodies, 0, in_bodies, 0, seed_bodies.length); + for (int b = 0; b < bodies; b++) { + out_bodies[b] = new Body(0, 0, 0, mass); + } + // no local copies of arrays so we make it an instance lambda + + dispatchLambdaKernel(bodies, (gid) -> { + Body bin = in_bodies[gid]; + Body bout = out_bodies[gid]; + Vec3 acc = bin.computeAcc(in_bodies, espSqr, delT); + + float myPosx = bin.getX(); + float myPosy = bin.getY(); + float myPosz = bin.getZ(); + bout.setX(myPosx + (bin.getVx() * delT) + (acc.x * .5f * delT)); + bout.setY(myPosy + (bin.getVy() * delT) + (acc.y * .5f * delT)); + bout.setZ(myPosz + (bin.getVz() * delT) + (acc.z * .5f * delT)); + + bout.setVx(bin.getVx() + acc.x); + bout.setVy(bin.getVy() + acc.y); + bout.setVz(bin.getVz() + acc.z); + }); + } + + @Test + public void test() { + testGeneratedHsail(); + } + + @Test + public void testUsingLambdaMethod() { + testGeneratedHsailUsingLambdaMethod(); + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/InstanceOopNBodyTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/InstanceOopNBodyTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2009, 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.compiler.hsail.test.lambda; + +import org.junit.*; +import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester; + +/** + * Tests OopStream NBody as an instance lambda. + */ +public class InstanceOopNBodyTest extends GraalKernelTester { + + static final int bodies = 1024; + static final float delT = .005f; + static final float espSqr = 1.0f; + static final float mass = 5f; + static final int width = 768; + static final int height = 768; + + @Result Body[] in_bodies = new Body[bodies]; + + @Result Body[] out_bodies = new Body[bodies]; + + static Body[] seed_bodies = new Body[bodies]; + static { + final float maxDist = width / 4; + for (int body = 0; body < bodies; body++) { + final float theta = (float) (Math.random() * Math.PI * 2); + final float phi = (float) (Math.random() * Math.PI * 2); + final float radius = (float) (Math.random() * maxDist); + float x = (float) (radius * Math.cos(theta) * Math.sin(phi)) + width / 2; + float y = (float) (radius * Math.sin(theta) * Math.sin(phi)) + height / 2; + float z = (float) (radius * Math.cos(phi)); + seed_bodies[body] = new Body(x, y, z, mass); + } + } + + @Override + public void runTest() { + System.arraycopy(seed_bodies, 0, in_bodies, 0, seed_bodies.length); + for (int b = 0; b < bodies; b++) { + out_bodies[b] = new Body(0, 0, 0, mass); + } + // no local copies of arrays so we make it an instance lambda + + dispatchLambdaKernel(bodies, (gid) -> { + float accx = 0.f; + float accy = 0.f; + float accz = 0.f; + Body inb = in_bodies[gid]; + Body outb = out_bodies[gid]; + float myPosx = inb.getX(); + float myPosy = inb.getY(); + float myPosz = inb.getZ(); + + for (Body b : in_bodies) { + final float dx = b.getX() - myPosx; + final float dy = b.getY() - myPosy; + final float dz = b.getZ() - myPosz; + final float invDist = 1.0f / (float) Math.sqrt((dx * dx) + (dy * dy) + (dz * dz) + espSqr); + final float s = b.getM() * invDist * invDist * invDist; + accx = accx + (s * dx); + accy = accy + (s * dy); + accz = accz + (s * dz); + } + + accx = accx * delT; + accy = accy * delT; + accz = accz * delT; + outb.setX(myPosx + (inb.getVx() * delT) + (accx * .5f * delT)); + outb.setY(myPosy + (inb.getVy() * delT) + (accy * .5f * delT)); + outb.setZ(myPosz + (inb.getVz() * delT) + (accz * .5f * delT)); + + outb.setVx(inb.getVx() + accx); + outb.setVy(inb.getVy() + accy); + outb.setVz(inb.getVz() + accz); + }); + } + + @Test + public void test() { + testGeneratedHsail(); + } + + @Test + public void testUsingLambdaMethod() { + testGeneratedHsailUsingLambdaMethod(); + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/IntCondMoveTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/IntCondMoveTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2009, 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.compiler.hsail.test.lambda; + +import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester; +import org.junit.Test; + +/** + * Tests conditional move of an int value. + */ +public class IntCondMoveTest extends GraalKernelTester { + + static final int NUM = 20; + @Result public int[] outArray = new int[NUM]; + public int[] inArray = new int[NUM]; + + void setupArrays() { + for (int i = 0; i < NUM; i++) { + inArray[i] = i; + outArray[i] = -i; + } + } + + @Override + public void runTest() { + setupArrays(); + + dispatchLambdaKernel(NUM, (gid) -> { + outArray[gid] = inArray[gid] * (gid > 9 ? 2 : 3); + }); + } + + @Test + public void test() { + testGeneratedHsail(); + } + + @Test + public void testUsingLambdaMethod() { + testGeneratedHsailUsingLambdaMethod(); + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/IntFieldAccessTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/IntFieldAccessTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2009, 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.compiler.hsail.test.lambda; + +import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester; +import org.junit.Test; + +/** + * Tests accessing an integer field. + */ +public class IntFieldAccessTest extends GraalKernelTester { + + static final int NUM = 20; + @Result public int[] outArray = new int[NUM]; + public int[] inArray = new int[NUM]; + + int intField = 7; + + void setupArrays() { + for (int i = 0; i < NUM; i++) { + inArray[i] = i; + outArray[i] = -i; + } + } + + @Override + public void runTest() { + setupArrays(); + + int[] out = outArray; + int[] in = inArray; + dispatchLambdaKernel(NUM, (gid) -> { + out[gid] = in[gid] + intField; + }); + } + + @Test + public void test() { + testGeneratedHsail(); + } + + @Test + public void testUsingLambdaMethod() { + testGeneratedHsailUsingLambdaMethod(); + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/IntNegateInstanceTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/IntNegateInstanceTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2009, 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.compiler.hsail.test.lambda; + +import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester; +import org.junit.Test; + +/** + * Tests integer negation. + */ +public class IntNegateInstanceTest extends GraalKernelTester { + + static final int NUM = 20; + @Result public int[] outArray = new int[NUM]; + public int[] inArray = new int[NUM]; + + void setupArrays() { + for (int i = 0; i < NUM; i++) { + inArray[i] = i; + outArray[i] = 0; + } + } + + @Override + public void runTest() { + setupArrays(); + + dispatchLambdaKernel(NUM, (gid) -> { + outArray[gid] = -inArray[gid]; + }); + } + + @Test + public void test() { + testGeneratedHsail(); + } + + @Test + public void testUsingLambdaMethod() { + testGeneratedHsailUsingLambdaMethod(); + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/IntSquaredInstanceTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/IntSquaredInstanceTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2009, 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.compiler.hsail.test.lambda; + +import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester; +import org.junit.Test; + +/** + * Tests squaring an integer as an instance lambda. + */ +public class IntSquaredInstanceTest extends GraalKernelTester { + + static final int NUM = 20; + @Result public int[] outArray = new int[NUM]; + public int[] inArray = new int[NUM]; + + void setupArrays() { + for (int i = 0; i < NUM; i++) { + inArray[i] = i; + outArray[i] = -i; + } + } + + @Override + public void runTest() { + setupArrays(); + + dispatchLambdaKernel(NUM, (gid) -> { + outArray[gid] = inArray[gid] * inArray[gid] + 1; + }); + } + + @Test + public void test() { + testGeneratedHsail(); + } + + @Test + public void testUsingLambdaMethod() { + testGeneratedHsailUsingLambdaMethod(); + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/IntSquaredStaticTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/IntSquaredStaticTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2009, 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.compiler.hsail.test.lambda; + +import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester; +import org.junit.Test; + +/** + * Tests squaring an integer as a static lambda. + */ +public class IntSquaredStaticTest extends GraalKernelTester { + + static final int NUM = 20; + @Result public int[] outArray = new int[NUM]; + public int[] inArray = new int[NUM]; + + void setupArrays() { + for (int i = 0; i < NUM; i++) { + inArray[i] = i; + outArray[i] = -i; + } + } + + @Override + public void runTest() { + setupArrays(); + + int[] out = outArray; + int[] in = inArray; + dispatchLambdaKernel(NUM, (gid) -> { + out[gid] = in[gid] * in[gid] + 1; + }); + } + + @Test + public void test() { + testGeneratedHsail(); + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/IntToLongTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/IntToLongTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2009, 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.compiler.hsail.test.lambda; + +import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester; +import org.junit.Test; + +/** + * Tests conversion an int to a long. + */ +public class IntToLongTest extends GraalKernelTester { + + static final int NUM = 20; + @Result public long[] outArray = new long[NUM]; + public int[] inArray = new int[NUM]; + + void setupArrays() { + for (int i = 0; i < NUM; i++) { + inArray[i] = ((i + 1) * (i % 3 == 0 ? 1 : -1)); + outArray[i] = 99; + } + } + + @Override + public void runTest() { + setupArrays(); + + dispatchLambdaKernel(NUM, (gid) -> { + outArray[gid] = inArray[gid]; + }); + } + + @Test + public void test() { + testGeneratedHsail(); + } + + @Test + public void testUsingLambdaMethod() { + testGeneratedHsailUsingLambdaMethod(); + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/IntegerObjectCreateTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/IntegerObjectCreateTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2009, 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.compiler.hsail.test.lambda; + +import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester; +import org.junit.Test; + +/** + * Tests allocation of an Integer object. + */ +public class IntegerObjectCreateTest extends GraalKernelTester { + + static final int NUM = 20; + @Result public Integer[] outArray = new Integer[NUM]; + public Integer[] inArray = new Integer[NUM]; + + void setupArrays() { + for (int i = 0; i < NUM; i++) { + inArray[i] = i; + outArray[i] = -i; + } + } + + @Override + public void runTest() { + setupArrays(); + + dispatchLambdaKernel(NUM, (gid) -> { + int val = inArray[gid]; + outArray[gid] = val * val + 1; + }); + } + + @Override + protected boolean supportsRequiredCapabilities() { + return canHandleObjectAllocation(); + } + + @Test + public void test() { + testGeneratedHsail(); + } + + @Test + public void testUsingLambdaMethod() { + testGeneratedHsailUsingLambdaMethod(); + } +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/IntegerObjectReadTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/IntegerObjectReadTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2009, 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.compiler.hsail.test.lambda; + +import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester; +import org.junit.Test; + +/** + * Tests reading and unboxing of an Integer object. + */ +public class IntegerObjectReadTest extends GraalKernelTester { + + static final int NUM = 20; + @Result public int[] outArray = new int[NUM]; + public Integer[] inArray = new Integer[NUM]; + + void setupArrays() { + for (int i = 0; i < NUM; i++) { + inArray[i] = i; + outArray[i] = -i; + } + } + + @Override + public void runTest() { + setupArrays(); + + dispatchLambdaKernel(NUM, (gid) -> { + int val = inArray[gid]; + outArray[gid] = val * val + 1; + }); + } + + @Test + public void test() { + testGeneratedHsail(); + } + + @Test + public void testUsingLambdaMethod() { + testGeneratedHsailUsingLambdaMethod(); + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/LongAdderTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/LongAdderTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2009, 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.compiler.hsail.test.lambda; + +import static com.oracle.graal.debug.Debug.*; +import static com.oracle.graal.debug.DelegatingDebugConfig.Feature.*; + +import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester; +import com.oracle.graal.debug.*; +import java.util.concurrent.atomic.LongAdder; + +import org.junit.Test; + +/** + * Tests calling LongAdder.add(). + */ +public class LongAdderTest extends GraalKernelTester { + + static final int NUM = 20; + @Result public long finalSum; + LongAdder adder = new LongAdder(); + + void setupArrays() { + } + + @Override + public void runTest() { + setupArrays(); + + dispatchLambdaKernel(NUM, (gid) -> { + adder.add(gid); + }); + + finalSum = adder.sum(); + } + + // cannot handle node: CurrentJavaThread + @Test(expected = com.oracle.graal.compiler.common.GraalInternalError.class) + public void test() { + try (DebugConfigScope dcs = setConfig(new DelegatingDebugConfig().disable(INTERCEPT))) { + testGeneratedHsail(); + } + } + + @Test(expected = com.oracle.graal.compiler.common.GraalInternalError.class) + public void testUsingLambdaMethod() { + try (DebugConfigScope dcs = setConfig(new DelegatingDebugConfig().disable(INTERCEPT))) { + testGeneratedHsailUsingLambdaMethod(); + } + } +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/LongCmpTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/LongCmpTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2009, 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.compiler.hsail.test.lambda; + +import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester; +import org.junit.Test; + +/** + * Tests comparing a long to a constant. + */ +public class LongCmpTest extends GraalKernelTester { + + static final int NUM = 20; + @Result public long[] outArray = new long[NUM]; + public long[] inArray = new long[NUM]; + + void setupArrays() { + for (int i = 0; i < NUM; i++) { + inArray[i] = i; + outArray[i] = -i; + } + } + + @Override + public void runTest() { + setupArrays(); + + dispatchLambdaKernel(NUM, (gid) -> { + long val = inArray[gid]; + long result = val * val; + if (val > 9) + result++; + outArray[gid] = result; + }); + } + + @Test + public void test() { + testGeneratedHsail(); + } + + @Test + public void testUsingLambdaMethod() { + testGeneratedHsailUsingLambdaMethod(); + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/LongCondMoveTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/LongCondMoveTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2009, 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.compiler.hsail.test.lambda; + +import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester; +import org.junit.Test; + +/** + * Tests conditional move of a long value. + */ +public class LongCondMoveTest extends GraalKernelTester { + + static final int NUM = 20; + @Result public long[] outArray = new long[NUM]; + public long[] inArray = new long[NUM]; + + void setupArrays() { + for (int i = 0; i < NUM; i++) { + inArray[i] = i; + outArray[i] = -i; + } + } + + @Override + public void runTest() { + setupArrays(); + + dispatchLambdaKernel(NUM, (gid) -> { + outArray[gid] = inArray[gid] * (gid > 9 ? 0x123456789L : 0x123456780L); + }); + } + + @Test + public void test() { + testGeneratedHsail(); + } + + @Test + public void testUsingLambdaMethod() { + testGeneratedHsailUsingLambdaMethod(); + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/LongNegateInstanceTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/LongNegateInstanceTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2009, 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.compiler.hsail.test.lambda; + +import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester; +import org.junit.Test; + +/** + * Tests negation of a long. + */ +public class LongNegateInstanceTest extends GraalKernelTester { + + static final int NUM = 20; + @Result public long[] outArray = new long[NUM]; + public long[] inArray = new long[NUM]; + + void setupArrays() { + for (int i = 0; i < NUM; i++) { + inArray[i] = i; + outArray[i] = 0; + } + } + + @Override + public void runTest() { + setupArrays(); + + dispatchLambdaKernel(NUM, (gid) -> { + outArray[gid] = -inArray[gid]; + }); + } + + @Test + public void test() { + testGeneratedHsail(); + } + + @Test + public void testUsingLambdaMethod() { + testGeneratedHsailUsingLambdaMethod(); + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/LongSquaredInstanceTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/LongSquaredInstanceTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2009, 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.compiler.hsail.test.lambda; + +import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester; +import org.junit.Test; + +/** + * Tests squaring of a long as an instance lambda. + */ +public class LongSquaredInstanceTest extends GraalKernelTester { + + static final int NUM = 20; + @Result public long[] outArray = new long[NUM]; + public long[] inArray = new long[NUM]; + + void setupArrays() { + for (int i = 0; i < NUM; i++) { + inArray[i] = i; + outArray[i] = -i; + } + } + + @Override + public void runTest() { + setupArrays(); + + dispatchLambdaKernel(NUM, (gid) -> { + outArray[gid] = inArray[gid] * inArray[gid] + 1; + }); + } + + @Test + public void test() { + testGeneratedHsail(); + } + + @Test + public void testUsingLambdaMethod() { + testGeneratedHsailUsingLambdaMethod(); + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/Main.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/Main.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2009, 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.compiler.hsail.test.lambda; + +/** + * a place to put a direct call to a test if you don't want to go thru junit. + */ + +public class Main { + + public static void main(String[] args) { + // new StaticIntFieldAccessTest().test(); + } +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/MandelInstanceTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/MandelInstanceTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2009, 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.compiler.hsail.test.lambda; + +import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester; +import org.junit.Test; + +/** + * Tests mandel as an instance lambda. + */ + +public class MandelInstanceTest extends GraalKernelTester { + + static final int WIDTH = 768; + static final int HEIGHT = WIDTH; + static final int maxIterations = 64; + + static final int RANGE = WIDTH * HEIGHT; + @Result public int[] rgb = new int[RANGE]; + int[] palette = new int[256]; + + void setupPalette(int[] in) { + for (int i = 0; i < in.length; i++) { + in[i] = i; + } + } + + @Override + public void runTest() { + setupPalette(palette); + + float x_offset = -1f; + float y_offset = 0f; + float scale = 3f; + + // call it for a range, specifying the lambda + dispatchLambdaKernel(RANGE, (gid) -> { + final int width = WIDTH; + final int height = HEIGHT; + float lx = (((gid % width * scale) - ((scale / 2) * width)) / width) + x_offset; + float ly = (((gid / width * scale) - ((scale / 2) * height)) / height) + y_offset; + + int count = 0; + float zx = lx; + float zy = ly; + float new_zx = 0f; + + // Iterate until the algorithm converges or until maxIterations are reached. + while (count < maxIterations && zx * zx + zy * zy < 8) { + new_zx = zx * zx - zy * zy + lx; + zy = 2 * zx * zy + ly; + zx = new_zx; + count++; + } + + rgb[gid] = palette[count]; + }); + } + + @Test + public void test() { + testGeneratedHsail(); + } + + @Test + public void testUsingLambdaMethod() { + testGeneratedHsailUsingLambdaMethod(); + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/MandelStaticTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/MandelStaticTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2009, 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.compiler.hsail.test.lambda; + +import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester; +import org.junit.Test; + +/** + * Tests static lambda version of Mandel. + */ +public class MandelStaticTest extends GraalKernelTester { + + static final int WIDTH = 768; + static final int HEIGHT = WIDTH; + static final int maxIterations = 64; + + static final int RANGE = WIDTH * HEIGHT; + @Result public int[] rgb = new int[RANGE]; + + void setupPalette(int[] in) { + for (int i = 0; i < in.length; i++) { + in[i] = i; + } + } + + @Override + public void runTest() { + int[] palette = new int[256]; + setupPalette(palette); + + // since we want this to be a fully static lambda, make local copies + // of the arrays and values that will get captured by the lambda + int[] rgb1 = this.rgb; + float x_offset = -1f; + float y_offset = 0f; + float scale = 3f; + + // call it for a range, specifying lambda + dispatchLambdaKernel(RANGE, (gid) -> { + final int width = WIDTH; + final int height = HEIGHT; + float lx = (((gid % width * scale) - ((scale / 2) * width)) / width) + x_offset; + float ly = (((gid / width * scale) - ((scale / 2) * height)) / height) + y_offset; + + int count = 0; + float zx = lx; + float zy = ly; + float new_zx = 0f; + + // Iterate until the algorithm converges or until maxIterations are reached. + while (count < maxIterations && zx * zx + zy * zy < 8) { + new_zx = zx * zx - zy * zy + lx; + zy = 2 * zx * zy + ly; + zx = new_zx; + count++; + } + + rgb1[gid] = palette[count]; + }); + } + + @Test + public void test() { + testGeneratedHsail(); + } + + @Test + public void testUsingLambdaMethod() { + testGeneratedHsailUsingLambdaMethod(); + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/NewStringEqualsTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/NewStringEqualsTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2009, 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.compiler.hsail.test.lambda; + +import static com.oracle.graal.debug.Debug.*; + +import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester; +import com.oracle.graal.debug.*; + +import org.junit.Test; + +/** + * Tests creating a String and calling .equals() on it. + */ +public class NewStringEqualsTest extends GraalKernelTester { + + static final int NUM = 20; + @Result public boolean[] outArray = new boolean[NUM]; + char[] chars = new char[100]; + + void setupArrays() { + for (int i = 0; i < chars.length; i++) { + chars[i] = (char) ('A' + i); + } + for (int i = 0; i < NUM; i++) { + } + } + + @Override + public void runTest() { + setupArrays(); + String base = "ABCDEFGHIJ"; + + dispatchLambdaKernel(NUM, (gid) -> { + outArray[gid] = new String(chars, 0, 10 + (gid % 3)).equals(base); + }); + } + + @Override + protected boolean supportsRequiredCapabilities() { + // although not escaping, seems to require object allocation support + return (canHandleObjectAllocation()); + } + + // NYI emitForeignCall charAlignedDisjointArraycopy + @Test(expected = com.oracle.graal.compiler.common.GraalInternalError.class) + public void test() { + try (DebugConfigScope s = disableIntercept()) { + testGeneratedHsail(); + } + } + + @Test(expected = com.oracle.graal.compiler.common.GraalInternalError.class) + public void testUsingLambdaMethod() { + try (DebugConfigScope s = disableIntercept()) { + testGeneratedHsailUsingLambdaMethod(); + } + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/NewStringLenTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/NewStringLenTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2009, 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.compiler.hsail.test.lambda; + +import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester; +import org.junit.Test; + +/** + * Tests creating a String and calling .length() on it. + */ +public class NewStringLenTest extends GraalKernelTester { + + static final int NUM = 20; + @Result public int[] outArray = new int[NUM]; + public int[] inArray = new int[NUM]; + char[] chars = new char[100]; + + void setupArrays() { + for (int i = 0; i < chars.length; i++) { + chars[i] = 'A'; + } + for (int i = 0; i < NUM; i++) { + inArray[i] = i + 10; + outArray[i] = -i; + } + } + + @Override + public void runTest() { + setupArrays(); + + dispatchLambdaKernel(NUM, (gid) -> { + outArray[gid] = Integer.toString(gid).length(); + }); + } + + @Override + protected boolean supportsRequiredCapabilities() { + // although not escaping, seems to require object allocation support + return (canHandleObjectAllocation()); + } + + @Test + public void test() { + testGeneratedHsail(); + } + + @Test + public void testUsingLambdaMethod() { + testGeneratedHsailUsingLambdaMethod(); + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/NonEscapingNewArrayTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/NonEscapingNewArrayTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2009, 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.compiler.hsail.test.lambda; + +import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester; +import org.junit.Test; + +/** + * Tests creating a non-escaping array and using it. + */ +public class NonEscapingNewArrayTest extends GraalKernelTester { + + static final int NUM = 20; + @Result public float[] outArray = new float[NUM]; + + void setupArrays() { + for (int i = 0; i < NUM; i++) { + outArray[i] = -i; + } + } + + @Override + public void runTest() { + setupArrays(); + + dispatchLambdaKernel(NUM, (gid) -> { + float[] ary = {gid, gid + 1, gid + 2}; + outArray[gid] = ary[0] * ary[1] * ary[2]; + }); + } + + @Test + public void test() { + testGeneratedHsail(); + } + + @Test + public void testUsingLambdaMethod() { + testGeneratedHsailUsingLambdaMethod(); + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/NonEscapingNewObjWithArrayTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/NonEscapingNewObjWithArrayTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2009, 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.compiler.hsail.test.lambda; + +import static com.oracle.graal.debug.Debug.*; +import static com.oracle.graal.debug.DelegatingDebugConfig.Feature.*; + +import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester; +import com.oracle.graal.debug.*; + +import org.junit.Test; + +import java.util.Arrays; + +/** + * Tests non-escaping object creation and calling a method on it. + */ +public class NonEscapingNewObjWithArrayTest extends GraalKernelTester { + static final int NUM = 20; + @Result public float[] outArray = new float[NUM]; + + static class MyObj { + float a[]; + + public MyObj(float[] src, int ofst) { + a = Arrays.copyOfRange(src, ofst, ofst + 3); + } + + public float productOf() { + return a[0] * a[1] * a[2]; + } + } + + void setupArrays() { + for (int i = 0; i < NUM; i++) { + outArray[i] = -i; + } + } + + @Override + public void runTest() { + setupArrays(); + float[] fsrc = new float[2 * NUM]; + for (int i = 0; i < 2 * NUM; i++) { + fsrc[i] = i; + } + + dispatchLambdaKernel(NUM, (gid) -> { + outArray[gid] = new MyObj(fsrc, gid).productOf(); + }); + } + + @Override + protected boolean supportsRequiredCapabilities() { + // although not escaping, seems to require object allocation support + return (canHandleObjectAllocation()); + } + + // NYI emitForeignCall floatArraycopy + @Test(expected = com.oracle.graal.compiler.common.GraalInternalError.class) + public void test() { + try (DebugConfigScope s = disableIntercept()) { + testGeneratedHsail(); + } + } + + @Test(expected = com.oracle.graal.compiler.common.GraalInternalError.class) + public void testUsingLambdaMethod() { + try (DebugConfigScope dcs = setConfig(new DelegatingDebugConfig().disable(INTERCEPT))) { + testGeneratedHsailUsingLambdaMethod(); + } + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/NonEscapingNewTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/NonEscapingNewTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2009, 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.compiler.hsail.test.lambda; + +import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester; +import org.junit.Test; +import com.oracle.graal.compiler.hsail.test.Vec3; + +/** + * Tests creation of three non-escaping objects. + */ +public class NonEscapingNewTest extends GraalKernelTester { + + static final int NUM = 20; + @Result public float[] outArray = new float[NUM]; + public Vec3[] inArray = new Vec3[NUM]; + + void setupArrays() { + for (int i = 0; i < NUM; i++) { + inArray[i] = new Vec3(i, i + 1, i + 2); + outArray[i] = -i; + } + } + + @Override + public void runTest() { + setupArrays(); + + dispatchLambdaKernel(NUM, (gid) -> { + Vec3 veca = inArray[gid]; + Vec3 vecb = inArray[(gid + 1) % NUM]; + Vec3 vecresult = Vec3.add(veca, vecb); + outArray[gid] = vecresult.z; + }); + } + + @Test + public void test() { + testGeneratedHsail(); + } + + @Test + public void testUsingLambdaMethod() { + testGeneratedHsailUsingLambdaMethod(); + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/ObjectArrayInstanceDerivedTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/ObjectArrayInstanceDerivedTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2009, 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.compiler.hsail.test.lambda; + +import org.junit.*; + +import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester; + +/** + * Tests calling a method on an object when there are derived types of that object. Note: if you + * enable these tests, not only will these tests fail but other tests like ObjectArrayInstanceTest + * will also fail because they depend on there being no derived classes from Body. + */ +public class ObjectArrayInstanceDerivedTest extends GraalKernelTester { + + static final int NUM = 20; + + class DerivedBody extends Body { + + DerivedBody(float x, float y, float z, float m) { + super(x, y, z, m); + } + + @Override + public float getX() { + return 42.0f; + } + } + + @Result public float[] outArray = new float[NUM]; + public Body[] inBodyArray = new Body[NUM]; + public Body[] unusedBodyArray = new Body[NUM]; + public DerivedBody[] unusedDerivedBodyArray = new DerivedBody[NUM]; + + void setupArrays() { + for (int i = 0; i < NUM; i++) { + inBodyArray[i] = new Body(i, i + 1, i + 2, i + 3); + // unusedBodyArray[i] = new DerivedBody(i, i+1, i+2, i+3); + outArray[i] = -i; + } + } + + @Override + public void runTest() { + setupArrays(); + + dispatchLambdaKernel(NUM, (gid) -> { + Body b = inBodyArray[gid]; + outArray[gid] = b.getX() * b.getY(); + }); + } + + @Ignore + @Test + public void test() { + testGeneratedHsail(); + } + + @Ignore + @Test + public void testUsingLambdaMethod() { + testGeneratedHsailUsingLambdaMethod(); + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/ObjectArrayInstanceTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/ObjectArrayInstanceTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2009, 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.compiler.hsail.test.lambda; + +import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester; + +import org.junit.*; + +/** + * Tests calling a method on an object when there are no derived types of that object. + */ +public class ObjectArrayInstanceTest extends GraalKernelTester { + + static final int NUM = 20; + + @Result public float[] outArray = new float[NUM]; + public Body[] inBodyArray = new Body[NUM]; + + void setupArrays() { + for (int i = 0; i < NUM; i++) { + inBodyArray[i] = new Body(i, i + 1, i + 2, i + 3); + outArray[i] = -i; + } + } + + @Override + public void runTest() { + setupArrays(); + + dispatchLambdaKernel(NUM, (gid) -> { + Body b = inBodyArray[gid]; + outArray[gid] = b.getX() * b.getY(); + }); + } + + @Ignore + @Test + public void test() { + testGeneratedHsail(); + } + + @Ignore + @Test + public void testUsingLambdaMethod() { + testGeneratedHsailUsingLambdaMethod(); + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/ObjectStoreNullTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/ObjectStoreNullTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2009, 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.compiler.hsail.test.lambda; + +import org.junit.Test; + +/** + * Tests the storing of null in an Object array + */ +public class ObjectStoreNullTest extends ObjectStoreTest { + + @Override + public void runTest() { + setupArrays(); + + dispatchLambdaKernel(NUM, (gid) -> { + outBodyArray[gid] = (gid % 3 == 1 ? null : inBodyArray[gid]); + }); + } + + @Override + @Test + public void test() { + testGeneratedHsail(); + } + + @Override + @Test + public void testUsingLambdaMethod() { + testGeneratedHsailUsingLambdaMethod(); + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/ObjectStoreTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/ObjectStoreTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2009, 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.compiler.hsail.test.lambda; + +import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester; +import org.junit.Test; + +/** + * Tests copying an object from one array to another. + */ +public class ObjectStoreTest extends GraalKernelTester { + + static final int NUM = 20; + + @Result public Body[] outBodyArray = new Body[NUM]; + public Body[] inBodyArray = new Body[NUM]; + + void setupArrays() { + for (int i = 0; i < NUM; i++) { + inBodyArray[i] = new Body(i, i + 1, i + 2, i + 3); + outBodyArray[i] = null; + } + } + + @Override + public void runTest() { + setupArrays(); + + dispatchLambdaKernel(NUM, (gid) -> { + outBodyArray[gid] = inBodyArray[gid]; + }); + } + + @Test + public void test() { + testGeneratedHsail(); + } + + @Test + public void testUsingLambdaMethod() { + testGeneratedHsailUsingLambdaMethod(); + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/OverloadMethodTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/OverloadMethodTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2009, 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.compiler.hsail.test.lambda; + +import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester; +import org.junit.Test; + +/** + * Tests calling methods with the same name but different signatures. + */ +public class OverloadMethodTest extends GraalKernelTester { + + static final int NUM = 20; + @Result public int[] outArray = new int[NUM]; + public int[] inArray = new int[NUM]; + + void setupArrays() { + for (int i = 0; i < NUM; i++) { + inArray[i] = i; + outArray[i] = -i; + } + } + + int addArgs(int a, int b) { + return a + b; + } + + int addArgs(int a, int b, int c) { + return a + b + c; + } + + @Override + public void runTest() { + setupArrays(); + + dispatchLambdaKernel(NUM, (gid) -> { + outArray[gid] = (gid > 9 ? addArgs(inArray[gid], gid + 1) : addArgs(inArray[gid], gid - 1, gid - 2)); + }); + } + + @Test + public void test() { + testGeneratedHsail(); + } + + @Test + public void testUsingLambdaMethod() { + testGeneratedHsailUsingLambdaMethod(); + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/ShortArrayTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/ShortArrayTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2009, 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.compiler.hsail.test.lambda; + +import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester; +import org.junit.Test; + +/** + * Tests accessing an array of shorts. + */ +public class ShortArrayTest extends GraalKernelTester { + + static final int NUM = 20; + @Result public int[] outArray = new int[NUM]; + public short[] inArray = new short[NUM]; + + void setupArrays() { + for (int i = 0; i < NUM; i++) { + inArray[i] = (short) ((i + 1) * (i % 3 == 0 ? 1 : -1)); + outArray[i] = 99; + } + } + + @Override + public void runTest() { + setupArrays(); + + dispatchLambdaKernel(NUM, (gid) -> { + outArray[gid] = inArray[gid]; + }); + } + + @Test + public void test() { + testGeneratedHsail(); + } + + @Test + public void testUsingLambdaMethod() { + testGeneratedHsailUsingLambdaMethod(); + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/StaticFloatFieldReadTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/StaticFloatFieldReadTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2009, 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.compiler.hsail.test.lambda; + +import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester; +import org.junit.Test; + +/** + * Tests reading from a static float field. + */ +public class StaticFloatFieldReadTest extends GraalKernelTester { + + static final int NUM = 20; + @Result public float[] outArray = new float[NUM]; + public float[] inArray = new float[NUM]; + + static float floatField = 7.123f; + + void setupArrays() { + for (int i = 0; i < NUM; i++) { + inArray[i] = i; + outArray[i] = -i; + } + } + + @Override + public void runTest() { + setupArrays(); + + float[] out = outArray; + float[] in = inArray; + dispatchLambdaKernel(NUM, (gid) -> { + out[gid] = in[gid] + floatField; + }); + } + + @Test + public void test() { + testGeneratedHsail(); + } + + @Test + public void testUsingLambdaMethod() { + testGeneratedHsailUsingLambdaMethod(); + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/StaticIntField2ReadTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/StaticIntField2ReadTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2009, 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.compiler.hsail.test.lambda; + +import org.junit.Test; + +/** + * Tests reading from a two static int fields in different classes. + */ +public class StaticIntField2ReadTest extends StaticIntFieldReadTest { + + static int intField2 = 8; + + @Override + public void runTest() { + setupArrays(); + + dispatchLambdaKernel(NUM, (gid) -> { + outArray[gid] = inArray[gid] * intField1 + intField2; + }); + } + + @Override + @Test + public void test() { + testGeneratedHsail(); + } + + @Override + @Test + public void testUsingLambdaMethod() { + testGeneratedHsailUsingLambdaMethod(); + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/StaticIntFieldReadTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/StaticIntFieldReadTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2009, 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.compiler.hsail.test.lambda; + +import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester; +import org.junit.Test; + +/** + * Tests reading from a static int field. + */ +public class StaticIntFieldReadTest extends GraalKernelTester { + + static final int NUM = 20; + @Result public int[] outArray = new int[NUM]; + public int[] inArray = new int[NUM]; + + static int intField1 = 7; + + void setupArrays() { + for (int i = 0; i < NUM; i++) { + inArray[i] = i; + outArray[i] = -i; + } + } + + @Override + public void runTest() { + setupArrays(); + + dispatchLambdaKernel(NUM, (gid) -> { + outArray[gid] = inArray[gid] + intField1; + }); + } + + @Test + public void test() { + testGeneratedHsail(); + } + + @Test + public void testUsingLambdaMethod() { + testGeneratedHsailUsingLambdaMethod(); + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/StaticIntFieldSameClassTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/StaticIntFieldSameClassTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2009, 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.compiler.hsail.test.lambda; + +import org.junit.Test; + +/** + * Tests reading from a two static int fields in the same class. + */ +public class StaticIntFieldSameClassTest extends StaticIntFieldReadTest { + + static int myField1 = 5; + static int myField2 = -99; + @Result int fieldResult; + + @Override + public void runTest() { + setupArrays(); + myField2 = -99; + dispatchLambdaKernel(NUM, (gid) -> { + int val = inArray[gid] * myField1; + outArray[gid] = val; + if (gid == 3) + myField2 = val + gid; + }); + fieldResult = myField2; + } + + @Override + @Test + public void test() { + testGeneratedHsail(); + } + + @Override + @Test + public void testUsingLambdaMethod() { + testGeneratedHsailUsingLambdaMethod(); + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/StaticIntFieldWriteTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/StaticIntFieldWriteTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2009, 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.compiler.hsail.test.lambda; + +import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester; +import org.junit.Test; + +/** + * Tests writing a static int field. + */ +public class StaticIntFieldWriteTest extends GraalKernelTester { + + static final int NUM = 20; + @Result public int[] outArray = new int[NUM]; + public int[] inArray = new int[NUM]; + @Result int fieldResult; + + static int intStaticField = -99; + + void setupArrays() { + for (int i = 0; i < NUM; i++) { + inArray[i] = i; + outArray[i] = -i; + } + } + + @Override + public void runTest() { + setupArrays(); + intStaticField = -99; + dispatchLambdaKernel(NUM, (gid) -> { + outArray[gid] = inArray[gid] * 2; + if (gid == 3) + intStaticField = outArray[gid]; + }); + fieldResult = intStaticField; // save for kerneltester comparison + } + + @Test + public void test() { + testGeneratedHsail(); + } + + @Test + public void testUsingLambdaMethod() { + testGeneratedHsailUsingLambdaMethod(); + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/StaticNBodyTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/StaticNBodyTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2009, 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.compiler.hsail.test.lambda; + +import java.util.*; +import org.junit.*; +import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester; + +/** + * Tests a static lambda version of nbody. + */ +public class StaticNBodyTest extends GraalKernelTester { + + static final int bodies = 1024; + static final float delT = .005f; + static final float espSqr = 1.0f; + static final float mass = 5f; + static final int width = 768; + static final int height = 768; + + @Result float[] in_xyz = new float[bodies * 3]; // positions xy and z of bodies + + @Result float[] out_xyz = new float[bodies * 3]; // positions xy and z of bodies + + @Result float[] in_vxyz = new float[bodies * 3]; // velocity component of x,y and z of + // bodies + + @Result float[] out_vxyz = new float[bodies * 3]; + + static float[] seed_xyz = new float[bodies * 3]; + static { + final float maxDist = width / 4; + for (int body = 0; body < (bodies * 3); body += 3) { + final float theta = (float) (Math.random() * Math.PI * 2); + final float phi = (float) (Math.random() * Math.PI * 2); + final float radius = (float) (Math.random() * maxDist); + seed_xyz[body + 0] = (float) (radius * Math.cos(theta) * Math.sin(phi)) + width / 2; + seed_xyz[body + 1] = (float) (radius * Math.sin(theta) * Math.sin(phi)) + height / 2; + seed_xyz[body + 2] = (float) (radius * Math.cos(phi)); + } + } + + @Override + public void runTest() { + System.arraycopy(seed_xyz, 0, in_xyz, 0, seed_xyz.length); + Arrays.fill(out_xyz, 0f); + Arrays.fill(out_vxyz, 0f); + Arrays.fill(in_vxyz, 0f); + + // local copies for a static lambda + float[] in_xyz1 = this.in_xyz; + float[] out_xyz1 = this.out_xyz; + float[] in_vxyz1 = this.in_vxyz; + float[] out_vxyz1 = this.out_vxyz; + + dispatchLambdaKernel(bodies, (gid) -> { + final int count = bodies * 3; + final int globalId = gid * 3; + + float accx = 0.f; + float accy = 0.f; + float accz = 0.f; + for (int i = 0; i < count; i += 3) { + final float dx = in_xyz1[i + 0] - in_xyz1[globalId + 0]; + final float dy = in_xyz1[i + 1] - in_xyz1[globalId + 1]; + final float dz = in_xyz1[i + 2] - in_xyz1[globalId + 2]; + final float invDist = (float) (1.0 / (Math.sqrt((dx * dx) + (dy * dy) + (dz * dz) + espSqr))); + accx += mass * invDist * invDist * invDist * dx; + accy += mass * invDist * invDist * invDist * dy; + accz += mass * invDist * invDist * invDist * dz; + } + accx *= delT; + accy *= delT; + accz *= delT; + out_xyz1[globalId + 0] = in_xyz1[globalId + 0] + (in_vxyz1[globalId + 0] * delT) + (accx * .5f * delT); + out_xyz1[globalId + 1] = in_xyz1[globalId + 1] + (in_vxyz1[globalId + 1] * delT) + (accy * .5f * delT); + out_xyz1[globalId + 2] = in_xyz1[globalId + 2] + (in_vxyz1[globalId + 2] * delT) + (accz * .5f * delT); + + out_vxyz1[globalId + 0] = in_vxyz1[globalId + 0] + accx; + out_vxyz1[globalId + 1] = in_vxyz1[globalId + 1] + accy; + out_vxyz1[globalId + 2] = in_vxyz1[globalId + 2] + accz; + }); + } + + @Test + public void test() { + testGeneratedHsail(); + } + + @Test + public void testUsingLambdaMethod() { + testGeneratedHsailUsingLambdaMethod(); + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/StringContainsTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/StringContainsTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2009, 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.compiler.hsail.test.lambda; + +import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester; +import org.junit.Test; + +/** + * Tests calling String.contains(). + */ +public class StringContainsTest extends GraalKernelTester { + + static final int NUM = 20; + @Result public boolean[] outArray = new boolean[NUM]; + public String[] inArray = new String[NUM]; + + void setupArrays() { + char[] chars = new char[100]; + for (int i = 0; i < chars.length; i++) { + chars[i] = (char) ('A' + i); + } + for (int i = 0; i < NUM; i++) { + inArray[i] = new String(chars, i, 10); + } + } + + @Override + public void runTest() { + setupArrays(); + String base = "CDE"; + + dispatchLambdaKernel(NUM, (gid) -> { + outArray[gid] = inArray[gid].contains(base); + }); + } + + @Test + public void test() { + testGeneratedHsail(); + } + + @Test + public void testUsingLambdaMethod() { + testGeneratedHsailUsingLambdaMethod(); + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/StringEqualsTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/StringEqualsTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2009, 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.compiler.hsail.test.lambda; + +import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester; +import org.junit.Test; + +/** + * Tests calling String.equals(). + */ +public class StringEqualsTest extends GraalKernelTester { + + static final int NUM = 20; + @Result public boolean[] outArray = new boolean[NUM]; + public String[] inArray = new String[NUM]; + + void setupArrays() { + char[] chars = new char[100]; + for (int i = 0; i < chars.length; i++) { + chars[i] = (char) ('A' + i); + } + for (int i = 0; i < NUM; i++) { + inArray[i] = new String(chars, 0, 10 + (i % 3)); + } + } + + @Override + public void runTest() { + setupArrays(); + String base = "ABCDEFGHIJ"; + + dispatchLambdaKernel(NUM, (gid) -> { + outArray[gid] = inArray[gid].equals(base); + }); + } + + @Test + public void test() { + testGeneratedHsail(); + } + + @Test + public void testUsingLambdaMethod() { + testGeneratedHsailUsingLambdaMethod(); + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/StringHashTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/StringHashTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2009, 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.compiler.hsail.test.lambda; + +import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester; +import org.junit.Test; + +/** + * Tests calling String.hashCode(). + */ +public class StringHashTest extends GraalKernelTester { + + static final int NUM = 20; + @Result public int[] outArray = new int[NUM]; + public String[] inArray = new String[NUM]; + + void setupArrays() { + char[] chars = new char[100]; + for (int i = 0; i < chars.length; i++) { + chars[i] = (char) ('A' + i); + } + for (int i = 0; i < NUM; i++) { + inArray[i] = new String(chars, 0, i + 1); + outArray[i] = -i; + } + } + + @Override + public void runTest() { + setupArrays(); + + dispatchLambdaKernel(NUM, (gid) -> { + outArray[gid] = inArray[gid].hashCode(); + }); + } + + @Test + public void test() { + testGeneratedHsail(); + } + + @Test + public void testUsingLambdaMethod() { + testGeneratedHsailUsingLambdaMethod(); + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/StringLenTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/StringLenTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2009, 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.compiler.hsail.test.lambda; + +import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester; +import org.junit.Test; + +/** + * Tests calling String.length(). + */ +public class StringLenTest extends GraalKernelTester { + + static final int NUM = 20; + @Result public int[] outArray = new int[NUM]; + public String[] inArray = new String[NUM]; + + void setupArrays() { + char[] chars = new char[100]; + for (int i = 0; i < chars.length; i++) { + chars[i] = 'A'; + } + for (int i = 0; i < NUM; i++) { + inArray[i] = new String(chars, 0, i + 10); + outArray[i] = -i; + } + } + + @Override + public void runTest() { + setupArrays(); + + dispatchLambdaKernel(NUM, (gid) -> { + outArray[gid] = inArray[gid].length(); + }); + } + + @Test + public void test() { + testGeneratedHsail(); + } + + @Test + public void testUsingLambdaMethod() { + testGeneratedHsailUsingLambdaMethod(); + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/StringUtilsCountMatches2Test.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/StringUtilsCountMatches2Test.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2009, 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.compiler.hsail.test.lambda; + +import static com.oracle.graal.compiler.hsail.test.lambda.StringUtilsCountMatchesTest.*; + +import org.junit.*; + +/** + * Tests calling a method similar to {@code StringUtils.countMatches()} from the Apache commons-lang + * library. The second argument varies per workitem. + */ +public class StringUtilsCountMatches2Test extends CountMatchesBase { + @Override + void setupArrays() { + char[] chars = new char[100]; + for (int i = 0; i < chars.length; i++) { + chars[i] = (char) ('A' + (i % 10)); + } + for (int i = 0; i < NUM; i++) { + inArray[i] = new String(chars, i, (i % 5 + 1)); + } + } + + @Override + public void runTest() { + setupArrays(); + String base = "ABCDE BCDEF CDEFG DEFGH EFGHI FGHIJ ABCDE BCDEF CDEFG DEFGH EFGHI FGHIJ "; + + dispatchLambdaKernel(NUM, (gid) -> { + outArray[gid] = countMatches(base, inArray[gid]); + }); + } + + @Test + public void test() { + testGeneratedHsail(); + } + + @Test + public void testUsingLambdaMethod() { + testGeneratedHsailUsingLambdaMethod(); + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/StringUtilsCountMatchesTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/StringUtilsCountMatchesTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2009, 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.compiler.hsail.test.lambda; + +import org.junit.*; + +/** + * Tests calling a method similar to {@code StringUtils.countMatches()} from the Apache commons-lang + * library. The first argument varies per workitem. + */ +public class StringUtilsCountMatchesTest extends CountMatchesBase { + + public static int countMatches(String str, String sub) { + if (isEmpty(str) || isEmpty(sub)) { + return 0; + } + int count = 0; + int idx = 0; + while ((idx = str.indexOf(sub, idx)) != -1) { + count++; + idx += sub.length(); + } + return count; + } + + private static boolean isEmpty(String str) { + return str == null || str.length() == 0; + } + + @Override + public void runTest() { + setupArrays(); + String base = "CDE"; + + dispatchLambdaKernel(NUM, (gid) -> { + outArray[gid] = countMatches(inArray[gid], base); + }); + } + + @Test + public void test() { + testGeneratedHsail(); + } + + @Test + public void testUsingLambdaMethod() { + testGeneratedHsailUsingLambdaMethod(); + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/SynchronizedMethodTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/SynchronizedMethodTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2009, 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.compiler.hsail.test.lambda; + +import static com.oracle.graal.debug.Debug.*; + +import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester; +import com.oracle.graal.debug.*; + +import org.junit.Test; + +/** + * Tests calling a synchronized method. + */ +public class SynchronizedMethodTest extends GraalKernelTester { + + static final int NUM = 20; + @Result public int[] outArray = new int[NUM]; + public int[] inArray = new int[NUM]; + + void setupArrays() { + for (int i = 0; i < NUM; i++) { + inArray[i] = i; + outArray[i] = -i; + } + } + + synchronized int syncSquare(int n) { + return n * n; + } + + @Override + public void runTest() { + setupArrays(); + + dispatchLambdaKernel(NUM, (gid) -> { + outArray[gid] = syncSquare(inArray[gid]); + }); + } + + // cannot handle the BeginLockScope node + @Test(expected = com.oracle.graal.compiler.common.GraalInternalError.class) + public void test() { + try (DebugConfigScope s = disableIntercept()) { + testGeneratedHsail(); + } + } + + // cannot handle the BeginLockScope node + @Test(expected = com.oracle.graal.compiler.common.GraalInternalError.class) + public void testUsingLambdaMethod() { + try (DebugConfigScope s = disableIntercept()) { + testGeneratedHsailUsingLambdaMethod(); + } + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/TooSimpleNewTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/TooSimpleNewTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2009, 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.compiler.hsail.test.lambda; + +import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester; +import org.junit.Test; +import com.oracle.graal.compiler.hsail.test.Vec3; + +/** + * Tests a very simple non-escaping object allocation. + */ +public class TooSimpleNewTest extends GraalKernelTester { + + static final int NUM = 20; + @Result public float[] outArray = new float[NUM]; + public float[] inArray = new float[NUM]; + + void setupArrays() { + for (int i = 0; i < NUM; i++) { + inArray[i] = i; + outArray[i] = -i; + } + } + + @Override + public void runTest() { + setupArrays(); + + dispatchLambdaKernel(NUM, (gid) -> { + float inval = inArray[gid]; + Vec3 vec3 = new Vec3(inval + 1, inval + 2, inval + 3); + outArray[gid] = vec3.x; + }); + } + + @Test + public void test() { + testGeneratedHsail(); + } + + @Test + public void testUsingLambdaMethod() { + testGeneratedHsailUsingLambdaMethod(); + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/TwoDIntArrayTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/TwoDIntArrayTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2009, 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.compiler.hsail.test.lambda; + +import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester; +import org.junit.Test; + +/** + * Tests reading from a 2-D int array. + */ +public class TwoDIntArrayTest extends GraalKernelTester { + + static final int NUM = 20; + @Result public int[] outArray = new int[NUM]; + public int[][] inArray = new int[NUM][NUM]; + + void setupArrays() { + for (int i = 0; i < NUM; i++) { + for (int j = 0; j < NUM; j++) { + inArray[i][j] = i * j; + } + outArray[i] = -i; + } + } + + @Override + public void runTest() { + setupArrays(); + + dispatchLambdaKernel(NUM, (gid) -> { + outArray[gid] = inArray[gid][gid] + 100; + }); + } + + @Test + public void test() { + testGeneratedHsail(); + } + + @Test + public void testUsingLambdaMethod() { + testGeneratedHsailUsingLambdaMethod(); + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/VarArgsTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/VarArgsTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2009, 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.compiler.hsail.test.lambda; + +import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester; +import org.junit.Test; + +/** + * Tests calling a varargs method. + */ +public class VarArgsTest extends GraalKernelTester { + + static final int NUM = 20; + @Result public int[] outArray = new int[NUM]; + public int[] inArray = new int[NUM]; + + void setupArrays() { + for (int i = 0; i < NUM; i++) { + inArray[i] = i; + outArray[i] = -i; + } + } + + int addArgs(Object... args) { + int sum = 0; + for (Object n : args) { + sum += (Integer) n; + } + return sum; + } + + @Override + public void runTest() { + setupArrays(); + + dispatchLambdaKernel(NUM, (gid) -> { + outArray[gid] = (gid > 9 ? addArgs(gid, gid + 1, gid + 2) : addArgs(inArray[gid], gid - 1, gid - 2, gid - 3)); + }); + } + + @Test + public void test() { + testGeneratedHsail(); + } + + @Test + public void testUsingLambdaMethod() { + testGeneratedHsailUsingLambdaMethod(); + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/Vec3ObjStreamFloatCaptureTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/Vec3ObjStreamFloatCaptureTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2009, 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.compiler.hsail.test.lambda; + +import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester; +import org.junit.Test; +import com.oracle.graal.compiler.hsail.test.Vec3; + +/** + * Tests codegen for a java 8 lambda style object array stream kernel, one float capture. + */ +public class Vec3ObjStreamFloatCaptureTest extends GraalKernelTester { + + static final int NUM = 20; + + @Result public Vec3[] inArray = new Vec3[NUM]; + float baseAdjustment = 0.5f; + + void setupArrays() { + for (int i = 0; i < NUM; i++) { + inArray[i] = new Vec3(i, i + 1, -1); + } + } + + @Override + public void runTest() { + setupArrays(); + float adjustment = baseAdjustment; + dispatchLambdaKernel(inArray, obj -> { + Vec3 vec3 = (Vec3) obj; + vec3.z = vec3.x + vec3.y - adjustment; + }); + } + + @Test + public void test() { + testGeneratedHsail(); + } + + @Test + public void testUsingLambdaMethod() { + testGeneratedHsailUsingLambdaMethod(); + } +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/Vec3ObjStreamIntCaptureTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/Vec3ObjStreamIntCaptureTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2009, 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.compiler.hsail.test.lambda; + +import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester; +import org.junit.Test; +import com.oracle.graal.compiler.hsail.test.Vec3; + +/** + * Tests codegen for a java 8 style object array stream kernel, one int capture. + */ +public class Vec3ObjStreamIntCaptureTest extends GraalKernelTester { + + static final int NUM = 20; + + @Result public Vec3[] inArray = new Vec3[NUM]; + int baseAdjustment = 7; + + void setupArrays() { + for (int i = 0; i < NUM; i++) { + inArray[i] = new Vec3(i, i + 1, -1); + } + } + + @Override + public void runTest() { + setupArrays(); + int adjustment = baseAdjustment; + dispatchLambdaKernel(inArray, obj -> { + Vec3 vec3 = (Vec3) obj; + vec3.z = vec3.x + vec3.y - adjustment; + }); + } + + @Test + public void test() { + testGeneratedHsail(); + } + + @Test + public void testUsingLambdaMethod() { + testGeneratedHsailUsingLambdaMethod(); + } +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/Vec3ObjStreamIntFloatCaptureTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/Vec3ObjStreamIntFloatCaptureTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2009, 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.compiler.hsail.test.lambda; + +import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester; +import org.junit.Test; +import com.oracle.graal.compiler.hsail.test.Vec3; + +/** + * Tests codegen for a java 8 style object array stream kernel, one int and one float capture. + */ +public class Vec3ObjStreamIntFloatCaptureTest extends GraalKernelTester { + + static final int NUM = 20; + + @Result public Vec3[] inArray = new Vec3[NUM]; + int baseAdjustment = 7; + float baseMultiplier = 0.5f; + + void setupArrays() { + for (int i = 0; i < NUM; i++) { + inArray[i] = new Vec3(i, i + 1, -1); + } + } + + @Override + public void runTest() { + setupArrays(); + int adjustment = baseAdjustment; + float multiplier = baseMultiplier; + + dispatchLambdaKernel(inArray, obj -> { + Vec3 vec3 = (Vec3) obj; + vec3.z = (vec3.x + vec3.y - adjustment) * multiplier; + }); + } + + @Test + public void test() { + testGeneratedHsail(); + } + + @Test + public void testUsingLambdaMethod() { + testGeneratedHsailUsingLambdaMethod(); + } +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/Vec3ObjStreamObjCaptureTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/Vec3ObjStreamObjCaptureTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2009, 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.compiler.hsail.test.lambda; + +import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester; +import org.junit.Test; +import com.oracle.graal.compiler.hsail.test.Vec3; + +/** + * Tests codegen for a java 8 lambda style object array stream kernel, one object capture. + */ +public class Vec3ObjStreamObjCaptureTest extends GraalKernelTester { + + static final int NUM = 20; + + @Result public Vec3[] inArray = new Vec3[NUM]; + float baseAdjustment = 0.5f; + + void setupArrays() { + for (int i = 0; i < NUM; i++) { + inArray[i] = new Vec3(i, i + 1, -1); + } + } + + @Override + public void runTest() { + setupArrays(); + Vec3 basevec = new Vec3(1, 2, 3); + dispatchLambdaKernel(inArray, obj -> { + Vec3 vec3 = (Vec3) obj; + vec3.z = vec3.x + vec3.y - basevec.z; + }); + } + + @Test + public void test() { + testGeneratedHsail(); + } + + @Test + public void testUsingLambdaMethod() { + testGeneratedHsailUsingLambdaMethod(); + } +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/Vec3ObjStreamObjFieldTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/Vec3ObjStreamObjFieldTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2009, 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.compiler.hsail.test.lambda; + +import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester; +import org.junit.Test; +import com.oracle.graal.compiler.hsail.test.Vec3; + +/** + * Tests codegen for a java 8 style object array stream kernel. Instance method which accesses an + * object field. + */ +public class Vec3ObjStreamObjFieldTest extends GraalKernelTester { + + static final int NUM = 20; + + @Result public Vec3[] inArray = new Vec3[NUM]; + Vec3 basevec = new Vec3(1, 2, 3); + + void setupArrays() { + for (int i = 0; i < NUM; i++) { + inArray[i] = new Vec3(i, i + 1, -1); + } + } + + @Override + public void runTest() { + setupArrays(); + dispatchLambdaKernel(inArray, obj -> { + Vec3 vec3 = (Vec3) obj; + vec3.z = vec3.x + vec3.y - basevec.z; + }); + } + + @Test + public void test() { + testGeneratedHsail(); + } + + @Test + public void testUsingLambdaMethod() { + testGeneratedHsailUsingLambdaMethod(); + } +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/Vec3ObjStreamTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/Vec3ObjStreamTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2009, 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.compiler.hsail.test.lambda; + +import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester; +import org.junit.Test; +import com.oracle.graal.compiler.hsail.test.Vec3; + +/** + * Tests codegen for a java 8 style object array stream kernel, no captures. + */ +public class Vec3ObjStreamTest extends GraalKernelTester { + + static final int NUM = 20; + + @Result public Vec3[] inArray = new Vec3[NUM]; + + void setupArrays() { + for (int i = 0; i < NUM; i++) { + inArray[i] = new Vec3(i, i + 1, -1); + } + } + + @Override + public void runTest() { + setupArrays(); + dispatchLambdaKernel(inArray, obj -> { + Vec3 vec3 = (Vec3) obj; + vec3.z = vec3.x + vec3.y; + }); + } + + @Test + public void test() { + testGeneratedHsail(); + } + + @Test + public void testUsingLambdaMethod() { + testGeneratedHsailUsingLambdaMethod(); + } +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/VecmathNBodyTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/VecmathNBodyTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2009, 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.compiler.hsail.test.lambda; + +import java.util.*; +import org.junit.*; +import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester; +import javax.vecmath.*; + +/** + * Tests NBody algorithm using the javax.vecmath package (all objects non-escaping). + */ +public class VecmathNBodyTest extends GraalKernelTester { + static final int bodies = 1024; + static final float delT = .005f; + static final float espSqr = 1.0f; + static final float mass = 5f; + static final int width = 768; + static final int height = 768; + + static class Body extends Vector3f { + + /** + * + */ + private static final long serialVersionUID = 1L; + + public Body(float _x, float _y, float _z, float _m) { + super(_x, _y, _z); + m = _m; + v = new Vector3f(0, 0, 0); + } + + float m; + Vector3f v; + + public float getM() { + return m; + } + + public Vector3f computeAcc(Body[] in_bodies, float espSqr1, float delT1) { + Vector3f acc = new Vector3f(); + + for (Body b : in_bodies) { + Vector3f d = new Vector3f(); + d.sub(b, this); + float invDist = 1.0f / (float) Math.sqrt(d.lengthSquared() + espSqr1); + float s = b.getM() * invDist * invDist * invDist; + acc.scaleAdd(s, d, acc); + } + + // now return acc scaled by delT + acc.scale(delT1); + return acc; + } + } + + @Result Body[] in_bodies = new Body[bodies]; + @Result Body[] out_bodies = new Body[bodies]; + + static Body[] seed_bodies = new Body[bodies]; + + static { + java.util.Random randgen = new Random(0); + final float maxDist = width / 4; + for (int body = 0; body < bodies; body++) { + final float theta = (float) (randgen.nextFloat() * Math.PI * 2); + final float phi = (float) (randgen.nextFloat() * Math.PI * 2); + final float radius = randgen.nextFloat() * maxDist; + float x = (float) (radius * Math.cos(theta) * Math.sin(phi)) + width / 2; + float y = (float) (radius * Math.sin(theta) * Math.sin(phi)) + height / 2; + float z = (float) (radius * Math.cos(phi)); + seed_bodies[body] = new Body(x, y, z, mass); + } + } + + @Override + public void runTest() { + System.arraycopy(seed_bodies, 0, in_bodies, 0, seed_bodies.length); + for (int b = 0; b < bodies; b++) { + out_bodies[b] = new Body(0, 0, 0, mass); + } + // no local copies of arrays so we make it an instance lambda + + dispatchLambdaKernel(bodies, (gid) -> { + Body inb = in_bodies[gid]; + Body outb = out_bodies[gid]; + Vector3f acc = inb.computeAcc(in_bodies, espSqr, delT); + + Vector3f tmpPos = new Vector3f(); + tmpPos.scaleAdd(delT, inb.v, inb); + tmpPos.scaleAdd(0.5f * delT, acc, tmpPos); + outb.set(tmpPos); + + outb.v.add(inb.v, acc); + }); + } + + @Override + protected boolean supportsRequiredCapabilities() { + return (canHandleDeoptVirtualObjects()); + } + + @Test + public void test() { + testGeneratedHsail(); + } + + @Test + public void testUsingLambdaMethod() { + testGeneratedHsailUsingLambdaMethod(); + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/VectorStreamTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/VectorStreamTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,190 @@ +/* + * Copyright (c) 2009, 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.compiler.hsail.test.lambda; + +import java.util.Vector; +import java.util.stream.Stream; +import static org.junit.Assert.assertTrue; +import org.junit.Test; + +/** + * Sumatra API tests which use a Stream derived from a Vector. + */ +public class VectorStreamTest { + + // Static and instance fields to test codegen for + // each type of variable + static int staticSize = 16; + final int size = staticSize; + + static int staticFactor = 3; + final int factor = staticFactor; + + class MyPoint { + + int x; + int y; + + public MyPoint(int _x, int _y) { + x = _x; + y = _y; + } + } + + public Vector buildMyPointInputArray() { + Vector inputs = new Vector<>(size); + + for (int i = 0; i < size; i++) { + inputs.add(new MyPoint(i, i + 1)); + } + return inputs; + } + + public int[] buildIntInputArray() { + int[] inputs = new int[size]; + + for (int i = 0; i < size; i++) { + inputs[i] = i * 4; + } + return inputs; + } + + @Test + public void testForEachObjectStreamNoCaptures() { + Vector inputs = buildMyPointInputArray(); + + Stream s = inputs.stream(); + s = s.parallel(); + s.forEach(p -> { + // Swap the values + int tmp = p.x; + p.x = p.y + factor; + p.y = tmp; + }); + + for (int k = 0; k < size; k++) { + MyPoint p = inputs.get(k); + // System.out.println( k + " ... p.x=" + p.x ); + assertTrue(p.x == (p.y + 1 + factor)); + } + } + + @Test + public void testForEachObjectStreamNoCapturesUseStatic() { + Vector inputs = buildMyPointInputArray(); + + Stream s = inputs.stream(); + s = s.parallel(); + s.forEach(p -> { + // Swap the values + int tmp = p.x; + p.x = p.y + staticFactor; + p.y = tmp; + }); + + for (int k = 0; k < size; k++) { + MyPoint p = inputs.get(k); + // System.out.println( k + " ... p.x=" + p.x ); + assertTrue(p.x == (p.y + 1 + staticFactor)); + } + } + + @Test + public void testForEachObjectStreamOneCapture() { + int[] data = buildIntInputArray(); + Vector inputs = buildMyPointInputArray(); + + Stream s = inputs.stream(); + s = s.parallel(); + s.forEach(p -> { + p.y = data[p.x]; + }); + + for (int k = 0; k < size; k++) { + MyPoint p = inputs.get(k); + // System.out.println( k + " ... p.x=" + p.x ); + assertTrue(p.y == data[p.x]); + } + + } + + @Test + public void testForEachObjectStreamOneCaptureUseStatic() { + int[] data = buildIntInputArray(); + Vector inputs = buildMyPointInputArray(); + + Stream s = inputs.stream(); + s = s.parallel(); + s.forEach(p -> { + p.y = data[p.x] + staticFactor; + }); + + for (int k = 0; k < size; k++) { + MyPoint p = inputs.get(k); + // System.out.println( k + " ... p.x=" + p.x ); + assertTrue(p.y == (data[p.x] + +staticFactor)); + } + + } + + @Test + public void testForEachObjectStreamTwoCaptures() { + int[] data = buildIntInputArray(); + int[] data2 = buildIntInputArray(); + Vector inputs = buildMyPointInputArray(); + + Stream s = inputs.stream(); + s = s.parallel(); + s.forEach(p -> { + p.y = data[p.x] + data2[p.x]; + }); + + for (int k = 0; k < size; k++) { + MyPoint p = inputs.get(k); + // System.out.println( k + " ... p.x=" + p.x ); + assertTrue(p.y == data[p.x] + data2[p.x]); + } + + } + + @Test + public void testForEachObjectStreamTwoCapturesUseStatic() { + int[] data = buildIntInputArray(); + int[] data2 = buildIntInputArray(); + Vector inputs = buildMyPointInputArray(); + + Stream s = inputs.stream(); + s = s.parallel(); + s.forEach(p -> { + p.y = data[p.x] + data2[p.x] + staticFactor; + }); + + for (int k = 0; k < size; k++) { + MyPoint p = inputs.get(k); + // System.out.println( k + " ... p.x=" + p.x ); + assertTrue(p.y == data[p.x] + data2[p.x] + staticFactor); + } + + } +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/VirtualCallTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/VirtualCallTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2009, 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.compiler.hsail.test.lambda; + +import static com.oracle.graal.debug.Debug.*; + +import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester; +import com.oracle.graal.debug.*; + +import org.junit.Test; + +/** + * Tests a true virtual method call. + */ +public class VirtualCallTest extends GraalKernelTester { + + static final int NUM = 20; + + static abstract class Shape { + + abstract public float getArea(); + } + + static class Circle extends Shape { + + private float radius; + + Circle(float r) { + radius = r; + } + + @Override + public float getArea() { + return (float) (Math.PI * radius * radius); + } + } + + static class Square extends Shape { + + private float len; + + Square(float _len) { + len = _len; + } + + @Override + public float getArea() { + return len * len; + } + } + + @Result public float[] outArray = new float[NUM]; + public Shape[] inShapeArray = new Shape[NUM]; + + void setupArrays() { + for (int i = 0; i < NUM; i++) { + if (i % 2 == 0) + inShapeArray[i] = new Circle(i + 1); + else + inShapeArray[i] = new Square(i + 1); + outArray[i] = -i; + } + } + + @Override + public void runTest() { + setupArrays(); + + dispatchLambdaKernel(NUM, (gid) -> { + Shape shape = inShapeArray[gid]; + outArray[gid] = shape.getArea(); + }); + } + + // graal says not inlining getArea():float (0 bytes): no type profile exists + @Test(expected = com.oracle.graal.compiler.common.GraalInternalError.class) + public void test() { + try (DebugConfigScope s = disableIntercept()) { + testGeneratedHsail(); + } + } + + @Test(expected = com.oracle.graal.compiler.common.GraalInternalError.class) + public void testUsingLambdaMethod() { + try (DebugConfigScope s = disableIntercept()) { + testGeneratedHsailUsingLambdaMethod(); + } + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILLIRGenerator.java --- a/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILLIRGenerator.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILLIRGenerator.java Wed Apr 23 15:48:38 2014 +0200 @@ -31,10 +31,11 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.*; -import com.oracle.graal.compiler.gen.*; -import com.oracle.graal.graph.*; +import com.oracle.graal.compiler.common.*; +import com.oracle.graal.compiler.common.calc.*; import com.oracle.graal.lir.*; import com.oracle.graal.lir.StandardOp.JumpOp; +import com.oracle.graal.lir.gen.*; import com.oracle.graal.lir.hsail.*; import com.oracle.graal.lir.hsail.HSAILArithmetic.ConvertOp; import com.oracle.graal.lir.hsail.HSAILArithmetic.Op1Stack; @@ -50,9 +51,6 @@ import com.oracle.graal.lir.hsail.HSAILMove.MembarOp; import com.oracle.graal.lir.hsail.HSAILMove.MoveFromRegOp; import com.oracle.graal.lir.hsail.HSAILMove.MoveToRegOp; -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.calc.*; -import com.oracle.graal.nodes.calc.FloatConvertNode.FloatConvert; import com.oracle.graal.phases.util.*; /** @@ -93,7 +91,7 @@ @Override public Variable emitMove(Value input) { - Variable result = newVariable(input.getKind()); + Variable result = newVariable(input.getPlatformKind()); emitMove(result, input); return result; } @@ -148,8 +146,7 @@ finalDisp += asConstant(index).asLong() * scale; } else { Value indexRegister; - Value convertedIndex; - convertedIndex = this.emitSignExtend(index, 32, 64); + Value convertedIndex = index.getKind() == Kind.Long ? index : this.emitSignExtend(index, 32, 64); if (scale != 1) { indexRegister = emitUMul(convertedIndex, Constant.forInt(scale)); } else { @@ -221,7 +218,9 @@ @Override public void emitIntegerTestBranch(Value left, Value right, LabelRef trueDestination, LabelRef falseDestination, double trueDestinationProbability) { - throw GraalInternalError.unimplemented(); + Variable result = emitAnd(left, right); + Variable dummyResult = newVariable(left.getKind()); + append(new CompareBranchOp(mapKindToCompareOp(left.getKind()), Condition.EQ, result, Constant.forInt(0), dummyResult, dummyResult, trueDestination, falseDestination, false)); } @Override @@ -415,7 +414,7 @@ } @Override - public Value emitDiv(Value a, Value b, DeoptimizingNode deopting) { + public Value emitDiv(Value a, Value b, LIRFrameState state) { Variable result = newVariable(a.getKind()); switch (a.getKind()) { case Int: @@ -438,7 +437,7 @@ } @Override - public Value emitRem(Value a, Value b, DeoptimizingNode deopting) { + public Value emitRem(Value a, Value b, LIRFrameState state) { Variable result = newVariable(a.getKind()); switch (a.getKind()) { case Int: @@ -460,12 +459,12 @@ } @Override - public Variable emitUDiv(Value a, Value b, DeoptimizingNode deopting) { + public Variable emitUDiv(Value a, Value b, LIRFrameState state) { throw GraalInternalError.unimplemented(); } @Override - public Variable emitURem(Value a, Value b, DeoptimizingNode deopting) { + public Variable emitURem(Value a, Value b, LIRFrameState state) { throw GraalInternalError.unimplemented(); } @@ -683,7 +682,7 @@ } @Override - public void emitDeoptimize(Value actionAndReason, Value speculation, DeoptimizingNode deopting) { + public void emitDeoptimize(Value actionAndReason, Value speculation, LIRFrameState state) { append(new ReturnOp(Value.ILLEGAL)); } @@ -830,7 +829,7 @@ * Graal generates for any switch construct appearing in Java bytecode. */ @Override - protected void emitStrategySwitch(Constant[] keyConstants, double[] keyProbabilities, LabelRef[] keyTargets, LabelRef defaultTarget, Variable value) { + public void emitStrategySwitch(Constant[] keyConstants, double[] keyProbabilities, LabelRef[] keyTargets, LabelRef defaultTarget, Variable value) { emitStrategySwitch(new SwitchStrategy.SequentialStrategy(keyProbabilities, keyConstants), value, keyTargets, defaultTarget); } @@ -855,7 +854,7 @@ * @param key the key that is compared against the key constants in the case statements. */ @Override - protected void emitStrategySwitch(SwitchStrategy strategy, Variable key, LabelRef[] keyTargets, LabelRef defaultTarget) { + public void emitStrategySwitch(SwitchStrategy strategy, Variable key, LabelRef[] keyTargets, LabelRef defaultTarget) { if ((key.getKind() == Kind.Int) || (key.getKind() == Kind.Long)) { // Append the LIR instruction for generating compare and branch instructions. append(new StrategySwitchOp(strategy, keyTargets, defaultTarget, key)); diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILNodeLIRBuilder.java --- a/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILNodeLIRBuilder.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILNodeLIRBuilder.java Wed Apr 23 15:48:38 2014 +0200 @@ -24,13 +24,13 @@ package com.oracle.graal.compiler.hsail; import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.common.*; +import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.compiler.gen.*; -import com.oracle.graal.debug.*; -import com.oracle.graal.graph.*; import com.oracle.graal.lir.*; +import com.oracle.graal.lir.gen.*; import com.oracle.graal.lir.hsail.*; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.type.*; /** * This class implements the HSAIL specific portion of the LIR generator. @@ -63,20 +63,16 @@ } @Override - public void visitSafepointNode(SafepointNode i) { - Debug.log("visitSafePointNode unimplemented"); - } - - @Override public void emitNullCheck(ValueNode v, DeoptimizingNode deopting) { assert v.stamp() instanceof ObjectStamp; Variable obj = newVariable(Kind.Object); gen.emitMove(obj, operand(v)); - append(new HSAILMove.NullCheckOp(obj, gen.state(deopting))); + append(new HSAILMove.NullCheckOp(obj, state(deopting))); } @Override public void visitInfopointNode(InfopointNode i) { + // TODO Auto-generated method stub throw GraalInternalError.unimplemented(); } } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/ControlPTXTest.java --- a/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/ControlPTXTest.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/ControlPTXTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -35,6 +35,7 @@ test("testIfElse2I", 19, 64); } + @Ignore("PTXHotSpotLIRGenerator.emitCompress is unimplemented") @Test public void testControl2() { compileKernel("testStatic"); diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/ObjectPTXTest.java --- a/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/ObjectPTXTest.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/ObjectPTXTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -151,7 +151,7 @@ @Ignore("Object return values not yet supported") @Test public void test9() { - for (Object o : new Object[]{null, "object", new Object(), new HashMap()}) { + for (Object o : new Object[]{null, "object", new Object(), new HashMap<>()}) { A a = new A(); a.o = o; test("testObject", a); diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXLIRGenerator.java --- a/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXLIRGenerator.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXLIRGenerator.java Wed Apr 23 15:48:38 2014 +0200 @@ -32,10 +32,12 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.*; -import com.oracle.graal.compiler.gen.*; -import com.oracle.graal.graph.*; +import com.oracle.graal.compiler.common.*; +import com.oracle.graal.compiler.common.calc.*; +import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.lir.*; import com.oracle.graal.lir.StandardOp.JumpOp; +import com.oracle.graal.lir.gen.*; import com.oracle.graal.lir.ptx.*; import com.oracle.graal.lir.ptx.PTXArithmetic.ConvertOp; import com.oracle.graal.lir.ptx.PTXArithmetic.Op1Stack; @@ -57,11 +59,6 @@ import com.oracle.graal.lir.ptx.PTXMemOp.StoreReturnValOp; import com.oracle.graal.lir.ptx.PTXMove.MoveFromRegOp; import com.oracle.graal.lir.ptx.PTXMove.MoveToRegOp; -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.calc.*; -import com.oracle.graal.nodes.calc.FloatConvertNode.FloatConvert; -import com.oracle.graal.nodes.extended.*; -import com.oracle.graal.nodes.type.*; import com.oracle.graal.phases.util.*; /** @@ -232,25 +229,17 @@ } @Override - public Variable emitLoad(PlatformKind kind, Value address, Access access) { + public Variable emitLoad(PlatformKind kind, Value address, LIRFrameState state) { PTXAddressValue loadAddress = asAddress(address); Variable result = newVariable(kind); - LIRFrameState state = null; - if (access instanceof DeoptimizingNode) { - state = state((DeoptimizingNode) access); - } append(new LoadOp((Kind) kind, result, loadAddress, state)); return result; } @Override - public void emitStore(PlatformKind kind, Value address, Value inputVal, Access access) { + public void emitStore(PlatformKind kind, Value address, Value inputVal, LIRFrameState state) { PTXAddressValue storeAddress = asAddress(address); Variable input = load(inputVal); - LIRFrameState state = null; - if (access instanceof DeoptimizingNode) { - state = state((DeoptimizingNode) access); - } append(new StoreOp((Kind) kind, storeAddress, input, state)); } @@ -376,7 +365,6 @@ @Override public Variable emitIntegerTestMove(Value left, Value right, Value trueValue, Value falseValue) { - emitIntegerTest(left, right); Variable result = newVariable(trueValue.getKind()); append(new CondMoveOp(result, Condition.EQ, load(trueValue), loadNonConst(falseValue), nextPredRegNum)); @@ -386,7 +374,6 @@ } private void emitIntegerTest(Value a, Value b) { - assert a.getKind().isNumericInteger(); if (LIRValueUtil.isVariable(b)) { @@ -498,7 +485,7 @@ } @Override - public Value emitDiv(Value a, Value b, DeoptimizingNode deopting) { + public Value emitDiv(Value a, Value b, LIRFrameState state) { Variable result = newVariable(a.getKind()); switch (a.getKind()) { case Int: @@ -520,7 +507,7 @@ } @Override - public Value emitRem(Value a, Value b, DeoptimizingNode deopting) { + public Value emitRem(Value a, Value b, LIRFrameState state) { Variable result = newVariable(a.getKind()); switch (a.getKind()) { case Int: @@ -536,12 +523,12 @@ } @Override - public Variable emitUDiv(Value a, Value b, DeoptimizingNode deopting) { + public Variable emitUDiv(Value a, Value b, LIRFrameState state) { throw GraalInternalError.unimplemented("PTXLIRGenerator.emitUDiv()"); } @Override - public Variable emitURem(Value a, Value b, DeoptimizingNode deopting) { + public Variable emitURem(Value a, Value b, LIRFrameState state) { throw GraalInternalError.unimplemented("PTXLIRGenerator.emitURem()"); } @@ -555,7 +542,6 @@ case Long: append(new Op2Stack(LAND, result, a, loadNonConst(b))); break; - default: throw GraalInternalError.shouldNotReachHere("missing: " + a.getKind()); } @@ -754,7 +740,7 @@ } @Override - public void emitDeoptimize(Value actionAndReason, Value speculation, DeoptimizingNode deopting) { + public void emitDeoptimize(Value actionAndReason, Value speculation, LIRFrameState state) { append(new ReturnOp(Value.ILLEGAL)); } @@ -830,13 +816,12 @@ @Override public void emitReturn(Value input) { - AllocatableValue operand = Value.ILLEGAL; if (input != null) { - operand = resultOperandFor(input.getKind()); + AllocatableValue operand = resultOperandFor(input.getKind()); // Load the global memory address from return parameter Variable loadVar = emitLoadReturnAddress(operand.getKind(), operand, null); - // Store result in global memory whose location is loadVar - emitStoreReturnValue(operand.getKind(), loadVar, operand, null); + // Store input in global memory whose location is loadVar + emitStoreReturnValue(operand.getKind(), loadVar, input, null); } emitReturnNoVal(); } @@ -846,7 +831,7 @@ } @Override - protected void emitStrategySwitch(SwitchStrategy strategy, Variable key, LabelRef[] keyTargets, LabelRef defaultTarget) { + public void emitStrategySwitch(SwitchStrategy strategy, Variable key, LabelRef[] keyTargets, LabelRef defaultTarget) { boolean needsTemp = key.getKind() == Kind.Object; append(new StrategySwitchOp(strategy, keyTargets, defaultTarget, key, needsTemp ? newVariable(key.getKind()) : Value.ILLEGAL, nextPredRegNum++)); } @@ -864,17 +849,16 @@ throw GraalInternalError.unimplemented("PTXLIRGenerator.emitUnwind()"); } - public Variable emitLoadParam(Kind kind, Value address, DeoptimizingNode deopting) { + public Variable emitLoadParam(Kind kind, Value address, LIRFrameState state) { PTXAddressValue loadAddress = asAddress(address); Variable result = newVariable(kind); - append(new LoadParamOp(kind, result, loadAddress, deopting != null ? state(deopting) : null)); + append(new LoadParamOp(kind, result, loadAddress, state)); return result; } - public Variable emitLoadReturnAddress(Kind kind, Value address, DeoptimizingNode deopting) { - + public Variable emitLoadReturnAddress(Kind kind, Value address, LIRFrameState state) { PTXAddressValue loadAddress = asAddress(address); Variable result; switch (kind) { @@ -886,18 +870,16 @@ break; default: result = newVariable(kind); - } - append(new LoadReturnAddrOp(kind, result, loadAddress, deopting != null ? state(deopting) : null)); + append(new LoadReturnAddrOp(kind, result, loadAddress, state)); return result; } - public void emitStoreReturnValue(Kind kind, Value address, Value inputVal, DeoptimizingNode deopting) { - + public void emitStoreReturnValue(Kind kind, Value address, Value inputVal, LIRFrameState state) { PTXAddressValue storeAddress = asAddress(address); Variable input = load(inputVal); - append(new StoreReturnValOp(kind, storeAddress, input, deopting != null ? state(deopting) : null)); + append(new StoreReturnValOp(kind, storeAddress, input, state)); } @Override @@ -908,4 +890,8 @@ return (new Variable(kind, 0)); } + public Value emitCompareAndSwap(Value address, Value expectedValue, Value newValue, Value trueValue, Value falseValue) { + throw GraalInternalError.unimplemented(); + } + } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXNodeLIRBuilder.java --- a/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXNodeLIRBuilder.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXNodeLIRBuilder.java Wed Apr 23 15:48:38 2014 +0200 @@ -27,13 +27,13 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.common.*; import com.oracle.graal.compiler.gen.*; import com.oracle.graal.debug.*; -import com.oracle.graal.graph.*; import com.oracle.graal.lir.*; +import com.oracle.graal.lir.gen.*; import com.oracle.graal.lir.ptx.*; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.java.*; /** * This class implements the PTX specific portion of the LIR generator. @@ -122,11 +122,6 @@ } @Override - public void visitCompareAndSwap(LoweredCompareAndSwapNode node, Value address) { - throw GraalInternalError.unimplemented("PTXLIRGenerator.visitCompareAndSwap()"); - } - - @Override public void visitBreakpointNode(BreakpointNode node) { throw GraalInternalError.unimplemented("PTXLIRGenerator.visitBreakpointNode()"); } @@ -141,7 +136,7 @@ @Override public void emitNullCheck(ValueNode v, DeoptimizingNode deopting) { assert v.getKind() == Kind.Object; - append(new PTXMove.NullCheckOp(gen.load(operand(v)), gen.state(deopting))); + append(new PTXMove.NullCheckOp(gen.load(operand(v)), state(deopting))); } @Override diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java --- a/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java Wed Apr 23 15:48:38 2014 +0200 @@ -33,10 +33,12 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.*; import com.oracle.graal.asm.sparc.*; -import com.oracle.graal.compiler.gen.*; -import com.oracle.graal.graph.*; +import com.oracle.graal.compiler.common.*; +import com.oracle.graal.compiler.common.calc.*; +import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.lir.*; import com.oracle.graal.lir.StandardOp.JumpOp; +import com.oracle.graal.lir.gen.*; import com.oracle.graal.lir.sparc.*; import com.oracle.graal.lir.sparc.SPARCArithmetic.BinaryCommutative; import com.oracle.graal.lir.sparc.SPARCArithmetic.BinaryRegConst; @@ -57,10 +59,6 @@ import com.oracle.graal.lir.sparc.SPARCMove.MoveFromRegOp; import com.oracle.graal.lir.sparc.SPARCMove.MoveToRegOp; import com.oracle.graal.lir.sparc.SPARCMove.StackLoadAddressOp; -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.calc.*; -import com.oracle.graal.nodes.calc.FloatConvertNode.FloatConvert; -import com.oracle.graal.nodes.type.*; import com.oracle.graal.phases.util.*; /** @@ -362,7 +360,7 @@ } @Override - protected void emitStrategySwitch(SwitchStrategy strategy, Variable key, LabelRef[] keyTargets, LabelRef defaultTarget) { + public void emitStrategySwitch(SwitchStrategy strategy, Variable key, LabelRef[] keyTargets, LabelRef defaultTarget) { // a temp is needed for loading long and object constants boolean needsTemp = key.getKind() == Kind.Long || key.getKind() == Kind.Object; append(new StrategySwitchOp(strategy, keyTargets, defaultTarget, key, needsTemp ? newVariable(key.getKind()) : Value.ILLEGAL)); @@ -593,7 +591,7 @@ } @Override - public Value emitDiv(Value a, Value b, DeoptimizingNode deopting) { + public Value emitDiv(Value a, Value b, LIRFrameState state) { Variable result = newVariable(a.getKind()); switch (a.getKind().getStackKind()) { case Int: @@ -615,8 +613,7 @@ } @Override - public Value emitRem(Value a, Value b, DeoptimizingNode deopting) { - LIRFrameState state = state(deopting); + public Value emitRem(Value a, Value b, LIRFrameState state) { Variable result = newVariable(a.getKind()); switch (a.getKind().getStackKind()) { case Int: @@ -632,7 +629,7 @@ } @Override - public Value emitUDiv(Value a, Value b, DeoptimizingNode deopting) { + public Value emitUDiv(Value a, Value b, LIRFrameState state) { // LIRFrameState state = state(deopting); switch (a.getKind().getStackKind()) { case Int: @@ -647,7 +644,7 @@ } @Override - public Value emitURem(Value a, Value b, DeoptimizingNode deopting) { + public Value emitURem(Value a, Value b, LIRFrameState state) { // LIRFrameState state = state(deopting); switch (a.getKind().getStackKind()) { case Int: @@ -917,7 +914,7 @@ } @Override - public void emitDeoptimize(Value actionAndReason, Value speculation, DeoptimizingNode deopting) { + public void emitDeoptimize(Value actionAndReason, Value speculation, LIRFrameState state) { append(new ReturnOp(Value.ILLEGAL)); } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCNodeLIRBuilder.java --- a/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCNodeLIRBuilder.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCNodeLIRBuilder.java Wed Apr 23 15:48:38 2014 +0200 @@ -25,11 +25,12 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.common.*; import com.oracle.graal.compiler.gen.*; +import com.oracle.graal.lir.gen.*; import com.oracle.graal.lir.sparc.*; import com.oracle.graal.lir.sparc.SPARCMove.NullCheckOp; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.java.*; /** * This class implements the SPARC specific portion of the LIR generator. @@ -47,11 +48,6 @@ } @Override - public void visitCompareAndSwap(LoweredCompareAndSwapNode i, Value address) { - throw new InternalError("NYI"); - } - - @Override public void visitBreakpointNode(BreakpointNode node) { JavaType[] sig = new JavaType[node.arguments().size()]; for (int i = 0; i < sig.length; i++) { @@ -65,11 +61,12 @@ @Override public void emitNullCheck(ValueNode v, DeoptimizingNode deopting) { assert v.getKind() == Kind.Object; - append(new NullCheckOp(gen.load(operand(v)), gen.state(deopting))); + append(new NullCheckOp(gen.load(operand(v)), state(deopting))); } @Override public void visitInfopointNode(InfopointNode i) { - throw new InternalError("NYI"); + // TODO Auto-generated method stub + throw GraalInternalError.unimplemented(); } } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/CheckGraalInvariants.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/CheckGraalInvariants.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/CheckGraalInvariants.java Wed Apr 23 15:48:38 2014 +0200 @@ -22,6 +22,8 @@ */ package com.oracle.graal.compiler.test; +import static com.oracle.graal.debug.DelegatingDebugConfig.Feature.*; + import java.io.*; import java.lang.reflect.*; import java.util.*; @@ -33,7 +35,6 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.api.runtime.*; import com.oracle.graal.debug.*; -import com.oracle.graal.debug.internal.*; import com.oracle.graal.java.*; import com.oracle.graal.nodes.*; import com.oracle.graal.phases.*; @@ -42,15 +43,16 @@ import com.oracle.graal.phases.util.*; import com.oracle.graal.phases.verify.*; import com.oracle.graal.runtime.*; +import com.oracle.graal.test.*; /** * Checks that all classes in graal.jar (which must be on the class path) comply with global * invariants such as using {@link Object#equals(Object)} to compare certain types instead of * identity comparisons. */ -public class CheckGraalInvariants { +public class CheckGraalInvariants extends GraalTest { - @Test + @LongTest public void test() { RuntimeProvider rt = Graal.getRequiredCapability(RuntimeProvider.class); Providers providers = rt.getHostBackend().getProviders(); @@ -106,14 +108,7 @@ String methodName = className + "." + m.getName(); if (matches(filters, methodName)) { StructuredGraph graph = new StructuredGraph(metaAccess.lookupJavaMethod(m)); - DebugConfig debugConfig = DebugScope.getConfig(); - DebugConfig noInterceptConfig = new DelegatingDebugConfig(debugConfig) { - @Override - public RuntimeException interceptException(Throwable e) { - return null; - } - }; - try (DebugConfigScope s = Debug.setConfig(noInterceptConfig)) { + try (DebugConfigScope s = Debug.setConfig(new DelegatingDebugConfig().disable(INTERCEPT))) { graphBuilderSuite.apply(graph, context); checkGraph(context, graph); } catch (VerificationError e) { diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionTest.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -29,7 +29,7 @@ import org.junit.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.nodes.calc.*; +import com.oracle.graal.compiler.common.calc.*; public class ConditionTest { diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FinalizableSubclassTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FinalizableSubclassTest.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FinalizableSubclassTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -59,7 +59,7 @@ } } - private StructuredGraph parseAndProcess(Class cl, Assumptions assumptions) { + private StructuredGraph parseAndProcess(Class cl, Assumptions assumptions) { Constructor[] constructors = cl.getConstructors(); Assert.assertTrue(constructors.length == 1); final ResolvedJavaMethod javaMethod = getMetaAccess().lookupJavaConstructor(constructors[0]); @@ -73,7 +73,7 @@ return graph; } - private void checkForRegisterFinalizeNode(Class cl, boolean shouldContainFinalizer, boolean optimistic) { + private void checkForRegisterFinalizeNode(Class cl, boolean shouldContainFinalizer, boolean optimistic) { Assumptions assumptions = new Assumptions(optimistic); StructuredGraph graph = parseAndProcess(cl, assumptions); Assert.assertTrue(graph.getNodes().filter(RegisterFinalizerNode.class).count() == (shouldContainFinalizer ? 1 : 0)); @@ -109,7 +109,7 @@ private static int loaderInstance = 0; private final String replaceTo; - private HashMap cache = new HashMap<>(); + private HashMap> cache = new HashMap<>(); public ClassTemplateLoader() { loaderInstance++; @@ -149,7 +149,7 @@ } dumpStringsInByteArray(classData); - Class c = defineClass(null, classData, 0, classData.length); + Class c = defineClass(null, classData, 0, classData.length); cache.put(nameReplaced, c); return c; } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -24,8 +24,8 @@ import static com.oracle.graal.api.code.CodeUtil.*; import static com.oracle.graal.compiler.GraalCompiler.*; +import static com.oracle.graal.compiler.common.GraalOptions.*; import static com.oracle.graal.nodes.ConstantNode.*; -import static com.oracle.graal.phases.GraalOptions.*; import java.io.*; import java.lang.reflect.*; @@ -38,8 +38,10 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.code.CallingConvention.Type; import com.oracle.graal.api.meta.*; +import com.oracle.graal.api.replacements.*; import com.oracle.graal.api.runtime.*; import com.oracle.graal.baseline.*; +import com.oracle.graal.compiler.common.*; import com.oracle.graal.compiler.target.*; import com.oracle.graal.debug.*; import com.oracle.graal.debug.Debug.Scope; @@ -168,7 +170,7 @@ protected void assertEquals(StructuredGraph expected, StructuredGraph graph, boolean excludeVirtual, boolean checkConstants) { String expectedString = getCanonicalGraphString(expected, excludeVirtual, checkConstants); String actualString = getCanonicalGraphString(graph, excludeVirtual, checkConstants); - String mismatchString = "mismatch in graphs:\n========= expected =========\n" + expectedString + "\n\n========= actual =========\n" + actualString; + String mismatchString = "mismatch in graphs:\n========= expected (" + expected + ") =========\n" + expectedString + "\n\n========= actual (" + graph + ") =========\n" + actualString; if (!excludeVirtual && getNodeCountExcludingUnusedConstants(expected) != getNodeCountExcludingUnusedConstants(graph)) { Debug.dump(expected, "Node count not matching - expected"); @@ -240,6 +242,10 @@ return providers; } + protected SnippetReflectionProvider getSnippetReflection() { + return Graal.getRequiredCapability(SnippetReflectionProvider.class); + } + protected TargetDescription getTarget() { return getProviders().getCodeCache().getTarget(); } @@ -670,7 +676,7 @@ } protected InstalledCode addMethod(final ResolvedJavaMethod method, final CompilationResult compResult) { - return getCodeCache().addMethod(method, compResult, null); + return getCodeCache().addMethod(method, compResult, null, null); } /** diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MemoryScheduleTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MemoryScheduleTest.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MemoryScheduleTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -22,7 +22,7 @@ */ package com.oracle.graal.compiler.test; -import static com.oracle.graal.phases.GraalOptions.*; +import static com.oracle.graal.compiler.common.GraalOptions.*; import static org.junit.Assert.*; import java.util.*; diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/NestedLoopTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/NestedLoopTest.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/NestedLoopTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -24,6 +24,7 @@ import org.junit.*; +import com.oracle.graal.compiler.common.cfg.*; import com.oracle.graal.debug.*; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; @@ -148,10 +149,10 @@ Debug.dump(graph, "Graph"); ControlFlowGraph cfg = ControlFlowGraph.compute(graph, true, true, true, true); - Assert.assertTrue(cfg.getLoops().length == 3); - Loop rootLoop = cfg.getLoops()[0]; - Loop nestedLoop = cfg.getLoops()[1]; - Loop innerMostLoop = cfg.getLoops()[2]; + Assert.assertTrue(cfg.getLoops().size() == 3); + Loop rootLoop = cfg.getLoops().get(0); + Loop nestedLoop = cfg.getLoops().get(1); + Loop innerMostLoop = cfg.getLoops().get(2); Invoke a = getInvoke("a", graph); Invoke b = getInvoke("b", graph); Invoke c = getInvoke("c", graph); @@ -168,14 +169,14 @@ Debug.dump(graph, "Graph"); } - private static boolean contains(Loop loop, Invoke node, ControlFlowGraph cfg) { + private static boolean contains(Loop loop, Invoke node, ControlFlowGraph cfg) { Block block = cfg.blockFor((Node) node); Assert.assertNotNull(block); return loop.blocks.contains(block); } - private static boolean containsDirect(Loop loop, Invoke node, ControlFlowGraph cfg) { - for (Loop child : loop.children) { + private static boolean containsDirect(Loop loop, Invoke node, ControlFlowGraph cfg) { + for (Loop child : loop.children) { if (contains(child, node, cfg)) { return false; } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/PushNodesThroughPiTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/PushNodesThroughPiTest.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/PushNodesThroughPiTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -26,6 +26,7 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.debug.*; import com.oracle.graal.debug.Debug.Scope; import com.oracle.graal.nodes.*; @@ -71,7 +72,7 @@ for (ReadNode rn : graph.getNodes().filter(ReadNode.class)) { if (rn.location() instanceof ConstantLocationNode && rn.object().stamp() instanceof ObjectStamp) { long disp = ((ConstantLocationNode) rn.location()).getDisplacement(); - ResolvedJavaType receiverType = ObjectStamp.typeOrNull(rn.object()); + ResolvedJavaType receiverType = StampTool.typeOrNull(rn.object()); ResolvedJavaField field = receiverType.findInstanceFieldWithOffset(disp); assert field != null : "Node " + rn + " tries to access a field which doesn't exists for this type"; diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/PushThroughIfTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/PushThroughIfTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,77 @@ +/* + * 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.test; + +import org.junit.*; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.debug.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.util.*; +import com.oracle.graal.phases.common.*; +import com.oracle.graal.phases.tiers.*; + +public class PushThroughIfTest extends GraalCompilerTest { + + public int field1; + public int field2; + + public int testSnippet(boolean b) { + int i; + if (b) { + i = field1; + } else { + i = field1; + } + return i + field2; + } + + @SuppressWarnings("unused") + public int referenceSnippet(boolean b) { + return field1 + field2; + } + + @Test + public void test1() { + test("testSnippet", "referenceSnippet"); + } + + private void test(String snippet, String reference) { + StructuredGraph graph = parse(snippet); + Debug.dump(graph, "Graph"); + for (FrameState fs : graph.getNodes(FrameState.class).snapshot()) { + fs.replaceAtUsages(null); + GraphUtil.killWithUnusedFloatingInputs(fs); + } + new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), new Assumptions(false))); + new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), new Assumptions(false))); + + StructuredGraph referenceGraph = parse(reference); + for (FrameState fs : referenceGraph.getNodes(FrameState.class).snapshot()) { + fs.replaceAtUsages(null); + GraphUtil.killWithUnusedFloatingInputs(fs); + } + new CanonicalizerPhase(true).apply(referenceGraph, new PhaseContext(getProviders(), new Assumptions(false))); + assertEquals(referenceGraph, graph); + } +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/SimpleCFGTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/SimpleCFGTest.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/SimpleCFGTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -41,9 +41,9 @@ AbstractEndNode trueEnd = graph.add(new EndNode()); AbstractEndNode falseEnd = graph.add(new EndNode()); - AbstractBeginNode trueBegin = graph.add(new BeginNode()); + BeginNode trueBegin = graph.add(new BeginNode()); trueBegin.setNext(trueEnd); - AbstractBeginNode falseBegin = graph.add(new BeginNode()); + BeginNode falseBegin = graph.add(new BeginNode()); falseBegin.setNext(falseEnd); IfNode ifNode = graph.add(new IfNode(null, trueBegin, falseBegin, 0.5)); diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/StampCanonicalizerTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/StampCanonicalizerTest.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/StampCanonicalizerTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -25,8 +25,8 @@ import org.junit.*; import com.oracle.graal.api.code.*; +import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.type.*; import com.oracle.graal.phases.common.*; import com.oracle.graal.phases.tiers.*; diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/backend/AllocatorTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/backend/AllocatorTest.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/backend/AllocatorTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -23,7 +23,7 @@ package com.oracle.graal.compiler.test.backend; import static com.oracle.graal.api.code.CodeUtil.*; -import static com.oracle.graal.phases.GraalOptions.*; +import static com.oracle.graal.compiler.common.GraalOptions.*; import java.util.*; @@ -33,15 +33,15 @@ import com.oracle.graal.api.code.CallingConvention.Type; import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.*; -import com.oracle.graal.compiler.gen.*; +import com.oracle.graal.compiler.common.cfg.*; import com.oracle.graal.compiler.test.*; import com.oracle.graal.debug.*; import com.oracle.graal.debug.Debug.Scope; import com.oracle.graal.lir.*; import com.oracle.graal.lir.LIRInstruction.ValueProcedure; import com.oracle.graal.lir.StandardOp.MoveOp; +import com.oracle.graal.lir.gen.*; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.cfg.*; import com.oracle.graal.phases.*; import com.oracle.graal.phases.schedule.*; @@ -114,7 +114,7 @@ SchedulePhase schedule = null; try (Scope s = Debug.scope("FrontEnd")) { schedule = GraalCompiler.emitFrontEnd(getProviders(), getBackend().getTarget(), graph, assumptions, null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.NONE, - graph.method().getProfilingInfo(), new SpeculationLog(), getSuites()); + graph.method().getProfilingInfo(), null, getSuites()); } catch (Throwable e) { throw Debug.handle(e); } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/deopt/CompiledMethodTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/deopt/CompiledMethodTest.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/deopt/CompiledMethodTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -59,8 +59,8 @@ new DeadCodeEliminationPhase().apply(graph); for (ConstantNode node : ConstantNode.getConstantNodes(graph)) { - if (node.getKind() == Kind.Object && " ".equals(node.getValue().asObject())) { - node.replace(graph, ConstantNode.forObject("-", getMetaAccess(), graph)); + if (node.getKind() == Kind.Object && " ".equals(getSnippetReflection().asObject(node.getValue()))) { + node.replace(graph, ConstantNode.forConstant(getSnippetReflection().forObject("-"), getMetaAccess(), graph)); } } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EscapeAnalysisTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EscapeAnalysisTest.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EscapeAnalysisTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -25,10 +25,10 @@ import org.junit.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.graph.*; import com.oracle.graal.loop.phases.*; import com.oracle.graal.nodes.calc.*; -import com.oracle.graal.nodes.type.*; import com.oracle.graal.nodes.virtual.*; import com.oracle.graal.phases.common.*; import com.oracle.graal.phases.schedule.*; @@ -62,7 +62,7 @@ @Test public void test3() { - testEscapeAnalysis("test3Snippet", Constant.forObject(null), false); + testEscapeAnalysis("test3Snippet", Constant.NULL_OBJECT, false); } public static Object test3Snippet() { @@ -257,7 +257,7 @@ @Test public void testCheckCast() { - testEscapeAnalysis("testCheckCastSnippet", Constant.forObject(TestClassObject.class), false); + testEscapeAnalysis("testCheckCastSnippet", getSnippetReflection().forObject(TestClassObject.class), false); } public Object testCheckCastSnippet() { @@ -279,7 +279,7 @@ @SuppressWarnings("unused") public static void testNewNodeSnippet() { - new IntegerAddNode(new IntegerStamp(32, false, Integer.MIN_VALUE, Integer.MAX_VALUE, 0, 0xFFFFFFFF), null, null); + new IntegerAddNode(new IntegerStamp(32, Integer.MIN_VALUE, Integer.MAX_VALUE, 0, 0xFFFFFFFF), null, null); } /** diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PartialEscapeAnalysisTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PartialEscapeAnalysisTest.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PartialEscapeAnalysisTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -120,6 +120,7 @@ } @Test + @Ignore public void testCache() { testPartialEscapeAnalysis("testCacheSnippet", 0.75, 1); } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/UnsafeEATest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/UnsafeEATest.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/UnsafeEATest.java Wed Apr 23 15:48:38 2014 +0200 @@ -27,7 +27,7 @@ import sun.misc.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.graph.*; +import com.oracle.graal.compiler.common.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.java.*; diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/nfi/NativeFunctionInterfaceTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/nfi/NativeFunctionInterfaceTest.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/nfi/NativeFunctionInterfaceTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -22,7 +22,7 @@ */ package com.oracle.graal.compiler.test.nfi; -import static com.oracle.graal.graph.UnsafeAccess.*; +import static com.oracle.graal.compiler.common.UnsafeAccess.*; import static java.io.File.*; import static java.lang.System.*; import static org.junit.Assert.*; diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java Wed Apr 23 15:48:38 2014 +0200 @@ -24,7 +24,7 @@ import static com.oracle.graal.compiler.GraalCompiler.Options.*; import static com.oracle.graal.compiler.MethodFilter.*; -import static com.oracle.graal.phases.GraalOptions.*; +import static com.oracle.graal.compiler.common.GraalOptions.*; import java.util.*; @@ -34,6 +34,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.api.meta.ProfilingInfo.TriState; import com.oracle.graal.compiler.alloc.*; +import com.oracle.graal.compiler.common.cfg.*; import com.oracle.graal.compiler.gen.*; import com.oracle.graal.compiler.target.*; import com.oracle.graal.debug.*; @@ -41,6 +42,7 @@ import com.oracle.graal.debug.internal.*; import com.oracle.graal.lir.*; import com.oracle.graal.lir.asm.*; +import com.oracle.graal.lir.gen.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.cfg.*; import com.oracle.graal.nodes.util.*; @@ -127,9 +129,8 @@ * * @param graph the graph to be compiled * @param cc the calling convention for calls to the code compiled for {@code graph} - * @param installedCodeOwner the method the compiled code will be - * {@linkplain InstalledCode#getMethod() associated} with once installed. This - * argument can be null. + * @param installedCodeOwner the method the compiled code will be associated with once + * installed. This argument can be null. * @return the result of the compilation */ public static T compileGraph(StructuredGraph graph, Object stub, CallingConvention cc, ResolvedJavaMethod installedCodeOwner, Providers providers, Backend backend, diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/Interval.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/Interval.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/Interval.java Wed Apr 23 15:48:38 2014 +0200 @@ -30,8 +30,8 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.common.*; import com.oracle.graal.debug.*; -import com.oracle.graal.graph.*; import com.oracle.graal.lir.*; import com.oracle.graal.phases.util.*; diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java Wed Apr 23 15:48:38 2014 +0200 @@ -35,10 +35,11 @@ import com.oracle.graal.compiler.alloc.Interval.RegisterBinding; import com.oracle.graal.compiler.alloc.Interval.RegisterPriority; import com.oracle.graal.compiler.alloc.Interval.SpillState; +import com.oracle.graal.compiler.common.*; +import com.oracle.graal.compiler.common.cfg.*; import com.oracle.graal.compiler.gen.*; import com.oracle.graal.debug.*; import com.oracle.graal.debug.Debug.Scope; -import com.oracle.graal.graph.*; import com.oracle.graal.lir.*; import com.oracle.graal.lir.LIRInstruction.OperandFlag; import com.oracle.graal.lir.LIRInstruction.OperandMode; @@ -46,7 +47,6 @@ import com.oracle.graal.lir.LIRInstruction.ValueProcedure; import com.oracle.graal.lir.StandardOp.MoveOp; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.cfg.*; import com.oracle.graal.phases.util.*; /** @@ -335,7 +335,7 @@ } int numLoops() { - return ir.getControlFlowGraph().getLoops().length; + return ir.getControlFlowGraph().getLoops().size(); } boolean isIntervalInLoop(int interval, int loop) { @@ -887,6 +887,7 @@ private static NodeLIRBuilder getNodeLIRGeneratorFromDebugContext() { if (Debug.isEnabled()) { NodeLIRBuilder lirGen = Debug.contextLookup(NodeLIRBuilder.class); + assert lirGen != null; return lirGen; } return null; diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScanWalker.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScanWalker.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScanWalker.java Wed Apr 23 15:48:38 2014 +0200 @@ -34,10 +34,10 @@ import com.oracle.graal.compiler.alloc.Interval.RegisterPriority; import com.oracle.graal.compiler.alloc.Interval.SpillState; import com.oracle.graal.compiler.alloc.Interval.State; +import com.oracle.graal.compiler.common.cfg.*; import com.oracle.graal.debug.*; import com.oracle.graal.lir.*; import com.oracle.graal.lir.StandardOp.MoveOp; -import com.oracle.graal.nodes.cfg.*; import com.oracle.graal.phases.util.*; /** diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/RegisterVerifier.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/RegisterVerifier.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/RegisterVerifier.java Wed Apr 23 15:48:38 2014 +0200 @@ -28,13 +28,13 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.common.*; +import com.oracle.graal.compiler.common.cfg.*; import com.oracle.graal.debug.*; -import com.oracle.graal.graph.*; import com.oracle.graal.lir.*; import com.oracle.graal.lir.LIRInstruction.OperandFlag; import com.oracle.graal.lir.LIRInstruction.OperandMode; import com.oracle.graal.lir.LIRInstruction.ValueProcedure; -import com.oracle.graal.nodes.cfg.*; import com.oracle.graal.phases.util.*; /** diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/BytecodeLIRBuilder.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/BytecodeLIRBuilder.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/BytecodeLIRBuilder.java Wed Apr 23 15:48:38 2014 +0200 @@ -22,10 +22,9 @@ */ package com.oracle.graal.compiler.gen; -import java.lang.reflect.*; - import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.lir.gen.*; public class BytecodeLIRBuilder { protected final LIRGenerator gen; @@ -53,7 +52,7 @@ gen.emitIncomingValues(params); Signature sig = method.getSignature(); - boolean isStatic = Modifier.isStatic(method.getModifiers()); + boolean isStatic = method.isStatic(); for (int i = 0; i < sig.getParameterCount(!isStatic); i++) { Value paramValue = params[i]; assert paramValue.getKind() == sig.getParameterKind(i).getStackKind(); diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/DebugInfoBuilder.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/DebugInfoBuilder.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/DebugInfoBuilder.java Wed Apr 23 15:48:38 2014 +0200 @@ -27,6 +27,7 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.common.*; import com.oracle.graal.debug.*; import com.oracle.graal.graph.*; import com.oracle.graal.lir.*; @@ -128,7 +129,6 @@ if (state.outerFrameState() != null) { caller = computeFrameForState(state.outerFrameState()); } - assert state.bci >= FrameState.BEFORE_BCI : "bci == " + state.bci; return new BytecodeFrame(caller, state.method(), state.bci, state.rethrowException(), state.duringCall(), values, numLocals, numStack, numLocks); } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerationResult.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerationResult.java Wed Apr 23 15:22:20 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2014, 2014, 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.gen; - -import com.oracle.graal.lir.*; - -public interface LIRGenerationResult { - FrameMap getFrameMap(); - - LIR getLIR(); - - boolean hasForeignCall(); - - void setForeignCall(boolean b); -} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerationResultBase.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerationResultBase.java Wed Apr 23 15:22:20 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2014, 2014, 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.gen; - -import com.oracle.graal.lir.*; - -public class LIRGenerationResultBase implements LIRGenerationResult { - private final LIR lir; - private final FrameMap frameMap; - /** - * Records whether the code being generated makes at least one foreign call. - */ - private boolean hasForeignCall; - - public LIRGenerationResultBase(LIR lir, FrameMap frameMap) { - this.lir = lir; - this.frameMap = frameMap; - } - - public LIR getLIR() { - return lir; - } - - /** - * Determines whether the code being generated makes at least one foreign call. - */ - public boolean hasForeignCall() { - return hasForeignCall; - } - - public final void setForeignCall(boolean hasForeignCall) { - this.hasForeignCall = hasForeignCall; - } - - public final FrameMap getFrameMap() { - return frameMap; - } - -} diff -r 518a7f487c4f -r 9363fffa8b07 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 Apr 23 15:22:20 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,637 +0,0 @@ -/* - * Copyright (c) 2009, 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.compiler.gen; - -import static com.oracle.graal.api.code.ValueUtil.*; -import static com.oracle.graal.api.meta.Value.*; -import static com.oracle.graal.lir.LIR.*; -import static com.oracle.graal.lir.LIRValueUtil.*; -import static com.oracle.graal.phases.GraalOptions.*; - -import java.util.*; - -import com.oracle.graal.api.code.*; -import com.oracle.graal.api.meta.*; -import com.oracle.graal.asm.*; -import com.oracle.graal.debug.*; -import com.oracle.graal.graph.*; -import com.oracle.graal.lir.*; -import com.oracle.graal.lir.StandardOp.BlockEndOp; -import com.oracle.graal.lir.StandardOp.LabelOp; -import com.oracle.graal.lir.StandardOp.NoOp; -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.calc.*; -import com.oracle.graal.nodes.cfg.*; -import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.nodes.type.*; -import com.oracle.graal.options.*; -import com.oracle.graal.phases.util.*; - -/** - * This class traverses the HIR instructions and generates LIR instructions from them. - */ -public abstract class LIRGenerator implements ArithmeticLIRGenerator, LIRGeneratorTool, LIRTypeTool { - - public static class Options { - // @formatter:off - @Option(help = "Print HIR along side LIR as the latter is generated") - public static final OptionValue PrintIRWithLIR = new OptionValue<>(false); - @Option(help = "The trace level for the LIR generator") - public static final OptionValue TraceLIRGeneratorLevel = new OptionValue<>(0); - // @formatter:on - } - - private final Providers providers; - private final CallingConvention cc; - - private DebugInfoBuilder debugInfoBuilder; - - protected AbstractBlock currentBlock; - public final int traceLevel; - public final boolean printIRWithLIR; - - /** - * Handle for an operation that loads a constant into a variable. The operation starts in the - * first block where the constant is used but will eventually be - * {@linkplain LIRGenerator#insertConstantLoads() moved} to a block dominating all usages of the - * constant. - */ - public static class LoadConstant implements Comparable { - /** - * The index of {@link #op} within {@link #block}'s instruction list or -1 if {@code op} is - * to be moved to a dominator block. - */ - int index; - - /** - * The operation that loads the constant. - */ - private final LIRInstruction op; - - /** - * The block that does or will contain {@link #op}. This is initially the block where the - * first usage of the constant is seen during LIR generation. - */ - Block block; - - /** - * The variable into which the constant is loaded. - */ - final Variable variable; - - public LoadConstant(Variable variable, Block block, int index, LIRInstruction op) { - this.variable = variable; - this.block = block; - this.index = index; - this.op = op; - } - - /** - * Sorts {@link LoadConstant} objects according to their enclosing blocks. This is used to - * group loads per block in {@link LIRGenerator#insertConstantLoads()}. - */ - public int compareTo(LoadConstant o) { - if (block.getId() < o.block.getId()) { - return -1; - } - if (block.getId() > o.block.getId()) { - return 1; - } - return 0; - } - - @Override - public String toString() { - return block + "#" + op; - } - - /** - * Removes the {@link #op} from its original location if it is still at that location. - */ - public void unpin(LIR lir) { - if (index >= 0) { - // Replace the move with a filler op so that the operation - // list does not need to be adjusted. - List instructions = lir.getLIRforBlock(block); - instructions.set(index, new NoOp(null, -1)); - index = -1; - } - } - } - - Map constantLoads; - - private LIRGenerationResult res; - - /** - * Set this before using the LIRGenerator. - * - * TODO this should be removed - */ - void setDebugInfoBuilder(DebugInfoBuilder builder) { - debugInfoBuilder = builder; - } - - /** - * Checks whether the supplied constant can be used without loading it into a register for store - * operations, i.e., on the right hand side of a memory access. - * - * @param c The constant to check. - * @return True if the constant can be used directly, false if the constant needs to be in a - * register. - */ - public abstract boolean canStoreConstant(Constant c, boolean isCompressed); - - public LIRGenerator(Providers providers, CallingConvention cc, LIRGenerationResult res) { - this.res = res; - this.providers = providers; - this.cc = cc; - this.traceLevel = Options.TraceLIRGeneratorLevel.getValue(); - this.printIRWithLIR = Options.PrintIRWithLIR.getValue(); - } - - /** - * Returns true if the redundant move elimination optimization should be done after register - * allocation. - */ - public boolean canEliminateRedundantMoves() { - return true; - } - - @Override - public TargetDescription target() { - return getCodeCache().getTarget(); - } - - public Providers getProviders() { - return providers; - } - - @Override - public MetaAccessProvider getMetaAccess() { - return providers.getMetaAccess(); - } - - @Override - public CodeCacheProvider getCodeCache() { - return providers.getCodeCache(); - } - - @Override - public ForeignCallsProvider getForeignCalls() { - return providers.getForeignCalls(); - } - - /** - * Creates a new {@linkplain Variable variable}. - * - * @param platformKind The kind of the new variable. - * @return a new variable - */ - @Override - public Variable newVariable(PlatformKind platformKind) { - return new Variable(platformKind, res.getLIR().nextVariable()); - } - - @Override - public RegisterAttributes attributes(Register register) { - return res.getFrameMap().registerConfig.getAttributesMap()[register.number]; - } - - @Override - public abstract Variable emitMove(Value input); - - public AllocatableValue asAllocatable(Value value) { - if (isAllocatableValue(value)) { - return asAllocatableValue(value); - } else { - return emitMove(value); - } - } - - public Variable load(Value value) { - if (!isVariable(value)) { - return emitMove(value); - } - return (Variable) value; - } - - public Value loadNonConst(Value value) { - if (isConstant(value) && !canInlineConstant((Constant) value)) { - return emitMove(value); - } - return value; - } - - public LabelRef getLIRBlock(FixedNode b) { - assert res.getLIR().getControlFlowGraph() instanceof ControlFlowGraph; - Block result = ((ControlFlowGraph) res.getLIR().getControlFlowGraph()).blockFor(b); - int suxIndex = currentBlock.getSuccessors().indexOf(result); - assert suxIndex != -1 : "Block not in successor list of current block"; - - assert currentBlock instanceof Block; - return LabelRef.forSuccessor(res.getLIR(), currentBlock, suxIndex); - } - - /** - * Determines if only oop maps are required for the code generated from the LIR. - */ - protected boolean needOnlyOopMaps() { - return false; - } - - private static FrameState getFrameState(DeoptimizingNode deopt) { - if (deopt instanceof DeoptimizingNode.DeoptBefore) { - assert !(deopt instanceof DeoptimizingNode.DeoptDuring || deopt instanceof DeoptimizingNode.DeoptAfter); - return ((DeoptimizingNode.DeoptBefore) deopt).stateBefore(); - } else if (deopt instanceof DeoptimizingNode.DeoptDuring) { - assert !(deopt instanceof DeoptimizingNode.DeoptAfter); - return ((DeoptimizingNode.DeoptDuring) deopt).stateDuring(); - } else { - assert deopt instanceof DeoptimizingNode.DeoptAfter; - return ((DeoptimizingNode.DeoptAfter) deopt).stateAfter(); - } - } - - public LIRFrameState state(DeoptimizingNode deopt) { - if (!deopt.canDeoptimize()) { - return null; - } - return stateFor(getFrameState(deopt)); - } - - public LIRFrameState stateWithExceptionEdge(DeoptimizingNode deopt, LabelRef exceptionEdge) { - if (!deopt.canDeoptimize()) { - return null; - } - return stateForWithExceptionEdge(getFrameState(deopt), exceptionEdge); - } - - public LIRFrameState stateFor(FrameState state) { - return stateForWithExceptionEdge(state, null); - } - - public LIRFrameState stateForWithExceptionEdge(FrameState state, LabelRef exceptionEdge) { - if (needOnlyOopMaps()) { - return new LIRFrameState(null, null, null); - } - assert state != null; - return getDebugInfoBuilder().build(state, exceptionEdge); - } - - /** - * Gets the ABI specific operand used to return a value of a given kind from a method. - * - * @param kind the kind of value being returned - * @return the operand representing the ABI defined location used return a value of kind - * {@code kind} - */ - public AllocatableValue resultOperandFor(Kind kind) { - if (kind == Kind.Void) { - return ILLEGAL; - } - return res.getFrameMap().registerConfig.getReturnRegister(kind).asValue(kind); - } - - public void append(LIRInstruction op) { - if (printIRWithLIR && !TTY.isSuppressed()) { - TTY.println(op.toStringWithIdPrefix()); - TTY.println(); - } - assert LIRVerifier.verify(op); - res.getLIR().getLIRforBlock(currentBlock).add(op); - } - - public boolean hasBlockEnd(AbstractBlock block) { - List ops = getResult().getLIR().getLIRforBlock(block); - if (ops.size() == 0) { - return false; - } - return ops.get(ops.size() - 1) instanceof BlockEndOp; - } - - public final void doBlockStart(AbstractBlock block) { - if (printIRWithLIR) { - TTY.print(block.toString()); - } - - currentBlock = block; - - // set up the list of LIR instructions - assert res.getLIR().getLIRforBlock(block) == null : "LIR list already computed for this block"; - res.getLIR().setLIRforBlock(block, new ArrayList()); - - append(new LabelOp(new Label(block.getId()), block.isAligned())); - - if (traceLevel >= 1) { - TTY.println("BEGIN Generating LIR for block B" + block.getId()); - } - } - - public final void doBlockEnd(AbstractBlock block) { - - if (traceLevel >= 1) { - TTY.println("END Generating LIR for block B" + block.getId()); - } - - currentBlock = null; - - if (printIRWithLIR) { - TTY.println(); - } - } - - public void emitIncomingValues(Value[] params) { - ((LabelOp) res.getLIR().getLIRforBlock(currentBlock).get(0)).setIncomingValues(params); - } - - public abstract void emitJump(LabelRef label); - - public abstract void emitCompareBranch(PlatformKind cmpKind, Value left, Value right, Condition cond, boolean unorderedIsTrue, LabelRef trueDestination, LabelRef falseDestination, - double trueDestinationProbability); - - public abstract void emitOverflowCheckBranch(LabelRef overflow, LabelRef noOverflow, double overflowProbability); - - public abstract void emitIntegerTestBranch(Value left, Value right, LabelRef trueDestination, LabelRef falseDestination, double trueSuccessorProbability); - - public abstract Variable emitConditionalMove(PlatformKind cmpKind, Value leftVal, Value right, Condition cond, boolean unorderedIsTrue, Value trueValue, Value falseValue); - - public abstract Variable emitIntegerTestMove(Value leftVal, Value right, Value trueValue, Value falseValue); - - protected abstract void emitForeignCall(ForeignCallLinkage linkage, Value result, Value[] arguments, Value[] temps, LIRFrameState info); - - public static AllocatableValue toStackKind(AllocatableValue value) { - if (value.getKind().getStackKind() != value.getKind()) { - // We only have stack-kinds in the LIR, so convert the operand kind for values from the - // calling convention. - if (isRegister(value)) { - return asRegister(value).asValue(value.getKind().getStackKind()); - } else if (isStackSlot(value)) { - return StackSlot.get(value.getKind().getStackKind(), asStackSlot(value).getRawOffset(), asStackSlot(value).getRawAddFrameSize()); - } else { - throw GraalInternalError.shouldNotReachHere(); - } - } - return value; - } - - @Override - public Variable emitForeignCall(ForeignCallLinkage linkage, DeoptimizingNode info, Value... args) { - LIRFrameState state = null; - if (linkage.canDeoptimize()) { - if (info != null) { - state = stateFor(getFrameState(info)); - } else { - assert needOnlyOopMaps(); - state = new LIRFrameState(null, null, null); - } - } - - // move the arguments into the correct location - CallingConvention linkageCc = linkage.getOutgoingCallingConvention(); - res.getFrameMap().callsMethod(linkageCc); - assert linkageCc.getArgumentCount() == args.length : "argument count mismatch"; - Value[] argLocations = new Value[args.length]; - for (int i = 0; i < args.length; i++) { - Value arg = args[i]; - AllocatableValue loc = linkageCc.getArgument(i); - emitMove(loc, arg); - argLocations[i] = loc; - } - res.setForeignCall(true); - emitForeignCall(linkage, linkageCc.getReturn(), argLocations, linkage.getTemporaries(), state); - - if (isLegal(linkageCc.getReturn())) { - return emitMove(linkageCc.getReturn()); - } else { - return null; - } - } - - protected void emitStrategySwitch(Constant[] keyConstants, double[] keyProbabilities, LabelRef[] keyTargets, LabelRef defaultTarget, Variable value) { - int keyCount = keyConstants.length; - SwitchStrategy strategy = SwitchStrategy.getBestStrategy(keyProbabilities, keyConstants, keyTargets); - long valueRange = keyConstants[keyCount - 1].asLong() - keyConstants[0].asLong() + 1; - double tableSwitchDensity = keyCount / (double) valueRange; - /* - * This heuristic tries to find a compromise between the effort for the best switch strategy - * and the density of a tableswitch. If the effort for the strategy is at least 4, then a - * tableswitch is preferred if better than a certain value that starts at 0.5 and lowers - * gradually with additional effort. - */ - if (strategy.getAverageEffort() < 4 || tableSwitchDensity < (1 / Math.sqrt(strategy.getAverageEffort()))) { - emitStrategySwitch(strategy, value, keyTargets, defaultTarget); - } else { - int minValue = keyConstants[0].asInt(); - assert valueRange < Integer.MAX_VALUE; - LabelRef[] targets = new LabelRef[(int) valueRange]; - for (int i = 0; i < valueRange; i++) { - targets[i] = defaultTarget; - } - for (int i = 0; i < keyCount; i++) { - targets[keyConstants[i].asInt() - minValue] = keyTargets[i]; - } - emitTableSwitch(minValue, defaultTarget, targets, value); - } - } - - protected abstract void emitStrategySwitch(SwitchStrategy strategy, Variable key, LabelRef[] keyTargets, LabelRef defaultTarget); - - protected abstract void emitTableSwitch(int lowKey, LabelRef defaultTarget, LabelRef[] targets, Value key); - - public CallingConvention getCallingConvention() { - return cc; - } - - public DebugInfoBuilder getDebugInfoBuilder() { - assert debugInfoBuilder != null; - return debugInfoBuilder; - } - - @Override - public void beforeRegisterAllocation() { - insertConstantLoads(); - } - - /** - * Moves deferred {@linkplain LoadConstant loads} of constants into blocks dominating all usages - * of the constant. Any operations inserted into a block are guaranteed to be immediately prior - * to the first control flow instruction near the end of the block. - */ - private void insertConstantLoads() { - if (constantLoads != null) { - // Remove loads where all usages are in the same block. - for (Iterator> iter = constantLoads.entrySet().iterator(); iter.hasNext();) { - LoadConstant lc = iter.next().getValue(); - - // Move loads of constant outside of loops - if (OptScheduleOutOfLoops.getValue()) { - Block outOfLoopDominator = lc.block; - while (outOfLoopDominator.getLoop() != null) { - outOfLoopDominator = outOfLoopDominator.getDominator(); - } - if (outOfLoopDominator != lc.block) { - lc.unpin(res.getLIR()); - lc.block = outOfLoopDominator; - } - } - - if (lc.index != -1) { - assert res.getLIR().getLIRforBlock(lc.block).get(lc.index) == lc.op; - iter.remove(); - } - } - if (constantLoads.isEmpty()) { - return; - } - - // Sorting groups the loads per block. - LoadConstant[] groupedByBlock = constantLoads.values().toArray(new LoadConstant[constantLoads.size()]); - Arrays.sort(groupedByBlock); - - int groupBegin = 0; - while (true) { - int groupEnd = groupBegin + 1; - Block block = groupedByBlock[groupBegin].block; - while (groupEnd < groupedByBlock.length && groupedByBlock[groupEnd].block == block) { - groupEnd++; - } - int groupSize = groupEnd - groupBegin; - - List ops = res.getLIR().getLIRforBlock(block); - int lastIndex = ops.size() - 1; - assert ops.get(lastIndex) instanceof BlockEndOp; - int insertionIndex = lastIndex; - for (int i = Math.max(0, lastIndex - MAX_EXCEPTION_EDGE_OP_DISTANCE_FROM_END); i < lastIndex; i++) { - if (getExceptionEdge(ops.get(i)) != null) { - insertionIndex = i; - break; - } - } - - if (groupSize == 1) { - ops.add(insertionIndex, groupedByBlock[groupBegin].op); - } else { - assert groupSize > 1; - List moves = new ArrayList<>(groupSize); - for (int i = groupBegin; i < groupEnd; i++) { - moves.add(groupedByBlock[i].op); - } - ops.addAll(insertionIndex, moves); - } - - if (groupEnd == groupedByBlock.length) { - break; - } - groupBegin = groupEnd; - } - constantLoads = null; - } - } - - /** - * Gets a garbage value for a given kind. - */ - protected Constant zapValueForKind(PlatformKind kind) { - long dead = 0xDEADDEADDEADDEADL; - switch ((Kind) kind) { - case Boolean: - return Constant.FALSE; - case Byte: - return Constant.forByte((byte) dead); - case Char: - return Constant.forChar((char) dead); - case Short: - return Constant.forShort((short) dead); - case Int: - return Constant.forInt((int) dead); - case Double: - return Constant.forDouble(Double.longBitsToDouble(dead)); - case Float: - return Constant.forFloat(Float.intBitsToFloat((int) dead)); - case Long: - return Constant.forLong(dead); - case Object: - return Constant.NULL_OBJECT; - default: - throw new IllegalArgumentException(kind.toString()); - } - } - - /** - * Default implementation: Return the Java stack kind for each stamp. - */ - public PlatformKind getPlatformKind(Stamp stamp) { - return stamp.getPlatformKind(this); - } - - public PlatformKind getIntegerKind(int bits, boolean unsigned) { - if (bits <= 8) { - return Kind.Byte; - } else if (bits <= 16) { - return Kind.Short; - } else if (bits <= 32) { - return Kind.Int; - } else { - assert bits <= 64; - return Kind.Long; - } - } - - public PlatformKind getFloatingKind(int bits) { - switch (bits) { - case 32: - return Kind.Float; - case 64: - return Kind.Double; - default: - throw GraalInternalError.shouldNotReachHere(); - } - } - - public PlatformKind getObjectKind() { - return Kind.Object; - } - - public abstract void emitBitCount(Variable result, Value operand); - - public abstract void emitBitScanForward(Variable result, Value operand); - - public abstract void emitBitScanReverse(Variable result, Value operand); - - public abstract void emitByteSwap(Variable result, Value operand); - - public abstract void emitArrayEquals(Kind kind, Variable result, Value array1, Value array2, Value length); - - public AbstractBlock getCurrentBlock() { - return currentBlock; - } - - void setCurrentBlock(AbstractBlock block) { - currentBlock = block; - } - - public LIRGenerationResult getResult() { - return res; - } -} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/NodeLIRBuilder.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/NodeLIRBuilder.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/NodeLIRBuilder.java Wed Apr 23 15:48:38 2014 +0200 @@ -31,21 +31,24 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.compiler.gen.LIRGenerator.LoadConstant; +import com.oracle.graal.compiler.common.*; +import com.oracle.graal.compiler.common.calc.*; +import com.oracle.graal.compiler.common.cfg.*; +import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.compiler.target.*; import com.oracle.graal.debug.*; import com.oracle.graal.debug.Debug.Scope; import com.oracle.graal.graph.*; import com.oracle.graal.lir.*; import com.oracle.graal.lir.StandardOp.JumpOp; +import com.oracle.graal.lir.gen.*; +import com.oracle.graal.lir.gen.LIRGenerator.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.cfg.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.nodes.type.*; import com.oracle.graal.nodes.virtual.*; -import com.oracle.graal.phases.*; /** * This class traverses the HIR instructions and generates LIR instructions from them. @@ -64,7 +67,6 @@ this.gen = gen; this.nodeOperands = graph.createNodeMap(); this.debugInfoBuilder = createDebugInfoBuilder(nodeOperands); - gen.setDebugInfoBuilder(debugInfoBuilder); } @SuppressWarnings("hiding") @@ -110,25 +112,25 @@ return setResult(node, value); } else { Variable loadedValue; - if (gen.constantLoads == null) { - gen.constantLoads = new HashMap<>(); + if (gen.getConstantLoads() == null) { + gen.setConstantLoads(new HashMap<>()); } - LoadConstant load = gen.constantLoads.get(value); + LoadConstant load = gen.getConstantLoads().get(value); assert gen.getCurrentBlock() instanceof Block; if (load == null) { int index = gen.getResult().getLIR().getLIRforBlock(gen.getCurrentBlock()).size(); loadedValue = gen.emitMove(value); LIRInstruction op = gen.getResult().getLIR().getLIRforBlock(gen.getCurrentBlock()).get(index); - gen.constantLoads.put(value, new LoadConstant(loadedValue, (Block) gen.getCurrentBlock(), index, op)); + gen.getConstantLoads().put(value, new LoadConstant(loadedValue, gen.getCurrentBlock(), index, op)); } else { - Block dominator = ControlFlowGraph.commonDominator(load.block, (Block) gen.getCurrentBlock()); - loadedValue = load.variable; - if (dominator != load.block) { + AbstractBlock dominator = ControlFlowGraph.commonDominator((Block) load.getBlock(), (Block) gen.getCurrentBlock()); + loadedValue = load.getVariable(); + if (dominator != load.getBlock()) { load.unpin(gen.getResult().getLIR()); } else { - assert load.block != gen.getCurrentBlock() || load.index < gen.getResult().getLIR().getLIRforBlock(gen.getCurrentBlock()).size(); + assert load.getBlock() != gen.getCurrentBlock() || load.getIndex() < gen.getResult().getLIR().getLIRforBlock(gen.getCurrentBlock()).size(); } - load.block = dominator; + load.setBlock(dominator); } return loadedValue; } @@ -212,9 +214,9 @@ try { doRoot((ValueNode) instr); } catch (GraalInternalError e) { - throw e.addContext(instr); + throw GraalGraphInternalError.transformAndAddContext(e, instr); } catch (Throwable e) { - throw new GraalInternalError(e).addContext(instr); + throw new GraalGraphInternalError(e).addContext(instr); } } } @@ -412,7 +414,7 @@ } else if (node instanceof LIRLowerable) { ((LIRLowerable) node).generate(this); } else if (node instanceof ArithmeticLIRLowerable) { - ((ArithmeticLIRLowerable) node).generate(this); + ((ArithmeticLIRLowerable) node).generate(this, gen); } else { throw GraalInternalError.shouldNotReachHere("node is not LIRLowerable: " + node); } @@ -566,7 +568,7 @@ if (x instanceof InvokeWithExceptionNode) { exceptionEdge = getLIRBlock(((InvokeWithExceptionNode) x).exceptionEdge()); } - LIRFrameState callState = gen.stateWithExceptionEdge(x, exceptionEdge); + LIRFrameState callState = stateWithExceptionEdge(x, exceptionEdge); Value result = invokeCc.getReturn(); if (callTarget instanceof DirectCallTargetNode) { @@ -659,7 +661,46 @@ return debugInfoBuilder; } - public void emitOverflowCheckBranch(AbstractBeginNode overflowSuccessor, AbstractBeginNode next, double probability) { + private static FrameState getFrameState(DeoptimizingNode deopt) { + if (deopt instanceof DeoptimizingNode.DeoptBefore) { + assert !(deopt instanceof DeoptimizingNode.DeoptDuring || deopt instanceof DeoptimizingNode.DeoptAfter); + return ((DeoptimizingNode.DeoptBefore) deopt).stateBefore(); + } else if (deopt instanceof DeoptimizingNode.DeoptDuring) { + assert !(deopt instanceof DeoptimizingNode.DeoptAfter); + return ((DeoptimizingNode.DeoptDuring) deopt).stateDuring(); + } else { + assert deopt instanceof DeoptimizingNode.DeoptAfter; + return ((DeoptimizingNode.DeoptAfter) deopt).stateAfter(); + } + } + + public LIRFrameState state(DeoptimizingNode deopt) { + if (!deopt.canDeoptimize()) { + return null; + } + return stateFor(getFrameState(deopt)); + } + + public LIRFrameState stateWithExceptionEdge(DeoptimizingNode deopt, LabelRef exceptionEdge) { + if (!deopt.canDeoptimize()) { + return null; + } + return stateForWithExceptionEdge(getFrameState(deopt), exceptionEdge); + } + + public LIRFrameState stateFor(FrameState state) { + return stateForWithExceptionEdge(state, null); + } + + public LIRFrameState stateForWithExceptionEdge(FrameState state, LabelRef exceptionEdge) { + if (gen.needOnlyOopMaps()) { + return new LIRFrameState(null, null, null); + } + assert state != null; + return getDebugInfoBuilder().build(state, exceptionEdge); + } + + public void emitOverflowCheckBranch(BeginNode overflowSuccessor, BeginNode next, double probability) { gen.emitOverflowCheckBranch(getLIRBlock(overflowSuccessor), getLIRBlock(next), probability); } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/PhiResolver.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/PhiResolver.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/PhiResolver.java Wed Apr 23 15:48:38 2014 +0200 @@ -29,6 +29,7 @@ import java.util.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.lir.gen.*; import com.oracle.graal.nodes.*; /** diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/HighTier.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/HighTier.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/HighTier.java Wed Apr 23 15:48:38 2014 +0200 @@ -22,8 +22,8 @@ */ package com.oracle.graal.compiler.phases; +import static com.oracle.graal.compiler.common.GraalOptions.*; import static com.oracle.graal.compiler.phases.HighTier.Options.*; -import static com.oracle.graal.phases.GraalOptions.*; import com.oracle.graal.loop.phases.*; import com.oracle.graal.nodes.spi.*; diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/LowTier.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/LowTier.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/LowTier.java Wed Apr 23 15:48:38 2014 +0200 @@ -22,7 +22,7 @@ */ package com.oracle.graal.compiler.phases; -import static com.oracle.graal.phases.GraalOptions.*; +import static com.oracle.graal.compiler.common.GraalOptions.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.options.*; diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/MidTier.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/MidTier.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/MidTier.java Wed Apr 23 15:48:38 2014 +0200 @@ -22,7 +22,7 @@ */ package com.oracle.graal.compiler.phases; -import static com.oracle.graal.phases.GraalOptions.*; +import static com.oracle.graal.compiler.common.GraalOptions.*; import com.oracle.graal.loop.phases.*; import com.oracle.graal.nodes.spi.*; @@ -51,9 +51,7 @@ } if (OptFloatingReads.getValue()) { - IncrementalCanonicalizerPhase incCanonicalizer = new IncrementalCanonicalizerPhase<>(canonicalizer); - incCanonicalizer.appendPhase(new FloatingReadPhase()); - appendPhase(incCanonicalizer); + appendPhase(new IncrementalCanonicalizerPhase<>(canonicalizer, new FloatingReadPhase())); if (OptReadElimination.getValue()) { appendPhase(new ReadEliminationPhase()); } @@ -84,7 +82,7 @@ appendPhase(new LoopSafepointInsertionPhase()); - appendPhase(new GuardLoweringPhase()); + appendPhase(new IncrementalCanonicalizerPhase<>(canonicalizer, new GuardLoweringPhase())); appendPhase(new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.MID_TIER)); diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/Backend.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/Backend.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/Backend.java Wed Apr 23 15:48:38 2014 +0200 @@ -23,12 +23,14 @@ package com.oracle.graal.compiler.target; import com.oracle.graal.api.code.*; +import com.oracle.graal.api.code.stack.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.*; +import com.oracle.graal.compiler.common.*; import com.oracle.graal.compiler.gen.*; -import com.oracle.graal.graph.*; import com.oracle.graal.lir.*; import com.oracle.graal.lir.asm.*; +import com.oracle.graal.lir.gen.*; import com.oracle.graal.nodes.*; import com.oracle.graal.phases.tiers.*; import com.oracle.graal.phases.util.*; @@ -96,12 +98,13 @@ public abstract boolean shouldAllocateRegisters(); + public abstract StackIntrospection getStackIntrospection(); + /** * Emits the code for a given graph. * - * @param installedCodeOwner the method the compiled code will be - * {@linkplain InstalledCode#getMethod() associated} with once installed. This - * argument can be null. + * @param installedCodeOwner the method the compiled code will be associated with once + * installed. This argument can be null. */ public abstract void emitCode(CompilationResultBuilder crb, LIR lir, ResolvedJavaMethod installedCodeOwner); diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/LIRGenLowerable.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/LIRGenLowerable.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/LIRGenLowerable.java Wed Apr 23 15:48:38 2014 +0200 @@ -24,6 +24,7 @@ import com.oracle.graal.compiler.gen.*; import com.oracle.graal.lir.*; +import com.oracle.graal.lir.gen.*; import com.oracle.graal.nodes.spi.*; /** diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/LIRGenResLowerable.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/LIRGenResLowerable.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/LIRGenResLowerable.java Wed Apr 23 15:48:38 2014 +0200 @@ -22,8 +22,8 @@ */ package com.oracle.graal.compiler.target; -import com.oracle.graal.compiler.gen.*; import com.oracle.graal.lir.*; +import com.oracle.graal.lir.gen.*; import com.oracle.graal.nodes.spi.*; /** diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.debug/src/com/oracle/graal/debug/Debug.java --- a/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/Debug.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/Debug.java Wed Apr 23 15:48:38 2014 +0200 @@ -23,6 +23,7 @@ package com.oracle.graal.debug; import static com.oracle.graal.debug.Debug.Initialization.*; +import static com.oracle.graal.debug.DelegatingDebugConfig.Feature.*; import static java.util.FormattableFlags.*; import java.io.*; @@ -187,6 +188,19 @@ /** * @see #scope(Object) + * @param contextObjects an array of object to be appended to the {@linkplain #context() + * current} debug context + */ + public static Scope scope(Object name, Object[] contextObjects) { + if (ENABLED) { + return DebugScope.getInstance().scope(convertFormatArg(name).toString(), null, contextObjects); + } else { + return null; + } + } + + /** + * @see #scope(Object) * @param context an object to be appended to the {@linkplain #context() current} debug context */ public static Scope scope(Object name, Object context) { @@ -259,17 +273,25 @@ } public static Scope forceLog() { - return Debug.sandbox("forceLog", new DelegatingDebugConfig(DebugScope.getConfig()) { - @Override - public boolean isLogEnabled() { - return true; - } + return Debug.sandbox("forceLog", new DelegatingDebugConfig().enable(LOG).enable(LOG_METHOD)); + } - @Override - public boolean isLogEnabledForMethod() { - return true; - } - }); + /** + * Opens a scope in which exception {@linkplain DebugConfig#interceptException(Throwable) + * interception} is disabled. It is recommended to use the try-with-resource statement for + * managing entering and leaving such scopes: + * + *
+     * try (DebugConfigScope s = Debug.disableIntercept()) {
+     *     ...
+     * }
+     * 
+ * + * This is particularly useful to suppress extraneous output in JUnit tests that are expected to + * throw an exception. + */ + public static DebugConfigScope disableIntercept() { + return Debug.setConfig(new DelegatingDebugConfig().disable(INTERCEPT)); } /** @@ -853,7 +875,7 @@ public static Object convertFormatArg(Object arg) { if (arg instanceof Class) { - return ((Class) arg).getSimpleName(); + return ((Class) arg).getSimpleName(); } return arg; } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DelegatingDebugConfig.java --- a/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DelegatingDebugConfig.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DelegatingDebugConfig.java Wed Apr 23 15:48:38 2014 +0200 @@ -25,45 +25,139 @@ import java.io.*; import java.util.*; +import com.oracle.graal.debug.internal.*; + public class DelegatingDebugConfig implements DebugConfig { protected final DebugConfig delegate; + /** + * The features of a {@link DelegatingDebugConfig} that can be force + * {@linkplain DelegatingDebugConfig#enable(Feature) enabled}/ + * {@linkplain DelegatingDebugConfig#disable(Feature) disabled} or + * {@linkplain DelegatingDebugConfig#delegate(Feature) delegated}. + */ + public enum Feature { + /** + * @see Debug#isLogEnabled() + */ + LOG, + /** + * @see Debug#isLogEnabledForMethod() + */ + LOG_METHOD, + /** + * @see Debug#isDumpEnabled() + */ + DUMP, + /** + * @see Debug#isDumpEnabledForMethod() + */ + DUMP_METHOD, + /** + * @see Debug#isMeterEnabled() + */ + METER, + /** + * @see Debug#isTimeEnabled() + */ + TIME, + /** + * @see DebugConfig#interceptException(Throwable) + */ + INTERCEPT + } + + private final Map featureState = new EnumMap<>(Feature.class); + + /** + * Creates a config that delegates to the {@link DebugScope#getConfig() current config}. + */ + public DelegatingDebugConfig() { + this(DebugScope.getConfig()); + } + + /** + * Creates a config that delegates to a given config. + */ public DelegatingDebugConfig(DebugConfig delegate) { this.delegate = delegate; } + public DelegatingDebugConfig enable(Feature feature) { + featureState.put(feature, Boolean.TRUE); + return this; + } + + public DelegatingDebugConfig disable(Feature feature) { + featureState.put(feature, Boolean.FALSE); + return this; + } + + public DelegatingDebugConfig delegate(Feature feature) { + featureState.put(feature, null); + return this; + } + @Override public boolean isLogEnabled() { - return delegate.isLogEnabled(); + Boolean fs = featureState.get(Feature.LOG); + if (fs == null) { + return delegate.isLogEnabled(); + } + return fs.booleanValue(); } public boolean isLogEnabledForMethod() { - return delegate.isLogEnabledForMethod(); + Boolean fs = featureState.get(Feature.LOG_METHOD); + if (fs == null) { + return delegate.isLogEnabledForMethod(); + } + return fs.booleanValue(); } @Override public boolean isMeterEnabled() { - return delegate.isMeterEnabled(); + Boolean fs = featureState.get(Feature.METER); + if (fs == null) { + return delegate.isMeterEnabled(); + } + return fs.booleanValue(); } @Override public boolean isDumpEnabled() { - return delegate.isDumpEnabled(); + Boolean fs = featureState.get(Feature.DUMP); + if (fs == null) { + return delegate.isDumpEnabled(); + } + return fs.booleanValue(); } public boolean isDumpEnabledForMethod() { - return delegate.isDumpEnabledForMethod(); + Boolean fs = featureState.get(Feature.DUMP_METHOD); + if (fs == null) { + return delegate.isDumpEnabledForMethod(); + } + return fs.booleanValue(); } @Override public boolean isTimeEnabled() { - return delegate.isTimeEnabled(); + Boolean fs = featureState.get(Feature.TIME); + if (fs == null) { + return delegate.isTimeEnabled(); + } + return fs.booleanValue(); } @Override public RuntimeException interceptException(Throwable e) { - return delegate.interceptException(e); + Boolean fs = featureState.get(Feature.INTERCEPT); + if (fs == null || fs) { + return delegate.interceptException(e); + } + return null; } @Override diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.graph.test/src/com/oracle/graal/graph/test/NodeUsagesTests.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.graph.test/src/com/oracle/graal/graph/test/NodeUsagesTests.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,425 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.graph.test; + +import static com.oracle.graal.graph.test.matchers.NodeIterableContains.*; +import static com.oracle.graal.graph.test.matchers.NodeIterableIsEmpty.*; +import static org.junit.Assert.*; + +import org.junit.*; + +import com.oracle.graal.graph.*; + +public class NodeUsagesTests { + + private static class Def extends Node { + + } + + private static class Use extends Node { + private @Input Def in0; + private @Input Def in1; + private @Input Def in2; + + public Use(Def in0, Def in1, Def in2) { + this.in0 = in0; + this.in1 = in1; + this.in2 = in2; + } + } + + @Test + public void testReplaceAtUsages() { + Graph graph = new Graph(); + Def def0 = graph.add(new Def()); + Def def1 = graph.add(new Def()); + Use use0 = graph.add(new Use(def0, null, null)); + Use use1 = graph.add(new Use(null, def0, null)); + Use use2 = graph.add(new Use(null, null, def0)); + + assertEquals(3, def0.usages().count()); + assertThat(def0.usages(), contains(use0)); + assertThat(def0.usages(), contains(use1)); + assertThat(def0.usages(), contains(use2)); + + assertThat(def0.usages(), isNotEmpty()); + assertThat(def1.usages(), isEmpty()); + + def0.replaceAtUsages(def1); + + assertThat(def0.usages(), isEmpty()); + + assertEquals(3, def1.usages().count()); + assertThat(def1.usages(), contains(use0)); + assertThat(def1.usages(), contains(use1)); + assertThat(def1.usages(), contains(use2)); + + assertThat(def1.usages(), isNotEmpty()); + } + + @Test + public void testReplaceAtUsagesWithPredicateAll() { + Graph graph = new Graph(); + Def def0 = graph.add(new Def()); + Def def1 = graph.add(new Def()); + Use use0 = graph.add(new Use(def0, null, null)); + Use use1 = graph.add(new Use(null, def0, null)); + Use use2 = graph.add(new Use(null, null, def0)); + + assertEquals(3, def0.usages().count()); + assertThat(def0.usages(), contains(use0)); + assertThat(def0.usages(), contains(use1)); + assertThat(def0.usages(), contains(use2)); + + assertThat(def0.usages(), isNotEmpty()); + assertThat(def1.usages(), isEmpty()); + + def0.replaceAtMatchingUsages(def1, u -> true); + + assertThat(def0.usages(), isEmpty()); + + assertEquals(3, def1.usages().count()); + assertThat(def1.usages(), contains(use0)); + assertThat(def1.usages(), contains(use1)); + assertThat(def1.usages(), contains(use2)); + + assertThat(def1.usages(), isNotEmpty()); + } + + @Test + public void testReplaceAtUsagesWithPredicateNone() { + Graph graph = new Graph(); + Def def0 = graph.add(new Def()); + Def def1 = graph.add(new Def()); + Use use0 = graph.add(new Use(def0, null, null)); + Use use1 = graph.add(new Use(null, def0, null)); + Use use2 = graph.add(new Use(null, null, def0)); + + assertEquals(3, def0.usages().count()); + assertThat(def0.usages(), contains(use0)); + assertThat(def0.usages(), contains(use1)); + assertThat(def0.usages(), contains(use2)); + + assertThat(def0.usages(), isNotEmpty()); + assertThat(def1.usages(), isEmpty()); + + def0.replaceAtMatchingUsages(def1, u -> false); + + assertThat(def1.usages(), isEmpty()); + + assertEquals(3, def0.usages().count()); + assertThat(def0.usages(), contains(use0)); + assertThat(def0.usages(), contains(use1)); + assertThat(def0.usages(), contains(use2)); + + assertThat(def0.usages(), isNotEmpty()); + } + + @Test + public void testReplaceAtUsagesWithPredicate1() { + Graph graph = new Graph(); + Def def0 = graph.add(new Def()); + Def def1 = graph.add(new Def()); + Use use0 = graph.add(new Use(def0, null, null)); + Use use1 = graph.add(new Use(null, def0, null)); + Use use2 = graph.add(new Use(null, null, def0)); + + assertEquals(3, def0.usages().count()); + assertThat(def0.usages(), contains(use0)); + assertThat(def0.usages(), contains(use1)); + assertThat(def0.usages(), contains(use2)); + + assertThat(def0.usages(), isNotEmpty()); + assertThat(def1.usages(), isEmpty()); + + def0.replaceAtMatchingUsages(def1, u -> u == use1); + + assertEquals(1, def1.usages().count()); + assertThat(def1.usages(), contains(use1)); + + assertThat(def1.usages(), isNotEmpty()); + + assertEquals(2, def0.usages().count()); + assertThat(def0.usages(), contains(use0)); + assertThat(def0.usages(), contains(use2)); + + assertThat(def0.usages(), isNotEmpty()); + } + + @Test + public void testReplaceAtUsagesWithPredicate2() { + Graph graph = new Graph(); + Def def0 = graph.add(new Def()); + Def def1 = graph.add(new Def()); + Use use0 = graph.add(new Use(def0, null, null)); + Use use1 = graph.add(new Use(null, def0, null)); + Use use2 = graph.add(new Use(null, null, def0)); + + assertEquals(3, def0.usages().count()); + assertThat(def0.usages(), contains(use0)); + assertThat(def0.usages(), contains(use1)); + assertThat(def0.usages(), contains(use2)); + + assertThat(def0.usages(), isNotEmpty()); + assertThat(def1.usages(), isEmpty()); + + def0.replaceAtMatchingUsages(def1, u -> u == use2); + + assertEquals(1, def1.usages().count()); + assertThat(def1.usages(), contains(use2)); + + assertThat(def1.usages(), isNotEmpty()); + + assertEquals(2, def0.usages().count()); + assertThat(def0.usages(), contains(use0)); + assertThat(def0.usages(), contains(use1)); + + assertThat(def0.usages(), isNotEmpty()); + } + + @Test + public void testReplaceAtUsagesWithPredicate0() { + Graph graph = new Graph(); + Def def0 = graph.add(new Def()); + Def def1 = graph.add(new Def()); + Use use0 = graph.add(new Use(def0, null, null)); + Use use1 = graph.add(new Use(null, def0, null)); + Use use2 = graph.add(new Use(null, null, def0)); + + assertEquals(3, def0.usages().count()); + assertThat(def0.usages(), contains(use0)); + assertThat(def0.usages(), contains(use1)); + assertThat(def0.usages(), contains(use2)); + + assertThat(def0.usages(), isNotEmpty()); + assertThat(def1.usages(), isEmpty()); + + def0.replaceAtMatchingUsages(def1, u -> u == use0); + + assertEquals(1, def1.usages().count()); + assertThat(def1.usages(), contains(use0)); + + assertThat(def1.usages(), isNotEmpty()); + + assertEquals(2, def0.usages().count()); + assertThat(def0.usages(), contains(use1)); + assertThat(def0.usages(), contains(use2)); + + assertThat(def0.usages(), isNotEmpty()); + } + + @Test + public void testReplaceAtUsagesWithPredicate02() { + Graph graph = new Graph(); + Def def0 = graph.add(new Def()); + Def def1 = graph.add(new Def()); + Use use0 = graph.add(new Use(def0, null, null)); + Use use1 = graph.add(new Use(null, def0, null)); + Use use2 = graph.add(new Use(null, null, def0)); + + assertEquals(3, def0.usages().count()); + assertThat(def0.usages(), contains(use0)); + assertThat(def0.usages(), contains(use1)); + assertThat(def0.usages(), contains(use2)); + + assertThat(def0.usages(), isNotEmpty()); + assertThat(def1.usages(), isEmpty()); + + def0.replaceAtMatchingUsages(def1, u -> u != use1); + + assertEquals(1, def0.usages().count()); + assertThat(def0.usages(), contains(use1)); + + assertThat(def0.usages(), isNotEmpty()); + + assertEquals(2, def1.usages().count()); + assertThat(def1.usages(), contains(use0)); + assertThat(def1.usages(), contains(use2)); + + assertThat(def1.usages(), isNotEmpty()); + } + + @Test + public void testReplaceAtUsagesWithPredicate023() { + Graph graph = new Graph(); + Def def0 = graph.add(new Def()); + Def def1 = graph.add(new Def()); + Use use0 = graph.add(new Use(def0, null, null)); + Use use1 = graph.add(new Use(null, def0, null)); + Use use2 = graph.add(new Use(null, null, def0)); + Use use3 = graph.add(new Use(null, null, def0)); + + assertEquals(4, def0.usages().count()); + assertThat(def0.usages(), contains(use0)); + assertThat(def0.usages(), contains(use1)); + assertThat(def0.usages(), contains(use2)); + assertThat(def0.usages(), contains(use3)); + + assertThat(def0.usages(), isNotEmpty()); + assertThat(def1.usages(), isEmpty()); + + def0.replaceAtMatchingUsages(def1, u -> u != use1); + + assertEquals(1, def0.usages().count()); + assertThat(def0.usages(), contains(use1)); + + assertThat(def0.usages(), isNotEmpty()); + + assertEquals(3, def1.usages().count()); + assertThat(def1.usages(), contains(use0)); + assertThat(def1.usages(), contains(use2)); + assertThat(def1.usages(), contains(use3)); + + assertThat(def1.usages(), isNotEmpty()); + } + + @Test + public void testReplaceAtUsagesWithPredicate013() { + Graph graph = new Graph(); + Def def0 = graph.add(new Def()); + Def def1 = graph.add(new Def()); + Use use0 = graph.add(new Use(def0, null, null)); + Use use1 = graph.add(new Use(null, def0, null)); + Use use2 = graph.add(new Use(null, null, def0)); + Use use3 = graph.add(new Use(null, null, def0)); + + assertEquals(4, def0.usages().count()); + assertThat(def0.usages(), contains(use0)); + assertThat(def0.usages(), contains(use1)); + assertThat(def0.usages(), contains(use2)); + assertThat(def0.usages(), contains(use3)); + + assertThat(def0.usages(), isNotEmpty()); + assertThat(def1.usages(), isEmpty()); + + def0.replaceAtMatchingUsages(def1, u -> u != use2); + + assertEquals(1, def0.usages().count()); + assertThat(def0.usages(), contains(use2)); + + assertThat(def0.usages(), isNotEmpty()); + + assertEquals(3, def1.usages().count()); + assertThat(def1.usages(), contains(use0)); + assertThat(def1.usages(), contains(use1)); + assertThat(def1.usages(), contains(use3)); + + assertThat(def1.usages(), isNotEmpty()); + } + + @Test + public void testReplaceAtUsagesWithPredicate2_3() { + Graph graph = new Graph(); + Def def0 = graph.add(new Def()); + Def def1 = graph.add(new Def()); + Use use0 = graph.add(new Use(def0, null, null)); + Use use1 = graph.add(new Use(null, def0, null)); + Use use2 = graph.add(new Use(null, null, def0)); + Use use3 = graph.add(new Use(null, null, def0)); + + assertEquals(4, def0.usages().count()); + assertThat(def0.usages(), contains(use0)); + assertThat(def0.usages(), contains(use1)); + assertThat(def0.usages(), contains(use2)); + assertThat(def0.usages(), contains(use3)); + + assertThat(def0.usages(), isNotEmpty()); + assertThat(def1.usages(), isEmpty()); + + def0.replaceAtMatchingUsages(def1, u -> u == use2); + + assertEquals(1, def1.usages().count()); + assertThat(def1.usages(), contains(use2)); + + assertThat(def1.usages(), isNotEmpty()); + + assertEquals(3, def0.usages().count()); + assertThat(def0.usages(), contains(use0)); + assertThat(def0.usages(), contains(use1)); + assertThat(def0.usages(), contains(use3)); + + assertThat(def0.usages(), isNotEmpty()); + } + + @Test + public void testReplaceAtUsagesWithPredicate01() { + Graph graph = new Graph(); + Def def0 = graph.add(new Def()); + Def def1 = graph.add(new Def()); + Use use0 = graph.add(new Use(def0, null, null)); + Use use1 = graph.add(new Use(null, def0, null)); + Use use2 = graph.add(new Use(null, null, def0)); + + assertEquals(3, def0.usages().count()); + assertThat(def0.usages(), contains(use0)); + assertThat(def0.usages(), contains(use1)); + assertThat(def0.usages(), contains(use2)); + + assertThat(def0.usages(), isNotEmpty()); + assertThat(def1.usages(), isEmpty()); + + def0.replaceAtMatchingUsages(def1, u -> u != use2); + + assertEquals(1, def0.usages().count()); + assertThat(def0.usages(), contains(use2)); + + assertThat(def0.usages(), isNotEmpty()); + + assertEquals(2, def1.usages().count()); + assertThat(def1.usages(), contains(use0)); + assertThat(def1.usages(), contains(use1)); + + assertThat(def1.usages(), isNotEmpty()); + } + + @Test + public void testReplaceAtUsagesWithPredicate12() { + Graph graph = new Graph(); + Def def0 = graph.add(new Def()); + Def def1 = graph.add(new Def()); + Use use0 = graph.add(new Use(def0, null, null)); + Use use1 = graph.add(new Use(null, def0, null)); + Use use2 = graph.add(new Use(null, null, def0)); + + assertEquals(3, def0.usages().count()); + assertThat(def0.usages(), contains(use0)); + assertThat(def0.usages(), contains(use1)); + assertThat(def0.usages(), contains(use2)); + + assertThat(def0.usages(), isNotEmpty()); + assertThat(def1.usages(), isEmpty()); + + def0.replaceAtMatchingUsages(def1, u -> u != use0); + + assertEquals(1, def0.usages().count()); + assertThat(def0.usages(), contains(use0)); + + assertThat(def0.usages(), isNotEmpty()); + + assertEquals(2, def1.usages().count()); + assertThat(def1.usages(), contains(use1)); + assertThat(def1.usages(), contains(use2)); + + assertThat(def1.usages(), isNotEmpty()); + } +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.graph.test/src/com/oracle/graal/graph/test/matchers/NodeIterableContains.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.graph.test/src/com/oracle/graal/graph/test/matchers/NodeIterableContains.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.graph.test.matchers; + +import org.hamcrest.*; + +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.iterators.*; + +public class NodeIterableContains extends TypeSafeDiagnosingMatcher> { + private T node; + + public NodeIterableContains(T node) { + this.node = node; + } + + public void describeTo(Description description) { + description.appendText("is a NodeIterable containing").appendValue(node); + } + + public static NodeIterableContains contains(T node) { + return new NodeIterableContains<>(node); + } + + public static NodeIterableContains d(T node) { + return new NodeIterableContains<>(node); + } + + @Override + protected boolean matchesSafely(NodeIterable iterable, Description description) { + return iterable.contains(node); + } +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.graph.test/src/com/oracle/graal/graph/test/matchers/NodeIterableIsEmpty.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.graph.test/src/com/oracle/graal/graph/test/matchers/NodeIterableIsEmpty.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.graph.test.matchers; + +import org.hamcrest.*; +import org.hamcrest.core.*; + +import com.oracle.graal.graph.iterators.*; + +public class NodeIterableIsEmpty extends BaseMatcher> { + + private static final NodeIterableIsEmpty INSTANCE = new NodeIterableIsEmpty(); + + public boolean matches(Object iterable) { + return iterable instanceof NodeIterable && ((NodeIterable) iterable).isEmpty(); + } + + public void describeTo(Description description) { + description.appendText("is an empty NodeIterable"); + } + + public static Matcher> isEmpty() { + return INSTANCE; + } + + public static Matcher> isNotEmpty() { + return IsNot.not(INSTANCE); + } +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.graph/src/com/oracle/graal/graph/FieldIntrospection.java --- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/FieldIntrospection.java Wed Apr 23 15:22:20 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,153 +0,0 @@ -/* - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.graph; - -import java.lang.reflect.*; -import java.util.*; -import java.util.concurrent.*; - -public abstract class FieldIntrospection extends UnsafeAccess { - - /** - * Interface used by {@link #rescanAllFieldOffsets(CalcOffset)} to determine the offset (in - * bytes) of a field. - */ - public interface CalcOffset { - - long getOffset(Field field); - } - - public static class DefaultCalcOffset implements CalcOffset { - - @Override - public long getOffset(Field field) { - return unsafe.objectFieldOffset(field); - } - } - - protected static final ConcurrentHashMap, FieldIntrospection> allClasses = new ConcurrentHashMap<>(); - - protected final Class clazz; - protected long[] dataOffsets; - protected Map fieldNames; - protected Map> fieldTypes; - - public FieldIntrospection(Class clazz) { - this.clazz = clazz; - } - - public static void rescanAllFieldOffsets(CalcOffset calc) { - for (FieldIntrospection nodeClass : allClasses.values()) { - nodeClass.rescanFieldOffsets(calc); - } - } - - protected abstract void rescanFieldOffsets(CalcOffset calc); - - public abstract static class BaseFieldScanner { - - private final CalcOffset calc; - - /** The offsets of fields that are not specially handled by subclasses. */ - public final ArrayList dataOffsets = new ArrayList<>(); - - public final Map fieldNames = new HashMap<>(); - public final Map> fieldTypes = new HashMap<>(); - - protected BaseFieldScanner(CalcOffset calc) { - this.calc = calc; - } - - protected void scan(Class clazz) { - Class currentClazz = clazz; - do { - for (Field field : currentClazz.getDeclaredFields()) { - if (Modifier.isStatic(field.getModifiers())) { - continue; - } - Class type = field.getType(); - long offset = calc.getOffset(field); - - // scanField() may overwrite the name with a customized name. - fieldNames.put(offset, field.getName()); - fieldTypes.put(offset, type); - - scanField(field, type, offset); - } - currentClazz = currentClazz.getSuperclass(); - } while (currentClazz.getSuperclass() != Object.class); - } - - protected abstract void scanField(Field field, Class type, long offset); - } - - protected static void copyInto(long[] dest, long[] src) { - assert dest.length == src.length; - for (int i = 0; i < dest.length; i++) { - dest[i] = src[i]; - } - } - - protected static void copyInto(T[] dest, T[] src) { - assert dest.length == src.length; - for (int i = 0; i < dest.length; i++) { - dest[i] = src[i]; - } - } - - protected static void copyInto(T[] dest, List src) { - assert dest.length == src.size(); - for (int i = 0; i < dest.length; i++) { - dest[i] = src.get(i); - } - } - - protected static T[] arrayUsingSortedOffsets(Map map, long[] sortedOffsets, T[] result) { - for (int i = 0; i < sortedOffsets.length; i++) { - result[i] = map.get(sortedOffsets[i]); - } - return result; - } - - protected static long[] sortedLongCopy(ArrayList list1) { - Collections.sort(list1); - long[] result = new long[list1.size()]; - for (int i = 0; i < list1.size(); i++) { - result[i] = list1.get(i); - } - return result; - } - - protected static long[] sortedLongCopy(ArrayList list1, ArrayList list2) { - Collections.sort(list1); - Collections.sort(list2); - long[] result = new long[list1.size() + list2.size()]; - for (int i = 0; i < list1.size(); i++) { - result[i] = list1.get(i); - } - for (int i = 0; i < list2.size(); i++) { - result[list1.size() + i] = list2.get(i); - } - return result; - } -} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.graph/src/com/oracle/graal/graph/GraalGraphInternalError.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/GraalGraphInternalError.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.graph; + +import com.oracle.graal.compiler.common.*; + +/** + * This error is the graph/node aware extension of GraalInternalError. + */ +public class GraalGraphInternalError extends GraalInternalError { + + private static final long serialVersionUID = -989290015525497919L; + private Node node; + private Graph graph; + + /** + * This constructor creates a {@link GraalGraphInternalError} with a message assembled via + * {@link String#format(String, Object...)}. It always uses the ENGLISH locale in order to + * always generate the same output. + * + * @param msg the message that will be associated with the error, in String.format syntax + * @param args parameters to String.format - parameters that implement {@link Iterable} will be + * expanded into a [x, x, ...] representation. + */ + public GraalGraphInternalError(String msg, Object... args) { + super(msg, args); + } + + /** + * This constructor creates a {@link GraalGraphInternalError} for a given causing Throwable + * instance. + * + * @param cause the original exception that contains additional information on this error + */ + public GraalGraphInternalError(Throwable cause) { + super(cause); + } + + /** + * This constructor creates a {@link GraalGraphInternalError} from a given GraalInternalError + * instance. + * + * @param e the original GraalInternalError + */ + protected GraalGraphInternalError(GraalInternalError e) { + super(e); + if (e instanceof GraalGraphInternalError) { + node = ((GraalGraphInternalError) e).node; + graph = ((GraalGraphInternalError) e).graph; + } + } + + /** + * Adds a graph to the context of this VerificationError. The first graph added via this method + * will be returned by {@link #graph()}. + * + * @param newGraph the graph which is in a incorrect state, if the verification error was not + * caused by a specific node + */ + GraalGraphInternalError addContext(Graph newGraph) { + if (newGraph != this.graph) { + addContext("graph", newGraph); + if (this.graph == null) { + this.graph = newGraph; + } + } + return this; + } + + /** + * Adds a node to the context of this VerificationError. The first node added via this method + * will be returned by {@link #node()}. + * + * @param newNode the node which is in a incorrect state, if the verification error was caused + * by a node + */ + public GraalGraphInternalError addContext(Node newNode) { + if (newNode != this.node) { + addContext("node", newNode); + if (this.node == null) { + this.node = newNode; + } + } + return this; + } + + /** + * Transform a GraalInternalError into a GraalGraphInternalError and add a graph to the context. + * + * @param e the previous error + * @param newGraph the graph which is in a incorrect state, if the verification error was not + * caused by a specific node + */ + public static GraalGraphInternalError transformAndAddContext(GraalInternalError e, Graph newGraph) { + GraalGraphInternalError graphError; + if (e instanceof GraalGraphInternalError) { + graphError = (GraalGraphInternalError) e; + } else { + graphError = new GraalGraphInternalError(e); + } + return graphError.addContext(newGraph); + } + + /** + * Transform a GraalInternalError into a GraalGraphInternalError and add a node to the context. + * + * @param e the previous error + * @param newNode the node which is in a incorrect state, if the verification error was caused + * by a node + */ + public static GraalGraphInternalError transformAndAddContext(GraalInternalError e, Node newNode) { + GraalGraphInternalError graphError; + if (e instanceof GraalGraphInternalError) { + graphError = (GraalGraphInternalError) e; + } else { + graphError = new GraalGraphInternalError(e); + } + return graphError.addContext(newNode); + } + + public Node node() { + return node; + } + + public Graph graph() { + return graph; + } +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.graph/src/com/oracle/graal/graph/GraalInternalError.java --- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/GraalInternalError.java Wed Apr 23 15:22:20 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,168 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.graph; - -import java.util.*; - -/** - * This error represents a conditions that should never occur during normal operation. - */ -public class GraalInternalError extends Error { - - private static final long serialVersionUID = 8776065085829593278L; - private Node node; - private Graph graph; - private final ArrayList context = new ArrayList<>(); - - public static RuntimeException unimplemented() { - throw new GraalInternalError("unimplemented"); - } - - public static RuntimeException unimplemented(String msg) { - throw new GraalInternalError("unimplemented: %s", msg); - } - - public static RuntimeException shouldNotReachHere() { - throw new GraalInternalError("should not reach here"); - } - - public static RuntimeException shouldNotReachHere(String msg) { - throw new GraalInternalError("should not reach here: %s", msg); - } - - /** - * Checks a given condition and throws a {@link GraalInternalError} if it is false. Guarantees - * are stronger than assertions in that they are always checked. Error messages for guarantee - * violations should clearly indicate the nature of the problem as well as a suggested solution - * if possible. - * - * @param condition the condition to check - * @param msg the message that will be associated with the error, in - * {@link String#format(String, Object...)} syntax - * @param args arguments to the format string - */ - public static void guarantee(boolean condition, String msg, Object... args) { - if (!condition) { - throw new GraalInternalError("failed guarantee: " + msg, args); - } - } - - /** - * This constructor creates a {@link GraalInternalError} with a message assembled via - * {@link String#format(String, Object...)}. It always uses the ENGLISH locale in order to - * always generate the same output. - * - * @param msg the message that will be associated with the error, in String.format syntax - * @param args parameters to String.format - parameters that implement {@link Iterable} will be - * expanded into a [x, x, ...] representation. - */ - public GraalInternalError(String msg, Object... args) { - super(format(msg, args)); - } - - /** - * This constructor creates a {@link GraalInternalError} for a given causing Throwable instance. - * - * @param cause the original exception that contains additional information on this error - */ - public GraalInternalError(Throwable cause) { - super(cause); - } - - @Override - public String toString() { - StringBuilder str = new StringBuilder(); - str.append(super.toString()); - for (String s : context) { - str.append("\n\tat ").append(s); - } - return str.toString(); - } - - private static String format(String msg, Object... args) { - if (args != null) { - // expand Iterable parameters into a list representation - for (int i = 0; i < args.length; i++) { - if (args[i] instanceof Iterable) { - ArrayList list = new ArrayList<>(); - for (Object o : (Iterable) args[i]) { - list.add(o); - } - args[i] = list.toString(); - } - } - } - return String.format(Locale.ENGLISH, msg, args); - } - - public GraalInternalError addContext(String newContext) { - this.context.add(newContext); - return this; - } - - public GraalInternalError addContext(String name, Object obj) { - return addContext(format("%s: %s", name, obj)); - } - - /** - * Adds a graph to the context of this VerificationError. The first graph added via this method - * will be returned by {@link #graph()}. - * - * @param newGraph the graph which is in a incorrect state, if the verification error was not - * caused by a specific node - */ - public GraalInternalError addContext(Graph newGraph) { - if (newGraph != this.graph) { - addContext("graph", newGraph); - if (this.graph == null) { - this.graph = newGraph; - } - } - return this; - } - - /** - * Adds a node to the context of this VerificationError. The first node added via this method - * will be returned by {@link #node()}. - * - * @param newNode the node which is in a incorrect state, if the verification error was caused - * by a node - */ - public GraalInternalError addContext(Node newNode) { - if (newNode != this.node) { - addContext("node", newNode); - if (this.node == null) { - this.node = newNode; - } - } - return this; - } - - public Node node() { - return node; - } - - public Graph graph() { - return graph; - } -} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Graph.java --- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Graph.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Graph.java Wed Apr 23 15:48:38 2014 +0200 @@ -24,6 +24,7 @@ import java.util.*; +import com.oracle.graal.compiler.common.*; import com.oracle.graal.debug.*; import com.oracle.graal.graph.GraphEvent.NodeEvent; import com.oracle.graal.graph.Node.ValueNumberable; @@ -525,7 +526,7 @@ */ public NodeIterable getNewNodes(Mark mark) { final int index = mark.getValue(); - return new AbstractNodeIterable() { + return new NodeIterable() { @Override public Iterator iterator() { @@ -540,7 +541,7 @@ * @return an {@link Iterable} providing all the live nodes. */ public NodeIterable getNodes() { - return new AbstractNodeIterable() { + return new NodeIterable() { @Override public Iterator iterator() { @@ -714,7 +715,7 @@ */ public NodeIterable getNodes(final Class type) { final NodeClass nodeClass = NodeClass.get(type); - return new AbstractNodeIterable() { + return new NodeIterable() { @Override public Iterator iterator() { @@ -839,7 +840,7 @@ throw new GraalInternalError(t); } } catch (GraalInternalError e) { - throw e.addContext(node).addContext(this); + throw GraalGraphInternalError.transformAndAddContext(e, node).addContext(this); } } return true; diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.graph/src/com/oracle/graal/graph/InputType.java --- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/InputType.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/InputType.java Wed Apr 23 15:48:38 2014 +0200 @@ -53,6 +53,10 @@ */ Association, /** + * Inputs that connect tightly coupled nodes, e.g., an InvokeNode and its CallTargetNode. + */ + Extension, + /** * Inputs of this type are temporarily exempt from type checking. This should only be used in * exceptional cases and should never survive to later stages of compilation. */ diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Node.java --- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Node.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Node.java Wed Apr 23 15:48:38 2014 +0200 @@ -111,7 +111,7 @@ * method. If not specified, then the class in which the annotated method is declared is * used (and is assumed to be a {@link Node} subclass). */ - Class value() default NodeIntrinsic.class; + Class value() default NodeIntrinsic.class; /** * Determines if the stamp of the instantiated intrinsic node has its stamp set from the @@ -189,7 +189,6 @@ Node current; private void advance() { - assert index == -1 || current != null; current = null; index++; if (index == 0) { @@ -228,10 +227,35 @@ } } - class NodeUsageIterable extends AbstractNodeIterable { + class NodeUsageWithModCountIterator extends NodeUsageIterator { + + private final int expectedModCount = usageModCount(); + + @Override + public boolean hasNext() { + if (expectedModCount != usageModCount()) { + throw new ConcurrentModificationException(); + } + return super.hasNext(); + } + + @Override + public Node next() { + if (expectedModCount != usageModCount()) { + throw new ConcurrentModificationException(); + } + return super.next(); + } + } + + class NodeUsageIterable implements NodeIterable { public NodeUsageIterator iterator() { - return new NodeUsageIterator(); + if (MODIFICATION_COUNTS_ENABLED) { + return new NodeUsageWithModCountIterator(); + } else { + return new NodeUsageIterator(); + } } @Override @@ -246,13 +270,7 @@ @Override public int count() { - if (usage0 == null) { - return 0; - } - if (usage1 == null) { - return 1; - } - return 2 + indexOfLastNonNull(extraUsages) + 1; + return usageCount(); } } @@ -349,6 +367,81 @@ } } + private int usageCount() { + if (usage0 == null) { + return 0; + } + if (usage1 == null) { + return 1; + } + return 2 + indexOfLastNonNull(extraUsages) + 1; + } + + /** + * Remove all usages between {@code fromIndex} and {@code toIndex} (exclusive), also, if + * {@code toIndex} is a valid usage, it is moved to {@code fromIndex}. + * + *

+ * Visually, + * + *

+     * {@code
+     * [1, 2, 3, 4, 5, 6, 7].removeUsagesAndShiftFirst(1, 2) == [1, 4, 6, 7, 5, null, null]}
+     * 
+ * + * + * @param fromIndex the index of the first element to be removed + * @param toIndex the index after the last element to be removed + */ + private void removeUsagesAndShiftFirst(int fromIndex, int toIndex) { + assert fromIndex < toIndex; + int firstNullIndex = usageCount(); + assert toIndex <= firstNullIndex; + int i = fromIndex; + int limit = toIndex; + if (toIndex < firstNullIndex) { + // move usage at toIndex to fromIndex(!) + movUsageTo(toIndex, fromIndex); + limit++; + i++; + } + while (i < limit && firstNullIndex > limit) { + movUsageTo(firstNullIndex - 1, i); + firstNullIndex--; + i++; + } + while (i < limit) { + if (i == 0) { + usage0 = null; + } else if (i == 1) { + usage1 = null; + } else { + extraUsages[i - INLINE_USAGE_COUNT] = null; + } + i++; + } + + } + + private void movUsageTo(int usageIndex, int toIndex) { + assert usageIndex > toIndex; + if (toIndex == 0) { + if (usageIndex == 1) { + usage0 = usage1; + usage1 = null; + } else { + usage0 = extraUsages[usageIndex - INLINE_USAGE_COUNT]; + extraUsages[usageIndex - INLINE_USAGE_COUNT] = null; + } + } else if (toIndex == 1) { + usage1 = extraUsages[usageIndex - INLINE_USAGE_COUNT]; + extraUsages[usageIndex - INLINE_USAGE_COUNT] = null; + } else { + extraUsages[toIndex - INLINE_USAGE_COUNT] = extraUsages[usageIndex - INLINE_USAGE_COUNT]; + extraUsages[usageIndex - INLINE_USAGE_COUNT] = null; + } + } + /** * Removes a given node from this node's {@linkplain #usages() usages}. * @@ -357,6 +450,7 @@ */ private boolean removeUsage(Node node) { assert recordsUsages(); + assert node != null; // It is critical that this method maintains the invariant that // the usage list has no null element preceding a non-null element incUsageModCount(); @@ -388,20 +482,19 @@ } return true; } - int lastNonNull = indexOfLastNonNull(extraUsages); - if (lastNonNull >= 0) { - for (int i = 0; i <= lastNonNull; ++i) { - Node n = extraUsages[i]; - if (n == node) { - if (i < lastNonNull) { - extraUsages[i] = extraUsages[lastNonNull]; - extraUsages[lastNonNull] = null; - } else { - extraUsages[i] = null; - } - return true; - } + int matchIndex = -1; + int i = 0; + Node n; + while (i < extraUsages.length && (n = extraUsages[i]) != null) { + if (n == node) { + matchIndex = i; } + i++; + } + if (matchIndex >= 0) { + extraUsages[matchIndex] = extraUsages[i - 1]; + extraUsages[i - 1] = null; + return true; } return false; } @@ -543,6 +636,40 @@ clearUsages(); } + public void replaceAtMatchingUsages(Node other, NodePredicate usagePredicate) { + assert checkReplaceWith(other); + NodeUsageIterator it = (NodeUsageIterator) usages().iterator(); + int removeStart = -1; + while (it.hasNext()) { + Node usage = it.next(); + if (usagePredicate.apply(usage)) { + if (removeStart < 0) { + removeStart = it.index - 1; + } + boolean result = usage.getNodeClass().replaceFirstInput(usage, this, other); + assert assertTrue(result, "not found in inputs, usage: %s", usage); + if (other != null) { + maybeNotifyChanged(usage); + if (other.recordsUsages()) { + other.addUsage(usage); + } + } + } else { + if (removeStart >= 0) { + int removeEndIndex = it.index - 1; + removeUsagesAndShiftFirst(removeStart, removeEndIndex); + it.index = removeStart; + it.advance(); + removeStart = -1; + } + } + } + if (removeStart >= 0) { + int removeEndIndex = it.index; + removeUsagesAndShiftFirst(removeStart, removeEndIndex); + } + } + public void replaceAtUsages(InputType type, Node other) { assert checkReplaceWith(other); for (Node usage : usages().snapshot()) { @@ -707,7 +834,7 @@ try { newNode = (Node) this.clone(); } catch (CloneNotSupportedException e) { - throw new GraalInternalError(e).addContext(this); + throw new GraalGraphInternalError(e).addContext(this); } if (clearInputsAndSuccessors) { nodeClass.clearInputs(newNode); @@ -907,7 +1034,8 @@ if ((flags & FormattableFlags.ALTERNATE) == FormattableFlags.ALTERNATE) { formatter.format("%s", toString(Verbosity.Id)); } else if ((flags & FormattableFlags.UPPERCASE) == FormattableFlags.UPPERCASE) { - formatter.format("%s", toString(Verbosity.Long)); + // Use All here since Long is only slightly longer than Short. + formatter.format("%s", toString(Verbosity.All)); } else { formatter.format("%s", toString(Verbosity.Short)); } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeBitMap.java --- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeBitMap.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeBitMap.java Wed Apr 23 15:48:38 2014 +0200 @@ -26,7 +26,7 @@ import com.oracle.graal.graph.iterators.*; -public final class NodeBitMap extends AbstractNodeIterable { +public final class NodeBitMap implements NodeIterable { private final boolean autoGrow; private final BitSet bitMap; diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java --- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java Wed Apr 23 15:48:38 2014 +0200 @@ -26,8 +26,8 @@ import java.lang.reflect.*; import java.util.*; -import java.util.concurrent.*; +import com.oracle.graal.compiler.common.*; import com.oracle.graal.debug.*; import com.oracle.graal.graph.Graph.DuplicationReplacement; import com.oracle.graal.graph.Node.Input; @@ -36,7 +36,7 @@ import com.oracle.graal.graph.spi.*; /** - * Lazily associated metadata for every {@link Node} type. The metadata includes: + * Metadata for every {@link Node} type. The metadata includes: *
    *
  • The offsets of fields annotated with {@link Input} and {@link Successor} as well as methods * for iterating over such fields.
  • @@ -45,72 +45,7 @@ */ public final class NodeClass extends FieldIntrospection { - /** - * Maps {@link Class} values (for {@link Node} types) to {@link NodeClass} values. - * - * Only a single Registry instance can be created. If a runtime creates a specialized registry, - * it must do so before the class initializer of {@link NodeClass} is executed. - */ - public static class Registry { - - private static Registry instance; - - /** - * Gets the singleton {@link Registry} instance, creating it first if necessary. - */ - static synchronized Registry instance() { - if (instance == null) { - return new Registry(); - } - return instance; - } - - protected Registry() { - assert instance == null : "exactly one registry can be created"; - instance = this; - } - - /** - * @return the {@link NodeClass} value for {@code key} or {@code null} if no such mapping - * exists - */ - protected NodeClass get(Class key) { - return (NodeClass) allClasses.get(key); - } - - /** - * Same as {@link #get(Class)} except that a {@link NodeClass} is created if no such mapping - * exists. The creation of a {@link NodeClass} must be serialized as - * {@link NodeClass#NodeClass(Class)} accesses both {@link FieldIntrospection#allClasses} - * and {@link NodeClass#nextIterableId}. - *

    - * The fact that {@link ConcurrentHashMap#put} {@link ConcurrentHashMap#get} are used should - * make the double-checked locking idiom work in the way {@link NodeClass#get(Class)} uses - * this method and {@link #get(Class)}. - */ - final synchronized NodeClass make(Class key) { - NodeClass value = (NodeClass) allClasses.get(key); - if (value == null) { - value = new NodeClass(key); - Object old = allClasses.putIfAbsent(key, value); - assert old == null; - registered(key, value); - } - return value; - } - - /** - * Hook for a subclass to be notified of a new mapping added to the registry. - * - * @param key - * @param value - */ - protected void registered(Class key, NodeClass value) { - - } - } - - private static final Registry registry = Registry.instance(); + private static final Object GetNodeClassLock = new Object(); /** * Gets the {@link NodeClass} associated with a given {@link Class}. @@ -118,11 +53,22 @@ @SuppressWarnings("unchecked") public static NodeClass get(Class c) { Class key = (Class) c; - NodeClass value = registry.get(key); - if (value != null) { - return value; + NodeClass value = (NodeClass) allClasses.get(key); + // The fact that {@link ConcurrentHashMap#put} and {@link ConcurrentHashMap#get} + // are used makes the double-checked locking idiom work. + if (value == null) { + // The creation of a NodeClass must be serialized as the NodeClass constructor accesses + // both FieldIntrospection.allClasses and NodeClass.nextIterableId. + synchronized (GetNodeClassLock) { + value = (NodeClass) allClasses.get(key); + if (value == null) { + value = new NodeClass(key); + Object old = allClasses.putIfAbsent(key, value); + assert old == null : old + " " + key; + } + } } - return registry.make(key); + return value; } public static final int NOT_ITERABLE = -1; @@ -137,10 +83,8 @@ private final int directInputCount; private final long[] inputOffsets; private final InputType[] inputTypes; - private final String[] inputNames; private final int directSuccessorCount; private final long[] successorOffsets; - private final String[] successorNames; private final Class[] dataTypes; private final boolean canGVN; private final boolean isLeafNode; @@ -180,20 +124,12 @@ directInputCount = scanner.inputOffsets.size(); inputOffsets = sortedLongCopy(scanner.inputOffsets, scanner.inputListOffsets); inputTypes = new InputType[inputOffsets.length]; - inputNames = new String[inputOffsets.length]; for (int i = 0; i < inputOffsets.length; i++) { inputTypes[i] = scanner.types.get(inputOffsets[i]); - inputNames[i] = scanner.names.get(inputOffsets[i]); assert inputTypes[i] != null; - assert inputNames[i] != null; } directSuccessorCount = scanner.successorOffsets.size(); successorOffsets = sortedLongCopy(scanner.successorOffsets, scanner.successorListOffsets); - successorNames = new String[successorOffsets.length]; - for (int i = 0; i < successorOffsets.length; i++) { - successorNames[i] = scanner.names.get(successorOffsets[i]); - assert successorNames[i] != null; - } dataOffsets = sortedLongCopy(scanner.dataOffsets); dataTypes = new Class[dataOffsets.length]; @@ -243,10 +179,10 @@ this.iterableId = nextIterableId++; List existingClasses = new LinkedList<>(); for (FieldIntrospection nodeClass : allClasses.values()) { - if (clazz.isAssignableFrom(nodeClass.clazz)) { + if (clazz.isAssignableFrom(nodeClass.getClazz())) { existingClasses.add((NodeClass) nodeClass); } - if (nodeClass.clazz.isAssignableFrom(clazz) && IterableNodeType.class.isAssignableFrom(nodeClass.clazz)) { + if (nodeClass.getClazz().isAssignableFrom(clazz) && IterableNodeType.class.isAssignableFrom(nodeClass.getClazz())) { NodeClass superNodeClass = (NodeClass) nodeClass; superNodeClass.iterableIds = Arrays.copyOf(superNodeClass.iterableIds, superNodeClass.iterableIds.length + 1); superNodeClass.iterableIds[superNodeClass.iterableIds.length - 1] = this.iterableId; @@ -271,7 +207,7 @@ @Override protected void rescanFieldOffsets(CalcOffset calc) { FieldScanner scanner = new FieldScanner(calc); - scanner.scan(clazz); + scanner.scan(getClazz()); assert directInputCount == scanner.inputOffsets.size(); copyInto(inputOffsets, sortedLongCopy(scanner.inputOffsets, scanner.inputListOffsets)); assert directSuccessorCount == scanner.successorOffsets.size(); @@ -388,7 +324,7 @@ @Override public String toString() { StringBuilder str = new StringBuilder(); - str.append("NodeClass ").append(clazz.getSimpleName()).append(" ["); + str.append("NodeClass ").append(getClazz().getSimpleName()).append(" ["); for (int i = 0; i < inputOffsets.length; i++) { str.append(i == 0 ? "" : ", ").append(inputOffsets[i]); } @@ -412,9 +348,9 @@ */ public static final class Position { - public final boolean input; - public final int index; - public final int subIndex; + private final boolean input; + private final int index; + private final int subIndex; public Position(boolean input, int index, int subIndex) { this.input = input; @@ -436,7 +372,7 @@ } public String getInputName(Node node) { - return node.getNodeClass().getEdgeName(this); + return node.getNodeClass().getName(this); } public void set(Node node, Node value) { @@ -480,6 +416,18 @@ } return true; } + + public int getSubIndex() { + return subIndex; + } + + public int getIndex() { + return index; + } + + public boolean isInput() { + return input; + } } private static Node getNode(Node node, long offset) { @@ -495,7 +443,7 @@ unsafe.putObject(node, offset, value); } - private static void putNodeList(Node node, long offset, NodeList value) { + private static void putNodeList(Node node, long offset, NodeList value) { unsafe.putObject(node, offset, value); } @@ -871,7 +819,7 @@ } public boolean valueEqual(Node a, Node b) { - if (!canGVN || a.getClass() != b.getClass()) { + if (a.getClass() != b.getClass()) { return a == b; } for (int i = 0; i < dataOffsets.length; ++i) { @@ -949,43 +897,39 @@ if (this == from) { return true; } - long[] offsets = pos.input ? inputOffsets : successorOffsets; - if (pos.index >= offsets.length) { + long[] offsets = pos.isInput() ? inputOffsets : successorOffsets; + if (pos.getIndex() >= offsets.length) { return false; } - long[] fromOffsets = pos.input ? from.inputOffsets : from.successorOffsets; - if (pos.index >= fromOffsets.length) { + long[] fromOffsets = pos.isInput() ? from.inputOffsets : from.successorOffsets; + if (pos.getIndex() >= fromOffsets.length) { return false; } - return offsets[pos.index] == fromOffsets[pos.index]; + return offsets[pos.getIndex()] == fromOffsets[pos.getIndex()]; } public Node get(Node node, Position pos) { - long offset = pos.input ? inputOffsets[pos.index] : successorOffsets[pos.index]; - if (pos.subIndex == NOT_ITERABLE) { + long offset = pos.isInput() ? inputOffsets[pos.getIndex()] : successorOffsets[pos.getIndex()]; + if (pos.getSubIndex() == NOT_ITERABLE) { return getNode(node, offset); } else { - return getNodeList(node, offset).get(pos.subIndex); + return getNodeList(node, offset).get(pos.getSubIndex()); } } public InputType getInputType(Position pos) { - assert pos.input; - return inputTypes[pos.index]; - } - - public String getEdgeName(Position pos) { - return pos.input ? inputNames[pos.index] : successorNames[pos.index]; + assert pos.isInput(); + return inputTypes[pos.getIndex()]; } public NodeList getNodeList(Node node, Position pos) { - long offset = pos.input ? inputOffsets[pos.index] : successorOffsets[pos.index]; - assert pos.subIndex == NODE_LIST; + long offset = pos.isInput() ? inputOffsets[pos.getIndex()] : successorOffsets[pos.getIndex()]; + assert pos.getSubIndex() == NODE_LIST; return getNodeList(node, offset); } public String getName(Position pos) { - return fieldNames.get(pos.input ? inputOffsets[pos.index] : successorOffsets[pos.index]); + return fieldNames.get(pos.isInput() ? inputOffsets[pos.getIndex()] : successorOffsets[pos.getIndex()]); } void updateInputSuccInPlace(Node node, InplaceUpdateClosure duplicationReplacement) { @@ -1028,7 +972,7 @@ int index = startIndex; while (index < inputOffsets.length) { NodeList list = getNodeList(node, inputOffsets[index]); - assert list != null : clazz; + assert list != null : getClazz(); putNodeList(node, inputOffsets[index], updateInputListCopy(list, node, duplicationReplacement)); index++; } @@ -1038,7 +982,7 @@ int index = startIndex; while (index < successorOffsets.length) { NodeList list = getNodeList(node, successorOffsets[index]); - assert list != null : clazz; + assert list != null : getClazz(); putNodeList(node, successorOffsets[index], updateSuccListCopy(list, node, duplicationReplacement)); index++; } @@ -1071,22 +1015,22 @@ } public void set(Node node, Position pos, Node x) { - long offset = pos.input ? inputOffsets[pos.index] : successorOffsets[pos.index]; - if (pos.subIndex == NOT_ITERABLE) { + long offset = pos.isInput() ? inputOffsets[pos.getIndex()] : successorOffsets[pos.getIndex()]; + if (pos.getSubIndex() == NOT_ITERABLE) { Node old = getNode(node, offset); - assert x == null || fieldTypes.get((pos.input ? inputOffsets : successorOffsets)[pos.index]).isAssignableFrom(x.getClass()) : this + ".set(node, pos, " + x + ")"; + assert x == null || fieldTypes.get((pos.isInput() ? inputOffsets : successorOffsets)[pos.getIndex()]).isAssignableFrom(x.getClass()) : this + ".set(node, pos, " + x + ")"; putNode(node, offset, x); - if (pos.input) { + if (pos.isInput()) { node.updateUsages(old, x); } else { node.updatePredecessor(old, x); } } else { NodeList list = getNodeList(node, offset); - if (pos.subIndex < list.size()) { - list.set(pos.subIndex, x); + if (pos.getSubIndex() < list.size()) { + list.set(pos.getSubIndex(), x); } else { - while (pos.subIndex < list.size() - 1) { + while (pos.getSubIndex() < list.size() - 1) { list.add(null); } list.add(x); @@ -1095,7 +1039,7 @@ } public NodeClassIterable getInputIterable(final Node node) { - assert clazz.isInstance(node); + assert getClazz().isInstance(node); return new NodeClassIterable() { @Override @@ -1115,7 +1059,7 @@ } public NodeClassIterable getSuccessorIterable(final Node node) { - assert clazz.isInstance(node); + assert getClazz().isInstance(node); return new NodeClassIterable() { @Override @@ -1148,7 +1092,7 @@ } while (index < inputOffsets.length) { NodeList list = getNodeList(node, inputOffsets[index]); - assert list != null : clazz; + assert list != null : getClazz(); if (list.replaceFirst(old, other)) { return true; } @@ -1171,7 +1115,7 @@ } while (index < successorOffsets.length) { NodeList list = getNodeList(node, successorOffsets[index]); - assert list != null : clazz + " " + successorOffsets[index] + " " + node; + assert list != null : getClazz() + " " + successorOffsets[index] + " " + node; if (list.replaceFirst(old, other)) { return true; } @@ -1228,7 +1172,7 @@ * @param newNode the node to which the inputs should be copied. */ public void copyInputs(Node node, Node newNode) { - assert node.getClass() == clazz && newNode.getClass() == clazz; + assert node.getClass() == getClazz() && newNode.getClass() == getClazz(); int index = 0; while (index < directInputCount) { @@ -1250,7 +1194,7 @@ * @param newNode the node to which the successors should be copied. */ public void copySuccessors(Node node, Node newNode) { - assert node.getClass() == clazz && newNode.getClass() == clazz; + assert node.getClass() == getClazz() && newNode.getClass() == getClazz(); int index = 0; while (index < directSuccessorCount) { @@ -1269,7 +1213,7 @@ } public boolean inputsEqual(Node node, Node other) { - assert node.getClass() == clazz && other.getClass() == clazz; + assert node.getClass() == getClazz() && other.getClass() == getClazz(); int index = 0; while (index < directInputCount) { if (getNode(other, inputOffsets[index]) != getNode(node, inputOffsets[index])) { @@ -1288,7 +1232,7 @@ } public boolean successorsEqual(Node node, Node other) { - assert node.getClass() == clazz && other.getClass() == clazz; + assert node.getClass() == getClazz() && other.getClass() == getClazz(); int index = 0; while (index < directSuccessorCount) { if (getNode(other, successorOffsets[index]) != getNode(node, successorOffsets[index])) { @@ -1307,7 +1251,7 @@ } public boolean inputContains(Node node, Node other) { - assert node.getClass() == clazz; + assert node.getClass() == getClazz(); int index = 0; while (index < directInputCount) { @@ -1327,7 +1271,7 @@ } public boolean successorContains(Node node, Node other) { - assert node.getClass() == clazz; + assert node.getClass() == getClazz(); int index = 0; while (index < directSuccessorCount) { @@ -1409,7 +1353,7 @@ } public Class getJavaClass() { - return clazz; + return getClazz(); } /** @@ -1509,7 +1453,7 @@ replacement = replacements.replacement(input); } if (replacement != input) { - assert isAssignable(nodeClass.fieldTypes.get(nodeClass.inputOffsets[pos.index]), replacement); + assert isAssignable(nodeClass.fieldTypes.get(nodeClass.inputOffsets[pos.getIndex()]), replacement); target = replacement; } else if (input.graph() == graph) { // patch to the outer world target = input; @@ -1528,7 +1472,7 @@ if (target == null) { Node replacement = replacements.replacement(succ); if (replacement != succ) { - assert isAssignable(nodeClass.fieldTypes.get(node.getNodeClass().successorOffsets[pos.index]), replacement); + assert isAssignable(nodeClass.fieldTypes.get(node.getNodeClass().successorOffsets[pos.getIndex()]), replacement); target = replacement; } } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClassIterable.java --- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClassIterable.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClassIterable.java Wed Apr 23 15:48:38 2014 +0200 @@ -30,7 +30,7 @@ * The iterator returned by this iterable can be used to access {@link Position Positions} during * iteration using {@link NodeClassIterator#nextPosition()}. */ -public abstract class NodeClassIterable extends AbstractNodeIterable { +public interface NodeClassIterable extends NodeIterable { @Override public abstract NodeClassIterator iterator(); diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeList.java --- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeList.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeList.java Wed Apr 23 15:48:38 2014 +0200 @@ -257,7 +257,7 @@ } @Override - public void snapshotTo(Collection to) { + public void snapshotTo(Collection to) { for (int i = 0; i < size; i++) { to.add(get(i)); } @@ -348,42 +348,6 @@ } @Override - public NodeIterable until(final T u) { - return new FilteredNodeIterable<>(this).until(u); - } - - @Override - public NodeIterable until(final Class clazz) { - return new FilteredNodeIterable<>(this).until(clazz); - } - - @Override - @SuppressWarnings("unchecked") - public NodeIterable filter(Class clazz) { - return (NodeIterable) new FilteredNodeIterable<>(this).and(NodePredicates.isA(clazz)); - } - - @Override - public NodeIterable filterInterface(Class iface) { - return new FilteredNodeIterable<>(this).and(NodePredicates.isAInterface(iface)); - } - - @Override - public FilteredNodeIterable filter(NodePredicate predicate) { - return new FilteredNodeIterable<>(this).and(predicate); - } - - @Override - public FilteredNodeIterable nonNull() { - return new FilteredNodeIterable<>(this).and(NodePredicates.isNotNull()); - } - - @Override - public NodeIterable distinct() { - return new FilteredNodeIterable<>(this).distinct(); - } - - @Override public T first() { if (size() > 0) { return get(0); diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.graph/src/com/oracle/graal/graph/UnsafeAccess.java --- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/UnsafeAccess.java Wed Apr 23 15:22:20 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,102 +0,0 @@ -/* - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.graph; - -import java.lang.reflect.*; - -import sun.misc.*; - -public class UnsafeAccess { - - /** - * An instance of {@link Unsafe} for use within Graal. - */ - public static final Unsafe unsafe = getUnsafe(); - - private static Unsafe getUnsafe() { - try { - // this will fail if Graal is not part of the boot class path - return Unsafe.getUnsafe(); - } catch (SecurityException e) { - // nothing to do - } - try { - Field theUnsafeInstance = Unsafe.class.getDeclaredField("theUnsafe"); - theUnsafeInstance.setAccessible(true); - return (Unsafe) theUnsafeInstance.get(Unsafe.class); - } catch (Exception e) { - // currently we rely on being able to use Unsafe... - throw new RuntimeException("exception while trying to get Unsafe.theUnsafe via reflection:", e); - } - } - - /** - * Copies the contents of a {@link String} to a native memory buffer as a {@code '\0'} - * terminated C string. The native memory buffer is allocated via - * {@link Unsafe#allocateMemory(long)}. The caller is responsible for releasing the buffer when - * it is no longer needed via {@link Unsafe#freeMemory(long)}. - * - * @return the native memory pointer of the C string created from {@code s} - */ - public static long createCString(String s) { - return writeCString(s, unsafe.allocateMemory(s.length() + 1)); - } - - /** - * Reads a {@code '\0'} terminated C string from native memory and converts it to a - * {@link String}. - * - * @return a Java string - */ - public static String readCString(long address) { - if (address == 0) { - return null; - } - StringBuffer sb = new StringBuffer(); - for (int i = 0;; i++) { - char c = (char) unsafe.getByte(address + i); - if (c == 0) { - break; - } - sb.append(c); - } - return sb.toString(); - } - - /** - * Writes the contents of a {@link String} to a native memory buffer as a {@code '\0'} - * terminated C string. The caller is responsible for ensuring the buffer is at least - * {@code s.length() + 1} bytes long. The caller is also responsible for releasing the buffer - * when it is no longer. - * - * @return the value of {@code buf} - */ - public static long writeCString(String s, long buf) { - int size = s.length(); - for (int i = 0; i < size; i++) { - unsafe.putByte(buf + i, (byte) s.charAt(i)); - } - unsafe.putByte(buf + size, (byte) '\0'); - return buf; - } -} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.graph/src/com/oracle/graal/graph/VerificationError.java --- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/VerificationError.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/VerificationError.java Wed Apr 23 15:48:38 2014 +0200 @@ -26,7 +26,7 @@ * This error represents a failed verification of a node . It must only be used for conditions that * should never occur during normal operation. */ -public class VerificationError extends GraalInternalError { +public class VerificationError extends GraalGraphInternalError { private static final long serialVersionUID = 8459607567446819822L; diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.graph/src/com/oracle/graal/graph/iterators/AbstractNodeIterable.java --- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/iterators/AbstractNodeIterable.java Wed Apr 23 15:22:20 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,117 +0,0 @@ -/* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.graph.iterators; - -import java.util.*; - -import com.oracle.graal.graph.*; - -public abstract class AbstractNodeIterable implements NodeIterable { - - @Override - public NodeIterable until(final T u) { - return new FilteredNodeIterable<>(this).until(u); - } - - @Override - public NodeIterable until(final Class clazz) { - return new FilteredNodeIterable<>(this).until(clazz); - } - - @Override - @SuppressWarnings("unchecked") - public NodeIterable filter(Class clazz) { - return (NodeIterable) new FilteredNodeIterable<>(this).and(NodePredicates.isA(clazz)); - } - - @Override - public NodeIterable filterInterface(Class iface) { - return new FilteredNodeIterable<>(this).and(NodePredicates.isAInterface(iface)); - } - - @Override - public FilteredNodeIterable filter(NodePredicate predicate) { - return new FilteredNodeIterable<>(this).and(predicate); - } - - @Override - public FilteredNodeIterable nonNull() { - return new FilteredNodeIterable<>(this).and(NodePredicates.isNotNull()); - } - - @Override - public NodeIterable distinct() { - return new FilteredNodeIterable<>(this).distinct(); - } - - @Override - public List snapshot() { - ArrayList list = new ArrayList<>(); - for (T n : this) { - list.add(n); - } - return list; - } - - @Override - public void snapshotTo(Collection to) { - for (T n : this) { - to.add(n); - } - } - - @Override - public T first() { - Iterator iterator = iterator(); - if (iterator.hasNext()) { - return iterator.next(); - } - return null; - } - - @Override - public int count() { - int count = 0; - Iterator iterator = iterator(); - while (iterator.hasNext()) { - iterator.next(); - count++; - } - return count; - } - - @Override - public boolean isEmpty() { - return !iterator().hasNext(); - } - - @Override - public boolean isNotEmpty() { - return iterator().hasNext(); - } - - @Override - public boolean contains(T node) { - return this.filter(NodePredicates.equals(node)).isNotEmpty(); - } -} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.graph/src/com/oracle/graal/graph/iterators/DistinctFilteredNodeIterable.java --- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/iterators/DistinctFilteredNodeIterable.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/iterators/DistinctFilteredNodeIterable.java Wed Apr 23 15:48:38 2014 +0200 @@ -39,6 +39,6 @@ @Override public Iterator iterator() { - return new DistinctPredicatedProxyNodeIterator<>(until, nodeIterable.iterator(), predicate); + return new DistinctPredicatedProxyNodeIterator<>(nodeIterable.iterator(), predicate); } } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.graph/src/com/oracle/graal/graph/iterators/DistinctPredicatedProxyNodeIterator.java --- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/iterators/DistinctPredicatedProxyNodeIterator.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/iterators/DistinctPredicatedProxyNodeIterator.java Wed Apr 23 15:48:38 2014 +0200 @@ -30,8 +30,8 @@ private NodeBitMap visited; - public DistinctPredicatedProxyNodeIterator(NodePredicate until, Iterator iterator, NodePredicate predicate) { - super(until, iterator, predicate); + public DistinctPredicatedProxyNodeIterator(Iterator iterator, NodePredicate predicate) { + super(iterator, predicate); } @Override diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.graph/src/com/oracle/graal/graph/iterators/FilteredNodeIterable.java --- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/iterators/FilteredNodeIterable.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/iterators/FilteredNodeIterable.java Wed Apr 23 15:48:38 2014 +0200 @@ -26,11 +26,10 @@ import com.oracle.graal.graph.*; -public class FilteredNodeIterable extends AbstractNodeIterable { +public class FilteredNodeIterable implements NodeIterable { protected final NodeIterable nodeIterable; protected NodePredicate predicate = NodePredicates.alwaysTrue(); - protected NodePredicate until = NodePredicates.isNull(); public FilteredNodeIterable(NodeIterable nodeIterable) { this.nodeIterable = nodeIterable; @@ -47,18 +46,6 @@ } @Override - public NodeIterable until(final T u) { - until = until.or(NodePredicates.equals(u)); - return this; - } - - @Override - public NodeIterable until(final Class clazz) { - until = until.or(NodePredicates.isA(clazz)); - return this; - } - - @Override public FilteredNodeIterable nonNull() { this.predicate = this.predicate.and(NodePredicates.isNotNull()); return this; @@ -68,13 +55,12 @@ public DistinctFilteredNodeIterable distinct() { DistinctFilteredNodeIterable distinct = new DistinctFilteredNodeIterable<>(nodeIterable); distinct.predicate = predicate; - distinct.until = until; return distinct; } @Override public Iterator iterator() { - return new PredicatedProxyNodeIterator<>(until, nodeIterable.iterator(), predicate); + return new PredicatedProxyNodeIterator<>(nodeIterable.iterator(), predicate); } @SuppressWarnings("unchecked") diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.graph/src/com/oracle/graal/graph/iterators/NodeIterable.java --- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/iterators/NodeIterable.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/iterators/NodeIterable.java Wed Apr 23 15:48:38 2014 +0200 @@ -28,32 +28,66 @@ public interface NodeIterable extends Iterable { - NodeIterable until(T u); + @SuppressWarnings("unchecked") + default NodeIterable filter(Class clazz) { + return (NodeIterable) new FilteredNodeIterable<>(this).and(NodePredicates.isA(clazz)); + } - NodeIterable until(Class clazz); + default NodeIterable filterInterface(Class iface) { + return new FilteredNodeIterable<>(this).and(NodePredicates.isAInterface(iface)); + } - NodeIterable filter(Class clazz); + default FilteredNodeIterable filter(NodePredicate predicate) { + return new FilteredNodeIterable<>(this).and(predicate); + } - NodeIterable filterInterface(Class iface); - - FilteredNodeIterable filter(NodePredicate predicate); + default FilteredNodeIterable nonNull() { + return new FilteredNodeIterable<>(this).and(NodePredicates.isNotNull()); + } - FilteredNodeIterable nonNull(); + default NodeIterable distinct() { + return new FilteredNodeIterable<>(this).distinct(); + } - NodeIterable distinct(); + default List snapshot() { + ArrayList list = new ArrayList<>(); + snapshotTo(list); + return list; + } - List snapshot(); - - void snapshotTo(Collection to); + default void snapshotTo(Collection to) { + for (T n : this) { + to.add(n); + } + } - T first(); - - int count(); + default T first() { + Iterator iterator = iterator(); + if (iterator.hasNext()) { + return iterator.next(); + } + return null; + } - boolean isEmpty(); - - boolean isNotEmpty(); + default int count() { + int count = 0; + Iterator iterator = iterator(); + while (iterator.hasNext()) { + iterator.next(); + count++; + } + return count; + } - boolean contains(T node); + default boolean isEmpty() { + return !iterator().hasNext(); + } + default boolean isNotEmpty() { + return iterator().hasNext(); + } + + default boolean contains(T node) { + return this.filter(NodePredicates.equals(node)).isNotEmpty(); + } } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.graph/src/com/oracle/graal/graph/iterators/NodePredicate.java --- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/iterators/NodePredicate.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/iterators/NodePredicate.java Wed Apr 23 15:48:38 2014 +0200 @@ -23,20 +23,21 @@ package com.oracle.graal.graph.iterators; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.iterators.NodePredicates.*; -public abstract class NodePredicate { +public interface NodePredicate { - public abstract boolean apply(Node n); + boolean apply(Node n); - public NodePredicate and(NodePredicate np) { - return NodePredicates.and(this, np); + default NodePredicate and(NodePredicate np) { + return new AndPredicate(this, np); } - public NodePredicate or(NodePredicate np) { - return NodePredicates.or(this, np); + default NodePredicate or(NodePredicate np) { + return new OrPredicate(this, np); } - public NodePredicate negate() { - return NodePredicates.not(this); + default NodePredicate negate() { + return new NotPredicate(this); } } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.graph/src/com/oracle/graal/graph/iterators/NodePredicates.java --- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/iterators/NodePredicates.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/iterators/NodePredicates.java Wed Apr 23 15:48:38 2014 +0200 @@ -27,7 +27,7 @@ public abstract class NodePredicates { private static final TautologyPredicate TAUTOLOGY = new TautologyPredicate(); - private static final FalsePredicate FALSE = new FalsePredicate(); + private static final ContradictionPredicate CONTRADICTION = new ContradictionPredicate(); private static final IsNullPredicate IS_NULL = new IsNullPredicate(); private static final IsNotNullPredicate IS_NOT_NULL = new IsNotNullPredicate(); @@ -36,7 +36,7 @@ } public static NodePredicate alwaysFalse() { - return FALSE; + return CONTRADICTION; } public static NodePredicate isNull() { @@ -52,60 +52,7 @@ } public static NodePredicate not(NodePredicate a) { - if (a == TAUTOLOGY) { - return FALSE; - } - if (a == FALSE) { - return TAUTOLOGY; - } - if (a == IS_NULL) { - return IS_NOT_NULL; - } - if (a == IS_NOT_NULL) { - return IS_NULL; - } - if (a instanceof NotPredicate) { - return ((NotPredicate) a).a; - } - if (a instanceof PositiveTypePredicate) { - return new NegativeTypePredicate((PositiveTypePredicate) a); - } - if (a instanceof NegativeTypePredicate) { - return new PositiveTypePredicate((NegativeTypePredicate) a); - } - if (a instanceof EqualsPredicate) { - return new NotEqualsPredicate(((EqualsPredicate) a).u); - } - if (a instanceof NotEqualsPredicate) { - return new EqualsPredicate(((NotEqualsPredicate) a).u); - } - return new NotPredicate(a); - } - - public static NodePredicate and(NodePredicate a, NodePredicate b) { - if (a == TAUTOLOGY) { - return b; - } - if (b == TAUTOLOGY) { - return a; - } - if (a == FALSE || b == FALSE) { - return FALSE; - } - return new AndPredicate(a, b); - } - - public static NodePredicate or(NodePredicate a, NodePredicate b) { - if (a == FALSE) { - return b; - } - if (b == FALSE) { - return a; - } - if (a == TAUTOLOGY || b == TAUTOLOGY) { - return TAUTOLOGY; - } - return new OrPredicate(a, b); + return a.negate(); } public static NegativeTypePredicate isNotA(Class clazz) { @@ -126,28 +73,52 @@ return new NegativeTypePredicate(iface); } - private static final class TautologyPredicate extends NodePredicate { + static final class TautologyPredicate implements NodePredicate { @Override public boolean apply(Node n) { return true; } + + public NodePredicate and(NodePredicate np) { + return np; + } + + public NodePredicate negate() { + return CONTRADICTION; + } + + public NodePredicate or(NodePredicate np) { + return this; + } } - private static final class FalsePredicate extends NodePredicate { + static final class ContradictionPredicate implements NodePredicate { @Override public boolean apply(Node n) { return false; } + + public NodePredicate and(NodePredicate np) { + return this; + } + + public NodePredicate negate() { + return TAUTOLOGY; + } + + public NodePredicate or(NodePredicate np) { + return np; + } } - private static final class AndPredicate extends NodePredicate { + static final class AndPredicate implements NodePredicate { private final NodePredicate a; private final NodePredicate b; - private AndPredicate(NodePredicate a, NodePredicate b) { + AndPredicate(NodePredicate a, NodePredicate b) { this.a = a; this.b = b; } @@ -158,11 +129,11 @@ } } - private static final class NotPredicate extends NodePredicate { + static final class NotPredicate implements NodePredicate { private final NodePredicate a; - private NotPredicate(NodePredicate n) { + NotPredicate(NodePredicate n) { this.a = n; } @@ -170,14 +141,18 @@ public boolean apply(Node n) { return !a.apply(n); } + + public NodePredicate negate() { + return a; + } } - private static final class OrPredicate extends NodePredicate { + static final class OrPredicate implements NodePredicate { private final NodePredicate a; private final NodePredicate b; - private OrPredicate(NodePredicate a, NodePredicate b) { + OrPredicate(NodePredicate a, NodePredicate b) { this.a = a; this.b = b; } @@ -188,27 +163,35 @@ } } - private static final class IsNullPredicate extends NodePredicate { + static final class IsNullPredicate implements NodePredicate { @Override public boolean apply(Node n) { return n == null; } + + public NodePredicate negate() { + return IS_NOT_NULL; + } } - private static final class IsNotNullPredicate extends NodePredicate { + static final class IsNotNullPredicate implements NodePredicate { @Override public boolean apply(Node n) { return n != null; } + + public NodePredicate negate() { + return IS_NULL; + } } - private static final class EqualsPredicate extends NodePredicate { + static final class EqualsPredicate implements NodePredicate { private final Node u; - public EqualsPredicate(Node u) { + EqualsPredicate(Node u) { this.u = u; } @@ -216,13 +199,17 @@ public boolean apply(Node n) { return u == n; } + + public NodePredicate negate() { + return new NotEqualsPredicate(u); + } } - private static final class NotEqualsPredicate extends NodePredicate { + static final class NotEqualsPredicate implements NodePredicate { private final Node u; - public NotEqualsPredicate(Node u) { + NotEqualsPredicate(Node u) { this.u = u; } @@ -230,14 +217,18 @@ public boolean apply(Node n) { return u != n; } + + public NodePredicate negate() { + return new EqualsPredicate(u); + } } - public static final class PositiveTypePredicate extends NodePredicate { + public static final class PositiveTypePredicate implements NodePredicate { private final Class type; private PositiveTypePredicate or; - public PositiveTypePredicate(Class type) { + PositiveTypePredicate(Class type) { this.type = type; } @@ -261,14 +252,18 @@ } return this; } + + public NodePredicate negate() { + return new NegativeTypePredicate(this); + } } - public static final class NegativeTypePredicate extends NodePredicate { + public static final class NegativeTypePredicate implements NodePredicate { private final Class type; private NegativeTypePredicate nor; - public NegativeTypePredicate(Class type) { + NegativeTypePredicate(Class type) { this.type = type; } @@ -292,5 +287,9 @@ } return this; } + + public NodePredicate negate() { + return new PositiveTypePredicate(this); + } } } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.graph/src/com/oracle/graal/graph/iterators/PredicatedProxyNodeIterator.java --- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/iterators/PredicatedProxyNodeIterator.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/iterators/PredicatedProxyNodeIterator.java Wed Apr 23 15:48:38 2014 +0200 @@ -30,10 +30,8 @@ private final Iterator iterator; private final NodePredicate predicate; - private final NodePredicate until; - public PredicatedProxyNodeIterator(NodePredicate until, Iterator iterator, NodePredicate predicate) { - this.until = until; + public PredicatedProxyNodeIterator(Iterator iterator, NodePredicate predicate) { this.iterator = iterator; this.predicate = predicate; } @@ -43,7 +41,7 @@ while ((current == null || !current.isAlive() || !predicate.apply(current)) && iterator.hasNext()) { current = iterator.next(); } - if (current != null && (!current.isAlive() || !predicate.apply(current) || until.apply(current))) { + if (current != null && (!current.isAlive() || !predicate.apply(current))) { current = null; } } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64DeoptimizationStub.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64DeoptimizationStub.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2014, 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.amd64; + +import static com.oracle.graal.amd64.AMD64.*; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.hotspot.*; +import com.oracle.graal.hotspot.meta.*; +import com.oracle.graal.hotspot.stubs.*; + +final class AMD64DeoptimizationStub extends DeoptimizationStub { + + private RegisterConfig registerConfig; + + public AMD64DeoptimizationStub(HotSpotProviders providers, TargetDescription target, HotSpotForeignCallLinkage linkage) { + super(providers, target, linkage); + registerConfig = new AMD64HotSpotRegisterConfig(target.arch, HotSpotGraalRuntime.runtime().getConfig(), new Register[]{rax, rbx, rcx, rdx, rsi, rdi, r8, r9, r10, r11, r13, r14}); + } + + @Override + public RegisterConfig getRegisterConfig() { + return registerConfig; + } +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64DeoptimizeOp.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64DeoptimizeOp.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64DeoptimizeOp.java Wed Apr 23 15:48:38 2014 +0200 @@ -41,6 +41,6 @@ @Override public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) { - AMD64Call.directCall(crb, masm, crb.foreignCalls.lookupForeignCall(UNCOMMON_TRAP), null, false, info); + AMD64Call.directCall(crb, masm, crb.foreignCalls.lookupForeignCall(UNCOMMON_TRAP_HANDLER), null, false, info); } } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java Wed Apr 23 15:48:38 2014 +0200 @@ -25,9 +25,7 @@ import static com.oracle.graal.amd64.AMD64.*; import static com.oracle.graal.api.code.CallingConvention.Type.*; import static com.oracle.graal.api.code.ValueUtil.*; -import static com.oracle.graal.phases.GraalOptions.*; -import static java.lang.reflect.Modifier.*; - +import static com.oracle.graal.compiler.common.GraalOptions.*; import java.util.*; import sun.misc.*; @@ -48,6 +46,7 @@ import com.oracle.graal.lir.*; import com.oracle.graal.lir.amd64.*; import com.oracle.graal.lir.asm.*; +import com.oracle.graal.lir.gen.*; import com.oracle.graal.nodes.*; /** @@ -225,7 +224,7 @@ Assembler masm = createAssembler(frameMap); HotSpotFrameContext frameContext = new HotSpotFrameContext(stub != null, omitFrame); CompilationResultBuilder crb = factory.createBuilder(getCodeCache(), getForeignCalls(), frameMap, masm, frameContext, compilationResult); - crb.setFrameSize(frameMap.frameSize()); + crb.setTotalFrameSize(frameMap.totalFrameSize()); StackSlot deoptimizationRescueSlot = gen.getDeoptimizationRescueSlot(); if (deoptimizationRescueSlot != null && stub == null) { crb.compilationResult.setCustomStackAreaOffset(frameMap.offsetForStackSlot(deoptimizationRescueSlot)); @@ -264,7 +263,7 @@ */ public void emitCodePrefix(ResolvedJavaMethod installedCodeOwner, CompilationResultBuilder crb, AMD64MacroAssembler asm, RegisterConfig regConfig, HotSpotVMConfig config, Label verifiedEntry) { HotSpotProviders providers = getProviders(); - if (installedCodeOwner != null && !isStatic(installedCodeOwner.getModifiers())) { + if (installedCodeOwner != null && !installedCodeOwner.isStatic()) { MarkId.recordMark(crb, MarkId.UNVERIFIED_ENTRY); CallingConvention cc = regConfig.getCallingConvention(JavaCallee, null, new JavaType[]{providers.getMetaAccess().lookupJavaType(Object.class)}, getTarget(), false); Register inlineCacheKlass = rax; // see definition of IC_Klass in diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackendFactory.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackendFactory.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackendFactory.java Wed Apr 23 15:48:38 2014 +0200 @@ -27,6 +27,7 @@ import com.oracle.graal.amd64.*; import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.api.replacements.*; import com.oracle.graal.api.runtime.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.meta.*; @@ -108,10 +109,11 @@ // to be valid for the entire run of the VM. Assumptions assumptions = new Assumptions(false); Providers p = new Providers(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, null); - Replacements replacements = createReplacements(runtime, assumptions, p); + HotSpotSnippetReflectionProvider snippetReflection = createSnippetReflection(); + Replacements replacements = createReplacements(runtime, assumptions, p, snippetReflection); HotSpotDisassemblerProvider disassembler = createDisassembler(runtime); HotSpotSuitesProvider suites = createSuites(runtime); - HotSpotProviders providers = new HotSpotProviders(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, replacements, disassembler, suites, registers); + HotSpotProviders providers = new HotSpotProviders(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, replacements, disassembler, suites, registers, snippetReflection); return createBackend(runtime, providers); } @@ -128,8 +130,8 @@ return new HotSpotDisassemblerProvider(runtime); } - protected Replacements createReplacements(HotSpotGraalRuntime runtime, Assumptions assumptions, Providers p) { - return new HotSpotReplacementsImpl(p, runtime.getConfig(), assumptions, p.getCodeCache().getTarget()); + protected Replacements createReplacements(HotSpotGraalRuntime runtime, Assumptions assumptions, Providers p, SnippetReflectionProvider snippetReflection) { + return new HotSpotReplacementsImpl(p, snippetReflection, runtime.getConfig(), assumptions, p.getCodeCache().getTarget()); } protected AMD64HotSpotForeignCallsProvider createForeignCalls(HotSpotGraalRuntime runtime, HotSpotMetaAccessProvider metaAccess, HotSpotCodeCacheProvider codeCache, @@ -153,6 +155,10 @@ return new HotSpotSuitesProvider(runtime); } + protected HotSpotSnippetReflectionProvider createSnippetReflection() { + return new HotSpotSnippetReflectionProvider(); + } + protected AMD64HotSpotLoweringProvider createLowerer(HotSpotGraalRuntime runtime, HotSpotMetaAccessProvider metaAccess, HotSpotForeignCallsProvider foreignCalls, HotSpotRegistersProvider registers) { return new AMD64HotSpotLoweringProvider(runtime, metaAccess, foreignCalls, registers); } @@ -183,15 +189,15 @@ } else { /* * System V Application Binary Interface, AMD64 Architecture Processor Supplement - * + * * Draft Version 0.96 - * + * * http://www.uclibc.org/docs/psABI-x86_64.pdf - * + * * 3.2.1 - * + * * ... - * + * * This subsection discusses usage of each register. Registers %rbp, %rbx and %r12 * through %r15 "belong" to the calling function and the called function is required to * preserve their values. In other words, a called function must preserve these diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBytecodeLIRBuilder.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBytecodeLIRBuilder.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBytecodeLIRBuilder.java Wed Apr 23 15:48:38 2014 +0200 @@ -24,13 +24,12 @@ import static com.oracle.graal.amd64.AMD64.*; -import java.lang.reflect.*; - import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.gen.*; import com.oracle.graal.hotspot.amd64.AMD64HotSpotLIRGenerator.SaveRbp; import com.oracle.graal.lir.StandardOp.NoOp; +import com.oracle.graal.lir.gen.*; public class AMD64HotSpotBytecodeLIRBuilder extends BytecodeLIRBuilder { @@ -72,7 +71,7 @@ gen.append(getSaveRbp().placeholder); Signature sig = method.getSignature(); - boolean isStatic = Modifier.isStatic(method.getModifiers()); + boolean isStatic = method.isStatic(); for (int i = 0; i < sig.getParameterCount(!isStatic); i++) { Value paramValue = params[i]; assert paramValue.getKind() == sig.getParameterKind(i).getStackKind(); diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotDeoptimizeCallerOp.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotDeoptimizeCallerOp.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotDeoptimizeCallerOp.java Wed Apr 23 15:48:38 2014 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,6 +26,7 @@ import com.oracle.graal.asm.amd64.*; import com.oracle.graal.lir.*; +import com.oracle.graal.lir.StandardOp.*; import com.oracle.graal.lir.amd64.*; import com.oracle.graal.lir.asm.*; @@ -33,11 +34,11 @@ * Removes the current frame and tail calls the uncommon trap routine. */ @Opcode("DEOPT_CALLER") -final class AMD64HotSpotDeoptimizeCallerOp extends AMD64HotSpotEpilogueOp { +final class AMD64HotSpotDeoptimizeCallerOp extends AMD64HotSpotEpilogueOp implements BlockEndOp { @Override public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) { leaveFrameAndRestoreRbp(crb, masm); - AMD64Call.directJmp(crb, masm, crb.foreignCalls.lookupForeignCall(UNCOMMON_TRAP)); + AMD64Call.directJmp(crb, masm, crb.foreignCalls.lookupForeignCall(UNCOMMON_TRAP_HANDLER)); } } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotEnterUnpackFramesStackFrameOp.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotEnterUnpackFramesStackFrameOp.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2013, 2014, 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.amd64; + +import static com.oracle.graal.amd64.AMD64.*; +import static com.oracle.graal.api.code.ValueUtil.*; +import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.asm.amd64.*; +import com.oracle.graal.hotspot.stubs.*; +import com.oracle.graal.lir.*; +import com.oracle.graal.lir.amd64.*; +import com.oracle.graal.lir.asm.*; + +/** + * Emits code that enters a stack frame which is tailored to call the C++ method + * {@link DeoptimizationStub#UNPACK_FRAMES Deoptimization::unpack_frames}. + */ +@Opcode("ENTER_UNPACK_FRAMES_STACK_FRAME") +final class AMD64HotSpotEnterUnpackFramesStackFrameOp extends AMD64LIRInstruction { + + private final Register thread; + private final int threadLastJavaSpOffset; + private final int threadLastJavaPcOffset; + private final int threadLastJavaFpOffset; + @Alive(REG) AllocatableValue framePc; + @Alive(REG) AllocatableValue senderSp; + @Alive(REG) AllocatableValue senderFp; + + AMD64HotSpotEnterUnpackFramesStackFrameOp(Register thread, int threadLastJavaSpOffset, int threadLastJavaPcOffset, int threadLastJavaFpOffset, AllocatableValue framePc, AllocatableValue senderSp, + AllocatableValue senderFp) { + this.thread = thread; + this.threadLastJavaSpOffset = threadLastJavaSpOffset; + this.threadLastJavaPcOffset = threadLastJavaPcOffset; + this.threadLastJavaFpOffset = threadLastJavaFpOffset; + this.framePc = framePc; + this.senderSp = senderSp; + this.senderFp = senderFp; + } + + @Override + public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) { + final int totalFrameSize = crb.frameMap.totalFrameSize(); + masm.push(asRegister(framePc)); + masm.push(asRegister(senderFp)); + masm.movq(rbp, rsp); + + /* + * Allocate a full sized frame. Since return address and base pointer are already in place + * (see above) we allocate two words less. + */ + masm.decrementq(rsp, totalFrameSize - 2 * crb.target.wordSize); + + // Set up last Java values. + masm.movq(new AMD64Address(thread, threadLastJavaSpOffset), rsp); + + /* + * Save the PC since it cannot easily be retrieved using the last Java SP after we aligned + * SP. Don't need the precise return PC here, just precise enough to point into this code + * blob. + */ + masm.leaq(rax, new AMD64Address(rip, 0)); + masm.movq(new AMD64Address(thread, threadLastJavaPcOffset), rax); + + // Use BP because the frames look interpreted now. + masm.movq(new AMD64Address(thread, threadLastJavaFpOffset), rbp); + + // Align the stack for the following unpackFrames call. + masm.andq(rsp, -(crb.target.stackAlignment)); + } +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotEpilogueOp.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotEpilogueOp.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotEpilogueOp.java Wed Apr 23 15:48:38 2014 +0200 @@ -29,7 +29,6 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.amd64.*; -import com.oracle.graal.lir.StandardOp.BlockEndOp; import com.oracle.graal.lir.*; import com.oracle.graal.lir.amd64.*; import com.oracle.graal.lir.asm.*; @@ -37,7 +36,7 @@ /** * Superclass for operations that use the value of RBP saved in a method's prologue. */ -abstract class AMD64HotSpotEpilogueOp extends AMD64LIRInstruction implements BlockEndOp { +abstract class AMD64HotSpotEpilogueOp extends AMD64LIRInstruction { /** * The type of location (i.e., stack or register) in which RBP is saved is not known until diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotForeignCallsProvider.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotForeignCallsProvider.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotForeignCallsProvider.java Wed Apr 23 15:48:38 2014 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2014, 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 @@ -36,7 +36,7 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.graph.*; +import com.oracle.graal.compiler.common.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.meta.*; @@ -51,7 +51,8 @@ @Override public void initialize(HotSpotProviders providers, HotSpotVMConfig config) { - Kind word = providers.getCodeCache().getTarget().wordKind; + TargetDescription target = providers.getCodeCache().getTarget(); + Kind word = target.wordKind; // The calling convention for the exception handler stub is (only?) defined in // TemplateInterpreterGenerator::generate_throw_exception() @@ -62,6 +63,8 @@ register(new HotSpotForeignCallLinkage(EXCEPTION_HANDLER, 0L, PRESERVES_REGISTERS, LEAF_NOFP, null, exceptionCc, NOT_REEXECUTABLE, ANY_LOCATION)); register(new HotSpotForeignCallLinkage(EXCEPTION_HANDLER_IN_CALLER, JUMP_ADDRESS, PRESERVES_REGISTERS, LEAF_NOFP, exceptionCc, null, NOT_REEXECUTABLE, ANY_LOCATION)); + link(new AMD64DeoptimizationStub(providers, target, registerStubCall(UNCOMMON_TRAP_HANDLER, REEXECUTABLE, LEAF, NO_LOCATIONS))); + // When the java.ext.dirs property is modified then the crypto classes might not be found. // If that's the case we ignore the ClassNotFoundException and continue since we cannot // replace a non-existing method anyway. diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotJumpToExceptionHandlerInCallerOp.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotJumpToExceptionHandlerInCallerOp.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotJumpToExceptionHandlerInCallerOp.java Wed Apr 23 15:48:38 2014 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,6 +31,7 @@ import com.oracle.graal.asm.amd64.*; import com.oracle.graal.asm.amd64.AMD64Assembler.ConditionFlag; import com.oracle.graal.lir.*; +import com.oracle.graal.lir.StandardOp.*; import com.oracle.graal.lir.asm.*; /** @@ -38,7 +39,7 @@ * and jumps to the handler. */ @Opcode("JUMP_TO_EXCEPTION_HANDLER_IN_CALLER") -final class AMD64HotSpotJumpToExceptionHandlerInCallerOp extends AMD64HotSpotEpilogueOp { +final class AMD64HotSpotJumpToExceptionHandlerInCallerOp extends AMD64HotSpotEpilogueOp implements BlockEndOp { @Use(REG) AllocatableValue handlerInCallerPc; @Use(REG) AllocatableValue exception; diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerationResult.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerationResult.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerationResult.java Wed Apr 23 15:48:38 2014 +0200 @@ -25,10 +25,10 @@ import java.util.*; import com.oracle.graal.api.code.*; -import com.oracle.graal.compiler.gen.*; import com.oracle.graal.hotspot.stubs.*; import com.oracle.graal.lir.*; import com.oracle.graal.lir.StandardOp.SaveRegistersOp; +import com.oracle.graal.lir.gen.*; public class AMD64HotSpotLIRGenerationResult extends LIRGenerationResultBase { diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java Wed Apr 23 15:48:38 2014 +0200 @@ -25,6 +25,7 @@ import static com.oracle.graal.amd64.AMD64.*; import static com.oracle.graal.api.code.ValueUtil.*; import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; +import static com.oracle.graal.hotspot.nodes.UncommonTrapCallNode.*; import java.util.*; @@ -32,27 +33,26 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.amd64.*; -import com.oracle.graal.compiler.gen.*; -import com.oracle.graal.graph.*; +import com.oracle.graal.compiler.common.*; +import com.oracle.graal.compiler.common.calc.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.HotSpotVMConfig.CompressEncoding; -import com.oracle.graal.hotspot.amd64.AMD64HotSpotMove.LoadCompressedPointer; -import com.oracle.graal.hotspot.amd64.AMD64HotSpotMove.StoreCompressedConstantOp; -import com.oracle.graal.hotspot.amd64.AMD64HotSpotMove.StoreCompressedPointer; import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.hotspot.nodes.type.*; import com.oracle.graal.hotspot.stubs.*; import com.oracle.graal.lir.*; import com.oracle.graal.lir.StandardOp.NoOp; +import com.oracle.graal.lir.StandardOp.SaveRegistersOp; import com.oracle.graal.lir.amd64.*; +import com.oracle.graal.lir.amd64.AMD64ControlFlow.CondMoveOp; +import com.oracle.graal.lir.amd64.AMD64Move.CompareAndSwapOp; import com.oracle.graal.lir.amd64.AMD64Move.LeaDataOp; import com.oracle.graal.lir.amd64.AMD64Move.LoadOp; import com.oracle.graal.lir.amd64.AMD64Move.MoveFromRegOp; import com.oracle.graal.lir.amd64.AMD64Move.MoveToRegOp; import com.oracle.graal.lir.amd64.AMD64Move.StoreConstantOp; import com.oracle.graal.lir.amd64.AMD64Move.StoreOp; -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.extended.*; +import com.oracle.graal.lir.gen.*; /** * LIR generator specialized for AMD64 HotSpot. @@ -60,6 +60,7 @@ public class AMD64HotSpotLIRGenerator extends AMD64LIRGenerator implements HotSpotLIRGenerator { final HotSpotVMConfig config; + private HotSpotLockStack lockStack; protected AMD64HotSpotLIRGenerator(HotSpotProviders providers, HotSpotVMConfig config, CallingConvention cc, LIRGenerationResult lirGenRes) { super(providers, cc, lirGenRes); @@ -126,7 +127,17 @@ @Override public StackSlot getLockSlot(int lockDepth) { - return ((HotSpotDebugInfoBuilder) getDebugInfoBuilder()).lockStack().makeLockSlot(lockDepth); + return getLockStack().makeLockSlot(lockDepth); + } + + private HotSpotLockStack getLockStack() { + assert lockStack != null; + return lockStack; + } + + protected void setLockStack(HotSpotLockStack lockStack) { + assert this.lockStack == null; + this.lockStack = lockStack; } private Register findPollOnReturnScratchRegister() { @@ -155,7 +166,7 @@ } @Override - protected boolean needOnlyOopMaps() { + public boolean needOnlyOopMaps() { // Stubs only need oop maps return ((AMD64HotSpotLIRGenerationResult) getResult()).getStub() != null; } @@ -173,12 +184,65 @@ super.emitForeignCall(linkage, result, arguments, temps, info); } - protected AMD64SaveRegistersOp emitSaveRegisters(Register[] savedRegisters, StackSlot[] savedRegisterLocations) { - AMD64SaveRegistersOp save = new AMD64SaveRegistersOp(savedRegisters, savedRegisterLocations, true); + public void emitLeaveCurrentStackFrame() { + append(new AMD64HotSpotLeaveCurrentStackFrameOp()); + } + + public void emitLeaveDeoptimizedStackFrame(Value frameSize, Value initialInfo) { + Variable frameSizeVariable = load(frameSize); + Variable initialInfoVariable = load(initialInfo); + append(new AMD64HotSpotLeaveDeoptimizedStackFrameOp(frameSizeVariable, initialInfoVariable)); + } + + public void emitEnterUnpackFramesStackFrame(Value framePc, Value senderSp, Value senderFp) { + Register thread = getProviders().getRegisters().getThreadRegister(); + Variable framePcVariable = load(framePc); + Variable senderSpVariable = load(senderSp); + Variable senderFpVariable = load(senderFp); + append(new AMD64HotSpotEnterUnpackFramesStackFrameOp(thread, config.threadLastJavaSpOffset(), config.threadLastJavaPcOffset(), config.threadLastJavaFpOffset(), framePcVariable, + senderSpVariable, senderFpVariable)); + } + + public void emitLeaveUnpackFramesStackFrame() { + Register thread = getProviders().getRegisters().getThreadRegister(); + append(new AMD64HotSpotLeaveUnpackFramesStackFrameOp(thread, config.threadLastJavaSpOffset(), config.threadLastJavaPcOffset(), config.threadLastJavaFpOffset())); + } + + /** + * @param savedRegisters the registers saved by this operation which may be subject to pruning + * @param savedRegisterLocations the slots to which the registers are saved + * @param supportsRemove determines if registers can be pruned + */ + protected AMD64SaveRegistersOp emitSaveRegisters(Register[] savedRegisters, StackSlot[] savedRegisterLocations, boolean supportsRemove) { + AMD64SaveRegistersOp save = new AMD64SaveRegistersOp(savedRegisters, savedRegisterLocations, supportsRemove); append(save); return save; } + /** + * Adds a node to the graph that saves all allocatable registers to the stack. + * + * @param supportsRemove determines if registers can be pruned + * @return the register save node + */ + private AMD64SaveRegistersOp emitSaveAllRegisters(Register[] savedRegisters, boolean supportsRemove) { + StackSlot[] savedRegisterLocations = new StackSlot[savedRegisters.length]; + for (int i = 0; i < savedRegisters.length; i++) { + PlatformKind kind = target().arch.getLargestStorableKind(savedRegisters[i].getRegisterCategory()); + assert kind != Kind.Illegal; + StackSlot spillSlot = getResult().getFrameMap().allocateSpillSlot(kind); + savedRegisterLocations[i] = spillSlot; + } + return emitSaveRegisters(savedRegisters, savedRegisterLocations, supportsRemove); + } + + @Override + public SaveRegistersOp emitSaveAllRegisters() { + // We are saving all registers. + // TODO Save upper half of YMM registers. + return emitSaveAllRegisters(cpuxmmRegisters, false); + } + protected void emitRestoreRegisters(AMD64SaveRegistersOp save) { append(new AMD64RestoreRegistersOp(save.getSlots().clone(), save)); } @@ -188,32 +252,25 @@ } @Override - public Variable emitForeignCall(ForeignCallLinkage linkage, DeoptimizingNode info, Value... args) { + public Variable emitForeignCall(ForeignCallLinkage linkage, LIRFrameState state, Value... args) { HotSpotForeignCallLinkage hotspotLinkage = (HotSpotForeignCallLinkage) linkage; boolean destroysRegisters = hotspotLinkage.destroysRegisters(); AMD64SaveRegistersOp save = null; - StackSlot[] savedRegisterLocations = null; if (destroysRegisters) { if (getStub() != null) { if (getStub().preservesRegisters()) { Register[] savedRegisters = getResult().getFrameMap().registerConfig.getAllocatableRegisters(); - savedRegisterLocations = new StackSlot[savedRegisters.length]; - for (int i = 0; i < savedRegisters.length; i++) { - PlatformKind kind = target().arch.getLargestStorableKind(savedRegisters[i].getRegisterCategory()); - assert kind != Kind.Illegal; - StackSlot spillSlot = getResult().getFrameMap().allocateSpillSlot(kind); - savedRegisterLocations[i] = spillSlot; - } - save = emitSaveRegisters(savedRegisters, savedRegisterLocations); + save = emitSaveAllRegisters(savedRegisters, true); } } } Variable result; - DeoptimizingNode deoptInfo = null; + // TODO (je) check if we can remove this + LIRFrameState deoptInfo = null; if (hotspotLinkage.canDeoptimize()) { - deoptInfo = info; + deoptInfo = state; assert deoptInfo != null || getStub() != null; assert hotspotLinkage.needsJavaFrameAnchor(); } @@ -230,9 +287,9 @@ if (destroysRegisters) { if (getStub() != null) { if (getStub().preservesRegisters()) { - assert !((AMD64HotSpotLIRGenerationResult) getResult()).getCalleeSaveInfo().containsKey(currentRuntimeCallInfo); - ((AMD64HotSpotLIRGenerationResult) getResult()).getCalleeSaveInfo().put(currentRuntimeCallInfo, save); - + AMD64HotSpotLIRGenerationResult generationResult = (AMD64HotSpotLIRGenerationResult) getResult(); + assert !generationResult.getCalleeSaveInfo().containsKey(currentRuntimeCallInfo); + generationResult.getCalleeSaveInfo().put(currentRuntimeCallInfo, save); emitRestoreRegisters(save); } else { assert zapRegisters(); @@ -243,6 +300,21 @@ return result; } + public Value emitUncommonTrapCall(Value trapRequest, SaveRegistersOp saveRegisterOp) { + ForeignCallLinkage linkage = getForeignCalls().lookupForeignCall(UNCOMMON_TRAP); + + Register thread = getProviders().getRegisters().getThreadRegister(); + append(new AMD64HotSpotCRuntimeCallPrologueOp(config.threadLastJavaSpOffset(), thread)); + Variable result = super.emitForeignCall(linkage, null, thread.asValue(Kind.Long), trapRequest); + append(new AMD64HotSpotCRuntimeCallEpilogueOp(config.threadLastJavaSpOffset(), config.threadLastJavaFpOffset(), thread)); + + Map calleeSaveInfo = ((AMD64HotSpotLIRGenerationResult) getResult()).getCalleeSaveInfo(); + assert !calleeSaveInfo.containsKey(currentRuntimeCallInfo); + calleeSaveInfo.put(currentRuntimeCallInfo, saveRegisterOp); + + return result; + } + protected AMD64ZapRegistersOp emitZapRegisters(Register[] zappedRegisters, Constant[] zapValues) { AMD64ZapRegistersOp zap = new AMD64ZapRegistersOp(zappedRegisters, zapValues); append(zap); @@ -307,9 +379,9 @@ } @Override - public void emitDeoptimize(Value actionAndReason, Value speculation, DeoptimizingNode deopting) { + public void emitDeoptimize(Value actionAndReason, Value speculation, LIRFrameState state) { moveDeoptValuesToThread(actionAndReason, speculation); - append(new AMD64DeoptimizeOp(state(deopting))); + append(new AMD64DeoptimizeOp(state)); } @Override @@ -333,18 +405,16 @@ } /** - * Returns whether or not the input access should be (de)compressed. - */ - private boolean isCompressedOperation(PlatformKind kind, Access access) { - return access != null && access.isCompressible() && ((kind == Kind.Long && config.useCompressedClassPointers) || (kind == Kind.Object && config.useCompressedOops)); - } - - /** * @return a compressed version of the incoming constant */ protected static Constant compress(Constant c, CompressEncoding encoding) { if (c.getKind() == Kind.Long) { - return Constant.forIntegerKind(Kind.Int, (int) (((c.asLong() - encoding.base) >> encoding.shift) & 0xffffffffL), c.getPrimitiveAnnotation()); + int compressedValue = (int) (((c.asLong() - encoding.base) >> encoding.shift) & 0xffffffffL); + if (c instanceof HotSpotMetaspaceConstant) { + return HotSpotMetaspaceConstant.forMetaspaceObject(Kind.Int, compressedValue, HotSpotMetaspaceConstant.getMetaspaceObject(c)); + } else { + return Constant.forIntegerKind(Kind.Int, compressedValue); + } } else { throw GraalInternalError.shouldNotReachHere(); } @@ -366,100 +436,72 @@ } } + public void emitPushInterpreterFrame(Value frameSize, Value framePc, Value senderSp, Value initialInfo) { + Variable frameSizeVariable = load(frameSize); + Variable framePcVariable = load(framePc); + Variable senderSpVariable = load(senderSp); + Variable initialInfoVariable = load(initialInfo); + append(new AMD64HotSpotPushInterpreterFrameOp(frameSizeVariable, framePcVariable, senderSpVariable, initialInfoVariable)); + } + @Override - public Variable emitLoad(PlatformKind kind, Value address, Access access) { + public Variable emitLoad(PlatformKind kind, Value address, LIRFrameState state) { AMD64AddressValue loadAddress = asAddressValue(address); Variable result = newVariable(toStackKind(kind)); - LIRFrameState state = null; - if (access instanceof DeoptimizingNode) { - state = state((DeoptimizingNode) access); - } - /** - * Currently, the (de)compression of pointers applies conditionally to some objects (oops, - * kind==Object) and some addresses (klass pointers, kind==Long). Initially, the input - * operation is checked to discover if it has been tagged as a potential "compression" - * candidate. Consequently, depending on the appropriate kind, the specific (de)compression - * functions are being called. - */ - if (isCompressedOperation(kind, access)) { - if (kind == Kind.Object) { - append(new LoadCompressedPointer(Kind.Object, result, getProviders().getRegisters().getHeapBaseRegister().asValue(), loadAddress, state, config.getOopEncoding())); - } else if (kind == Kind.Long) { - Variable scratch = config.getKlassEncoding().base != 0 ? newVariable(Kind.Long) : null; - append(new LoadCompressedPointer(Kind.Long, result, scratch, loadAddress, state, config.getKlassEncoding())); - } else { - throw GraalInternalError.shouldNotReachHere("can't handle: " + access); - } - } else { - append(new LoadOp(getMemoryKind(kind), result, loadAddress, state)); - } + append(new LoadOp(getMemoryKind(kind), result, loadAddress, state)); return result; } @Override - public void emitStore(PlatformKind kind, Value address, Value inputVal, Access access) { + public void emitStore(PlatformKind kind, Value address, Value inputVal, LIRFrameState state) { AMD64AddressValue storeAddress = asAddressValue(address); - LIRFrameState state = null; - if (access instanceof DeoptimizingNode) { - state = state((DeoptimizingNode) access); - } - boolean isCompressed = isCompressedOperation(kind, access); if (isConstant(inputVal)) { Constant c = asConstant(inputVal); - if (canStoreConstant(c, isCompressed)) { - if (isCompressed) { - if (c.getKind() == Kind.Object) { - append(new StoreCompressedConstantOp(Kind.Object, storeAddress, c, state)); - } else if (c.getKind() == Kind.Long) { - // It's always a good idea to directly store compressed constants since they - // have to be materialized as 64 bits encoded otherwise. - Constant value = compress(c, config.getKlassEncoding()); - append(new StoreCompressedConstantOp(Kind.Long, storeAddress, value, state)); - } else { - throw GraalInternalError.shouldNotReachHere("can't handle: " + access); - } - return; - } else { - append(new StoreConstantOp(getMemoryKind(kind), storeAddress, c, state)); - return; - } + if (canStoreConstant(c, false)) { + append(new StoreConstantOp(getMemoryKind(kind), storeAddress, c, state)); + return; } } Variable input = load(inputVal); - if (isCompressed) { - if (kind == Kind.Object) { - if (input.getKind() == Kind.Object) { - Variable scratch = newVariable(Kind.Long); - Register heapBaseReg = getProviders().getRegisters().getHeapBaseRegister(); - append(new StoreCompressedPointer(Kind.Object, storeAddress, input, scratch, state, config.getOopEncoding(), heapBaseReg)); - } else { - // the input oop is already compressed - append(new StoreOp(input.getKind(), storeAddress, input, state)); - } - } else if (kind == Kind.Long) { - Variable scratch = newVariable(Kind.Long); - Register heapBaseReg = getProviders().getRegisters().getHeapBaseRegister(); - append(new StoreCompressedPointer(Kind.Long, storeAddress, input, scratch, state, config.getKlassEncoding(), heapBaseReg)); - } else { - append(new StoreOp(getMemoryKind(kind), storeAddress, input, state)); + append(new StoreOp(getMemoryKind(kind), storeAddress, input, state)); + } + + @Override + public Value emitCompress(Value pointer, CompressEncoding encoding, boolean nonNull) { + if (pointer.getPlatformKind() == Kind.Object) { + Variable result = newVariable(NarrowOopStamp.NarrowOop); + append(new AMD64HotSpotMove.CompressPointer(result, asAllocatable(pointer), getProviders().getRegisters().getHeapBaseRegister().asValue(), encoding, nonNull)); + return result; + } else { + assert pointer.getPlatformKind() == Kind.Long; + Variable result = newVariable(Kind.Int); + AllocatableValue base = Value.ILLEGAL; + if (encoding.base != 0) { + base = newVariable(Kind.Long); + append(new AMD64Move.MoveToRegOp(Kind.Long, base, Constant.forLong(encoding.base))); } - } else { - append(new StoreOp(getMemoryKind(kind), storeAddress, input, state)); + append(new AMD64HotSpotMove.CompressPointer(result, asAllocatable(pointer), base, encoding, nonNull)); + return result; } } @Override - public Value emitCompress(Value pointer, CompressEncoding encoding) { - Variable result = newVariable(NarrowOopStamp.NarrowOop); - append(new AMD64HotSpotMove.CompressPointer(result, asAllocatable(pointer), getProviders().getRegisters().getHeapBaseRegister().asValue(), encoding)); - return result; - } - - @Override - public Value emitUncompress(Value pointer, CompressEncoding encoding) { - Variable result = newVariable(Kind.Object); - append(new AMD64HotSpotMove.UncompressPointer(result, asAllocatable(pointer), getProviders().getRegisters().getHeapBaseRegister().asValue(), encoding)); - return result; + public Value emitUncompress(Value pointer, CompressEncoding encoding, boolean nonNull) { + if (pointer.getPlatformKind() == NarrowOopStamp.NarrowOop) { + Variable result = newVariable(Kind.Object); + append(new AMD64HotSpotMove.UncompressPointer(result, asAllocatable(pointer), getProviders().getRegisters().getHeapBaseRegister().asValue(), encoding, nonNull)); + return result; + } else { + assert pointer.getPlatformKind() == Kind.Int; + Variable result = newVariable(Kind.Long); + AllocatableValue base = Value.ILLEGAL; + if (encoding.base != 0) { + base = newVariable(Kind.Long); + append(new AMD64Move.MoveToRegOp(Kind.Long, base, Constant.forLong(encoding.base))); + } + append(new AMD64HotSpotMove.UncompressPointer(result, asAllocatable(pointer), base, encoding, nonNull)); + return result; + } } @Override @@ -475,4 +517,38 @@ } } + public Value emitCompareAndSwap(Value address, Value expectedValue, Value newValue, Value trueValue, Value falseValue) { + PlatformKind kind = newValue.getPlatformKind(); + assert kind == expectedValue.getPlatformKind(); + Kind memKind = getMemoryKind(kind); + + AMD64AddressValue addressValue = asAddressValue(address); + RegisterValue raxRes = AMD64.rax.asValue(kind); + emitMove(raxRes, expectedValue); + append(new CompareAndSwapOp(memKind, raxRes, addressValue, raxRes, asAllocatable(newValue))); + + assert trueValue.getPlatformKind() == falseValue.getPlatformKind(); + Variable result = newVariable(trueValue.getPlatformKind()); + append(new CondMoveOp(result, Condition.EQ, asAllocatable(trueValue), falseValue)); + return result; + } + + public Value emitAtomicReadAndAdd(Value address, Value delta) { + PlatformKind kind = delta.getPlatformKind(); + Kind memKind = getMemoryKind(kind); + Variable result = newVariable(kind); + AMD64AddressValue addressValue = asAddressValue(address); + append(new AMD64Move.AtomicReadAndAddOp(memKind, result, addressValue, asAllocatable(delta))); + return result; + } + + public Value emitAtomicReadAndWrite(Value address, Value newValue) { + PlatformKind kind = newValue.getPlatformKind(); + Kind memKind = getMemoryKind(kind); + Variable result = newVariable(kind); + AMD64AddressValue addressValue = asAddressValue(address); + append(new AMD64Move.AtomicReadAndWriteOp(memKind, result, addressValue, asAllocatable(newValue))); + return result; + } + } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLeaveCurrentStackFrameOp.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLeaveCurrentStackFrameOp.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2013, 2014, 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.amd64; + +import static com.oracle.graal.amd64.AMD64.*; + +import com.oracle.graal.asm.amd64.*; +import com.oracle.graal.lir.*; +import com.oracle.graal.lir.asm.*; + +/** + * Pops the current frame off the stack including the return address. + */ +@Opcode("LEAVE_CURRENT_STACK_FRAME") +final class AMD64HotSpotLeaveCurrentStackFrameOp extends AMD64HotSpotEpilogueOp { + + @Override + public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) { + leaveFrameAndRestoreRbp(crb, masm); + masm.addq(rsp, crb.target.arch.getReturnAddressSize()); + } +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLeaveDeoptimizedStackFrameOp.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLeaveDeoptimizedStackFrameOp.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.hotspot.amd64; + +import static com.oracle.graal.api.code.ValueUtil.*; +import static com.oracle.graal.amd64.AMD64.*; +import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.asm.amd64.*; +import com.oracle.graal.lir.*; +import com.oracle.graal.lir.asm.*; + +/** + * Pops the current frame off the stack including the return address. + */ +@Opcode("LEAVE_DEOPTIMIZED_STACK_FRAME") +final class AMD64HotSpotLeaveDeoptimizedStackFrameOp extends AMD64HotSpotEpilogueOp { + + @Use(REG) AllocatableValue frameSize; + @Use(REG) AllocatableValue framePointer; + + public AMD64HotSpotLeaveDeoptimizedStackFrameOp(AllocatableValue frameSize, AllocatableValue initialInfo) { + this.frameSize = frameSize; + this.framePointer = initialInfo; + } + + @Override + public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) { + masm.addq(rsp, asRegister(frameSize)); + // Restore the frame pointer before stack bang because if a stack overflow is thrown it + // needs to be pushed (and preserved). + masm.movq(rbp, asRegister(framePointer)); + } +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLeaveUnpackFramesStackFrameOp.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLeaveUnpackFramesStackFrameOp.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.hotspot.amd64; + +import static com.oracle.graal.amd64.AMD64.*; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.asm.amd64.*; +import com.oracle.graal.hotspot.stubs.*; +import com.oracle.graal.lir.*; +import com.oracle.graal.lir.amd64.*; +import com.oracle.graal.lir.asm.*; + +/** + * Emits code that leaves a stack frame which is tailored to call the C++ method + * {@link DeoptimizationStub#UNPACK_FRAMES Deoptimization::unpack_frames}. + */ +@Opcode("LEAVE_UNPACK_FRAMES_STACK_FRAME") +final class AMD64HotSpotLeaveUnpackFramesStackFrameOp extends AMD64LIRInstruction { + + private final Register thread; + private final int threadLastJavaSpOffset; + private final int threadLastJavaPcOffset; + private final int threadLastJavaFpOffset; + + AMD64HotSpotLeaveUnpackFramesStackFrameOp(Register thread, int threadLastJavaSpOffset, int threadLastJavaPcOffset, int threadLastJavaFpOffset) { + this.thread = thread; + this.threadLastJavaSpOffset = threadLastJavaSpOffset; + this.threadLastJavaPcOffset = threadLastJavaPcOffset; + this.threadLastJavaFpOffset = threadLastJavaFpOffset; + } + + @Override + public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) { + // Restore stack pointer. + masm.movq(rsp, new AMD64Address(thread, threadLastJavaSpOffset)); + + // Clear last Java frame values. + masm.movslq(new AMD64Address(thread, threadLastJavaSpOffset), 0); + masm.movslq(new AMD64Address(thread, threadLastJavaPcOffset), 0); + masm.movslq(new AMD64Address(thread, threadLastJavaFpOffset), 0); + } +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLoweringProvider.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLoweringProvider.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLoweringProvider.java Wed Apr 23 15:48:38 2014 +0200 @@ -41,7 +41,7 @@ @Override public void initialize(HotSpotProviders providers, HotSpotVMConfig config) { - convertSnippets = new AMD64ConvertSnippets.Templates(providers, providers.getCodeCache().getTarget()); + convertSnippets = new AMD64ConvertSnippets.Templates(providers, providers.getSnippetReflection(), providers.getCodeCache().getTarget()); super.initialize(providers, config); } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotMemoryPeephole.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotMemoryPeephole.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotMemoryPeephole.java Wed Apr 23 15:48:38 2014 +0200 @@ -28,15 +28,17 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.amd64.*; import com.oracle.graal.compiler.amd64.*; -import com.oracle.graal.graph.*; +import com.oracle.graal.compiler.common.*; +import com.oracle.graal.compiler.common.calc.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.data.*; +import com.oracle.graal.hotspot.meta.*; +import com.oracle.graal.hotspot.nodes.type.*; import com.oracle.graal.lir.*; import com.oracle.graal.lir.amd64.*; import com.oracle.graal.lir.amd64.AMD64ControlFlow.BranchOp; import com.oracle.graal.lir.asm.*; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.extended.*; /** @@ -63,9 +65,9 @@ masm.cmpl(x.toAddress(), 0); } else { if (y.getKind() == Kind.Object) { - crb.recordInlineDataInCode(new OopData(0, constant.asObject(), true)); + crb.recordInlineDataInCode(new OopData(0, HotSpotObjectConstant.asObject(constant), true)); } else if (y.getKind() == Kind.Long) { - crb.recordInlineDataInCode(new MetaspaceData(0, constant.asLong(), constant.getPrimitiveAnnotation(), true)); + crb.recordInlineDataInCode(new MetaspaceData(0, constant.asLong(), HotSpotMetaspaceConstant.getMetaspaceObject(constant), true)); } else { throw GraalInternalError.shouldNotReachHere(); } @@ -82,11 +84,21 @@ } @Override + protected Kind getMemoryKind(Access access) { + PlatformKind kind = gen.getLIRGenerator().getPlatformKind(access.asNode().stamp()); + if (kind == NarrowOopStamp.NarrowOop) { + return Kind.Int; + } else { + return (Kind) kind; + } + } + + @Override protected boolean emitCompareBranchMemory(ValueNode left, ValueNode right, Access access, Condition cond, boolean unorderedIsTrue, LabelRef trueLabel, LabelRef falseLabel, double trueLabelProbability) { if (HotSpotGraalRuntime.runtime().getConfig().useCompressedOops) { ValueNode other = selectOtherInput(left, right, access); - Kind kind = access.accessLocation().getValueKind(); + Kind kind = getMemoryKind(access); if (other.isConstant() && kind == Kind.Object && access.isCompressible()) { ensureEvaluated(other); diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotMove.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotMove.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotMove.java Wed Apr 23 15:48:38 2014 +0200 @@ -31,10 +31,10 @@ import com.oracle.graal.asm.*; import com.oracle.graal.asm.amd64.*; import com.oracle.graal.asm.amd64.AMD64Assembler.ConditionFlag; -import com.oracle.graal.graph.*; +import com.oracle.graal.compiler.common.*; import com.oracle.graal.hotspot.HotSpotVMConfig.CompressEncoding; import com.oracle.graal.hotspot.data.*; -import com.oracle.graal.hotspot.nodes.type.*; +import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.lir.*; import com.oracle.graal.lir.amd64.*; import com.oracle.graal.lir.amd64.AMD64Move.LoadOp; @@ -53,8 +53,8 @@ public void emitMemAccess(CompilationResultBuilder crb, AMD64MacroAssembler masm) { if (kind == Kind.Long) { if (NumUtil.isInt(input.asLong())) { - if (input.getPrimitiveAnnotation() != null) { - crb.recordInlineDataInCode(new MetaspaceData(0, input.asLong(), input.getPrimitiveAnnotation(), true)); + if (input instanceof HotSpotMetaspaceConstant) { + crb.recordInlineDataInCode(new MetaspaceData(0, input.asLong(), HotSpotMetaspaceConstant.getMetaspaceObject(input), true)); } masm.movl(address.toAddress(), (int) input.asLong()); } else { @@ -64,7 +64,7 @@ if (input.isNull()) { masm.movl(address.toAddress(), 0); } else if (crb.target.inlineObjects) { - crb.recordInlineDataInCode(new OopData(0, input.asObject(), true)); + crb.recordInlineDataInCode(new OopData(0, HotSpotObjectConstant.asObject(input), true)); masm.movl(address.toAddress(), 0xDEADDEAD); } else { throw GraalInternalError.shouldNotReachHere("Cannot store 64-bit constants to memory"); @@ -78,25 +78,36 @@ public static class CompressPointer extends AMD64LIRInstruction { private final CompressEncoding encoding; + private final boolean nonNull; @Def({REG, HINT}) protected AllocatableValue result; @Use({REG}) protected AllocatableValue input; - @Temp({REG, ILLEGAL}) protected AllocatableValue baseRegister; + @Alive({REG, ILLEGAL}) protected AllocatableValue baseRegister; - public CompressPointer(AllocatableValue result, AllocatableValue input, AllocatableValue baseRegister, CompressEncoding encoding) { + public CompressPointer(AllocatableValue result, AllocatableValue input, AllocatableValue baseRegister, CompressEncoding encoding, boolean nonNull) { this.result = result; this.input = input; this.baseRegister = baseRegister; this.encoding = encoding; + this.nonNull = nonNull; } @Override public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) { - if (result.getPlatformKind() == NarrowOopStamp.NarrowOop) { - AMD64Move.move(Kind.Long, crb, masm, result, input); - encodePointer(masm, asRegister(result), asRegister(baseRegister), encoding); - } else { - throw GraalInternalError.unimplemented(); + AMD64Move.move(Kind.Long, crb, masm, result, input); + + Register resReg = asRegister(result); + if (encoding.base != 0) { + Register baseReg = asRegister(baseRegister); + if (!nonNull) { + masm.testq(resReg, resReg); + masm.cmovq(ConditionFlag.Equal, resReg, baseReg); + } + masm.subq(resReg, baseReg); + } + + if (encoding.shift != 0) { + masm.shrq(resReg, encoding.shift); } } } @@ -104,25 +115,43 @@ public static class UncompressPointer extends AMD64LIRInstruction { private final CompressEncoding encoding; + private final boolean nonNull; @Def({REG, HINT}) protected AllocatableValue result; @Use({REG}) protected AllocatableValue input; - @Temp({REG, ILLEGAL}) protected AllocatableValue baseRegister; + @Alive({REG, ILLEGAL}) protected AllocatableValue baseRegister; - public UncompressPointer(AllocatableValue result, AllocatableValue input, AllocatableValue baseRegister, CompressEncoding encoding) { + public UncompressPointer(AllocatableValue result, AllocatableValue input, AllocatableValue baseRegister, CompressEncoding encoding, boolean nonNull) { this.result = result; this.input = input; this.baseRegister = baseRegister; this.encoding = encoding; + this.nonNull = nonNull; } @Override public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) { - if (result.getKind() == Kind.Object) { - AMD64Move.move(Kind.Int, crb, masm, result, input); - decodePointer(masm, asRegister(result), asRegister(baseRegister), encoding); - } else { - throw GraalInternalError.unimplemented(); + AMD64Move.move(Kind.Int, crb, masm, result, input); + + Register resReg = asRegister(result); + if (encoding.shift != 0) { + masm.shlq(resReg, encoding.shift); + } + + if (encoding.base != 0) { + if (nonNull) { + masm.addq(resReg, asRegister(baseRegister)); + } else { + if (encoding.shift == 0) { + // if encoding.shift != 0, the flags are already set by the shlq + masm.testq(resReg, resReg); + } + + Label done = new Label(); + masm.jccb(ConditionFlag.Equal, done); + masm.addq(resReg, asRegister(baseRegister)); + masm.bind(done); + } } } } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotNodeLIRBuilder.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotNodeLIRBuilder.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotNodeLIRBuilder.java Wed Apr 23 15:48:38 2014 +0200 @@ -26,8 +26,6 @@ import static com.oracle.graal.api.code.ValueUtil.*; import static com.oracle.graal.hotspot.HotSpotBackend.*; -import java.lang.reflect.*; - import com.oracle.graal.amd64.*; import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; @@ -39,17 +37,14 @@ import com.oracle.graal.graph.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.amd64.AMD64HotSpotLIRGenerator.SaveRbp; -import com.oracle.graal.hotspot.amd64.AMD64HotSpotMove.CompareAndSwapCompressedOp; import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.hotspot.nodes.*; import com.oracle.graal.lir.*; import com.oracle.graal.lir.StandardOp.NoOp; import com.oracle.graal.lir.amd64.*; -import com.oracle.graal.lir.amd64.AMD64ControlFlow.CondMoveOp; import com.oracle.graal.lir.amd64.AMD64Move.CompareAndSwapOp; +import com.oracle.graal.lir.gen.*; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.calc.*; -import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind; /** @@ -60,6 +55,9 @@ public AMD64HotSpotNodeLIRBuilder(StructuredGraph graph, LIRGenerator gen) { super(graph, gen); memoryPeephole = new AMD64HotSpotMemoryPeephole(this); + assert gen instanceof AMD64HotSpotLIRGenerator; + assert getDebugInfoBuilder() instanceof HotSpotDebugInfoBuilder; + ((AMD64HotSpotLIRGenerator) gen).setLockStack(((HotSpotDebugInfoBuilder) getDebugInfoBuilder()).lockStack()); } private AMD64HotSpotLIRGenerator getGen() { @@ -111,7 +109,7 @@ @Override public void visitSafepointNode(SafepointNode i) { - LIRFrameState info = gen.state(i); + LIRFrameState info = state(i); append(new AMD64HotSpotSafepointOp(info, getGen().config, this)); } @@ -123,9 +121,8 @@ } else { assert invokeKind == InvokeKind.Static || invokeKind == InvokeKind.Special; HotSpotResolvedJavaMethod resolvedMethod = (HotSpotResolvedJavaMethod) callTarget.target(); - assert !Modifier.isAbstract(resolvedMethod.getModifiers()) : "Cannot make direct call to abstract method."; - Constant metaspaceMethod = resolvedMethod.getMetaspaceMethodConstant(); - append(new AMD64HotspotDirectStaticCallOp(callTarget.target(), result, parameters, temps, callState, invokeKind, metaspaceMethod)); + assert !resolvedMethod.isAbstract() : "Cannot make direct call to abstract method."; + append(new AMD64HotspotDirectStaticCallOp(callTarget.target(), result, parameters, temps, callState, invokeKind)); } } @@ -165,7 +162,7 @@ @Override public void visitInfopointNode(InfopointNode i) { - if (i.getState() != null && i.getState().bci == FrameState.AFTER_BCI) { + if (i.getState() != null && i.getState().bci == BytecodeFrame.AFTER_BCI) { Debug.log("Ignoring InfopointNode for AFTER_BCI"); } else { super.visitInfopointNode(i); @@ -198,32 +195,10 @@ RegisterValue raxLocal = AMD64.rax.asValue(kind); gen.emitMove(raxLocal, expected); - append(new CompareAndSwapOp(raxLocal, address, raxLocal, newVal)); + append(new CompareAndSwapOp(kind, raxLocal, address, raxLocal, newVal)); Variable result = newVariable(x.getKind()); gen.emitMove(result, raxLocal); setResult(x, result); } - - @Override - public void visitCompareAndSwap(LoweredCompareAndSwapNode node, Value address) { - Kind kind = node.getNewValue().getKind(); - assert kind == node.getExpectedValue().getKind(); - Value expected = gen.loadNonConst(operand(node.getExpectedValue())); - Variable newValue = gen.load(operand(node.getNewValue())); - AMD64AddressValue addressValue = getGen().asAddressValue(address); - RegisterValue raxRes = AMD64.rax.asValue(kind); - gen.emitMove(raxRes, expected); - if (getGen().config.useCompressedOops && node.isCompressible()) { - Variable scratch = newVariable(Kind.Long); - Register heapBaseReg = getGen().getProviders().getRegisters().getHeapBaseRegister(); - append(new CompareAndSwapCompressedOp(raxRes, addressValue, raxRes, newValue, scratch, getGen().config.getOopEncoding(), heapBaseReg)); - } else { - append(new CompareAndSwapOp(raxRes, addressValue, raxRes, newValue)); - } - Variable result = newVariable(node.getKind()); - append(new CondMoveOp(result, Condition.EQ, gen.load(Constant.TRUE), Constant.FALSE)); - setResult(node, result); - } - } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotPushInterpreterFrameOp.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotPushInterpreterFrameOp.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.hotspot.amd64; + +import static com.oracle.graal.amd64.AMD64.*; +import static com.oracle.graal.api.code.ValueUtil.*; +import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.asm.amd64.*; +import com.oracle.graal.hotspot.*; +import com.oracle.graal.lir.*; +import com.oracle.graal.lir.amd64.*; +import com.oracle.graal.lir.asm.*; + +/** + * Pushes an interpreter frame to the stack. + */ +@Opcode("PUSH_INTERPRETER_FRAME") +final class AMD64HotSpotPushInterpreterFrameOp extends AMD64LIRInstruction { + + @Alive(REG) AllocatableValue frameSize; + @Alive(REG) AllocatableValue framePc; + @Alive(REG) AllocatableValue senderSp; + @Alive(REG) AllocatableValue initialInfo; + + AMD64HotSpotPushInterpreterFrameOp(AllocatableValue frameSize, AllocatableValue framePc, AllocatableValue senderSp, AllocatableValue initialInfo) { + this.frameSize = frameSize; + this.framePc = framePc; + this.senderSp = senderSp; + this.initialInfo = initialInfo; + } + + @Override + public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) { + final Register frameSizeRegister = asRegister(frameSize); + final Register framePcRegister = asRegister(framePc); + final Register senderSpRegister = asRegister(senderSp); + final Register initialInfoRegister = asRegister(initialInfo); + final HotSpotVMConfig config = HotSpotGraalRuntime.runtime().getConfig(); + final int wordSize = HotSpotGraalRuntime.runtime().getTarget().wordSize; + + // We'll push PC and BP by hand. + masm.subq(frameSizeRegister, 2 * wordSize); + + // Push return address. + masm.push(framePcRegister); + + // Prolog + masm.push(initialInfoRegister); + masm.movq(initialInfoRegister, rsp); + masm.subq(rsp, frameSizeRegister); + + // This value is corrected by layout_activation_impl. + masm.movptr(new AMD64Address(initialInfoRegister, config.frameInterpreterFrameLastSpOffset * wordSize), 0); + + // Make the frame walkable. + masm.movq(new AMD64Address(initialInfoRegister, config.frameInterpreterFrameSenderSpOffset * wordSize), senderSpRegister); + } +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRegisterConfig.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRegisterConfig.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRegisterConfig.java Wed Apr 23 15:48:38 2014 +0200 @@ -23,7 +23,7 @@ package com.oracle.graal.hotspot.amd64; import static com.oracle.graal.amd64.AMD64.*; -import static com.oracle.graal.phases.GraalOptions.*; +import static com.oracle.graal.compiler.common.GraalOptions.*; import java.util.*; @@ -31,10 +31,9 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.code.CallingConvention.Type; import com.oracle.graal.api.meta.*; -import com.oracle.graal.graph.*; +import com.oracle.graal.compiler.common.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.nodes.type.*; -import com.oracle.graal.phases.*; public class AMD64HotSpotRegisterConfig implements RegisterConfig { diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotReturnOp.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotReturnOp.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotReturnOp.java Wed Apr 23 15:48:38 2014 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,13 +29,14 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.amd64.*; import com.oracle.graal.lir.*; +import com.oracle.graal.lir.StandardOp.*; import com.oracle.graal.lir.asm.*; /** * Returns from a function. */ @Opcode("RETURN") -final class AMD64HotSpotReturnOp extends AMD64HotSpotEpilogueOp { +final class AMD64HotSpotReturnOp extends AMD64HotSpotEpilogueOp implements BlockEndOp { @Use({REG, ILLEGAL}) protected Value value; private final boolean isStub; diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotSafepointOp.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotSafepointOp.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotSafepointOp.java Wed Apr 23 15:48:38 2014 +0200 @@ -24,7 +24,7 @@ import static com.oracle.graal.amd64.AMD64.*; import static com.oracle.graal.asm.NumUtil.*; -import static com.oracle.graal.phases.GraalOptions.*; +import static com.oracle.graal.compiler.common.GraalOptions.*; import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; @@ -77,7 +77,7 @@ if (ImmutableCode.getValue()) { Kind hostWordKind = HotSpotGraalRuntime.getHostWordKind(); int alignment = hostWordKind.getBitCount() / Byte.SIZE; - Constant pollingPageAddress = Constant.forIntegerKind(hostWordKind, config.safepointPollingAddress, null); + Constant pollingPageAddress = Constant.forIntegerKind(hostWordKind, config.safepointPollingAddress); // This move will be patched to load the safepoint page from a data segment // co-located with the immutable code. asm.movq(scratch, (AMD64Address) crb.recordDataReferenceInCode(pollingPageAddress, alignment)); diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotUnwindOp.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotUnwindOp.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotUnwindOp.java Wed Apr 23 15:48:38 2014 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,6 +31,7 @@ import com.oracle.graal.asm.amd64.*; import com.oracle.graal.hotspot.stubs.*; import com.oracle.graal.lir.*; +import com.oracle.graal.lir.StandardOp.*; import com.oracle.graal.lir.amd64.*; import com.oracle.graal.lir.asm.*; @@ -38,7 +39,7 @@ * Removes the current frame and jumps to the {@link UnwindExceptionToCallerStub}. */ @Opcode("UNWIND") -final class AMD64HotSpotUnwindOp extends AMD64HotSpotEpilogueOp { +final class AMD64HotSpotUnwindOp extends AMD64HotSpotEpilogueOp implements BlockEndOp { @Use({REG}) protected RegisterValue exception; diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotspotDirectStaticCallOp.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotspotDirectStaticCallOp.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotspotDirectStaticCallOp.java Wed Apr 23 15:48:38 2014 +0200 @@ -22,42 +22,32 @@ */ package com.oracle.graal.hotspot.amd64; -import com.oracle.graal.amd64.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.amd64.*; -import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.meta.HotSpotCodeCacheProvider.MarkId; import com.oracle.graal.lir.*; import com.oracle.graal.lir.amd64.AMD64Call.DirectCallOp; -import com.oracle.graal.lir.amd64.*; import com.oracle.graal.lir.asm.*; import com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind; /** - * A direct call that complies with the conventions for such calls in HotSpot. In particular, for - * calls using an inline cache, a MOVE instruction is emitted just prior to the aligned direct call. + * A direct call that complies with the conventions for such calls in HotSpot. It doesn't use an + * inline cache so it's just a patchable call site. */ @Opcode("CALL_DIRECT") final class AMD64HotspotDirectStaticCallOp extends DirectCallOp { - private final Constant metaspaceMethod; private final InvokeKind invokeKind; - AMD64HotspotDirectStaticCallOp(ResolvedJavaMethod target, Value result, Value[] parameters, Value[] temps, LIRFrameState state, InvokeKind invokeKind, Constant metaspaceMethod) { + AMD64HotspotDirectStaticCallOp(ResolvedJavaMethod target, Value result, Value[] parameters, Value[] temps, LIRFrameState state, InvokeKind invokeKind) { super(target, result, parameters, temps, state); assert invokeKind == InvokeKind.Static || invokeKind == InvokeKind.Special; - this.metaspaceMethod = metaspaceMethod; this.invokeKind = invokeKind; } @Override public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) { - // The mark for an invocation that uses an inline cache must be placed at the - // instruction that loads the Klass from the inline cache. - AMD64Move.move(crb, masm, AMD64.rbx.asValue(Kind.Long), metaspaceMethod); MarkId.recordMark(crb, invokeKind == InvokeKind.Static ? MarkId.INVOKESTATIC : MarkId.INVOKESPECIAL); - // This must be emitted exactly like this to ensure it's patchable - masm.movq(AMD64.rax, HotSpotGraalRuntime.runtime().getConfig().nonOopBits); super.emitCode(crb, masm); } } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64PrefetchOp.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64PrefetchOp.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64PrefetchOp.java Wed Apr 23 15:48:38 2014 +0200 @@ -26,7 +26,7 @@ import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; import com.oracle.graal.asm.amd64.*; -import com.oracle.graal.graph.*; +import com.oracle.graal.compiler.common.*; import com.oracle.graal.lir.amd64.*; import com.oracle.graal.lir.asm.*; diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64RawNativeCallNode.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64RawNativeCallNode.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64RawNativeCallNode.java Wed Apr 23 15:48:38 2014 +0200 @@ -26,11 +26,11 @@ import com.oracle.graal.api.code.CallingConvention.Type; import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.amd64.*; +import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.compiler.gen.*; import com.oracle.graal.compiler.target.*; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.type.*; public class AMD64RawNativeCallNode extends FixedWithNextNode implements LIRGenLowerable { diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/DonorThreadPool.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/DonorThreadPool.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2014, 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.hsail; + +import static com.oracle.graal.hotspot.hsail.HSAILHotSpotBackend.Options.*; + +import java.util.concurrent.*; + +import com.oracle.graal.hotspot.hsail.HSAILHotSpotBackend.Options; + +/** + * Thread pool for HSAIL allocation support. + */ +public class DonorThreadPool { + + private final Thread[] threads; + + void waitAt(CyclicBarrier barrier) { + try { + barrier.await(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + /** + * Creates a pool of threads whose size is given by {@link Options#HsailDonorThreads}. + */ + DonorThreadPool() { + int size = HsailDonorThreads.getValue(); + this.threads = new Thread[size]; + CyclicBarrier barrier = new CyclicBarrier(size + 1); + + // fill in threads + for (int i = 0; i < size; i++) { + threads[i] = new Thread(new Runnable() { + @Override + public void run() { + while (true) { + waitAt(barrier); + } + } + }, "HsailDonorThread-" + i); + threads[i].setDaemon(true); + threads[i].start(); + } + // creating thread waits at barrier to make sure others have started + waitAt(barrier); + } + + public Thread[] getThreads() { + return threads; + } +} \ No newline at end of file diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/ForEachToGraal.java --- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/ForEachToGraal.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/ForEachToGraal.java Wed Apr 23 15:48:38 2014 +0200 @@ -62,7 +62,7 @@ * @param intConsumerClass a class implementing {@code java.util.function.IntConsumer} * @return a {@link HotSpotNmethod} handle to the compiled and installed kernel */ - private static HotSpotNmethod getCompiledLambda(Class intConsumerClass) { + private static HotSpotNmethod getCompiledLambda(Class intConsumerClass) { Method acceptMethod = null; for (Method m : intConsumerClass.getMethods()) { if (m.getName().equals("accept")) { diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotAssembler.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotAssembler.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2009, 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.hsail; + +import java.lang.reflect.*; + +import com.amd.okra.*; +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.asm.hsail.*; +import com.oracle.graal.hotspot.meta.*; + +/** + * This class contains routines to emit HSAIL assembly code. + */ +public class HSAILHotSpotAssembler extends HSAILAssembler { + + public HSAILHotSpotAssembler(TargetDescription target) { + super(target); + } + + @Override + public final void mov(Register a, Constant src) { + String regName = "$d" + a.encoding(); + // For a null object simply move 0x0 into the destination register. + if (src.isNull()) { + emitString("mov_b64 " + regName + ", 0x0; // null object"); + } else { + Object obj = HotSpotObjectConstant.asObject(src); + // Get a JNI reference handle to the object. + long refHandle = OkraUtil.getRefHandle(obj); + // Get the clasname of the object for emitting a comment. + Class clazz = obj.getClass(); + String className = clazz.getName(); + String comment = "// handle for object of type " + className; + // If the object is an array note the array length in the comment. + if (className.startsWith("[")) { + comment += ", length " + Array.getLength(obj); + } + // First move the reference handle into a register. + emitString("mov_b64 " + regName + ", 0x" + Long.toHexString(refHandle) + "; " + comment); + // Next load the Object addressed by this reference handle into the destination reg. + emitString("ld_global_u64 " + regName + ", [" + regName + "];"); + } + } +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackend.java --- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackend.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackend.java Wed Apr 23 15:48:38 2014 +0200 @@ -27,6 +27,8 @@ import static com.oracle.graal.api.code.ValueUtil.*; import static com.oracle.graal.api.meta.LocationIdentity.*; import static com.oracle.graal.compiler.GraalCompiler.*; +import static com.oracle.graal.hotspot.hsail.HSAILHotSpotBackend.Options.*; +import static com.oracle.graal.hotspot.hsail.replacements.HSAILNewObjectSnippets.Options.*; import java.lang.reflect.*; import java.util.*; @@ -44,11 +46,13 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.*; import com.oracle.graal.asm.hsail.*; +import com.oracle.graal.compiler.common.*; +import com.oracle.graal.compiler.common.cfg.*; +import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.compiler.gen.*; import com.oracle.graal.debug.*; import com.oracle.graal.debug.Debug.Scope; import com.oracle.graal.gpu.*; -import com.oracle.graal.graph.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.bridge.CompilerToVM.CodeInstallResult; import com.oracle.graal.hotspot.meta.*; @@ -57,14 +61,16 @@ import com.oracle.graal.java.*; import com.oracle.graal.lir.*; import com.oracle.graal.lir.asm.*; +import com.oracle.graal.lir.gen.*; import com.oracle.graal.lir.hsail.*; -import com.oracle.graal.lir.hsail.HSAILControlFlow.DeoptimizeOp; +import com.oracle.graal.lir.hsail.HSAILControlFlow.DeoptimizingOp; +import com.oracle.graal.lir.hsail.HSAILMove.AtomicReadAndAddOp; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.StructuredGraph.GuardsStage; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.java.*; -import com.oracle.graal.nodes.type.*; +import com.oracle.graal.options.*; import com.oracle.graal.phases.*; import com.oracle.graal.phases.tiers.*; @@ -73,6 +79,14 @@ */ public class HSAILHotSpotBackend extends HotSpotBackend { + public static class Options { + + // @formatter:off + @Option(help = "Number of donor threads for HSAIL kernel dispatch") + static public final OptionValue HsailDonorThreads = new OptionValue<>(4); + // @formatter:on + } + private Map paramTypeMap = new HashMap<>(); private final boolean deviceInitialized; // TODO: get maximum Concurrency from okra @@ -103,18 +117,6 @@ private static native boolean initialize(); /** - * Control how many threads run on simulator (used only from junit tests). - */ - public void setSimulatorSingleThreaded() { - String simThrEnv = System.getenv("SIMTHREADS"); - if (simThrEnv == null || !simThrEnv.equals("1")) { - setSimulatorSingleThreaded0(); - } - } - - private static native void setSimulatorSingleThreaded0(); - - /** * Determines if the GPU device (or simulator) is available and initialized. */ public boolean isDeviceInitialized() { @@ -257,7 +259,7 @@ Debug.log("Param count: %d", parameterTypes.length); for (int i = 0; i < parameterTypes.length; i++) { ParameterNode parameter = hostGraph.getParameter(i); - Debug.log("Param [%d]=%d", i, parameter); + Debug.log("Param [%d]=%s", i, parameter); parameterTypes[i] = parameter.stamp().javaType(hostBackend.getProviders().getMetaAccess()); Debug.log(" %s", parameterTypes[i]); } @@ -293,7 +295,7 @@ assert hsailCode.getDataReferences().isEmpty(); // from host code - result.setFrameSize(hostCode.getFrameSize()); + result.setTotalFrameSize(hostCode.getTotalFrameSize()); result.setCustomStackAreaOffset(hostCode.getCustomStackAreaOffset()); result.setRegisterRestoreEpilogueOffset(hostCode.getRegisterRestoreEpilogueOffset()); result.setTargetCode(hostCode.getTargetCode(), hostCode.getTargetCodeSize()); @@ -347,15 +349,23 @@ return result; } + private static final ThreadLocal donorThreadPool = new ThreadLocal() { + @Override + protected DonorThreadPool initialValue() { + return new DonorThreadPool(); + } + }; + public boolean executeKernel(HotSpotInstalledCode kernel, int jobSize, Object[] args) throws InvalidInstalledCodeException { if (!deviceInitialized) { throw new GraalInternalError("Cannot execute GPU kernel if device is not initialized"); } Object[] oopsSaveArea = new Object[maxDeoptIndex * 16]; - return executeKernel0(kernel, jobSize, args, oopsSaveArea); + return executeKernel0(kernel, jobSize, args, oopsSaveArea, donorThreadPool.get().getThreads(), HsailAllocBytesPerWorkitem.getValue()); } - private static native boolean executeKernel0(HotSpotInstalledCode kernel, int jobSize, Object[] args, Object[] oopsSave) throws InvalidInstalledCodeException; + private static native boolean executeKernel0(HotSpotInstalledCode kernel, int jobSize, Object[] args, Object[] oopsSave, Thread[] donorThreads, int allocBytesPerWorkitem) + throws InvalidInstalledCodeException; /** * Use the HSAIL register set when the compilation target is HSAIL. @@ -412,7 +422,7 @@ @Override protected Assembler createAssembler(FrameMap frameMap) { - return new HSAILAssembler(getTarget()); + return new HSAILHotSpotAssembler(getTarget()); } @Override @@ -423,15 +433,32 @@ // save lirGen for later use by setHostGraph CompilationResultBuilder crb = new HSAILCompilationResultBuilder(getCodeCache(), getForeignCalls(), frameMap, masm, frameContext, compilationResult, (HSAILHotSpotLIRGenerationResult) lirGenRes); - crb.setFrameSize(frameMap.frameSize()); + crb.setTotalFrameSize(frameMap.totalFrameSize()); return crb; } @Override public void emitCode(CompilationResultBuilder crb, LIR lir, ResolvedJavaMethod method) { assert method != null : lir + " is not associated with a method"; + Kind wordKind = getProviders().getCodeCache().getTarget().wordKind; - boolean useHSAILDeoptimization = getRuntime().getConfig().useHSAILDeoptimization; + HotSpotVMConfig config = getRuntime().getConfig(); + boolean useHSAILDeoptimization = config.useHSAILDeoptimization; + boolean useHSAILSafepoints = config.useHSAILSafepoints; + + // see what graph nodes we have to see if we are using the thread register + // if not, we don't have to emit the code that sets that up + // maybe there is a better way to do this? + boolean usesThreadRegister = false; + search: for (AbstractBlock b : lir.linearScanOrder()) { + for (LIRInstruction op : lir.getLIRforBlock(b)) { + if (op instanceof AtomicReadAndAddOp) { + usesThreadRegister = true; + assert useHSAILDeoptimization : "cannot use thread register if HSAIL deopt support is disabled"; + break search; + } + } + } // Emit the prologue. HSAILAssembler asm = (HSAILAssembler) crb.asm; @@ -442,7 +469,7 @@ // We're subtracting 1 because we're not making the final gid as a parameter. int nonConstantParamCount = sigParamCount - 1; - boolean isStatic = (Modifier.isStatic(method.getModifiers())); + boolean isStatic = (method.isStatic()); // Determine if this is an object lambda. boolean isObjectLambda = true; @@ -542,18 +569,51 @@ String workItemReg = "$s" + Integer.toString(asRegister(cc.getArgument(nonConstantParamCount)).encoding()); asm.emitString("workitemabsid_u32 " + workItemReg + ", 0;"); - final int offsetToDeopt = getRuntime().getConfig().hsailDeoptOffset; final String deoptInProgressLabel = "@LHandleDeoptInProgress"; if (useHSAILDeoptimization) { - AllocatableValue scratch64 = HSAIL.d16.asValue(Kind.Object); - AllocatableValue scratch32 = HSAIL.s34.asValue(Kind.Int); - HSAILAddress deoptInfoAddr = new HSAILAddressValue(Kind.Int, scratch64, offsetToDeopt).toAddress(); - asm.emitLoadKernelArg(scratch64, asm.getDeoptInfoName(), "u64"); - asm.emitComment("// Check if a deopt has occurred and abort if true before doing any work"); - asm.emitLoadAcquire(scratch32, deoptInfoAddr); - asm.emitCompare(scratch32, Constant.forInt(0), "ne", false, false); + // Aliases for d16 + RegisterValue d16_deoptInfo = HSAIL.d16.asValue(wordKind); + RegisterValue d16_donorThreads = d16_deoptInfo; + + // Aliases for d17 + RegisterValue d17_donorThreadIndex = HSAIL.d17.asValue(wordKind); + RegisterValue d17_safepointFlagAddrIndex = d17_donorThreadIndex; + + // Aliases for s34 + RegisterValue s34_deoptOccurred = HSAIL.s34.asValue(Kind.Int); + RegisterValue s34_donorThreadIndex = s34_deoptOccurred; + + asm.emitLoadKernelArg(d16_deoptInfo, asm.getDeoptInfoName(), "u64"); + asm.emitComment("// Check if a deopt or safepoint has occurred and abort if true before doing any work"); + + if (useHSAILSafepoints) { + // Load address of _notice_safepoints field + asm.emitLoad(wordKind, d17_safepointFlagAddrIndex, new HSAILAddressValue(wordKind, d16_deoptInfo, config.hsailNoticeSafepointsOffset).toAddress()); + // Load int value from that field + asm.emitLoadAcquire(s34_deoptOccurred, new HSAILAddressValue(Kind.Int, d17_safepointFlagAddrIndex, 0).toAddress()); + asm.emitCompare(Kind.Int, s34_deoptOccurred, Constant.forInt(0), "ne", false, false); + asm.cbr(deoptInProgressLabel); + } + asm.emitLoadAcquire(s34_deoptOccurred, new HSAILAddressValue(Kind.Int, d16_deoptInfo, config.hsailDeoptOccurredOffset).toAddress()); + asm.emitCompare(Kind.Int, s34_deoptOccurred, Constant.forInt(0), "ne", false, false); asm.cbr(deoptInProgressLabel); + // load thread register if needed + if (usesThreadRegister) { + assert HsailDonorThreads.getValue() > 0; + asm.emitLoad(wordKind, d16_donorThreads, new HSAILAddressValue(wordKind, d16_deoptInfo, config.hsailDonorThreadsOffset).toAddress()); + if (HsailDonorThreads.getValue() != 1) { + asm.emitComment("// map workitem to a donor thread"); + asm.emitString(String.format("rem_u32 $%s, %s, %d;", s34_donorThreadIndex.getRegister(), workItemReg, HsailDonorThreads.getValue())); + asm.emitConvert(d17_donorThreadIndex, s34_donorThreadIndex, wordKind, Kind.Int); + asm.emit("mad", d16_donorThreads, d17_donorThreadIndex, Constant.forInt(8), d16_donorThreads); + } else { + // workitem is already mapped to solitary donor thread + } + AllocatableValue threadRegValue = getProviders().getRegisters().getThreadRegister().asValue(wordKind); + asm.emitComment("// $" + getProviders().getRegisters().getThreadRegister() + " will point to a donor thread for this workitem"); + asm.emitLoad(wordKind, threadRegValue, new HSAILAddressValue(wordKind, d16_donorThreads).toAddress()); + } } /* @@ -566,8 +626,8 @@ asm.emitString(spillsegTemplate); // Emit object array load prologue here. if (isObjectLambda) { - boolean useCompressedOops = getRuntime().getConfig().useCompressedOops; - final int arrayElementsOffset = HotSpotGraalRuntime.getArrayBaseOffset(Kind.Object); + boolean useCompressedOops = config.useCompressedOops; + final int arrayElementsOffset = HotSpotGraalRuntime.getArrayBaseOffset(wordKind); String iterationObjArgReg = HSAIL.mapRegister(cc.getArgument(nonConstantParamCount - 1)); // iterationObjArgReg will be the highest $d register in use (it is the last parameter) // so tempReg can be the next higher $d register @@ -586,8 +646,8 @@ // Load u32 into the d 64 reg since it will become an object address asm.emitString("ld_global_u32 " + tmpReg + ", " + "[" + tmpReg + "]" + "; // Load compressed ptr from array"); - long narrowOopBase = getRuntime().getConfig().narrowOopBase; - long narrowOopShift = getRuntime().getConfig().narrowOopShift; + long narrowOopBase = config.narrowOopBase; + long narrowOopShift = config.narrowOopShift; if (narrowOopBase == 0 && narrowOopShift == 0) { // No more calculation to do, mov to target register @@ -629,36 +689,36 @@ // TODO: keep track of whether we need it if (useHSAILDeoptimization) { - final int offsetToDeoptSaveStates = getRuntime().getConfig().hsailSaveStatesOffset0; - final int sizeofKernelDeopt = getRuntime().getConfig().hsailSaveStatesOffset1 - getRuntime().getConfig().hsailSaveStatesOffset0; - final int offsetToNeverRanArray = getRuntime().getConfig().hsailNeverRanArrayOffset; - final int offsetToDeoptNextIndex = getRuntime().getConfig().hsailDeoptNextIndexOffset; - final int offsetToDeoptimizationWorkItem = getRuntime().getConfig().hsailDeoptimizationWorkItem; - final int offsetToDeoptimizationReason = getRuntime().getConfig().hsailDeoptimizationReason; - final int offsetToDeoptimizationFrame = getRuntime().getConfig().hsailDeoptimizationFrame; - final int offsetToFramePc = getRuntime().getConfig().hsailFramePcOffset; - final int offsetToNumSaves = getRuntime().getConfig().hsailFrameNumSRegOffset; - final int offsetToSaveArea = getRuntime().getConfig().hsailFrameSaveAreaOffset; + final int offsetToDeoptSaveStates = config.hsailSaveStatesOffset0; + final int sizeofKernelDeopt = config.hsailSaveStatesOffset1 - config.hsailSaveStatesOffset0; + final int offsetToNeverRanArray = config.hsailNeverRanArrayOffset; + final int offsetToDeoptNextIndex = config.hsailDeoptNextIndexOffset; + final int offsetToDeoptimizationWorkItem = config.hsailDeoptimizationWorkItem; + final int offsetToDeoptimizationReason = config.hsailDeoptimizationReason; + final int offsetToDeoptimizationFrame = config.hsailDeoptimizationFrame; + final int offsetToFramePc = config.hsailFramePcOffset; + final int offsetToNumSaves = config.hsailFrameNumSRegOffset; + final int offsetToSaveArea = config.hsailFrameSaveAreaOffset; - AllocatableValue scratch64 = HSAIL.d16.asValue(Kind.Object); - AllocatableValue cuSaveAreaPtr = HSAIL.d17.asValue(Kind.Object); - AllocatableValue waveMathScratch1 = HSAIL.d18.asValue(Kind.Object); - AllocatableValue waveMathScratch2 = HSAIL.d19.asValue(Kind.Object); + AllocatableValue scratch64 = HSAIL.d16.asValue(wordKind); + AllocatableValue cuSaveAreaPtr = HSAIL.d17.asValue(wordKind); + AllocatableValue waveMathScratch1 = HSAIL.d18.asValue(wordKind); + AllocatableValue waveMathScratch2 = HSAIL.d19.asValue(wordKind); - AllocatableValue actionAndReasonReg = HSAIL.s32.asValue(Kind.Int); - AllocatableValue codeBufferOffsetReg = HSAIL.s33.asValue(Kind.Int); + AllocatableValue actionAndReasonReg = HSAIL.actionAndReasonReg.asValue(Kind.Int); + AllocatableValue codeBufferOffsetReg = HSAIL.codeBufferOffsetReg.asValue(Kind.Int); AllocatableValue scratch32 = HSAIL.s34.asValue(Kind.Int); AllocatableValue workidreg = HSAIL.s35.asValue(Kind.Int); - AllocatableValue dregOopMapReg = HSAIL.s39.asValue(Kind.Int); + AllocatableValue dregOopMapReg = HSAIL.dregOopMapReg.asValue(Kind.Int); HSAILAddress deoptNextIndexAddr = new HSAILAddressValue(Kind.Int, scratch64, offsetToDeoptNextIndex).toAddress(); HSAILAddress neverRanArrayAddr = new HSAILAddressValue(Kind.Int, scratch64, offsetToNeverRanArray).toAddress(); // The just-started lanes that see the deopt flag will jump here asm.emitString0(deoptInProgressLabel + ":\n"); - asm.emitLoad(Kind.Object, waveMathScratch1, neverRanArrayAddr); + asm.emitLoad(wordKind, waveMathScratch1, neverRanArrayAddr); asm.emitWorkItemAbsId(workidreg); - asm.emitConvert(waveMathScratch2, workidreg, Kind.Object, Kind.Int); + asm.emitConvert(waveMathScratch2, workidreg, wordKind, Kind.Int); asm.emit("add", waveMathScratch1, waveMathScratch1, waveMathScratch2); HSAILAddress neverRanStoreAddr = new HSAILAddressValue(Kind.Byte, waveMathScratch1, 0).toAddress(); asm.emitStore(Kind.Byte, Constant.forInt(1), neverRanStoreAddr); @@ -668,7 +728,7 @@ asm.emitString0(asm.getDeoptLabelName() + ":\n"); String labelExit = asm.getDeoptLabelName() + "_Exit"; - HSAILAddress deoptInfoAddr = new HSAILAddressValue(Kind.Int, scratch64, offsetToDeopt).toAddress(); + HSAILAddress deoptInfoAddr = new HSAILAddressValue(Kind.Int, scratch64, config.hsailDeoptOccurredOffset).toAddress(); asm.emitLoadKernelArg(scratch64, asm.getDeoptInfoName(), "u64"); // Set deopt occurred flag @@ -680,7 +740,7 @@ // scratch32 now holds next index to use // set error condition if no room in save area asm.emitComment("// assert room to save deopt"); - asm.emitCompare(scratch32, Constant.forInt(maxDeoptIndex), "lt", false, false); + asm.emitCompare(Kind.Int, scratch32, Constant.forInt(maxDeoptIndex), "lt", false, false); asm.cbr("@L_StoreDeopt"); // if assert fails, store a guaranteed negative workitemid in top level deopt occurred // flag @@ -694,7 +754,7 @@ // Store deopt for this workitem into its slot in the HSAILComputeUnitSaveStates array asm.emitComment("// Convert id's for ptr math"); - asm.emitConvert(cuSaveAreaPtr, scratch32, Kind.Object, Kind.Int); + asm.emitConvert(cuSaveAreaPtr, scratch32, wordKind, Kind.Int); asm.emitComment("// multiply by sizeof KernelDeoptArea"); asm.emit("mul", cuSaveAreaPtr, cuSaveAreaPtr, Constant.forInt(sizeofKernelDeopt)); asm.emitComment("// Add computed offset to deoptInfoPtr base"); @@ -725,9 +785,7 @@ asm.emitStore(Kind.Short, dregOopMapReg, dregOopMapAddr); // get the union of registers needed to be saved at the infopoints - // usedRegs array assumes d15 has the highest register number we wish to save - // and initially has all registers as false - boolean[] infoUsedRegs = new boolean[HSAIL.d15.number + 1]; + boolean[] infoUsedRegs = new boolean[HSAIL.threadRegister.number + 1]; List infoList = crb.compilationResult.getInfopoints(); for (Infopoint info : infoList) { BytecodeFrame frame = info.debugInfo.frame(); @@ -784,10 +842,10 @@ ExternalCompilationResult compilationResult = (ExternalCompilationResult) crb.compilationResult; HSAILHotSpotLIRGenerationResult lirGenRes = ((HSAILCompilationResultBuilder) crb).lirGenRes; - compilationResult.setHostGraph(prepareHostGraph(method, lirGenRes.getDeopts(), getProviders(), getRuntime().getConfig())); + compilationResult.setHostGraph(prepareHostGraph(method, lirGenRes.getDeopts(), getProviders(), config)); } - private static StructuredGraph prepareHostGraph(ResolvedJavaMethod method, List deopts, HotSpotProviders providers, HotSpotVMConfig config) { + private static StructuredGraph prepareHostGraph(ResolvedJavaMethod method, List deopts, HotSpotProviders providers, HotSpotVMConfig config) { if (deopts.isEmpty()) { return null; } @@ -796,17 +854,17 @@ ParameterNode hsailFrame = hostGraph.unique(new ParameterNode(1, StampFactory.forKind(providers.getCodeCache().getTarget().wordKind))); ParameterNode reasonAndAction = hostGraph.unique(new ParameterNode(2, StampFactory.intValue())); ParameterNode speculation = hostGraph.unique(new ParameterNode(3, StampFactory.object())); - AbstractBeginNode[] branches = new AbstractBeginNode[deopts.size() + 1]; + BeginNode[] branches = new BeginNode[deopts.size() + 1]; int[] keys = new int[deopts.size()]; int[] keySuccessors = new int[deopts.size() + 1]; double[] keyProbabilities = new double[deopts.size() + 1]; int i = 0; - Collections.sort(deopts, new Comparator() { - public int compare(DeoptimizeOp o1, DeoptimizeOp o2) { + Collections.sort(deopts, new Comparator() { + public int compare(DeoptimizingOp o1, DeoptimizingOp o2) { return o1.getCodeBufferPos() - o2.getCodeBufferPos(); } }); - for (DeoptimizeOp deopt : deopts) { + for (DeoptimizingOp deopt : deopts) { keySuccessors[i] = i; keyProbabilities[i] = 1.0 / deopts.size(); keys[i] = deopt.getCodeBufferPos(); @@ -828,15 +886,14 @@ return hostGraph; } - private static AbstractBeginNode createHostCrashBranch(StructuredGraph hostGraph, ValueNode deoptId) { + private static BeginNode createHostCrashBranch(StructuredGraph hostGraph, ValueNode deoptId) { VMErrorNode vmError = hostGraph.add(new VMErrorNode("Error in HSAIL deopt. DeoptId=%d", deoptId)); // ConvertNode.convert(hostGraph, Kind.Long, deoptId))); vmError.setNext(hostGraph.add(new ReturnNode(ConstantNode.defaultForKind(hostGraph.method().getSignature().getReturnKind(), hostGraph)))); return BeginNode.begin(vmError); } - private static AbstractBeginNode createHostDeoptBranch(DeoptimizeOp deopt, ParameterNode hsailFrame, ValueNode reasonAndAction, ValueNode speculation, HotSpotProviders providers, - HotSpotVMConfig config) { + private static BeginNode createHostDeoptBranch(DeoptimizingOp deopt, ParameterNode hsailFrame, ValueNode reasonAndAction, ValueNode speculation, HotSpotProviders providers, HotSpotVMConfig config) { BeginNode branch = hsailFrame.graph().add(new BeginNode()); DynamicDeoptimizeNode deoptimization = hsailFrame.graph().add(new DynamicDeoptimizeNode(reasonAndAction, speculation)); deoptimization.setStateBefore(createFrameState(deopt.getFrameState().topFrame, hsailFrame, providers, config)); @@ -868,7 +925,7 @@ return frameState; } - @SuppressWarnings({"unused"}) + @SuppressWarnings("unused") private static MonitorIdNode getMonitorIdForHotSpotMonitorValueFromFrame(HotSpotMonitorValue lockValue, ParameterNode hsailFrame, StructuredGraph hsailGraph) { if (lockValue.isEliminated()) { return null; @@ -910,7 +967,7 @@ int longSize = providers.getCodeCache().getTarget().arch.getSizeInBytes(Kind.Long); long offset = config.hsailFrameSaveAreaOffset + longSize * (regNumber - HSAIL.d0.number); LocationNode numSRegsLocation = ConstantLocationNode.create(FINAL_LOCATION, Kind.Byte, config.hsailFrameNumSRegOffset, hostGraph); - ValueNode numSRegs = hostGraph.unique(new FloatingReadNode(hsailFrame, numSRegsLocation, null, StampFactory.forInteger(8, false))); + ValueNode numSRegs = hostGraph.unique(new FloatingReadNode(hsailFrame, numSRegsLocation, null, StampFactory.forInteger(8))); numSRegs = SignExtendNode.convert(numSRegs, StampFactory.forKind(Kind.Byte)); location = IndexedLocationNode.create(FINAL_LOCATION, valueKind, offset, numSRegs, hostGraph, 4); } else { diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackendFactory.java --- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackendFactory.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackendFactory.java Wed Apr 23 15:48:38 2014 +0200 @@ -28,10 +28,10 @@ import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.hsail.*; -import com.oracle.graal.java.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.phases.tiers.*; import com.oracle.graal.phases.util.*; +import com.oracle.graal.hotspot.hsail.replacements.*; @ServiceProvider(HotSpotBackendFactory.class) public class HSAILHotSpotBackendFactory implements HotSpotBackendFactory { @@ -40,7 +40,7 @@ public HSAILHotSpotBackend createBackend(HotSpotGraalRuntime runtime, HotSpotBackend hostBackend) { HotSpotProviders host = hostBackend.getProviders(); - HotSpotRegisters registers = new HotSpotRegisters(Register.None, Register.None, Register.None); + HotSpotRegisters registers = new HotSpotRegisters(HSAIL.threadRegister, Register.None, Register.None); HotSpotMetaAccessProvider metaAccess = host.getMetaAccess(); HSAILHotSpotCodeCacheProvider codeCache = new HSAILHotSpotCodeCacheProvider(runtime, createTarget()); ConstantReflectionProvider constantReflection = host.getConstantReflection(); @@ -50,10 +50,13 @@ // to be valid for the entire run of the VM. Assumptions assumptions = new Assumptions(false); Providers p = new Providers(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, null); - Replacements replacements = new HSAILHotSpotReplacementsImpl(p, assumptions, codeCache.getTarget(), host.getReplacements()); + Replacements replacements = new HSAILHotSpotReplacementsImpl(p, host.getSnippetReflection(), assumptions, codeCache.getTarget(), host.getReplacements()); HotSpotDisassemblerProvider disassembler = host.getDisassembler(); - SuitesProvider suites = new DefaultSuitesProvider(); - HotSpotProviders providers = new HotSpotProviders(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, replacements, disassembler, suites, registers); + SuitesProvider suites = new HotSpotSuitesProvider(runtime); + HotSpotProviders providers = new HotSpotProviders(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, replacements, disassembler, suites, registers, host.getSnippetReflection()); + + // pass registers info down to ReplacementsUtil (maybe a better way to do this?) + HSAILHotSpotReplacementsUtil.initialize(providers.getRegisters()); return new HSAILHotSpotBackend(runtime, providers); } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotLIRGenerationResult.java --- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotLIRGenerationResult.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotLIRGenerationResult.java Wed Apr 23 15:48:38 2014 +0200 @@ -24,23 +24,23 @@ import java.util.*; -import com.oracle.graal.compiler.gen.*; import com.oracle.graal.lir.*; -import com.oracle.graal.lir.hsail.HSAILControlFlow.DeoptimizeOp; +import com.oracle.graal.lir.gen.*; +import com.oracle.graal.lir.hsail.HSAILControlFlow.DeoptimizingOp; public class HSAILHotSpotLIRGenerationResult extends LIRGenerationResultBase { - private List deopts = new ArrayList<>(); + private List deopts = new ArrayList<>(); public HSAILHotSpotLIRGenerationResult(LIR lir, FrameMap frameMap) { super(lir, frameMap); } - public List getDeopts() { + public List getDeopts() { return deopts; } - public void addDeopt(DeoptimizeOp deopt) { + public void addDeopt(DeoptimizingOp deopt) { deopts.add(deopt); } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotLIRGenerator.java --- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotLIRGenerator.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotLIRGenerator.java Wed Apr 23 15:48:38 2014 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2014, 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 @@ -27,28 +27,28 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.compiler.gen.*; +import com.oracle.graal.compiler.common.*; +import com.oracle.graal.compiler.common.calc.*; import com.oracle.graal.compiler.hsail.*; -import com.oracle.graal.graph.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.HotSpotVMConfig.CompressEncoding; import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.hotspot.nodes.type.*; import com.oracle.graal.lir.*; +import com.oracle.graal.lir.StandardOp.SaveRegistersOp; +import com.oracle.graal.lir.gen.*; import com.oracle.graal.lir.hsail.*; +import com.oracle.graal.lir.hsail.HSAILControlFlow.CondMoveOp; import com.oracle.graal.lir.hsail.HSAILControlFlow.DeoptimizeOp; import com.oracle.graal.lir.hsail.HSAILControlFlow.ForeignCall1ArgOp; import com.oracle.graal.lir.hsail.HSAILControlFlow.ForeignCall2ArgOp; import com.oracle.graal.lir.hsail.HSAILControlFlow.ForeignCallNoArgOp; -import com.oracle.graal.lir.hsail.HSAILMove.LoadCompressedPointer; +import com.oracle.graal.lir.hsail.HSAILMove.CompareAndSwapOp; import com.oracle.graal.lir.hsail.HSAILMove.LoadOp; import com.oracle.graal.lir.hsail.HSAILMove.MoveFromRegOp; import com.oracle.graal.lir.hsail.HSAILMove.MoveToRegOp; -import com.oracle.graal.lir.hsail.HSAILMove.StoreCompressedPointer; import com.oracle.graal.lir.hsail.HSAILMove.StoreConstantOp; import com.oracle.graal.lir.hsail.HSAILMove.StoreOp; -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.extended.*; import com.oracle.graal.phases.util.*; /** @@ -92,22 +92,11 @@ return config.narrowKlassBase; } - private static boolean isCompressCandidate(Access access) { - return access != null && access.isCompressible(); - } - @Override public boolean canStoreConstant(Constant c, boolean isCompressed) { return true; } - /** - * Returns whether or not the input access should be (de)compressed. - */ - private boolean isCompressedOperation(PlatformKind kind, Access access) { - return access != null && access.isCompressible() && ((kind == Kind.Long && config.useCompressedClassPointers) || (kind == Kind.Object && config.useCompressedOops)); - } - private static Kind getMemoryKind(PlatformKind kind) { if (kind == NarrowOopStamp.NarrowOop) { return Kind.Int; @@ -117,20 +106,10 @@ } @Override - public Variable emitLoad(PlatformKind kind, Value address, Access access) { + public Variable emitLoad(PlatformKind kind, Value address, LIRFrameState state) { HSAILAddressValue loadAddress = asAddressValue(address); Variable result = newVariable(kind); - LIRFrameState state = null; - if (access instanceof DeoptimizingNode) { - state = state((DeoptimizingNode) access); - } - if (isCompressCandidate(access) && config.useCompressedOops && kind == Kind.Object) { - Variable scratch = newVariable(Kind.Long); - append(new LoadCompressedPointer(Kind.Object, result, scratch, loadAddress, state, getNarrowOopBase(), getNarrowOopShift(), getLogMinObjectAlignment())); - } else if (isCompressCandidate(access) && config.useCompressedClassPointers && kind == Kind.Long) { - Variable scratch = newVariable(Kind.Long); - append(new LoadCompressedPointer(Kind.Object, result, scratch, loadAddress, state, getNarrowKlassBase(), getNarrowKlassShift(), getLogKlassAlignment())); - } else if (kind == NarrowOopStamp.NarrowOop) { + if (kind == NarrowOopStamp.NarrowOop) { append(new LoadOp(Kind.Int, result, loadAddress, state)); } else { append(new LoadOp(getMemoryKind(kind), result, loadAddress, state)); @@ -139,49 +118,51 @@ } @Override - public void emitStore(PlatformKind kind, Value address, Value inputVal, Access access) { + public void emitStore(PlatformKind kind, Value address, Value inputVal, LIRFrameState state) { HSAILAddressValue storeAddress = asAddressValue(address); - LIRFrameState state = null; - if (access instanceof DeoptimizingNode) { - state = state((DeoptimizingNode) access); - } - boolean isCompressed = isCompressedOperation(kind, access); if (isConstant(inputVal)) { Constant c = asConstant(inputVal); - if (canStoreConstant(c, isCompressed)) { - if (isCompressed) { - if ((c.getKind() == Kind.Object) && c.isNull()) { - append(new StoreConstantOp(Kind.Int, storeAddress, Constant.forInt(0), state)); - } else if (c.getKind() == Kind.Long) { - Constant value = compress(c, config.getKlassEncoding()); - append(new StoreConstantOp(Kind.Int, storeAddress, value, state)); - } else { - throw GraalInternalError.shouldNotReachHere("can't handle: " + access); - } - return; - } else { - append(new StoreConstantOp(getMemoryKind(kind), storeAddress, c, state)); - return; - } + if (canStoreConstant(c, false)) { + append(new StoreConstantOp(getMemoryKind(kind), storeAddress, c, state)); + return; } } Variable input = load(inputVal); - if (isCompressCandidate(access) && config.useCompressedOops && kind == Kind.Object) { - Variable scratch = newVariable(Kind.Long); - append(new StoreCompressedPointer(Kind.Object, storeAddress, input, scratch, state, getNarrowOopBase(), getNarrowOopShift(), getLogMinObjectAlignment())); - } else if (isCompressCandidate(access) && config.useCompressedClassPointers && kind == Kind.Long) { - Variable scratch = newVariable(Kind.Long); - append(new StoreCompressedPointer(Kind.Object, storeAddress, input, scratch, state, getNarrowKlassBase(), getNarrowKlassShift(), getLogKlassAlignment())); - } else if (kind == NarrowOopStamp.NarrowOop) { + if (kind == NarrowOopStamp.NarrowOop) { append(new StoreOp(Kind.Int, storeAddress, input, state)); } else { append(new StoreOp(getMemoryKind(kind), storeAddress, input, state)); } } + public Value emitCompareAndSwap(Value address, Value expectedValue, Value newValue, Value trueValue, Value falseValue) { + PlatformKind kind = newValue.getPlatformKind(); + assert kind == expectedValue.getPlatformKind(); + Kind memKind = getMemoryKind(kind); + + HSAILAddressValue addressValue = asAddressValue(address); + Variable expected = emitMove(expectedValue); + Variable casResult = newVariable(kind); + append(new CompareAndSwapOp(memKind, casResult, addressValue, expected, asAllocatable(newValue))); + + assert trueValue.getPlatformKind() == falseValue.getPlatformKind(); + Variable nodeResult = newVariable(trueValue.getPlatformKind()); + append(new CondMoveOp(HSAILLIRGenerator.mapKindToCompareOp(memKind), casResult, expected, nodeResult, Condition.EQ, trueValue, falseValue)); + return nodeResult; + } + + public Value emitAtomicReadAndAdd(Value address, Value delta) { + PlatformKind kind = delta.getPlatformKind(); + Kind memKind = getMemoryKind(kind); + Variable result = newVariable(kind); + HSAILAddressValue addressValue = asAddressValue(address); + append(new HSAILMove.AtomicReadAndAddOp(memKind, result, addressValue, asAllocatable(delta))); + return result; + } + @Override - public void emitDeoptimize(Value actionAndReason, Value failedSpeculation, DeoptimizingNode deopting) { - emitDeoptimizeInner(actionAndReason, state(deopting), "emitDeoptimize"); + public void emitDeoptimize(Value actionAndReason, Value failedSpeculation, LIRFrameState state) { + emitDeoptimizeInner(actionAndReason, state, "emitDeoptimize"); } /*** @@ -199,7 +180,7 @@ * emitting a comment as to what Foreign call they would have made. */ @Override - public Variable emitForeignCall(ForeignCallLinkage linkage, DeoptimizingNode info, Value... args) { + public Variable emitForeignCall(ForeignCallLinkage linkage, LIRFrameState state, Value... args) { Variable result = newVariable(Kind.Object); // linkage.getDescriptor().getResultType()); // to make the LIRVerifier happy, we move any constants into registers @@ -252,33 +233,68 @@ */ protected static Constant compress(Constant c, CompressEncoding encoding) { if (c.getKind() == Kind.Long) { - return Constant.forIntegerKind(Kind.Int, (int) (((c.asLong() - encoding.base) >> encoding.shift) & 0xffffffffL), c.getPrimitiveAnnotation()); + int compressedValue = (int) (((c.asLong() - encoding.base) >> encoding.shift) & 0xffffffffL); + if (c instanceof HotSpotMetaspaceConstant) { + return HotSpotMetaspaceConstant.forMetaspaceObject(Kind.Int, compressedValue, HotSpotMetaspaceConstant.getMetaspaceObject(c)); + } else { + return Constant.forIntegerKind(Kind.Int, compressedValue); + } } else { throw GraalInternalError.shouldNotReachHere(); } } public void emitTailcall(Value[] args, Value address) { - throw GraalInternalError.shouldNotReachHere("NYI"); + throw GraalInternalError.unimplemented(); } public void emitDeoptimizeCaller(DeoptimizationAction action, DeoptimizationReason reason) { - throw GraalInternalError.shouldNotReachHere("NYI"); + throw GraalInternalError.unimplemented(); } public StackSlot getLockSlot(int lockDepth) { - throw GraalInternalError.shouldNotReachHere("NYI"); + throw GraalInternalError.unimplemented(); } - public Value emitCompress(Value pointer, CompressEncoding encoding) { + @Override + public Value emitCompress(Value pointer, CompressEncoding encoding, boolean nonNull) { Variable result = newVariable(NarrowOopStamp.NarrowOop); - append(new HSAILMove.CompressPointer(result, newVariable(pointer.getPlatformKind()), asAllocatable(pointer), encoding.base, encoding.shift, encoding.alignment)); + append(new HSAILMove.CompressPointer(result, newVariable(pointer.getPlatformKind()), asAllocatable(pointer), encoding.base, encoding.shift, encoding.alignment, nonNull)); + return result; + } + + @Override + public Value emitUncompress(Value pointer, CompressEncoding encoding, boolean nonNull) { + Variable result = newVariable(Kind.Object); + append(new HSAILMove.UncompressPointer(result, asAllocatable(pointer), encoding.base, encoding.shift, encoding.alignment, nonNull)); return result; } - public Value emitUncompress(Value pointer, CompressEncoding encoding) { - Variable result = newVariable(Kind.Object); - append(new HSAILMove.UncompressPointer(result, asAllocatable(pointer), encoding.base, encoding.shift, encoding.alignment)); - return result; + public void emitLeaveCurrentStackFrame() { + throw GraalInternalError.unimplemented(); + } + + public void emitLeaveDeoptimizedStackFrame(Value frameSize, Value initialInfo) { + throw GraalInternalError.unimplemented(); + } + + public void emitEnterUnpackFramesStackFrame(Value framePc, Value senderSp, Value senderFp) { + throw GraalInternalError.unimplemented(); + } + + public void emitLeaveUnpackFramesStackFrame() { + throw GraalInternalError.unimplemented(); + } + + public SaveRegistersOp emitSaveAllRegisters() { + throw GraalInternalError.unimplemented(); + } + + public void emitPushInterpreterFrame(Value frameSize, Value framePc, Value senderSp, Value initialInfo) { + throw GraalInternalError.unimplemented(); + } + + public Value emitUncommonTrapCall(Value trapRequest, SaveRegistersOp saveRegisterOp) { + throw GraalInternalError.unimplemented(); } } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotLoweringProvider.java --- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotLoweringProvider.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotLoweringProvider.java Wed Apr 23 15:48:38 2014 +0200 @@ -22,41 +22,59 @@ */ package com.oracle.graal.hotspot.hsail; -import java.util.*; - import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.common.*; import com.oracle.graal.graph.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; +import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.java.*; -import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.hotspot.hsail.replacements.*; + +import java.util.HashMap; public class HSAILHotSpotLoweringProvider extends HotSpotLoweringProvider { - abstract static class LoweringStrategy { + private HSAILNewObjectSnippets.Templates hsailNewObjectSnippets; + + abstract class LoweringStrategy { abstract void lower(Node n, LoweringTool tool); } - static LoweringStrategy PassThruStrategy = new LoweringStrategy() { + LoweringStrategy PassThruStrategy = new LoweringStrategy() { @Override void lower(Node n, LoweringTool tool) { return; } }; - static LoweringStrategy RejectStrategy = new LoweringStrategy() { + LoweringStrategy RejectStrategy = new LoweringStrategy() { @Override void lower(Node n, LoweringTool tool) { throw new GraalInternalError("Node implementing Lowerable not handled in HSAIL Backend: " + n); } }; + LoweringStrategy NewObjectStrategy = new LoweringStrategy() { + @Override + void lower(Node n, LoweringTool tool) { + StructuredGraph graph = (StructuredGraph) n.graph(); + if (graph.getGuardsStage() == StructuredGraph.GuardsStage.AFTER_FSA) { + if (n instanceof NewInstanceNode) { + hsailNewObjectSnippets.lower((NewInstanceNode) n, tool); + } else if (n instanceof NewArrayNode) { + hsailNewObjectSnippets.lower((NewArrayNode) n, tool); + } + } + } + }; + // strategy to replace an UnwindNode with a DeoptNode - static LoweringStrategy UnwindNodeStrategy = new LoweringStrategy() { + LoweringStrategy UnwindNodeStrategy = new LoweringStrategy() { @Override void lower(Node n, LoweringTool tool) { StructuredGraph graph = (StructuredGraph) n.graph(); @@ -85,12 +103,13 @@ } }; - private static HashMap, LoweringStrategy> strategyMap = new HashMap<>(); - static { + private HashMap, LoweringStrategy> strategyMap = new HashMap<>(); + + void initStrategyMap() { strategyMap.put(ConvertNode.class, PassThruStrategy); strategyMap.put(FloatConvertNode.class, PassThruStrategy); - strategyMap.put(NewInstanceNode.class, RejectStrategy); - strategyMap.put(NewArrayNode.class, RejectStrategy); + strategyMap.put(NewInstanceNode.class, NewObjectStrategy); + strategyMap.put(NewArrayNode.class, NewObjectStrategy); strategyMap.put(NewMultiArrayNode.class, RejectStrategy); strategyMap.put(DynamicNewArrayNode.class, RejectStrategy); strategyMap.put(MonitorEnterNode.class, RejectStrategy); @@ -98,12 +117,20 @@ strategyMap.put(UnwindNode.class, UnwindNodeStrategy); } - private static LoweringStrategy getStrategy(Node n) { + private LoweringStrategy getStrategy(Node n) { return strategyMap.get(n.getClass()); } public HSAILHotSpotLoweringProvider(HotSpotGraalRuntime runtime, MetaAccessProvider metaAccess, ForeignCallsProvider foreignCalls, HotSpotRegistersProvider registers) { super(runtime, metaAccess, foreignCalls, registers); + initStrategyMap(); + } + + @Override + public void initialize(HotSpotProviders providers, HotSpotVMConfig config) { + super.initialize(providers, config); + TargetDescription target = providers.getCodeCache().getTarget(); + hsailNewObjectSnippets = new HSAILNewObjectSnippets.Templates(providers, target); } @Override diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotNodeLIRBuilder.java --- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotNodeLIRBuilder.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotNodeLIRBuilder.java Wed Apr 23 15:48:38 2014 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,71 +23,31 @@ package com.oracle.graal.hotspot.hsail; -import sun.misc.*; - +import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.compiler.gen.*; +import com.oracle.graal.asm.*; +import com.oracle.graal.compiler.common.*; import com.oracle.graal.compiler.hsail.*; -import com.oracle.graal.graph.*; +import com.oracle.graal.debug.*; +import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.HotSpotVMConfig.CompressEncoding; +import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.hotspot.nodes.*; import com.oracle.graal.lir.*; +import com.oracle.graal.lir.gen.*; import com.oracle.graal.lir.hsail.*; -import com.oracle.graal.lir.hsail.HSAILControlFlow.CondMoveOp; -import com.oracle.graal.lir.hsail.HSAILMove.CompareAndSwapCompressedOp; import com.oracle.graal.lir.hsail.HSAILMove.CompareAndSwapOp; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.calc.*; -import com.oracle.graal.nodes.java.*; /** * The HotSpot specific portion of the HSAIL LIR generator. */ -public class HSAILHotSpotNodeLIRBuilder extends HSAILNodeLIRBuilder { +public class HSAILHotSpotNodeLIRBuilder extends HSAILNodeLIRBuilder implements HotSpotNodeLIRBuilder { public HSAILHotSpotNodeLIRBuilder(StructuredGraph graph, LIRGenerator lirGen) { super(graph, lirGen); } - private HSAILHotSpotLIRGenerator getGen() { - return (HSAILHotSpotLIRGenerator) gen; - } - - /** - * Appends either a {@link CompareAndSwapOp} or a {@link CompareAndSwapCompressedOp} depending - * on whether the memory location of a given {@link LoweredCompareAndSwapNode} contains a - * compressed oop. For the {@link CompareAndSwapCompressedOp} case, allocates a number of - * scratch registers. The result {@link #operand(ValueNode) operand} for {@code node} complies - * with the API for {@link Unsafe#compareAndSwapInt(Object, long, int, int)}. - * - * @param address the memory location targeted by the operation - */ - @Override - public void visitCompareAndSwap(LoweredCompareAndSwapNode node, Value address) { - Kind kind = node.getNewValue().getKind(); - assert kind == node.getExpectedValue().getKind(); - Variable expected = gen.load(operand(node.getExpectedValue())); - Variable newValue = gen.load(operand(node.getNewValue())); - HSAILAddressValue addressValue = getGen().asAddressValue(address); - Variable casResult = newVariable(kind); - if (getGen().config.useCompressedOops && node.isCompressible()) { - // make 64-bit scratch variables for expected and new - Variable scratchExpected64 = newVariable(Kind.Long); - Variable scratchNewValue64 = newVariable(Kind.Long); - // make 32-bit scratch variables for expected and new and result - Variable scratchExpected32 = newVariable(Kind.Int); - Variable scratchNewValue32 = newVariable(Kind.Int); - Variable scratchCasResult32 = newVariable(Kind.Int); - append(new CompareAndSwapCompressedOp(casResult, addressValue, expected, newValue, scratchExpected64, scratchNewValue64, scratchExpected32, scratchNewValue32, scratchCasResult32, - getGen().getNarrowOopBase(), getGen().getNarrowOopShift(), getGen().getLogMinObjectAlignment())); - } else { - append(new CompareAndSwapOp(casResult, addressValue, expected, newValue)); - } - Variable nodeResult = newVariable(node.getKind()); - append(new CondMoveOp(HSAILLIRGenerator.mapKindToCompareOp(kind), casResult, expected, nodeResult, Condition.EQ, Constant.INT_1, Constant.INT_0)); - setResult(node, nodeResult); - } - @Override protected void emitNode(ValueNode node) { if (node instanceof CurrentJavaThreadNode) { @@ -97,14 +57,75 @@ } } + private HSAILHotSpotLIRGenerator getGen() { + return (HSAILHotSpotLIRGenerator) gen; + } + /** * @return a compressed version of the incoming constant lifted from AMD64HotSpotLIRGenerator */ protected static Constant compress(Constant c, CompressEncoding encoding) { if (c.getKind() == Kind.Long) { - return Constant.forIntegerKind(Kind.Int, (int) (((c.asLong() - encoding.base) >> encoding.shift) & 0xffffffffL), c.getPrimitiveAnnotation()); + int compressedValue = (int) (((c.asLong() - encoding.base) >> encoding.shift) & 0xffffffffL); + if (c instanceof HotSpotMetaspaceConstant) { + return HotSpotMetaspaceConstant.forMetaspaceObject(Kind.Int, compressedValue, HotSpotMetaspaceConstant.getMetaspaceObject(c)); + } else { + return Constant.forIntegerKind(Kind.Int, compressedValue); + } } else { throw GraalInternalError.shouldNotReachHere(); } } + + public void visitDirectCompareAndSwap(DirectCompareAndSwapNode x) { + Kind kind = x.newValue().getKind(); + assert kind == x.expectedValue().getKind(); + + Variable expected = getGen().load(operand(x.expectedValue())); + Variable newVal = getGen().load(operand(x.newValue())); + + int disp = 0; + HSAILAddressValue address; + Value index = operand(x.offset()); + if (ValueUtil.isConstant(index) && NumUtil.isInt(ValueUtil.asConstant(index).asLong() + disp)) { + assert !getGen().getCodeCache().needsDataPatch(ValueUtil.asConstant(index)); + disp += (int) ValueUtil.asConstant(index).asLong(); + address = new HSAILAddressValue(kind, getGen().load(operand(x.object())), disp); + } else { + throw GraalInternalError.shouldNotReachHere("NYI"); + } + + Variable casResult = newVariable(kind); + append(new CompareAndSwapOp(kind, casResult, address, expected, newVal)); + + setResult(x, casResult); + } + + @Override + public void visitSafepointNode(SafepointNode i) { + HotSpotVMConfig config = getGen().config; + if (config.useHSAILSafepoints == true) { + LIRFrameState info = state(i); + HSAILHotSpotSafepointOp safepoint = new HSAILHotSpotSafepointOp(info, config, this); + ((HSAILHotSpotLIRGenerationResult) getGen().getResult()).addDeopt(safepoint); + append(safepoint); + } else { + Debug.log("HSAIL safepoints turned off"); + } + } + + @Override + public void emitPrefetchAllocate(ValueNode address, ValueNode distance) { + // nop + } + + @Override + public void emitPatchReturnAddress(ValueNode address) { + throw GraalInternalError.unimplemented(); + } + + @Override + public void emitJumpToExceptionHandlerInCaller(ValueNode handlerInCallerPc, ValueNode exception, ValueNode exceptionPc) { + throw GraalInternalError.unimplemented(); + } } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotRegisterConfig.java --- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotRegisterConfig.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotRegisterConfig.java Wed Apr 23 15:48:38 2014 +0200 @@ -28,7 +28,7 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.code.CallingConvention.Type; import com.oracle.graal.api.meta.*; -import com.oracle.graal.graph.*; +import com.oracle.graal.compiler.common.*; import com.oracle.graal.hotspot.nodes.type.*; import com.oracle.graal.hsail.*; diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotReplacementsImpl.java --- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotReplacementsImpl.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotReplacementsImpl.java Wed Apr 23 15:48:38 2014 +0200 @@ -27,6 +27,7 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.api.replacements.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.phases.util.*; @@ -41,8 +42,8 @@ private final Replacements host; private HashSet ignoredResolvedMethods = new HashSet<>(); - public HSAILHotSpotReplacementsImpl(Providers providers, Assumptions assumptions, TargetDescription target, Replacements host) { - super(providers, assumptions, target); + public HSAILHotSpotReplacementsImpl(Providers providers, SnippetReflectionProvider snippetReflection, Assumptions assumptions, TargetDescription target, Replacements host) { + super(providers, snippetReflection, assumptions, target); this.host = host; } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotSafepointOp.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotSafepointOp.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.hotspot.hsail; + +import static com.oracle.graal.api.code.ValueUtil.*; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.asm.hsail.*; +import com.oracle.graal.hotspot.*; +import com.oracle.graal.hsail.*; +import com.oracle.graal.lir.*; +import com.oracle.graal.lir.asm.*; +import com.oracle.graal.lir.hsail.*; +import com.oracle.graal.nodes.spi.*; + +/** + * Emits a safepoint deoptimization from HSA back to CPU. + */ +@Opcode("SAFEPOINT") +public class HSAILHotSpotSafepointOp extends HSAILLIRInstruction implements HSAILControlFlow.DeoptimizingOp { + private Constant actionAndReason; + @State protected LIRFrameState frameState; + protected int codeBufferPos = -1; + protected int dregOopMap = 0; + final int offsetToNoticeSafepoints; + + public HSAILHotSpotSafepointOp(LIRFrameState state, HotSpotVMConfig config, NodeLIRBuilderTool tool) { + actionAndReason = tool.getLIRGeneratorTool().getMetaAccess().encodeDeoptActionAndReason(DeoptimizationAction.None, DeoptimizationReason.None, 0); + frameState = state; + offsetToNoticeSafepoints = config.hsailNoticeSafepointsOffset; + } + + @Override + public void emitCode(CompilationResultBuilder crb, HSAILAssembler masm) { + + // get a unique codeBuffer position + // when we save our state, we will save this as well (it can be used as a key to get the + // debugInfo) + codeBufferPos = masm.position(); + + masm.emitComment(" /* HSAIL safepoint bci=" + frameState.debugInfo().getBytecodePosition().getBCI() + ", frameState=" + frameState + " */"); + String afterSafepointLabel = "@LAfterSafepoint_at_pos_" + codeBufferPos; + + AllocatableValue scratch64 = HSAIL.d16.asValue(Kind.Object); + AllocatableValue spAddrReg = HSAIL.d17.asValue(Kind.Object); + AllocatableValue scratch32 = HSAIL.s34.asValue(Kind.Int); + masm.emitLoadKernelArg(scratch64, masm.getDeoptInfoName(), "u64"); + + // Build address of noticeSafepoints field + HSAILAddress noticeSafepointsAddr = new HSAILAddressValue(Kind.Object, scratch64, offsetToNoticeSafepoints).toAddress(); + masm.emitLoad(Kind.Object, spAddrReg, noticeSafepointsAddr); + + // Load int value from that field + HSAILAddress noticeSafepointsIntAddr = new HSAILAddressValue(Kind.Int, spAddrReg, 0).toAddress(); + masm.emitLoadAcquire(scratch32, noticeSafepointsIntAddr); + masm.emitCompare(Kind.Int, scratch32, Constant.forInt(0), "eq", false, false); + masm.cbr(afterSafepointLabel); + + BytecodeFrame frame = frameState.debugInfo().frame(); + for (int i = 0; i < frame.numLocals + frame.numStack; i++) { + Value val = frame.values[i]; + if (isLegal(val) && isRegister(val)) { + Register reg = asRegister(val); + if (val.getKind() == Kind.Object) { + dregOopMap |= 1 << (reg.encoding()); + } + } + } + + AllocatableValue actionAndReasonReg = HSAIL.actionAndReasonReg.asValue(Kind.Int); + AllocatableValue codeBufferOffsetReg = HSAIL.codeBufferOffsetReg.asValue(Kind.Int); + AllocatableValue dregOopMapReg = HSAIL.dregOopMapReg.asValue(Kind.Int); + masm.emitMov(Kind.Int, actionAndReasonReg, actionAndReason); + masm.emitMov(Kind.Int, codeBufferOffsetReg, Constant.forInt(codeBufferPos)); + masm.emitMov(Kind.Int, dregOopMapReg, Constant.forInt(dregOopMap)); + masm.emitJumpToLabelName(masm.getDeoptLabelName()); + + masm.emitString0(afterSafepointLabel + ":\n"); + + // now record the debuginfo + crb.recordInfopoint(codeBufferPos, frameState, InfopointReason.SAFEPOINT); + } + + public LIRFrameState getFrameState() { + return frameState; + } + + public int getCodeBufferPos() { + return codeBufferPos; + } +} \ No newline at end of file diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/replacements/HSAILHotSpotReplacementsUtil.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/replacements/HSAILHotSpotReplacementsUtil.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2012, 2014, 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.hsail.replacements; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.nodes.java.*; +import com.oracle.graal.replacements.Snippet.Fold; +import com.oracle.graal.word.*; +import com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil; +import com.oracle.graal.hotspot.meta.*; + +//JaCoCo Exclude + +/** + * A collection of methods used in HSAIL-specific snippets and substitutions. + */ +public class HSAILHotSpotReplacementsUtil extends HotSpotReplacementsUtil { + + private static HotSpotRegistersProvider hsailRegisters; + + public static void initialize(HotSpotRegistersProvider registers) { + hsailRegisters = registers; + } + + /** + * Gets the value of the thread register as a Word. + */ + public static Word thread() { + return registerAsWord(threadRegister(), true, false); + } + + @Fold + public static Register threadRegister() { + return hsailRegisters.getThreadRegister(); + } + + public static Word atomicGetAndAddTlabTop(Word thread, int size) { + return Word.unsigned(AtomicReadAndAddNode.getAndAddLong(null, thread.rawValue() + threadTlabTopOffset(), size, TLAB_TOP_LOCATION)); + } + + public static final LocationIdentity TLAB_PFTOP_LOCATION = new NamedLocationIdentity("TlabPfTop"); + + @Fold + public static int threadTlabPfTopOffset() { + return config().threadTlabPfTopOffset(); + } + + public static void writeTlabPfTop(Word thread, Word val) { + thread.writeWord(threadTlabPfTopOffset(), val, TLAB_PFTOP_LOCATION); + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/replacements/HSAILNewObjectSnippets.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/replacements/HSAILNewObjectSnippets.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,255 @@ +/* + * 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.hsail.replacements; + +import static com.oracle.graal.api.code.UnsignedMath.*; +import static com.oracle.graal.compiler.common.GraalOptions.*; +import static com.oracle.graal.hotspot.hsail.replacements.HSAILHotSpotReplacementsUtil.*; +import static com.oracle.graal.hotspot.hsail.replacements.HSAILNewObjectSnippets.Options.*; +import static com.oracle.graal.nodes.PiArrayNode.*; +import static com.oracle.graal.nodes.extended.BranchProbabilityNode.*; +import static com.oracle.graal.replacements.SnippetTemplate.*; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.common.type.*; +import com.oracle.graal.debug.*; +import com.oracle.graal.hotspot.*; +import com.oracle.graal.hotspot.meta.*; +import com.oracle.graal.hotspot.replacements.*; +import com.oracle.graal.hotspot.stubs.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.java.*; +import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.options.*; +import com.oracle.graal.replacements.*; +import com.oracle.graal.replacements.Snippet.ConstantParameter; +import com.oracle.graal.replacements.SnippetTemplate.AbstractTemplates; +import com.oracle.graal.replacements.SnippetTemplate.Arguments; +import com.oracle.graal.replacements.SnippetTemplate.SnippetInfo; +import com.oracle.graal.word.*; + +/** + * HSAIL-specific Snippets used for implementing NEW and NEWARRAY. + */ +public class HSAILNewObjectSnippets extends NewObjectSnippets { + + static public class Options { + + // @formatter:off + @Option(help = "In HSAIL allocation, allow allocation from eden as fallback if TLAB is full") + static final OptionValue HsailUseEdenAllocate = new OptionValue<>(false); + + @Option(help = "Estimate of number of bytes allocated by each HSAIL workitem, used to size TLABs") + static public final OptionValue HsailAllocBytesPerWorkitem = new OptionValue<>(64); + + // @formatter:on + } + + private static final boolean hsailUseEdenAllocate = HsailUseEdenAllocate.getValue(); + + @Snippet + public static Object allocateInstanceAtomic(@ConstantParameter int size, Word hub, Word prototypeMarkWord, @ConstantParameter boolean fillContents, @ConstantParameter String typeContext) { + Word thread = thread(); + boolean haveResult = false; + if (useTLAB()) { + Word top = atomicGetAndAddTlabTop(thread, size); + Word end = readTlabEnd(thread); + Word newTop = top.add(size); + if (probability(FAST_PATH_PROBABILITY, newTop.belowOrEqual(end))) { + // writeTlabTop(thread, newTop) was done by the atomicGetAndAdd + Object result = formatObject(hub, size, top, prototypeMarkWord, fillContents, true, false, true); + profileAllocation("instance", size, typeContext); + return piCast(verifyOop(result), StampFactory.forNodeIntrinsic()); + } else { + // only one overflower will be the first overflower, detectable because + // oldtop was still below end + if (top.belowOrEqual(end)) { + // hack alert: store the last good top before overflow into pf_top + // we will move it back into top later when back in the VM + writeTlabPfTop(thread, top); + } + // useless logic but see notes on deopt path below + haveResult = newTop.belowOrEqual(end); + } + } + if (hsailUseEdenAllocate) { + // originally: + // result = NewInstanceStubCall.call(hub); + + // we could not allocate from tlab, try allocating directly from eden + // false for no logging + Word memory = NewInstanceStub.edenAllocate(Word.unsigned(size), false); + if (memory.notEqual(0)) { + new_eden.inc(); + Object result = formatObject(hub, size, memory, prototypeMarkWord, fillContents, true, false, true); + profileAllocation("instance", size, typeContext); + return piCast(verifyOop(result), StampFactory.forNodeIntrinsic()); + } + } + // haveResult test here helps avoid dropping earlier stores were seen to be dropped without + // this. + if (!haveResult) { + DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint); + } + // will never get here but this keeps the compiler happy + return Word.zero().toObject(); + } + + @Snippet + public static Object allocateArrayAtomic(Word hub, int length, Word prototypeMarkWord, @ConstantParameter int headerSize, @ConstantParameter int log2ElementSize, + @ConstantParameter boolean fillContents, @ConstantParameter boolean maybeUnroll, @ConstantParameter String typeContext) { + if (!belowThan(length, MAX_ARRAY_FAST_PATH_ALLOCATION_LENGTH)) { + // This handles both negative array sizes and very large array sizes + DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint); + } + return allocateArrayAtomicImpl(hub, length, prototypeMarkWord, headerSize, log2ElementSize, fillContents, maybeUnroll, typeContext); + } + + private static Object allocateArrayAtomicImpl(Word hub, int length, Word prototypeMarkWord, int headerSize, int log2ElementSize, boolean fillContents, boolean maybeUnroll, String typeContext) { + int alignment = wordSize(); + int allocationSize = computeArrayAllocationSize(length, alignment, headerSize, log2ElementSize); + Word thread = thread(); + boolean haveResult = false; + if (useTLAB()) { + Word top = atomicGetAndAddTlabTop(thread, allocationSize); + Word end = readTlabEnd(thread); + Word newTop = top.add(allocationSize); + if (probability(FAST_PATH_PROBABILITY, newTop.belowOrEqual(end))) { + // writeTlabTop(thread, newTop) was done by the atomicGetAndAdd + newarray_loopInit.inc(); + // we are not in a stub so we can set useSnippetCounters to true + Object result = formatArray(hub, allocationSize, length, headerSize, top, prototypeMarkWord, fillContents, maybeUnroll, true); + profileAllocation("array", allocationSize, typeContext); + return piArrayCast(verifyOop(result), length, StampFactory.forNodeIntrinsic()); + } else { + // only one overflower will be the first overflower, detectable because + // oldtop was still below end + if (top.belowOrEqual(end)) { + // hack alert: store the last good top before overflow into pf_top + // we will move it back into top later when back in the VM + writeTlabPfTop(thread, top); + } + // useless logic but see notes on deopt path below + haveResult = newTop.belowOrEqual(end); + } + } + // we could not allocate from tlab, try allocating directly from eden + if (hsailUseEdenAllocate) { + // false for no logging + Word memory = NewInstanceStub.edenAllocate(Word.unsigned(allocationSize), false); + if (memory.notEqual(0)) { + newarray_eden.inc(); + // we are not in a stub so we can set useSnippetCounters to true + Object result = formatArray(hub, allocationSize, length, headerSize, memory, prototypeMarkWord, fillContents, maybeUnroll, true); + profileAllocation("array", allocationSize, typeContext); + return piArrayCast(verifyOop(result), length, StampFactory.forNodeIntrinsic()); + } + } + if (!haveResult) { + DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint); + } + // will never get here but this keeps the compiler happy + return Word.zero().toObject(); + } + + public static class Templates extends AbstractTemplates { + + private final SnippetInfo allocateInstance = snippet(HSAILNewObjectSnippets.class, "allocateInstanceAtomic"); + private final SnippetInfo allocateArray = snippet(HSAILNewObjectSnippets.class, "allocateArrayAtomic"); + + // private final SnippetInfo allocateArrayDynamic = snippet(NewObjectSnippets.class, + // "allocateArrayDynamic"); + // private final SnippetInfo newmultiarray = snippet(NewObjectSnippets.class, + // "newmultiarray"); + + public Templates(HotSpotProviders providers, TargetDescription target) { + super(providers, providers.getSnippetReflection(), target); + } + + /** + * Lowers a {@link NewInstanceNode}. + */ + public void lower(NewInstanceNode newInstanceNode, LoweringTool tool) { + StructuredGraph graph = newInstanceNode.graph(); + HotSpotResolvedObjectType type = (HotSpotResolvedObjectType) newInstanceNode.instanceClass(); + assert !type.isArray(); + ConstantNode hub = ConstantNode.forConstant(type.klass(), providers.getMetaAccess(), graph); + int size = instanceSize(type); + + Arguments args = new Arguments(allocateInstance, graph.getGuardsStage(), tool.getLoweringStage()); + args.addConst("size", size); + args.add("hub", hub); + args.add("prototypeMarkWord", type.prototypeMarkWord()); + args.addConst("fillContents", newInstanceNode.fillContents()); + args.addConst("typeContext", MetaUtil.toJavaName(type, false)); + + SnippetTemplate template = template(args); + Debug.log("Lowering allocateInstance in %s: node=%s, template=%s, arguments=%s", graph, newInstanceNode, template, args); + template.instantiate(providers.getMetaAccess(), newInstanceNode, DEFAULT_REPLACER, args); + } + + /** + * Lowers a {@link NewArrayNode}. + */ + public void lower(NewArrayNode newArrayNode, LoweringTool tool) { + StructuredGraph graph = newArrayNode.graph(); + ResolvedJavaType elementType = newArrayNode.elementType(); + HotSpotResolvedObjectType arrayType = (HotSpotResolvedObjectType) elementType.getArrayClass(); + Kind elementKind = elementType.getKind(); + ConstantNode hub = ConstantNode.forConstant(arrayType.klass(), providers.getMetaAccess(), graph); + final int headerSize = HotSpotGraalRuntime.getArrayBaseOffset(elementKind); + // lowerer extends HotSpotLoweringProvider so we can just use that + HotSpotLoweringProvider lowerer = (HotSpotLoweringProvider) providers.getLowerer(); + int log2ElementSize = CodeUtil.log2(lowerer.getScalingFactor(elementKind)); + + Arguments args = new Arguments(allocateArray, graph.getGuardsStage(), tool.getLoweringStage()); + args.add("hub", hub); + args.add("length", newArrayNode.length()); + args.add("prototypeMarkWord", arrayType.prototypeMarkWord()); + args.addConst("headerSize", headerSize); + args.addConst("log2ElementSize", log2ElementSize); + args.addConst("fillContents", newArrayNode.fillContents()); + args.addConst("maybeUnroll", newArrayNode.length().isConstant()); + args.addConst("typeContext", MetaUtil.toJavaName(arrayType, false)); + + SnippetTemplate template = template(args); + Debug.log("Lowering allocateArray in %s: node=%s, template=%s, arguments=%s", graph, newArrayNode, template, args); + template.instantiate(providers.getMetaAccess(), newArrayNode, DEFAULT_REPLACER, args); + } + + private static int instanceSize(HotSpotResolvedObjectType type) { + int size = type.instanceSize(); + assert (size % wordSize()) == 0; + assert size >= 0; + return size; + } + } + + private static final SnippetCounter.Group countersNew = SnippetCounters.getValue() ? new SnippetCounter.Group("NewInstance") : null; + private static final SnippetCounter new_eden = new SnippetCounter(countersNew, "eden", "used edenAllocate"); + + private static final SnippetCounter.Group countersNewArray = SnippetCounters.getValue() ? new SnippetCounter.Group("NewArray") : null; + private static final SnippetCounter newarray_loopInit = new SnippetCounter(countersNewArray, "tlabLoopInit", "TLAB alloc with zeroing in a loop"); + private static final SnippetCounter newarray_eden = new SnippetCounter(countersNewArray, "eden", "used edenAllocate"); +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotBackend.java --- a/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotBackend.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotBackend.java Wed Apr 23 15:48:38 2014 +0200 @@ -36,11 +36,12 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.*; import com.oracle.graal.asm.ptx.*; +import com.oracle.graal.compiler.common.*; +import com.oracle.graal.compiler.common.cfg.*; import com.oracle.graal.compiler.gen.*; import com.oracle.graal.debug.*; import com.oracle.graal.debug.Debug.Scope; import com.oracle.graal.gpu.*; -import com.oracle.graal.graph.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.lir.*; @@ -49,10 +50,11 @@ import com.oracle.graal.lir.LIRInstruction.ValueProcedure; import com.oracle.graal.lir.StandardOp.LabelOp; import com.oracle.graal.lir.asm.*; +import com.oracle.graal.lir.gen.*; import com.oracle.graal.lir.ptx.*; +import com.oracle.graal.lir.ptx.PTXControlFlow.PTXPredicatedLIRInstruction; import com.oracle.graal.lir.ptx.PTXMemOp.LoadReturnAddrOp; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.cfg.*; import com.oracle.graal.phases.*; import com.oracle.graal.phases.common.*; import com.oracle.graal.phases.tiers.*; @@ -339,7 +341,7 @@ Assembler masm = createAssembler(frameMap); PTXFrameContext frameContext = new PTXFrameContext(); CompilationResultBuilder crb = factory.createBuilder(getCodeCache(), getForeignCalls(), frameMap, masm, frameContext, compilationResult); - crb.setFrameSize(0); + crb.setTotalFrameSize(0); return crb; } @@ -409,12 +411,20 @@ assert codeCacheOwner != null : lir + " is not associated with a method"; RegisterAnalysis registerAnalysis = new RegisterAnalysis(); + // Assume no predicate registers are used + int maxPredRegNum = -1; for (AbstractBlock b : lir.codeEmittingOrder()) { for (LIRInstruction op : lir.getLIRforBlock(b)) { if (op instanceof LabelOp) { // Don't consider this as a definition } else { + if (op instanceof PTXPredicatedLIRInstruction) { + // Update maximum predicate register number if op uses a larger number + int opPredRegNum = ((PTXPredicatedLIRInstruction) op).getPredRegNum(); + maxPredRegNum = (opPredRegNum > maxPredRegNum) ? opPredRegNum : maxPredRegNum; + } + // Record registers used in the kernel registerAnalysis.op = op; op.forEachTemp(registerAnalysis); op.forEachOutput(registerAnalysis); @@ -422,13 +432,13 @@ } } + // Emit register declarations Assembler asm = crb.asm; registerAnalysis.emitDeclarations(asm); // emit predicate register declaration - int maxPredRegNum = lir.numVariables(); - if (maxPredRegNum > 0) { - asm.emitString(".reg .pred %p<" + maxPredRegNum + ">;"); + if (maxPredRegNum > -1) { + asm.emitString(".reg .pred %p<" + ++maxPredRegNum + ">;"); } } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotBackendFactory.java --- a/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotBackendFactory.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotBackendFactory.java Wed Apr 23 15:48:38 2014 +0200 @@ -47,7 +47,7 @@ HotSpotDisassemblerProvider disassembler = host.getDisassembler(); SuitesProvider suites = new DefaultSuitesProvider(); HotSpotRegistersProvider registers = new HotSpotRegisters(PTX.tid, Register.None, Register.None); - HotSpotProviders providers = new HotSpotProviders(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, replacements, disassembler, suites, registers); + HotSpotProviders providers = new HotSpotProviders(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, replacements, disassembler, suites, registers, host.getSnippetReflection()); return new PTXHotSpotBackend(runtime, providers); } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotForeignCallsProvider.java --- a/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotForeignCallsProvider.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotForeignCallsProvider.java Wed Apr 23 15:48:38 2014 +0200 @@ -24,7 +24,7 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.graph.*; +import com.oracle.graal.compiler.common.*; import com.oracle.graal.hotspot.meta.*; public class PTXHotSpotForeignCallsProvider implements HotSpotForeignCallsProvider { diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotLIRGenerator.java --- a/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotLIRGenerator.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotLIRGenerator.java Wed Apr 23 15:48:38 2014 +0200 @@ -25,12 +25,13 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.compiler.gen.*; +import com.oracle.graal.compiler.common.*; import com.oracle.graal.compiler.ptx.*; -import com.oracle.graal.graph.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.HotSpotVMConfig.CompressEncoding; import com.oracle.graal.hotspot.meta.*; +import com.oracle.graal.lir.StandardOp.SaveRegistersOp; +import com.oracle.graal.lir.gen.*; /** * LIR generator specialized for PTX HotSpot. @@ -59,13 +60,43 @@ throw GraalInternalError.unimplemented(); } - public Value emitCompress(Value pointer, CompressEncoding encoding) { + @Override + public Value emitCompress(Value pointer, CompressEncoding encoding, boolean nonNull) { + // TODO + throw GraalInternalError.unimplemented(); + } + + @Override + public Value emitUncompress(Value pointer, CompressEncoding encoding, boolean nonNull) { // TODO throw GraalInternalError.unimplemented(); } - public Value emitUncompress(Value pointer, CompressEncoding encoding) { - // TODO + public void emitLeaveCurrentStackFrame() { + throw GraalInternalError.unimplemented(); + } + + public void emitLeaveDeoptimizedStackFrame(Value frameSize, Value initialInfo) { + throw GraalInternalError.unimplemented(); + } + + public void emitEnterUnpackFramesStackFrame(Value framePc, Value senderSp, Value senderFp) { + throw GraalInternalError.unimplemented(); + } + + public void emitLeaveUnpackFramesStackFrame() { + throw GraalInternalError.unimplemented(); + } + + public SaveRegistersOp emitSaveAllRegisters() { + throw GraalInternalError.unimplemented(); + } + + public void emitPushInterpreterFrame(Value frameSize, Value framePc, Value senderSp, Value initialInfo) { + throw GraalInternalError.unimplemented(); + } + + public Value emitUncommonTrapCall(Value trapRequest, SaveRegistersOp saveRegisterOp) { throw GraalInternalError.unimplemented(); } } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotLoweringProvider.java --- a/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotLoweringProvider.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotLoweringProvider.java Wed Apr 23 15:48:38 2014 +0200 @@ -22,6 +22,7 @@ */ package com.oracle.graal.hotspot.ptx; +import com.oracle.graal.compiler.common.*; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotNodeLIRBuilder.java --- a/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotNodeLIRBuilder.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotNodeLIRBuilder.java Wed Apr 23 15:48:38 2014 +0200 @@ -23,11 +23,11 @@ package com.oracle.graal.hotspot.ptx; -import com.oracle.graal.compiler.gen.*; +import com.oracle.graal.compiler.common.*; import com.oracle.graal.compiler.ptx.*; -import com.oracle.graal.graph.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.nodes.*; +import com.oracle.graal.lir.gen.*; import com.oracle.graal.nodes.*; /** diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotRegisterConfig.java --- a/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotRegisterConfig.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotRegisterConfig.java Wed Apr 23 15:48:38 2014 +0200 @@ -29,7 +29,7 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.code.CallingConvention.Type; import com.oracle.graal.api.meta.*; -import com.oracle.graal.graph.*; +import com.oracle.graal.compiler.common.*; import com.oracle.graal.lir.*; public class PTXHotSpotRegisterConfig implements RegisterConfig { diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXWrapperBuilder.java --- a/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXWrapperBuilder.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXWrapperBuilder.java Wed Apr 23 15:48:38 2014 +0200 @@ -31,13 +31,12 @@ import static com.oracle.graal.hotspot.ptx.PTXWrapperBuilder.LaunchArg.*; import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*; import static com.oracle.graal.nodes.ConstantNode.*; -import static java.lang.reflect.Modifier.*; - import java.util.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.common.*; +import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.debug.*; -import com.oracle.graal.graph.*; import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.hotspot.nodes.*; import com.oracle.graal.java.*; @@ -47,7 +46,6 @@ import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.java.*; -import com.oracle.graal.nodes.type.*; import com.oracle.graal.replacements.*; import com.oracle.graal.replacements.nodes.*; import com.oracle.graal.word.*; @@ -61,8 +59,8 @@ *

  • PINNED: a buffer into which the address of pinned objects is saved.
  • *
  • OBJECT_OFFSETS: the offsets of the object values in PARAMS.
  • *
- * - * + * + * * The PARAMS buffer is the {@code CU_LAUNCH_PARAM_BUFFER_POINTER} buffer passed in the * {@code extra} argument to the {@code cuLaunchKernel} function. This buffer contains the * parameters to the call. The buffer is word aligned and each parameter is aligned in the buffer @@ -74,13 +72,13 @@ * The object pointers in PARAMS are specified by OBJECT_OFFSETS. *

* As a concrete example, for a kernel whose Java method signature is: - * + * *

  *     static int kernel(int p1, short p2, Object p3, long p4)
  * 
- * + * * the graph created is shown below as psuedo-code: - * + * *
  *     int kernel_wrapper(int p1, short p2, oop p3, long p4) {
  *         address kernelAddr = kernel.start;
@@ -121,7 +119,7 @@
     /**
      * The size of the buffer holding the kernel parameters and the extra word for storing the
      * pointer to device memory for the return value.
-     * 
+     *
      * @see LaunchArg#ParametersAndReturnValueBufferSize
      */
     int bufSize;
@@ -152,7 +150,7 @@
 
     /**
      * Creates the graph implementing the CPU to GPU transition.
-     * 
+     *
      * @param method a method that has been compiled to GPU binary code
      * @param kernel the installed GPU binary for {@code method}
      * @see PTXWrapperBuilder
@@ -163,7 +161,7 @@
         int intSize = Integer.SIZE / Byte.SIZE;
         Kind wordKind = providers.getCodeCache().getTarget().wordKind;
         Signature sig = method.getSignature();
-        boolean isStatic = isStatic(method.getModifiers());
+        boolean isStatic = method.isStatic();
         int sigCount = sig.getParameterCount(false);
         javaParameters = new ParameterNode[(!isStatic ? 1 : 0) + sigCount];
         javaParameterOffsetsInKernelParametersBuffer = new int[javaParameters.length];
@@ -192,7 +190,7 @@
             }
         }
 
-        InvokeNode kernelStart = createInvoke(getClass(), "getKernelStart", ConstantNode.forObject(kernel, providers.getMetaAccess(), getGraph()));
+        InvokeNode kernelStart = createInvoke(getClass(), "getKernelStart", ConstantNode.forConstant(HotSpotObjectConstant.forObject(kernel), providers.getMetaAccess(), getGraph()));
 
         AllocaNode buf = append(new AllocaNode(bufSize / wordSize, new BitSet()));
         ValueNode objectParametersOffsets;
@@ -290,8 +288,8 @@
             Debug.dump(getGraph(), "Initial kernel launch graph");
         }
 
-        rewriteWordTypes();
-        inlineInvokes();
+        rewriteWordTypes(providers.getSnippetReflection());
+        inlineInvokes(providers.getSnippetReflection());
 
         if (Debug.isDumpEnabled()) {
             Debug.dump(getGraph(), "Kernel launch graph before compilation");
@@ -300,7 +298,7 @@
 
     /**
      * Computes offset and size of space in PARAMS for a Java parameter.
-     * 
+     *
      * @param kind the kind of the parameter
      * @param javaParametersIndex the index of the Java parameter
      */
diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot.server/src/com/oracle/graal/hotspot/server/ReplacingStreams.java
--- a/graal/com.oracle.graal.hotspot.server/src/com/oracle/graal/hotspot/server/ReplacingStreams.java	Wed Apr 23 15:22:20 2014 +0200
+++ b/graal/com.oracle.graal.hotspot.server/src/com/oracle/graal/hotspot/server/ReplacingStreams.java	Wed Apr 23 15:48:38 2014 +0200
@@ -28,6 +28,7 @@
 
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.hotspot.logging.*;
+import com.oracle.graal.hotspot.meta.*;
 
 public class ReplacingStreams {
 
@@ -172,7 +173,7 @@
                 if (constant.getKind() != Kind.Object) {
                     return obj;
                 }
-                Object contents = constant.asObject();
+                Object contents = HotSpotObjectConstant.asObject(constant);
                 if (contents == null) {
                     return obj;
                 }
@@ -182,12 +183,12 @@
                 }
                 placeholder = objectMap.get(contents);
                 if (placeholder != null) {
-                    return Constant.forObject(placeholder);
+                    return HotSpotObjectConstant.forObject(placeholder);
                 }
                 if (contents instanceof Remote) {
-                    return Constant.forObject(createRemoteCallPlaceholder(contents));
+                    return HotSpotObjectConstant.forObject(createRemoteCallPlaceholder(contents));
                 }
-                return Constant.forObject(createDummyPlaceholder(contents));
+                return HotSpotObjectConstant.forObject(createDummyPlaceholder(contents));
             }
             return obj;
         }
diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCDeoptimizationStub.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCDeoptimizationStub.java	Wed Apr 23 15:48:38 2014 +0200
@@ -0,0 +1,45 @@
+/*
+ * 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.sparc;
+
+import static com.oracle.graal.sparc.SPARC.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.hotspot.*;
+import com.oracle.graal.hotspot.meta.*;
+import com.oracle.graal.hotspot.stubs.*;
+
+final class SPARCDeoptimizationStub extends DeoptimizationStub {
+
+    private RegisterConfig registerConfig;
+
+    public SPARCDeoptimizationStub(HotSpotProviders providers, TargetDescription target, HotSpotForeignCallLinkage linkage) {
+        super(providers, target, linkage);
+        registerConfig = new SPARCHotSpotRegisterConfig(target, new Register[]{o0, o1, o2, o3, o4, o5, o7, l0, l1, l2, l3, l4, l5, l6, l7, i0, i1, i2, i3, i4, i5, f0, f1, f2, f3, f4, f5, f6, f7});
+    }
+
+    @Override
+    public RegisterConfig getRegisterConfig() {
+        return registerConfig;
+    }
+}
diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCDeoptimizeOp.java
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCDeoptimizeOp.java	Wed Apr 23 15:22:20 2014 +0200
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCDeoptimizeOp.java	Wed Apr 23 15:48:38 2014 +0200
@@ -49,6 +49,6 @@
         // [Deopt Handler Code]
         // 0xffffffff749bb60c: call 0xffffffff748da540 ; {runtime_call}
         // 0xffffffff749bb610: nop
-        SPARCCall.directCall(crb, masm, crb.foreignCalls.lookupForeignCall(UNCOMMON_TRAP), null, false, info);
+        SPARCCall.directCall(crb, masm, crb.foreignCalls.lookupForeignCall(UNCOMMON_TRAP_HANDLER), null, false, info);
     }
 }
diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java	Wed Apr 23 15:22:20 2014 +0200
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java	Wed Apr 23 15:48:38 2014 +0200
@@ -24,10 +24,8 @@
 
 import static com.oracle.graal.api.code.CallingConvention.Type.*;
 import static com.oracle.graal.api.code.ValueUtil.*;
-import static com.oracle.graal.phases.GraalOptions.*;
+import static com.oracle.graal.compiler.common.GraalOptions.*;
 import static com.oracle.graal.sparc.SPARC.*;
-import static java.lang.reflect.Modifier.*;
-
 import java.util.*;
 
 import sun.misc.*;
@@ -45,8 +43,8 @@
 import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Nop;
 import com.oracle.graal.asm.sparc.SPARCMacroAssembler.RestoreWindow;
 import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Setx;
+import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.compiler.gen.*;
-import com.oracle.graal.graph.*;
 import com.oracle.graal.hotspot.*;
 import com.oracle.graal.hotspot.meta.HotSpotCodeCacheProvider.MarkId;
 import com.oracle.graal.hotspot.meta.*;
@@ -54,6 +52,7 @@
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.StandardOp.SaveRegistersOp;
 import com.oracle.graal.lir.asm.*;
+import com.oracle.graal.lir.gen.*;
 import com.oracle.graal.lir.sparc.*;
 import com.oracle.graal.nodes.*;
 
@@ -174,7 +173,7 @@
         // On SPARC we always use stack frames.
         HotSpotFrameContext frameContext = new HotSpotFrameContext(stub != null);
         CompilationResultBuilder crb = factory.createBuilder(getProviders().getCodeCache(), getProviders().getForeignCalls(), frameMap, masm, frameContext, compilationResult);
-        crb.setFrameSize(frameMap.frameSize());
+        crb.setTotalFrameSize(frameMap.totalFrameSize());
         StackSlot deoptimizationRescueSlot = gen.getDeoptimizationRescueSlot();
         if (deoptimizationRescueSlot != null && stub == null) {
             crb.compilationResult.setCustomStackAreaOffset(frameMap.offsetForStackSlot(deoptimizationRescueSlot));
@@ -201,7 +200,7 @@
         FrameMap frameMap = crb.frameMap;
         RegisterConfig regConfig = frameMap.registerConfig;
         HotSpotVMConfig config = getRuntime().getConfig();
-        Label unverifiedStub = installedCodeOwner == null || isStatic(installedCodeOwner.getModifiers()) ? null : new Label();
+        Label unverifiedStub = installedCodeOwner == null || installedCodeOwner.isStatic() ? null : new Label();
 
         // Emit the prefix
 
diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackendFactory.java
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackendFactory.java	Wed Apr 23 15:22:20 2014 +0200
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackendFactory.java	Wed Apr 23 15:48:38 2014 +0200
@@ -60,10 +60,11 @@
         // to be valid for the entire run of the VM.
         Assumptions assumptions = new Assumptions(false);
         Providers p = new Providers(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, null);
-        HotSpotReplacementsImpl replacements = new HotSpotReplacementsImpl(p, runtime.getConfig(), assumptions, target);
+        HotSpotSnippetReflectionProvider snippetReflection = new HotSpotSnippetReflectionProvider();
+        HotSpotReplacementsImpl replacements = new HotSpotReplacementsImpl(p, snippetReflection, runtime.getConfig(), assumptions, target);
         HotSpotDisassemblerProvider disassembler = new HotSpotDisassemblerProvider(runtime);
         HotSpotSuitesProvider suites = new HotSpotSuitesProvider(runtime);
-        HotSpotProviders providers = new HotSpotProviders(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, replacements, disassembler, suites, registers);
+        HotSpotProviders providers = new HotSpotProviders(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, replacements, disassembler, suites, registers, snippetReflection);
 
         return new SPARCHotSpotBackend(runtime, providers);
     }
diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotDeoptimizeCallerOp.java
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotDeoptimizeCallerOp.java	Wed Apr 23 15:22:20 2014 +0200
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotDeoptimizeCallerOp.java	Wed Apr 23 15:48:38 2014 +0200
@@ -47,7 +47,7 @@
         // HotSpotFrameContext frameContext = backend.new HotSpotFrameContext(isStub);
         // frameContext.enter(crb);
         Register scratch = g3;
-        SPARCCall.indirectJmp(crb, masm, scratch, crb.foreignCalls.lookupForeignCall(UNCOMMON_TRAP));
+        SPARCCall.indirectJmp(crb, masm, scratch, crb.foreignCalls.lookupForeignCall(UNCOMMON_TRAP_HANDLER));
 
         // frameContext.leave(crb);
     }
diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotForeignCallsProvider.java
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotForeignCallsProvider.java	Wed Apr 23 15:22:20 2014 +0200
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotForeignCallsProvider.java	Wed Apr 23 15:48:38 2014 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, 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
@@ -46,7 +46,8 @@
 
     @Override
     public void initialize(HotSpotProviders providers, HotSpotVMConfig config) {
-        Kind word = providers.getCodeCache().getTarget().wordKind;
+        TargetDescription target = providers.getCodeCache().getTarget();
+        Kind word = target.wordKind;
 
         // The calling convention for the exception handler stub is (only?) defined in
         // TemplateInterpreterGenerator::generate_throw_exception()
@@ -60,6 +61,8 @@
         register(new HotSpotForeignCallLinkage(EXCEPTION_HANDLER, 0L, PRESERVES_REGISTERS, LEAF_NOFP, outgoingExceptionCc, incomingExceptionCc, NOT_REEXECUTABLE, ANY_LOCATION));
         register(new HotSpotForeignCallLinkage(EXCEPTION_HANDLER_IN_CALLER, JUMP_ADDRESS, PRESERVES_REGISTERS, LEAF_NOFP, outgoingExceptionCc, incomingExceptionCc, NOT_REEXECUTABLE, ANY_LOCATION));
 
+        link(new SPARCDeoptimizationStub(providers, target, registerStubCall(UNCOMMON_TRAP_HANDLER, REEXECUTABLE, LEAF, NO_LOCATIONS)));
+
         super.initialize(providers, config);
     }
 
diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerationResult.java
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerationResult.java	Wed Apr 23 15:22:20 2014 +0200
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerationResult.java	Wed Apr 23 15:48:38 2014 +0200
@@ -23,8 +23,8 @@
 package com.oracle.graal.hotspot.sparc;
 
 import com.oracle.graal.api.code.*;
-import com.oracle.graal.compiler.gen.*;
 import com.oracle.graal.hotspot.stubs.*;
+import com.oracle.graal.lir.gen.*;
 
 public interface SPARCHotSpotLIRGenerationResult extends LIRGenerationResult {
 
diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java	Wed Apr 23 15:22:20 2014 +0200
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java	Wed Apr 23 15:48:38 2014 +0200
@@ -27,24 +27,25 @@
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
-import com.oracle.graal.compiler.gen.*;
+import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.compiler.sparc.*;
-import com.oracle.graal.graph.*;
 import com.oracle.graal.hotspot.*;
 import com.oracle.graal.hotspot.HotSpotVMConfig.CompressEncoding;
 import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.hotspot.stubs.*;
 import com.oracle.graal.lir.*;
+import com.oracle.graal.lir.StandardOp.SaveRegistersOp;
+import com.oracle.graal.lir.gen.*;
 import com.oracle.graal.lir.sparc.*;
 import com.oracle.graal.lir.sparc.SPARCMove.LoadOp;
 import com.oracle.graal.lir.sparc.SPARCMove.StoreConstantOp;
 import com.oracle.graal.lir.sparc.SPARCMove.StoreOp;
-import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.extended.*;
 
 public class SPARCHotSpotLIRGenerator extends SPARCLIRGenerator implements HotSpotLIRGenerator {
 
     final HotSpotVMConfig config;
+    private HotSpotLockStack lockStack;
 
     public SPARCHotSpotLIRGenerator(HotSpotProviders providers, HotSpotVMConfig config, CallingConvention cc, LIRGenerationResult lirGenRes) {
         super(providers, cc, lirGenRes);
@@ -65,11 +66,21 @@
 
     @Override
     public StackSlot getLockSlot(int lockDepth) {
-        return ((HotSpotDebugInfoBuilder) getDebugInfoBuilder()).lockStack().makeLockSlot(lockDepth);
+        return getLockStack().makeLockSlot(lockDepth);
+    }
+
+    private HotSpotLockStack getLockStack() {
+        assert lockStack != null;
+        return lockStack;
+    }
+
+    protected void setLockStack(HotSpotLockStack lockStack) {
+        assert this.lockStack == null;
+        this.lockStack = lockStack;
     }
 
     @Override
-    protected boolean needOnlyOopMaps() {
+    public boolean needOnlyOopMaps() {
         // Stubs only need oop maps
         return getStub() != null;
     }
@@ -79,12 +90,13 @@
     }
 
     @Override
-    public Variable emitForeignCall(ForeignCallLinkage linkage, DeoptimizingNode info, Value... args) {
+    public Variable emitForeignCall(ForeignCallLinkage linkage, LIRFrameState state, Value... args) {
         HotSpotForeignCallLinkage hotspotLinkage = (HotSpotForeignCallLinkage) linkage;
         Variable result;
-        DeoptimizingNode deoptInfo = null;
+        // TODO (je) check if this can be removed
+        LIRFrameState deoptInfo = null;
         if (hotspotLinkage.canDeoptimize()) {
-            deoptInfo = info;
+            deoptInfo = state;
             assert deoptInfo != null || getStub() != null;
         }
 
@@ -141,9 +153,9 @@
     }
 
     @Override
-    public void emitDeoptimize(Value actionAndReason, Value speculation, DeoptimizingNode deopting) {
+    public void emitDeoptimize(Value actionAndReason, Value speculation, LIRFrameState state) {
         moveDeoptValuesToThread(actionAndReason, speculation);
-        append(new SPARCDeoptimizeOp(state(deopting)));
+        append(new SPARCDeoptimizeOp(state));
     }
 
     @Override
@@ -157,14 +169,10 @@
     }
 
     @Override
-    public Variable emitLoad(PlatformKind kind, Value address, Access access) {
+    public Variable emitLoad(PlatformKind kind, Value address, LIRFrameState state) {
         SPARCAddressValue loadAddress = asAddressValue(address);
         Variable result = newVariable(kind);
-        LIRFrameState state = null;
-        if (access instanceof DeoptimizingNode) {
-            state = state((DeoptimizingNode) access);
-        }
-        if (isCompressCandidate(access)) {
+        if (isCompressCandidate(null)) {
             if (config.useCompressedOops && kind == Kind.Object) {
                 // append(new LoadCompressedPointer(kind, result, loadAddress, access != null ?
                 // state(access) :
@@ -187,19 +195,15 @@
     }
 
     @Override
-    public void emitStore(PlatformKind kind, Value address, Value inputVal, Access access) {
+    public void emitStore(PlatformKind kind, Value address, Value inputVal, LIRFrameState state) {
         SPARCAddressValue storeAddress = asAddressValue(address);
-        LIRFrameState state = null;
-        if (access instanceof DeoptimizingNode) {
-            state = state((DeoptimizingNode) access);
-        }
         if (isConstant(inputVal)) {
             Constant c = asConstant(inputVal);
-            if (canStoreConstant(c, isCompressCandidate(access))) {
+            if (canStoreConstant(c, isCompressCandidate(null))) {
                 if (inputVal.getKind() == Kind.Object) {
-                    append(new StoreConstantOp((Kind) kind, storeAddress, c, state, config.useCompressedOops && isCompressCandidate(access)));
+                    append(new StoreConstantOp((Kind) kind, storeAddress, c, state, config.useCompressedOops && isCompressCandidate(null)));
                 } else if (inputVal.getKind() == Kind.Long) {
-                    append(new StoreConstantOp((Kind) kind, storeAddress, c, state, config.useCompressedClassPointers && isCompressCandidate(access)));
+                    append(new StoreConstantOp((Kind) kind, storeAddress, c, state, config.useCompressedClassPointers && isCompressCandidate(null)));
                 } else {
                     append(new StoreConstantOp((Kind) kind, storeAddress, c, state, false));
                 }
@@ -207,7 +211,7 @@
             }
         }
         Variable input = load(inputVal);
-        if (isCompressCandidate(access)) {
+        if (isCompressCandidate(null)) {
             if (config.useCompressedOops && kind == Kind.Object) {
                 // if (input.getKind() == Kind.Object) {
                 // Variable scratch = newVariable(Kind.Long);
@@ -233,6 +237,11 @@
         }
     }
 
+    public Value emitCompareAndSwap(Value address, Value expectedValue, Value newValue, Value trueValue, Value falseValue) {
+        // TODO Auto-generated method stub
+        throw GraalInternalError.unimplemented();
+    }
+
     @Override
     public Value emitNot(Value input) {
         GraalInternalError.shouldNotReachHere("binary negation not implemented");
@@ -243,13 +252,50 @@
         return deoptimizationRescueSlot;
     }
 
-    public Value emitCompress(Value pointer, CompressEncoding encoding) {
+    @Override
+    public Value emitCompress(Value pointer, CompressEncoding encoding, boolean nonNull) {
+        // TODO
+        throw GraalInternalError.unimplemented();
+    }
+
+    @Override
+    public Value emitUncompress(Value pointer, CompressEncoding encoding, boolean nonNull) {
         // TODO
         throw GraalInternalError.unimplemented();
     }
 
-    public Value emitUncompress(Value pointer, CompressEncoding encoding) {
-        // TODO
+    public SaveRegistersOp emitSaveAllRegisters() {
+        // TODO Auto-generated method stub
+        throw GraalInternalError.unimplemented();
+    }
+
+    public void emitLeaveCurrentStackFrame() {
+        // TODO Auto-generated method stub
+        throw GraalInternalError.unimplemented();
+    }
+
+    public void emitLeaveDeoptimizedStackFrame(Value frameSize, Value initialInfo) {
+        // TODO Auto-generated method stub
+        throw GraalInternalError.unimplemented();
+    }
+
+    public void emitEnterUnpackFramesStackFrame(Value framePc, Value senderSp, Value senderFp) {
+        // TODO Auto-generated method stub
+        throw GraalInternalError.unimplemented();
+    }
+
+    public void emitLeaveUnpackFramesStackFrame() {
+        // TODO Auto-generated method stub
+        throw GraalInternalError.unimplemented();
+    }
+
+    public void emitPushInterpreterFrame(Value frameSize, Value framePc, Value senderSp, Value initialInfo) {
+        // TODO Auto-generated method stub
+        throw GraalInternalError.unimplemented();
+    }
+
+    public Value emitUncommonTrapCall(Value trapRequest, SaveRegistersOp saveRegisterOp) {
+        // TODO Auto-generated method stub
         throw GraalInternalError.unimplemented();
     }
 }
diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotNodeLIRBuilder.java
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotNodeLIRBuilder.java	Wed Apr 23 15:22:20 2014 +0200
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotNodeLIRBuilder.java	Wed Apr 23 15:48:38 2014 +0200
@@ -26,8 +26,6 @@
 import static com.oracle.graal.hotspot.HotSpotBackend.*;
 import static com.oracle.graal.sparc.SPARC.*;
 
-import java.lang.reflect.*;
-
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.gen.*;
@@ -37,6 +35,7 @@
 import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.hotspot.nodes.*;
 import com.oracle.graal.lir.*;
+import com.oracle.graal.lir.gen.*;
 import com.oracle.graal.lir.sparc.*;
 import com.oracle.graal.lir.sparc.SPARCMove.CompareAndSwapOp;
 import com.oracle.graal.nodes.*;
@@ -46,6 +45,9 @@
 
     public SPARCHotSpotNodeLIRBuilder(StructuredGraph graph, LIRGenerator lirGen) {
         super(graph, lirGen);
+        assert gen instanceof SPARCHotSpotLIRGenerator;
+        assert getDebugInfoBuilder() instanceof HotSpotDebugInfoBuilder;
+        ((SPARCHotSpotLIRGenerator) gen).setLockStack(((HotSpotDebugInfoBuilder) getDebugInfoBuilder()).lockStack());
     }
 
     @Override
@@ -60,7 +62,7 @@
 
     @Override
     public void visitSafepointNode(SafepointNode i) {
-        LIRFrameState info = gen.state(i);
+        LIRFrameState info = state(i);
         append(new SPARCHotSpotSafepointOp(info, getGen().config, gen));
     }
 
@@ -100,9 +102,8 @@
         } else {
             assert invokeKind == InvokeKind.Static || invokeKind == InvokeKind.Special;
             HotSpotResolvedJavaMethod resolvedMethod = (HotSpotResolvedJavaMethod) callTarget.target();
-            assert !Modifier.isAbstract(resolvedMethod.getModifiers()) : "Cannot make direct call to abstract method.";
-            Constant metaspaceMethod = resolvedMethod.getMetaspaceMethodConstant();
-            append(new SPARCHotspotDirectStaticCallOp(callTarget.target(), result, parameters, temps, callState, invokeKind, metaspaceMethod));
+            assert !resolvedMethod.isAbstract() : "Cannot make direct call to abstract method.";
+            append(new SPARCHotspotDirectStaticCallOp(callTarget.target(), result, parameters, temps, callState, invokeKind));
         }
     }
 
diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotRegisterConfig.java
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotRegisterConfig.java	Wed Apr 23 15:22:20 2014 +0200
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotRegisterConfig.java	Wed Apr 23 15:48:38 2014 +0200
@@ -22,7 +22,7 @@
  */
 package com.oracle.graal.hotspot.sparc;
 
-import static com.oracle.graal.phases.GraalOptions.*;
+import static com.oracle.graal.compiler.common.GraalOptions.*;
 import static com.oracle.graal.sparc.SPARC.*;
 
 import java.util.*;
@@ -30,7 +30,7 @@
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.code.CallingConvention.Type;
 import com.oracle.graal.api.meta.*;
-import com.oracle.graal.graph.*;
+import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.hotspot.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.sparc.*;
diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotSafepointOp.java
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotSafepointOp.java	Wed Apr 23 15:22:20 2014 +0200
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotSafepointOp.java	Wed Apr 23 15:48:38 2014 +0200
@@ -33,8 +33,8 @@
 import com.oracle.graal.hotspot.meta.HotSpotCodeCacheProvider.MarkId;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.asm.*;
+import com.oracle.graal.lir.gen.*;
 import com.oracle.graal.lir.sparc.*;
-import com.oracle.graal.nodes.spi.*;
 
 /**
  * Emits a safepoint poll.
diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotspotDirectStaticCallOp.java
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotspotDirectStaticCallOp.java	Wed Apr 23 15:22:20 2014 +0200
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotspotDirectStaticCallOp.java	Wed Apr 23 15:48:38 2014 +0200
@@ -22,44 +22,32 @@
  */
 package com.oracle.graal.hotspot.sparc;
 
-import static com.oracle.graal.sparc.SPARC.*;
-
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.sparc.*;
-import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Setx;
-import com.oracle.graal.hotspot.*;
 import com.oracle.graal.hotspot.meta.HotSpotCodeCacheProvider.MarkId;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.asm.*;
 import com.oracle.graal.lir.sparc.SPARCCall.DirectCallOp;
-import com.oracle.graal.lir.sparc.*;
 import com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind;
 
 /**
- * A direct call that complies with the conventions for such calls in HotSpot. In particular, for
- * calls using an inline cache, a MOVE instruction is emitted just prior to the aligned direct call.
+ * A direct call that complies with the conventions for such calls in HotSpot. It doesn't use an
+ * inline cache so it's just a patchable call site.
  */
 @Opcode("CALL_DIRECT")
 final class SPARCHotspotDirectStaticCallOp extends DirectCallOp {
 
-    private final Constant metaspaceMethod;
     private final InvokeKind invokeKind;
 
-    SPARCHotspotDirectStaticCallOp(ResolvedJavaMethod target, Value result, Value[] parameters, Value[] temps, LIRFrameState state, InvokeKind invokeKind, Constant metaspaceMethod) {
+    SPARCHotspotDirectStaticCallOp(ResolvedJavaMethod target, Value result, Value[] parameters, Value[] temps, LIRFrameState state, InvokeKind invokeKind) {
         super(target, result, parameters, temps, state);
         assert invokeKind == InvokeKind.Static || invokeKind == InvokeKind.Special;
-        this.metaspaceMethod = metaspaceMethod;
         this.invokeKind = invokeKind;
     }
 
     @Override
     public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
-        // The mark for an invocation that uses an inline cache must be placed at the
-        // instruction that loads the Klass from the inline cache.
-        SPARCMove.move(crb, masm, g5.asValue(Kind.Long), metaspaceMethod);
         MarkId.recordMark(crb, invokeKind == InvokeKind.Static ? MarkId.INVOKESTATIC : MarkId.INVOKESPECIAL);
-        // SPARCMove.move(crb, masm, g3.asValue(Kind.Long), Constant.LONG_0);
-        new Setx(HotSpotGraalRuntime.runtime().getConfig().nonOopBits, g3, true).emit(masm);
         super.emitCode(crb, masm);
     }
 }
diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/AheadOfTimeCompilationTest.java
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/AheadOfTimeCompilationTest.java	Wed Apr 23 15:22:20 2014 +0200
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/AheadOfTimeCompilationTest.java	Wed Apr 23 15:48:38 2014 +0200
@@ -24,8 +24,8 @@
 
 import static com.oracle.graal.api.code.CodeUtil.*;
 import static com.oracle.graal.compiler.GraalCompiler.*;
+import static com.oracle.graal.compiler.common.GraalOptions.*;
 import static com.oracle.graal.nodes.ConstantNode.*;
-import static com.oracle.graal.phases.GraalOptions.*;
 
 import org.junit.*;
 
@@ -81,7 +81,7 @@
         assertEquals(0, result.getNodes().filter(ReadNode.class).count());
     }
 
-    public static Class getClassObject() {
+    public static Class getClassObject() {
         return AheadOfTimeCompilationTest.class;
     }
 
@@ -104,7 +104,7 @@
 
         NodeIterable filter = getConstantNodes(result);
         assertEquals(1, filter.count());
-        Object mirror = filter.first().asConstant().asObject();
+        Object mirror = HotSpotObjectConstant.asObject(filter.first().asConstant());
         assertEquals(Class.class, mirror.getClass());
         assertEquals(AheadOfTimeCompilationTest.class, mirror);
 
@@ -112,7 +112,7 @@
         assertEquals(0, result.getNodes().filter(ReadNode.class).count());
     }
 
-    public static Class getPrimitiveClassObject() {
+    public static Class getPrimitiveClassObject() {
         return int.class;
     }
 
@@ -132,7 +132,7 @@
         StructuredGraph result = compile("getPrimitiveClassObject", false);
         NodeIterable filter = getConstantNodes(result);
         assertEquals(1, filter.count());
-        Object mirror = filter.first().asConstant().asObject();
+        Object mirror = HotSpotObjectConstant.asObject(filter.first().asConstant());
         assertEquals(Class.class, mirror.getClass());
         assertEquals(Integer.TYPE, mirror);
 
@@ -160,7 +160,7 @@
 
         NodeIterable filter = getConstantNodes(result);
         assertEquals(1, filter.count());
-        Object mirror = filter.first().asConstant().asObject();
+        Object mirror = HotSpotObjectConstant.asObject(filter.first().asConstant());
         assertEquals(String.class, mirror.getClass());
         assertEquals("test string", mirror);
 
@@ -193,7 +193,7 @@
         assertEquals(1, getConstantNodes(result).count());
         ConstantNode constant = getConstantNodes(result).first();
         assertEquals(Kind.Object, constant.getKind());
-        assertEquals(Boolean.TRUE, constant.asConstant().asObject());
+        assertEquals(Boolean.TRUE, HotSpotObjectConstant.asObject(constant.asConstant()));
     }
 
     private StructuredGraph compile(String test, boolean compileAOT) {
diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/CompileTheWorldTest.java
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/CompileTheWorldTest.java	Wed Apr 23 15:22:20 2014 +0200
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/CompileTheWorldTest.java	Wed Apr 23 15:48:38 2014 +0200
@@ -22,7 +22,7 @@
  */
 package com.oracle.graal.hotspot.test;
 
-import static com.oracle.graal.phases.GraalOptions.*;
+import static com.oracle.graal.compiler.common.GraalOptions.*;
 
 import org.junit.*;
 
diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/CompressedOopTest.java
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/CompressedOopTest.java	Wed Apr 23 15:22:20 2014 +0200
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/CompressedOopTest.java	Wed Apr 23 15:48:38 2014 +0200
@@ -200,7 +200,7 @@
         while (j < objects.length) {
             if (!installedBenchmarkCode.isValid()) {
                 // This can get invalidated due to lack of MDO update
-                installedBenchmarkCode = getInstalledCode("queueTest");
+                installedBenchmarkCode = getInstalledCode("queueTest", Object.class, Object.class);
             }
             installedBenchmarkCode.executeVarargs(q, objects[j]);
             j++;
diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotCryptoSubstitutionTest.java
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotCryptoSubstitutionTest.java	Wed Apr 23 15:22:20 2014 +0200
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotCryptoSubstitutionTest.java	Wed Apr 23 15:48:38 2014 +0200
@@ -127,7 +127,7 @@
     }
 
     private static Method lookup(String className, String methodName) {
-        Class c;
+        Class c;
         try {
             c = Class.forName(className);
             for (Method m : c.getDeclaredMethods()) {
@@ -180,7 +180,7 @@
         return result;
     }
 
-    private static byte[] readClassfile16(Class c) throws IOException {
+    private static byte[] readClassfile16(Class c) throws IOException {
         String classFilePath = "/" + c.getName().replace('.', '/') + ".class";
         InputStream stream = c.getResourceAsStream(classFilePath);
         int bytesToRead = stream.available();
diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotMethodSubstitutionTest.java
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotMethodSubstitutionTest.java	Wed Apr 23 15:22:20 2014 +0200
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotMethodSubstitutionTest.java	Wed Apr 23 15:48:38 2014 +0200
@@ -74,7 +74,7 @@
         test("getSuperClass");
         test("getComponentType");
 
-        for (Class c : new Class[]{getClass(), Cloneable.class, int[].class, String[][].class}) {
+        for (Class c : new Class[]{getClass(), Cloneable.class, int[].class, String[][].class}) {
             assertEquals(c.getModifiers(), ClassSubstitutions.getModifiers(c));
             assertEquals(c.isInterface(), ClassSubstitutions.isInterface(c));
             assertEquals(c.isArray(), ClassSubstitutions.isArray(c));
diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotMonitorValueTest.java
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotMonitorValueTest.java	Wed Apr 23 15:22:20 2014 +0200
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotMonitorValueTest.java	Wed Apr 23 15:48:38 2014 +0200
@@ -33,8 +33,8 @@
 import com.oracle.graal.api.code.CompilationResult.Call;
 import com.oracle.graal.api.code.CompilationResult.Infopoint;
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.compiler.test.*;
-import com.oracle.graal.graph.*;
 import com.oracle.graal.hotspot.meta.*;
 
 public class HotSpotMonitorValueTest extends GraalCompilerTest {
diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotNodeClassSubstitutionsTest.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotNodeClassSubstitutionsTest.java	Wed Apr 23 15:48:38 2014 +0200
@@ -0,0 +1,44 @@
+/*
+ * 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.test;
+
+import org.junit.*;
+
+import com.oracle.graal.graph.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.replacements.test.*;
+
+/**
+ * Tests HotSpot specific substitutions for {@link NodeClass}.
+ */
+public class HotSpotNodeClassSubstitutionsTest extends MethodSubstitutionTest {
+
+    @Test
+    public void test() {
+        test("get", ValueNode.class);
+    }
+
+    public static NodeClass get(Class c) {
+        return NodeClass.get(c);
+    }
+}
diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotNodeSubstitutionsTest.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotNodeSubstitutionsTest.java	Wed Apr 23 15:48:38 2014 +0200
@@ -0,0 +1,45 @@
+/*
+ * 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.test;
+
+import org.junit.*;
+
+import com.oracle.graal.graph.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.replacements.test.*;
+
+/**
+ * Tests HotSpot specific substitutions for {@link Node}.
+ */
+public class HotSpotNodeSubstitutionsTest extends MethodSubstitutionTest {
+
+    @Test
+    public void test() {
+        StructuredGraph graph = new StructuredGraph();
+        test("getNodeClass", ConstantNode.forInt(42, graph));
+    }
+
+    public static NodeClass getNodeClass(Node n) {
+        return n.getNodeClass();
+    }
+}
diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotResolvedJavaFieldTest.java
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotResolvedJavaFieldTest.java	Wed Apr 23 15:22:20 2014 +0200
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotResolvedJavaFieldTest.java	Wed Apr 23 15:48:38 2014 +0200
@@ -24,7 +24,6 @@
 
 import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
 import static com.oracle.graal.hotspot.meta.HotSpotResolvedObjectType.*;
-import static java.lang.reflect.Modifier.*;
 
 import java.lang.reflect.*;
 
@@ -38,7 +37,7 @@
  */
 public class HotSpotResolvedJavaFieldTest {
 
-    private static final Class[] classesWithInternalFields = {Class.class, ClassLoader.class};
+    private static final Class[] classesWithInternalFields = {Class.class, ClassLoader.class};
 
     /**
      * Tests that {@link HotSpotResolvedJavaField#getModifiers()} only includes the modifiers
@@ -47,7 +46,7 @@
      */
     @Test
     public void testModifiersForInternal() {
-        for (Class c : classesWithInternalFields) {
+        for (Class c : classesWithInternalFields) {
             ResolvedJavaType type = HotSpotResolvedObjectType.fromClass(c);
             for (ResolvedJavaField field : type.getInstanceFields(false)) {
                 if (field.isInternal()) {
@@ -63,7 +62,7 @@
      */
     @Test
     public void testCachingForInternalFields() {
-        for (Class c : classesWithInternalFields) {
+        for (Class c : classesWithInternalFields) {
             HotSpotResolvedObjectType type = (HotSpotResolvedObjectType) HotSpotResolvedObjectType.fromClass(c);
             for (ResolvedJavaField field : type.getInstanceFields(false)) {
                 if (field.isInternal()) {
@@ -79,7 +78,7 @@
     public void testIsInObject() {
         for (Field f : String.class.getDeclaredFields()) {
             HotSpotResolvedJavaField rf = (HotSpotResolvedJavaField) runtime().getHostProviders().getMetaAccess().lookupJavaField(f);
-            Assert.assertEquals(rf.toString(), rf.isInObject("a string"), !isStatic(rf.getModifiers()));
+            Assert.assertEquals(rf.toString(), rf.isInObject("a string"), !rf.isStatic());
         }
     }
 }
diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/InstalledCodeExecuteHelperTest.java
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/InstalledCodeExecuteHelperTest.java	Wed Apr 23 15:22:20 2014 +0200
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/InstalledCodeExecuteHelperTest.java	Wed Apr 23 15:48:38 2014 +0200
@@ -89,7 +89,7 @@
             assert parameterTypes.length == args.length;
             for (int i = 0; i < argsToBind.length; i++) {
                 ParameterNode param = graph.getParameter(i);
-                Constant c = Constant.forBoxed(parameterTypes[i].getKind(), argsToBind[i]);
+                Constant c = HotSpotObjectConstant.forBoxedValue(parameterTypes[i].getKind(), argsToBind[i]);
                 ConstantNode replacement = ConstantNode.forConstant(c, getMetaAccess(), graph);
                 param.replaceAtUsages(replacement);
             }
diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierAdditionTest.java
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierAdditionTest.java	Wed Apr 23 15:22:20 2014 +0200
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierAdditionTest.java	Wed Apr 23 15:48:38 2014 +0200
@@ -187,7 +187,7 @@
      */
     @Test
     public void test8() throws Exception {
-        test2("testUnsafeLoad", wr, new Long(32), null);
+        test2("testUnsafeLoad", wr, new Long(useCompressedOops() ? 20 : 32), null);
     }
 
     /**
@@ -207,7 +207,7 @@
      */
     @Test
     public void test9() throws Exception {
-        test2("testUnsafeLoad", wr, new Long(16), new Integer(16));
+        test2("testUnsafeLoad", wr, new Long(useCompressedOops() ? 10 : 16), new Integer(useCompressedOops() ? 10 : 16));
     }
 
     static Object[] src = new Object[1];
diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierVerificationTest.java
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierVerificationTest.java	Wed Apr 23 15:22:20 2014 +0200
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierVerificationTest.java	Wed Apr 23 15:48:38 2014 +0200
@@ -685,7 +685,7 @@
                 }
 
                 @Override
-                protected Boolean afterSplit(AbstractBeginNode node, Boolean oldState) {
+                protected Boolean afterSplit(BeginNode node, Boolean oldState) {
                     return false;
                 }
             };
diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java	Wed Apr 23 15:22:20 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java	Wed Apr 23 15:48:38 2014 +0200
@@ -25,14 +25,13 @@
 import static com.oracle.graal.api.code.CallingConvention.Type.*;
 import static com.oracle.graal.api.code.CodeUtil.*;
 import static com.oracle.graal.compiler.GraalCompiler.*;
+import static com.oracle.graal.compiler.common.GraalOptions.*;
 import static com.oracle.graal.hotspot.bridge.VMToCompilerImpl.*;
 import static com.oracle.graal.nodes.StructuredGraph.*;
-import static com.oracle.graal.phases.GraalOptions.*;
 import static com.oracle.graal.phases.common.InliningUtil.*;
 
 import java.io.*;
 import java.lang.management.*;
-import java.lang.reflect.*;
 import java.util.*;
 import java.util.concurrent.*;
 import java.util.concurrent.atomic.*;
@@ -42,6 +41,7 @@
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.baseline.*;
 import com.oracle.graal.compiler.*;
+import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.debug.Debug.Scope;
 import com.oracle.graal.debug.internal.*;
@@ -57,9 +57,7 @@
 
 import edu.umd.cs.findbugs.annotations.*;
 
-public class CompilationTask implements Runnable, Comparable {
-
-    private static final long TIMESTAMP_START = System.currentTimeMillis();
+public class CompilationTask implements Runnable, Comparable {
 
     // Keep static finals in a group with withinEnqueue as the last one. CompilationTask can be
     // called from within it's own clinit so it needs to be careful about accessing state. Once
@@ -314,7 +312,7 @@
             }
 
             try (TimerCloseable b = CodeInstallationTime.start()) {
-                installedCode = installMethod(result);
+                installedCode = (HotSpotInstalledCode) installMethod(result);
                 if (!isOSR) {
                     ProfilingInfo profile = method.getProfilingInfo();
                     profile.setCompilerIRSize(StructuredGraph.class, graph.getNodeCount());
@@ -365,31 +363,30 @@
      */
     private void printCompilation() {
         final boolean isOSR = entryBCI != StructuredGraph.INVOCATION_ENTRY_BCI;
-        final int mod = method.getModifiers();
         String compilerName = "";
         if (HotSpotCIPrintCompilerName.getValue()) {
             compilerName = "Graal:";
         }
         HotSpotVMConfig config = backend.getRuntime().getConfig();
         int compLevel = config.compilationLevelFullOptimization;
-        char compLevelChar;
+        String compLevelString;
         if (config.tieredCompilation) {
-            compLevelChar = '-';
+            compLevelString = "- ";
             if (compLevel != -1) {
-                compLevelChar = (char) ('0' + compLevel);
+                compLevelString = (char) ('0' + compLevel) + " ";
             }
         } else {
-            compLevelChar = ' ';
+            compLevelString = "";
         }
         boolean hasExceptionHandlers = method.getExceptionHandlers().length > 0;
-        TTY.println(String.format("%s%7d %4d %c%c%c%c%c%c      %s %s(%d bytes)", compilerName, (System.currentTimeMillis() - TIMESTAMP_START), id, isOSR ? '%' : ' ',
-                        Modifier.isSynchronized(mod) ? 's' : ' ', hasExceptionHandlers ? '!' : ' ', blocking ? 'b' : ' ', Modifier.isNative(mod) ? 'n' : ' ', compLevelChar,
-                        MetaUtil.format("%H::%n(%p)", method), isOSR ? "@ " + entryBCI + " " : "", method.getCodeSize()));
+        TTY.println(String.format("%s%7d %4d %c%c%c%c%c %s      %s %s(%d bytes)", compilerName, backend.getRuntime().compilerToVm.getTimeStamp(), id, isOSR ? '%' : ' ', method.isSynchronized() ? 's'
+                        : ' ', hasExceptionHandlers ? '!' : ' ', blocking ? 'b' : ' ', method.isNative() ? 'n' : ' ', compLevelString, MetaUtil.format("%H::%n(%p)", method), isOSR ? "@ " + entryBCI +
+                        " " : "", method.getCodeSize()));
     }
 
-    private HotSpotInstalledCode installMethod(final CompilationResult compResult) {
+    private InstalledCode installMethod(final CompilationResult compResult) {
         final HotSpotCodeCacheProvider codeCache = backend.getProviders().getCodeCache();
-        HotSpotInstalledCode installedCode = null;
+        InstalledCode installedCode = null;
         try (Scope s = Debug.scope("CodeInstall", new DebugDumpScope(String.valueOf(id), true), codeCache, method)) {
             installedCode = codeCache.installMethod(method, compResult);
         } catch (Throwable e) {
diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompileTheWorld.java
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompileTheWorld.java	Wed Apr 23 15:22:20 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompileTheWorld.java	Wed Apr 23 15:48:38 2014 +0200
@@ -22,9 +22,9 @@
  */
 package com.oracle.graal.hotspot;
 
+import static com.oracle.graal.compiler.common.GraalOptions.*;
 import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
 import static com.oracle.graal.nodes.StructuredGraph.*;
-import static com.oracle.graal.phases.GraalOptions.*;
 
 import java.io.*;
 import java.lang.reflect.*;
@@ -35,8 +35,8 @@
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.api.meta.ProfilingInfo.TriState;
 import com.oracle.graal.bytecode.*;
+import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.debug.*;
-import com.oracle.graal.graph.*;
 import com.oracle.graal.hotspot.HotSpotOptions.OptionConsumer;
 import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.options.*;
@@ -311,7 +311,7 @@
         }
 
         println();
-        TTY.println("CompileTheWorld : Done (%d classes, %d methods, %d ms)", classFileCounter, compiledMethodsCounter, compileTime);
+        println("CompileTheWorld : Done (%d classes, %d methods, %d ms)", classFileCounter, compiledMethodsCounter, compileTime);
     }
 
     class CTWCompilationTask extends CompilationTask {
diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotBackend.java
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotBackend.java	Wed Apr 23 15:22:20 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotBackend.java	Wed Apr 23 15:48:38 2014 +0200
@@ -25,7 +25,9 @@
 import java.util.*;
 
 import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.code.stack.*;
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.compiler.common.cfg.*;
 import com.oracle.graal.compiler.target.*;
 import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.hotspot.stubs.*;
@@ -34,7 +36,6 @@
 import com.oracle.graal.lir.StandardOp.LabelOp;
 import com.oracle.graal.lir.StandardOp.SaveRegistersOp;
 import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.cfg.*;
 import com.oracle.graal.phases.tiers.*;
 import com.oracle.graal.word.*;
 
@@ -44,9 +45,9 @@
 public abstract class HotSpotBackend extends Backend {
 
     /**
-     * Descriptor for SharedRuntime::deopt_blob()->uncommon_trap().
+     * Descriptor for {@link DeoptimizationStub}.
      */
-    public static final ForeignCallDescriptor UNCOMMON_TRAP = new ForeignCallDescriptor("deoptimize", void.class);
+    public static final ForeignCallDescriptor UNCOMMON_TRAP_HANDLER = new ForeignCallDescriptor("uncommonTrapHandler", void.class);
 
     /**
      * Descriptor for {@link ExceptionHandlerStub}. This stub is called by the
@@ -96,7 +97,7 @@
 
     /**
      * Finds all the registers that are defined by some given LIR.
-     * 
+     *
      * @param lir the LIR to examine
      * @return the registers that are defined by or used as temps for any instruction in {@code lir}
      */
@@ -134,7 +135,7 @@
      * {@linkplain SaveRegistersOp#remove(Set) removed} as these registers are declared as
      * temporaries in the stub's {@linkplain ForeignCallLinkage linkage} (and thus will be saved by
      * the stub's caller).
-     * 
+     *
      * @param stub the stub to update
      * @param destroyedRegisters the registers destroyed by the stub
      * @param calleeSaveInfo a map from debug infos to the operations that provide their
@@ -158,6 +159,11 @@
     }
 
     @Override
+    public StackIntrospection getStackIntrospection() {
+        return runtime;
+    }
+
+    @Override
     public HotSpotProviders getProviders() {
         return (HotSpotProviders) super.getProviders();
     }
diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotCompiledRuntimeStub.java
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotCompiledRuntimeStub.java	Wed Apr 23 15:22:20 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotCompiledRuntimeStub.java	Wed Apr 23 15:48:38 2014 +0200
@@ -22,11 +22,14 @@
  */
 package com.oracle.graal.hotspot;
 
+import static com.oracle.graal.hotspot.HotSpotBackend.*;
+
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.code.CompilationResult.Call;
 import com.oracle.graal.api.code.CompilationResult.DataPatch;
 import com.oracle.graal.api.code.CompilationResult.Infopoint;
 import com.oracle.graal.hotspot.data.*;
+import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.hotspot.stubs.*;
 
 /**
@@ -40,8 +43,8 @@
 
     public HotSpotCompiledRuntimeStub(TargetDescription target, Stub stub, CompilationResult compResult) {
         super(target, compResult);
+        this.stubName = stub.toString();
         assert checkStubInvariants(compResult);
-        this.stubName = stub.toString();
     }
 
     /**
@@ -50,6 +53,15 @@
     private boolean checkStubInvariants(CompilationResult compResult) {
         assert compResult.getExceptionHandlers().isEmpty();
         for (DataPatch data : compResult.getDataReferences()) {
+            if (data.data instanceof MetaspaceData) {
+                MetaspaceData meta = (MetaspaceData) data.data;
+                if (meta.annotation instanceof HotSpotResolvedObjectType && ((HotSpotResolvedObjectType) meta.annotation).getName().equals("[I")) {
+                    // special handling for NewArrayStub
+                    // embedding the type '[I' is safe, since it is never unloaded
+                    continue;
+                }
+            }
+
             assert !(data.data instanceof PatchedData) : this + " cannot have embedded object or metadata constant: " + data.data;
         }
         for (Infopoint infopoint : compResult.getInfopoints()) {
@@ -57,8 +69,13 @@
             Call call = (Call) infopoint;
             assert call.target instanceof HotSpotForeignCallLinkage : this + " cannot have non runtime call: " + call.target;
             HotSpotForeignCallLinkage linkage = (HotSpotForeignCallLinkage) call.target;
-            assert !linkage.isCompiledStub() : this + " cannot call compiled stub " + linkage;
+            assert !linkage.isCompiledStub() || linkage.getDescriptor() == UNCOMMON_TRAP_HANDLER : this + " cannot call compiled stub " + linkage;
         }
         return true;
     }
+
+    @Override
+    public String toString() {
+        return stubName != null ? stubName : super.toString();
+    }
 }
diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotDebugInfoBuilder.java
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotDebugInfoBuilder.java	Wed Apr 23 15:22:20 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotDebugInfoBuilder.java	Wed Apr 23 15:48:38 2014 +0200
@@ -64,4 +64,10 @@
     protected LIRFrameState newLIRFrameState(LabelRef exceptionEdge, BytecodeFrame frame, VirtualObject[] virtualObjectsArray) {
         return new HotSpotLIRFrameState(frame, virtualObjectsArray, exceptionEdge);
     }
+
+    @Override
+    protected BytecodeFrame computeFrameForState(FrameState state) {
+        assert state.bci >= 0 || state.bci == BytecodeFrame.BEFORE_BCI;
+        return super.computeFrameForState(state);
+    }
 }
diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotForeignCallLinkage.java
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotForeignCallLinkage.java	Wed Apr 23 15:22:20 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotForeignCallLinkage.java	Wed Apr 23 15:48:38 2014 +0200
@@ -151,7 +151,7 @@
         return regConfig.getCallingConvention(ccType, returnType, parameterTypes, target, false);
     }
 
-    private static JavaType asJavaType(Class type, MetaAccessProvider metaAccess, CodeCacheProvider codeCache) {
+    private static JavaType asJavaType(Class type, MetaAccessProvider metaAccess, CodeCacheProvider codeCache) {
         if (WordBase.class.isAssignableFrom(type)) {
             return metaAccess.lookupJavaType(codeCache.getTarget().wordKind.toJavaClass());
         } else {
diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java	Wed Apr 23 15:22:20 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java	Wed Apr 23 15:48:38 2014 +0200
@@ -22,9 +22,9 @@
  */
 package com.oracle.graal.hotspot;
 
-import static com.oracle.graal.graph.UnsafeAccess.*;
+import static com.oracle.graal.compiler.common.GraalOptions.*;
+import static com.oracle.graal.compiler.common.UnsafeAccess.*;
 import static com.oracle.graal.hotspot.HotSpotGraalRuntime.Options.*;
-import static com.oracle.graal.phases.GraalOptions.*;
 
 import java.lang.reflect.*;
 import java.util.*;
@@ -33,10 +33,12 @@
 import sun.reflect.*;
 
 import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.code.stack.*;
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.replacements.*;
 import com.oracle.graal.api.runtime.*;
+import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.compiler.target.*;
-import com.oracle.graal.graph.*;
 import com.oracle.graal.hotspot.bridge.*;
 import com.oracle.graal.hotspot.logging.*;
 import com.oracle.graal.hotspot.meta.*;
@@ -48,7 +50,7 @@
 /**
  * Singleton class holding the instance of the {@link GraalRuntime}.
  */
-public final class HotSpotGraalRuntime implements GraalRuntime, RuntimeProvider {
+public final class HotSpotGraalRuntime implements GraalRuntime, RuntimeProvider, StackIntrospection {
 
     private static final HotSpotGraalRuntime instance = new HotSpotGraalRuntime();
     static {
@@ -62,7 +64,7 @@
     public static HotSpotGraalRuntime runtime() {
         SecurityManager sm = System.getSecurityManager();
         if (sm != null) {
-            Class cc = Reflection.getCallerClass();
+            Class cc = Reflection.getCallerClass();
             if (cc != null && cc.getClassLoader() != null) {
                 sm.checkPermission(Graal.ACCESS_PERMISSION);
             }
@@ -153,7 +155,7 @@
      * Checks that a factory overriding is valid. A factory B can only override/replace a factory A
      * if the B.getClass() is a subclass of A.getClass(). This models the assumption that B is
      * extends the behavior of A and has therefore understood the behavior expected of A.
-     * 
+     *
      * @param baseFactory
      * @param overridingFactory
      */
@@ -265,15 +267,13 @@
 
     /**
      * Gets the Graal mirror for a {@link Class} object.
-     * 
+     *
      * @return the {@link HotSpotResolvedJavaType} corresponding to {@code javaClass}
      */
     public ResolvedJavaType fromClass(Class javaClass) {
         return graalMirrors.get(javaClass);
     }
 
-    public static final String GRAAL_GPU_ISALIST_PROPERTY_NAME = "graal.gpu.isalist";
-
     /**
      * Gets the names of the supported GPU architectures for the purpose of finding the
      * corresponding {@linkplain HotSpotBackendFactory backend} objects.
@@ -320,7 +320,7 @@
 
     /**
      * Converts a name to a Java type.
-     * 
+     *
      * @param name a well formed Java type in {@linkplain JavaType#getName() internal} format
      * @param accessingType the context of resolution (may be null)
      * @param resolve force resolution to a {@link ResolvedJavaType}. If true, this method will
@@ -364,6 +364,10 @@
     public  T getCapability(Class clazz) {
         if (clazz == RuntimeProvider.class) {
             return (T) this;
+        } else if (clazz == StackIntrospection.class) {
+            return (T) this;
+        } else if (clazz == SnippetReflectionProvider.class) {
+            return (T) getHostProviders().getSnippetReflection();
         }
         return null;
     }
@@ -383,7 +387,7 @@
 
     /**
      * The offset from the origin of an array to the first element.
-     * 
+     *
      * @return the offset in bytes
      */
     public static int getArrayBaseOffset(Kind kind) {
@@ -413,7 +417,7 @@
 
     /**
      * The scale used for the index when accessing elements of an array of this kind.
-     * 
+     *
      * @return the scale in order to convert the index into a byte offset
      */
     public static int getArrayIndexScale(Kind kind) {
@@ -440,4 +444,50 @@
                 throw GraalInternalError.shouldNotReachHere();
         }
     }
+
+    public Iterable getStackTrace(ResolvedJavaMethod[] initialMethods, ResolvedJavaMethod[] matchingMethods, int initialSkip) {
+        final long[] initialMetaMethods = toMeta(initialMethods);
+        final long[] matchingMetaMethods = toMeta(matchingMethods);
+        class StackFrameIterator implements Iterator {
+
+            private HotSpotStackFrameReference current = compilerToVm.getNextStackFrame(null, initialMetaMethods, initialSkip);
+            // we don't want to read ahead if hasNext isn't called
+            private boolean advanced = true;
+
+            public boolean hasNext() {
+                update();
+                return current != null;
+            }
+
+            public InspectedFrame next() {
+                update();
+                advanced = false;
+                return current;
+            }
+
+            private void update() {
+                if (!advanced) {
+                    current = compilerToVm.getNextStackFrame(current, matchingMetaMethods, 0);
+                    advanced = true;
+                }
+            }
+        }
+        return new Iterable() {
+            public Iterator iterator() {
+                return new StackFrameIterator();
+            }
+        };
+    }
+
+    private static long[] toMeta(ResolvedJavaMethod[] methods) {
+        if (methods == null) {
+            return null;
+        } else {
+            long[] result = new long[methods.length];
+            for (int i = 0; i < result.length; i++) {
+                result[i] = ((HotSpotResolvedJavaMethod) methods[i]).getMetaspaceMethod();
+            }
+            return result;
+        }
+    }
 }
diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotHostBackend.java
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotHostBackend.java	Wed Apr 23 15:22:20 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotHostBackend.java	Wed Apr 23 15:48:38 2014 +0200
@@ -22,7 +22,7 @@
  */
 package com.oracle.graal.hotspot;
 
-import static com.oracle.graal.phases.GraalOptions.*;
+import static com.oracle.graal.compiler.common.GraalOptions.*;
 
 import java.util.*;
 
diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotLIRGenerator.java
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotLIRGenerator.java	Wed Apr 23 15:22:20 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotLIRGenerator.java	Wed Apr 23 15:48:38 2014 +0200
@@ -24,27 +24,41 @@
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
-import com.oracle.graal.compiler.gen.*;
 import com.oracle.graal.hotspot.HotSpotVMConfig.CompressEncoding;
 import com.oracle.graal.hotspot.meta.*;
-import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.lir.StandardOp.SaveRegistersOp;
+import com.oracle.graal.lir.gen.*;
 
 /**
  * This interface defines the contract a HotSpot backend LIR generator needs to fulfill in addition
- * to abstract methods from {@link LIRGenerator} and {@link NodeLIRBuilderTool}.
+ * to abstract methods from {@link LIRGenerator} and {@link LIRGeneratorTool}.
  */
-public interface HotSpotLIRGenerator {
+public interface HotSpotLIRGenerator extends LIRGeneratorTool {
 
     /**
      * Emits an operation to make a tail call.
-     * 
+     *
      * @param args the arguments of the call
      * @param address the target address of the call
      */
     void emitTailcall(Value[] args, Value address);
 
+    void emitLeaveCurrentStackFrame();
+
+    void emitLeaveDeoptimizedStackFrame(Value frameSize, Value initialInfo);
+
+    void emitEnterUnpackFramesStackFrame(Value framePc, Value senderSp, Value senderFp);
+
+    void emitLeaveUnpackFramesStackFrame();
+
+    SaveRegistersOp emitSaveAllRegisters();
+
     void emitDeoptimizeCaller(DeoptimizationAction action, DeoptimizationReason reason);
 
+    void emitPushInterpreterFrame(Value frameSize, Value framePc, Value senderSp, Value initialInfo);
+
+    Value emitUncommonTrapCall(Value trapRequest, SaveRegistersOp saveRegisterOp);
+
     /**
      * Gets a stack slot for a lock at a given lock nesting depth.
      */
@@ -52,7 +66,7 @@
 
     HotSpotProviders getProviders();
 
-    Value emitCompress(Value pointer, CompressEncoding encoding);
+    Value emitCompress(Value pointer, CompressEncoding encoding, boolean nonNull);
 
-    Value emitUncompress(Value pointer, CompressEncoding encoding);
+    Value emitUncompress(Value pointer, CompressEncoding encoding, boolean nonNull);
 }
diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotNodeLIRBuilder.java
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotNodeLIRBuilder.java	Wed Apr 23 15:22:20 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotNodeLIRBuilder.java	Wed Apr 23 15:48:38 2014 +0200
@@ -22,8 +22,8 @@
  */
 package com.oracle.graal.hotspot;
 
-import com.oracle.graal.compiler.gen.*;
 import com.oracle.graal.hotspot.nodes.*;
+import com.oracle.graal.lir.gen.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
 
diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotOptions.java
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotOptions.java	Wed Apr 23 15:22:20 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotOptions.java	Wed Apr 23 15:48:38 2014 +0200
@@ -33,8 +33,8 @@
 import java.nio.file.*;
 import java.util.*;
 
+import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.debug.*;
-import com.oracle.graal.graph.*;
 import com.oracle.graal.hotspot.logging.*;
 import com.oracle.graal.options.*;
 import com.oracle.graal.phases.common.*;
@@ -217,7 +217,7 @@
      * @param c the class in which the field is declared
      * @param name the name of the field
      */
-    private static void unconditionallyEnableTimerOrMetric(Class c, String name) {
+    private static void unconditionallyEnableTimerOrMetric(Class c, String name) {
         try {
             Field field = c.getDeclaredField(name);
             String propertyName;
diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotReplacementsImpl.java
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotReplacementsImpl.java	Wed Apr 23 15:22:20 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotReplacementsImpl.java	Wed Apr 23 15:48:38 2014 +0200
@@ -26,10 +26,11 @@
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.replacements.*;
+import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.hotspot.replacements.*;
 import com.oracle.graal.nodes.*;
-import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.util.*;
 import com.oracle.graal.replacements.*;
 
@@ -41,8 +42,8 @@
 
     private final HotSpotVMConfig config;
 
-    public HotSpotReplacementsImpl(Providers providers, HotSpotVMConfig config, Assumptions assumptions, TargetDescription target) {
-        super(providers, assumptions, target);
+    public HotSpotReplacementsImpl(Providers providers, SnippetReflectionProvider snippetReflection, HotSpotVMConfig config, Assumptions assumptions, TargetDescription target) {
+        super(providers, snippetReflection, assumptions, target);
         this.config = config;
     }
 
diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotStackFrameReference.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotStackFrameReference.java	Wed Apr 23 15:48:38 2014 +0200
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2014, 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;
+
+import java.util.*;
+
+import com.oracle.graal.api.code.stack.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.hotspot.bridge.*;
+import com.oracle.graal.hotspot.meta.*;
+
+public class HotSpotStackFrameReference implements InspectedFrame {
+
+    private CompilerToVM compilerToVM;
+
+    // information used to find the stack frame
+    private long stackPointer;
+    private int frameNumber;
+
+    // information about the stack frame's contents
+    private int bci;
+    private long metaspaceMethod;
+    private Object[] locals;
+    private boolean[] localIsVirtual;
+
+    public long getStackPointer() {
+        return stackPointer;
+    }
+
+    public int getFrameNumber() {
+        return frameNumber;
+    }
+
+    public Object getLocal(int index) {
+        return locals[index];
+    }
+
+    public boolean isVirtual(int index) {
+        return localIsVirtual == null ? false : localIsVirtual[index];
+    }
+
+    public void materializeVirtualObjects(boolean invalidateCode) {
+        compilerToVM.materializeVirtualObjects(this, invalidateCode);
+    }
+
+    public int getBytecodeIndex() {
+        return bci;
+    }
+
+    public ResolvedJavaMethod getMethod() {
+        return HotSpotResolvedJavaMethod.fromMetaspace(metaspaceMethod);
+    }
+
+    public boolean hasVirtualObjects() {
+        return localIsVirtual != null;
+    }
+
+    @Override
+    public String toString() {
+        return "HotSpotStackFrameReference [stackPointer=" + stackPointer + ", frameNumber=" + frameNumber + ", bci=" + bci + ", method=" + getMethod() + ", locals=" + Arrays.toString(locals) +
+                        ", localIsVirtual=" + Arrays.toString(localIsVirtual) + "]";
+    }
+}
diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotSymbol.java
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotSymbol.java	Wed Apr 23 15:22:20 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotSymbol.java	Wed Apr 23 15:48:38 2014 +0200
@@ -22,12 +22,12 @@
  */
 package com.oracle.graal.hotspot;
 
-import static com.oracle.graal.graph.UnsafeAccess.*;
+import static com.oracle.graal.compiler.common.UnsafeAccess.*;
 import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
 
 import java.io.*;
 
-import com.oracle.graal.graph.*;
+import com.oracle.graal.compiler.common.*;
 
 /**
  * Represents a metaspace {@code Symbol}.
diff -r 518a7f487c4f -r 9363fffa8b07 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 Apr 23 15:22:20 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java	Wed Apr 23 15:48:38 2014 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -22,12 +22,12 @@
  */
 package com.oracle.graal.hotspot;
 
-import static com.oracle.graal.graph.UnsafeAccess.*;
+import static com.oracle.graal.compiler.common.UnsafeAccess.*;
 
 import java.lang.reflect.*;
 import java.util.*;
 
-import com.oracle.graal.graph.*;
+import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.hotspot.bridge.*;
 import com.oracle.graal.hotspot.meta.*;
 
@@ -857,6 +857,7 @@
     @HotSpotVMField(name = "Array::_length", type = "int", get = HotSpotVMField.Type.OFFSET) @Stable public int metaspaceArrayLengthOffset;
     @HotSpotVMField(name = "Array::_data[0]", type = "Klass*", get = HotSpotVMField.Type.OFFSET) @Stable public int metaspaceArrayBaseOffset;
 
+    @HotSpotVMField(name = "InstanceKlass::_graal_node_class", type = "oop", get = HotSpotVMField.Type.OFFSET) @Stable public int klassNodeClassOffset;
     @HotSpotVMField(name = "InstanceKlass::_source_file_name_index", type = "u2", get = HotSpotVMField.Type.OFFSET) @Stable public int klassSourceFileNameIndexOffset;
     @HotSpotVMField(name = "InstanceKlass::_init_state", type = "u1", get = HotSpotVMField.Type.OFFSET) @Stable public int klassStateOffset;
     @HotSpotVMField(name = "InstanceKlass::_constants", type = "ConstantPool*", get = HotSpotVMField.Type.OFFSET) @Stable public int instanceKlassConstantsOffset;
@@ -961,7 +962,10 @@
         return javaThreadAnchorOffset + javaFrameAnchorFlagsOffset;
     }
 
+    // These are only valid on AMD64.
     @HotSpotVMConstant(name = "frame::arg_reg_save_area_bytes", archs = {"amd64"}) @Stable public int runtimeCallStackSize;
+    @HotSpotVMConstant(name = "frame::interpreter_frame_sender_sp_offset", archs = {"amd64"}) @Stable public int frameInterpreterFrameSenderSpOffset;
+    @HotSpotVMConstant(name = "frame::interpreter_frame_last_sp_offset", archs = {"amd64"}) @Stable public int frameInterpreterFrameLastSpOffset;
 
     @HotSpotVMField(name = "PtrQueue::_active", type = "bool", get = HotSpotVMField.Type.OFFSET) @Stable public int ptrQueueActiveOffset;
     @HotSpotVMField(name = "PtrQueue::_buf", type = "void**", get = HotSpotVMField.Type.OFFSET) @Stable public int ptrQueueBufferOffset;
@@ -1009,16 +1013,19 @@
     @HotSpotVMField(name = "ThreadShadow::_pending_failed_speculation", type = "oop", get = HotSpotVMField.Type.OFFSET) @Stable public int pendingFailedSpeculationOffset;
 
     @HotSpotVMFlag(name = "UseHSAILDeoptimization") @Stable public boolean useHSAILDeoptimization;
+    @HotSpotVMFlag(name = "UseHSAILSafepoints") @Stable public boolean useHSAILSafepoints;
 
     /**
      * Offsets of Hsail deoptimization fields (defined in gpu_hsail.hpp). Used to propagate
      * exceptions from Hsail back to C++ runtime.
      */
+    @HotSpotVMField(name = "Hsail::HSAILDeoptimizationInfo::_notice_safepoints", type = "jint*", get = HotSpotVMField.Type.OFFSET) @Stable public int hsailNoticeSafepointsOffset;
     @HotSpotVMField(name = "Hsail::HSAILDeoptimizationInfo::_deopt_save_states[0]", type = "Hsail::HSAILKernelDeoptimization", get = HotSpotVMField.Type.OFFSET) @Stable public int hsailSaveStatesOffset0;
     @HotSpotVMField(name = "Hsail::HSAILDeoptimizationInfo::_deopt_save_states[1]", type = "Hsail::HSAILKernelDeoptimization", get = HotSpotVMField.Type.OFFSET) @Stable public int hsailSaveStatesOffset1;
-    @HotSpotVMField(name = "Hsail::HSAILDeoptimizationInfo::_deopt_occurred", type = "jint", get = HotSpotVMField.Type.OFFSET) @Stable public int hsailDeoptOffset;
+    @HotSpotVMField(name = "Hsail::HSAILDeoptimizationInfo::_deopt_occurred", type = "jint", get = HotSpotVMField.Type.OFFSET) @Stable public int hsailDeoptOccurredOffset;
     @HotSpotVMField(name = "Hsail::HSAILDeoptimizationInfo::_never_ran_array", type = "jboolean *", get = HotSpotVMField.Type.OFFSET) @Stable public int hsailNeverRanArrayOffset;
     @HotSpotVMField(name = "Hsail::HSAILDeoptimizationInfo::_deopt_next_index", type = "jint", get = HotSpotVMField.Type.OFFSET) @Stable public int hsailDeoptNextIndexOffset;
+    @HotSpotVMField(name = "Hsail::HSAILDeoptimizationInfo::_donor_threads", type = "JavaThread**", get = HotSpotVMField.Type.OFFSET) @Stable public int hsailDonorThreadsOffset;
 
     @HotSpotVMField(name = "Hsail::HSAILKernelDeoptimization::_workitemid", type = "jint", get = HotSpotVMField.Type.OFFSET) @Stable public int hsailDeoptimizationWorkItem;
     @HotSpotVMField(name = "Hsail::HSAILKernelDeoptimization::_actionAndReason", type = "jint", get = HotSpotVMField.Type.OFFSET) @Stable public int hsailDeoptimizationReason;
@@ -1054,6 +1061,7 @@
     @HotSpotVMConstant(name = "Method::_force_inline") @Stable public int methodFlagsForceInline;
     @HotSpotVMConstant(name = "Method::_dont_inline") @Stable public int methodFlagsDontInline;
     @HotSpotVMConstant(name = "Method::_hidden") @Stable public int methodFlagsHidden;
+    @HotSpotVMConstant(name = "Method::nonvirtual_vtable_index") @Stable public int nonvirtualVtableIndex;
 
     @HotSpotVMConstant(name = "JVM_ACC_MONITOR_MATCH") @Stable public int jvmAccMonitorMatch;
     @HotSpotVMConstant(name = "JVM_ACC_HAS_MONITOR_BYTECODES") @Stable public int jvmAccHasMonitorBytecodes;
@@ -1244,6 +1252,7 @@
     @HotSpotVMField(name = "ThreadLocalAllocBuffer::_start", type = "HeapWord*", get = HotSpotVMField.Type.OFFSET) @Stable private int threadLocalAllocBufferStartOffset;
     @HotSpotVMField(name = "ThreadLocalAllocBuffer::_end", type = "HeapWord*", get = HotSpotVMField.Type.OFFSET) @Stable private int threadLocalAllocBufferEndOffset;
     @HotSpotVMField(name = "ThreadLocalAllocBuffer::_top", type = "HeapWord*", get = HotSpotVMField.Type.OFFSET) @Stable private int threadLocalAllocBufferTopOffset;
+    @HotSpotVMField(name = "ThreadLocalAllocBuffer::_pf_top", type = "HeapWord*", get = HotSpotVMField.Type.OFFSET) @Stable private int threadLocalAllocBufferPfTopOffset;
     @HotSpotVMField(name = "ThreadLocalAllocBuffer::_slow_allocations", type = "unsigned", get = HotSpotVMField.Type.OFFSET) @Stable private int threadLocalAllocBufferSlowAllocationsOffset;
     @HotSpotVMField(name = "ThreadLocalAllocBuffer::_fast_refill_waste", type = "unsigned", get = HotSpotVMField.Type.OFFSET) @Stable private int threadLocalAllocBufferFastRefillWasteOffset;
     @HotSpotVMField(name = "ThreadLocalAllocBuffer::_number_of_refills", type = "unsigned", get = HotSpotVMField.Type.OFFSET) @Stable private int threadLocalAllocBufferNumberOfRefillsOffset;
@@ -1282,6 +1291,10 @@
         return threadTlabOffset + threadLocalAllocBufferTopOffset;
     }
 
+    public int threadTlabPfTopOffset() {
+        return threadTlabOffset + threadLocalAllocBufferPfTopOffset;
+    }
+
     @HotSpotVMFlag(name = "TLABStats") @Stable public boolean tlabStats;
     @Stable public boolean inlineContiguousAllocationSupported;
 
@@ -1340,7 +1353,6 @@
     }
 
     @Stable public long handleDeoptStub;
-    @Stable public long uncommonTrapStub;
 
     @HotSpotVMField(name = "StubRoutines::_aescrypt_encryptBlock", type = "address", get = HotSpotVMField.Type.VALUE) @Stable public long aescryptEncryptBlockStub;
     @HotSpotVMField(name = "StubRoutines::_aescrypt_decryptBlock", type = "address", get = HotSpotVMField.Type.VALUE) @Stable public long aescryptDecryptBlockStub;
@@ -1410,6 +1422,10 @@
 
     @Stable public int graalCountersSize;
 
+    @Stable public long deoptimizationFetchUnrollInfo;
+    @Stable public long deoptimizationUncommonTrap;
+    @Stable public long deoptimizationUnpackFrames;
+
     @HotSpotVMConstant(name = "Deoptimization::Reason_none") @Stable public int deoptReasonNone;
     @HotSpotVMConstant(name = "Deoptimization::Reason_null_check") @Stable public int deoptReasonNullCheck;
     @HotSpotVMConstant(name = "Deoptimization::Reason_range_check") @Stable public int deoptReasonRangeCheck;
@@ -1440,6 +1456,19 @@
     @HotSpotVMConstant(name = "Deoptimization::_reason_shift") @Stable public int deoptimizationReasonShift;
     @HotSpotVMConstant(name = "Deoptimization::_debug_id_shift") @Stable public int deoptimizationDebugIdShift;
 
+    @HotSpotVMConstant(name = "Deoptimization::Unpack_deopt") @Stable public int deoptimizationUnpackDeopt;
+    @HotSpotVMConstant(name = "Deoptimization::Unpack_exception") @Stable public int deoptimizationUnpackException;
+    @HotSpotVMConstant(name = "Deoptimization::Unpack_uncommon_trap") @Stable public int deoptimizationUnpackUncommonTrap;
+    @HotSpotVMConstant(name = "Deoptimization::Unpack_reexecute") @Stable public int deoptimizationUnpackReexecute;
+
+    @HotSpotVMField(name = "Deoptimization::UnrollBlock::_size_of_deoptimized_frame", type = "int", get = HotSpotVMField.Type.OFFSET) @Stable public int deoptimizationUnrollBlockSizeOfDeoptimizedFrameOffset;
+    @HotSpotVMField(name = "Deoptimization::UnrollBlock::_caller_adjustment", type = "int", get = HotSpotVMField.Type.OFFSET) @Stable public int deoptimizationUnrollBlockCallerAdjustmentOffset;
+    @HotSpotVMField(name = "Deoptimization::UnrollBlock::_number_of_frames", type = "int", get = HotSpotVMField.Type.OFFSET) @Stable public int deoptimizationUnrollBlockNumberOfFramesOffset;
+    @HotSpotVMField(name = "Deoptimization::UnrollBlock::_total_frame_sizes", type = "int", get = HotSpotVMField.Type.OFFSET) @Stable public int deoptimizationUnrollBlockTotalFrameSizesOffset;
+    @HotSpotVMField(name = "Deoptimization::UnrollBlock::_frame_sizes", type = "intptr_t*", get = HotSpotVMField.Type.OFFSET) @Stable public int deoptimizationUnrollBlockFrameSizesOffset;
+    @HotSpotVMField(name = "Deoptimization::UnrollBlock::_frame_pcs", type = "address*", get = HotSpotVMField.Type.OFFSET) @Stable public int deoptimizationUnrollBlockFramePcsOffset;
+    @HotSpotVMField(name = "Deoptimization::UnrollBlock::_initial_info", type = "intptr_t", get = HotSpotVMField.Type.OFFSET) @Stable public int deoptimizationUnrollBlockInitialInfoOffset;
+
     @HotSpotVMConstant(name = "vmIntrinsics::_invokeBasic") @Stable public int vmIntrinsicInvokeBasic;
     @HotSpotVMConstant(name = "vmIntrinsics::_linkToVirtual") @Stable public int vmIntrinsicLinkToVirtual;
     @HotSpotVMConstant(name = "vmIntrinsics::_linkToStatic") @Stable public int vmIntrinsicLinkToStatic;
@@ -1499,6 +1528,22 @@
             this.alignment = alignment;
         }
 
+        public int compress(long ptr) {
+            if (ptr == 0L) {
+                return 0;
+            } else {
+                return (int) ((ptr - base) >>> shift);
+            }
+        }
+
+        public long uncompress(int ptr) {
+            if (ptr == 0) {
+                return 0L;
+            } else {
+                return ((ptr & 0xFFFFFFFFL) << shift) + base;
+            }
+        }
+
         @Override
         public String toString() {
             return "base: " + base + " shift: " + shift + " alignment: " + alignment;
diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVmSymbols.java
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVmSymbols.java	Wed Apr 23 15:22:20 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVmSymbols.java	Wed Apr 23 15:48:38 2014 +0200
@@ -22,7 +22,7 @@
  */
 package com.oracle.graal.hotspot;
 
-import static com.oracle.graal.graph.UnsafeAccess.*;
+import static com.oracle.graal.compiler.common.UnsafeAccess.*;
 import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
 import sun.misc.*;
 
diff -r 518a7f487c4f -r 9363fffa8b07 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 Apr 23 15:22:20 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java	Wed Apr 23 15:48:38 2014 +0200
@@ -25,7 +25,7 @@
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
-import com.oracle.graal.graph.*;
+import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.hotspot.*;
 import com.oracle.graal.hotspot.meta.*;
 
@@ -36,7 +36,7 @@
 
     /**
      * Copies the original bytecode of a given method into a given byte array.
-     * 
+     *
      * @param metaspaceMethod the metaspace Method object
      * @param code the array into which to copy the original bytecode
      * @return the value of {@code code}
@@ -49,7 +49,7 @@
 
     /**
      * Determines if a given metaspace Method object has balanced monitors.
-     * 
+     *
      * @param metaspaceMethod the metaspace Method object to query
      * @return true if the method has balanced monitors
      */
@@ -63,7 +63,7 @@
      * 
  • the method may have a bytecode breakpoint set
  • *
  • the method may have other bytecode features that require special handling by the VM
  • * - * + * * @param metaspaceMethod the metaspace Method object to query * @return true if the method can be inlined */ @@ -75,7 +75,7 @@ *
  • a CompileOracle directive may forces inlining of this methods
  • *
  • an annotation forces inlining of this method
  • * - * + * * @param metaspaceMethod the metaspace Method object to query * @return true if the method should be inlined */ @@ -83,7 +83,7 @@ /** * Used to implement {@link ResolvedJavaType#findUniqueConcreteMethod(ResolvedJavaMethod)}. - * + * * @param metaspaceMethod the metaspace Method on which to based the search * @return the metaspace Method result or 0 is there is no unique concrete method for * {@code metaspaceMethod} @@ -92,7 +92,7 @@ /** * Returns the implementor for the given interface class. - * + * * @param metaspaceKlass the metaspace klass to get the implementor for * @return the implementor as metaspace klass pointer or null if there is no implementor */ @@ -100,7 +100,7 @@ /** * Determines if a given metaspace method is ignored by security stack walks. - * + * * @param metaspaceMethod the metaspace Method object * @return true if the method is ignored */ @@ -108,7 +108,7 @@ /** * Converts a name to a metaspace klass. - * + * * @param name a well formed Java type in {@linkplain JavaType#getName() internal} format * @param accessingClass the context of resolution (may be null) * @param resolve force resolution to a {@link ResolvedJavaType}. If true, this method will @@ -134,7 +134,7 @@ /** * Looks up a class entry in a constant pool. - * + * * @param metaspaceConstantPool metaspace constant pool pointer * @param cpi constant pool index * @return a metaspace Klass for a resolved method entry, a metaspace Symbol otherwise (with @@ -144,7 +144,7 @@ /** * Looks up a method entry in a constant pool. - * + * * @param metaspaceConstantPool metaspace constant pool pointer * @param cpi constant pool index * @return a metaspace Method for a resolved method entry, 0 otherwise @@ -154,12 +154,12 @@ /** * Looks up a field entry in a constant pool and attempts to resolve it. The values returned in * {@code info} are: - * + * *
          *     [(int) flags,   // only valid if field is resolved
          *      (int) offset]  // only valid if field is resolved
          * 
    - * + * * @param metaspaceConstantPool metaspace constant pool pointer * @param cpi constant pool index * @param info an array in which the details of the field are returned @@ -221,16 +221,16 @@ /** * Installs the result of a compilation into the code cache. - * + * * @param compiledCode the result of a compilation * @param code the details of the installed CodeBlob are written to this object * @return the outcome of the installation as a {@link CodeInstallResult}. */ - CodeInstallResult installCode(HotSpotCompiledCode compiledCode, HotSpotInstalledCode code, SpeculationLog speculationLog); + CodeInstallResult installCode(HotSpotCompiledCode compiledCode, InstalledCode code, SpeculationLog speculationLog); /** * Notifies the VM of statistics for a completed compilation. - * + * * @param id the identifier of the compilation * @param method the method compiled * @param osr specifies if the compilation was for on-stack-replacement @@ -240,7 +240,7 @@ * @param timeUnitsPerSecond the granularity of the units for the {@code time} value * @param installedCode the nmethod installed as a result of the compilation */ - void notifyCompilationStatistics(int id, HotSpotResolvedJavaMethod method, boolean osr, int processedBytecodes, long time, long timeUnitsPerSecond, HotSpotInstalledCode installedCode); + void notifyCompilationStatistics(int id, HotSpotResolvedJavaMethod method, boolean osr, int processedBytecodes, long time, long timeUnitsPerSecond, InstalledCode installedCode); void printCompilationStatistics(boolean perCompiler, boolean aggregate); @@ -257,7 +257,7 @@ /** * Gets the metaspace Method object corresponding to a given {@link Class} object and slot * number. - * + * * @param holder method holder * @param slot slot number of the method * @return the metaspace Method @@ -270,9 +270,9 @@ StackTraceElement getStackTraceElement(long metaspaceMethod, int bci); - Object executeCompiledMethod(Object arg1, Object arg2, Object arg3, HotSpotInstalledCode hotspotInstalledCode) throws InvalidInstalledCodeException; + Object executeCompiledMethod(Object arg1, Object arg2, Object arg3, InstalledCode hotspotInstalledCode) throws InvalidInstalledCodeException; - Object executeCompiledMethodVarargs(Object[] args, HotSpotInstalledCode hotspotInstalledCode) throws InvalidInstalledCodeException; + Object executeCompiledMethodVarargs(Object[] args, InstalledCode hotspotInstalledCode) throws InvalidInstalledCodeException; long[] getLineNumberTable(long metaspaceMethod); @@ -282,7 +282,7 @@ String getFileName(HotSpotResolvedJavaType method); - Object readUnsafeUncompressedPointer(Object o, long displacement); + Class getJavaMirror(long metaspaceKlass); long readUnsafeKlassPointer(Object o); @@ -290,12 +290,12 @@ /** * Invalidates the profiling information and restarts profiling upon the next invocation. - * + * * @param metaspaceMethod the metaspace Method object */ void reprofile(long metaspaceMethod); - void invalidateInstalledCode(HotSpotInstalledCode hotspotInstalledCode); + void invalidateInstalledCode(InstalledCode hotspotInstalledCode); /** * Collects the current values of all Graal benchmark counters, summed up over all threads. @@ -311,17 +311,46 @@ /** * Gets the names of the supported GPU architectures. - * + * * @return a comma separated list of names */ String getGPUs(); /** - * + * * @param metaspaceMethod the method to check * @param entryBCI * @param level the compilation level * @return true if the {@code metaspaceMethod} has code for {@code level} */ boolean hasCompiledCodeForOSR(long metaspaceMethod, int entryBCI, int level); + + /** + * Fetch the time stamp used for printing inside hotspot. It's relative to VM start to that all + * events can be ordered. + * + * @return milliseconds since VM start + */ + long getTimeStamp(); + + /** + * Looks for the next Java stack frame with the given method. + * + * @param frame the starting point of the search, where {@code null} refers to the topmost frame + * @param methods the metaspace methods to look for, where {@code null} means that any frame is + * returned + * @return the frame, or {@code null} if the end of the stack was reached during the search + */ + HotSpotStackFrameReference getNextStackFrame(HotSpotStackFrameReference frame, long[] methods, int initialSkip); + + /** + * Materialized all virtual objects within the given stack frame and update the locals within + * the given stackFrame object. + * + * @param invalidate if {@code true}, the compiled method for the stack frame will be + * invalidated. + */ + void materializeVirtualObjects(HotSpotStackFrameReference stackFrame, boolean invalidate); + + void resolveInvokeDynamic(long metaspaceConstantPool, int index); } diff -r 518a7f487c4f -r 9363fffa8b07 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 Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java Wed Apr 23 15:48:38 2014 +0200 @@ -32,10 +32,10 @@ */ public class CompilerToVMImpl implements CompilerToVM { - private native int installCode0(HotSpotCompiledCode compiledCode, HotSpotInstalledCode code, SpeculationLog speculationLog); + private native int installCode0(HotSpotCompiledCode compiledCode, InstalledCode code, SpeculationLog speculationLog); @Override - public CodeInstallResult installCode(HotSpotCompiledCode compiledCode, HotSpotInstalledCode code, SpeculationLog speculationLog) { + public CodeInstallResult installCode(HotSpotCompiledCode compiledCode, InstalledCode code, SpeculationLog speculationLog) { return CodeInstallResult.getEnum(installCode0(compiledCode, code, speculationLog)); } @@ -120,7 +120,7 @@ public native StackTraceElement getStackTraceElement(long metaspaceMethod, int bci); @Override - public native Object executeCompiledMethodVarargs(Object[] args, HotSpotInstalledCode hotspotInstalledCode); + public native Object executeCompiledMethodVarargs(Object[] args, InstalledCode hotspotInstalledCode); @Override public native long[] getLineNumberTable(long metaspaceMethod); @@ -138,10 +138,10 @@ public native void reprofile(long metaspaceMethod); @Override - public native void invalidateInstalledCode(HotSpotInstalledCode hotspotInstalledCode); + public native void invalidateInstalledCode(InstalledCode hotspotInstalledCode); @Override - public native Object readUnsafeUncompressedPointer(Object o, long displacement); + public native Class getJavaMirror(long metaspaceKlass); @Override public native long readUnsafeKlassPointer(Object o); @@ -150,12 +150,12 @@ public native void doNotInlineOrCompile(long metaspaceMethod); @Override - public Object executeCompiledMethod(Object arg1, Object arg2, Object arg3, HotSpotInstalledCode hotspotInstalledCode) throws InvalidInstalledCodeException { + public Object executeCompiledMethod(Object arg1, Object arg2, Object arg3, InstalledCode hotspotInstalledCode) throws InvalidInstalledCodeException { return executeCompiledMethodVarargs(new Object[]{arg1, arg2, arg3}, hotspotInstalledCode); } public synchronized native void notifyCompilationStatistics(int id, HotSpotResolvedJavaMethod method, boolean osr, int processedBytecodes, long time, long timeUnitsPerSecond, - HotSpotInstalledCode installedCode); + InstalledCode installedCode); public synchronized native void printCompilationStatistics(boolean perCompiler, boolean aggregate); @@ -175,4 +175,11 @@ public native boolean hasCompiledCodeForOSR(long metaspaceMethod, int entryBCI, int level); + public native HotSpotStackFrameReference getNextStackFrame(HotSpotStackFrameReference frame, long[] methods, int initialSkip); + + public native void materializeVirtualObjects(HotSpotStackFrameReference stackFrame, boolean invalidate); + + public native long getTimeStamp(); + + public native void resolveInvokeDynamic(long metaspaceConstantPool, int index); } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/FastNodeClassRegistry.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/FastNodeClassRegistry.java Wed Apr 23 15:22:20 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.hotspot.bridge; - -import com.oracle.graal.graph.*; -import com.oracle.graal.hotspot.meta.*; - -/** - * A fast-path for {@link NodeClass} retrieval using {@link HotSpotResolvedObjectType}. - */ -class FastNodeClassRegistry extends NodeClass.Registry { - - @SuppressWarnings("unused") - static void initialize() { - new FastNodeClassRegistry(); - } - - private static HotSpotResolvedObjectType type(Class key) { - return (HotSpotResolvedObjectType) HotSpotResolvedObjectType.fromClass(key); - } - - @Override - public NodeClass get(Class key) { - return type(key).getNodeClass(); - } - - @Override - protected void registered(Class key, NodeClass value) { - type(key).setNodeClass(value); - } -} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompiler.java diff -r 518a7f487c4f -r 9363fffa8b07 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 Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java Wed Apr 23 15:48:38 2014 +0200 @@ -34,9 +34,9 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.*; import com.oracle.graal.compiler.CompilerThreadFactory.DebugConfigAccess; +import com.oracle.graal.compiler.common.*; import com.oracle.graal.debug.*; import com.oracle.graal.debug.internal.*; -import com.oracle.graal.graph.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.CompilationTask.Enqueueing; import com.oracle.graal.hotspot.CompileTheWorld.Config; @@ -144,8 +144,6 @@ public void startCompiler(boolean bootstrapEnabled) throws Throwable { - FastNodeClassRegistry.initialize(); - bootstrapRunning = bootstrapEnabled; if (LogFile.getValue() != null) { @@ -250,7 +248,7 @@ /** * Take action related to entering a new execution phase. - * + * * @param phase the execution phase being entered */ protected void phaseTransition(String phase) { @@ -347,7 +345,7 @@ private void enqueue(Method m) throws Throwable { JavaMethod javaMethod = runtime.getHostProviders().getMetaAccess().lookupJavaMethod(m); - assert !Modifier.isAbstract(((HotSpotResolvedJavaMethod) javaMethod).getModifiers()) && !Modifier.isNative(((HotSpotResolvedJavaMethod) javaMethod).getModifiers()) : javaMethod; + assert !((HotSpotResolvedJavaMethod) javaMethod).isAbstract() && !((HotSpotResolvedJavaMethod) javaMethod).isNative() : javaMethod; compileMethod((HotSpotResolvedJavaMethod) javaMethod, StructuredGraph.INVOCATION_ENTRY_BCI, false); } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/data/MetaspaceData.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/data/MetaspaceData.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/data/MetaspaceData.java Wed Apr 23 15:48:38 2014 +0200 @@ -26,7 +26,7 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.graph.*; +import com.oracle.graal.compiler.common.*; /** * A data item that represents a metaspace pointer. diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/data/OopData.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/data/OopData.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/data/OopData.java Wed Apr 23 15:48:38 2014 +0200 @@ -26,7 +26,7 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.graph.*; +import com.oracle.graal.compiler.common.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.nodes.type.*; diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/debug/BenchmarkCounters.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/debug/BenchmarkCounters.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/debug/BenchmarkCounters.java Wed Apr 23 15:48:38 2014 +0200 @@ -30,7 +30,8 @@ import sun.misc.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.graph.*; +import com.oracle.graal.compiler.common.*; +import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.bridge.*; import com.oracle.graal.hotspot.meta.*; @@ -40,7 +41,6 @@ import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.debug.*; import com.oracle.graal.nodes.extended.*; -import com.oracle.graal.nodes.type.*; import com.oracle.graal.options.*; import com.oracle.graal.replacements.nodes.*; diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/logging/CountingProxy.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/logging/CountingProxy.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/logging/CountingProxy.java Wed Apr 23 15:48:38 2014 +0200 @@ -79,7 +79,7 @@ return interf.cast(obj); } - private static ArrayList proxies = new ArrayList<>(); + private static ArrayList> proxies = new ArrayList<>(); static { if (ENABLED) { @@ -87,7 +87,7 @@ @Override public void run() { - for (CountingProxy proxy : proxies) { + for (CountingProxy proxy : proxies) { proxy.print(); } } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotCodeCacheProvider.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotCodeCacheProvider.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotCodeCacheProvider.java Wed Apr 23 15:48:38 2014 +0200 @@ -35,8 +35,8 @@ import com.oracle.graal.api.code.CompilationResult.Mark; import com.oracle.graal.api.code.CompilationResult.PrimitiveData; import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.common.*; import com.oracle.graal.debug.*; -import com.oracle.graal.graph.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.bridge.*; import com.oracle.graal.hotspot.bridge.CompilerToVM.CodeInstallResult; @@ -196,7 +196,7 @@ return runtime.getConfig().runtimeCallStackSize; } - public HotSpotInstalledCode logOrDump(HotSpotInstalledCode installedCode, CompilationResult compResult) { + public InstalledCode logOrDump(InstalledCode installedCode, CompilationResult compResult) { if (Debug.isDumpEnabled()) { Debug.dump(new Object[]{compResult, installedCode}, "After code installation"); } @@ -206,7 +206,7 @@ return installedCode; } - public HotSpotInstalledCode installMethod(HotSpotResolvedJavaMethod method, CompilationResult compResult) { + public InstalledCode installMethod(HotSpotResolvedJavaMethod method, CompilationResult compResult) { if (compResult.getId() == -1) { compResult.setId(method.allocateCompileId(compResult.getEntryBCI())); } @@ -216,17 +216,21 @@ } @Override - public InstalledCode addMethod(ResolvedJavaMethod method, CompilationResult compResult, SpeculationLog log) { + public InstalledCode addMethod(ResolvedJavaMethod method, CompilationResult compResult, SpeculationLog log, InstalledCode predefinedInstalledCode) { HotSpotResolvedJavaMethod hotspotMethod = (HotSpotResolvedJavaMethod) method; if (compResult.getId() == -1) { compResult.setId(hotspotMethod.allocateCompileId(compResult.getEntryBCI())); } - HotSpotInstalledCode code = new HotSpotNmethod(hotspotMethod, compResult.getName(), false); - CodeInstallResult result = runtime.getCompilerToVM().installCode(new HotSpotCompiledNmethod(target, hotspotMethod, compResult), code, log); + InstalledCode installedCode = predefinedInstalledCode; + if (installedCode == null) { + HotSpotInstalledCode code = new HotSpotNmethod(hotspotMethod, compResult.getName(), false); + installedCode = code; + } + CodeInstallResult result = runtime.getCompilerToVM().installCode(new HotSpotCompiledNmethod(target, hotspotMethod, compResult), installedCode, log); if (result != CodeInstallResult.OK) { - return null; + throw new BailoutException("Code installation failed: " + result); } - return logOrDump(code, compResult); + return logOrDump(installedCode, compResult); } @Override @@ -251,14 +255,16 @@ } public boolean needsDataPatch(Constant constant) { - return constant.getPrimitiveAnnotation() != null; + return constant instanceof HotSpotMetaspaceConstant; } public Data createDataItem(Constant constant, int alignment) { - if (constant.getPrimitiveAnnotation() != null) { - return new MetaspaceData(alignment, constant.asLong(), constant.getPrimitiveAnnotation(), false); + if (constant instanceof HotSpotMetaspaceConstant) { + // constant.getKind() == target.wordKind for uncompressed pointers + // otherwise, it's a compressed pointer + return new MetaspaceData(alignment, constant.asLong(), HotSpotMetaspaceConstant.getMetaspaceObject(constant), constant.getKind() != target.wordKind); } else if (constant.getKind().isObject()) { - return new OopData(alignment, constant.asObject(), false); + return new OopData(alignment, HotSpotObjectConstant.asObject(constant), false); } else { return new PrimitiveData(constant, alignment); } @@ -271,7 +277,7 @@ public String disassemble(InstalledCode code) { if (code.isValid()) { - long codeBlob = ((HotSpotInstalledCode) code).getCodeBlob(); + long codeBlob = ((HotSpotInstalledCode) code).getAddress(); return runtime.getCompilerToVM().disassembleCodeBlob(codeBlob); } return null; diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantPool.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantPool.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantPool.java Wed Apr 23 15:48:38 2014 +0200 @@ -22,14 +22,14 @@ */ package com.oracle.graal.hotspot.meta; -import static com.oracle.graal.graph.UnsafeAccess.*; +import static com.oracle.graal.compiler.common.UnsafeAccess.*; import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; import java.lang.invoke.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.bytecode.*; -import com.oracle.graal.graph.*; +import com.oracle.graal.compiler.common.*; import com.oracle.graal.hotspot.*; /** @@ -368,13 +368,13 @@ return lookupType(cpi, opcode); case String: Object string = runtime().getCompilerToVM().resolvePossiblyCachedConstantInPool(metaspaceConstantPool, cpi); - return Constant.forObject(string); + return HotSpotObjectConstant.forObject(string); case MethodHandle: case MethodHandleInError: case MethodType: case MethodTypeInError: Object obj = runtime().getCompilerToVM().resolveConstantInPool(metaspaceConstantPool, cpi); - return Constant.forObject(obj); + return HotSpotObjectConstant.forObject(obj); default: throw GraalInternalError.shouldNotReachHere("unknown constant pool tag " + tag); } @@ -394,10 +394,15 @@ } @Override - public Object lookupAppendix(int cpi, int opcode) { + public Constant lookupAppendix(int cpi, int opcode) { assert Bytecodes.isInvoke(opcode); final int index = toConstantPoolIndex(cpi, opcode); - return runtime().getCompilerToVM().lookupAppendixInPool(metaspaceConstantPool, index); + Object result = runtime().getCompilerToVM().lookupAppendixInPool(metaspaceConstantPool, index); + if (result == null) { + return null; + } else { + return HotSpotObjectConstant.forObject(result); + } } /** @@ -496,7 +501,7 @@ break; case Bytecodes.INVOKEDYNAMIC: // invokedynamic instructions point to a constant pool cache entry. - index = decodeConstantPoolCacheIndex(cpi); + index = decodeConstantPoolCacheIndex(cpi) + runtime().getConfig().constantPoolCpCacheIndexTag; index = runtime().getCompilerToVM().constantPoolRemapInstructionOperandFromCache(metaspaceConstantPool, index); break; default: @@ -512,13 +517,7 @@ index = getUncachedKlassRefIndexAt(index); tag = getTagAt(index); assert tag == JVM_CONSTANT.Class || tag == JVM_CONSTANT.UnresolvedClass || tag == JVM_CONSTANT.UnresolvedClassInError : tag; - break; - default: - // nothing - break; - } - - switch (tag) { + // fall-through case Class: case UnresolvedClass: case UnresolvedClassInError: @@ -529,6 +528,12 @@ unsafe.ensureClassInitialized(klass); } break; + case InvokeDynamic: + if (!isInvokedynamicIndex(cpi)) { + throw new IllegalArgumentException("InvokeDynamic entries must be accessed"); + } + runtime().getCompilerToVM().resolveInvokeDynamic(metaspaceConstantPool, cpi); + break; default: // nothing break; diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantReflectionProvider.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantReflectionProvider.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantReflectionProvider.java Wed Apr 23 15:48:38 2014 +0200 @@ -22,13 +22,13 @@ */ package com.oracle.graal.hotspot.meta; -import static com.oracle.graal.graph.UnsafeAccess.*; +import static com.oracle.graal.compiler.common.UnsafeAccess.*; import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*; import java.lang.reflect.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.graph.*; +import com.oracle.graal.compiler.common.*; import com.oracle.graal.hotspot.*; /** @@ -48,15 +48,34 @@ } @Override - public Integer lookupArrayLength(Constant array) { - if (array.getKind() != Kind.Object || array.isNull() || !array.asObject().getClass().isArray()) { + public Integer readArrayLength(Constant array) { + if (array.getKind() != Kind.Object || array.isNull() || !HotSpotObjectConstant.asObject(array).getClass().isArray()) { return null; } - return Array.getLength(array.asObject()); + return Array.getLength(HotSpotObjectConstant.asObject(array)); } @Override - public Constant readUnsafeConstant(Kind kind, Object base, long displacement, boolean compressible) { + public Constant readUnsafeConstant(Kind kind, Constant baseConstant, long initialDisplacement) { + Object base; + long displacement; + if (baseConstant.getKind() == Kind.Object) { + base = HotSpotObjectConstant.asObject(baseConstant); + displacement = initialDisplacement; + if (base == null) { + return null; + } + } else if (baseConstant.getKind().isNumericInteger()) { + long baseLong = baseConstant.asLong(); + if (baseLong == 0L) { + return null; + } + displacement = initialDisplacement + baseLong; + base = null; + } else { + throw GraalInternalError.shouldNotReachHere(); + } + switch (kind) { case Boolean: return Constant.forBoolean(base == null ? unsafe.getByte(displacement) != 0 : unsafe.getBoolean(base, displacement)); @@ -84,15 +103,132 @@ return Constant.forDouble(base == null ? unsafe.getDouble(displacement) : unsafe.getDouble(base, displacement)); case Object: { Object o = null; - if (compressible) { + if (baseConstant.getKind() == Kind.Object) { o = unsafe.getObject(base, displacement); + } else if (baseConstant instanceof HotSpotMetaspaceConstant) { + Object metaspaceObject = HotSpotMetaspaceConstant.getMetaspaceObject(baseConstant); + if (metaspaceObject instanceof HotSpotResolvedObjectType && initialDisplacement == runtime.getConfig().classMirrorOffset) { + o = ((HotSpotResolvedObjectType) metaspaceObject).mirror(); + } else { + throw GraalInternalError.shouldNotReachHere(); + } } else { - o = runtime.getCompilerToVM().readUnsafeUncompressedPointer(base, displacement); + throw GraalInternalError.shouldNotReachHere(); } - return Constant.forObject(o); + return HotSpotObjectConstant.forObject(o); } default: throw GraalInternalError.shouldNotReachHere(); } } + + @Override + public Constant readRawConstant(Kind kind, Constant baseConstant, long initialDisplacement, int bits) { + Object base; + long displacement; + if (baseConstant.getKind() == Kind.Object) { + base = HotSpotObjectConstant.asObject(baseConstant); + displacement = initialDisplacement; + if (base == null) { + return null; + } + } else if (baseConstant.getKind().isNumericInteger()) { + long baseLong = baseConstant.asLong(); + if (baseLong == 0L) { + return null; + } + displacement = initialDisplacement + baseLong; + base = null; + } else { + throw GraalInternalError.shouldNotReachHere(); + } + + long rawValue; + switch (bits) { + case 8: + rawValue = base == null ? unsafe.getByte(displacement) : unsafe.getByte(base, displacement); + break; + case 16: + rawValue = base == null ? unsafe.getShort(displacement) : unsafe.getShort(base, displacement); + break; + case 32: + rawValue = base == null ? unsafe.getInt(displacement) : unsafe.getInt(base, displacement); + break; + case 64: + rawValue = base == null ? unsafe.getLong(displacement) : unsafe.getLong(base, displacement); + break; + default: + throw GraalInternalError.shouldNotReachHere(); + } + + if (base != null && displacement == config().hubOffset) { + if (config().useCompressedClassPointers) { + assert bits == 32 && kind == Kind.Int; + long klassPointer = config().getKlassEncoding().uncompress((int) rawValue); + assert klassPointer == runtime.getCompilerToVM().readUnsafeKlassPointer(base); + return HotSpotMetaspaceConstant.forMetaspaceObject(kind, rawValue, HotSpotResolvedObjectType.fromMetaspaceKlass(klassPointer)); + } else { + assert bits == 64 && kind == Kind.Long; + return HotSpotMetaspaceConstant.forMetaspaceObject(kind, rawValue, HotSpotResolvedObjectType.fromMetaspaceKlass(rawValue)); + } + } else { + switch (kind) { + case Int: + return Constant.forInt((int) rawValue); + case Long: + return Constant.forLong(rawValue); + case Float: + return Constant.forFloat(Float.intBitsToFloat((int) rawValue)); + case Double: + return Constant.forDouble(Double.longBitsToDouble(rawValue)); + default: + throw GraalInternalError.shouldNotReachHere(); + } + } + } + + @Override + public Constant readArrayElement(Constant array, int index) { + if (array.getKind() != Kind.Object || array.isNull()) { + return null; + } + Object a = HotSpotObjectConstant.asObject(array); + + if (index < 0 || index >= Array.getLength(a)) { + return null; + } + + if (a instanceof Object[]) { + return HotSpotObjectConstant.forObject(((Object[]) a)[index]); + } else { + return Constant.forBoxedPrimitive(Array.get(a, index)); + } + } + + @Override + public Constant boxPrimitive(Constant source) { + if (!source.getKind().isPrimitive()) { + return null; + } + return HotSpotObjectConstant.forObject(source.asBoxedPrimitive()); + } + + @Override + public Constant unboxPrimitive(Constant source) { + if (!source.getKind().isObject()) { + return null; + } + return Constant.forBoxedPrimitive(HotSpotObjectConstant.asObject(source)); + } + + @Override + public ResolvedJavaType asJavaType(Constant constant) { + if (constant.getKind() == Kind.Object) { + Object obj = HotSpotObjectConstant.asObject(constant); + if (obj instanceof Class) { + return runtime.getHostProviders().getMetaAccess().lookupJavaType((Class) obj); + } + } + return null; + } } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotDisassemblerProvider.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotDisassemblerProvider.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotDisassemblerProvider.java Wed Apr 23 15:48:38 2014 +0200 @@ -38,7 +38,7 @@ public String disassemble(InstalledCode code) { if (code.isValid()) { - long codeBlob = ((HotSpotInstalledCode) code).getCodeBlob(); + long codeBlob = ((HotSpotInstalledCode) code).getAddress(); return runtime.getCompilerToVM().disassembleCodeBlob(codeBlob); } return null; diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotHostForeignCallsProvider.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotHostForeignCallsProvider.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotHostForeignCallsProvider.java Wed Apr 23 15:48:38 2014 +0200 @@ -30,6 +30,7 @@ import static com.oracle.graal.hotspot.nodes.NewArrayStubCall.*; import static com.oracle.graal.hotspot.nodes.NewInstanceStubCall.*; import static com.oracle.graal.hotspot.nodes.NewMultiArrayStubCall.*; +import static com.oracle.graal.hotspot.nodes.UncommonTrapCallNode.*; import static com.oracle.graal.hotspot.nodes.VMErrorNode.*; import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*; import static com.oracle.graal.hotspot.replacements.MonitorSnippets.*; @@ -37,12 +38,13 @@ import static com.oracle.graal.hotspot.replacements.SystemSubstitutions.*; import static com.oracle.graal.hotspot.replacements.ThreadSubstitutions.*; import static com.oracle.graal.hotspot.replacements.WriteBarrierSnippets.*; +import static com.oracle.graal.hotspot.stubs.DeoptimizationStub.*; import static com.oracle.graal.hotspot.stubs.ExceptionHandlerStub.*; import static com.oracle.graal.hotspot.stubs.NewArrayStub.*; import static com.oracle.graal.hotspot.stubs.NewInstanceStub.*; import static com.oracle.graal.hotspot.stubs.StubUtil.*; import static com.oracle.graal.hotspot.stubs.UnwindExceptionToCallerStub.*; -import static com.oracle.graal.java.GraphBuilderPhase.RuntimeCalls.*; +import static com.oracle.graal.hotspot.meta.HotSpotLoweringProvider.RuntimeCalls.*; import static com.oracle.graal.nodes.java.RegisterFinalizerNode.*; import static com.oracle.graal.replacements.Log.*; import static com.oracle.graal.replacements.MathSubstitutionsX86.*; @@ -64,26 +66,25 @@ super(runtime, metaAccess, codeCache); } - private static void link(Stub stub) { + protected static void link(Stub stub) { stub.getLinkage().setCompiledStub(stub); } public static ForeignCallDescriptor lookupArraycopyDescriptor(Kind kind, boolean aligned, boolean disjoint) { - return (ForeignCallDescriptor) arraycopyDescriptors[aligned ? 1 : 0][disjoint ? 1 : 0].get(kind); + return arraycopyDescriptors[aligned ? 1 : 0][disjoint ? 1 : 0].get(kind); } - private static final EnumMap[][] arraycopyDescriptors = new EnumMap[2][2]; + @SuppressWarnings("unchecked") private static final EnumMap[][] arraycopyDescriptors = new EnumMap[2][2]; static { // Populate the EnumMap instances for (int i = 0; i < arraycopyDescriptors.length; i++) { for (int j = 0; j < arraycopyDescriptors[i].length; j++) { - arraycopyDescriptors[i][j] = new EnumMap(Kind.class); + arraycopyDescriptors[i][j] = new EnumMap<>(Kind.class); } } } - @SuppressWarnings("unchecked") private static ForeignCallDescriptor registerArraycopyDescriptor(Kind kind, boolean aligned, boolean disjoint) { String name = kind + (aligned ? "Aligned" : "") + (disjoint ? "Disjoint" : "") + "Arraycopy"; ForeignCallDescriptor desc = new ForeignCallDescriptor(name, void.class, Word.class, Word.class, Word.class); @@ -102,7 +103,6 @@ public void initialize(HotSpotProviders providers, HotSpotVMConfig c) { TargetDescription target = providers.getCodeCache().getTarget(); - registerForeignCall(UNCOMMON_TRAP, c.uncommonTrapStub, NativeCall, PRESERVES_REGISTERS, LEAF_NOFP, REEXECUTABLE, NO_LOCATIONS); registerForeignCall(DEOPT_HANDLER, c.handleDeoptStub, NativeCall, PRESERVES_REGISTERS, LEAF_NOFP, REEXECUTABLE, NO_LOCATIONS); registerForeignCall(IC_MISS_HANDLER, c.inlineCacheMissStub(), NativeCall, PRESERVES_REGISTERS, LEAF_NOFP, REEXECUTABLE, NO_LOCATIONS); @@ -115,8 +115,11 @@ registerForeignCall(EXCEPTION_HANDLER_FOR_PC, c.exceptionHandlerForPcAddress, NativeCall, DESTROYS_REGISTERS, NOT_LEAF, REEXECUTABLE, ANY_LOCATION); registerForeignCall(EXCEPTION_HANDLER_FOR_RETURN_ADDRESS, c.exceptionHandlerForReturnAddressAddress, NativeCall, DESTROYS_REGISTERS, NOT_LEAF, REEXECUTABLE, ANY_LOCATION); + registerForeignCall(FETCH_UNROLL_INFO, c.deoptimizationFetchUnrollInfo, NativeCall, DESTROYS_REGISTERS, NOT_LEAF, REEXECUTABLE, ANY_LOCATION); registerForeignCall(NEW_ARRAY_C, c.newArrayAddress, NativeCall, DESTROYS_REGISTERS, NOT_LEAF, REEXECUTABLE, ANY_LOCATION); registerForeignCall(NEW_INSTANCE_C, c.newInstanceAddress, NativeCall, DESTROYS_REGISTERS, NOT_LEAF, REEXECUTABLE, ANY_LOCATION); + registerForeignCall(UNCOMMON_TRAP, c.deoptimizationUncommonTrap, NativeCall, DESTROYS_REGISTERS, NOT_LEAF, NOT_REEXECUTABLE, ANY_LOCATION); + registerForeignCall(UNPACK_FRAMES, c.deoptimizationUnpackFrames, NativeCall, DESTROYS_REGISTERS, LEAF, NOT_REEXECUTABLE, ANY_LOCATION); registerForeignCall(VM_MESSAGE_C, c.vmMessageAddress, NativeCall, DESTROYS_REGISTERS, NOT_LEAF, REEXECUTABLE, NO_LOCATIONS); link(new NewInstanceStub(providers, target, registerStubCall(NEW_INSTANCE, REEXECUTABLE, NOT_LEAF, ANY_LOCATION))); diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotInstalledCode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotInstalledCode.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotInstalledCode.java Wed Apr 23 15:48:38 2014 +0200 @@ -22,45 +22,32 @@ */ package com.oracle.graal.hotspot.meta; -import static com.oracle.graal.graph.UnsafeAccess.*; +import static com.oracle.graal.compiler.common.UnsafeAccess.*; import sun.misc.*; import com.oracle.graal.api.code.*; -import com.oracle.graal.hotspot.*; + +import edu.umd.cs.findbugs.annotations.*; /** * Implementation of {@link InstalledCode} for HotSpot. */ -public abstract class HotSpotInstalledCode extends CompilerObject implements InstalledCode { - - private static final long serialVersionUID = 156632908220561612L; - - /** - * Raw address of this code blob. - */ - private long codeBlob; +public abstract class HotSpotInstalledCode extends InstalledCode { /** * Total size of the code blob. */ - private int size; + @SuppressFBWarnings(value = "UWF_UNWRITTEN_FIELD", justification = "field is set by the native part") private int size; /** * Start address of the code. */ - private long codeStart; + @SuppressFBWarnings(value = "UWF_UNWRITTEN_FIELD", justification = "field is set by the native part") private long codeStart; /** * Size of the code. */ - private int codeSize; - - /** - * @return the address of this code blob - */ - public long getCodeBlob() { - return codeBlob; - } + @SuppressFBWarnings(value = "UWF_UNWRITTEN_FIELD", justification = "field is set by the native part") private int codeSize; /** * @return the total size of this code blob @@ -77,13 +64,14 @@ return null; } byte[] blob = new byte[size]; - unsafe.copyMemory(null, codeBlob, blob, Unsafe.ARRAY_BYTE_BASE_OFFSET, size); + unsafe.copyMemory(null, getAddress(), blob, Unsafe.ARRAY_BYTE_BASE_OFFSET, size); return blob; } @Override public abstract String toString(); + @Override public long getStart() { return codeStart; } @@ -92,6 +80,7 @@ return codeSize; } + @Override public byte[] getCode() { if (!isValid()) { return null; diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotLoweringProvider.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotLoweringProvider.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotLoweringProvider.java Wed Apr 23 15:48:38 2014 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,18 +26,20 @@ import static com.oracle.graal.api.meta.DeoptimizationAction.*; import static com.oracle.graal.api.meta.DeoptimizationReason.*; import static com.oracle.graal.api.meta.LocationIdentity.*; +import static com.oracle.graal.compiler.common.GraalOptions.*; import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; import static com.oracle.graal.hotspot.meta.HotSpotForeignCallsProviderImpl.*; import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*; import static com.oracle.graal.hotspot.replacements.NewObjectSnippets.*; import static com.oracle.graal.nodes.java.ArrayLengthNode.*; -import static com.oracle.graal.phases.GraalOptions.*; import java.util.*; import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.*; +import com.oracle.graal.compiler.common.*; +import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.graph.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.debug.*; @@ -90,7 +92,7 @@ newObjectSnippets = new NewObjectSnippets.Templates(providers, target); monitorSnippets = new MonitorSnippets.Templates(providers, target, config.useFastLocking); writeBarrierSnippets = new WriteBarrierSnippets.Templates(providers, target, config.useCompressedOops ? config.getOopEncoding() : null); - boxingSnippets = new BoxingSnippets.Templates(providers, target); + boxingSnippets = new BoxingSnippets.Templates(providers, providers.getSnippetReflection(), target); exceptionObjectSnippets = new LoadExceptionObjectSnippets.Templates(providers, target); unsafeLoadSnippets = new UnsafeLoadSnippets.Templates(providers, target); providers.getReplacements().registerSnippetTemplateCache(new UnsafeArrayCopySnippets.Templates(providers, target)); @@ -110,6 +112,8 @@ lowerStoreFieldNode((StoreFieldNode) n, tool); } else if (n instanceof CompareAndSwapNode) { lowerCompareAndSwapNode((CompareAndSwapNode) n); + } else if (n instanceof AtomicReadAndWriteNode) { + lowerAtomicReadAndWriteNode((AtomicReadAndWriteNode) n); } else if (n instanceof LoadIndexedNode) { lowerLoadIndexedNode((LoadIndexedNode) n, tool); } else if (n instanceof StoreIndexedNode) { @@ -134,8 +138,8 @@ lowerOSRStartNode((OSRStartNode) n); } else if (n instanceof DynamicCounterNode) { lowerDynamicCounterNode((DynamicCounterNode) n); - } else if (n instanceof DeferredForeignCallNode) { - lowerDeferredForeignCallNode((DeferredForeignCallNode) n); + } else if (n instanceof BytecodeExceptionNode) { + lowerBytecodeExceptionNode((BytecodeExceptionNode) n); } else if (n instanceof CheckCastDynamicNode) { checkcastDynamicSnippets.lower((CheckCastDynamicNode) n, tool); } else if (n instanceof InstanceOfNode) { @@ -219,7 +223,7 @@ NodeInputList parameters = callTarget.arguments(); ValueNode receiver = parameters.size() <= 0 ? null : parameters.get(0); GuardingNode receiverNullCheck = null; - if (!callTarget.isStatic() && receiver.stamp() instanceof ObjectStamp && !ObjectStamp.isObjectNonNull(receiver)) { + if (!callTarget.isStatic() && receiver.stamp() instanceof ObjectStamp && !StampTool.isObjectNonNull(receiver)) { receiverNullCheck = createNullCheck(receiver, invoke.asNode(), tool); invoke.setGuard(receiverNullCheck); } @@ -234,7 +238,7 @@ int vtableEntryOffset = hsMethod.vtableEntryOffset(); assert vtableEntryOffset > 0; Kind wordKind = runtime.getTarget().wordKind; - FloatingReadNode hub = createReadHub(graph, wordKind, receiver, receiverNullCheck); + ValueNode hub = createReadHub(graph, wordKind, receiver, receiverNullCheck); ReadNode metaspaceMethod = createReadVirtualMethod(graph, wordKind, hub, hsMethod); // We use LocationNode.ANY_LOCATION for the reads that access the @@ -307,7 +311,7 @@ private void lowerLoadFieldNode(LoadFieldNode loadField, LoweringTool tool) { StructuredGraph graph = loadField.graph(); HotSpotResolvedJavaField field = (HotSpotResolvedJavaField) loadField.field(); - ValueNode object = loadField.isStatic() ? ConstantNode.forObject(field.getDeclaringClass().mirror(), metaAccess, graph) : loadField.object(); + ValueNode object = loadField.isStatic() ? ConstantNode.forConstant(HotSpotObjectConstant.forObject(field.getDeclaringClass().mirror()), metaAccess, graph) : loadField.object(); assert loadField.getKind() != Kind.Illegal; BarrierType barrierType = getFieldLoadBarrierType(field); @@ -351,7 +355,7 @@ private void lowerStoreFieldNode(StoreFieldNode storeField, LoweringTool tool) { StructuredGraph graph = storeField.graph(); HotSpotResolvedJavaField field = (HotSpotResolvedJavaField) storeField.field(); - ValueNode object = storeField.isStatic() ? ConstantNode.forObject(field.getDeclaringClass().mirror(), metaAccess, graph) : storeField.object(); + ValueNode object = storeField.isStatic() ? ConstantNode.forConstant(HotSpotObjectConstant.forObject(field.getDeclaringClass().mirror()), metaAccess, graph) : storeField.object(); BarrierType barrierType = getFieldStoreBarrierType(storeField); ValueNode value = implicitStoreConvert(graph, storeField.field().getKind(), storeField.value()); @@ -370,16 +374,35 @@ } } - private static void lowerCompareAndSwapNode(CompareAndSwapNode cas) { - // Separate out GC barrier semantics + private void lowerCompareAndSwapNode(CompareAndSwapNode cas) { StructuredGraph graph = cas.graph(); - LocationNode location = IndexedLocationNode.create(cas.getLocationIdentity(), cas.expected().getKind(), cas.displacement(), cas.offset(), graph, 1); - LoweredCompareAndSwapNode atomicNode = graph.add(new LoweredCompareAndSwapNode(cas.object(), location, cas.expected(), cas.newValue(), getCompareAndSwapBarrier(cas), - cas.expected().getKind() == Kind.Object)); + Kind valueKind = cas.getValueKind(); + LocationNode location = IndexedLocationNode.create(cas.getLocationIdentity(), valueKind, cas.displacement(), cas.offset(), graph, 1); + + ValueNode expectedValue = implicitStoreConvert(graph, valueKind, cas.expected(), true); + ValueNode newValue = implicitStoreConvert(graph, valueKind, cas.newValue(), true); + + LoweredCompareAndSwapNode atomicNode = graph.add(new LoweredCompareAndSwapNode(cas.object(), location, expectedValue, newValue, getCompareAndSwapBarrierType(cas), false)); atomicNode.setStateAfter(cas.stateAfter()); graph.replaceFixedWithFixed(cas, atomicNode); } + private void lowerAtomicReadAndWriteNode(AtomicReadAndWriteNode n) { + StructuredGraph graph = n.graph(); + Kind valueKind = n.getValueKind(); + LocationNode location = IndexedLocationNode.create(n.getLocationIdentity(), valueKind, 0, n.offset(), graph, 1); + + ValueNode newValue = implicitStoreConvert(graph, valueKind, n.newValue()); + + LoweredAtomicReadAndWriteNode memoryRead = graph.add(new LoweredAtomicReadAndWriteNode(n.object(), location, newValue, getAtomicReadAndWriteBarrierType(n), false)); + memoryRead.setStateAfter(n.stateAfter()); + + ValueNode readValue = implicitLoadConvert(graph, valueKind, memoryRead); + + n.replaceAtUsages(readValue); + graph.replaceFixedWithFixed(n, memoryRead); + } + private void lowerLoadIndexedNode(LoadIndexedNode loadIndexed, LoweringTool tool) { StructuredGraph graph = loadIndexed.graph(); Kind elementKind = loadIndexed.elementKind(); @@ -406,10 +429,10 @@ CheckCastNode checkcastNode = null; CheckCastDynamicNode checkcastDynamicNode = null; - if (elementKind == Kind.Object && !ObjectStamp.isObjectAlwaysNull(value)) { + if (elementKind == Kind.Object && !StampTool.isObjectAlwaysNull(value)) { // Store check! - ResolvedJavaType arrayType = ObjectStamp.typeOrNull(array); - if (arrayType != null && ObjectStamp.isExactType(array)) { + ResolvedJavaType arrayType = StampTool.typeOrNull(array); + if (arrayType != null && StampTool.isExactType(array)) { ResolvedJavaType elementType = arrayType.getComponentType(); if (!MetaUtil.isJavaLangObject(elementType)) { checkcastNode = graph.add(new CheckCastNode(elementType, value, null, true)); @@ -418,7 +441,7 @@ } } else { Kind wordKind = runtime.getTarget().wordKind; - FloatingReadNode arrayClass = createReadHub(graph, wordKind, array, boundsCheck); + ValueNode arrayClass = createReadHub(graph, wordKind, array, boundsCheck); LocationNode location = ConstantLocationNode.create(FINAL_LOCATION, wordKind, runtime.getConfig().arrayClassElementOffset, graph); /* * Anchor the read of the element klass to the cfg, because it is only valid when @@ -471,7 +494,7 @@ ReadNode memoryRead = createUnsafeRead(graph, load, null); // An unsafe read must not float outside its block otherwise // it may float above an explicit null check on its object. - memoryRead.setGuard(AbstractBeginNode.prevBegin(load)); + memoryRead.setGuard(BeginNode.prevBegin(load)); graph.replaceFixedWithFixed(load, memoryRead); } } @@ -524,7 +547,7 @@ assert loadHub.getKind() == wordKind; ValueNode object = loadHub.object(); GuardingNode guard = loadHub.getGuard(); - FloatingReadNode hub = createReadHub(graph, wordKind, object, guard); + ValueNode hub = createReadHub(graph, wordKind, object, guard); graph.replaceFloating(loadHub, hub); } } @@ -661,11 +684,51 @@ } } - private void lowerDeferredForeignCallNode(DeferredForeignCallNode deferred) { - StructuredGraph graph = deferred.graph(); + static final class Exceptions { + protected static final ArrayIndexOutOfBoundsException cachedArrayIndexOutOfBoundsException; + protected static final NullPointerException cachedNullPointerException; + + static { + cachedArrayIndexOutOfBoundsException = new ArrayIndexOutOfBoundsException(); + cachedArrayIndexOutOfBoundsException.setStackTrace(new StackTraceElement[0]); + cachedNullPointerException = new NullPointerException(); + cachedNullPointerException.setStackTrace(new StackTraceElement[0]); + } + } + + public static final class RuntimeCalls { + public static final ForeignCallDescriptor CREATE_NULL_POINTER_EXCEPTION = new ForeignCallDescriptor("createNullPointerException", NullPointerException.class); + public static final ForeignCallDescriptor CREATE_OUT_OF_BOUNDS_EXCEPTION = new ForeignCallDescriptor("createOutOfBoundsException", ArrayIndexOutOfBoundsException.class, int.class); + } + + private void lowerBytecodeExceptionNode(BytecodeExceptionNode node) { + StructuredGraph graph = node.graph(); if (graph.getGuardsStage() == StructuredGraph.GuardsStage.FLOATING_GUARDS) { - ForeignCallNode foreignCallNode = graph.add(new ForeignCallNode(foreignCalls, deferred.getDescriptor(), deferred.stamp(), deferred.getArguments())); - graph.replaceFixedWithFixed(deferred, foreignCallNode); + if (OmitHotExceptionStacktrace.getValue()) { + Throwable exception; + if (node.getExceptionClass() == NullPointerException.class) { + exception = Exceptions.cachedNullPointerException; + } else if (node.getExceptionClass() == ArrayIndexOutOfBoundsException.class) { + exception = Exceptions.cachedArrayIndexOutOfBoundsException; + } else { + throw GraalInternalError.shouldNotReachHere(); + } + FloatingNode exceptionNode = ConstantNode.forConstant(HotSpotObjectConstant.forObject(exception), metaAccess, graph); + graph.replaceFixedWithFloating(node, exceptionNode); + + } else { + ForeignCallDescriptor descriptor; + if (node.getExceptionClass() == NullPointerException.class) { + descriptor = RuntimeCalls.CREATE_NULL_POINTER_EXCEPTION; + } else if (node.getExceptionClass() == ArrayIndexOutOfBoundsException.class) { + descriptor = RuntimeCalls.CREATE_OUT_OF_BOUNDS_EXCEPTION; + } else { + throw GraalInternalError.shouldNotReachHere(); + } + + ForeignCallNode foreignCallNode = graph.add(new ForeignCallNode(foreignCalls, descriptor, node.stamp(), node.getArguments())); + graph.replaceFixedWithFixed(node, foreignCallNode); + } } } @@ -703,6 +766,14 @@ long displacement = 0; int indexScaling = 1; + boolean signExtend = false; + if (offset instanceof SignExtendNode) { + SignExtendNode extend = (SignExtendNode) offset; + if (extend.getResultBits() == 64) { + signExtend = true; + offset = extend.getInput(); + } + } if (offset instanceof IntegerAddNode) { IntegerAddNode integerAddNode = (IntegerAddNode) offset; if (integerAddNode.y() instanceof ConstantNode) { @@ -727,14 +798,17 @@ } } } - + if (signExtend) { + // If we were using sign extended values before restore the sign extension. + offset = offset.graph().addOrUnique(new SignExtendNode(offset, 64)); + } return IndexedLocationNode.create(locationIdentity, accessKind, displacement, offset, offset.graph(), indexScaling); } private static boolean addReadBarrier(UnsafeLoadNode load) { if (useG1GC() && load.graph().getGuardsStage() == StructuredGraph.GuardsStage.FIXED_DEOPTS && load.object().getKind() == Kind.Object && load.accessKind() == Kind.Object && - !ObjectStamp.isObjectAlwaysNull(load.object())) { - ResolvedJavaType type = ObjectStamp.typeOrNull(load.object()); + !StampTool.isObjectAlwaysNull(load.object())) { + ResolvedJavaType type = StampTool.typeOrNull(load.object()); if (type != null && !type.isArray()) { return true; } @@ -755,18 +829,37 @@ return metaspaceMethod; } - private FloatingReadNode createReadHub(StructuredGraph graph, Kind wordKind, ValueNode object, GuardingNode guard) { + private ValueNode createReadHub(StructuredGraph graph, Kind wordKind, ValueNode object, GuardingNode guard) { HotSpotVMConfig config = runtime.getConfig(); LocationNode location = ConstantLocationNode.create(FINAL_LOCATION, wordKind, config.hubOffset, graph); assert !object.isConstant() || object.asConstant().isNull(); - return graph.unique(new FloatingReadNode(object, location, null, StampFactory.forKind(wordKind), guard, BarrierType.NONE, config.useCompressedClassPointers)); + + Stamp hubStamp; + if (config.useCompressedClassPointers) { + hubStamp = StampFactory.forInteger(32); + } else { + hubStamp = StampFactory.forKind(wordKind); + } + + FloatingReadNode memoryRead = graph.unique(new FloatingReadNode(object, location, null, hubStamp, guard, BarrierType.NONE, false)); + if (config.useCompressedClassPointers) { + return CompressionNode.uncompress(memoryRead, config.getKlassEncoding()); + } else { + return memoryRead; + } } private WriteNode createWriteHub(StructuredGraph graph, Kind wordKind, ValueNode object, ValueNode value) { HotSpotVMConfig config = runtime.getConfig(); LocationNode location = ConstantLocationNode.create(HUB_LOCATION, wordKind, config.hubOffset, graph); assert !object.isConstant() || object.asConstant().isNull(); - return graph.add(new WriteNode(object, value, location, BarrierType.NONE, config.useCompressedClassPointers)); + + ValueNode writeValue = value; + if (config.useCompressedClassPointers) { + writeValue = CompressionNode.compress(value, config.getKlassEncoding()); + } + + return graph.add(new WriteNode(object, writeValue, location, BarrierType.NONE, false)); } private static BarrierType getFieldLoadBarrierType(HotSpotResolvedJavaField loadField) { @@ -778,45 +871,53 @@ } private static BarrierType getFieldStoreBarrierType(StoreFieldNode storeField) { - BarrierType barrierType = BarrierType.NONE; if (storeField.field().getKind() == Kind.Object) { - barrierType = BarrierType.IMPRECISE; + return BarrierType.IMPRECISE; } - return barrierType; + return BarrierType.NONE; } private static BarrierType getArrayStoreBarrierType(StoreIndexedNode store) { - BarrierType barrierType = BarrierType.NONE; if (store.elementKind() == Kind.Object) { - barrierType = BarrierType.PRECISE; + return BarrierType.PRECISE; } - return barrierType; + return BarrierType.NONE; } private static BarrierType getUnsafeStoreBarrierType(UnsafeStoreNode store) { - BarrierType barrierType = BarrierType.NONE; if (store.value().getKind() == Kind.Object) { - ResolvedJavaType type = ObjectStamp.typeOrNull(store.object()); + ResolvedJavaType type = StampTool.typeOrNull(store.object()); if (type != null && !type.isArray()) { - barrierType = BarrierType.IMPRECISE; + return BarrierType.IMPRECISE; } else { - barrierType = BarrierType.PRECISE; + return BarrierType.PRECISE; } } - return barrierType; + return BarrierType.NONE; } - private static BarrierType getCompareAndSwapBarrier(CompareAndSwapNode cas) { - BarrierType barrierType = BarrierType.NONE; + private static BarrierType getCompareAndSwapBarrierType(CompareAndSwapNode cas) { if (cas.expected().getKind() == Kind.Object) { - ResolvedJavaType type = ObjectStamp.typeOrNull(cas.object()); + ResolvedJavaType type = StampTool.typeOrNull(cas.object()); if (type != null && !type.isArray()) { - barrierType = BarrierType.IMPRECISE; + return BarrierType.IMPRECISE; } else { - barrierType = BarrierType.PRECISE; + return BarrierType.PRECISE; } } - return barrierType; + return BarrierType.NONE; + } + + private static BarrierType getAtomicReadAndWriteBarrierType(AtomicReadAndWriteNode n) { + if (n.newValue().getKind() == Kind.Object) { + ResolvedJavaType type = StampTool.typeOrNull(n.object()); + if (type != null && !type.isArray()) { + return BarrierType.IMPRECISE; + } else { + return BarrierType.PRECISE; + } + } + return BarrierType.NONE; } protected static ConstantLocationNode createFieldLocation(StructuredGraph graph, HotSpotResolvedJavaField field, boolean initialization) { @@ -902,7 +1003,7 @@ } private static GuardingNode createNullCheck(ValueNode object, FixedNode before, LoweringTool tool) { - if (ObjectStamp.isObjectNonNull(object)) { + if (StampTool.isObjectNonNull(object)) { return null; } return tool.createGuard(before, before.graph().unique(new IsNullNode(object)), DeoptimizationReason.NullCheckException, DeoptimizationAction.InvalidateReprofile, true); diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMetaAccessProvider.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMetaAccessProvider.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMetaAccessProvider.java Wed Apr 23 15:48:38 2014 +0200 @@ -22,13 +22,13 @@ */ package com.oracle.graal.hotspot.meta; -import static com.oracle.graal.graph.UnsafeAccess.*; +import static com.oracle.graal.compiler.common.UnsafeAccess.*; import java.lang.reflect.*; import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.graph.*; +import com.oracle.graal.compiler.common.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.replacements.*; @@ -54,7 +54,7 @@ if (constant.getKind() != Kind.Object || constant.isNull()) { return null; } - Object o = constant.asObject(); + Object o = HotSpotObjectConstant.asObject(constant); return HotSpotResolvedObjectType.fromClass(o.getClass()); } @@ -93,7 +93,7 @@ } } - public ResolvedJavaMethod lookupJavaConstructor(Constructor reflectionConstructor) { + public ResolvedJavaMethod lookupJavaConstructor(Constructor reflectionConstructor) { try { Class holder = reflectionConstructor.getDeclaringClass(); final int slot = reflectionConstructorSlot.getInt(reflectionConstructor); @@ -295,7 +295,7 @@ } else { if (lookupJavaType.isArray()) { // TODO(tw): Add compressed pointer support. - int length = Array.getLength(constant.asObject()); + int length = Array.getLength(HotSpotObjectConstant.asObject(constant)); ResolvedJavaType elementType = lookupJavaType.getComponentType(); Kind elementKind = elementType.getKind(); final int headerSize = HotSpotGraalRuntime.getArrayBaseOffset(elementKind); diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMetaspaceConstant.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMetaspaceConstant.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2014, 2014, 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.meta; + +import java.util.*; + +import com.oracle.graal.api.meta.*; + +public final class HotSpotMetaspaceConstant extends PrimitiveConstant { + + private static final long serialVersionUID = 1003463314013122983L; + + public static Constant forMetaspaceObject(Kind kind, long primitive, Object metaspaceObject) { + return new HotSpotMetaspaceConstant(kind, primitive, metaspaceObject); + } + + public static Object getMetaspaceObject(Constant constant) { + return ((HotSpotMetaspaceConstant) constant).metaspaceObject; + } + + private final Object metaspaceObject; + + private HotSpotMetaspaceConstant(Kind kind, long primitive, Object metaspaceObject) { + super(kind, primitive); + this.metaspaceObject = metaspaceObject; + } + + @Override + public int hashCode() { + return super.hashCode() ^ System.identityHashCode(metaspaceObject); + } + + @Override + public boolean equals(Object o) { + return o == this || (o instanceof HotSpotMetaspaceConstant && super.equals(o) && Objects.equals(metaspaceObject, ((HotSpotMetaspaceConstant) o).metaspaceObject)); + } + + @Override + public String toString() { + return super.toString() + "{" + metaspaceObject + "}"; + } +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodData.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodData.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodData.java Wed Apr 23 15:48:38 2014 +0200 @@ -22,7 +22,7 @@ */ package com.oracle.graal.hotspot.meta; -import static com.oracle.graal.graph.UnsafeAccess.*; +import static com.oracle.graal.compiler.common.UnsafeAccess.*; import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; import static java.lang.String.*; diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodDataAccessor.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodDataAccessor.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodDataAccessor.java Wed Apr 23 15:48:38 2014 +0200 @@ -26,7 +26,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.api.meta.ProfilingInfo.TriState; -import com.oracle.graal.graph.*; +import com.oracle.graal.compiler.common.*; import com.oracle.graal.hotspot.*; /** diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotNmethod.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotNmethod.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotNmethod.java Wed Apr 23 15:48:38 2014 +0200 @@ -24,8 +24,6 @@ import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; -import java.lang.reflect.*; - import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; @@ -40,8 +38,6 @@ */ public final class HotSpotNmethod extends HotSpotInstalledCode { - private static final long serialVersionUID = -1784683588947054103L; - /** * This (indirect) Method* reference is safe since class redefinition preserves all methods * associated with nmethods in the code cache. @@ -71,31 +67,25 @@ return isExternal; } - @Override public ResolvedJavaMethod getMethod() { return method; } @Override - public boolean isValid() { - return getCodeBlob() != 0; - } - - @Override public void invalidate() { runtime().getCompilerToVM().invalidateInstalledCode(this); } @Override public String toString() { - return String.format("InstalledNmethod[method=%s, codeBlob=0x%x, isDefault=%b, name=%s]", method, getCodeBlob(), isDefault, name); + return String.format("InstalledNmethod[method=%s, codeBlob=0x%x, isDefault=%b, name=%s]", method, getAddress(), isDefault, name); } protected boolean checkThreeObjectArgs() { - assert method.getSignature().getParameterCount(!Modifier.isStatic(method.getModifiers())) == 3; + assert method.getSignature().getParameterCount(!method.isStatic()) == 3; assert method.getSignature().getParameterKind(0) == Kind.Object; assert method.getSignature().getParameterKind(1) == Kind.Object; - assert !Modifier.isStatic(method.getModifiers()) || method.getSignature().getParameterKind(2) == Kind.Object; + assert !method.isStatic() || method.getSignature().getParameterKind(2) == Kind.Object; return true; } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotObjectConstant.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotObjectConstant.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2009, 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.meta; + +import com.oracle.graal.api.meta.*; + +/** + * Represents a constant non-{@code null} object reference, within the compiler and across the + * compiler/runtime interface. + */ +public final class HotSpotObjectConstant extends Constant { + + private static final long serialVersionUID = 3592151693708093496L; + + public static Constant forObject(Object object) { + if (object == null) { + return Constant.NULL_OBJECT; + } else { + return new HotSpotObjectConstant(object); + } + } + + public static Constant forBoxedValue(Kind kind, Object value) { + if (kind == Kind.Object) { + return HotSpotObjectConstant.forObject(value); + } else { + return Constant.forBoxedPrimitive(value); + } + } + + public static Object asObject(Constant constant) { + if (constant.isNull()) { + return null; + } else { + return ((HotSpotObjectConstant) constant).object; + } + } + + public static Object asBoxedValue(Constant constant) { + if (constant.isNull()) { + return null; + } else if (constant.getKind() == Kind.Object) { + return ((HotSpotObjectConstant) constant).object; + } else { + return constant.asBoxedPrimitive(); + } + } + + private final Object object; + + private HotSpotObjectConstant(Object object) { + super(Kind.Object); + this.object = object; + assert object != null; + } + + @Override + public boolean isNull() { + return false; + } + + @Override + public boolean isDefaultForKind() { + return false; + } + + @Override + public Object asBoxedPrimitive() { + throw new IllegalArgumentException(); + } + + @Override + public int asInt() { + throw new IllegalArgumentException(); + } + + @Override + public boolean asBoolean() { + throw new IllegalArgumentException(); + } + + @Override + public long asLong() { + throw new IllegalArgumentException(); + } + + @Override + public float asFloat() { + throw new IllegalArgumentException(); + } + + @Override + public double asDouble() { + throw new IllegalArgumentException(); + } + + @Override + public int hashCode() { + return System.identityHashCode(object); + } + + @Override + public boolean equals(Object o) { + return o == this || (o instanceof HotSpotObjectConstant && super.equals(o) && object == ((HotSpotObjectConstant) o).object); + } + + @Override + public String toValueString() { + if (object instanceof String) { + return (String) object; + } else { + return Kind.Object.format(object); + } + } + + @Override + public String toString() { + return getKind().getJavaName() + "[" + Kind.Object.format(object) + "]"; + } +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotProviders.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotProviders.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotProviders.java Wed Apr 23 15:48:38 2014 +0200 @@ -23,6 +23,7 @@ package com.oracle.graal.hotspot.meta; import com.oracle.graal.api.meta.*; +import com.oracle.graal.api.replacements.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.phases.tiers.*; import com.oracle.graal.phases.util.*; @@ -36,13 +37,16 @@ private final HotSpotDisassemblerProvider disassembler; private final SuitesProvider suites; private final HotSpotRegistersProvider registers; + private final SnippetReflectionProvider snippetReflection; public HotSpotProviders(HotSpotMetaAccessProvider metaAccess, HotSpotCodeCacheProvider codeCache, ConstantReflectionProvider constantReflection, HotSpotForeignCallsProvider foreignCalls, - LoweringProvider lowerer, Replacements replacements, HotSpotDisassemblerProvider disassembler, SuitesProvider suites, HotSpotRegistersProvider registers) { + LoweringProvider lowerer, Replacements replacements, HotSpotDisassemblerProvider disassembler, SuitesProvider suites, HotSpotRegistersProvider registers, + SnippetReflectionProvider snippetReflection) { super(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, replacements); this.disassembler = disassembler; this.suites = suites; this.registers = registers; + this.snippetReflection = snippetReflection; } @Override @@ -72,4 +76,7 @@ return registers; } + public SnippetReflectionProvider getSnippetReflection() { + return snippetReflection; + } } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java Wed Apr 23 15:48:38 2014 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,17 +23,16 @@ package com.oracle.graal.hotspot.meta; import static com.oracle.graal.api.meta.MetaUtil.*; +import static com.oracle.graal.compiler.common.GraalOptions.*; import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; import static com.oracle.graal.hotspot.meta.HotSpotResolvedObjectType.*; -import static com.oracle.graal.phases.GraalOptions.*; -import static java.lang.reflect.Modifier.*; import java.lang.annotation.*; import java.lang.reflect.*; import java.util.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.graph.*; +import com.oracle.graal.compiler.common.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.options.*; import com.oracle.graal.replacements.*; @@ -200,11 +199,10 @@ assert !ImmutableCode.getValue() || isCalledForSnippets() : receiver; if (receiver == null) { - assert isStatic(modifiers); - if (Modifier.isFinal(getModifiers())) { + assert isStatic(); + if (isFinal()) { if (holder.isInitialized() && !holder.getName().equals(SystemClassName) && isEmbeddable()) { return readValue(receiver); - } } } else { @@ -212,14 +210,14 @@ * for non-static final fields, we must assume that they are only initialized if they * have a non-default value. */ - assert !isStatic(modifiers); - Object object = receiver.asObject(); + assert !isStatic(); + Object object = HotSpotObjectConstant.asObject(receiver); // Canonicalization may attempt to process an unsafe read before // processing a guard (e.g. a null check or a type check) for this read // so we need to check the object being read if (object != null && isInObject(object)) { - if (Modifier.isFinal(getModifiers())) { + if (isFinal()) { Constant value = readValue(receiver); if (assumeNonStaticFinalFieldsAsFinal(object.getClass()) || !value.isDefaultForKind()) { return value; @@ -234,7 +232,7 @@ if (StableOptionValue.class.isAssignableFrom(clazz)) { assert getName().equals("value") : "Unexpected field in " + StableOptionValue.class.getName() + " hierarchy:" + this; StableOptionValue option = (StableOptionValue) object; - return Constant.forObject(option.getValue()); + return HotSpotObjectConstant.forObject(option.getValue()); } } } @@ -244,12 +242,12 @@ /** * Determines if a given object contains this field. - * + * * @return true iff this is a non-static field and its declaring class is assignable from * {@code object}'s class */ public boolean isInObject(Object object) { - if (isStatic(modifiers)) { + if (isStatic()) { return false; } return getDeclaringClass().isAssignableFrom(HotSpotResolvedObjectType.fromClass(object.getClass())); @@ -258,16 +256,15 @@ @Override public Constant readValue(Constant receiver) { if (receiver == null) { - assert isStatic(modifiers); + assert isStatic(); if (holder.isInitialized()) { - return runtime().getHostProviders().getConstantReflection().readUnsafeConstant(getKind(), holder.mirror(), offset, getKind() == Kind.Object); + return runtime().getHostProviders().getConstantReflection().readUnsafeConstant(getKind(), HotSpotObjectConstant.forObject(holder.mirror()), offset); } return null; } else { - assert !isStatic(modifiers); - Object object = receiver.asObject(); - assert object != null && isInObject(object); - return runtime().getHostProviders().getConstantReflection().readUnsafeConstant(getKind(), object, offset, getKind() == Kind.Object); + assert !isStatic(); + assert receiver.isNonNull() && isInObject(HotSpotObjectConstant.asObject(receiver)); + return runtime().getHostProviders().getConstantReflection().readUnsafeConstant(getKind(), receiver, offset); } } @@ -332,7 +329,7 @@ /** * Checks if this field has the {@link Stable} annotation. - * + * * @return true if field has {@link Stable} annotation, false otherwise */ public boolean isStable() { diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java Wed Apr 23 15:48:38 2014 +0200 @@ -22,18 +22,19 @@ */ package com.oracle.graal.hotspot.meta; -import static com.oracle.graal.graph.UnsafeAccess.*; +import static com.oracle.graal.compiler.common.GraalOptions.*; +import static com.oracle.graal.compiler.common.UnsafeAccess.*; import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; -import static com.oracle.graal.phases.GraalOptions.*; import java.lang.annotation.*; import java.lang.reflect.*; +import java.util.*; import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.api.meta.ProfilingInfo.TriState; +import com.oracle.graal.compiler.common.*; import com.oracle.graal.debug.*; -import com.oracle.graal.graph.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.debug.*; import com.oracle.graal.nodes.*; @@ -55,11 +56,10 @@ private final HotSpotSignature signature; private HotSpotMethodData methodData; private byte[] code; - private SpeculationLog speculationLog; /** * Gets the holder of a HotSpot metaspace method native object. - * + * * @param metaspaceMethod a metaspace Method object * @return the {@link ResolvedJavaType} corresponding to the holder of the * {@code metaspaceMethod} @@ -74,7 +74,7 @@ /** * Gets the {@link ResolvedJavaMethod} for a HotSpot metaspace method native object. - * + * * @param metaspaceMethod a metaspace Method object * @return the {@link ResolvedJavaMethod} corresponding to {@code metaspaceMethod} */ @@ -110,7 +110,7 @@ /** * Returns a pointer to this method's constant method data structure ( * {@code Method::_constMethod}). - * + * * @return pointer to this method's ConstMethod */ private long getConstMethod() { @@ -134,7 +134,7 @@ /** * Returns this method's flags ({@code Method::_flags}). - * + * * @return flags of this method */ private int getFlags() { @@ -143,7 +143,7 @@ /** * Returns this method's constant method flags ({@code ConstMethod::_flags}). - * + * * @return flags of this method's ConstMethod */ private int getConstMethodFlags() { @@ -159,7 +159,11 @@ * Gets the address of the C++ Method object for this method. */ public Constant getMetaspaceMethodConstant() { - return Constant.forIntegerKind(getHostWordKind(), metaspaceMethod, this); + return HotSpotMetaspaceConstant.forMetaspaceObject(getHostWordKind(), metaspaceMethod, this); + } + + public long getMetaspaceMethod() { + return metaspaceMethod; } @Override @@ -182,8 +186,7 @@ @Override public boolean canBeStaticallyBound() { - int modifiers = getModifiers(); - return (Modifier.isFinal(modifiers) || Modifier.isPrivate(modifiers) || Modifier.isStatic(modifiers)) && !Modifier.isAbstract(modifiers); + return (isFinal() || isPrivate() || isStatic() || holder.isFinal()) && !isAbstract(); } @Override @@ -248,7 +251,7 @@ /** * Returns true if this method has a {@code CallerSensitive} annotation. - * + * * @return true if CallerSensitive annotation present, false otherwise */ public boolean isCallerSensitive() { @@ -257,7 +260,7 @@ /** * Returns true if this method has a {@code ForceInline} annotation. - * + * * @return true if ForceInline annotation present, false otherwise */ public boolean isForceInline() { @@ -266,7 +269,7 @@ /** * Returns true if this method has a {@code DontInline} annotation. - * + * * @return true if DontInline annotation present, false otherwise */ public boolean isDontInline() { @@ -283,7 +286,7 @@ /** * Returns true if this method is one of the special methods that is ignored by security stack * walks. - * + * * @return true if special method ignored by security stack walks, false otherwise */ public boolean ignoredBySecurityStackWalk() { @@ -310,18 +313,17 @@ @Override public boolean isClassInitializer() { - return "".equals(name) && Modifier.isStatic(getModifiers()); + return "".equals(name) && isStatic(); } @Override public boolean isConstructor() { - return "".equals(name) && !Modifier.isStatic(getModifiers()); + return "".equals(name) && !isStatic(); } @Override public int getMaxLocals() { - int modifiers = getModifiers(); - if (Modifier.isAbstract(modifiers) || Modifier.isNative(modifiers)) { + if (isAbstract() || isNative()) { return 0; } HotSpotVMConfig config = runtime().getConfig(); @@ -330,8 +332,7 @@ @Override public int getMaxStackSize() { - int modifiers = getModifiers(); - if (Modifier.isAbstract(modifiers) || Modifier.isNative(modifiers)) { + if (isAbstract() || isNative()) { return 0; } HotSpotVMConfig config = runtime().getConfig(); @@ -374,7 +375,7 @@ /** * Gets the value of {@code Method::_code}. - * + * * @return the value of {@code Method::_code} */ private long getCompiledCode() { @@ -384,7 +385,7 @@ /** * Returns whether this method has compiled code. - * + * * @return true if this method has compiled code, false otherwise */ public boolean hasCompiledCode() { @@ -451,7 +452,7 @@ @Override public Annotation[][] getParameterAnnotations() { if (isConstructor()) { - Constructor javaConstructor = toJavaConstructor(); + Constructor javaConstructor = toJavaConstructor(); return javaConstructor == null ? null : javaConstructor.getParameterAnnotations(); } Method javaMethod = toJava(); @@ -486,7 +487,7 @@ @Override public Type[] getGenericParameterTypes() { if (isConstructor()) { - Constructor javaConstructor = toJavaConstructor(); + Constructor javaConstructor = toJavaConstructor(); return javaConstructor == null ? null : javaConstructor.getGenericParameterTypes(); } Method javaMethod = toJava(); @@ -511,7 +512,7 @@ } } - private Constructor toJavaConstructor() { + private Constructor toJavaConstructor() { try { return holder.mirror().getDeclaredConstructor(signatureToTypes()); } catch (NoSuchMethodException e) { @@ -589,7 +590,7 @@ /** * Returns the offset of this method into the v-table. The method must have a v-table entry as * indicated by {@link #isInVirtualMethodTable()}, otherwise an exception is thrown. - * + * * @return the offset of this method into the v-table */ public int vtableEntryOffset() { @@ -608,19 +609,44 @@ /** * Returns this method's virtual table index. - * + * * @return virtual table index */ private int getVtableIndex() { + assert !holder.isInterface(); HotSpotVMConfig config = runtime().getConfig(); - return unsafe.getInt(metaspaceMethod + config.methodVtableIndexOffset); + int result = unsafe.getInt(metaspaceMethod + config.methodVtableIndexOffset); + assert result >= config.nonvirtualVtableIndex : "must be linked"; + return result; } + /** + * The {@link SpeculationLog} for methods compiled by Graal hang off this per-declaring-type + * {@link ClassValue}. The raw Method* value is safe to use as a key in the map as a) it is + * never moves and b) we never read from it. + *

    + * One implication is that we will preserve {@link SpeculationLog}s for methods that have been + * redefined via class redefinition. It's tempting to periodically flush such logs but we cannot + * read the JVM_ACC_IS_OBSOLETE bit (or anything else) via the raw pointer as obsoleted methods + * are subject to clean up and deletion (see InstanceKlass::purge_previous_versions_internal). + */ + private static final ClassValue> SpeculationLogs = new ClassValue>() { + @Override + protected Map computeValue(java.lang.Class type) { + return new HashMap<>(4); + } + }; + public SpeculationLog getSpeculationLog() { - if (speculationLog == null) { - speculationLog = new SpeculationLog(); + Map map = SpeculationLogs.get(holder.mirror()); + synchronized (map) { + SpeculationLog log = map.get(this.metaspaceMethod); + if (log == null) { + log = new HotSpotSpeculationLog(); + map.put(metaspaceMethod, log); + } + return log; } - return speculationLog; } public int intrinsicId() { @@ -636,13 +662,13 @@ Object[] objArguments = new Object[arguments.length]; for (int i = 0; i < arguments.length; i++) { - objArguments[i] = arguments[i].asBoxedValue(); + objArguments[i] = HotSpotObjectConstant.asBoxedValue(arguments[i]); } - Object objReceiver = receiver != null ? receiver.asObject() : null; + Object objReceiver = receiver != null ? HotSpotObjectConstant.asObject(receiver) : null; try { Object objResult = javaMethod.invoke(objReceiver, objArguments); - return javaMethod.getReturnType() == void.class ? null : Constant.forBoxed(getSignature().getReturnKind(), objResult); + return javaMethod.getReturnType() == void.class ? null : HotSpotObjectConstant.forBoxedValue(getSignature().getReturnKind(), objResult); } catch (IllegalAccessException | InvocationTargetException ex) { throw new IllegalArgumentException(ex); @@ -652,18 +678,18 @@ @Override public Constant newInstance(Constant[] arguments) { assert isConstructor(); - Constructor javaConstructor = toJavaConstructor(); + Constructor javaConstructor = toJavaConstructor(); javaConstructor.setAccessible(true); Object[] objArguments = new Object[arguments.length]; for (int i = 0; i < arguments.length; i++) { - objArguments[i] = arguments[i].asBoxedValue(); + objArguments[i] = HotSpotObjectConstant.asBoxedValue(arguments[i]); } try { Object objResult = javaConstructor.newInstance(objArguments); assert objResult != null; - return Constant.forObject(objResult); + return HotSpotObjectConstant.forObject(objResult); } catch (IllegalAccessException | InvocationTargetException | InstantiationException ex) { throw new IllegalArgumentException(ex); @@ -672,7 +698,7 @@ /** * Allocates a compile id for this method by asking the VM for one. - * + * * @param entryBCI entry bci * @return compile id */ diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java Wed Apr 23 15:48:38 2014 +0200 @@ -23,17 +23,15 @@ package com.oracle.graal.hotspot.meta; import static com.oracle.graal.api.meta.MetaUtil.*; -import static com.oracle.graal.graph.UnsafeAccess.*; +import static com.oracle.graal.compiler.common.UnsafeAccess.*; import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; -import static java.lang.reflect.Modifier.*; - import java.lang.annotation.*; import java.lang.reflect.*; import java.net.*; import java.util.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.graph.*; +import com.oracle.graal.compiler.common.*; import com.oracle.graal.hotspot.*; /** @@ -48,11 +46,6 @@ */ private final Class javaClass; - /** - * Used for implemented a lazy binding from a {@link Node} type to a {@link NodeClass} value. - */ - private NodeClass nodeClass; - private HashMap fieldCache; private HashMap methodCache; private HotSpotResolvedJavaField[] instanceFields; @@ -79,7 +72,7 @@ */ public static ResolvedJavaType fromMetaspaceKlass(long metaspaceKlass) { assert metaspaceKlass != 0; - Class javaClass = (Class) runtime().getCompilerToVM().readUnsafeUncompressedPointer(null, metaspaceKlass + runtime().getConfig().classMirrorOffset); + Class javaClass = runtime().getCompilerToVM().getJavaMirror(metaspaceKlass); assert javaClass != null; return fromClass(javaClass); } @@ -138,7 +131,7 @@ @Override public ResolvedJavaType getComponentType() { - Class javaComponentType = mirror().getComponentType(); + Class javaComponentType = mirror().getComponentType(); return javaComponentType == null ? null : fromClass(javaComponentType); } @@ -146,7 +139,7 @@ public ResolvedJavaType findUniqueConcreteSubtype() { HotSpotVMConfig config = runtime().getConfig(); if (isArray()) { - return isFinal(getElementalType(this).getModifiers()) ? this : null; + return getElementalType(this).isFinal() ? this : null; } else if (isInterface()) { final long implementorMetaspaceKlass = runtime().getCompilerToVM().getKlassImplementor(metaspaceKlass()); @@ -162,20 +155,20 @@ * than one implementors (see: InstanceKlass::add_implementor). The isInterface check * takes care of this fact since this class is an interface. */ - if (isAbstract(type.getModifiers()) || type.isInterface() || !type.isLeafClass()) { + if (type.isAbstract() || type.isInterface() || !type.isLeafClass()) { return null; } return type; } else { HotSpotResolvedObjectType type = this; - while (isAbstract(type.getModifiers())) { + while (type.isAbstract()) { long subklass = type.getSubklass(); if (subklass == 0 || unsafeReadWord(subklass + config.nextSiblingOffset) != 0) { return null; } type = (HotSpotResolvedObjectType) fromMetaspaceKlass(subklass); } - if (isAbstract(type.getModifiers()) || type.isInterface() || !type.isLeafClass()) { + if (type.isAbstract() || type.isInterface() || !type.isLeafClass()) { return null; } return type; @@ -204,14 +197,14 @@ @Override public HotSpotResolvedObjectType getSuperclass() { - Class javaSuperclass = mirror().getSuperclass(); + Class javaSuperclass = mirror().getSuperclass(); return javaSuperclass == null ? null : (HotSpotResolvedObjectType) fromClass(javaSuperclass); } @Override public ResolvedJavaType[] getInterfaces() { if (interfaces == null) { - Class[] javaInterfaces = mirror().getInterfaces(); + Class[] javaInterfaces = mirror().getInterfaces(); ResolvedJavaType[] result = new ResolvedJavaType[javaInterfaces.length]; for (int i = 0; i < javaInterfaces.length; i++) { result[i] = fromClass(javaInterfaces[i]); @@ -260,14 +253,14 @@ if (isArray()) { return getComponentType().asExactType() != null ? this : null; } - return isFinal(getModifiers()) ? this : null; + return isFinal() ? this : null; } @Override public Constant getEncoding(Representation r) { switch (r) { case JavaClass: - return Constant.forObject(mirror()); + return HotSpotObjectConstant.forObject(mirror()); case ObjectHub: return klass(); default: @@ -330,7 +323,7 @@ @Override public boolean isInstance(Constant obj) { if (obj.getKind() == Kind.Object && !obj.isNull()) { - return mirror().isInstance(obj.asObject()); + return mirror().isInstance(HotSpotObjectConstant.asObject(obj)); } return false; } @@ -363,7 +356,7 @@ @Override public ResolvedJavaMethod resolveMethod(ResolvedJavaMethod method) { assert method instanceof HotSpotMethod; - if (!isAbstract(method.getModifiers()) && method.getDeclaringClass().equals(this)) { + if (!method.isAbstract() && method.getDeclaringClass().equals(this)) { return method; } @@ -372,7 +365,7 @@ return null; } HotSpotResolvedJavaMethod resolvedMethod = HotSpotResolvedJavaMethod.fromMetaspace(resolvedMetaspaceMethod); - if (isAbstract(resolvedMethod.getModifiers())) { + if (resolvedMethod.isAbstract()) { return null; } return resolvedMethod; @@ -661,7 +654,7 @@ * Gets the metaspace Klass boxed in a {@link Constant}. */ public Constant klass() { - return Constant.forIntegerKind(runtime().getTarget().wordKind, metaspaceKlass(), this); + return HotSpotMetaspaceConstant.forMetaspaceObject(runtime().getTarget().wordKind, metaspaceKlass(), this); } public boolean isPrimaryType() { @@ -717,7 +710,7 @@ @Override public ResolvedJavaMethod[] getDeclaredConstructors() { - Constructor[] constructors = mirror().getDeclaredConstructors(); + Constructor[] constructors = mirror().getDeclaredConstructors(); ResolvedJavaMethod[] result = new ResolvedJavaMethod[constructors.length]; for (int i = 0; i < constructors.length; i++) { result[i] = runtime().getHostProviders().getMetaAccess().lookupJavaConstructor(constructors[i]); @@ -747,21 +740,7 @@ @Override public Constant newArray(int length) { - return Constant.forObject(Array.newInstance(mirror(), length)); - } - - /** - * @return the {@link NodeClass} value (which may be {@code null}) associated with this type - */ - public NodeClass getNodeClass() { - return nodeClass; - } - - /** - * Sets the {@link NodeClass} value associated with this type. - */ - public void setNodeClass(NodeClass nodeClass) { - this.nodeClass = nodeClass; + return HotSpotObjectConstant.forObject(Array.newInstance(mirror(), length)); } @Override diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedPrimitiveType.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedPrimitiveType.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedPrimitiveType.java Wed Apr 23 15:48:38 2014 +0200 @@ -27,7 +27,7 @@ import java.net.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.graph.*; +import com.oracle.graal.compiler.common.*; /** * Implementation of {@link JavaType} for primitive HotSpot types. @@ -253,6 +253,6 @@ @Override public Constant newArray(int length) { - return Constant.forObject(Array.newInstance(mirror(), length)); + return HotSpotObjectConstant.forObject(Array.newInstance(mirror(), length)); } } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntimeStub.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntimeStub.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntimeStub.java Wed Apr 23 15:48:38 2014 +0200 @@ -24,7 +24,7 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.graph.*; +import com.oracle.graal.compiler.common.*; import com.oracle.graal.hotspot.stubs.*; /** @@ -32,8 +32,6 @@ */ public class HotSpotRuntimeStub extends HotSpotInstalledCode { - private static final long serialVersionUID = -6388648408298441748L; - private final Stub stub; public HotSpotRuntimeStub(Stub stub) { @@ -44,18 +42,21 @@ return null; } + @Override public boolean isValid() { return true; } + @Override public void invalidate() { } @Override public String toString() { - return String.format("InstalledRuntimeStub[stub=%s, codeBlob=0x%x]", stub, getCodeBlob()); + return String.format("InstalledRuntimeStub[stub=%s, codeBlob=0x%x]", stub, getAddress()); } + @Override public Object executeVarargs(Object... args) throws InvalidInstalledCodeException { throw new GraalInternalError("Cannot call stub %s", stub); } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSignature.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSignature.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSignature.java Wed Apr 23 15:48:38 2014 +0200 @@ -27,7 +27,7 @@ import java.util.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.graph.*; +import com.oracle.graal.compiler.common.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.java.*; diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSnippetReflectionProvider.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSnippetReflectionProvider.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2014, 2014, 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.meta; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.api.replacements.*; + +public class HotSpotSnippetReflectionProvider implements SnippetReflectionProvider { + + @Override + public Constant forObject(Object object) { + return HotSpotObjectConstant.forObject(object); + } + + @Override + public Object asObject(Constant constant) { + return HotSpotObjectConstant.asObject(constant); + } + + @Override + public Constant forBoxed(Kind kind, Object value) { + return HotSpotObjectConstant.forBoxedValue(kind, value); + } + + @Override + public Object asBoxedValue(Constant constant) { + return HotSpotObjectConstant.asBoxedValue(constant); + } +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSpeculationLog.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSpeculationLog.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2014, 2014, 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.meta; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; + +public class HotSpotSpeculationLog extends SpeculationLog { + + @Override + public Constant speculate(Object reason) { + addSpeculation(reason); + return HotSpotObjectConstant.forObject(reason); + } +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSuitesProvider.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSuitesProvider.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSuitesProvider.java Wed Apr 23 15:48:38 2014 +0200 @@ -22,7 +22,7 @@ */ package com.oracle.graal.hotspot.meta; -import static com.oracle.graal.phases.GraalOptions.*; +import static com.oracle.graal.compiler.common.GraalOptions.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.phases.*; diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nfi/HotSpotNativeFunctionHandle.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nfi/HotSpotNativeFunctionHandle.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nfi/HotSpotNativeFunctionHandle.java Wed Apr 23 15:48:38 2014 +0200 @@ -26,17 +26,17 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.common.*; import com.oracle.graal.debug.*; import com.oracle.graal.debug.Debug.Scope; -import com.oracle.graal.graph.*; public class HotSpotNativeFunctionHandle implements NativeFunctionHandle { private final InstalledCode code; private final String name; - private final Class[] argumentTypes; + private final Class[] argumentTypes; - public HotSpotNativeFunctionHandle(InstalledCode code, String name, Class... argumentTypes) { + public HotSpotNativeFunctionHandle(InstalledCode code, String name, Class... argumentTypes) { this.argumentTypes = argumentTypes; this.name = name; this.code = code; @@ -63,7 +63,7 @@ assert checkArgs(args); try { traceCall(args); - Object res = code.executeVarargs(args); + Object res = code.executeVarargs(args, null, null); traceResult(res); return res; } catch (InvalidInstalledCodeException e) { @@ -76,7 +76,7 @@ for (int i = 0; i < argumentTypes.length; i++) { Object arg = args[i]; assert arg != null; - Class expectedType = argumentTypes[i]; + Class expectedType = argumentTypes[i]; if (expectedType.isPrimitive()) { Kind kind = Kind.fromJavaClass(expectedType); expectedType = kind.toBoxedJavaClass(); diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nfi/HotSpotNativeFunctionInterface.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nfi/HotSpotNativeFunctionInterface.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nfi/HotSpotNativeFunctionInterface.java Wed Apr 23 15:48:38 2014 +0200 @@ -23,7 +23,7 @@ package com.oracle.graal.hotspot.nfi; import static com.oracle.graal.api.code.CodeUtil.*; -import static com.oracle.graal.graph.UnsafeAccess.*; +import static com.oracle.graal.compiler.common.UnsafeAccess.*; import static com.oracle.graal.hotspot.nfi.NativeCallStubGraphBuilder.*; import com.oracle.graal.api.code.*; @@ -86,13 +86,13 @@ } @Override - public HotSpotNativeFunctionHandle getFunctionHandle(NativeLibraryHandle library, String name, Class returnType, Class... argumentTypes) { + public HotSpotNativeFunctionHandle getFunctionHandle(NativeLibraryHandle library, String name, Class returnType, Class... argumentTypes) { HotSpotNativeFunctionPointer functionPointer = lookupFunctionPointer(name, library, true); return createHandle(functionPointer, returnType, argumentTypes); } @Override - public HotSpotNativeFunctionHandle getFunctionHandle(NativeLibraryHandle[] libraries, String name, Class returnType, Class... argumentTypes) { + public HotSpotNativeFunctionHandle getFunctionHandle(NativeLibraryHandle[] libraries, String name, Class returnType, Class... argumentTypes) { HotSpotNativeFunctionPointer functionPointer = null; for (NativeLibraryHandle libraryHandle : libraries) { functionPointer = lookupFunctionPointer(name, libraryHandle, false); @@ -105,7 +105,7 @@ } @Override - public HotSpotNativeFunctionHandle getFunctionHandle(String name, Class returnType, Class... argumentTypes) { + public HotSpotNativeFunctionHandle getFunctionHandle(String name, Class returnType, Class... argumentTypes) { if (rtldDefault == null) { throw new UnsatisfiedLinkError(name); } @@ -136,14 +136,14 @@ } @Override - public HotSpotNativeFunctionHandle getFunctionHandle(NativeFunctionPointer functionPointer, Class returnType, Class... argumentTypes) { + public HotSpotNativeFunctionHandle getFunctionHandle(NativeFunctionPointer functionPointer, Class returnType, Class... argumentTypes) { if (!(functionPointer instanceof HotSpotNativeFunctionPointer)) { throw new UnsatisfiedLinkError(functionPointer.getName()); } return createHandle(functionPointer, returnType, argumentTypes); } - private HotSpotNativeFunctionHandle createHandle(NativeFunctionPointer functionPointer, Class returnType, Class... argumentTypes) { + private HotSpotNativeFunctionHandle createHandle(NativeFunctionPointer functionPointer, Class returnType, Class... argumentTypes) { HotSpotNativeFunctionPointer hs = (HotSpotNativeFunctionPointer) functionPointer; InstalledCode code = installNativeFunctionStub(hs.value, returnType, argumentTypes); return new HotSpotNativeFunctionHandle(code, hs.name, argumentTypes); @@ -152,7 +152,7 @@ /** * Creates and installs a stub for calling a native function. */ - private InstalledCode installNativeFunctionStub(long functionPointer, Class returnType, Class... argumentTypes) { + private InstalledCode installNativeFunctionStub(long functionPointer, Class returnType, Class... argumentTypes) { StructuredGraph g = getGraph(providers, factory, functionPointer, returnType, argumentTypes); Suites suites = providers.getSuites().createSuites(); PhaseSuite phaseSuite = backend.getSuites().getDefaultGraphBuilderSuite().copy(); @@ -161,7 +161,7 @@ DefaultProfilingInfo.get(TriState.UNKNOWN), null, suites, new CompilationResult(), CompilationResultBuilderFactory.Default); InstalledCode installedCode; try (Scope s = Debug.scope("CodeInstall", providers.getCodeCache(), g.method())) { - installedCode = providers.getCodeCache().addMethod(g.method(), compResult, null); + installedCode = providers.getCodeCache().addMethod(g.method(), compResult, null, null); } return installedCode; } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nfi/NativeCallStubGraphBuilder.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nfi/NativeCallStubGraphBuilder.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nfi/NativeCallStubGraphBuilder.java Wed Apr 23 15:48:38 2014 +0200 @@ -27,12 +27,12 @@ import java.util.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.graph.*; +import com.oracle.graal.compiler.common.*; +import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.java.*; -import com.oracle.graal.nodes.type.*; import com.oracle.graal.nodes.virtual.*; import com.oracle.graal.word.phases.*; @@ -43,13 +43,13 @@ /** * Creates a graph for a stub used to call a native function. - * + * * @param functionPointer a native function pointer * @param returnType the type of the return value * @param argumentTypes the types of the arguments * @return the graph that represents the call stub */ - public static StructuredGraph getGraph(HotSpotProviders providers, RawNativeCallNodeFactory factory, long functionPointer, Class returnType, Class... argumentTypes) { + public static StructuredGraph getGraph(HotSpotProviders providers, RawNativeCallNodeFactory factory, long functionPointer, Class returnType, Class... argumentTypes) { try { ResolvedJavaMethod method = providers.getMetaAccess().lookupJavaMethod(NativeCallStubGraphBuilder.class.getMethod("libCall", Object.class, Object.class, Object.class)); StructuredGraph g = new StructuredGraph(method); @@ -91,14 +91,14 @@ ReturnNode returnNode = g.add(new ReturnNode(boxedResult)); callNode.setNext(returnNode); - (new WordTypeRewriterPhase(providers.getMetaAccess(), Kind.Long)).apply(g); + (new WordTypeRewriterPhase(providers.getMetaAccess(), providers.getSnippetReflection(), Kind.Long)).apply(g); return g; } catch (NoSuchMethodException e) { throw GraalInternalError.shouldNotReachHere("Call Stub method not found"); } } - private static FixedWithNextNode getParameters(StructuredGraph g, ParameterNode argumentsArray, int numArgs, Class[] argumentTypes, List args, HotSpotProviders providers) { + private static FixedWithNextNode getParameters(StructuredGraph g, ParameterNode argumentsArray, int numArgs, Class[] argumentTypes, List args, HotSpotProviders providers) { assert numArgs == argumentTypes.length; FixedWithNextNode last = null; for (int i = 0; i < numArgs; i++) { @@ -111,7 +111,7 @@ last.setNext(boxedElement); last = boxedElement; } - Class type = argumentTypes[i]; + Class type = argumentTypes[i]; Kind kind = getKind(type); if (kind == Kind.Object) { // array value @@ -140,8 +140,8 @@ return last; } - public static Kind getElementKind(Class clazz) { - Class componentType = clazz.getComponentType(); + public static Kind getElementKind(Class clazz) { + Class componentType = clazz.getComponentType(); if (componentType == null) { throw new IllegalArgumentException("Parameter type not supported: " + clazz); } @@ -151,7 +151,7 @@ throw new IllegalArgumentException("Parameter type not supported: " + clazz); } - private static Kind getKind(Class clazz) { + private static Kind getKind(Class clazz) { if (clazz == int.class || clazz == Integer.class) { return Kind.Int; } else if (clazz == long.class || clazz == Long.class) { diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/AllocaNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/AllocaNode.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/AllocaNode.java Wed Apr 23 15:48:38 2014 +0200 @@ -26,12 +26,12 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.compiler.gen.*; +import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.compiler.target.*; import com.oracle.graal.hotspot.*; +import com.oracle.graal.lir.gen.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.nodes.type.*; /** * Reserves a block of memory in the stack frame of a method. The block is reserved in the frame for diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassCastNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassCastNode.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassCastNode.java Wed Apr 23 15:48:38 2014 +0200 @@ -54,7 +54,7 @@ ValueNode javaClass = getJavaClass(); if (javaClass.isConstant()) { ValueNode object = getObject(); - Class c = (Class) javaClass.asConstant().asObject(); + Class c = (Class) HotSpotObjectConstant.asObject(javaClass.asConstant()); if (c != null && !c.isPrimitive()) { HotSpotResolvedObjectType type = (HotSpotResolvedObjectType) HotSpotResolvedObjectType.fromClass(c); CheckCastNode checkcast = graph().add(new CheckCastNode(type, object, null, false)); diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassGetComponentTypeNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassGetComponentTypeNode.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassGetComponentTypeNode.java Wed Apr 23 15:48:38 2014 +0200 @@ -24,13 +24,14 @@ import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; +import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.hotspot.replacements.*; import com.oracle.graal.nodes.*; import com.oracle.graal.replacements.nodes.*; /** * {@link MacroNode Macro node} for {@link Class#getComponentType()}. - * + * * @see ClassSubstitutions#getComponentType(Class) */ public class ClassGetComponentTypeNode extends MacroNode implements Canonicalizable { @@ -47,10 +48,10 @@ public Node canonical(CanonicalizerTool tool) { ValueNode javaClass = getJavaClass(); if (javaClass.isConstant()) { - Class c = (Class) javaClass.asConstant().asObject(); + Class c = (Class) HotSpotObjectConstant.asObject(javaClass.asConstant()); if (c != null) { - Class componentType = c.getComponentType(); - return ConstantNode.forObject(componentType, tool.getMetaAccess(), graph()); + Class componentType = c.getComponentType(); + return ConstantNode.forConstant(HotSpotObjectConstant.forObject(componentType), tool.getMetaAccess(), graph()); } } return this; diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassGetModifiersNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassGetModifiersNode.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassGetModifiersNode.java Wed Apr 23 15:48:38 2014 +0200 @@ -24,6 +24,7 @@ import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; +import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.hotspot.replacements.*; import com.oracle.graal.nodes.*; import com.oracle.graal.replacements.nodes.*; @@ -47,7 +48,7 @@ public Node canonical(CanonicalizerTool tool) { ValueNode javaClass = getJavaClass(); if (javaClass.isConstant()) { - Class c = (Class) javaClass.asConstant().asObject(); + Class c = (Class) HotSpotObjectConstant.asObject(javaClass.asConstant()); if (c != null) { return ConstantNode.forInt(c.getModifiers(), graph()); } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassGetSuperclassNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassGetSuperclassNode.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassGetSuperclassNode.java Wed Apr 23 15:48:38 2014 +0200 @@ -24,13 +24,14 @@ import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; +import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.hotspot.replacements.*; import com.oracle.graal.nodes.*; import com.oracle.graal.replacements.nodes.*; /** * {@link MacroNode Macro node} for {@link Class#getSuperclass()}. - * + * * @see ClassSubstitutions#getSuperclass(Class) */ public class ClassGetSuperclassNode extends MacroNode implements Canonicalizable { @@ -47,10 +48,10 @@ public Node canonical(CanonicalizerTool tool) { ValueNode javaClass = getJavaClass(); if (javaClass.isConstant()) { - Class c = (Class) javaClass.asConstant().asObject(); + Class c = (Class) HotSpotObjectConstant.asObject(javaClass.asConstant()); if (c != null) { - Class superclass = c.getSuperclass(); - return ConstantNode.forObject(superclass, tool.getMetaAccess(), graph()); + Class superclass = c.getSuperclass(); + return ConstantNode.forConstant(HotSpotObjectConstant.forObject(superclass), tool.getMetaAccess(), graph()); } } return this; diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassIsArrayNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassIsArrayNode.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassIsArrayNode.java Wed Apr 23 15:48:38 2014 +0200 @@ -24,6 +24,7 @@ import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; +import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.hotspot.replacements.*; import com.oracle.graal.nodes.*; import com.oracle.graal.replacements.nodes.*; @@ -47,7 +48,7 @@ public Node canonical(CanonicalizerTool tool) { ValueNode javaClass = getJavaClass(); if (javaClass.isConstant()) { - Class c = (Class) javaClass.asConstant().asObject(); + Class c = (Class) HotSpotObjectConstant.asObject(javaClass.asConstant()); if (c != null) { return ConstantNode.forBoolean(c.isArray(), graph()); } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassIsInstanceNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassIsInstanceNode.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassIsInstanceNode.java Wed Apr 23 15:48:38 2014 +0200 @@ -55,13 +55,13 @@ ValueNode javaClass = getJavaClass(); if (javaClass.isConstant()) { ValueNode object = getObject(); - Class c = (Class) javaClass.asConstant().asObject(); + Class c = (Class) HotSpotObjectConstant.asObject(javaClass.asConstant()); if (c != null) { if (c.isPrimitive()) { return ConstantNode.forBoolean(false, graph()); } if (object.isConstant()) { - Object o = object.asConstant().asObject(); + Object o = HotSpotObjectConstant.asObject(object.asConstant()); return ConstantNode.forBoolean(o != null && c.isInstance(o), graph()); } HotSpotResolvedObjectType type = (HotSpotResolvedObjectType) HotSpotResolvedObjectType.fromClass(c); diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassIsInterfaceNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassIsInterfaceNode.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassIsInterfaceNode.java Wed Apr 23 15:48:38 2014 +0200 @@ -24,6 +24,7 @@ import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; +import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.hotspot.replacements.*; import com.oracle.graal.nodes.*; import com.oracle.graal.replacements.nodes.*; @@ -47,7 +48,7 @@ public Node canonical(CanonicalizerTool tool) { ValueNode javaClass = getJavaClass(); if (javaClass.isConstant()) { - Class c = (Class) javaClass.asConstant().asObject(); + Class c = (Class) HotSpotObjectConstant.asObject(javaClass.asConstant()); if (c != null) { return ConstantNode.forBoolean(c.isInterface(), graph()); } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassIsPrimitiveNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassIsPrimitiveNode.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassIsPrimitiveNode.java Wed Apr 23 15:48:38 2014 +0200 @@ -24,6 +24,7 @@ import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; +import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.hotspot.replacements.*; import com.oracle.graal.nodes.*; import com.oracle.graal.replacements.nodes.*; @@ -47,7 +48,7 @@ public Node canonical(CanonicalizerTool tool) { ValueNode javaClass = getJavaClass(); if (javaClass.isConstant()) { - Class c = (Class) javaClass.asConstant().asObject(); + Class c = (Class) HotSpotObjectConstant.asObject(javaClass.asConstant()); if (c != null) { return ConstantNode.forBoolean(c.isPrimitive(), graph()); } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CompressionNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CompressionNode.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CompressionNode.java Wed Apr 23 15:48:38 2014 +0200 @@ -23,6 +23,8 @@ package com.oracle.graal.hotspot.nodes; import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.common.*; +import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; import com.oracle.graal.hotspot.*; @@ -73,7 +75,7 @@ } else if (input instanceof IntegerStamp) { // compressed metaspace pointer assert PrimitiveStamp.getBits(input) == 64; - return StampFactory.forInteger(32, false); + return StampFactory.forInteger(32); } break; case Uncompress: @@ -84,7 +86,7 @@ } else if (input instanceof IntegerStamp) { // metaspace pointer assert PrimitiveStamp.getBits(input) == 32; - return StampFactory.forInteger(64, false); + return StampFactory.forInteger(64); } break; } @@ -105,13 +107,21 @@ @Override public void generate(NodeLIRBuilderTool gen) { HotSpotLIRGenerator hsGen = (HotSpotLIRGenerator) gen.getLIRGeneratorTool(); + boolean nonNull; + if (input.stamp() instanceof ObjectStamp) { + nonNull = StampTool.isObjectNonNull(input.stamp()); + } else { + // metaspace pointers are never null + nonNull = true; + } + Value result; switch (op) { case Compress: - result = hsGen.emitCompress(gen.operand(input), encoding); + result = hsGen.emitCompress(gen.operand(input), encoding, nonNull); break; case Uncompress: - result = hsGen.emitUncompress(gen.operand(input), encoding); + result = hsGen.emitUncompress(gen.operand(input), encoding, nonNull); break; default: throw GraalInternalError.shouldNotReachHere(); diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CurrentJavaThreadNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CurrentJavaThreadNode.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CurrentJavaThreadNode.java Wed Apr 23 15:48:38 2014 +0200 @@ -26,11 +26,11 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.graph.*; +import com.oracle.graal.compiler.common.*; +import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.nodes.type.*; import com.oracle.graal.word.*; /** diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/DeoptimizeCallerNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/DeoptimizeCallerNode.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/DeoptimizeCallerNode.java Wed Apr 23 15:48:38 2014 +0200 @@ -23,11 +23,11 @@ package com.oracle.graal.hotspot.nodes; import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.graph.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.nodes.type.*; /** * Removes the current frame and tail calls the uncommon trap routine. diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/DeoptimizingStubCall.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/DeoptimizingStubCall.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/DeoptimizingStubCall.java Wed Apr 23 15:48:38 2014 +0200 @@ -22,8 +22,8 @@ */ package com.oracle.graal.hotspot.nodes; +import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.type.*; public class DeoptimizingStubCall extends DeoptimizingFixedWithNextNode { diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/DimensionsNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/DimensionsNode.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/DimensionsNode.java Wed Apr 23 15:48:38 2014 +0200 @@ -28,8 +28,8 @@ 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.lir.gen.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.word.*; diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/EndLockScopeNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/EndLockScopeNode.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/EndLockScopeNode.java Wed Apr 23 15:48:38 2014 +0200 @@ -23,11 +23,11 @@ package com.oracle.graal.hotspot.nodes; import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.nodes.type.*; /** * Intrinsic for closing a {@linkplain BeginLockScopeNode scope} binding a stack-based lock with an diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/EnterUnpackFramesStackFrameNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/EnterUnpackFramesStackFrameNode.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2013, 2014, 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.compiler.common.type.*; +import com.oracle.graal.hotspot.*; +import com.oracle.graal.hotspot.stubs.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.word.*; + +/** + * Emits code to enter a low-level stack frame specifically to call out to the C++ method + * {@link DeoptimizationStub#UNPACK_FRAMES Deoptimization::unpack_frames}. + */ +public class EnterUnpackFramesStackFrameNode extends FixedWithNextNode implements LIRLowerable { + + @Input private ValueNode framePc; + @Input private ValueNode senderSp; + @Input private ValueNode senderFp; + + public EnterUnpackFramesStackFrameNode(ValueNode framePc, ValueNode senderSp, ValueNode senderFp) { + super(StampFactory.forVoid()); + this.framePc = framePc; + this.senderSp = senderSp; + this.senderFp = senderFp; + } + + @Override + public void generate(NodeLIRBuilderTool gen) { + Value operandValue = gen.operand(framePc); + Value senderSpValue = gen.operand(senderSp); + Value senderFpValue = gen.operand(senderFp); + ((HotSpotLIRGenerator) gen.getLIRGeneratorTool()).emitEnterUnpackFramesStackFrame(operandValue, senderSpValue, senderFpValue); + } + + @NodeIntrinsic + public static native void enterUnpackFramesStackFrame(Word framePc, Word senderSp, Word senderFp); +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/GetObjectAddressNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/GetObjectAddressNode.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/GetObjectAddressNode.java Wed Apr 23 15:48:38 2014 +0200 @@ -23,9 +23,9 @@ package com.oracle.graal.hotspot.nodes; import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.nodes.type.*; /** * Intrinsification for getting the address of an object. The code path(s) between a call to diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/HotSpotDirectCallTargetNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/HotSpotDirectCallTargetNode.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/HotSpotDirectCallTargetNode.java Wed Apr 23 15:48:38 2014 +0200 @@ -26,9 +26,9 @@ import com.oracle.graal.api.code.CallingConvention.Type; import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind; -import com.oracle.graal.nodes.type.*; public class HotSpotDirectCallTargetNode extends DirectCallTargetNode { diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/HotSpotIndirectCallTargetNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/HotSpotIndirectCallTargetNode.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/HotSpotIndirectCallTargetNode.java Wed Apr 23 15:48:38 2014 +0200 @@ -26,8 +26,8 @@ import com.oracle.graal.api.code.CallingConvention.Type; import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.type.*; public class HotSpotIndirectCallTargetNode extends IndirectCallTargetNode { diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/JumpToExceptionHandlerInCallerNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/JumpToExceptionHandlerInCallerNode.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/JumpToExceptionHandlerInCallerNode.java Wed Apr 23 15:48:38 2014 +0200 @@ -22,10 +22,10 @@ */ package com.oracle.graal.hotspot.nodes; +import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.nodes.type.*; import com.oracle.graal.word.*; /** diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/LeaveCurrentStackFrameNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/LeaveCurrentStackFrameNode.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2013, 2014, 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.compiler.common.type.*; +import com.oracle.graal.hotspot.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.spi.*; + +/** + * Emits code to leave (pop) the current low-level stack frame. This operation also removes the + * return address if its location is on the stack. + */ +public class LeaveCurrentStackFrameNode extends FixedWithNextNode implements LIRLowerable { + + public LeaveCurrentStackFrameNode() { + super(StampFactory.forVoid()); + } + + @Override + public void generate(NodeLIRBuilderTool gen) { + ((HotSpotLIRGenerator) gen.getLIRGeneratorTool()).emitLeaveCurrentStackFrame(); + } + + @NodeIntrinsic + public static native void leaveCurrentStackFrame(); +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/LeaveDeoptimizedStackFrameNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/LeaveDeoptimizedStackFrameNode.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2013, 2014, 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.compiler.common.type.*; +import com.oracle.graal.hotspot.*; +import com.oracle.graal.hotspot.stubs.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.word.*; + +/** + * Emits code to leave (pop) the current low-level stack frame which is being deoptimized. This node + * is only used in {@link DeoptimizationStub}. + */ +public class LeaveDeoptimizedStackFrameNode extends FixedWithNextNode implements LIRLowerable { + + @Input private ValueNode frameSize; + @Input private ValueNode initialInfo; + + public LeaveDeoptimizedStackFrameNode(ValueNode frameSize, ValueNode initialInfo) { + super(StampFactory.forVoid()); + this.frameSize = frameSize; + this.initialInfo = initialInfo; + } + + @Override + public void generate(NodeLIRBuilderTool gen) { + Value frameSizeValue = gen.operand(frameSize); + Value initialInfoValue = gen.operand(initialInfo); + ((HotSpotLIRGenerator) gen.getLIRGeneratorTool()).emitLeaveDeoptimizedStackFrame(frameSizeValue, initialInfoValue); + } + + @NodeIntrinsic + public static native void leaveDeoptimizedStackFrame(int frameSize, Word initialInfo); +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/LeaveUnpackFramesStackFrameNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/LeaveUnpackFramesStackFrameNode.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2013, 2014, 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.compiler.common.type.*; +import com.oracle.graal.hotspot.*; +import com.oracle.graal.hotspot.stubs.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.spi.*; + +/** + * Emits code to leave a low-level stack frame specifically to call out to the C++ method + * {@link DeoptimizationStub#UNPACK_FRAMES Deoptimization::unpack_frames}. + */ +public class LeaveUnpackFramesStackFrameNode extends FixedWithNextNode implements LIRLowerable { + + public LeaveUnpackFramesStackFrameNode() { + super(StampFactory.forVoid()); + } + + @Override + public void generate(NodeLIRBuilderTool gen) { + ((HotSpotLIRGenerator) gen.getLIRGeneratorTool()).emitLeaveUnpackFramesStackFrame(); + } + + @NodeIntrinsic + public static native void leaveUnpackFramesStackFrame(); +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/MonitorCounterNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/MonitorCounterNode.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/MonitorCounterNode.java Wed Apr 23 15:48:38 2014 +0200 @@ -26,8 +26,8 @@ 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.lir.gen.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.word.*; diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewArrayStubCall.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewArrayStubCall.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewArrayStubCall.java Wed Apr 23 15:48:38 2014 +0200 @@ -24,13 +24,13 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.compiler.gen.*; import com.oracle.graal.compiler.target.*; import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.hotspot.stubs.*; import com.oracle.graal.lir.*; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.type.*; import com.oracle.graal.word.*; /** @@ -63,7 +63,7 @@ @Override public void generate(NodeLIRBuilder gen) { ForeignCallLinkage linkage = gen.getLIRGeneratorTool().getForeignCalls().lookupForeignCall(NEW_ARRAY); - Variable result = gen.getLIRGenerator().emitForeignCall(linkage, this, gen.operand(hub), gen.operand(length)); + Variable result = gen.getLIRGenerator().emitForeignCall(linkage, gen.state(this), gen.operand(hub), gen.operand(length)); gen.setResult(this, result); } diff -r 518a7f487c4f -r 9363fffa8b07 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 Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewInstanceStubCall.java Wed Apr 23 15:48:38 2014 +0200 @@ -24,11 +24,11 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.hotspot.stubs.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.nodes.type.*; import com.oracle.graal.word.*; /** @@ -59,7 +59,7 @@ @Override public void generate(NodeLIRBuilderTool gen) { ForeignCallLinkage linkage = gen.getLIRGeneratorTool().getForeignCalls().lookupForeignCall(NEW_INSTANCE); - Value result = gen.getLIRGeneratorTool().emitForeignCall(linkage, this, gen.operand(hub)); + Value result = gen.getLIRGeneratorTool().emitForeignCall(linkage, gen.state(this), gen.operand(hub)); gen.setResult(this, result); } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewMultiArrayStubCall.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewMultiArrayStubCall.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewMultiArrayStubCall.java Wed Apr 23 15:48:38 2014 +0200 @@ -24,11 +24,11 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.nodes.type.*; import com.oracle.graal.word.*; /** diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/PatchReturnAddressNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/PatchReturnAddressNode.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/PatchReturnAddressNode.java Wed Apr 23 15:48:38 2014 +0200 @@ -22,10 +22,10 @@ */ package com.oracle.graal.hotspot.nodes; +import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.nodes.type.*; import com.oracle.graal.word.*; /** diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/PrefetchAllocateNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/PrefetchAllocateNode.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/PrefetchAllocateNode.java Wed Apr 23 15:48:38 2014 +0200 @@ -23,11 +23,11 @@ package com.oracle.graal.hotspot.nodes; +import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.compiler.gen.*; import com.oracle.graal.compiler.target.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.type.*; import com.oracle.graal.word.*; public class PrefetchAllocateNode extends FixedWithNextNode implements LIRGenLowerable { diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/PushInterpreterFrameNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/PushInterpreterFrameNode.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2013, 2014, 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.compiler.common.type.*; +import com.oracle.graal.hotspot.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.word.*; + +/** + * A call to the runtime code implementing the uncommon trap logic. + */ +public class PushInterpreterFrameNode extends FixedWithNextNode implements LIRLowerable { + + @Input private ValueNode framePc; + @Input private ValueNode frameSize; + @Input private ValueNode senderSp; + @Input private ValueNode initialInfo; + + public PushInterpreterFrameNode(ValueNode frameSize, ValueNode framePc, ValueNode senderSp, ValueNode initialInfo) { + super(StampFactory.forVoid()); + this.frameSize = frameSize; + this.framePc = framePc; + this.senderSp = senderSp; + this.initialInfo = initialInfo; + } + + @Override + public void generate(NodeLIRBuilderTool gen) { + Value frameSizeValue = gen.operand(frameSize); + Value framePcValue = gen.operand(framePc); + Value senderSpValue = gen.operand(senderSp); + Value initialInfoValue = gen.operand(initialInfo); + ((HotSpotLIRGenerator) gen.getLIRGeneratorTool()).emitPushInterpreterFrame(frameSizeValue, framePcValue, senderSpValue, initialInfoValue); + } + + @NodeIntrinsic + public static native void pushInterpreterFrame(Word frameSize, Word framePc, Word senderSp, Word initialInfo); + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/SaveAllRegistersNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/SaveAllRegistersNode.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2013, 2014, 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.compiler.common.type.*; +import com.oracle.graal.hotspot.*; +import com.oracle.graal.lir.StandardOp.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.spi.*; + +/** + * Saves all allocatable registers. + */ +public class SaveAllRegistersNode extends FixedWithNextNode implements LIRLowerable { + + private SaveRegistersOp saveRegistersOp; + + public SaveAllRegistersNode() { + super(StampFactory.forKind(Kind.Long)); + } + + @Override + public void generate(NodeLIRBuilderTool gen) { + saveRegistersOp = ((HotSpotLIRGenerator) gen.getLIRGeneratorTool()).emitSaveAllRegisters(); + } + + /** + * @return the map from registers to the stack locations in they are saved + */ + public SaveRegistersOp getSaveRegistersOp() { + assert saveRegistersOp != null : "saved registers op has not yet been created"; + return saveRegistersOp; + } + + /** + * @return a token that couples this node to an {@link UncommonTrapCallNode} so that the latter + * has access to the {@linkplain SaveRegistersOp#getMap register save map} + */ + @NodeIntrinsic + public static native long saveAllRegisters(); +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/SnippetAnchorNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/SnippetAnchorNode.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/SnippetAnchorNode.java Wed Apr 23 15:48:38 2014 +0200 @@ -22,11 +22,11 @@ */ package com.oracle.graal.hotspot.nodes; +import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.extended.*; -import com.oracle.graal.nodes.type.*; @NodeInfo(allowedUsageTypes = {InputType.Value, InputType.Anchor, InputType.Guard}) public final class SnippetAnchorNode extends FixedWithNextNode implements Simplifiable, GuardingNode { @@ -37,7 +37,7 @@ @Override public void simplify(SimplifierTool tool) { - AbstractBeginNode prevBegin = BeginNode.prevBegin(this); + BeginNode prevBegin = BeginNode.prevBegin(this); replaceAtUsages(InputType.Anchor, prevBegin); replaceAtUsages(InputType.Guard, prevBegin); if (usages().isEmpty()) { diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/SnippetLocationProxyNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/SnippetLocationProxyNode.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/SnippetLocationProxyNode.java Wed Apr 23 15:48:38 2014 +0200 @@ -22,12 +22,12 @@ */ package com.oracle.graal.hotspot.nodes; +import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.extended.*; -import com.oracle.graal.nodes.type.*; @NodeInfo(allowedUsageTypes = {InputType.Association, InputType.Value}) public final class SnippetLocationProxyNode extends FloatingNode implements Canonicalizable { diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/StubForeignCallNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/StubForeignCallNode.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/StubForeignCallNode.java Wed Apr 23 15:48:38 2014 +0200 @@ -24,11 +24,11 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.nodes.type.*; /** * Node for a {@linkplain ForeignCallDescriptor foreign} call from within a stub. @@ -68,7 +68,7 @@ @Override public void generate(NodeLIRBuilderTool gen) { assert graph().start() instanceof StubStartNode; - ForeignCallLinkage linkage = gen.getLIRGeneratorTool().getForeignCalls().lookupForeignCall(descriptor); + ForeignCallLinkage linkage = foreignCalls.lookupForeignCall(descriptor); Value[] operands = operands(gen); Value result = gen.getLIRGeneratorTool().emitForeignCall(linkage, null, operands); if (result != null) { diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/TailcallNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/TailcallNode.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/TailcallNode.java Wed Apr 23 15:48:38 2014 +0200 @@ -24,19 +24,18 @@ import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; -import java.lang.reflect.*; import java.util.*; import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.compiler.gen.*; +import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.compiler.target.*; import com.oracle.graal.graph.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.java.*; +import com.oracle.graal.lir.gen.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.nodes.type.*; /** * Performs a tail call to the specified target compiled method, with the parameter taken from the @@ -62,7 +61,7 @@ public void generate(NodeLIRBuilderTool gen, LIRGenerationResult res) { HotSpotVMConfig config = runtime().getConfig(); ResolvedJavaMethod method = frameState.method(); - boolean isStatic = Modifier.isStatic(method.getModifiers()); + boolean isStatic = method.isStatic(); JavaType[] signature = MetaUtil.signatureToTypes(method.getSignature(), isStatic ? null : method.getDeclaringClass()); CallingConvention cc = res.getFrameMap().registerConfig.getCallingConvention(CallingConvention.Type.JavaCall, null, signature, gen.getLIRGeneratorTool().target(), false); diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/UncommonTrapCallNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/UncommonTrapCallNode.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.hotspot.nodes; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.common.type.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.hotspot.*; +import com.oracle.graal.lir.StandardOp.SaveRegistersOp; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.extended.*; +import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.word.*; + +/** + * A call to the runtime code implementing the uncommon trap logic. + */ +@NodeInfo(allowedUsageTypes = {InputType.Memory}) +public class UncommonTrapCallNode extends FixedWithNextNode implements LIRLowerable, MemoryCheckpoint.Multi { + + @Input private ValueNode trapRequest; + @Input private SaveAllRegistersNode registerSaver; + private final ForeignCallsProvider foreignCalls; + public static final ForeignCallDescriptor UNCOMMON_TRAP = new ForeignCallDescriptor("uncommonTrap", Word.class, Word.class, int.class); + + public UncommonTrapCallNode(@InjectedNodeParameter ForeignCallsProvider foreignCalls, ValueNode registerSaver, ValueNode trapRequest) { + super(StampFactory.forKind(Kind.fromJavaClass(UNCOMMON_TRAP.getResultType()))); + this.trapRequest = trapRequest; + this.registerSaver = (SaveAllRegistersNode) registerSaver; + this.foreignCalls = foreignCalls; + } + + @Override + public LocationIdentity[] getLocationIdentities() { + return foreignCalls.getKilledLocations(UNCOMMON_TRAP); + } + + public SaveRegistersOp getSaveRegistersOp() { + return registerSaver.getSaveRegistersOp(); + } + + @Override + public void generate(NodeLIRBuilderTool gen) { + Value trapRequestValue = gen.operand(trapRequest); + Value result = ((HotSpotLIRGenerator) gen.getLIRGeneratorTool()).emitUncommonTrapCall(trapRequestValue, getSaveRegistersOp()); + gen.setResult(this, result); + } + + @NodeIntrinsic + public static native Word uncommonTrap(long registerSaver, int trapRequest); + + public MemoryCheckpoint asMemoryCheckpoint() { + return null; + } + + public MemoryPhiNode asMemoryPhi() { + return null; + } +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/VMErrorNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/VMErrorNode.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/VMErrorNode.java Wed Apr 23 15:48:38 2014 +0200 @@ -27,9 +27,9 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.nodes.type.*; import com.oracle.graal.replacements.*; /** diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/WriteBarrier.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/WriteBarrier.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/WriteBarrier.java Wed Apr 23 15:48:38 2014 +0200 @@ -22,11 +22,11 @@ */ package com.oracle.graal.hotspot.nodes; +import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.nodes.type.*; public abstract class WriteBarrier extends FixedWithNextNode implements Lowerable { diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/type/NarrowOopStamp.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/type/NarrowOopStamp.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/type/NarrowOopStamp.java Wed Apr 23 15:48:38 2014 +0200 @@ -23,9 +23,9 @@ package com.oracle.graal.hotspot.nodes.type; import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.common.spi.*; +import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.hotspot.HotSpotVMConfig.CompressEncoding; -import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.nodes.type.*; public class NarrowOopStamp extends ObjectStamp { @@ -76,7 +76,7 @@ } @Override - public PlatformKind getPlatformKind(LIRTypeTool tool) { + public PlatformKind getPlatformKind(PlatformKindTool tool) { return NarrowOop; } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/AheadOfTimeVerificationPhase.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/AheadOfTimeVerificationPhase.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/AheadOfTimeVerificationPhase.java Wed Apr 23 15:48:38 2014 +0200 @@ -25,7 +25,9 @@ import static com.oracle.graal.nodes.ConstantNode.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.type.*; import com.oracle.graal.phases.*; import com.oracle.graal.phases.tiers.*; @@ -44,7 +46,7 @@ protected boolean verify(StructuredGraph graph, PhaseContext context) { for (ConstantNode node : getConstantNodes(graph)) { if (node.recordsUsages() || !node.gatherUsages(graph).isEmpty()) { - if (isObject(node) && !isNullReference(node) && !isInternedString(node)) { + if (isObject(node) && !isNullReference(node) && !isInternedString(node) && !isDirectMethodHandle(node)) { throw new VerificationError("illegal object constant: " + node); } } @@ -57,7 +59,14 @@ } private static boolean isNullReference(ConstantNode node) { - return isObject(node) && node.asConstant().asObject() == null; + return isObject(node) && node.asConstant().isNull(); + } + + private static boolean isDirectMethodHandle(ConstantNode node) { + if (!isObject(node)) { + return false; + } + return "Ljava/lang/invoke/DirectMethodHandle;".equals(StampTool.typeOrNull(node).getName()); } @SuppressFBWarnings(value = "ES_COMPARING_STRINGS_WITH_EQ", justification = "reference equality is what we want") @@ -66,7 +75,7 @@ return false; } - Object o = node.asConstant().asObject(); + Object o = HotSpotObjectConstant.asObject(node.asConstant()); if (!(o instanceof String)) { return false; } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/LoadJavaMirrorWithKlassPhase.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/LoadJavaMirrorWithKlassPhase.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/LoadJavaMirrorWithKlassPhase.java Wed Apr 23 15:48:38 2014 +0200 @@ -26,10 +26,10 @@ import static com.oracle.graal.nodes.ConstantNode.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.extended.*; -import com.oracle.graal.nodes.type.*; import com.oracle.graal.phases.*; import com.oracle.graal.phases.common.*; import com.oracle.graal.phases.tiers.*; @@ -54,9 +54,9 @@ } private FloatingReadNode getClassConstantReplacement(StructuredGraph graph, PhaseContext context, Constant constant) { - if (constant.getKind() == Kind.Object && constant.asObject() instanceof Class) { + if (constant.getKind() == Kind.Object && HotSpotObjectConstant.asObject(constant) instanceof Class) { MetaAccessProvider metaAccess = context.getMetaAccess(); - ResolvedJavaType type = metaAccess.lookupJavaType((Class) constant.asObject()); + ResolvedJavaType type = metaAccess.lookupJavaType((Class) HotSpotObjectConstant.asObject(constant)); assert type instanceof HotSpotResolvedObjectType; Constant klass = ((HotSpotResolvedObjectType) type).klass(); diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/OnStackReplacementPhase.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/OnStackReplacementPhase.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/OnStackReplacementPhase.java Wed Apr 23 15:48:38 2014 +0200 @@ -23,6 +23,7 @@ package com.oracle.graal.hotspot.phases; import com.oracle.graal.api.code.*; +import com.oracle.graal.compiler.common.*; import com.oracle.graal.debug.*; import com.oracle.graal.graph.*; import com.oracle.graal.graph.Node.Verbosity; diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/WriteBarrierAdditionPhase.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/WriteBarrierAdditionPhase.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/WriteBarrierAdditionPhase.java Wed Apr 23 15:48:38 2014 +0200 @@ -75,12 +75,12 @@ } protected void addG1PostWriteBarrier(FixedAccessNode node, ValueNode object, ValueNode value, LocationNode location, boolean precise, StructuredGraph graph) { - final boolean alwaysNull = ObjectStamp.isObjectAlwaysNull(value); + final boolean alwaysNull = StampTool.isObjectAlwaysNull(value); graph.addAfterFixed(node, graph.add(new G1PostWriteBarrier(object, value, location, precise, alwaysNull))); } protected void addSerialPostWriteBarrier(FixedAccessNode node, ValueNode object, ValueNode value, LocationNode location, boolean precise, StructuredGraph graph) { - final boolean alwaysNull = ObjectStamp.isObjectAlwaysNull(value); + final boolean alwaysNull = StampTool.isObjectAlwaysNull(value); final LocationNode loc = (precise ? location : null); graph.addAfterFixed(node, graph.add(new SerialWriteBarrier(object, loc, precise, alwaysNull))); } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/AESCryptSubstitutions.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/AESCryptSubstitutions.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/AESCryptSubstitutions.java Wed Apr 23 15:48:38 2014 +0200 @@ -27,7 +27,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.api.replacements.*; -import com.oracle.graal.graph.*; +import com.oracle.graal.compiler.common.*; import com.oracle.graal.graph.Node.ConstantNodeParameter; import com.oracle.graal.graph.Node.NodeIntrinsic; import com.oracle.graal.hotspot.*; diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/AbstractMethodHandleNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/AbstractMethodHandleNode.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/AbstractMethodHandleNode.java Wed Apr 23 15:48:38 2014 +0200 @@ -22,10 +22,11 @@ */ package com.oracle.graal.hotspot.replacements; -import java.lang.reflect.*; import java.util.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.common.*; +import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; import com.oracle.graal.hotspot.meta.*; @@ -52,7 +53,7 @@ /** * Search for an instance field with the given name in a class. - * + * * @param className name of the class to search in * @param fieldName name of the field to be searched * @return resolved java field @@ -99,7 +100,7 @@ /** * Get the receiver of a MethodHandle.invokeBasic call. - * + * * @return the receiver argument node */ private ValueNode getReceiver() { @@ -108,7 +109,7 @@ /** * Get the MemberName argument of a MethodHandle.linkTo* call. - * + * * @return the MemberName argument node (which is the last argument) */ private ValueNode getMemberName() { @@ -118,7 +119,7 @@ /** * Used from {@link MethodHandleInvokeBasicNode} to get the target {@link InvokeNode} if the * method handle receiver is constant. - * + * * @return invoke node for the {@link java.lang.invoke.MethodHandle} target */ protected InvokeNode getInvokeBasicTarget() { @@ -137,7 +138,7 @@ * Used from {@link MethodHandleLinkToStaticNode}, {@link MethodHandleLinkToSpecialNode}, * {@link MethodHandleLinkToVirtualNode}, and {@link MethodHandleLinkToInterfaceNode} to get the * target {@link InvokeNode} if the member name argument is constant. - * + * * @return invoke node for the member name target */ protected InvokeNode getLinkToTarget() { @@ -152,7 +153,7 @@ /** * Helper function to get the {@link InvokeNode} for the vmtarget of a * java.lang.invoke.MemberName. - * + * * @param memberName constant member name node * @return invoke node for the member name target */ @@ -162,7 +163,7 @@ Constant vmtarget = memberNameVmtargetField.readValue(memberName); // Create a method from the vmtarget pointer - Class c = (Class) clazz.asObject(); + Class c = (Class) HotSpotObjectConstant.asObject(clazz); HotSpotResolvedObjectType holderClass = (HotSpotResolvedObjectType) HotSpotResolvedObjectType.fromClass(c); HotSpotResolvedJavaMethod targetMethod = HotSpotResolvedJavaMethod.fromMetaspace(vmtarget.asLong()); @@ -171,7 +172,7 @@ // to a direct call we must cast the receiver and arguments to its // actual types. HotSpotSignature signature = targetMethod.getSignature(); - final boolean isStatic = Modifier.isStatic(targetMethod.getModifiers()); + final boolean isStatic = targetMethod.isStatic(); final int receiverSkip = isStatic ? 0 : 1; // Cast receiver to its type. @@ -188,7 +189,7 @@ // Try to get the most accurate receiver type if (this instanceof MethodHandleLinkToVirtualNode || this instanceof MethodHandleLinkToInterfaceNode) { - ResolvedJavaType receiverType = ObjectStamp.typeOrNull(getReceiver().stamp()); + ResolvedJavaType receiverType = StampTool.typeOrNull(getReceiver().stamp()); if (receiverType != null) { ResolvedJavaMethod concreteMethod = receiverType.findUniqueConcreteMethod(targetMethod); if (concreteMethod != null) { @@ -212,7 +213,7 @@ /** * Inserts a node to cast the argument at index to the given type if the given type is more * concrete than the argument type. - * + * * @param index of the argument to be cast * @param type the type the argument should be cast to */ @@ -221,7 +222,7 @@ ResolvedJavaType targetType = (ResolvedJavaType) type; if (!targetType.isPrimitive()) { ValueNode argument = arguments.get(index); - ResolvedJavaType argumentType = ObjectStamp.typeOrNull(argument.stamp()); + ResolvedJavaType argumentType = StampTool.typeOrNull(argument.stamp()); if (argumentType == null || (argumentType.isAssignableFrom(targetType) && !argumentType.equals(targetType))) { PiNode piNode = graph().unique(new PiNode(argument, StampFactory.declared(targetType))); arguments.set(index, piNode); @@ -233,12 +234,12 @@ /** * Creates an {@link InvokeNode} for the given target method. The {@link CallTargetNode} passed * to the InvokeNode is in fact a {@link SelfReplacingMethodCallTargetNode}. - * + * * @param targetMethod the method the be called * @return invoke node for the member name target */ private InvokeNode createTargetInvokeNode(ResolvedJavaMethod targetMethod) { - InvokeKind invokeKind = Modifier.isStatic(targetMethod.getModifiers()) ? InvokeKind.Static : InvokeKind.Special; + InvokeKind invokeKind = targetMethod.isStatic() ? InvokeKind.Static : InvokeKind.Special; JavaType returnType = targetMethod.getSignature().getReturnType(null); // MethodHandleLinkTo* nodes have a trailing MemberName argument which diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopyCallNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopyCallNode.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopyCallNode.java Wed Apr 23 15:48:38 2014 +0200 @@ -27,6 +27,8 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.api.runtime.*; +import com.oracle.graal.compiler.common.*; +import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.graph.*; import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.hotspot.nodes.*; @@ -34,8 +36,6 @@ import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.nodes.type.*; -import com.oracle.graal.phases.*; import com.oracle.graal.replacements.SnippetTemplate.Arguments; import com.oracle.graal.runtime.*; diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopyNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopyNode.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopyNode.java Wed Apr 23 15:48:38 2014 +0200 @@ -26,6 +26,7 @@ import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.common.*; import com.oracle.graal.debug.*; import com.oracle.graal.debug.Debug.Scope; import com.oracle.graal.loop.phases.*; @@ -33,7 +34,6 @@ import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; import com.oracle.graal.nodes.virtual.*; -import com.oracle.graal.phases.*; import com.oracle.graal.phases.common.*; import com.oracle.graal.phases.tiers.*; import com.oracle.graal.replacements.nodes.*; @@ -69,8 +69,8 @@ } private StructuredGraph selectSnippet(LoweringTool tool, final Replacements replacements) { - ResolvedJavaType srcType = ObjectStamp.typeOrNull(getSource().stamp()); - ResolvedJavaType destType = ObjectStamp.typeOrNull(getDestination().stamp()); + ResolvedJavaType srcType = StampTool.typeOrNull(getSource().stamp()); + ResolvedJavaType destType = StampTool.typeOrNull(getDestination().stamp()); if (srcType == null || !srcType.isArray() || destType == null || !destType.isArray()) { return null; @@ -143,13 +143,13 @@ * Returns true if this copy doesn't require store checks. Trivially true for primitive arrays. */ private boolean isExact() { - ResolvedJavaType srcType = ObjectStamp.typeOrNull(getSource().stamp()); + ResolvedJavaType srcType = StampTool.typeOrNull(getSource().stamp()); if (srcType.getComponentType().getKind().isPrimitive() || getSource() == getDestination()) { return true; } - ResolvedJavaType destType = ObjectStamp.typeOrNull(getDestination().stamp()); - if (ObjectStamp.isExactType(getDestination().stamp())) { + ResolvedJavaType destType = StampTool.typeOrNull(getDestination().stamp()); + if (StampTool.isExactType(getDestination().stamp())) { if (destType != null && destType.isAssignableFrom(srcType)) { return true; } @@ -171,10 +171,10 @@ if (state.getState() == EscapeState.Virtual) { type = state.getVirtualObject().type(); } else { - type = ObjectStamp.typeOrNull(state.getMaterializedValue()); + type = StampTool.typeOrNull(state.getMaterializedValue()); } } else { - type = ObjectStamp.typeOrNull(entry); + type = StampTool.typeOrNull(entry); } if (type == null || !destComponentType.isAssignableFrom(type)) { return false; diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopySnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopySnippets.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopySnippets.java Wed Apr 23 15:48:38 2014 +0200 @@ -22,16 +22,16 @@ */ package com.oracle.graal.hotspot.replacements; +import static com.oracle.graal.compiler.common.GraalOptions.*; import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*; import static com.oracle.graal.nodes.GuardingPiNode.*; import static com.oracle.graal.nodes.extended.BranchProbabilityNode.*; -import static com.oracle.graal.phases.GraalOptions.*; import java.lang.reflect.*; import java.util.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.graph.*; +import com.oracle.graal.compiler.common.*; import com.oracle.graal.graph.Node.ConstantNodeParameter; import com.oracle.graal.graph.Node.NodeIntrinsic; import com.oracle.graal.nodes.*; diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CallSiteTargetNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CallSiteTargetNode.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CallSiteTargetNode.java Wed Apr 23 15:48:38 2014 +0200 @@ -28,6 +28,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; +import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.replacements.nodes.*; @@ -44,7 +45,7 @@ private ConstantNode getConstantCallTarget(MetaAccessProvider metaAccess, Assumptions assumptions) { if (getCallSite().isConstant() && !getCallSite().isNullConstant()) { - CallSite callSite = (CallSite) getCallSite().asConstant().asObject(); + CallSite callSite = (CallSite) HotSpotObjectConstant.asObject(getCallSite().asConstant()); MethodHandle target = callSite.getTarget(); if (!(callSite instanceof ConstantCallSite)) { if (assumptions == null || !assumptions.useOptimisticAssumptions()) { @@ -52,7 +53,7 @@ } assumptions.record(new Assumptions.CallSiteTargetValue(callSite, target)); } - return ConstantNode.forObject(target, metaAccess, graph()); + return ConstantNode.forConstant(HotSpotObjectConstant.forObject(target), metaAccess, graph()); } return null; } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CheckCastDynamicSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CheckCastDynamicSnippets.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CheckCastDynamicSnippets.java Wed Apr 23 15:48:38 2014 +0200 @@ -31,14 +31,14 @@ import static com.oracle.graal.replacements.SnippetTemplate.*; import com.oracle.graal.api.code.*; +import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.debug.*; +import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.hotspot.nodes.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.nodes.type.*; -import com.oracle.graal.phases.util.*; import com.oracle.graal.replacements.*; import com.oracle.graal.replacements.SnippetTemplate.AbstractTemplates; import com.oracle.graal.replacements.SnippetTemplate.Arguments; @@ -69,8 +69,8 @@ private final SnippetInfo dynamic = snippet(CheckCastDynamicSnippets.class, "checkcastDynamic"); - public Templates(Providers providers, TargetDescription target) { - super(providers, target); + public Templates(HotSpotProviders providers, TargetDescription target) { + super(providers, providers.getSnippetReflection(), target); } public void lower(CheckCastDynamicNode checkcast, LoweringTool tool) { diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CipherBlockChainingSubstitutions.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CipherBlockChainingSubstitutions.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CipherBlockChainingSubstitutions.java Wed Apr 23 15:48:38 2014 +0200 @@ -27,7 +27,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.api.replacements.*; -import com.oracle.graal.graph.*; +import com.oracle.graal.compiler.common.*; import com.oracle.graal.graph.Node.ConstantNodeParameter; import com.oracle.graal.graph.Node.NodeIntrinsic; import com.oracle.graal.hotspot.nodes.*; @@ -63,35 +63,12 @@ } @Fold - private static Class getAESCryptClass() { + private static Class getAESCryptClass() { return AESCryptSubstitutions.AESCryptClass; } - @MethodSubstitution(isStatic = false, optional = true) - static void encrypt(Object rcvr, byte[] in, int inOffset, int inLength, byte[] out, int outOffset) { - Object embeddedCipher = UnsafeLoadNode.load(rcvr, embeddedCipherOffset, Kind.Object, LocationIdentity.ANY_LOCATION); - if (getAESCryptClass().isInstance(embeddedCipher)) { - Object aesCipher = PiNode.piCastNonNull(embeddedCipher, AESCryptSubstitutions.AESCryptClass); - crypt(rcvr, in, inOffset, inLength, out, outOffset, aesCipher, true); - } else { - encrypt(rcvr, in, inOffset, inLength, out, outOffset); - } - } - - @MethodSubstitution(isStatic = false, optional = true) - static void decrypt(Object rcvr, byte[] in, int inOffset, int inLength, byte[] out, int outOffset) { - Object realReceiver = PiNode.piCastNonNull(rcvr, cipherBlockChainingClass); - Object embeddedCipher = UnsafeLoadNode.load(realReceiver, embeddedCipherOffset, Kind.Object, LocationIdentity.ANY_LOCATION); - if (in != out && getAESCryptClass().isInstance(embeddedCipher)) { - Object aesCipher = PiNode.piCastNonNull(embeddedCipher, AESCryptSubstitutions.AESCryptClass); - crypt(realReceiver, in, inOffset, inLength, out, outOffset, aesCipher, false); - } else { - decrypt(realReceiver, in, inOffset, inLength, out, outOffset); - } - } - - @MethodSubstitution(value = "encrypt", isStatic = false, optional = true) - static int encryptInt(Object rcvr, byte[] in, int inOffset, int inLength, byte[] out, int outOffset) { + @MethodSubstitution(isStatic = false) + static int encrypt(Object rcvr, byte[] in, int inOffset, int inLength, byte[] out, int outOffset) { Object realReceiver = PiNode.piCastNonNull(rcvr, cipherBlockChainingClass); Object embeddedCipher = UnsafeLoadNode.load(realReceiver, embeddedCipherOffset, Kind.Object, LocationIdentity.ANY_LOCATION); if (getAESCryptClass().isInstance(embeddedCipher)) { @@ -99,12 +76,12 @@ crypt(realReceiver, in, inOffset, inLength, out, outOffset, aesCipher, true); return inLength; } else { - return encryptInt(realReceiver, in, inOffset, inLength, out, outOffset); + return encrypt(realReceiver, in, inOffset, inLength, out, outOffset); } } - @MethodSubstitution(value = "decrypt", isStatic = false, optional = true) - static int decryptInt(Object rcvr, byte[] in, int inOffset, int inLength, byte[] out, int outOffset) { + @MethodSubstitution(isStatic = false) + static int decrypt(Object rcvr, byte[] in, int inOffset, int inLength, byte[] out, int outOffset) { Object realReceiver = PiNode.piCastNonNull(rcvr, cipherBlockChainingClass); Object embeddedCipher = UnsafeLoadNode.load(realReceiver, embeddedCipherOffset, Kind.Object, LocationIdentity.ANY_LOCATION); if (in != out && getAESCryptClass().isInstance(embeddedCipher)) { @@ -112,7 +89,7 @@ crypt(realReceiver, in, inOffset, inLength, out, outOffset, aesCipher, false); return inLength; } else { - return decryptInt(realReceiver, in, inOffset, inLength, out, outOffset); + return decrypt(realReceiver, in, inOffset, inLength, out, outOffset); } } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CompositeValueClassSubstitutions.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CompositeValueClassSubstitutions.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,64 @@ +/* + * 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.replacements; + +import static com.oracle.graal.compiler.common.GraalOptions.*; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.api.replacements.*; +import com.oracle.graal.hotspot.meta.*; +import com.oracle.graal.lir.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.replacements.nodes.*; + +/** + * Substitutions for improving the performance of {@link CompositeValueClass#getClass()}. + */ +@ClassSubstitution(CompositeValueClass.class) +public class CompositeValueClassSubstitutions { + + /** + * A macro node for calls to {@link CompositeValueClass#get(Class)}. It can use the compiler's + * knowledge about node classes to replace itself with a constant value for a constant + * {@link Class} parameter. + */ + public static class CompositeValueClassGetNode extends PureFunctionMacroNode { + + public CompositeValueClassGetNode(Invoke invoke) { + super(invoke); + } + + @SuppressWarnings("unchecked") + @Override + protected Constant evaluate(Constant param, MetaAccessProvider metaAccess) { + if (param.isNull() || ImmutableCode.getValue()) { + return null; + } + return HotSpotObjectConstant.forObject(CompositeValueClass.get((Class) HotSpotObjectConstant.asObject(param))); + } + } + + @MacroSubstitution(isStatic = true, forced = true, macro = CompositeValueClassGetNode.class) + private static native CompositeValueClass get(Class c); +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotNodeClassSubstitutions.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotNodeClassSubstitutions.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,69 @@ +/* + * 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.replacements; + +import static com.oracle.graal.compiler.common.GraalOptions.*; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.api.replacements.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.hotspot.meta.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.replacements.nodes.*; + +/** + * Substitutions for improving the performance of {@link NodeClass#get}. + */ +@ClassSubstitution(NodeClass.class) +public class HotSpotNodeClassSubstitutions { + + /** + * A macro node for calls to {@link NodeClass#get(Class)}. It can use the compiler's knowledge + * about node classes to replace itself with a constant value for a constant {@link Class} + * parameter. + */ + public static class NodeClassGetNode extends PureFunctionMacroNode { + + public NodeClassGetNode(Invoke invoke) { + super(invoke); + } + + @Override + protected Constant evaluate(Constant param, MetaAccessProvider metaAccess) { + if (param.isNull() || ImmutableCode.getValue()) { + return null; + } + return HotSpotObjectConstant.forObject(NodeClass.get((Class) HotSpotObjectConstant.asObject(param))); + } + } + + /** + * NOTE: A {@link MethodSubstitution} similar to + * {@link HotSpotNodeSubstitutions#getNodeClass(Node)} is not possible here because there is no + * guarantee that {@code c} is initialized (accessing a Class literal in Java is not a class + * initialization barrier). + */ + @MacroSubstitution(isStatic = true, forced = true, macro = NodeClassGetNode.class) + public static native NodeClass get(Class c); +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotNodeSubstitutions.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotNodeSubstitutions.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,47 @@ +/* + * 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.replacements; + +import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*; +import static com.oracle.graal.nodes.PiNode.*; + +import com.oracle.graal.api.replacements.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.word.*; + +@ClassSubstitution(Node.class) +public class HotSpotNodeSubstitutions { + + /** + * Gets the value of the {@code InstanceKlass::_graal_node_class} field from the InstanceKlass + * pointed to by {@code node}'s header. + */ + @MethodSubstitution(isStatic = false) + public static NodeClass getNodeClass(final Node node) { + // HotSpot creates the NodeClass for each Node subclass while initializing it + // so we are guaranteed to read a non-null value here. As long as NodeClass + // is final, the stamp of the PiNode below will automatically be exact. + Word klass = loadHub(node); + return piCastNonNull(klass.readObject(Word.signed(klassNodeClassOffset()), KLASS_NODE_CLASS), NodeClass.class); + } +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotReplacementsUtil.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotReplacementsUtil.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotReplacementsUtil.java Wed Apr 23 15:48:38 2014 +0200 @@ -22,7 +22,7 @@ */ package com.oracle.graal.hotspot.replacements; -import static com.oracle.graal.graph.UnsafeAccess.*; +import static com.oracle.graal.compiler.common.UnsafeAccess.*; import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; import static com.oracle.graal.hotspot.meta.HotSpotForeignCallsProviderImpl.*; import static com.oracle.graal.nodes.extended.BranchProbabilityNode.*; @@ -30,7 +30,7 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.graph.*; +import com.oracle.graal.compiler.common.*; import com.oracle.graal.graph.Node.ConstantNodeParameter; import com.oracle.graal.graph.Node.NodeIntrinsic; import com.oracle.graal.hotspot.*; @@ -80,6 +80,20 @@ return config().threadExceptionPcOffset; } + public static final LocationIdentity LAST_JAVA_PC_LOCATION = new NamedLocationIdentity("LastJavaPc"); + + @Fold + public static int threadLastJavaPcOffset() { + return config().threadLastJavaPcOffset(); + } + + public static final LocationIdentity LAST_JAVA_FP_LOCATION = new NamedLocationIdentity("LastJavaFp"); + + @Fold + public static int threadLastJavaFpOffset() { + return config().threadLastJavaFpOffset(); + } + public static final LocationIdentity TLAB_TOP_LOCATION = new NamedLocationIdentity("TlabTop"); @Fold @@ -111,6 +125,16 @@ return config().pendingExceptionOffset; } + public static final LocationIdentity PENDING_DEOPTIMIZATION_LOCATION = new NamedLocationIdentity("PendingDeoptimization"); + + /** + * @see HotSpotVMConfig#pendingDeoptimizationOffset + */ + @Fold + private static int threadPendingDeoptimizationOffset() { + return config().pendingDeoptimizationOffset; + } + public static final LocationIdentity OBJECT_RESULT_LOCATION = new NamedLocationIdentity("ObjectResult"); @Fold @@ -140,6 +164,14 @@ thread.writeWord(threadExceptionPcOffset(), value, EXCEPTION_PC_LOCATION); } + public static void writeLastJavaPc(Word thread, Word value) { + thread.writeWord(threadLastJavaPcOffset(), value, LAST_JAVA_PC_LOCATION); + } + + public static void writeLastJavaFp(Word thread, Word value) { + thread.writeWord(threadLastJavaFpOffset(), value, LAST_JAVA_FP_LOCATION); + } + public static Word readTlabTop(Word thread) { return thread.readWord(threadTlabTopOffset(), TLAB_TOP_LOCATION); } @@ -174,6 +206,22 @@ } /** + * Reads the pending deoptimization value for the given thread. + * + * @return {@code true} if there was a pending deoptimization + */ + public static int readPendingDeoptimization(Word thread) { + return thread.readInt(threadPendingDeoptimizationOffset(), PENDING_DEOPTIMIZATION_LOCATION); + } + + /** + * Writes the pending deoptimization value for the given thread. + */ + public static void writePendingDeoptimization(Word thread, int value) { + thread.writeInt(threadPendingDeoptimizationOffset(), value, PENDING_DEOPTIMIZATION_LOCATION); + } + + /** * Gets and clears the object result from a runtime call stored in a thread local. * * @return the object that was in the thread local @@ -498,6 +546,9 @@ @NodeIntrinsic(value = ReadRegisterNode.class, setStampFromReturnType = true) public static native Word registerAsWord(@ConstantNodeParameter Register register, @ConstantNodeParameter boolean directUse, @ConstantNodeParameter boolean incoming); + @NodeIntrinsic(value = WriteRegisterNode.class, setStampFromReturnType = true) + public static native void writeRegisterAsWord(@ConstantNodeParameter Register register, Word value); + @SuppressWarnings("unused") @NodeIntrinsic(value = UnsafeLoadNode.class, setStampFromReturnType = true) private static Word loadWordFromObjectIntrinsic(Object object, long offset, @ConstantNodeParameter Kind wordKind, @ConstantNodeParameter LocationIdentity locationIdentity) { @@ -556,6 +607,13 @@ return config().arrayKlassOffset; } + public static final LocationIdentity KLASS_NODE_CLASS = new NamedLocationIdentity("KlassNodeClass"); + + @Fold + public static int klassNodeClassOffset() { + return config().klassNodeClassOffset; + } + @Fold public static int classMirrorOffset() { return config().classMirrorOffset; diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotSubstitutions.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotSubstitutions.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotSubstitutions.java Wed Apr 23 15:48:38 2014 +0200 @@ -42,5 +42,8 @@ replacements.registerSubstitutions(CipherBlockChainingSubstitutions.class); replacements.registerSubstitutions(CRC32Substitutions.class); replacements.registerSubstitutions(ReflectionSubstitutions.class); + replacements.registerSubstitutions(HotSpotNodeClassSubstitutions.class); + replacements.registerSubstitutions(HotSpotNodeSubstitutions.class); + replacements.registerSubstitutions(CompositeValueClassSubstitutions.class); } } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/InstanceOfSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/InstanceOfSnippets.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/InstanceOfSnippets.java Wed Apr 23 15:48:38 2014 +0200 @@ -33,6 +33,7 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.api.meta.ProfilingInfo.TriState; +import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.hotspot.nodes.*; import com.oracle.graal.hotspot.replacements.TypeCheckSnippetUtils.Hints; @@ -40,9 +41,7 @@ import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.nodes.type.*; import com.oracle.graal.options.*; -import com.oracle.graal.phases.util.*; import com.oracle.graal.replacements.*; import com.oracle.graal.replacements.Snippet.ConstantParameter; import com.oracle.graal.replacements.Snippet.VarargsParameter; @@ -181,7 +180,7 @@ * Type test used when the type being tested against is not known at compile time. */ @Snippet - public static Object instanceofDynamic(Class mirror, Object object, Object trueValue, Object falseValue) { + public static Object instanceofDynamic(Class mirror, Object object, Object trueValue, Object falseValue) { if (probability(NOT_FREQUENT_PROBABILITY, object == null)) { isNull.inc(); return falseValue; @@ -216,8 +215,8 @@ private final SnippetInfo instanceofSecondary = snippet(InstanceOfSnippets.class, "instanceofSecondary"); private final SnippetInfo instanceofDynamic = snippet(InstanceOfSnippets.class, "instanceofDynamic"); - public Templates(Providers providers, TargetDescription target) { - super(providers, target); + public Templates(HotSpotProviders providers, TargetDescription target) { + super(providers, providers.getSnippetReflection(), target); } @Override diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/LoadExceptionObjectSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/LoadExceptionObjectSnippets.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/LoadExceptionObjectSnippets.java Wed Apr 23 15:48:38 2014 +0200 @@ -28,12 +28,12 @@ import static com.oracle.graal.replacements.SnippetTemplate.*; import com.oracle.graal.api.code.*; +import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.nodes.type.*; import com.oracle.graal.replacements.*; import com.oracle.graal.replacements.Snippet.ConstantParameter; import com.oracle.graal.replacements.SnippetTemplate.AbstractTemplates; @@ -66,7 +66,7 @@ private final SnippetInfo loadException = snippet(LoadExceptionObjectSnippets.class, "loadException"); public Templates(HotSpotProviders providers, TargetDescription target) { - super(providers, target); + super(providers, providers.getSnippetReflection(), target); } public void lower(LoadExceptionObjectNode loadExceptionObject, HotSpotRegistersProvider registers, LoweringTool tool) { diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MonitorSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MonitorSnippets.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MonitorSnippets.java Wed Apr 23 15:48:38 2014 +0200 @@ -48,7 +48,6 @@ import com.oracle.graal.nodes.type.*; import com.oracle.graal.options.*; import com.oracle.graal.phases.common.*; -import com.oracle.graal.phases.util.*; import com.oracle.graal.replacements.*; import com.oracle.graal.replacements.Snippet.ConstantParameter; import com.oracle.graal.replacements.Snippet.Fold; @@ -417,8 +416,8 @@ private final boolean useFastLocking; - public Templates(Providers providers, TargetDescription target, boolean useFastLocking) { - super(providers, target); + public Templates(HotSpotProviders providers, TargetDescription target, boolean useFastLocking) { + super(providers, providers.getSnippetReflection(), target); this.useFastLocking = useFastLocking; } @@ -458,7 +457,7 @@ } static boolean isTracingEnabledForType(ValueNode object) { - ResolvedJavaType type = ObjectStamp.typeOrNull(object.stamp()); + ResolvedJavaType type = StampTool.typeOrNull(object.stamp()); if (TRACE_TYPE_FILTER == null) { return false; } else { @@ -508,11 +507,11 @@ for (ReturnNode ret : rets) { returnType = checkCounter.getMethod().getSignature().getReturnType(checkCounter.getMethod().getDeclaringClass()); String msg = "unbalanced monitors in " + MetaUtil.format("%H.%n(%p)", graph.method()) + ", count = %d"; - ConstantNode errMsg = ConstantNode.forObject(msg, providers.getMetaAccess(), graph); + ConstantNode errMsg = ConstantNode.forConstant(HotSpotObjectConstant.forObject(msg), providers.getMetaAccess(), graph); callTarget = graph.add(new MethodCallTargetNode(InvokeKind.Static, checkCounter.getMethod(), new ValueNode[]{errMsg}, returnType)); invoke = graph.add(new InvokeNode(callTarget, 0)); List stack = Collections.emptyList(); - FrameState stateAfter = new FrameState(graph.method(), FrameState.AFTER_BCI, new ValueNode[0], stack, new ValueNode[0], new MonitorIdNode[0], false, false); + FrameState stateAfter = new FrameState(graph.method(), BytecodeFrame.AFTER_BCI, new ValueNode[0], stack, new ValueNode[0], new MonitorIdNode[0], false, false); invoke.setStateAfter(graph.add(stateAfter)); graph.addBeforeFixed(ret, invoke); diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippets.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippets.java Wed Apr 23 15:48:38 2014 +0200 @@ -24,18 +24,19 @@ import static com.oracle.graal.api.code.UnsignedMath.*; import static com.oracle.graal.api.meta.MetaUtil.*; +import static com.oracle.graal.compiler.common.GraalOptions.*; import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*; import static com.oracle.graal.hotspot.replacements.NewObjectSnippets.Options.*; import static com.oracle.graal.nodes.PiArrayNode.*; import static com.oracle.graal.nodes.extended.BranchProbabilityNode.*; -import static com.oracle.graal.phases.GraalOptions.*; import static com.oracle.graal.replacements.SnippetTemplate.*; import static com.oracle.graal.replacements.nodes.ExplodeLoopNode.*; import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.common.*; +import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.debug.*; -import com.oracle.graal.graph.*; import com.oracle.graal.graph.Node.ConstantNodeParameter; import com.oracle.graal.graph.Node.NodeIntrinsic; import com.oracle.graal.hotspot.*; @@ -46,9 +47,7 @@ import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.nodes.type.*; import com.oracle.graal.options.*; -import com.oracle.graal.phases.util.*; import com.oracle.graal.replacements.*; import com.oracle.graal.replacements.Snippet.ConstantParameter; import com.oracle.graal.replacements.Snippet.Fold; @@ -106,7 +105,7 @@ return ProfileAllocations.getValue(); } - private static void profileAllocation(String path, long size, String typeContext) { + protected static void profileAllocation(String path, long size, String typeContext) { if (doProfile()) { String name = createName(path, typeContext); @@ -348,7 +347,7 @@ /** * Formats some allocated memory with an object header and zeroes out the rest. */ - private static Object formatObject(Word hub, int size, Word memory, Word compileTimePrototypeMarkWord, boolean fillContents, boolean constantSize, boolean noAsserts, boolean useSnippetCounters) { + protected static Object formatObject(Word hub, int size, Word memory, Word compileTimePrototypeMarkWord, boolean fillContents, boolean constantSize, boolean noAsserts, boolean useSnippetCounters) { Word prototypeMarkWord = useBiasedLocking() ? hub.readWord(prototypeMarkWordOffset(), PROTOTYPE_MARK_WORD_LOCATION) : compileTimePrototypeMarkWord; initializeObjectHeader(memory, prototypeMarkWord, hub); if (fillContents) { @@ -382,8 +381,8 @@ private final SnippetInfo allocateInstanceDynamic = snippet(NewObjectSnippets.class, "allocateInstanceDynamic"); private final SnippetInfo newmultiarray = snippet(NewObjectSnippets.class, "newmultiarray"); - public Templates(Providers providers, TargetDescription target) { - super(providers, target); + public Templates(HotSpotProviders providers, TargetDescription target) { + super(providers, providers.getSnippetReflection(), target); } /** diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectCloneNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectCloneNode.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectCloneNode.java Wed Apr 23 15:48:38 2014 +0200 @@ -29,6 +29,7 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.debug.*; import com.oracle.graal.debug.Debug.Scope; import com.oracle.graal.nodes.*; @@ -59,7 +60,7 @@ return null; } - ResolvedJavaType type = ObjectStamp.typeOrNull(getObject()); + ResolvedJavaType type = StampTool.typeOrNull(getObject()); if (type != null) { if (type.isArray()) { Method method = ObjectCloneSnippets.arrayCloneMethods.get(type.getComponentType().getKind()); @@ -105,7 +106,7 @@ /* * Looks at the given stamp and determines if it is an exact type (or can be assumed to be an * exact type) and if it is a cloneable type. - * + * * If yes, then the exact type is returned, otherwise it returns null. */ private static ResolvedJavaType getConcreteType(Stamp stamp, Assumptions assumptions, MetaAccessProvider metaAccess) { diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectCloneSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectCloneSnippets.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectCloneSnippets.java Wed Apr 23 15:48:38 2014 +0200 @@ -26,7 +26,7 @@ import java.util.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.graph.*; +import com.oracle.graal.compiler.common.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.java.*; import com.oracle.graal.replacements.*; diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectGetClassNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectGetClassNode.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectGetClassNode.java Wed Apr 23 15:48:38 2014 +0200 @@ -22,7 +22,7 @@ */ package com.oracle.graal.hotspot.replacements; -import static com.oracle.graal.phases.GraalOptions.*; +import static com.oracle.graal.compiler.common.GraalOptions.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.api.meta.ResolvedJavaType.Representation; @@ -67,13 +67,10 @@ if (usages().isEmpty()) { return null; } else { - Stamp stamp = getObject().stamp(); - if (stamp instanceof ObjectStamp) { - ObjectStamp objectStamp = (ObjectStamp) stamp; - if (objectStamp.isExactType()) { - Constant clazz = objectStamp.type().getEncoding(Representation.JavaClass); - return ConstantNode.forConstant(clazz, tool.getMetaAccess(), graph()); - } + if (StampTool.isExactType(getObject())) { + ResolvedJavaType type = StampTool.typeOrNull(getObject()); + Constant clazz = type.getEncoding(Representation.JavaClass); + return ConstantNode.forConstant(clazz, tool.getMetaAccess(), graph()); } return this; } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ReflectionGetCallerClassNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ReflectionGetCallerClassNode.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ReflectionGetCallerClassNode.java Wed Apr 23 15:48:38 2014 +0200 @@ -25,6 +25,7 @@ import static com.oracle.graal.compiler.GraalCompiler.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.common.*; import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; import com.oracle.graal.hotspot.meta.*; @@ -93,7 +94,7 @@ if (!method.ignoredBySecurityStackWalk()) { // We have reached the desired frame; return the holder class. HotSpotResolvedObjectType callerClass = method.getDeclaringClass(); - return ConstantNode.forObject(callerClass.mirror(), metaAccess, graph()); + return ConstantNode.forConstant(HotSpotObjectConstant.forObject(callerClass.mirror()), metaAccess, graph()); } break; } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/SystemIdentityHashCodeNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/SystemIdentityHashCodeNode.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/SystemIdentityHashCodeNode.java Wed Apr 23 15:48:38 2014 +0200 @@ -22,9 +22,10 @@ */ package com.oracle.graal.hotspot.replacements; -import static com.oracle.graal.phases.GraalOptions.*; +import static com.oracle.graal.compiler.common.GraalOptions.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.nodes.*; import com.oracle.graal.replacements.nodes.*; @@ -36,6 +37,6 @@ @Override protected Constant evaluate(Constant param, MetaAccessProvider metaAccess) { - return ImmutableCode.getValue() || param.isNull() ? null : Constant.forInt(System.identityHashCode(param.asObject())); + return ImmutableCode.getValue() || param.isNull() ? null : Constant.forInt(System.identityHashCode(HotSpotObjectConstant.asObject(param))); } } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ThreadSubstitutions.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ThreadSubstitutions.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ThreadSubstitutions.java Wed Apr 23 15:48:38 2014 +0200 @@ -29,7 +29,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.api.replacements.*; -import com.oracle.graal.graph.*; +import com.oracle.graal.compiler.common.*; import com.oracle.graal.graph.Node.ConstantNodeParameter; import com.oracle.graal.graph.Node.NodeIntrinsic; import com.oracle.graal.hotspot.nodes.*; diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/TypeCheckSnippetUtils.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/TypeCheckSnippetUtils.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/TypeCheckSnippetUtils.java Wed Apr 23 15:48:38 2014 +0200 @@ -22,9 +22,9 @@ */ package com.oracle.graal.hotspot.replacements; +import static com.oracle.graal.compiler.common.GraalOptions.*; import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*; import static com.oracle.graal.nodes.extended.BranchProbabilityNode.*; -import static com.oracle.graal.phases.GraalOptions.*; import java.util.*; diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/UnsafeArrayCopyNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/UnsafeArrayCopyNode.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/UnsafeArrayCopyNode.java Wed Apr 23 15:48:38 2014 +0200 @@ -25,11 +25,11 @@ import static com.oracle.graal.api.meta.LocationIdentity.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.nodes.type.*; import com.oracle.graal.replacements.SnippetTemplate.Arguments; @NodeInfo(allowedUsageTypes = {InputType.Memory}) diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/UnsafeArrayCopySnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/UnsafeArrayCopySnippets.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/UnsafeArrayCopySnippets.java Wed Apr 23 15:48:38 2014 +0200 @@ -31,10 +31,10 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.*; +import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.hotspot.phases.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.phases.util.*; import com.oracle.graal.replacements.*; import com.oracle.graal.replacements.Snippet.Fold; import com.oracle.graal.replacements.SnippetTemplate.AbstractTemplates; @@ -249,8 +249,8 @@ private final SnippetInfo[] arraycopySnippets; private final SnippetInfo genericPrimitiveSnippet; - public Templates(Providers providers, TargetDescription target) { - super(providers, target); + public Templates(HotSpotProviders providers, TargetDescription target) { + super(providers, providers.getSnippetReflection(), target); arraycopySnippets = new SnippetInfo[Kind.values().length]; arraycopySnippets[Kind.Boolean.ordinal()] = snippet(UnsafeArrayCopySnippets.class, "arraycopyBoolean"); diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/UnsafeLoadSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/UnsafeLoadSnippets.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/UnsafeLoadSnippets.java Wed Apr 23 15:48:38 2014 +0200 @@ -26,10 +26,10 @@ import static com.oracle.graal.replacements.SnippetTemplate.*; import com.oracle.graal.api.code.*; +import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.nodes.HeapAccess.BarrierType; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.phases.util.*; import com.oracle.graal.replacements.*; import com.oracle.graal.replacements.SnippetTemplate.AbstractTemplates; import com.oracle.graal.replacements.SnippetTemplate.Arguments; @@ -52,8 +52,8 @@ private final SnippetInfo unsafeLoad = snippet(UnsafeLoadSnippets.class, "lowerUnsafeLoad"); - public Templates(Providers providers, TargetDescription target) { - super(providers, target); + public Templates(HotSpotProviders providers, TargetDescription target) { + super(providers, providers.getSnippetReflection(), target); } public void lower(UnsafeLoadNode load, LoweringTool tool) { diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/WriteBarrierSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/WriteBarrierSnippets.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/WriteBarrierSnippets.java Wed Apr 23 15:48:38 2014 +0200 @@ -22,13 +22,14 @@ */ package com.oracle.graal.hotspot.replacements; +import static com.oracle.graal.compiler.common.GraalOptions.*; import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*; import static com.oracle.graal.nodes.extended.BranchProbabilityNode.*; -import static com.oracle.graal.phases.GraalOptions.*; import static com.oracle.graal.replacements.SnippetTemplate.*; import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.common.*; import com.oracle.graal.graph.Node.ConstantNodeParameter; import com.oracle.graal.graph.Node.NodeIntrinsic; import com.oracle.graal.hotspot.HotSpotVMConfig.CompressEncoding; @@ -39,8 +40,6 @@ import com.oracle.graal.nodes.HeapAccess.BarrierType; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.phases.*; -import com.oracle.graal.phases.util.*; import com.oracle.graal.replacements.*; import com.oracle.graal.replacements.Snippet.ConstantParameter; import com.oracle.graal.replacements.SnippetTemplate.AbstractTemplates; @@ -334,8 +333,8 @@ private final CompressEncoding oopEncoding; - public Templates(Providers providers, TargetDescription target, CompressEncoding oopEncoding) { - super(providers, target); + public Templates(HotSpotProviders providers, TargetDescription target, CompressEncoding oopEncoding) { + super(providers, providers.getSnippetReflection(), target); this.oopEncoding = oopEncoding; } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/DeoptimizationStub.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/DeoptimizationStub.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,277 @@ +/* + * Copyright (c) 2013, 2014, 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.stubs; + +import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*; +import static com.oracle.graal.hotspot.stubs.StubUtil.*; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.asm.*; +import com.oracle.graal.compiler.common.*; +import com.oracle.graal.graph.Node.ConstantNodeParameter; +import com.oracle.graal.graph.Node.NodeIntrinsic; +import com.oracle.graal.hotspot.*; +import com.oracle.graal.hotspot.meta.*; +import com.oracle.graal.hotspot.nodes.*; +import com.oracle.graal.replacements.*; +import com.oracle.graal.replacements.Snippet.*; +import com.oracle.graal.word.*; + +/** + * Deoptimization stub. + * + * This is the entry point for code which is returning to a de-optimized frame. + * + * The steps taken by this frame are as follows: + * + * - push a dummy "register_save" and save the return values (O0, O1, F0/F1, G1) and all potentially + * live registers (at a pollpoint many registers can be live). + * + * - call the C routine: Deoptimization::fetch_unroll_info (this function returns information about + * the number and size of interpreter frames which are equivalent to the frame which is being + * deoptimized) + * + * - deallocate the unpack frame, restoring only results values. Other volatile registers will now + * be captured in the vframeArray as needed. + * + * - deallocate the deoptimization frame + * + * - in a loop using the information returned in the previous step push new interpreter frames (take + * care to propagate the return values through each new frame pushed) + * + * - create a dummy "unpack_frame" and save the return values (O0, O1, F0) + * + * - call the C routine: Deoptimization::unpack_frames (this function lays out values on the + * interpreter frame which was just created) + * + * - deallocate the dummy unpack_frame + * + * - ensure that all the return values are correctly set and then do a return to the interpreter + * entry point + */ +public class DeoptimizationStub extends SnippetStub { + + private final TargetDescription target; + + public DeoptimizationStub(HotSpotProviders providers, TargetDescription target, HotSpotForeignCallLinkage linkage) { + super(providers, target, linkage); + this.target = target; + } + + @Override + public boolean preservesRegisters() { + return false; + } + + @Override + protected Object getConstantParameterValue(int index, String name) { + switch (index) { + case 0: + return providers.getRegisters().getThreadRegister(); + case 1: + return providers.getRegisters().getStackPointerRegister(); + default: + throw GraalInternalError.shouldNotReachHere("unknown parameter " + name + " at index " + index); + } + } + + /** + * Uncommon trap. + * + * We save the argument return registers. We call the first C routine, fetch_unroll_info(). This + * routine captures the return values and returns a structure which describes the current frame + * size and the sizes of all replacement frames. The current frame is compiled code and may + * contain many inlined functions, each with their own JVM state. We pop the current frame, then + * push all the new frames. Then we call the C routine unpack_frames() to populate these frames. + * Finally unpack_frames() returns us the new target address. Notice that callee-save registers + * are BLOWN here; they have already been captured in the vframeArray at the time the return PC + * was patched. + * + *

    + * ATTENTION: We cannot do any complicated operations e.g. logging via printf in this snippet + * because we change the current stack layout and so the code is very sensitive to register + * allocation. + */ + @Snippet + private static void uncommonTrapHandler(@ConstantParameter Register threadRegister, @ConstantParameter Register stackPointerRegister) { + final Word thread = registerAsWord(threadRegister); + long registerSaver = SaveAllRegistersNode.saveAllRegisters(); + + final int actionAndReason = readPendingDeoptimization(thread); + writePendingDeoptimization(thread, -1); + + final Word unrollBlock = UncommonTrapCallNode.uncommonTrap(registerSaver, actionAndReason); + + // Pop all the frames we must move/replace. + // + // Frame picture (youngest to oldest) + // 1: self-frame (no frame link) + // 2: deoptimizing frame (no frame link) + // 3: caller of deoptimizing frame (could be compiled/interpreted). + + // Pop self-frame. + LeaveCurrentStackFrameNode.leaveCurrentStackFrame(); + + // Load the initial info we should save (e.g. frame pointer). + final Word initialInfo = unrollBlock.readWord(deoptimizationUnrollBlockInitialInfoOffset()); + + // Pop deoptimized frame + final int sizeOfDeoptimizedFrame = unrollBlock.readInt(deoptimizationUnrollBlockSizeOfDeoptimizedFrameOffset()); + LeaveDeoptimizedStackFrameNode.leaveDeoptimizedStackFrame(sizeOfDeoptimizedFrame, initialInfo); + + /* + * Stack bang to make sure there's enough room for the interpreter frames. Bang stack for + * total size of the interpreter frames plus shadow page size. Bang one page at a time + * because large sizes can bang beyond yellow and red zones. + */ + final int totalFrameSizes = unrollBlock.readInt(deoptimizationUnrollBlockTotalFrameSizesOffset()); + final int bangPages = NumUtil.roundUp(totalFrameSizes, pageSize()) / pageSize() + stackShadowPages(); + Word stackPointer = readRegister(stackPointerRegister); + + for (int i = 1; i < bangPages; i++) { + stackPointer.writeInt(-(i * pageSize()), i); + } + + // Load number of interpreter frames. + final int numberOfFrames = unrollBlock.readInt(deoptimizationUnrollBlockNumberOfFramesOffset()); + + // Load address of array of frame sizes. + final Word frameSizes = unrollBlock.readWord(deoptimizationUnrollBlockFrameSizesOffset()); + + // Load address of array of frame PCs. + final Word framePcs = unrollBlock.readWord(deoptimizationUnrollBlockFramePcsOffset()); + + /* + * Get the current stack pointer (sender's original SP) before adjustment so that we can + * save it in the skeletal interpreter frame. + */ + Word senderSp = readRegister(stackPointerRegister); + + // Adjust old interpreter frame to make space for new frame's extra Java locals. + final int callerAdjustment = unrollBlock.readInt(deoptimizationUnrollBlockCallerAdjustmentOffset()); + writeRegister(stackPointerRegister, readRegister(stackPointerRegister).subtract(callerAdjustment)); + + for (int i = 0; i < numberOfFrames; i++) { + final Word frameSize = frameSizes.readWord(i * wordSize()); + final Word framePc = framePcs.readWord(i * wordSize()); + + // Push an interpreter frame onto the stack. + PushInterpreterFrameNode.pushInterpreterFrame(frameSize, framePc, senderSp, initialInfo); + + // Get the current stack pointer (sender SP) and pass it to next frame. + senderSp = readRegister(stackPointerRegister); + } + + // Get final return address. + final Word framePc = framePcs.readWord(numberOfFrames * wordSize()); + + /* + * Enter a frame to call out to unpack frames. Since we changed the stack pointer to an + * unknown alignment we need to align it here before calling C++ code. + */ + final Word senderFp = initialInfo; + EnterUnpackFramesStackFrameNode.enterUnpackFramesStackFrame(framePc, senderSp, senderFp); + + // Pass uncommon trap mode to unpack frames. + final int mode = deoptimizationUnpackUncommonTrap(); + unpackFrames(UNPACK_FRAMES, thread, mode); + + LeaveUnpackFramesStackFrameNode.leaveUnpackFramesStackFrame(); + } + + /** + * Reads the value of the passed register as a Word. + */ + private static Word readRegister(Register register) { + return registerAsWord(register, false, false); + } + + /** + * Writes the value of the passed register. + * + * @param value value the register should be set to + */ + private static void writeRegister(Register register, Word value) { + writeRegisterAsWord(register, value); + } + + @Fold + private static int stackShadowPages() { + return config().useStackBanging ? config().stackShadowPages : 0; + } + + @Fold + private static int deoptimizationUnrollBlockSizeOfDeoptimizedFrameOffset() { + return config().deoptimizationUnrollBlockSizeOfDeoptimizedFrameOffset; + } + + @Fold + private static int deoptimizationUnrollBlockCallerAdjustmentOffset() { + return config().deoptimizationUnrollBlockCallerAdjustmentOffset; + } + + @Fold + private static int deoptimizationUnrollBlockNumberOfFramesOffset() { + return config().deoptimizationUnrollBlockNumberOfFramesOffset; + } + + @Fold + private static int deoptimizationUnrollBlockTotalFrameSizesOffset() { + return config().deoptimizationUnrollBlockTotalFrameSizesOffset; + } + + @Fold + private static int deoptimizationUnrollBlockFrameSizesOffset() { + return config().deoptimizationUnrollBlockFrameSizesOffset; + } + + @Fold + private static int deoptimizationUnrollBlockFramePcsOffset() { + return config().deoptimizationUnrollBlockFramePcsOffset; + } + + @Fold + private static int deoptimizationUnrollBlockInitialInfoOffset() { + return config().deoptimizationUnrollBlockInitialInfoOffset; + } + + @Fold + private static int deoptimizationUnpackDeopt() { + return config().deoptimizationUnpackDeopt; + } + + @Fold + private static int deoptimizationUnpackUncommonTrap() { + return config().deoptimizationUnpackUncommonTrap; + } + + public static final ForeignCallDescriptor FETCH_UNROLL_INFO = descriptorFor(DeoptimizationStub.class, "fetchUnrollInfo"); + public static final ForeignCallDescriptor UNPACK_FRAMES = descriptorFor(DeoptimizationStub.class, "unpackFrames"); + + @NodeIntrinsic(value = StubForeignCallNode.class, setStampFromReturnType = true) + public static native Word fetchUnrollInfo(@ConstantNodeParameter ForeignCallDescriptor fetchUnrollInfo, Word thread); + + @NodeIntrinsic(value = StubForeignCallNode.class, setStampFromReturnType = true) + public static native int unpackFrames(@ConstantNodeParameter ForeignCallDescriptor unpackFrames, Word thread, int mode); +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ForeignCallStub.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ForeignCallStub.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ForeignCallStub.java Wed Apr 23 15:48:38 2014 +0200 @@ -27,6 +27,7 @@ import static com.oracle.graal.hotspot.HotSpotForeignCallLinkage.RegisterEffect.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.debug.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.HotSpotForeignCallLinkage.Transition; @@ -34,7 +35,6 @@ import com.oracle.graal.hotspot.nodes.*; import com.oracle.graal.hotspot.replacements.*; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.type.*; import com.oracle.graal.replacements.*; import com.oracle.graal.replacements.nodes.*; import com.oracle.graal.word.*; @@ -63,7 +63,7 @@ /** * Creates a stub for a call to code at a given address. - * + * * @param address the address of the code to call * @param descriptor the signature of the call to this stub * @param prependThread true if the JavaThread value for the current thread is to be prepended @@ -78,7 +78,7 @@ super(providers, HotSpotForeignCallLinkage.create(providers.getMetaAccess(), providers.getCodeCache(), providers.getForeignCalls(), descriptor, 0L, PRESERVES_REGISTERS, JavaCall, JavaCallee, transition, reexecutable, killedLocations)); this.prependThread = prependThread; - Class[] targetParameterTypes = createTargetParameters(descriptor); + Class[] targetParameterTypes = createTargetParameters(descriptor); ForeignCallDescriptor targetSig = new ForeignCallDescriptor(descriptor.getName() + ":C", descriptor.getResultType(), targetParameterTypes); target = HotSpotForeignCallLinkage.create(providers.getMetaAccess(), providers.getCodeCache(), providers.getForeignCalls(), targetSig, address, DESTROYS_REGISTERS, NativeCall, NativeCall, transition, reexecutable, killedLocations); @@ -91,10 +91,10 @@ return target; } - private Class[] createTargetParameters(ForeignCallDescriptor descriptor) { - Class[] parameters = descriptor.getArgumentTypes(); + private Class[] createTargetParameters(ForeignCallDescriptor descriptor) { + Class[] parameters = descriptor.getArgumentTypes(); if (prependThread) { - Class[] newParameters = new Class[parameters.length + 1]; + Class[] newParameters = new Class[parameters.length + 1]; System.arraycopy(parameters, 0, newParameters, 1, parameters.length); newParameters[0] = Word.class; return newParameters; @@ -141,7 +141,7 @@ * Creates a graph for this stub. *

    * If the stub returns an object, the graph created corresponds to this pseudo code: - * + * *

          *     Object foreignFunctionStub(args...) {
          *         foreignFunction(currentThread,  args);
    @@ -152,10 +152,10 @@
          *         return verifyObject(getAndClearObjectResult(thread()));
          *     }
          * 
    - * + * * If the stub returns a primitive or word, the graph created corresponds to this pseudo code * (using {@code int} as the primitive return type): - * + * *
          *     int foreignFunctionStub(args...) {
          *         int result = foreignFunction(currentThread,  args);
    @@ -165,9 +165,9 @@
          *         return result;
          *     }
          * 
    - * + * * If the stub is void, the graph created corresponds to this pseudo code: - * + * *
          *     void foreignFunctionStub(args...) {
          *         foreignFunction(currentThread,  args);
    @@ -176,7 +176,7 @@
          *         }
          *     }
          * 
    - * + * * In each example above, the {@code currentThread} argument is the C++ JavaThread value (i.e., * %r15 on AMD64) and is only prepended if {@link #prependThread} is true. */ @@ -203,8 +203,8 @@ Debug.dump(graph, "Initial stub graph"); } - kit.rewriteWordTypes(); - kit.inlineInvokes(); + kit.rewriteWordTypes(providers.getSnippetReflection()); + kit.inlineInvokes(providers.getSnippetReflection()); if (Debug.isDumpEnabled()) { Debug.dump(graph, "Stub graph before compilation"); diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewArrayStub.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewArrayStub.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewArrayStub.java Wed Apr 23 15:48:38 2014 +0200 @@ -22,7 +22,6 @@ */ package com.oracle.graal.hotspot.stubs; -import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*; import static com.oracle.graal.hotspot.replacements.NewObjectSnippets.*; import static com.oracle.graal.hotspot.stubs.NewInstanceStub.*; @@ -61,16 +60,10 @@ protected Arguments makeArguments(SnippetInfo stub) { HotSpotResolvedObjectType intArrayType = (HotSpotResolvedObjectType) providers.getMetaAccess().lookupJavaType(int[].class); - // RuntimeStub cannot (currently) support oops or metadata embedded in the code so we - // convert the hub (i.e., Klass*) for int[] to be a naked word. This should be safe since - // the int[] class will never be unloaded. - Constant intArrayHub = intArrayType.klass(); - intArrayHub = Constant.forIntegerKind(runtime().getTarget().wordKind, intArrayHub.asLong(), null); - Arguments args = new Arguments(stub, GuardsStage.FLOATING_GUARDS, LoweringTool.StandardLoweringStage.HIGH_TIER); args.add("hub", null); args.add("length", null); - args.addConst("intArrayHub", intArrayHub); + args.addConst("intArrayHub", intArrayType.klass()); args.addConst("threadRegister", providers.getRegisters().getThreadRegister()); return args; } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewInstanceStub.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewInstanceStub.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewInstanceStub.java Wed Apr 23 15:48:38 2014 +0200 @@ -65,7 +65,7 @@ // convert the hub (i.e., Klass*) for int[] to be a naked word. This should be safe since // the int[] class will never be unloaded. Constant intArrayHub = intArrayType.klass(); - intArrayHub = Constant.forIntegerKind(runtime().getTarget().wordKind, intArrayHub.asLong(), null); + intArrayHub = Constant.forIntegerKind(runtime().getTarget().wordKind, intArrayHub.asLong()); Arguments args = new Arguments(stub, GuardsStage.FLOATING_GUARDS, LoweringTool.StandardLoweringStage.HIGH_TIER); args.add("hub", null); @@ -231,7 +231,7 @@ * @param log specifies if logging is enabled * @return the allocated chunk or {@link Word#zero()} if allocation fails */ - static Word edenAllocate(Word sizeInBytes, boolean log) { + public static Word edenAllocate(Word sizeInBytes, boolean log) { Word heapTopAddress = Word.unsigned(heapTopAddress()); Word heapEndAddress = Word.unsigned(heapEndAddress()); diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/SnippetStub.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/SnippetStub.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/SnippetStub.java Wed Apr 23 15:48:38 2014 +0200 @@ -26,13 +26,12 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.graph.*; +import com.oracle.graal.compiler.common.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.StructuredGraph.GuardsStage; import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.phases.util.*; import com.oracle.graal.replacements.*; import com.oracle.graal.replacements.SnippetTemplate.AbstractTemplates; import com.oracle.graal.replacements.SnippetTemplate.Arguments; @@ -45,8 +44,8 @@ static class Template extends AbstractTemplates { - Template(Providers providers, TargetDescription target, Class declaringClass) { - super(providers, target); + Template(HotSpotProviders providers, TargetDescription target, Class declaringClass) { + super(providers, providers.getSnippetReflection(), target); this.info = snippet(declaringClass, null); } @@ -65,7 +64,7 @@ /** * Creates a new snippet stub. - * + * * @param linkage linkage details for a call to the stub */ public SnippetStub(HotSpotProviders providers, TargetDescription target, HotSpotForeignCallLinkage linkage) { diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java Wed Apr 23 15:48:38 2014 +0200 @@ -23,18 +23,18 @@ package com.oracle.graal.hotspot.stubs; import static com.oracle.graal.compiler.GraalCompiler.*; +import static com.oracle.graal.compiler.common.GraalOptions.*; import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; -import static com.oracle.graal.phases.GraalOptions.*; import java.util.*; import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.common.*; import com.oracle.graal.compiler.target.*; import com.oracle.graal.debug.*; import com.oracle.graal.debug.Debug.Scope; import com.oracle.graal.debug.internal.*; -import com.oracle.graal.graph.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.bridge.CompilerToVM.CodeInstallResult; import com.oracle.graal.hotspot.meta.*; @@ -95,7 +95,7 @@ /** * Creates a new stub. - * + * * @param linkage linkage details for a call to the stub */ public Stub(HotSpotProviders providers, HotSpotForeignCallLinkage linkage) { @@ -125,8 +125,7 @@ } /** - * Gets the method the stub's code will be {@linkplain InstalledCode#getMethod() associated} - * with once installed. This may be null. + * Gets the method the stub's code will be associated with once installed. This may be null. */ protected abstract ResolvedJavaMethod getInstalledCodeOwner(); diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/StubUtil.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/StubUtil.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/StubUtil.java Wed Apr 23 15:48:38 2014 +0200 @@ -69,7 +69,7 @@ } assert found != null : "could not find foreign call named " + name + " in " + stubClass; List> paramList = Arrays.asList(found.getParameterTypes()); - Class[] cCallTypes = paramList.subList(1, paramList.size()).toArray(new Class[paramList.size() - 1]); + Class[] cCallTypes = paramList.subList(1, paramList.size()).toArray(new Class[paramList.size() - 1]); return new ForeignCallDescriptor(name, found.getReturnType(), cCallTypes); } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.hsail/src/com/oracle/graal/hsail/HSAIL.java --- a/graal/com.oracle.graal.hsail/src/com/oracle/graal/hsail/HSAIL.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.hsail/src/com/oracle/graal/hsail/HSAIL.java Wed Apr 23 15:48:38 2014 +0200 @@ -131,6 +131,12 @@ public static final Register d17 = new Register(81, 17, "d17", CPU); public static final Register d18 = new Register(82, 18, "d18", CPU); public static final Register d19 = new Register(83, 19, "d19", CPU); + public static final Register d20 = new Register(84, 20, "d20", CPU); + + public static final Register threadRegister = d20; + public static final Register actionAndReasonReg = s32; + public static final Register codeBufferOffsetReg = s33; + public static final Register dregOopMapReg = s39; // @formatter:off public static final Register[] cRegisters = { @@ -145,7 +151,7 @@ }; public static final Register[] dRegisters = { - d0, d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11, d12, d13, d14, d15 + d0, d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11, d12, d13, d14, d15, threadRegister }; public static final Register[] qRegisters = { @@ -154,9 +160,12 @@ public static final Register[] allRegisters = { c0, c1, c2, c3, c4, c5, c6, c7, s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, + s16, s17, s18, s19, s20, s21, s22, s23, s24, s25, s26, s27, s28, s29, s30, s31, d0, d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11, d12, d13, d14, d15, q0, q1, q2, q3, q4, q5, q6, q7, q8, q9, q10, q11, - q12, q13, q14, q15 + q12, q13, q14, q15, + s32, s33, s34, s35, s36, s37, s38, s39, + d16, d17, d18, d19, threadRegister }; // @formatter:on diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.java.decompiler/src/com/oracle/graal/java/decompiler/Decompiler.java --- a/graal/com.oracle.graal.java.decompiler/src/com/oracle/graal/java/decompiler/Decompiler.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.java.decompiler/src/com/oracle/graal/java/decompiler/Decompiler.java Wed Apr 23 15:48:38 2014 +0200 @@ -25,7 +25,7 @@ import java.io.*; import java.util.*; -import com.oracle.graal.graph.*; +import com.oracle.graal.compiler.common.*; import com.oracle.graal.java.decompiler.block.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.cfg.*; diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.java.decompiler/src/com/oracle/graal/java/decompiler/DecompilerLoopSimplify.java --- a/graal/com.oracle.graal.java.decompiler/src/com/oracle/graal/java/decompiler/DecompilerLoopSimplify.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.java.decompiler/src/com/oracle/graal/java/decompiler/DecompilerLoopSimplify.java Wed Apr 23 15:48:38 2014 +0200 @@ -25,6 +25,7 @@ import java.io.*; import java.util.*; +import com.oracle.graal.compiler.common.cfg.*; import com.oracle.graal.java.decompiler.block.*; import com.oracle.graal.nodes.cfg.*; @@ -46,7 +47,7 @@ cfgBlocks.remove(0); if (firstBlock.isLoopHeader()) { DecompilerLoopBlock loopBlock = new DecompilerLoopBlock(firstBlock, decompiler, decompiler.getSchedule(), infoStream); - Loop loop = firstBlock.getLoop(); + Loop loop = firstBlock.getLoop(); for (int i = 0; i < cfgBlocks.size(); i++) { if (loop.blocks.contains(cfgBlocks.get(i)) && cfgBlocks.get(i) != firstBlock) { diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.java.decompiler/src/com/oracle/graal/java/decompiler/lines/DecompilerSyntaxLine.java --- a/graal/com.oracle.graal.java.decompiler/src/com/oracle/graal/java/decompiler/lines/DecompilerSyntaxLine.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.java.decompiler/src/com/oracle/graal/java/decompiler/lines/DecompilerSyntaxLine.java Wed Apr 23 15:48:38 2014 +0200 @@ -48,7 +48,7 @@ protected static String getStringRepresentation(Node node) { if (node instanceof ConstantNode) { - return String.valueOf(((ConstantNode) node).asConstant().asBoxedValue()); + return ((ConstantNode) node).asConstant().toValueString(); } else if (node instanceof ParameterNode) { return "param_" + ((ParameterNode) node).index(); } else { diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.java/src/com/oracle/graal/java/AbstractBytecodeParser.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/AbstractBytecodeParser.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/AbstractBytecodeParser.java Wed Apr 23 15:48:38 2014 +0200 @@ -25,8 +25,6 @@ import static com.oracle.graal.api.code.TypeCheckHints.*; import static com.oracle.graal.bytecode.Bytecodes.*; -import static java.lang.reflect.Modifier.*; - import java.util.*; import com.oracle.graal.api.code.*; @@ -34,16 +32,15 @@ import com.oracle.graal.api.meta.ProfilingInfo.TriState; import com.oracle.graal.api.meta.ResolvedJavaType.Representation; import com.oracle.graal.bytecode.*; +import com.oracle.graal.compiler.common.*; +import com.oracle.graal.compiler.common.calc.*; import com.oracle.graal.debug.*; -import com.oracle.graal.graph.*; import com.oracle.graal.java.BciBlockMapping.BciBlock; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.calc.*; -import com.oracle.graal.nodes.calc.FloatConvertNode.FloatConvert; import com.oracle.graal.options.*; import com.oracle.graal.phases.*; -public abstract class AbstractBytecodeParser> { +public abstract class AbstractBytecodeParser> { static class Options { // @formatter:off @@ -327,7 +324,7 @@ private void genArithmeticOp(Kind result, int opcode) { T y = frameState.pop(result); T x = frameState.pop(result); - boolean isStrictFP = isStrict(method.getModifiers()); + boolean isStrictFP = method.isStrict(); T v; switch (opcode) { case IADD: @@ -712,13 +709,6 @@ protected abstract void emitNullCheck(T receiver); - protected static final ArrayIndexOutOfBoundsException cachedArrayIndexOutOfBoundsException = new ArrayIndexOutOfBoundsException(); - protected static final NullPointerException cachedNullPointerException = new NullPointerException(); - static { - cachedArrayIndexOutOfBoundsException.setStackTrace(new StackTraceElement[0]); - cachedNullPointerException.setStackTrace(new StackTraceElement[0]); - } - protected abstract void emitBoundsCheck(T index, T length); private static final DebugMetric EXPLICIT_EXCEPTIONS = Debug.metric("ExplicitExceptions"); @@ -830,7 +820,7 @@ * * @return an array of size successorCount with the accumulated probability for each successor. */ - private static double[] successorProbabilites(int successorCount, int[] keySuccessors, double[] keyProbabilities) { + public static double[] successorProbabilites(int successorCount, int[] keySuccessors, double[] keyProbabilities) { double[] probability = new double[successorCount]; for (int i = 0; i < keySuccessors.length; i++) { probability[keySuccessors[i]] += keyProbabilities[i]; @@ -880,17 +870,11 @@ } } - double[] successorProbabilities = successorProbabilites(actualSuccessors.size(), keySuccessors, keyProbabilities); - T switchNode = append(genIntegerSwitch(value, actualSuccessors.size(), keys, keyProbabilities, keySuccessors)); - for (int i = 0; i < actualSuccessors.size(); i++) { - setBlockSuccessor(switchNode, i, createBlockTarget(successorProbabilities[i], actualSuccessors.get(i), frameState)); - } + genIntegerSwitch(value, actualSuccessors, keys, keyProbabilities, keySuccessors); } - protected abstract void setBlockSuccessor(T switchNode, int i, T createBlockTarget); - - protected abstract T genIntegerSwitch(T value, int size, int[] keys, double[] keyProbabilities, int[] keySuccessors); + protected abstract void genIntegerSwitch(T value, ArrayList actualSuccessors, int[] keys, double[] keyProbabilities, int[] keySuccessors); private static class SuccessorInfo { @@ -911,18 +895,8 @@ return probability == 0 && optimisticOpts.removeNeverExecutedCode() && entryBCI == StructuredGraph.INVOCATION_ENTRY_BCI; } - protected abstract T genDeoptimization(); - - /** - * Returns a block begin node with the specified state. If the specified probability is 0, the - * block deoptimizes immediately. - */ - protected abstract T createBlockTarget(double probability, BciBlock bciBlock, AbstractFrameStateBuilder stateAfter); - protected abstract void processBlock(BciBlock block); - protected abstract void appendGoto(T target); - protected abstract void iterateBytecodesForBlock(BciBlock block); public void processBytecode(int bci, int opcode) { diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.java/src/com/oracle/graal/java/AbstractFrameStateBuilder.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/AbstractFrameStateBuilder.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/AbstractFrameStateBuilder.java Wed Apr 23 15:48:38 2014 +0200 @@ -23,19 +23,88 @@ package com.oracle.graal.java; -import com.oracle.graal.api.meta.*; +import java.util.*; -public abstract class AbstractFrameStateBuilder { +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.java.BciBlockMapping.BciBlock; +import com.oracle.graal.java.BciBlockMapping.LocalLiveness; + +public abstract class AbstractFrameStateBuilder> { protected final ResolvedJavaMethod method; protected int stackSize; + protected final T[] locals; + protected final T[] stack; + protected T[] lockedObjects; - public AbstractFrameStateBuilder(ResolvedJavaMethod method) { + /** + * @see BytecodeFrame#rethrowException + */ + protected boolean rethrowException; + + public AbstractFrameStateBuilder(ResolvedJavaMethod method, T[] l, T[] s, T[] lo) { this.method = method; + this.locals = l; + this.stack = s; + this.lockedObjects = lo; + } + + protected AbstractFrameStateBuilder(S other) { + this.method = other.method; + this.stackSize = other.stackSize; + this.locals = other.locals.clone(); + this.stack = other.stack.clone(); + this.lockedObjects = other.lockedObjects == getEmtpyArray() ? getEmtpyArray() : other.lockedObjects.clone(); + this.rethrowException = other.rethrowException; + + assert locals.length == method.getMaxLocals(); + assert stack.length == Math.max(1, method.getMaxStackSize()); } - protected AbstractFrameStateBuilder(AbstractFrameStateBuilder other) { - this.method = other.method; + public abstract S copy(); + + protected abstract T[] getEmtpyArray(); + + public abstract boolean isCompatibleWith(S other); + + public void clearNonLiveLocals(BciBlock block, LocalLiveness liveness, boolean liveIn) { + /* + * (lstadler) if somebody is tempted to remove/disable this clearing code: it's possible to + * remove it for normal compilations, but not for OSR compilations - otherwise dead object + * slots at the OSR entry aren't cleared. it is also not enough to rely on PiNodes with + * Kind.Illegal, because the conflicting branch might not have been parsed. + */ + if (liveness == null) { + return; + } + if (liveIn) { + for (int i = 0; i < locals.length; i++) { + if (!liveness.localIsLiveIn(block, i)) { + locals[i] = null; + } + } + } else { + for (int i = 0; i < locals.length; i++) { + if (!liveness.localIsLiveOut(block, i)) { + locals[i] = null; + } + } + } + } + + /** + * @see BytecodeFrame#rethrowException + */ + public boolean rethrowException() { + return rethrowException; + } + + /** + * @see BytecodeFrame#rethrowException + */ + public void setRethrowException(boolean b) { + rethrowException = b; } /** @@ -43,7 +112,9 @@ * * @return the size of the local variables */ - public abstract int localsSize(); + public int localsSize() { + return locals.length; + } /** * Gets the current size (height) of the stack. @@ -58,7 +129,9 @@ * @param i the index into the locals * @return the instruction that produced the value for the specified local */ - public abstract T localAt(int i); + public T localAt(int i) { + return locals[i]; + } /** * Get the value on the stack at the specified stack index. @@ -66,7 +139,9 @@ * @param i the index into the stack, with {@code 0} being the bottom of the stack * @return the instruction at the specified position in the stack */ - public abstract T stackAt(int i); + public T stackAt(int i) { + return stack[i]; + } /** * Loads the local variable at the specified index, checking that the returned value is non-null @@ -75,7 +150,12 @@ * @param i the index of the local variable to load * @return the instruction that produced the specified local */ - public abstract T loadLocal(int i); + public T loadLocal(int i) { + T x = locals[i]; + assert !isTwoSlot(x.getKind()) || locals[i + 1] == null; + assert i == 0 || locals[i - 1] == null || !isTwoSlot(locals[i - 1].getKind()); + return x; + } /** * Stores a given local variable at the specified index. If the value occupies two slots, then @@ -84,9 +164,26 @@ * @param i the index at which to store * @param x the instruction which produces the value for the local */ - public abstract void storeLocal(int i, T x); + public void storeLocal(int i, T x) { + assert x == null || x.getKind() != Kind.Void && x.getKind() != Kind.Illegal : "unexpected value: " + x; + locals[i] = x; + if (x != null && isTwoSlot(x.getKind())) { + // if this is a double word, then kill i+1 + locals[i + 1] = null; + } + if (x != null && i > 0) { + T p = locals[i - 1]; + if (p != null && isTwoSlot(p.getKind())) { + // if there was a double word at i - 1, then kill it + locals[i - 1] = null; + } + } + } - public abstract void storeStack(int i, T x); + public void storeStack(int i, T x) { + assert x == null || (stack[i] == null || x.getKind() == stack[i].getKind()) : "Method does not handle changes from one-slot to two-slot values or non-alive values"; + stack[i] = x; + } /** * Pushes an instruction onto the stack with the expected type. @@ -94,51 +191,76 @@ * @param kind the type expected for this instruction * @param x the instruction to push onto the stack */ - public abstract void push(Kind kind, T x); + public void push(Kind kind, T x) { + assert x.getKind() != Kind.Void && x.getKind() != Kind.Illegal; + xpush(assertKind(kind, x)); + if (isTwoSlot(kind)) { + xpush(null); + } + } /** * Pushes a value onto the stack without checking the type. * * @param x the instruction to push onto the stack */ - public abstract void xpush(T x); + public void xpush(T x) { + assert x == null || (x.getKind() != Kind.Void && x.getKind() != Kind.Illegal); + stack[stackSize++] = x; + } /** * Pushes a value onto the stack and checks that it is an int. * * @param x the instruction to push onto the stack */ - public abstract void ipush(T x); + public void ipush(T x) { + xpush(assertInt(x)); + } /** * Pushes a value onto the stack and checks that it is a float. * * @param x the instruction to push onto the stack */ - public abstract void fpush(T x); + public void fpush(T x) { + xpush(assertFloat(x)); + } /** * Pushes a value onto the stack and checks that it is an object. * * @param x the instruction to push onto the stack */ - public abstract void apush(T x); + public void apush(T x) { + xpush(assertObject(x)); + } /** * Pushes a value onto the stack and checks that it is a long. * * @param x the instruction to push onto the stack */ - public abstract void lpush(T x); + public void lpush(T x) { + xpush(assertLong(x)); + xpush(null); + } /** * Pushes a value onto the stack and checks that it is a double. * * @param x the instruction to push onto the stack */ - public abstract void dpush(T x); + public void dpush(T x) { + xpush(assertDouble(x)); + xpush(null); + } - public abstract void pushReturn(Kind kind, T x); + public void pushReturn(Kind kind, T x) { + if (kind != Kind.Void) { + push(kind.getStackKind(), x); + } + } /** * Pops an instruction off the stack with the expected type. @@ -146,49 +268,70 @@ * @param kind the expected type * @return the instruction on the top of the stack */ - public abstract T pop(Kind kind); + public T pop(Kind kind) { + assert kind != Kind.Void; + if (isTwoSlot(kind)) { + xpop(); + } + return assertKind(kind, xpop()); + } /** * Pops a value off of the stack without checking the type. * * @return x the instruction popped off the stack */ - public abstract T xpop(); + public T xpop() { + T result = stack[--stackSize]; + return result; + } /** * Pops a value off of the stack and checks that it is an int. * * @return x the instruction popped off the stack */ - public abstract T ipop(); + public T ipop() { + return assertInt(xpop()); + } /** * Pops a value off of the stack and checks that it is a float. * * @return x the instruction popped off the stack */ - public abstract T fpop(); + public T fpop() { + return assertFloat(xpop()); + } /** * Pops a value off of the stack and checks that it is an object. * * @return x the instruction popped off the stack */ - public abstract T apop(); + public T apop() { + return assertObject(xpop()); + } /** * Pops a value off of the stack and checks that it is a long. * * @return x the instruction popped off the stack */ - public abstract T lpop(); + public T lpop() { + assertHigh(xpop()); + return assertLong(xpop()); + } /** * Pops a value off of the stack and checks that it is a double. * * @return x the instruction popped off the stack */ - public abstract T dpop(); + public T dpop() { + assertHigh(xpop()); + return assertDouble(xpop()); + } /** * Pop the specified number of slots off of this stack and return them as an array of @@ -196,7 +339,19 @@ * * @return an array containing the arguments off of the stack */ - public abstract T[] popArguments(int slotSize, int argSize); + public T[] popArguments(int slotSize, int argSize) { + int base = stackSize - slotSize; + List r = new ArrayList<>(argSize); + int stackindex = 0; + while (stackindex < slotSize) { + T element = stack[base + stackindex]; + assert element != null; + r.add(element); + stackindex += stackSlots(element.getKind()); + } + stackSize = base; + return r.toArray(getEmtpyArray()); + } /** * Peeks an element from the operand stack. @@ -206,7 +361,17 @@ * ignored. * @return The peeked argument. */ - public abstract T peek(int argumentNumber); + public T peek(int argumentNumber) { + int idx = stackSize() - 1; + for (int i = 0; i < argumentNumber; i++) { + if (stackAt(idx) == null) { + idx--; + assert isTwoSlot(stackAt(idx).getKind()); + } + idx--; + } + return stackAt(idx); + } public static int stackSlots(Kind kind) { return isTwoSlot(kind) ? 2 : 1; @@ -224,4 +389,38 @@ return kind == Kind.Long || kind == Kind.Double; } + private T assertKind(Kind kind, T x) { + assert x != null && x.getKind() == kind : "kind=" + kind + ", value=" + x + ((x == null) ? "" : ", value.kind=" + x.getKind()); + return x; + } + + private T assertLong(T x) { + assert x != null && (x.getKind() == Kind.Long); + return x; + } + + private T assertInt(T x) { + assert x != null && (x.getKind() == Kind.Int); + return x; + } + + private T assertFloat(T x) { + assert x != null && (x.getKind() == Kind.Float); + return x; + } + + private T assertObject(T x) { + assert x != null && (x.getKind() == Kind.Object); + return x; + } + + private T assertDouble(T x) { + assert x != null && (x.getKind() == Kind.Double); + return x; + } + + private void assertHigh(T x) { + assert x == null; + } + } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.java/src/com/oracle/graal/java/BciBlockMapping.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/BciBlockMapping.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/BciBlockMapping.java Wed Apr 23 15:48:38 2014 +0200 @@ -23,17 +23,17 @@ package com.oracle.graal.java; import static com.oracle.graal.bytecode.Bytecodes.*; -import static com.oracle.graal.phases.GraalOptions.*; +import static com.oracle.graal.compiler.common.GraalOptions.*; import java.util.*; import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.bytecode.*; +import com.oracle.graal.compiler.common.cfg.*; import com.oracle.graal.debug.*; import com.oracle.graal.debug.Debug.Scope; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.cfg.*; /** * Builds a mapping between bytecodes and basic blocks and builds a conservative control flow graph @@ -82,12 +82,14 @@ public boolean isLoopHeader; public int loopId; - public FixedWithNextNode firstInstruction; - public HIRFrameStateBuilder entryState; + /** + * XXX to be removed - currently only used by baseline compiler + */ + public Loop loop; + public boolean isLoopEnd; - // public ArrayList successors = new ArrayList<>(2); - // public ArrayList predecessors = new ArrayList<>(2); // only used in the - // baseline + public FixedWithNextNode firstInstruction; + public AbstractFrameStateBuilder entryState; public long exits; @@ -148,14 +150,12 @@ return sb.toString(); } - public Loop getLoop() { - // TODO Auto-generated method stub - return null; + public Loop getLoop() { + return loop; } public int getLoopDepth() { - // TODO Auto-generated method stub - return 0; + return Long.bitCount(loops); } public boolean isLoopHeader() { @@ -163,13 +163,11 @@ } public boolean isLoopEnd() { - // TODO Auto-generated method stub - return false; + return isLoopEnd; } public boolean isExceptionEntry() { - // TODO Auto-generated method stub - return false; + return isExceptionEntry; } public BciBlock getSuccessor(int index) { @@ -720,6 +718,10 @@ for (BciBlock successor : block.getSuccessors()) { // Recursively process successors. loops |= computeBlockOrder(successor); + if (block.visited && successor.active) { + // Reached block via backward branch. + block.isLoopEnd = true; + } } block.loops = loops; diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.java/src/com/oracle/graal/java/BytecodeDisassembler.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/BytecodeDisassembler.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/BytecodeDisassembler.java Wed Apr 23 15:48:38 2014 +0200 @@ -117,26 +117,7 @@ String desc = null; if (constant instanceof Constant) { Constant c = ((Constant) constant); - switch (c.getKind()) { - 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; - } + desc = c.toValueString(); } else { desc = constant.toString(); } diff -r 518a7f487c4f -r 9363fffa8b07 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 Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Wed Apr 23 15:48:38 2014 +0200 @@ -25,11 +25,7 @@ import static com.oracle.graal.api.meta.DeoptimizationAction.*; import static com.oracle.graal.api.meta.DeoptimizationReason.*; import static com.oracle.graal.bytecode.Bytecodes.*; -import static com.oracle.graal.java.GraphBuilderPhase.RuntimeCalls.*; -import static com.oracle.graal.phases.GraalOptions.*; -import static java.lang.reflect.Modifier.*; - -import java.lang.reflect.*; +import static com.oracle.graal.compiler.common.GraalOptions.*; import java.util.*; import com.oracle.graal.api.code.*; @@ -37,6 +33,9 @@ import com.oracle.graal.api.meta.ProfilingInfo.TriState; import com.oracle.graal.api.meta.ResolvedJavaType.Representation; import com.oracle.graal.bytecode.*; +import com.oracle.graal.compiler.common.*; +import com.oracle.graal.compiler.common.calc.*; +import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.debug.*; import com.oracle.graal.graph.*; import com.oracle.graal.graph.Node.ValueNumberable; @@ -45,7 +44,6 @@ import com.oracle.graal.java.BciBlockMapping.LocalLiveness; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; -import com.oracle.graal.nodes.calc.FloatConvertNode.FloatConvert; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind; @@ -59,12 +57,6 @@ */ public class GraphBuilderPhase extends BasePhase { - public static final class RuntimeCalls { - - public static final ForeignCallDescriptor CREATE_NULL_POINTER_EXCEPTION = new ForeignCallDescriptor("createNullPointerException", NullPointerException.class); - public static final ForeignCallDescriptor CREATE_OUT_OF_BOUNDS_EXCEPTION = new ForeignCallDescriptor("createOutOfBoundsException", ArrayIndexOutOfBoundsException.class, int.class); - } - private final GraphBuilderConfiguration graphBuilderConfig; public GraphBuilderPhase(GraphBuilderConfiguration graphBuilderConfig) { @@ -122,13 +114,10 @@ } } - private BciBlock[] loopHeaders; - private LocalLiveness liveness; - /** * Gets the current frame state being processed by this builder. */ - protected AbstractFrameStateBuilder getCurrentFrameState() { + protected HIRFrameStateBuilder getCurrentFrameState() { return parser.getFrameState(); } @@ -200,6 +189,8 @@ class BytecodeParser extends AbstractBytecodeParser { + private BciBlock[] loopHeaders; + private LocalLiveness liveness; /** * Head of placeholder list. */ @@ -225,9 +216,9 @@ liveness = blockMap.liveness; lastInstr = currentGraph.start(); - if (isSynchronized(method.getModifiers())) { + if (method.isSynchronized()) { // add a monitor enter to the start block - currentGraph.start().setStateAfter(frameState.create(FrameState.BEFORE_BCI)); + currentGraph.start().setStateAfter(frameState.create(BytecodeFrame.BEFORE_BCI)); methodSynchronizedObject = synchronizedObject(frameState, method); lastInstr = genMonitorEnter(methodSynchronizedObject); } @@ -290,12 +281,12 @@ protected void finishPrepare(FixedWithNextNode startInstr) { } - private BciBlock unwindBlock(int bci) { + private BciBlock unwindBlock() { if (unwindBlock == null) { unwindBlock = new ExceptionDispatchBlock(); unwindBlock.startBci = -1; unwindBlock.endBci = -1; - unwindBlock.deoptBci = bci; + unwindBlock.deoptBci = method.isSynchronized() ? BytecodeFrame.UNWIND_BCI : BytecodeFrame.AFTER_EXCEPTION_BCI; unwindBlock.setId(Integer.MAX_VALUE); } return unwindBlock; @@ -415,7 +406,7 @@ } private DispatchBeginNode handleException(ValueNode exceptionObject, int bci) { - assert bci == FrameState.BEFORE_BCI || bci == bci() : "invalid bci"; + assert bci == BytecodeFrame.BEFORE_BCI || bci == bci() : "invalid bci"; Debug.log("Creating exception dispatch edges at %d, exception object=%s, exception seen=%s", bci, exceptionObject, profilingInfo.getExceptionSeen(bci)); BciBlock dispatchBlock = currentBlock.exceptionDispatchBlock(); @@ -425,7 +416,7 @@ * unwind immediately. */ if (bci != currentBlock.endBci || dispatchBlock == null) { - dispatchBlock = unwindBlock(bci); + dispatchBlock = unwindBlock(); } HIRFrameStateBuilder dispatchState = frameState.copy(); @@ -642,7 +633,7 @@ @Override protected void emitNullCheck(ValueNode receiver) { - if (ObjectStamp.isObjectNonNull(receiver.stamp())) { + if (StampTool.isObjectNonNull(receiver.stamp())) { return; } BlockPlaceholderNode trueSucc = currentGraph.add(new BlockPlaceholderNode(this)); @@ -650,16 +641,10 @@ append(new IfNode(currentGraph.unique(new IsNullNode(receiver)), trueSucc, falseSucc, 0.01)); lastInstr = falseSucc; - if (OmitHotExceptionStacktrace.getValue()) { - ValueNode exception = ConstantNode.forObject(cachedNullPointerException, metaAccess, currentGraph); - trueSucc.setNext(handleException(exception, bci())); - } else { - DeferredForeignCallNode call = currentGraph.add(new DeferredForeignCallNode(CREATE_NULL_POINTER_EXCEPTION)); - call.setStamp(StampFactory.exactNonNull(metaAccess.lookupJavaType(CREATE_NULL_POINTER_EXCEPTION.getResultType()))); - call.setStateAfter(frameState.create(bci())); - trueSucc.setNext(call); - call.setNext(handleException(call, bci())); - } + BytecodeExceptionNode exception = currentGraph.add(new BytecodeExceptionNode(metaAccess, NullPointerException.class)); + exception.setStateAfter(frameState.create(bci())); + trueSucc.setNext(exception); + exception.setNext(handleException(exception, bci())); } @Override @@ -669,16 +654,10 @@ append(new IfNode(currentGraph.unique(new IntegerBelowThanNode(index, length)), trueSucc, falseSucc, 0.99)); lastInstr = trueSucc; - if (OmitHotExceptionStacktrace.getValue()) { - ValueNode exception = ConstantNode.forObject(cachedArrayIndexOutOfBoundsException, metaAccess, currentGraph); - falseSucc.setNext(handleException(exception, bci())); - } else { - DeferredForeignCallNode call = currentGraph.add(new DeferredForeignCallNode(CREATE_OUT_OF_BOUNDS_EXCEPTION, index)); - call.setStamp(StampFactory.exactNonNull(metaAccess.lookupJavaType(CREATE_OUT_OF_BOUNDS_EXCEPTION.getResultType()))); - call.setStateAfter(frameState.create(bci())); - falseSucc.setNext(call); - call.setNext(handleException(call, bci())); - } + BytecodeExceptionNode exception = currentGraph.add(new BytecodeExceptionNode(metaAccess, ArrayIndexOutOfBoundsException.class, index)); + exception.setStateAfter(frameState.create(bci())); + falseSucc.setNext(exception); + exception.setNext(handleException(exception, bci())); } @Override @@ -720,9 +699,9 @@ @Override protected void genInvokeDynamic(JavaMethod target) { if (target instanceof ResolvedJavaMethod) { - Object appendix = constantPool.lookupAppendix(stream.readCPI4(), Bytecodes.INVOKEDYNAMIC); + Constant appendix = constantPool.lookupAppendix(stream.readCPI4(), Bytecodes.INVOKEDYNAMIC); if (appendix != null) { - frameState.apush(ConstantNode.forObject(appendix, metaAccess, currentGraph)); + frameState.apush(ConstantNode.forConstant(appendix, metaAccess, currentGraph)); } ValueNode[] args = frameState.popArguments(target.getSignature().getParameterSlots(false), target.getSignature().getParameterCount(false)); appendInvoke(InvokeKind.Static, (ResolvedJavaMethod) target, args); @@ -741,10 +720,10 @@ * https://wikis.oracle.com/display/HotSpotInternals/Method+handles * +and+invokedynamic */ - boolean hasReceiver = !isStatic(((ResolvedJavaMethod) target).getModifiers()); - Object appendix = constantPool.lookupAppendix(stream.readCPI(), Bytecodes.INVOKEVIRTUAL); + boolean hasReceiver = !((ResolvedJavaMethod) target).isStatic(); + Constant appendix = constantPool.lookupAppendix(stream.readCPI(), Bytecodes.INVOKEVIRTUAL); if (appendix != null) { - frameState.apush(ConstantNode.forObject(appendix, metaAccess, currentGraph)); + frameState.apush(ConstantNode.forConstant(appendix, metaAccess, currentGraph)); } ValueNode[] args = frameState.popArguments(target.getSignature().getParameterSlots(hasReceiver), target.getSignature().getParameterCount(hasReceiver)); if (hasReceiver) { @@ -834,7 +813,7 @@ append(new InfopointNode(InfopointReason.METHOD_END, frameState.create(bci()))); } - synchronizedEpilogue(FrameState.AFTER_BCI, x); + synchronizedEpilogue(BytecodeFrame.AFTER_BCI, x); if (frameState.lockDepth() != 0) { throw new BailoutException("unbalanced monitors"); } @@ -890,13 +869,12 @@ } @Override - protected void setBlockSuccessor(ValueNode switchNode, int i, ValueNode createBlockTarget) { - ((IntegerSwitchNode) switchNode).setBlockSuccessor(i, (AbstractBeginNode) createBlockTarget); - } - - @Override - protected ValueNode genIntegerSwitch(ValueNode value, int size, int[] keys, double[] keyProbabilities, int[] keySuccessors) { - return new IntegerSwitchNode(value, size, keys, keyProbabilities, keySuccessors); + protected void genIntegerSwitch(ValueNode value, ArrayList actualSuccessors, int[] keys, double[] keyProbabilities, int[] keySuccessors) { + double[] successorProbabilities = successorProbabilites(actualSuccessors.size(), keySuccessors, keyProbabilities); + IntegerSwitchNode switchNode = append(new IntegerSwitchNode(value, actualSuccessors.size(), keys, keyProbabilities, keySuccessors)); + for (int i = 0; i < actualSuccessors.size(); i++) { + switchNode.setBlockSuccessor(i, createBlockTarget(successorProbabilities[i], actualSuccessors.get(i), frameState)); + } } @Override @@ -997,7 +975,7 @@ } lastLoopExit = loopExit; Debug.log("Target %s (%s) Exits %s, scanning framestates...", targetBlock, target, loop); - newState.insertLoopProxies(loopExit, loop.entryState); + newState.insertLoopProxies(loopExit, (HIRFrameStateBuilder) loop.entryState); loopExit.setStateAfter(newState.create(bci)); } @@ -1008,25 +986,17 @@ return new Target(target, state); } - @Override - protected ValueNode genDeoptimization() { - return currentGraph.add(new DeoptimizeNode(InvalidateReprofile, UnreachedCode)); - } - - protected FixedNode createTarget(double probability, BciBlock block, AbstractFrameStateBuilder stateAfter) { + private FixedNode createTarget(double probability, BciBlock block, HIRFrameStateBuilder stateAfter) { assert probability >= 0 && probability <= 1.01 : probability; if (isNeverExecutedCode(probability)) { - return (FixedNode) genDeoptimization(); + return currentGraph.add(new DeoptimizeNode(InvalidateReprofile, UnreachedCode)); } else { assert block != null; return createTarget(block, stateAfter); } - } - protected FixedNode createTarget(BciBlock block, AbstractFrameStateBuilder abstractState) { - assert abstractState instanceof HIRFrameStateBuilder; - HIRFrameStateBuilder state = (HIRFrameStateBuilder) abstractState; + private FixedNode createTarget(BciBlock block, HIRFrameStateBuilder state) { assert block != null && state != null; assert !block.isExceptionEntry || state.stackSize() == 1; @@ -1047,7 +1017,7 @@ } // We already saw this block before, so we have to merge states. - if (!block.entryState.isCompatibleWith(state)) { + if (!((HIRFrameStateBuilder) block.entryState).isCompatibleWith(state)) { throw new BailoutException("stacks do not match; bytecodes would not verify"); } @@ -1060,7 +1030,7 @@ LoopBeginNode loopBegin = (LoopBeginNode) block.firstInstruction; Target target = checkLoopExit(currentGraph.add(new LoopEndNode(loopBegin)), block, state); FixedNode result = target.fixed; - block.entryState.merge(loopBegin, target.state); + ((HIRFrameStateBuilder) block.entryState).merge(loopBegin, target.state); Debug.log("createTarget %s: merging backward branch to loop header %s, result: %s", block, loopBegin, result); return result; @@ -1095,7 +1065,7 @@ AbstractEndNode newEnd = currentGraph.add(new EndNode()); Target target = checkLoopExit(newEnd, block, state); FixedNode result = target.fixed; - block.entryState.merge(mergeNode, target.state); + ((HIRFrameStateBuilder) block.entryState).merge(mergeNode, target.state); mergeNode.addForwardEnd(newEnd); Debug.log("createTarget %s: merging state, result: %s", block, result); @@ -1106,18 +1076,17 @@ * Returns a block begin node with the specified state. If the specified probability is * 0, the block deoptimizes immediately. */ - @Override - protected AbstractBeginNode createBlockTarget(double probability, BciBlock block, AbstractFrameStateBuilder stateAfter) { + private BeginNode createBlockTarget(double probability, BciBlock block, HIRFrameStateBuilder stateAfter) { FixedNode target = createTarget(probability, block, stateAfter); - AbstractBeginNode begin = AbstractBeginNode.begin(target); + BeginNode begin = BeginNode.begin(target); - assert !(target instanceof DeoptimizeNode && begin.stateAfter() != null) : "We are not allowed to set the stateAfter of the begin node, because we have to deoptimize " + assert !(target instanceof DeoptimizeNode && begin instanceof BeginStateSplitNode && ((BeginStateSplitNode) begin).stateAfter() != null) : "We are not allowed to set the stateAfter of the begin node, because we have to deoptimize " + "to a bci _before_ the actual if, so that the interpreter can update the profiling information."; return begin; } private ValueNode synchronizedObject(HIRFrameStateBuilder state, ResolvedJavaMethod target) { - if (isStatic(target.getModifiers())) { + if (target.isStatic()) { return appendConstant(target.getDeclaringClass().getEncoding(Representation.JavaClass)); } else { return state.loadLocal(0); @@ -1134,7 +1103,7 @@ try (Indent indent = Debug.logAndIndent("Parsing block %s firstInstruction: %s loopHeader: %b", block, block.firstInstruction, block.isLoopHeader)) { lastInstr = block.firstInstruction; - frameState = block.entryState; + frameState = (HIRFrameStateBuilder) block.entryState; parser.setCurrentFrameState(frameState); currentBlock = block; @@ -1183,13 +1152,12 @@ private void createUnwind() { assert frameState.stackSize() == 1 : frameState; ValueNode exception = frameState.apop(); - append(new FixedGuardNode(currentGraph.unique(new IsNullNode(exception)), NullCheckException, InvalidateReprofile, true)); - synchronizedEpilogue(FrameState.AFTER_EXCEPTION_BCI, null); + synchronizedEpilogue(BytecodeFrame.AFTER_EXCEPTION_BCI, null); append(new UnwindNode(exception)); } private void synchronizedEpilogue(int bci, ValueNode returnValue) { - if (Modifier.isSynchronized(method.getModifiers())) { + if (method.isSynchronized()) { MonitorExitNode monitorExit = genMonitorExit(methodSynchronizedObject, returnValue); if (returnValue != null) { frameState.push(returnValue.getKind(), returnValue); @@ -1216,7 +1184,7 @@ ResolvedJavaType resolvedCatchType = (ResolvedJavaType) catchType; for (ResolvedJavaType skippedType : graphBuilderConfig.getSkippedExceptionTypes()) { if (skippedType.isAssignableFrom(resolvedCatchType)) { - BciBlock nextBlock = block.getSuccessorCount() == 1 ? unwindBlock(block.deoptBci) : block.getSuccessor(1); + BciBlock nextBlock = block.getSuccessorCount() == 1 ? unwindBlock() : block.getSuccessor(1); ValueNode exception = frameState.stackAt(0); FixedNode trueSuccessor = currentGraph.add(new DeoptimizeNode(InvalidateReprofile, UnreachedCode)); FixedNode nextDispatch = createTarget(nextBlock, frameState); @@ -1227,7 +1195,7 @@ } if (initialized) { - BciBlock nextBlock = block.getSuccessorCount() == 1 ? unwindBlock(block.deoptBci) : block.getSuccessor(1); + BciBlock nextBlock = block.getSuccessorCount() == 1 ? unwindBlock() : block.getSuccessor(1); ValueNode exception = frameState.stackAt(0); CheckCastNode checkCast = currentGraph.add(new CheckCastNode((ResolvedJavaType) catchType, exception, null, false)); frameState.apop(); @@ -1243,10 +1211,7 @@ } } - @Override - protected void appendGoto(ValueNode targetNode) { - assert targetNode instanceof FixedNode; - FixedNode target = (FixedNode) targetNode; + private void appendGoto(FixedNode target) { if (lastInstr != null) { lastInstr.setNext(target); } @@ -1332,7 +1297,7 @@ frameState.clearNonLiveLocals(currentBlock, liveness, false); } if (lastInstr instanceof StateSplit) { - if (lastInstr.getClass() == AbstractBeginNode.class) { + if (lastInstr.getClass() == BeginNode.class) { // BeginNodes do not need a frame state } else { StateSplit stateSplit = (StateSplit) lastInstr; diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.java/src/com/oracle/graal/java/HIRFrameStateBuilder.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/HIRFrameStateBuilder.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/HIRFrameStateBuilder.java Wed Apr 23 15:48:38 2014 +0200 @@ -23,54 +23,37 @@ package com.oracle.graal.java; import static com.oracle.graal.graph.iterators.NodePredicates.*; -import static com.oracle.graal.nodes.ValueNodeUtil.*; -import static java.lang.reflect.Modifier.*; - import java.util.*; import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.debug.*; import com.oracle.graal.graph.Node.Verbosity; -import com.oracle.graal.java.BciBlockMapping.BciBlock; -import com.oracle.graal.java.BciBlockMapping.LocalLiveness; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.java.*; -import com.oracle.graal.nodes.type.*; import com.oracle.graal.nodes.util.*; -public class HIRFrameStateBuilder extends AbstractFrameStateBuilder { +public class HIRFrameStateBuilder extends AbstractFrameStateBuilder { private static final ValueNode[] EMPTY_ARRAY = new ValueNode[0]; private static final MonitorIdNode[] EMPTY_MONITOR_ARRAY = new MonitorIdNode[0]; - private final ValueNode[] locals; - private final ValueNode[] stack; - private ValueNode[] lockedObjects; private MonitorIdNode[] monitorIds; private final StructuredGraph graph; - /** - * @see BytecodeFrame#rethrowException - */ - private boolean rethrowException; - public HIRFrameStateBuilder(ResolvedJavaMethod method, StructuredGraph graph, boolean eagerResolve) { - super(method); + super(method, new ValueNode[method.getMaxLocals()], new ValueNode[Math.max(1, method.getMaxStackSize())], EMPTY_ARRAY); assert graph != null; - this.locals = new ValueNode[method.getMaxLocals()]; - // we always need at least one stack slot (for exceptions) - this.stack = new ValueNode[Math.max(1, method.getMaxStackSize())]; - this.lockedObjects = EMPTY_ARRAY; this.monitorIds = EMPTY_MONITOR_ARRAY; this.graph = graph; int javaIndex = 0; int index = 0; - if (!isStatic(method.getModifiers())) { + if (!method.isStatic()) { // add the receiver ParameterNode receiver = graph.unique(new ParameterNode(javaIndex, StampFactory.declaredNonNull(method.getDeclaringClass()))); storeLocal(javaIndex, receiver); @@ -85,7 +68,7 @@ if (eagerResolve) { type = type.resolve(accessingClass); } - Kind kind = type.getKind().getStackKind(); + Kind kind = type.getKind(); Stamp stamp; if (kind == Kind.Object && type instanceof ResolvedJavaType) { stamp = StampFactory.declared((ResolvedJavaType) type); @@ -103,12 +86,7 @@ super(other); assert other.graph != null; graph = other.graph; - locals = other.locals.clone(); - stack = other.stack.clone(); - lockedObjects = other.lockedObjects == EMPTY_ARRAY ? EMPTY_ARRAY : other.lockedObjects.clone(); monitorIds = other.monitorIds == EMPTY_MONITOR_ARRAY ? EMPTY_MONITOR_ARRAY : other.monitorIds.clone(); - stackSize = other.stackSize; - rethrowException = other.rethrowException; assert locals.length == method.getMaxLocals(); assert stack.length == Math.max(1, method.getMaxStackSize()); @@ -116,6 +94,11 @@ } @Override + protected ValueNode[] getEmtpyArray() { + return EMPTY_ARRAY; + } + + @Override public String toString() { StringBuilder sb = new StringBuilder(); sb.append("[locals: ["); @@ -142,10 +125,12 @@ return graph.add(new FrameState(method, bci, locals, Arrays.asList(stack).subList(0, stackSize), lockedObjects, monitorIds, rethrowException, false)); } + @Override public HIRFrameStateBuilder copy() { return new HIRFrameStateBuilder(this); } + @Override public boolean isCompatibleWith(HIRFrameStateBuilder other) { assert method.equals(other.method) && graph == other.graph && localsSize() == other.localsSize() : "Can only compare frame states of the same method"; assert lockedObjects.length == monitorIds.length && other.lockedObjects.length == other.monitorIds.length : "mismatch between lockedObjects and monitorIds"; @@ -272,7 +257,7 @@ } } - public void insertProxies(AbstractBeginNode begin) { + public void insertProxies(BeginNode begin) { for (int i = 0; i < localsSize(); i++) { ValueNode value = localAt(i); if (value != null) { @@ -316,57 +301,9 @@ } } - public void clearNonLiveLocals(BciBlock block, LocalLiveness liveness, boolean liveIn) { - if (liveness == null) { - return; - } - if (liveIn) { - for (int i = 0; i < locals.length; i++) { - if (!liveness.localIsLiveIn(block, i)) { - locals[i] = null; - } - } - } else { - for (int i = 0; i < locals.length; i++) { - if (!liveness.localIsLiveOut(block, i)) { - locals[i] = null; - } - } - } - } - - /** - * @see BytecodeFrame#rethrowException - */ - public boolean rethrowException() { - return rethrowException; - } - - /** - * @see BytecodeFrame#rethrowException - */ - public void setRethrowException(boolean b) { - rethrowException = b; - } - - @Override - public int localsSize() { - return locals.length; - } - - @Override - public ValueNode localAt(int i) { - return locals[i]; - } - - @Override - public ValueNode stackAt(int i) { - return stack[i]; - } - /** * Adds a locked monitor to this frame state. - * + * * @param object the object whose monitor will be locked. */ public void pushLock(ValueNode object, MonitorIdNode monitorId) { @@ -380,7 +317,7 @@ /** * Removes a locked monitor from this frame state. - * + * * @return the object whose monitor was removed from the locks list. */ public ValueNode popLock() { @@ -404,159 +341,6 @@ return lockedObjects.length; } - @Override - public ValueNode loadLocal(int i) { - ValueNode x = locals[i]; - assert !x.isDeleted(); - assert !isTwoSlot(x.getKind()) || locals[i + 1] == null; - assert i == 0 || locals[i - 1] == null || !isTwoSlot(locals[i - 1].getKind()); - return x; - } - - @Override - public void storeLocal(int i, ValueNode x) { - assert x == null || x.isAlive() && x.getKind() != Kind.Void && x.getKind() != Kind.Illegal : "unexpected value: " + x; - locals[i] = x; - if (x != null && isTwoSlot(x.getKind())) { - // if this is a double word, then kill i+1 - locals[i + 1] = null; - } - if (x != null && i > 0) { - ValueNode p = locals[i - 1]; - if (p != null && isTwoSlot(p.getKind())) { - // if there was a double word at i - 1, then kill it - locals[i - 1] = null; - } - } - } - - @Override - public void storeStack(int i, ValueNode x) { - assert x == null || x.isAlive() && (stack[i] == null || x.getKind() == stack[i].getKind()) : "Method does not handle changes from one-slot to two-slot values or non-alive values"; - stack[i] = x; - } - - @Override - public void push(Kind kind, ValueNode x) { - assert x.isAlive() && x.getKind() != Kind.Void && x.getKind() != Kind.Illegal; - xpush(assertKind(kind, x)); - if (isTwoSlot(kind)) { - xpush(null); - } - } - - @Override - public void xpush(ValueNode x) { - assert x == null || (x.isAlive() && x.getKind() != Kind.Void && x.getKind() != Kind.Illegal); - stack[stackSize++] = x; - } - - @Override - public void ipush(ValueNode x) { - xpush(assertInt(x)); - } - - @Override - public void fpush(ValueNode x) { - xpush(assertFloat(x)); - } - - @Override - public void apush(ValueNode x) { - xpush(assertObject(x)); - } - - @Override - public void lpush(ValueNode x) { - xpush(assertLong(x)); - xpush(null); - } - - @Override - public void dpush(ValueNode x) { - xpush(assertDouble(x)); - xpush(null); - } - - @Override - public void pushReturn(Kind kind, ValueNode x) { - if (kind != Kind.Void) { - push(kind.getStackKind(), x); - } - } - - @Override - public ValueNode pop(Kind kind) { - assert kind != Kind.Void; - if (isTwoSlot(kind)) { - xpop(); - } - return assertKind(kind, xpop()); - } - - @Override - public ValueNode xpop() { - ValueNode result = stack[--stackSize]; - assert result == null || !result.isDeleted(); - return result; - } - - @Override - public ValueNode ipop() { - return assertInt(xpop()); - } - - @Override - public ValueNode fpop() { - return assertFloat(xpop()); - } - - @Override - public ValueNode apop() { - return assertObject(xpop()); - } - - @Override - public ValueNode lpop() { - assertHigh(xpop()); - return assertLong(xpop()); - } - - @Override - public ValueNode dpop() { - assertHigh(xpop()); - return assertDouble(xpop()); - } - - @Override - public ValueNode[] popArguments(int slotSize, int argSize) { - int base = stackSize - slotSize; - ValueNode[] r = new ValueNode[argSize]; - int argIndex = 0; - int stackindex = 0; - while (stackindex < slotSize) { - ValueNode element = stack[base + stackindex]; - assert element != null; - r[argIndex++] = element; - stackindex += stackSlots(element.getKind()); - } - stackSize = base; - return r; - } - - @Override - public ValueNode peek(int argumentNumber) { - int idx = stackSize() - 1; - for (int i = 0; i < argumentNumber; i++) { - if (stackAt(idx) == null) { - idx--; - assert isTwoSlot(stackAt(idx).getKind()); - } - idx--; - } - return stackAt(idx); - } - public boolean contains(ValueNode value) { for (int i = 0; i < localsSize(); i++) { if (localAt(i) == value) { diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.java/src/com/oracle/graal/java/VerifyOptionsPhase.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/VerifyOptionsPhase.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/VerifyOptionsPhase.java Wed Apr 23 15:48:38 2014 +0200 @@ -24,11 +24,10 @@ package com.oracle.graal.java; import static com.oracle.graal.api.meta.MetaUtil.*; -import static java.lang.reflect.Modifier.*; - import java.util.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.common.*; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.java.*; @@ -84,7 +83,7 @@ this.optionValueType = metaAccess.lookupJavaType(OptionValue.class); this.option = option; this.boxingTypes = new HashSet<>(); - for (Class c : new Class[]{Boolean.class, Byte.class, Short.class, Character.class, Integer.class, Float.class, Long.class, Double.class}) { + for (Class c : new Class[]{Boolean.class, Byte.class, Short.class, Character.class, Integer.class, Float.class, Long.class, Double.class}) { this.boxingTypes.add(metaAccess.lookupJavaType(c)); } } @@ -114,9 +113,9 @@ if (node instanceof StoreFieldNode) { ResolvedJavaField field = ((StoreFieldNode) node).field(); verify(field.getDeclaringClass().equals(declaringClass), node, "store to field " + format("%H.%n", field)); - verify(isStatic(field.getModifiers()), node, "store to field " + format("%H.%n", field)); + verify(field.isStatic(), node, "store to field " + format("%H.%n", field)); if (optionValueType.isAssignableFrom((ResolvedJavaType) field.getType())) { - verify(isFinal(field.getModifiers()), node, "option field " + format("%H.%n", field) + " not final"); + verify(field.isFinal(), node, "option field " + format("%H.%n", field) + " not final"); } else { verify((field.isSynthetic()), node, "store to non-synthetic field " + format("%H.%n", field)); } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/JTTTest.java --- a/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/JTTTest.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/JTTTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -64,7 +64,7 @@ assert parameterTypes.length == args.length; for (int i = 0; i < args.length; i++) { ParameterNode param = graph.getParameter(i); - Constant c = Constant.forBoxed(parameterTypes[i].getKind(), args[i]); + Constant c = getSnippetReflection().forBoxed(parameterTypes[i].getKind(), args[i]); ConstantNode replacement = ConstantNode.forConstant(c, getMetaAccess(), graph); param.replaceAtUsages(replacement); } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/hotpath/HP_series.java --- a/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/hotpath/HP_series.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/hotpath/HP_series.java Wed Apr 23 15:48:38 2014 +0200 @@ -24,6 +24,8 @@ package com.oracle.graal.jtt.hotpath; +import org.junit.*; + import com.oracle.graal.jtt.*; /* @@ -104,7 +106,8 @@ * different implementation may return different results. The 11 ulp delta allowed for test(100) * tries to account for that but is not guaranteed to work forever. */ - // @Test + @Ignore("failure-prone because of the variabiliy of pow/cos/sin") + @Test public void run0() throws Throwable { double expected = 0.6248571921291398d; runTestWithDelta(11 * Math.ulp(expected), "test", 100); diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/hotspot/Test6186134.java --- a/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/hotspot/Test6186134.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/hotspot/Test6186134.java Wed Apr 23 15:48:38 2014 +0200 @@ -43,7 +43,7 @@ return num-- > 0; } - public ArrayList test1() { + public ArrayList test1() { ArrayList res = new ArrayList<>(); int maxResults = Integer.MAX_VALUE; int n = 0; diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/hotspot/Test6823354.java --- a/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/hotspot/Test6823354.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/hotspot/Test6823354.java Wed Apr 23 15:48:38 2014 +0200 @@ -198,10 +198,10 @@ } static void loadandrunclass(String classname) throws Exception { - Class cl = Class.forName(classname); + Class cl = Class.forName(classname); URLClassLoader apploader = (URLClassLoader) cl.getClassLoader(); ClassLoader loader = new URLClassLoader(apploader.getURLs(), apploader.getParent()); - Class c = loader.loadClass(classname); + Class c = loader.loadClass(classname); Runnable r = (Runnable) c.newInstance(); r.run(); } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/hotspot/Test6959129.java --- a/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/hotspot/Test6959129.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/hotspot/Test6959129.java Wed Apr 23 15:48:38 2014 +0200 @@ -22,30 +22,16 @@ */ package com.oracle.graal.jtt.hotspot; +import org.junit.*; + import com.oracle.graal.jtt.*; -//@formatter:off - -/** - * @test - * @bug 6959129 - * @summary COMPARISON WITH INTEGER.MAX_INT DOES NOT WORK CORRECTLY IN THE CLIENT VM. - * - * This test will not run properly without assertions - * - * @run main/othervm -ea Test6959129 - */ public class Test6959129 extends JTTTest { - public static int test() { + public static long test() { int min = Integer.MAX_VALUE - 30000; int max = Integer.MAX_VALUE; - try { - maxMoves(min, max); - } catch (AssertionError e) { - return 95; - } - return 97; + return maxMoves(min, max); } /** @@ -55,7 +41,9 @@ long n = n2; long moves = 0; while (n != 1) { - assert n > 1; + if (n <= 1) { + throw new IllegalStateException(); + } if (isEven(n)) { n = n / 2; } else { @@ -86,7 +74,7 @@ return maxmoves; } - //@Test + @Test(timeout = 20000) public void run0() throws Throwable { runTest("test"); } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/jdk/UnsafeAllocateInstance01.java --- a/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/jdk/UnsafeAllocateInstance01.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/jdk/UnsafeAllocateInstance01.java Wed Apr 23 15:48:38 2014 +0200 @@ -43,7 +43,7 @@ return newObject.field01; } - public static void testClassForException(Class clazz) throws SecurityException, InstantiationException { + public static void testClassForException(Class clazz) throws SecurityException, InstantiationException { final Unsafe unsafe = getUnsafe(); unsafe.allocateInstance(clazz); } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/lang/Class_forName02.java --- a/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/lang/Class_forName02.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/lang/Class_forName02.java Wed Apr 23 15:48:38 2014 +0200 @@ -31,7 +31,7 @@ public static String test(int i) throws ClassNotFoundException { String clname = null; - Class cl = null; + Class cl = null; if (i == 0) { clname = "java.lang.Object"; cl = Object.class; diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/lang/Class_forName03.java --- a/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/lang/Class_forName03.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/lang/Class_forName03.java Wed Apr 23 15:48:38 2014 +0200 @@ -33,7 +33,7 @@ public static String test(int i) throws ClassNotFoundException { String clname = null; - Class cl = null; + Class cl = null; if (i == 0) { clname = "java.lang.Object[]"; cl = Object.class; diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/lang/Class_getComponentType01.java --- a/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/lang/Class_getComponentType01.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/lang/Class_getComponentType01.java Wed Apr 23 15:48:38 2014 +0200 @@ -31,7 +31,7 @@ public final class Class_getComponentType01 extends JTTTest { public static String test(int i) { - Class cl = Object.class; + Class cl = Object.class; if (i == 0) { cl = int.class; } else if (i == 1) { diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/lang/Class_getModifiers01.java --- a/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/lang/Class_getModifiers01.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/lang/Class_getModifiers01.java Wed Apr 23 15:48:38 2014 +0200 @@ -39,7 +39,7 @@ private static class Private { } - public static int test(Class c) { + public static int test(Class c) { return c.getModifiers(); } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/lang/Class_getSuperClass01.java --- a/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/lang/Class_getSuperClass01.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/lang/Class_getSuperClass01.java Wed Apr 23 15:48:38 2014 +0200 @@ -31,7 +31,7 @@ public final class Class_getSuperClass01 extends JTTTest { public static String test(int i) { - Class cl = Object.class; + Class cl = Object.class; if (i == 0) { cl = int.class; } else if (i == 1) { diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/lang/Class_isAssignableFrom01.java --- a/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/lang/Class_isAssignableFrom01.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/lang/Class_isAssignableFrom01.java Wed Apr 23 15:48:38 2014 +0200 @@ -31,7 +31,7 @@ public final class Class_isAssignableFrom01 extends JTTTest { public static boolean test(int i) { - Class source = Object.class; + Class source = Object.class; if (i == 0) { source = int.class; } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/lang/Class_isAssignableFrom02.java --- a/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/lang/Class_isAssignableFrom02.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/lang/Class_isAssignableFrom02.java Wed Apr 23 15:48:38 2014 +0200 @@ -31,7 +31,7 @@ public final class Class_isAssignableFrom02 extends JTTTest { public static boolean test(int i) { - Class source = Object.class; + Class source = Object.class; if (i == 0) { source = int.class; } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/lang/Class_isAssignableFrom03.java --- a/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/lang/Class_isAssignableFrom03.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/lang/Class_isAssignableFrom03.java Wed Apr 23 15:48:38 2014 +0200 @@ -31,7 +31,7 @@ public final class Class_isAssignableFrom03 extends JTTTest implements Cloneable { public static boolean test(int i) { - Class source = Object.class; + Class source = Object.class; if (i == 0) { source = int.class; } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/lang/Class_isInstance07.java --- a/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/lang/Class_isInstance07.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/lang/Class_isInstance07.java Wed Apr 23 15:48:38 2014 +0200 @@ -35,7 +35,7 @@ static final String[] sarray = {}; static final Object thisObject = new Class_isInstance07(); - public static boolean test(int i, Class c) { + public static boolean test(int i, Class c) { Object object = null; if (i == 0) { object = obj; diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/lang/Int_less02.java --- a/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/lang/Int_less02.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/lang/Int_less02.java Wed Apr 23 15:48:38 2014 +0200 @@ -20,8 +20,6 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -/* - */ package com.oracle.graal.jtt.lang; import org.junit.*; diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/lang/JDK_ClassLoaders02.java --- a/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/lang/JDK_ClassLoaders02.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/lang/JDK_ClassLoaders02.java Wed Apr 23 15:48:38 2014 +0200 @@ -20,26 +20,6 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -/* - * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved. - * - * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product - * that is described in this document. In particular, and without limitation, these intellectual property - * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or - * more additional patents or pending patent applications in the U.S. and in other countries. - * - * U.S. Government Rights - Commercial software. Government users are subject to the Sun - * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its - * supplements. - * - * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or - * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks - * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the - * U.S. and other countries. - * - * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open - * Company, Ltd. - */ package com.oracle.graal.jtt.lang; import java.net.*; diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/lang/LambdaEagerTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/lang/LambdaEagerTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2014, 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.jtt.lang; + +import java.util.*; +import java.util.function.*; + +import org.junit.*; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.common.*; +import com.oracle.graal.compiler.test.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.options.*; +import com.oracle.graal.options.OptionValue.OverrideScope; + +public class LambdaEagerTest extends GraalCompilerTest { + + private static final EnumSet UNRESOLVED_UNREACHED = EnumSet.of(DeoptimizationReason.Unresolved, DeoptimizationReason.UnreachedCode); + + private static int doBinary(IntBinaryOperator op, int x, int y) { + return op.applyAsInt(x, y); + } + + private static int add(int x, int y) { + return x + y; + } + + public static int nonCapturing(int x, int y) { + return doBinary((a, b) -> a + b, x, y); + } + + public static int nonCapturing2(int x, int y) { + return doBinary(LambdaEagerTest::add, x, y); + } + + public static int capturing(int x, int y, int z) { + return doBinary((a, b) -> a + b - z, x, y); + } + + @Test + public void testEagerResolveNonCapturing01() { + Result expected = new Result(3, null); + testAgainstExpected(getMethod("nonCapturing"), expected, UNRESOLVED_UNREACHED, 1, 2); + } + + @Test + public void testEagerResolveNonCapturing02() { + Result expected = new Result(3, null); + testAgainstExpected(getMethod("nonCapturing2"), expected, UNRESOLVED_UNREACHED, 1, 2); + } + + @Test + public void testEagerResolveCapturing() { + Result expected = new Result(0, null); + testAgainstExpected(getMethod("capturing"), expected, UNRESOLVED_UNREACHED, 1, 2, 3); + } + + @Override + protected InstalledCode getCode(ResolvedJavaMethod method, StructuredGraph graph, boolean forceCompile) { + try (OverrideScope scope = OptionValue.override(GraalOptions.InlineEverything, true)) { + return super.getCode(method, graph, forceCompile); + } + } +} \ No newline at end of file diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/loop/Loop07.java --- a/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/loop/Loop07.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/loop/Loop07.java Wed Apr 23 15:48:38 2014 +0200 @@ -26,8 +26,6 @@ import com.oracle.graal.jtt.*; -/* - */ public class Loop07 extends JTTTest { public static String test(int arg) { diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/loop/Loop07_2.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/loop/Loop07_2.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2014, 2014, 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.jtt.loop; + +import org.junit.*; + +import com.oracle.graal.jtt.*; + +public class Loop07_2 extends JTTTest { + + public static int test(int arg) { + int count = arg; + for (int i = 0; i < arg; i++) { + count++; + } + return count; + } + + @Test + public void run0() throws Throwable { + runTest("test", 0); + } + + @Test + public void run1() throws Throwable { + runTest("test", 10); + } + + @Test + public void run2() throws Throwable { + runTest("test", 25); + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/micro/FloatingReads.java --- a/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/micro/FloatingReads.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/micro/FloatingReads.java Wed Apr 23 15:48:38 2014 +0200 @@ -22,6 +22,8 @@ */ package com.oracle.graal.jtt.micro; +import org.junit.*; + import com.oracle.graal.jtt.*; public class FloatingReads extends JTTTest { @@ -61,22 +63,22 @@ return a + b + c; } - // @Test + @Test public void run0() { runTest("test", 10); } - // @Test + @Test public void run1() { runTest("test", 1000); } - // @Test + @Test public void run2() { runTest("test", 1); } - // @Test + @Test public void run3() { runTest("test", 0); } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/threads/Monitor_contended01.java --- a/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/threads/Monitor_contended01.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/threads/Monitor_contended01.java Wed Apr 23 15:48:38 2014 +0200 @@ -71,7 +71,7 @@ } } - @LongTest + @LongTest(timeout = 20000) public void run0() throws Throwable { runTest("test"); } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/threads/Monitor_notowner01.java --- a/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/threads/Monitor_notowner01.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/threads/Monitor_notowner01.java Wed Apr 23 15:48:38 2014 +0200 @@ -62,7 +62,7 @@ } } - @LongTest + @LongTest(timeout = 20000) public void run0() throws Throwable { runTest("test"); } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/threads/Monitorenter01.java --- a/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/threads/Monitorenter01.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/threads/Monitorenter01.java Wed Apr 23 15:48:38 2014 +0200 @@ -41,7 +41,7 @@ } } - @Test + @Test(timeout = 20000) public void run0() throws Throwable { runTest("test"); } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/threads/Monitorenter02.java --- a/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/threads/Monitorenter02.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/threads/Monitorenter02.java Wed Apr 23 15:48:38 2014 +0200 @@ -45,7 +45,7 @@ } } - @Test + @Test(timeout = 20000) public void run0() throws Throwable { runTest("test"); } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/threads/Object_wait01.java --- a/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/threads/Object_wait01.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/threads/Object_wait01.java Wed Apr 23 15:48:38 2014 +0200 @@ -57,22 +57,22 @@ } } - @LongTest + @LongTest(timeout = 20000) public void run0() throws Throwable { runTest("test", 0); } - @LongTest + @LongTest(timeout = 20000) public void run1() throws Throwable { runTest("test", 1); } - @LongTest + @LongTest(timeout = 20000) public void run2() throws Throwable { runTest("test", 3); } - @LongTest + @LongTest(timeout = 20000) public void run3() throws Throwable { runTest("test", 15); } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/threads/Object_wait02.java --- a/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/threads/Object_wait02.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/threads/Object_wait02.java Wed Apr 23 15:48:38 2014 +0200 @@ -57,17 +57,17 @@ } } - @LongTest + @LongTest(timeout = 20000) public void run0() throws Throwable { runTest("test", 0); } - @LongTest + @LongTest(timeout = 20000) public void run1() throws Throwable { runTest("test", 1); } - @LongTest + @LongTest(timeout = 20000) public void run2() throws Throwable { runTest("test", 2); } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/threads/Object_wait03.java --- a/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/threads/Object_wait03.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/threads/Object_wait03.java Wed Apr 23 15:48:38 2014 +0200 @@ -63,17 +63,17 @@ } } - @LongTest + @LongTest(timeout = 20000) public void run0() throws Throwable { runTest("test", 0); } - @LongTest + @LongTest(timeout = 20000) public void run1() throws Throwable { runTest("test", 1); } - @LongTest + @LongTest(timeout = 20000) public void run2() throws Throwable { runTest("test", 2); } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/threads/Object_wait04.java --- a/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/threads/Object_wait04.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/threads/Object_wait04.java Wed Apr 23 15:48:38 2014 +0200 @@ -67,32 +67,32 @@ } } - @LongTest + @LongTest(timeout = 20000) public void run0() throws Throwable { runTest("test", 0); } - @LongTest + @LongTest(timeout = 20000) public void run1() throws Throwable { runTest("test", 1); } - @LongTest + @LongTest(timeout = 20000) public void run2() throws Throwable { runTest("test", 2); } - @LongTest + @LongTest(timeout = 20000) public void run3() throws Throwable { runTest("test", 3); } - @LongTest + @LongTest(timeout = 20000) public void run4() throws Throwable { runTest("test", 4); } - @LongTest + @LongTest(timeout = 20000) public void run5() throws Throwable { runTest("test", 5); } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/threads/SynchronizedLoopExit01.java --- a/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/threads/SynchronizedLoopExit01.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/threads/SynchronizedLoopExit01.java Wed Apr 23 15:48:38 2014 +0200 @@ -30,9 +30,9 @@ /** * Inspired by {@code com.sun.media.sound.DirectAudioDevice$DirectDL.drain()}. - * + * * Two loop exits hold a monitor while merging. - * + * */ public final class SynchronizedLoopExit01 extends JTTTest { @@ -53,7 +53,7 @@ return b; } - @Test + @Test(timeout = 20000) public void run0() throws Throwable { runTest("test"); } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/threads/Thread_isInterrupted02.java --- a/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/threads/Thread_isInterrupted02.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/threads/Thread_isInterrupted02.java Wed Apr 23 15:48:38 2014 +0200 @@ -85,12 +85,12 @@ } } - @LongTest + @LongTest(timeout = 20000) public void run0() throws Throwable { runTest("test", 0, 0); } - @LongTest + @LongTest(timeout = 20000) public void run1() throws Throwable { runTest("test", 1, 500); } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/threads/Thread_isInterrupted03.java --- a/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/threads/Thread_isInterrupted03.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/threads/Thread_isInterrupted03.java Wed Apr 23 15:48:38 2014 +0200 @@ -68,7 +68,7 @@ } } - @LongTest + @LongTest(timeout = 20000) public void run0() throws Throwable { runTest("test"); } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/threads/Thread_isInterrupted04.java --- a/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/threads/Thread_isInterrupted04.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/threads/Thread_isInterrupted04.java Wed Apr 23 15:48:38 2014 +0200 @@ -66,7 +66,7 @@ } - @LongTest + @LongTest(timeout = 20000) public void run0() throws Throwable { runTest("test"); } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/threads/Thread_isInterrupted05.java --- a/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/threads/Thread_isInterrupted05.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/threads/Thread_isInterrupted05.java Wed Apr 23 15:48:38 2014 +0200 @@ -66,7 +66,7 @@ } } - @LongTest + @LongTest(timeout = 20000) public void run0() throws Throwable { runTest("test"); } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/threads/Thread_join01.java --- a/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/threads/Thread_join01.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/threads/Thread_join01.java Wed Apr 23 15:48:38 2014 +0200 @@ -43,7 +43,7 @@ cont = false; } - @LongTest + @LongTest(timeout = 20000) public void run0() throws Throwable { runTest("test"); } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/threads/Thread_join02.java --- a/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/threads/Thread_join02.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/threads/Thread_join02.java Wed Apr 23 15:48:38 2014 +0200 @@ -50,7 +50,7 @@ cont = false; } - @LongTest + @LongTest(timeout = 20000) public void run0() throws Throwable { runTest("test"); } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/threads/Thread_join03.java --- a/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/threads/Thread_join03.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/threads/Thread_join03.java Wed Apr 23 15:48:38 2014 +0200 @@ -47,7 +47,7 @@ cont = false; } - @LongTest + @LongTest(timeout = 20000) public void run0() throws Throwable { runTest("test"); } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/threads/Thread_sleep01.java --- a/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/threads/Thread_sleep01.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/threads/Thread_sleep01.java Wed Apr 23 15:48:38 2014 +0200 @@ -35,17 +35,17 @@ return System.currentTimeMillis() - before >= i; } - @LongTest + @LongTest(timeout = 20000) public void run0() throws Throwable { runTest("test", 10); } - @LongTest + @LongTest(timeout = 20000) public void run1() throws Throwable { runTest("test", 20); } - @LongTest + @LongTest(timeout = 20000) public void run2() throws Throwable { runTest("test", 100); } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/threads/Thread_yield01.java --- a/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/threads/Thread_yield01.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/threads/Thread_yield01.java Wed Apr 23 15:48:38 2014 +0200 @@ -35,7 +35,7 @@ return true; } - @Test + @Test(timeout = 20000) public void run0() throws Throwable { runTest("test"); } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Arithmetic.java --- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Arithmetic.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Arithmetic.java Wed Apr 23 15:48:38 2014 +0200 @@ -30,7 +30,7 @@ import com.oracle.graal.asm.*; import com.oracle.graal.asm.amd64.*; import com.oracle.graal.asm.amd64.AMD64Assembler.ConditionFlag; -import com.oracle.graal.graph.*; +import com.oracle.graal.compiler.common.*; import com.oracle.graal.lir.*; import com.oracle.graal.lir.amd64.AMD64Move.MemOp; import com.oracle.graal.lir.asm.*; @@ -82,6 +82,27 @@ } /** + * Unary operation with separate source and destination operand but register only. + */ + public static class Unary2RegOp extends AMD64LIRInstruction { + + @Opcode private final AMD64Arithmetic opcode; + @Def({REG}) protected AllocatableValue result; + @Use({REG}) protected AllocatableValue x; + + public Unary2RegOp(AMD64Arithmetic opcode, AllocatableValue result, AllocatableValue x) { + this.opcode = opcode; + this.result = result; + this.x = x; + } + + @Override + public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) { + emit(crb, masm, opcode, result, x, null); + } + } + + /** * Unary operation with single operand for source and destination. */ public static class Unary1Op extends AMD64LIRInstruction { @@ -431,9 +452,6 @@ case LNOT: masm.notq(asLongReg(result)); break; - case L2I: - masm.andl(asIntReg(result), 0xFFFFFFFF); - break; default: throw GraalInternalError.shouldNotReachHere(); } @@ -568,6 +586,9 @@ case I2L: masm.movslq(asLongReg(dst), asIntReg(src)); break; + case L2I: + masm.movl(asIntReg(dst), asLongReg(src)); + break; case F2D: masm.cvtss2sd(asDoubleReg(dst), asFloatReg(src)); break; diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64ArrayEqualsOp.java --- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64ArrayEqualsOp.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64ArrayEqualsOp.java Wed Apr 23 15:48:38 2014 +0200 @@ -23,7 +23,7 @@ package com.oracle.graal.lir.amd64; import static com.oracle.graal.api.code.ValueUtil.*; -import static com.oracle.graal.graph.UnsafeAccess.*; +import static com.oracle.graal.compiler.common.UnsafeAccess.*; import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; import java.lang.reflect.*; @@ -38,7 +38,7 @@ import com.oracle.graal.asm.amd64.AMD64Assembler.ConditionFlag; import com.oracle.graal.lir.*; import com.oracle.graal.lir.asm.*; -import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.lir.gen.*; /** * Emits code which compares two arrays of the same length. If the CPU supports any vector diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Compare.java --- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Compare.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Compare.java Wed Apr 23 15:48:38 2014 +0200 @@ -28,7 +28,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.*; import com.oracle.graal.asm.amd64.*; -import com.oracle.graal.graph.*; +import com.oracle.graal.compiler.common.*; import com.oracle.graal.lir.*; import com.oracle.graal.lir.amd64.AMD64Move.MemOp; import com.oracle.graal.lir.asm.*; @@ -65,7 +65,8 @@ (name().startsWith("S") && x.getKind().getStackKind() == Kind.Int && y.getKind().getStackKind() == Kind.Int) || (name().startsWith("I") && x.getKind() == Kind.Int && y.getKind() == Kind.Int) || (name().startsWith("L") && x.getKind() == Kind.Long && y.getKind() == Kind.Long) || (name().startsWith("A") && x.getKind() == Kind.Object && y.getKind() == Kind.Object) || - (name().startsWith("F") && x.getKind() == Kind.Float && y.getKind() == Kind.Float) || (name().startsWith("D") && x.getKind() == Kind.Double && y.getKind() == Kind.Double); + (name().startsWith("F") && x.getKind() == Kind.Float && y.getKind() == Kind.Float) || (name().startsWith("D") && x.getKind() == Kind.Double && y.getKind() == Kind.Double) : String.format( + "%s(%s, %s)", opcode, x, y); } } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64ControlFlow.java --- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64ControlFlow.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64ControlFlow.java Wed Apr 23 15:48:38 2014 +0200 @@ -33,12 +33,12 @@ import com.oracle.graal.asm.amd64.*; import com.oracle.graal.asm.amd64.AMD64Address.Scale; import com.oracle.graal.asm.amd64.AMD64Assembler.ConditionFlag; -import com.oracle.graal.graph.*; +import com.oracle.graal.compiler.common.*; +import com.oracle.graal.compiler.common.calc.*; import com.oracle.graal.lir.*; import com.oracle.graal.lir.StandardOp.BlockEndOp; import com.oracle.graal.lir.SwitchStrategy.BaseSwitchClosure; import com.oracle.graal.lir.asm.*; -import com.oracle.graal.nodes.calc.*; public class AMD64ControlFlow { @@ -261,7 +261,7 @@ @Use({REG, STACK, CONST}) protected Value falseValue; private final ConditionFlag condition; - public CondMoveOp(Variable result, Condition condition, Variable trueValue, Value falseValue) { + public CondMoveOp(Variable result, Condition condition, AllocatableValue trueValue, Value falseValue) { this.result = result; this.condition = intCond(condition); this.trueValue = trueValue; diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64FrameMap.java --- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64FrameMap.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64FrameMap.java Wed Apr 23 15:48:38 2014 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,6 +24,7 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.asm.*; import com.oracle.graal.lir.*; /** @@ -33,7 +34,7 @@ * *
      *   Base       Contents
    - *
    + * 
      *            :                                :  -----
      *   caller   | incoming overflow argument n   |    ^
      *   frame    :     ...                        :    | positive
    @@ -88,8 +89,7 @@
     
         @Override
         protected int alignFrameSize(int size) {
    -        int x = size + returnAddressSize() + (target.stackAlignment - 1);
    -        return (x / target.stackAlignment) * target.stackAlignment - returnAddressSize();
    +        return NumUtil.roundUp(size + returnAddressSize(), target.stackAlignment) - returnAddressSize();
         }
     
         @Override
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64MathIntrinsicOp.java
    --- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64MathIntrinsicOp.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64MathIntrinsicOp.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -26,7 +26,7 @@
     
     import com.oracle.graal.api.meta.*;
     import com.oracle.graal.asm.amd64.*;
    -import com.oracle.graal.graph.*;
    +import com.oracle.graal.compiler.common.*;
     import com.oracle.graal.lir.*;
     import com.oracle.graal.lir.asm.*;
     
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Move.java
    --- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Move.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Move.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -33,7 +33,7 @@
     import com.oracle.graal.api.meta.*;
     import com.oracle.graal.asm.*;
     import com.oracle.graal.asm.amd64.*;
    -import com.oracle.graal.graph.*;
    +import com.oracle.graal.compiler.common.*;
     import com.oracle.graal.lir.*;
     import com.oracle.graal.lir.StandardOp.ImplicitNullCheck;
     import com.oracle.graal.lir.StandardOp.MoveOp;
    @@ -396,12 +396,15 @@
         @Opcode("CAS")
         public static class CompareAndSwapOp extends AMD64LIRInstruction {
     
    +        private final Kind accessKind;
    +
             @Def protected AllocatableValue result;
             @Use({COMPOSITE}) protected AMD64AddressValue address;
             @Use protected AllocatableValue cmpValue;
             @Use protected AllocatableValue newValue;
     
    -        public CompareAndSwapOp(AllocatableValue result, AMD64AddressValue address, AllocatableValue cmpValue, AllocatableValue newValue) {
    +        public CompareAndSwapOp(Kind accessKind, AllocatableValue result, AMD64AddressValue address, AllocatableValue cmpValue, AllocatableValue newValue) {
    +            this.accessKind = accessKind;
                 this.result = result;
                 this.address = address;
                 this.cmpValue = cmpValue;
    @@ -410,7 +413,90 @@
     
             @Override
             public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
    -            compareAndSwap(crb, masm, result, address, cmpValue, newValue);
    +            assert asRegister(cmpValue).equals(AMD64.rax) && asRegister(result).equals(AMD64.rax);
    +
    +            if (crb.target.isMP) {
    +                masm.lock();
    +            }
    +            switch (accessKind) {
    +                case Int:
    +                    masm.cmpxchgl(asRegister(newValue), address.toAddress());
    +                    break;
    +                case Long:
    +                case Object:
    +                    masm.cmpxchgq(asRegister(newValue), address.toAddress());
    +                    break;
    +                default:
    +                    throw GraalInternalError.shouldNotReachHere();
    +            }
    +        }
    +    }
    +
    +    @Opcode("ATOMIC_READ_AND_ADD")
    +    public static class AtomicReadAndAddOp extends AMD64LIRInstruction {
    +
    +        private final Kind accessKind;
    +
    +        @Def protected AllocatableValue result;
    +        @Alive({COMPOSITE}) protected AMD64AddressValue address;
    +        @Use protected AllocatableValue delta;
    +
    +        public AtomicReadAndAddOp(Kind accessKind, AllocatableValue result, AMD64AddressValue address, AllocatableValue delta) {
    +            this.accessKind = accessKind;
    +            this.result = result;
    +            this.address = address;
    +            this.delta = delta;
    +        }
    +
    +        @Override
    +        public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
    +            move(accessKind, crb, masm, result, delta);
    +            if (crb.target.isMP) {
    +                masm.lock();
    +            }
    +            switch (accessKind) {
    +                case Int:
    +                    masm.xaddl(address.toAddress(), asRegister(result));
    +                    break;
    +                case Long:
    +                    masm.xaddq(address.toAddress(), asRegister(result));
    +                    break;
    +                default:
    +                    throw GraalInternalError.shouldNotReachHere();
    +            }
    +        }
    +    }
    +
    +    @Opcode("ATOMIC_READ_AND_WRITE")
    +    public static class AtomicReadAndWriteOp extends AMD64LIRInstruction {
    +
    +        private final Kind accessKind;
    +
    +        @Def protected AllocatableValue result;
    +        @Alive({COMPOSITE}) protected AMD64AddressValue address;
    +        @Use protected AllocatableValue newValue;
    +
    +        public AtomicReadAndWriteOp(Kind accessKind, AllocatableValue result, AMD64AddressValue address, AllocatableValue newValue) {
    +            this.accessKind = accessKind;
    +            this.result = result;
    +            this.address = address;
    +            this.newValue = newValue;
    +        }
    +
    +        @Override
    +        public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
    +            move(accessKind, crb, masm, result, newValue);
    +            switch (accessKind) {
    +                case Int:
    +                    masm.xchgl(asRegister(result), address.toAddress());
    +                    break;
    +                case Long:
    +                case Object:
    +                    masm.xchgq(asRegister(result), address.toAddress());
    +                    break;
    +                default:
    +                    throw GraalInternalError.shouldNotReachHere();
    +            }
             }
         }
     
    @@ -641,24 +727,4 @@
                     throw GraalInternalError.shouldNotReachHere();
             }
         }
    -
    -    protected static void compareAndSwap(CompilationResultBuilder crb, AMD64MacroAssembler masm, AllocatableValue result, AMD64AddressValue address, AllocatableValue cmpValue,
    -                    AllocatableValue newValue) {
    -        assert asRegister(cmpValue).equals(AMD64.rax) && asRegister(result).equals(AMD64.rax);
    -
    -        if (crb.target.isMP) {
    -            masm.lock();
    -        }
    -        switch (cmpValue.getKind()) {
    -            case Int:
    -                masm.cmpxchgl(asRegister(newValue), address.toAddress());
    -                break;
    -            case Long:
    -            case Object:
    -                masm.cmpxchgq(asRegister(newValue), address.toAddress());
    -                break;
    -            default:
    -                throw GraalInternalError.shouldNotReachHere();
    -        }
    -    }
     }
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64TestMemoryOp.java
    --- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64TestMemoryOp.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64TestMemoryOp.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -27,7 +27,7 @@
     
     import com.oracle.graal.api.meta.*;
     import com.oracle.graal.asm.amd64.*;
    -import com.oracle.graal.graph.*;
    +import com.oracle.graal.compiler.common.*;
     import com.oracle.graal.lir.*;
     import com.oracle.graal.lir.amd64.AMD64Move.MemOp;
     import com.oracle.graal.lir.asm.*;
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64TestOp.java
    --- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64TestOp.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64TestOp.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -27,7 +27,7 @@
     
     import com.oracle.graal.api.meta.*;
     import com.oracle.graal.asm.amd64.*;
    -import com.oracle.graal.graph.*;
    +import com.oracle.graal.compiler.common.*;
     import com.oracle.graal.lir.asm.*;
     
     public class AMD64TestOp extends AMD64LIRInstruction {
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILArithmetic.java
    --- a/graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILArithmetic.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILArithmetic.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -27,7 +27,7 @@
     
     import com.oracle.graal.api.meta.*;
     import com.oracle.graal.asm.hsail.*;
    -import com.oracle.graal.graph.*;
    +import com.oracle.graal.compiler.common.*;
     import com.oracle.graal.lir.*;
     import com.oracle.graal.lir.asm.*;
     
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILBitManipulationOp.java
    --- a/graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILBitManipulationOp.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILBitManipulationOp.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -24,7 +24,7 @@
     
     import com.oracle.graal.api.meta.*;
     import com.oracle.graal.asm.hsail.*;
    -import com.oracle.graal.graph.*;
    +import com.oracle.graal.compiler.common.*;
     import com.oracle.graal.lir.*;
     import com.oracle.graal.lir.asm.*;
     
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILCompare.java
    --- a/graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILCompare.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILCompare.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -26,20 +26,26 @@
     
     import com.oracle.graal.api.meta.*;
     import com.oracle.graal.asm.hsail.*;
    -import com.oracle.graal.graph.*;
    +import com.oracle.graal.compiler.common.*;
    +import com.oracle.graal.compiler.common.calc.*;
     import com.oracle.graal.lir.*;
     import com.oracle.graal.lir.asm.*;
    -import com.oracle.graal.nodes.calc.*;
     
     /**
      * Implementation of compare operations.
      */
     public enum HSAILCompare {
    -    ICMP,
    -    LCMP,
    -    ACMP,
    -    FCMP,
    -    DCMP;
    +    ICMP(Kind.Int),
    +    LCMP(Kind.Long),
    +    ACMP(Kind.Object),
    +    FCMP(Kind.Float),
    +    DCMP(Kind.Double);
    +
    +    public final Kind kind;
    +
    +    private HSAILCompare(Kind kind) {
    +        this.kind = kind;
    +    }
     
         public static class CompareOp extends HSAILLIRInstruction {
     
    @@ -60,7 +66,7 @@
     
             @Override
             public void emitCode(CompilationResultBuilder crb, HSAILAssembler masm) {
    -            emit(crb, masm, condition, x, y, z, unordered);
    +            emit(crb, masm, opcode, condition, x, y, z, unordered);
             }
     
             @Override
    @@ -72,8 +78,8 @@
         }
     
         @SuppressWarnings("unused")
    -    public static void emit(CompilationResultBuilder crb, HSAILAssembler masm, Condition condition, Value x, Value y, Value z, boolean unorderedIsTrue) {
    -        emitCompare(masm, condition, x, y, unorderedIsTrue);
    +    public static void emit(CompilationResultBuilder crb, HSAILAssembler masm, HSAILCompare opcode, Condition condition, Value x, Value y, Value z, boolean unorderedIsTrue) {
    +        masm.emitCompare(opcode.kind, x, y, conditionToString(condition), unorderedIsTrue, isUnsignedCompare(condition));
         }
     
         public static String conditionToString(Condition condition) {
    @@ -110,9 +116,4 @@
                     return false;
             }
         }
    -
    -    private static void emitCompare(HSAILAssembler masm, Condition condition, Value src0, Value src1, boolean unordered) {
    -        masm.emitCompare(src0, src1, conditionToString(condition), unordered, isUnsignedCompare(condition));
    -    }
    -
     }
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILControlFlow.java
    --- a/graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILControlFlow.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILControlFlow.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -29,13 +29,13 @@
     import com.oracle.graal.api.meta.*;
     import com.oracle.graal.asm.*;
     import com.oracle.graal.asm.hsail.*;
    -import com.oracle.graal.graph.*;
    +import com.oracle.graal.compiler.common.*;
    +import com.oracle.graal.compiler.common.calc.*;
     import com.oracle.graal.hsail.*;
     import com.oracle.graal.lir.*;
     import com.oracle.graal.lir.StandardOp.BlockEndOp;
     import com.oracle.graal.lir.SwitchStrategy.BaseSwitchClosure;
     import com.oracle.graal.lir.asm.*;
    -import com.oracle.graal.nodes.calc.*;
     
     /**
      * Implementation of control flow instructions.
    @@ -101,7 +101,7 @@
                             case Int:
                             case Long:
                                 // Generate cascading compare and branches for each case.
    -                            masm.emitCompare(key, keyConstants[index], HSAILCompare.conditionToString(condition), false, false);
    +                            masm.emitCompare(key.getKind(), key, keyConstants[index], HSAILCompare.conditionToString(condition), false, false);
                                 masm.cbr(masm.nameOf(target));
                                 break;
                             case Object:
    @@ -129,11 +129,17 @@
             }
         }
     
    +    public interface DeoptimizingOp {
    +        public LIRFrameState getFrameState();
    +
    +        public int getCodeBufferPos();
    +    }
    +
         /***
          * The ALIVE annotation is so we can get a scratch32 register that does not clobber
          * actionAndReason.
          */
    -    public static class DeoptimizeOp extends ReturnOp {
    +    public static class DeoptimizeOp extends ReturnOp implements DeoptimizingOp {
     
             @Alive({REG, CONST}) protected Value actionAndReason;
             @State protected LIRFrameState frameState;
    @@ -173,6 +179,8 @@
                 // debugInfo)
                 codeBufferPos = masm.position();
     
    +            masm.emitComment("/* HSAIL Deoptimization pos=" + codeBufferPos + ", bci=" + frameState.debugInfo().getBytecodePosition().getBCI() + ", frameState=" + frameState + " */");
    +
                 // get the bitmap of $d regs that contain references
                 ReferenceMap referenceMap = frameState.debugInfo().getReferenceMap();
                 for (int dreg = HSAIL.d0.number; dreg <= HSAIL.d15.number; dreg++) {
    @@ -181,14 +189,9 @@
                     }
                 }
     
    -            // here we will by convention use some never-allocated registers to pass to the epilogue
    -            // deopt code
    -            // todo: define these in HSAIL.java
    -            // we need to pass the actionAndReason and the codeBufferPos
    -
    -            AllocatableValue actionAndReasonReg = HSAIL.s32.asValue(Kind.Int);
    -            AllocatableValue codeBufferOffsetReg = HSAIL.s33.asValue(Kind.Int);
    -            AllocatableValue dregOopMapReg = HSAIL.s39.asValue(Kind.Int);
    +            AllocatableValue actionAndReasonReg = HSAIL.actionAndReasonReg.asValue(Kind.Int);
    +            AllocatableValue codeBufferOffsetReg = HSAIL.codeBufferOffsetReg.asValue(Kind.Int);
    +            AllocatableValue dregOopMapReg = HSAIL.dregOopMapReg.asValue(Kind.Int);
                 masm.emitMov(Kind.Int, actionAndReasonReg, actionAndReason);
                 masm.emitMov(Kind.Int, codeBufferOffsetReg, Constant.forInt(codeBufferPos));
                 masm.emitMov(Kind.Int, dregOopMapReg, Constant.forInt(dregOopMap));
    @@ -286,10 +289,10 @@
             @Override
             public void emitCode(CompilationResultBuilder crb, HSAILAssembler masm) {
                 if (crb.isSuccessorEdge(trueDestination)) {
    -                HSAILCompare.emit(crb, masm, condition.negate(), x, y, z, !unordered);
    +                HSAILCompare.emit(crb, masm, opcode, condition.negate(), x, y, z, !unordered);
                     masm.cbr(masm.nameOf(falseDestination.label()));
                 } else {
    -                HSAILCompare.emit(crb, masm, condition, x, y, z, unordered);
    +                HSAILCompare.emit(crb, masm, opcode, condition, x, y, z, unordered);
                     masm.cbr(masm.nameOf(trueDestination.label()));
                     if (!crb.isSuccessorEdge(falseDestination)) {
                         masm.jmp(falseDestination.label());
    @@ -320,7 +323,7 @@
     
             @Override
             public void emitCode(CompilationResultBuilder crb, HSAILAssembler masm) {
    -            HSAILCompare.emit(crb, masm, condition, left, right, right, false);
    +            HSAILCompare.emit(crb, masm, opcode, condition, left, right, right, false);
                 cmove(masm, result, trueValue, falseValue);
             }
         }
    @@ -336,7 +339,7 @@
     
             @Override
             public void emitCode(CompilationResultBuilder crb, HSAILAssembler masm) {
    -            HSAILCompare.emit(crb, masm, condition, left, right, right, unorderedIsTrue);
    +            HSAILCompare.emit(crb, masm, opcode, condition, left, right, right, unorderedIsTrue);
                 cmove(masm, result, trueValue, falseValue);
             }
         }
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILMove.java
    --- a/graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILMove.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILMove.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -28,8 +28,8 @@
     import com.oracle.graal.api.code.*;
     import com.oracle.graal.api.meta.*;
     import com.oracle.graal.asm.hsail.*;
    +import com.oracle.graal.compiler.common.*;
     import com.oracle.graal.debug.*;
    -import com.oracle.graal.graph.*;
     import com.oracle.graal.lir.*;
     import com.oracle.graal.lir.StandardOp.MoveOp;
     import com.oracle.graal.lir.asm.*;
    @@ -95,6 +95,13 @@
                 super(moveKind);
                 this.result = result;
                 this.input = input;
    +            checkForNullObjectInput();
    +        }
    +
    +        private void checkForNullObjectInput() {
    +            if (result.getKind() == Kind.Object && isConstant(input) && input.getKind() == Kind.Long && ((Constant) input).asLong() == 0) {
    +                input = Constant.NULL_OBJECT;
    +            }
             }
     
             @Override
    @@ -311,24 +318,26 @@
             private final long base;
             private final int shift;
             private final int alignment;
    +        private final boolean nonNull;
     
             @Def({REG}) protected AllocatableValue result;
             @Temp({REG, HINT}) protected AllocatableValue scratch;
             @Use({REG}) protected AllocatableValue input;
     
    -        public CompressPointer(AllocatableValue result, AllocatableValue scratch, AllocatableValue input, long base, int shift, int alignment) {
    +        public CompressPointer(AllocatableValue result, AllocatableValue scratch, AllocatableValue input, long base, int shift, int alignment, boolean nonNull) {
                 this.result = result;
                 this.scratch = scratch;
                 this.input = input;
                 this.base = base;
                 this.shift = shift;
                 this.alignment = alignment;
    +            this.nonNull = nonNull;
             }
     
             @Override
             public void emitCode(CompilationResultBuilder crb, HSAILAssembler masm) {
                 masm.emitMov(Kind.Long, scratch, input);
    -            boolean testForNull = (input.getKind() == Kind.Object);
    +            boolean testForNull = !nonNull;
                 encodePointer(masm, scratch, base, shift, alignment, testForNull);
                 masm.emitConvert(result, scratch, "u32", "u64");
             }
    @@ -339,22 +348,24 @@
             private final long base;
             private final int shift;
             private final int alignment;
    +        private final boolean nonNull;
     
             @Def({REG, HINT}) protected AllocatableValue result;
             @Use({REG}) protected AllocatableValue input;
     
    -        public UncompressPointer(AllocatableValue result, AllocatableValue input, long base, int shift, int alignment) {
    +        public UncompressPointer(AllocatableValue result, AllocatableValue input, long base, int shift, int alignment, boolean nonNull) {
                 this.result = result;
                 this.input = input;
                 this.base = base;
                 this.shift = shift;
                 this.alignment = alignment;
    +            this.nonNull = nonNull;
             }
     
             @Override
             public void emitCode(CompilationResultBuilder crb, HSAILAssembler masm) {
                 masm.emitConvert(result, input, "u64", "u32");
    -            boolean testForNull = (result.getKind() == Kind.Object);
    +            boolean testForNull = !nonNull;
                 decodePointer(masm, result, base, shift, alignment, testForNull);
             }
         }
    @@ -414,12 +425,15 @@
         @Opcode("CAS")
         public static class CompareAndSwapOp extends HSAILLIRInstruction {
     
    +        private final Kind accessKind;
    +
             @Def protected AllocatableValue result;
             @Use({COMPOSITE}) protected HSAILAddressValue address;
             @Use protected AllocatableValue cmpValue;
             @Use protected AllocatableValue newValue;
     
    -        public CompareAndSwapOp(AllocatableValue result, HSAILAddressValue address, AllocatableValue cmpValue, AllocatableValue newValue) {
    +        public CompareAndSwapOp(Kind accessKind, AllocatableValue result, HSAILAddressValue address, AllocatableValue cmpValue, AllocatableValue newValue) {
    +            this.accessKind = accessKind;
                 this.result = result;
                 this.address = address;
                 this.cmpValue = cmpValue;
    @@ -428,54 +442,40 @@
     
             @Override
             public void emitCode(CompilationResultBuilder crb, HSAILAssembler masm) {
    -            masm.emitAtomicCas(result, address.toAddress(), cmpValue, newValue);
    +            masm.emitAtomicCas(accessKind, result, address.toAddress(), cmpValue, newValue);
             }
         }
     
    -    @Opcode("CAS")
    -    public static class CompareAndSwapCompressedOp extends CompareAndSwapOp {
    +    @Opcode("ATOMIC_READ_AND_ADD")
    +    public static class AtomicReadAndAddOp extends HSAILLIRInstruction {
     
    -        @Temp({REG}) private AllocatableValue scratchCmpValue64;
    -        @Temp({REG}) private AllocatableValue scratchNewValue64;
    -        @Temp({REG}) private AllocatableValue scratchCmpValue32;
    -        @Temp({REG}) private AllocatableValue scratchNewValue32;
    -        @Temp({REG}) private AllocatableValue scratchCasResult32;
    -        private final long base;
    -        private final int shift;
    -        private final int alignment;
    +        private final Kind accessKind;
    +
    +        @Def protected AllocatableValue result;
    +        @Use({COMPOSITE}) protected HSAILAddressValue address;
    +        @Use({REG, CONST}) protected Value delta;
     
    -        public CompareAndSwapCompressedOp(AllocatableValue result, HSAILAddressValue address, AllocatableValue cmpValue, AllocatableValue newValue, AllocatableValue scratchCmpValue64,
    -                        AllocatableValue scratchNewValue64, AllocatableValue scratchCmpValue32, AllocatableValue scratchNewValue32, AllocatableValue scratchCasResult32, long base, int shift,
    -                        int alignment) {
    -            super(result, address, cmpValue, newValue);
    -            this.scratchCmpValue64 = scratchCmpValue64;
    -            this.scratchNewValue64 = scratchNewValue64;
    -            this.scratchCmpValue32 = scratchCmpValue32;
    -            this.scratchNewValue32 = scratchNewValue32;
    -            this.scratchCasResult32 = scratchCasResult32;
    -            this.base = base;
    -            this.shift = shift;
    -            this.alignment = alignment;
    +        public AtomicReadAndAddOp(Kind accessKind, AllocatableValue result, HSAILAddressValue address, Value delta) {
    +            this.accessKind = accessKind;
    +            this.result = result;
    +            this.address = address;
    +            this.delta = delta;
    +        }
    +
    +        public HSAILAddressValue getAddress() {
    +            return address;
             }
     
             @Override
             public void emitCode(CompilationResultBuilder crb, HSAILAssembler masm) {
    -            // assume any encoded or decoded value could be null
    -            boolean testForNull = true;
    -            // set up scratch registers to be encoded versions
    -            masm.emitMov(Kind.Long, scratchCmpValue64, cmpValue);
    -            encodePointer(masm, scratchCmpValue64, base, shift, alignment, testForNull);
    -            masm.emitMov(Kind.Long, scratchNewValue64, newValue);
    -            encodePointer(masm, scratchNewValue64, base, shift, alignment, testForNull);
    -            // get encoded versions into 32-bit registers
    -            masm.emitConvertForceUnsigned(scratchCmpValue32, scratchCmpValue64);
    -            masm.emitConvertForceUnsigned(scratchNewValue32, scratchNewValue64);
    -            // finally do the cas
    -            masm.emitAtomicCas(scratchCasResult32, address.toAddress(), scratchCmpValue32, scratchNewValue32);
    -            // and convert the 32-bit CasResult back to 64-bit
    -            masm.emitConvertForceUnsigned(result, scratchCasResult32);
    -            // and decode/uncompress the 64-bit cas result
    -            decodePointer(masm, result, base, shift, alignment, testForNull);
    +            switch (accessKind) {
    +                case Int:
    +                case Long:
    +                    masm.emitAtomicAdd(result, address.toAddress(), delta);
    +                    break;
    +                default:
    +                    throw GraalInternalError.shouldNotReachHere();
    +            }
             }
         }
     
    @@ -521,4 +521,5 @@
                 throw GraalInternalError.shouldNotReachHere();
             }
         }
    +
     }
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXArithmetic.java
    --- a/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXArithmetic.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXArithmetic.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -42,7 +42,7 @@
     import com.oracle.graal.asm.ptx.PTXMacroAssembler.Sub;
     import com.oracle.graal.asm.ptx.PTXMacroAssembler.Ushr;
     import com.oracle.graal.asm.ptx.PTXMacroAssembler.Xor;
    -import com.oracle.graal.graph.*;
    +import com.oracle.graal.compiler.common.*;
     import com.oracle.graal.lir.*;
     import com.oracle.graal.lir.asm.*;
     
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXBitManipulationOp.java
    --- a/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXBitManipulationOp.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXBitManipulationOp.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -25,7 +25,7 @@
     import com.oracle.graal.api.code.*;
     import com.oracle.graal.api.meta.*;
     import com.oracle.graal.asm.ptx.*;
    -import com.oracle.graal.graph.*;
    +import com.oracle.graal.compiler.common.*;
     import com.oracle.graal.lir.*;
     import com.oracle.graal.lir.asm.*;
     
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXCompare.java
    --- a/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXCompare.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXCompare.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -28,10 +28,10 @@
     import com.oracle.graal.api.meta.*;
     import com.oracle.graal.asm.ptx.*;
     import com.oracle.graal.asm.ptx.PTXAssembler.Setp;
    -import com.oracle.graal.graph.*;
    +import com.oracle.graal.compiler.common.*;
    +import com.oracle.graal.compiler.common.calc.*;
     import com.oracle.graal.lir.*;
     import com.oracle.graal.lir.asm.*;
    -import com.oracle.graal.nodes.calc.*;
     
     public enum PTXCompare {
         ICMP,
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXControlFlow.java
    --- a/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXControlFlow.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXControlFlow.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,9 +22,9 @@
      */
     package com.oracle.graal.lir.ptx;
     
    +import static com.oracle.graal.compiler.common.calc.Condition.*;
     import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
     import static com.oracle.graal.lir.LIRValueUtil.*;
    -import static com.oracle.graal.nodes.calc.Condition.*;
     
     import com.oracle.graal.api.code.CompilationResult.JumpTable;
     import com.oracle.graal.api.meta.*;
    @@ -33,15 +33,27 @@
     import com.oracle.graal.asm.ptx.PTXAssembler.Setp;
     import com.oracle.graal.asm.ptx.*;
     import com.oracle.graal.asm.ptx.PTXMacroAssembler.Mov;
    -import com.oracle.graal.graph.*;
    +import com.oracle.graal.compiler.common.*;
    +import com.oracle.graal.compiler.common.calc.*;
     import com.oracle.graal.lir.*;
     import com.oracle.graal.lir.StandardOp.BlockEndOp;
     import com.oracle.graal.lir.SwitchStrategy.BaseSwitchClosure;
     import com.oracle.graal.lir.asm.*;
    -import com.oracle.graal.nodes.calc.*;
     
     public class PTXControlFlow {
     
    +    public static abstract class PTXPredicatedLIRInstruction extends PTXLIRInstruction {
    +        private int predRegNum;
    +
    +        PTXPredicatedLIRInstruction(int regNum) {
    +            predRegNum = regNum;
    +        }
    +
    +        public int getPredRegNum() {
    +            return predRegNum;
    +        }
    +    }
    +
         public static class ReturnOp extends PTXLIRInstruction {
     
             @Use({REG, ILLEGAL}) protected Value x;
    @@ -69,26 +81,25 @@
             }
         }
     
    -    public static class BranchOp extends PTXLIRInstruction implements StandardOp.BranchOp {
    +    public static class BranchOp extends PTXPredicatedLIRInstruction implements StandardOp.BranchOp {
     
             protected final Condition condition;
             protected final LabelRef trueDestination;
             protected final LabelRef falseDestination;
    -        protected int predRegNum;
     
             public BranchOp(Condition condition, LabelRef trueDestination, LabelRef falseDestination, int predReg) {
    +            super(predReg);
                 this.condition = condition;
                 this.trueDestination = trueDestination;
                 this.falseDestination = falseDestination;
    -            this.predRegNum = predReg;
             }
     
             @Override
             public void emitCode(CompilationResultBuilder crb, PTXMacroAssembler masm) {
                 if (crb.isSuccessorEdge(trueDestination)) {
    -                masm.bra(masm.nameOf(falseDestination.label()), predRegNum, false);
    +                masm.bra(masm.nameOf(falseDestination.label()), getPredRegNum(), false);
                 } else {
    -                masm.bra(masm.nameOf(trueDestination.label()), predRegNum, true);
    +                masm.bra(masm.nameOf(trueDestination.label()), getPredRegNum(), true);
                     if (!crb.isSuccessorEdge(falseDestination)) {
                         masm.jmp(falseDestination.label());
                     }
    @@ -96,49 +107,47 @@
             }
         }
     
    -    public static class CondMoveOp extends PTXLIRInstruction {
    +    public static class CondMoveOp extends PTXPredicatedLIRInstruction {
     
             @Def({REG, HINT}) protected Value result;
             @Alive({REG}) protected Value trueValue;
             @Use({REG, STACK, CONST}) protected Value falseValue;
             private final Condition condition;
    -        private final int predicate;
     
             public CondMoveOp(Variable result, Condition condition, Variable trueValue, Value falseValue, int predicateRegister) {
    +            super(predicateRegister);
                 this.result = result;
                 this.condition = condition;
                 this.trueValue = trueValue;
                 this.falseValue = falseValue;
    -            this.predicate = predicateRegister;
             }
     
             @Override
             public void emitCode(CompilationResultBuilder crb, PTXMacroAssembler masm) {
    -            cmove(crb, masm, result, false, condition, false, trueValue, falseValue, predicate);
    +            cmove(crb, masm, result, false, condition, false, trueValue, falseValue, getPredRegNum());
             }
         }
     
    -    public static class FloatCondMoveOp extends PTXLIRInstruction {
    +    public static class FloatCondMoveOp extends PTXPredicatedLIRInstruction {
     
             @Def({REG}) protected Value result;
             @Alive({REG}) protected Value trueValue;
             @Alive({REG}) protected Value falseValue;
             private final Condition condition;
             private final boolean unorderedIsTrue;
    -        private final int predicate;
     
             public FloatCondMoveOp(Variable result, Condition condition, boolean unorderedIsTrue, Variable trueValue, Variable falseValue, int predicateRegister) {
    +            super(predicateRegister);
                 this.result = result;
                 this.condition = condition;
                 this.unorderedIsTrue = unorderedIsTrue;
                 this.trueValue = trueValue;
                 this.falseValue = falseValue;
    -            this.predicate = predicateRegister;
             }
     
             @Override
             public void emitCode(CompilationResultBuilder crb, PTXMacroAssembler masm) {
    -            cmove(crb, masm, result, true, condition, unorderedIsTrue, trueValue, falseValue, predicate);
    +            cmove(crb, masm, result, true, condition, unorderedIsTrue, trueValue, falseValue, getPredRegNum());
             }
         }
     
    @@ -193,7 +202,7 @@
             }
         }
     
    -    public static class StrategySwitchOp extends PTXLIRInstruction implements BlockEndOp {
    +    public static class StrategySwitchOp extends PTXPredicatedLIRInstruction implements BlockEndOp {
     
             @Use({CONST}) protected Constant[] keyConstants;
             private final LabelRef[] keyTargets;
    @@ -201,10 +210,9 @@
             @Alive({REG}) protected Value key;
             @Temp({REG, ILLEGAL}) protected Value scratch;
             private final SwitchStrategy strategy;
    -        // Number of predicate register that would be set by this instruction.
    -        protected int predRegNum;
     
             public StrategySwitchOp(SwitchStrategy strategy, LabelRef[] keyTargets, LabelRef defaultTarget, Value key, Value scratch, int predReg) {
    +            super(predReg);
                 this.strategy = strategy;
                 this.keyConstants = strategy.keyConstants;
                 this.keyTargets = keyTargets;
    @@ -214,7 +222,6 @@
                 assert keyConstants.length == keyTargets.length;
                 assert keyConstants.length == strategy.keyProbabilities.length;
                 assert (scratch.getKind() == Kind.Illegal) == (key.getKind() == Kind.Int || key.getKind() == Kind.Long);
    -            predRegNum = predReg;
             }
     
             @Override
    @@ -228,40 +235,38 @@
                                 if (crb.codeCache.needsDataPatch(keyConstants[index])) {
                                     crb.recordInlineDataInCode(keyConstants[index]);
                                 }
    -                            new Setp(EQ, keyConstants[index], key, predRegNum).emit(masm);
    +                            new Setp(EQ, keyConstants[index], key, getPredRegNum()).emit(masm);
                                 break;
                             case Object:
                                 assert condition == Condition.EQ || condition == Condition.NE;
                                 PTXMove.move(crb, masm, scratch, keyConstants[index]);
    -                            new Setp(condition, scratch, key, predRegNum).emit(masm);
    +                            new Setp(condition, scratch, key, getPredRegNum()).emit(masm);
                                 break;
                             default:
                                 throw new GraalInternalError("switch only supported for int, long and object");
                         }
    -                    masm.bra(masm.nameOf(target), predRegNum, true);
    +                    masm.bra(masm.nameOf(target), getPredRegNum(), true);
                     }
                 };
                 strategy.run(closure);
             }
         }
     
    -    public static class TableSwitchOp extends PTXLIRInstruction implements BlockEndOp {
    +    public static class TableSwitchOp extends PTXPredicatedLIRInstruction implements BlockEndOp {
     
             private final int lowKey;
             private final LabelRef defaultTarget;
             private final LabelRef[] targets;
             @Alive protected Value index;
             @Temp protected Value scratch;
    -        // Number of predicate register that would be set by this instruction.
    -        protected int predRegNum;
     
             public TableSwitchOp(final int lowKey, final LabelRef defaultTarget, final LabelRef[] targets, Variable index, Variable scratch, int predReg) {
    +            super(predReg);
                 this.lowKey = lowKey;
                 this.defaultTarget = defaultTarget;
                 this.targets = targets;
                 this.index = index;
                 this.scratch = scratch;
    -            predRegNum = predReg;
             }
     
             @Override
    @@ -272,14 +277,14 @@
                 if (lowKey != 0) {
                     // subtract the low value from the switch value
                     // new Sub(value, value, lowKey).emit(masm);
    -                new Setp(GT, index, Constant.forInt(highKey - lowKey), predRegNum).emit(masm);
    +                new Setp(GT, index, Constant.forInt(highKey - lowKey), getPredRegNum()).emit(masm);
                 } else {
    -                new Setp(GT, index, Constant.forInt(highKey), predRegNum).emit(masm);
    +                new Setp(GT, index, Constant.forInt(highKey), getPredRegNum()).emit(masm);
                 }
     
                 // Jump to default target if index is not within the jump table
                 if (defaultTarget != null) {
    -                masm.bra(masm.nameOf(defaultTarget.label()), predRegNum, true);
    +                masm.bra(masm.nameOf(defaultTarget.label()), getPredRegNum(), true);
                 }
     
                 // address of jump table
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXMemOp.java
    --- a/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXMemOp.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXMemOp.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -31,7 +31,7 @@
     import com.oracle.graal.asm.ptx.PTXMacroAssembler.LoadAddr;
     import com.oracle.graal.asm.ptx.PTXMacroAssembler.LoadParam;
     import com.oracle.graal.asm.ptx.PTXMacroAssembler.St;
    -import com.oracle.graal.graph.*;
    +import com.oracle.graal.compiler.common.*;
     import com.oracle.graal.lir.*;
     import com.oracle.graal.lir.asm.*;
     
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXMove.java
    --- a/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXMove.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXMove.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -30,7 +30,7 @@
     import com.oracle.graal.api.meta.*;
     import com.oracle.graal.asm.ptx.*;
     import com.oracle.graal.asm.ptx.PTXMacroAssembler.Mov;
    -import com.oracle.graal.graph.*;
    +import com.oracle.graal.compiler.common.*;
     import com.oracle.graal.lir.*;
     import com.oracle.graal.lir.StandardOp.MoveOp;
     import com.oracle.graal.lir.StandardOp.NullCheck;
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXTestOp.java
    --- a/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXTestOp.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXTestOp.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -28,8 +28,8 @@
     import com.oracle.graal.api.meta.*;
     import com.oracle.graal.asm.ptx.*;
     import com.oracle.graal.asm.ptx.PTXAssembler.Setp;
    +import com.oracle.graal.compiler.common.calc.*;
     import com.oracle.graal.lir.asm.*;
    -import com.oracle.graal.nodes.calc.*;
     
     public class PTXTestOp extends PTXLIRInstruction {
     
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArithmetic.java
    --- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArithmetic.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArithmetic.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -56,10 +56,10 @@
     import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Neg;
     import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Not;
     import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Signx;
    -import com.oracle.graal.graph.*;
    +import com.oracle.graal.compiler.common.*;
     import com.oracle.graal.lir.*;
     import com.oracle.graal.lir.asm.*;
    -import com.oracle.graal.nodes.spi.*;
    +import com.oracle.graal.lir.gen.*;
     
     public enum SPARCArithmetic {
         // @formatter:off
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCBitManipulationOp.java
    --- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCBitManipulationOp.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCBitManipulationOp.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -37,10 +37,10 @@
     import com.oracle.graal.asm.sparc.SPARCAssembler.Sub;
     import com.oracle.graal.asm.sparc.*;
     import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Mov;
    -import com.oracle.graal.graph.*;
    +import com.oracle.graal.compiler.common.*;
     import com.oracle.graal.lir.*;
     import com.oracle.graal.lir.asm.*;
    -import com.oracle.graal.nodes.spi.*;
    +import com.oracle.graal.lir.gen.*;
     
     public class SPARCBitManipulationOp extends SPARCLIRInstruction {
     
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCByteSwapOp.java
    --- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCByteSwapOp.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCByteSwapOp.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -24,7 +24,7 @@
     
     import com.oracle.graal.api.meta.*;
     import com.oracle.graal.asm.sparc.*;
    -import com.oracle.graal.graph.*;
    +import com.oracle.graal.compiler.common.*;
     import com.oracle.graal.lir.*;
     import com.oracle.graal.lir.asm.*;
     
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCCompare.java
    --- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCCompare.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCCompare.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -29,7 +29,7 @@
     import com.oracle.graal.api.meta.*;
     import com.oracle.graal.asm.sparc.*;
     import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Cmp;
    -import com.oracle.graal.graph.*;
    +import com.oracle.graal.compiler.common.*;
     import com.oracle.graal.lir.*;
     import com.oracle.graal.lir.asm.*;
     
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java
    --- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -48,12 +48,12 @@
     import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Jmp;
     import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Nop;
     import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Ret;
    -import com.oracle.graal.graph.*;
    +import com.oracle.graal.compiler.common.*;
    +import com.oracle.graal.compiler.common.calc.*;
     import com.oracle.graal.lir.*;
     import com.oracle.graal.lir.StandardOp.BlockEndOp;
     import com.oracle.graal.lir.SwitchStrategy.BaseSwitchClosure;
     import com.oracle.graal.lir.asm.*;
    -import com.oracle.graal.nodes.calc.*;
     
     public class SPARCControlFlow {
     
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMathIntrinsicOp.java
    --- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMathIntrinsicOp.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMathIntrinsicOp.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -27,7 +27,7 @@
     import com.oracle.graal.api.meta.*;
     import com.oracle.graal.asm.sparc.SPARCAssembler.Fsqrtd;
     import com.oracle.graal.asm.sparc.*;
    -import com.oracle.graal.graph.*;
    +import com.oracle.graal.compiler.common.*;
     import com.oracle.graal.lir.*;
     import com.oracle.graal.lir.asm.*;
     
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java
    --- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -49,7 +49,7 @@
     import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Mov;
     import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Setuw;
     import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Setx;
    -import com.oracle.graal.graph.*;
    +import com.oracle.graal.compiler.common.*;
     import com.oracle.graal.lir.*;
     import com.oracle.graal.lir.StandardOp.ImplicitNullCheck;
     import com.oracle.graal.lir.StandardOp.MoveOp;
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCTestOp.java
    --- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCTestOp.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCTestOp.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -30,7 +30,7 @@
     import com.oracle.graal.asm.sparc.SPARCAssembler.Ldsw;
     import com.oracle.graal.asm.sparc.SPARCAssembler.Ldx;
     import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Cmp;
    -import com.oracle.graal.graph.*;
    +import com.oracle.graal.compiler.common.*;
     import com.oracle.graal.lir.asm.*;
     
     public class SPARCTestOp extends SPARCLIRInstruction {
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/CompositeValueClass.java
    --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/CompositeValueClass.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/CompositeValueClass.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -25,7 +25,7 @@
     import java.lang.reflect.*;
     import java.util.*;
     
    -import com.oracle.graal.graph.*;
    +import com.oracle.graal.compiler.common.*;
     import com.oracle.graal.lir.CompositeValue.Component;
     import com.oracle.graal.lir.LIRInstruction.OperandFlag;
     import com.oracle.graal.lir.LIRInstruction.OperandMode;
    @@ -86,7 +86,7 @@
         @Override
         protected void rescanFieldOffsets(CalcOffset calc) {
             ValueFieldScanner scanner = new ValueFieldScanner(calc);
    -        scanner.scan(clazz);
    +        scanner.scan(getClazz());
     
             OperandModeAnnotation mode = scanner.valueAnnotations.get(CompositeValue.Component.class);
             copyInto(componentOffsets, sortedLongCopy(mode.scalarOffsets, mode.arrayOffsets));
    @@ -108,7 +108,7 @@
             }
     
             @Override
    -        protected void scan(Class clazz) {
    +        public void scan(Class clazz) {
                 super.scan(clazz);
             }
     
    @@ -127,7 +127,7 @@
         @Override
         public String toString() {
             StringBuilder str = new StringBuilder();
    -        str.append(getClass().getSimpleName()).append(" ").append(clazz.getSimpleName()).append(" component[");
    +        str.append(getClass().getSimpleName()).append(" ").append(getClazz().getSimpleName()).append(" component[");
             for (int i = 0; i < componentOffsets.length; i++) {
                 str.append(i == 0 ? "" : ", ").append(componentOffsets[i]);
             }
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/ControlFlowOptimizer.java
    --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/ControlFlowOptimizer.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/ControlFlowOptimizer.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -27,7 +27,7 @@
     import java.util.*;
     
     import com.oracle.graal.debug.*;
    -import com.oracle.graal.nodes.cfg.*;
    +import com.oracle.graal.compiler.common.cfg.*;
     
     /**
      * This class performs basic optimizations on the control flow graph after LIR generation.
    @@ -49,7 +49,7 @@
         /**
          * Checks whether a block can be deleted. Only blocks with exactly one successor and an
          * unconditional branch to this successor are eligable.
    -     * 
    +     *
          * @param block the block checked for deletion
          * @return whether the block can be deleted
          */
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/EdgeMoveOptimizer.java
    --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/EdgeMoveOptimizer.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/EdgeMoveOptimizer.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -24,8 +24,8 @@
     
     import java.util.*;
     
    +import com.oracle.graal.compiler.common.cfg.*;
     import com.oracle.graal.lir.StandardOp.MoveOp;
    -import com.oracle.graal.nodes.cfg.*;
     
     /**
      * This class optimizes moves, particularly those that result from eliminating SSA form.
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIR.java
    --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIR.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIR.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -25,9 +25,9 @@
     import java.util.*;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.cfg.*;
     import com.oracle.graal.lir.LIRInstruction.StateProcedure;
     import com.oracle.graal.lir.StandardOp.BlockEndOp;
    -import com.oracle.graal.nodes.cfg.*;
     
     /**
      * This class implements the overall container for the LIR graph and directs its construction,
    @@ -105,7 +105,7 @@
     
         /**
          * Gets the linear scan ordering of blocks as a list.
    -     * 
    +     *
          * @return the blocks in linear scan order
          */
         public List> linearScanOrder() {
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInstruction.java
    --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInstruction.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInstruction.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -30,8 +30,8 @@
     
     import com.oracle.graal.api.code.*;
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.*;
     import com.oracle.graal.debug.*;
    -import com.oracle.graal.graph.*;
     import com.oracle.graal.lir.asm.*;
     
     /**
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInstructionClass.java
    --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInstructionClass.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInstructionClass.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -27,7 +27,7 @@
     
     import com.oracle.graal.api.code.*;
     import com.oracle.graal.api.meta.*;
    -import com.oracle.graal.graph.*;
    +import com.oracle.graal.compiler.common.*;
     import com.oracle.graal.lir.LIRInstruction.OperandFlag;
     import com.oracle.graal.lir.LIRInstruction.OperandMode;
     import com.oracle.graal.lir.LIRInstruction.StateProcedure;
    @@ -118,7 +118,7 @@
         @Override
         protected void rescanFieldOffsets(CalcOffset calc) {
             InstructionFieldScanner scanner = new InstructionFieldScanner(calc);
    -        scanner.scan(clazz);
    +        scanner.scan(getClazz());
     
             OperandModeAnnotation mode = scanner.valueAnnotations.get(LIRInstruction.Use.class);
             copyInto(useOffsets, sortedLongCopy(mode.scalarOffsets, mode.arrayOffsets));
    @@ -177,7 +177,7 @@
             }
     
             @Override
    -        protected void scan(Class clazz) {
    +        public void scan(Class clazz) {
                 if (clazz.getAnnotation(Opcode.class) != null) {
                     opcodeConstant = clazz.getAnnotation(Opcode.class).value();
                 }
    @@ -213,7 +213,7 @@
         @Override
         public String toString() {
             StringBuilder str = new StringBuilder();
    -        str.append(getClass().getSimpleName()).append(" ").append(clazz.getSimpleName()).append(" use[");
    +        str.append(getClass().getSimpleName()).append(" ").append(getClazz().getSimpleName()).append(" use[");
             for (int i = 0; i < useOffsets.length; i++) {
                 str.append(i == 0 ? "" : ", ").append(useOffsets[i]);
             }
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRIntrospection.java
    --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRIntrospection.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRIntrospection.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -31,7 +31,7 @@
     
     import com.oracle.graal.api.code.*;
     import com.oracle.graal.api.meta.*;
    -import com.oracle.graal.graph.*;
    +import com.oracle.graal.compiler.common.*;
     import com.oracle.graal.lir.LIRInstruction.OperandFlag;
     import com.oracle.graal.lir.LIRInstruction.OperandMode;
     import com.oracle.graal.lir.LIRInstruction.ValueProcedure;
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRVerifier.java
    --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRVerifier.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRVerifier.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -29,12 +29,12 @@
     
     import com.oracle.graal.api.code.*;
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.*;
    +import com.oracle.graal.compiler.common.cfg.*;
     import com.oracle.graal.debug.*;
    -import com.oracle.graal.graph.*;
     import com.oracle.graal.lir.LIRInstruction.OperandFlag;
     import com.oracle.graal.lir.LIRInstruction.OperandMode;
     import com.oracle.graal.lir.LIRInstruction.ValueProcedure;
    -import com.oracle.graal.nodes.cfg.*;
     
     public final class LIRVerifier {
     
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LabelRef.java
    --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LabelRef.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LabelRef.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,14 +23,14 @@
     package com.oracle.graal.lir;
     
     import com.oracle.graal.asm.*;
    +import com.oracle.graal.compiler.common.cfg.*;
     import com.oracle.graal.lir.StandardOp.BranchOp;
     import com.oracle.graal.lir.StandardOp.JumpOp;
    -import com.oracle.graal.nodes.cfg.*;
     
     /**
      * LIR instructions such as {@link JumpOp} and {@link BranchOp} need to reference their target
    - * {@link Block}. However, direct references are not possible since the control flow graph (and
    - * therefore successors lists) can be changed by optimizations - and fixing the instructions is
    + * {@link AbstractBlock}. However, direct references are not possible since the control flow graph
    + * (and therefore successors lists) can be changed by optimizations - and fixing the instructions is
      * error prone. Therefore, we represent an edge to block B from block A via the tuple {@code (A,
      * successor-index-of-B)}. That is, indirectly by storing the index into the successor list of A.
      * Note therefore that the successor list cannot be re-ordered.
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/NullCheckOptimizer.java
    --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/NullCheckOptimizer.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/NullCheckOptimizer.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -24,9 +24,9 @@
     
     import java.util.*;
     
    +import com.oracle.graal.compiler.common.cfg.*;
     import com.oracle.graal.lir.StandardOp.ImplicitNullCheck;
     import com.oracle.graal.lir.StandardOp.NullCheck;
    -import com.oracle.graal.nodes.cfg.*;
     
     public final class NullCheckOptimizer {
     
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/RedundantMoveElimination.java
    --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/RedundantMoveElimination.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/RedundantMoveElimination.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -28,12 +28,12 @@
     
     import com.oracle.graal.api.code.*;
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.cfg.*;
     import com.oracle.graal.debug.*;
     import com.oracle.graal.lir.LIRInstruction.OperandFlag;
     import com.oracle.graal.lir.LIRInstruction.OperandMode;
     import com.oracle.graal.lir.LIRInstruction.ValueProcedure;
     import com.oracle.graal.lir.StandardOp.MoveOp;
    -import com.oracle.graal.nodes.cfg.*;
     
     /**
      * Removes move instructions, where the destination value is already in place.
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/StandardOp.java
    --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/StandardOp.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/StandardOp.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -29,9 +29,9 @@
     import com.oracle.graal.api.code.*;
     import com.oracle.graal.api.meta.*;
     import com.oracle.graal.asm.*;
    -import com.oracle.graal.graph.*;
    +import com.oracle.graal.compiler.common.*;
    +import com.oracle.graal.compiler.common.cfg.*;
     import com.oracle.graal.lir.asm.*;
    -import com.oracle.graal.nodes.cfg.*;
     
     /**
      * A collection of machine-independent LIR operations, as well as interfaces to be implemented for
    @@ -154,7 +154,7 @@
     
             /**
              * Prunes {@code doNotSave} from the registers saved by this operation.
    -         * 
    +         *
              * @param doNotSave registers that should not be saved by this operation
              * @return the number of registers pruned
              * @throws UnsupportedOperationException if removal is not {@linkplain #supportsRemove()
    @@ -165,7 +165,7 @@
             /**
              * Gets a map from the saved registers saved by this operation to the frame slots in which
              * they are saved.
    -         * 
    +         *
              * @param frameMap used to {@linkplain FrameMap#indexForStackSlot(StackSlot) convert} a
              *            virtual slot to a frame slot index
              */
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/SwitchStrategy.java
    --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/SwitchStrategy.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/SwitchStrategy.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -26,8 +26,8 @@
     
     import com.oracle.graal.api.meta.*;
     import com.oracle.graal.asm.*;
    +import com.oracle.graal.compiler.common.calc.*;
     import com.oracle.graal.lir.asm.*;
    -import com.oracle.graal.nodes.calc.*;
     
     /**
      * This class encapsulates different strategies on how to generate code for switch instructions.
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/CompilationResultBuilder.java
    --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/CompilationResultBuilder.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/CompilationResultBuilder.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -30,10 +30,10 @@
     import com.oracle.graal.api.code.CompilationResult.Data;
     import com.oracle.graal.api.meta.*;
     import com.oracle.graal.asm.*;
    +import com.oracle.graal.compiler.common.*;
    +import com.oracle.graal.compiler.common.cfg.*;
     import com.oracle.graal.debug.*;
    -import com.oracle.graal.graph.*;
     import com.oracle.graal.lir.*;
    -import com.oracle.graal.nodes.cfg.*;
     
     /**
      * Fills in a {@link CompilationResult} as its code is being assembled.
    @@ -88,8 +88,8 @@
             assert frameContext != null;
         }
     
    -    public void setFrameSize(int frameSize) {
    -        compilationResult.setFrameSize(frameSize);
    +    public void setTotalFrameSize(int frameSize) {
    +        compilationResult.setTotalFrameSize(frameSize);
         }
     
         private static final CompilationResult.Mark[] NO_REFS = {};
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/gen/ArithmeticLIRGenerator.java
    --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/gen/ArithmeticLIRGenerator.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -0,0 +1,88 @@
    +/*
    + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
    + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    + *
    + * This code is free software; you can redistribute it and/or modify it
    + * under the terms of the GNU General Public License version 2 only, as
    + * published by the Free Software Foundation.
    + *
    + * This code is distributed in the hope that it will be useful, but WITHOUT
    + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    + * version 2 for more details (a copy is included in the LICENSE file that
    + * accompanied this code).
    + *
    + * You should have received a copy of the GNU General Public License version
    + * 2 along with this work; if not, write to the Free Software Foundation,
    + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    + *
    + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    + * or visit www.oracle.com if you need additional information or have any
    + * questions.
    + */
    +package com.oracle.graal.lir.gen;
    +
    +import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.calc.*;
    +import com.oracle.graal.compiler.common.type.*;
    +import com.oracle.graal.lir.*;
    +
    +/**
    + * This interface can be used to generate LIR for arithmetic operations.
    + */
    +public interface ArithmeticLIRGenerator {
    +
    +    PlatformKind getPlatformKind(Stamp stamp);
    +
    +    Value emitNegate(Value input);
    +
    +    Value emitAdd(Value a, Value b);
    +
    +    Value emitSub(Value a, Value b);
    +
    +    Value emitMul(Value a, Value b);
    +
    +    Value emitDiv(Value a, Value b, LIRFrameState state);
    +
    +    Value emitRem(Value a, Value b, LIRFrameState state);
    +
    +    Value emitUDiv(Value a, Value b, LIRFrameState state);
    +
    +    Value emitURem(Value a, Value b, LIRFrameState state);
    +
    +    Value emitNot(Value input);
    +
    +    Value emitAnd(Value a, Value b);
    +
    +    Value emitOr(Value a, Value b);
    +
    +    Value emitXor(Value a, Value b);
    +
    +    Value emitShl(Value a, Value b);
    +
    +    Value emitShr(Value a, Value b);
    +
    +    Value emitUShr(Value a, Value b);
    +
    +    Value emitFloatConvert(FloatConvert op, Value inputVal);
    +
    +    Value emitReinterpret(PlatformKind to, Value inputVal);
    +
    +    Value emitNarrow(Value inputVal, int bits);
    +
    +    Value emitSignExtend(Value inputVal, int fromBits, int toBits);
    +
    +    Value emitZeroExtend(Value inputVal, int fromBits, int toBits);
    +
    +    Value emitMathAbs(Value input);
    +
    +    Value emitMathSqrt(Value input);
    +
    +    Value emitMathLog(Value input, boolean base10);
    +
    +    Value emitMathCos(Value input);
    +
    +    Value emitMathSin(Value input);
    +
    +    Value emitMathTan(Value input);
    +}
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/gen/LIRGenerationResult.java
    --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/gen/LIRGenerationResult.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -0,0 +1,35 @@
    +/*
    + * Copyright (c) 2014, 2014, Oracle and/or its affiliates. All rights reserved.
    + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    + *
    + * This code is free software; you can redistribute it and/or modify it
    + * under the terms of the GNU General Public License version 2 only, as
    + * published by the Free Software Foundation.
    + *
    + * This code is distributed in the hope that it will be useful, but WITHOUT
    + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    + * version 2 for more details (a copy is included in the LICENSE file that
    + * accompanied this code).
    + *
    + * You should have received a copy of the GNU General Public License version
    + * 2 along with this work; if not, write to the Free Software Foundation,
    + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    + *
    + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    + * or visit www.oracle.com if you need additional information or have any
    + * questions.
    + */
    +package com.oracle.graal.lir.gen;
    +
    +import com.oracle.graal.lir.*;
    +
    +public interface LIRGenerationResult {
    +    FrameMap getFrameMap();
    +
    +    LIR getLIR();
    +
    +    boolean hasForeignCall();
    +
    +    void setForeignCall(boolean b);
    +}
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/gen/LIRGenerationResultBase.java
    --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/gen/LIRGenerationResultBase.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -0,0 +1,59 @@
    +/*
    + * Copyright (c) 2014, 2014, Oracle and/or its affiliates. All rights reserved.
    + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    + *
    + * This code is free software; you can redistribute it and/or modify it
    + * under the terms of the GNU General Public License version 2 only, as
    + * published by the Free Software Foundation.
    + *
    + * This code is distributed in the hope that it will be useful, but WITHOUT
    + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    + * version 2 for more details (a copy is included in the LICENSE file that
    + * accompanied this code).
    + *
    + * You should have received a copy of the GNU General Public License version
    + * 2 along with this work; if not, write to the Free Software Foundation,
    + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    + *
    + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    + * or visit www.oracle.com if you need additional information or have any
    + * questions.
    + */
    +package com.oracle.graal.lir.gen;
    +
    +import com.oracle.graal.lir.*;
    +
    +public class LIRGenerationResultBase implements LIRGenerationResult {
    +    private final LIR lir;
    +    private final FrameMap frameMap;
    +    /**
    +     * Records whether the code being generated makes at least one foreign call.
    +     */
    +    private boolean hasForeignCall;
    +
    +    public LIRGenerationResultBase(LIR lir, FrameMap frameMap) {
    +        this.lir = lir;
    +        this.frameMap = frameMap;
    +    }
    +
    +    public LIR getLIR() {
    +        return lir;
    +    }
    +
    +    /**
    +     * Determines whether the code being generated makes at least one foreign call.
    +     */
    +    public boolean hasForeignCall() {
    +        return hasForeignCall;
    +    }
    +
    +    public final void setForeignCall(boolean hasForeignCall) {
    +        this.hasForeignCall = hasForeignCall;
    +    }
    +
    +    public final FrameMap getFrameMap() {
    +        return frameMap;
    +    }
    +
    +}
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/gen/LIRGenerator.java
    --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/gen/LIRGenerator.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -0,0 +1,598 @@
    +/*
    + * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
    + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    + *
    + * This code is free software; you can redistribute it and/or modify it
    + * under the terms of the GNU General Public License version 2 only, as
    + * published by the Free Software Foundation.
    + *
    + * This code is distributed in the hope that it will be useful, but WITHOUT
    + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    + * version 2 for more details (a copy is included in the LICENSE file that
    + * accompanied this code).
    + *
    + * You should have received a copy of the GNU General Public License version
    + * 2 along with this work; if not, write to the Free Software Foundation,
    + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    + *
    + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    + * or visit www.oracle.com if you need additional information or have any
    + * questions.
    + */
    +package com.oracle.graal.lir.gen;
    +
    +import static com.oracle.graal.api.code.ValueUtil.*;
    +import static com.oracle.graal.api.meta.Value.*;
    +import static com.oracle.graal.compiler.common.GraalOptions.*;
    +import static com.oracle.graal.lir.LIR.*;
    +import static com.oracle.graal.lir.LIRValueUtil.*;
    +
    +import java.util.*;
    +
    +import com.oracle.graal.api.code.*;
    +import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.asm.*;
    +import com.oracle.graal.compiler.common.*;
    +import com.oracle.graal.compiler.common.calc.*;
    +import com.oracle.graal.compiler.common.cfg.*;
    +import com.oracle.graal.compiler.common.spi.*;
    +import com.oracle.graal.compiler.common.type.*;
    +import com.oracle.graal.debug.*;
    +import com.oracle.graal.lir.*;
    +import com.oracle.graal.lir.StandardOp.BlockEndOp;
    +import com.oracle.graal.lir.StandardOp.LabelOp;
    +import com.oracle.graal.lir.StandardOp.NoOp;
    +import com.oracle.graal.options.*;
    +
    +/**
    + * This class traverses the HIR instructions and generates LIR instructions from them.
    + */
    +public abstract class LIRGenerator implements ArithmeticLIRGenerator, LIRGeneratorTool, PlatformKindTool {
    +
    +    public static class Options {
    +        // @formatter:off
    +        @Option(help = "Print HIR along side LIR as the latter is generated")
    +        public static final OptionValue PrintIRWithLIR = new OptionValue<>(false);
    +        @Option(help = "The trace level for the LIR generator")
    +        public static final OptionValue TraceLIRGeneratorLevel = new OptionValue<>(0);
    +        // @formatter:on
    +    }
    +
    +    private final CodeGenProviders providers;
    +    private final CallingConvention cc;
    +
    +    protected AbstractBlock currentBlock;
    +    public final int traceLevel;
    +    public final boolean printIRWithLIR;
    +
    +    /**
    +     * Handle for an operation that loads a constant into a variable. The operation starts in the
    +     * first block where the constant is used but will eventually be
    +     * {@linkplain LIRGenerator#insertConstantLoads() moved} to a block dominating all usages of the
    +     * constant.
    +     */
    +    public static class LoadConstant implements Comparable {
    +        /**
    +         * The index of {@link #op} within {@link #block}'s instruction list or -1 if {@code op} is
    +         * to be moved to a dominator block.
    +         */
    +        int index;
    +
    +        /**
    +         * The operation that loads the constant.
    +         */
    +        private final LIRInstruction op;
    +
    +        /**
    +         * The block that does or will contain {@link #op}. This is initially the block where the
    +         * first usage of the constant is seen during LIR generation.
    +         */
    +        AbstractBlock block;
    +
    +        /**
    +         * The variable into which the constant is loaded.
    +         */
    +        final Variable variable;
    +
    +        public LoadConstant(Variable variable, AbstractBlock block, int index, LIRInstruction op) {
    +            this.variable = variable;
    +            this.block = block;
    +            this.index = index;
    +            this.op = op;
    +        }
    +
    +        /**
    +         * Sorts {@link LoadConstant} objects according to their enclosing blocks. This is used to
    +         * group loads per block in {@link LIRGenerator#insertConstantLoads()}.
    +         */
    +        public int compareTo(LoadConstant o) {
    +            if (block.getId() < o.block.getId()) {
    +                return -1;
    +            }
    +            if (block.getId() > o.block.getId()) {
    +                return 1;
    +            }
    +            return 0;
    +        }
    +
    +        @Override
    +        public String toString() {
    +            return block + "#" + op;
    +        }
    +
    +        /**
    +         * Removes the {@link #op} from its original location if it is still at that location.
    +         */
    +        public void unpin(LIR lir) {
    +            if (index >= 0) {
    +                // Replace the move with a filler op so that the operation
    +                // list does not need to be adjusted.
    +                List instructions = lir.getLIRforBlock(block);
    +                instructions.set(index, new NoOp(null, -1));
    +                index = -1;
    +            }
    +        }
    +
    +        public AbstractBlock getBlock() {
    +            return block;
    +        }
    +
    +        public void setBlock(AbstractBlock block) {
    +            this.block = block;
    +        }
    +
    +        public Variable getVariable() {
    +            return variable;
    +        }
    +
    +        public int getIndex() {
    +            return index;
    +        }
    +
    +        public void setIndex(int index) {
    +            this.index = index;
    +        }
    +    }
    +
    +    private Map constantLoads;
    +
    +    private LIRGenerationResult res;
    +
    +    /**
    +     * Checks whether the supplied constant can be used without loading it into a register for store
    +     * operations, i.e., on the right hand side of a memory access.
    +     *
    +     * @param c The constant to check.
    +     * @return True if the constant can be used directly, false if the constant needs to be in a
    +     *         register.
    +     */
    +    public abstract boolean canStoreConstant(Constant c, boolean isCompressed);
    +
    +    public LIRGenerator(CodeGenProviders providers, CallingConvention cc, LIRGenerationResult res) {
    +        this.res = res;
    +        this.providers = providers;
    +        this.cc = cc;
    +        this.traceLevel = Options.TraceLIRGeneratorLevel.getValue();
    +        this.printIRWithLIR = Options.PrintIRWithLIR.getValue();
    +    }
    +
    +    /**
    +     * Returns true if the redundant move elimination optimization should be done after register
    +     * allocation.
    +     */
    +    public boolean canEliminateRedundantMoves() {
    +        return true;
    +    }
    +
    +    @Override
    +    public TargetDescription target() {
    +        return getCodeCache().getTarget();
    +    }
    +
    +    public CodeGenProviders getProviders() {
    +        return providers;
    +    }
    +
    +    @Override
    +    public MetaAccessProvider getMetaAccess() {
    +        return providers.getMetaAccess();
    +    }
    +
    +    @Override
    +    public CodeCacheProvider getCodeCache() {
    +        return providers.getCodeCache();
    +    }
    +
    +    @Override
    +    public ForeignCallsProvider getForeignCalls() {
    +        return providers.getForeignCalls();
    +    }
    +
    +    /**
    +     * Creates a new {@linkplain Variable variable}.
    +     *
    +     * @param platformKind The kind of the new variable.
    +     * @return a new variable
    +     */
    +    @Override
    +    public Variable newVariable(PlatformKind platformKind) {
    +        return new Variable(platformKind, res.getLIR().nextVariable());
    +    }
    +
    +    @Override
    +    public RegisterAttributes attributes(Register register) {
    +        return res.getFrameMap().registerConfig.getAttributesMap()[register.number];
    +    }
    +
    +    @Override
    +    public abstract Variable emitMove(Value input);
    +
    +    public AllocatableValue asAllocatable(Value value) {
    +        if (isAllocatableValue(value)) {
    +            return asAllocatableValue(value);
    +        } else {
    +            return emitMove(value);
    +        }
    +    }
    +
    +    public Variable load(Value value) {
    +        if (!isVariable(value)) {
    +            return emitMove(value);
    +        }
    +        return (Variable) value;
    +    }
    +
    +    public Value loadNonConst(Value value) {
    +        if (isConstant(value) && !canInlineConstant((Constant) value)) {
    +            return emitMove(value);
    +        }
    +        return value;
    +    }
    +
    +    /**
    +     * Determines if only oop maps are required for the code generated from the LIR.
    +     */
    +    public boolean needOnlyOopMaps() {
    +        return false;
    +    }
    +
    +    /**
    +     * Gets the ABI specific operand used to return a value of a given kind from a method.
    +     *
    +     * @param kind the kind of value being returned
    +     * @return the operand representing the ABI defined location used return a value of kind
    +     *         {@code kind}
    +     */
    +    public AllocatableValue resultOperandFor(Kind kind) {
    +        if (kind == Kind.Void) {
    +            return ILLEGAL;
    +        }
    +        return res.getFrameMap().registerConfig.getReturnRegister(kind).asValue(kind);
    +    }
    +
    +    public void append(LIRInstruction op) {
    +        if (printIRWithLIR && !TTY.isSuppressed()) {
    +            TTY.println(op.toStringWithIdPrefix());
    +            TTY.println();
    +        }
    +        assert LIRVerifier.verify(op);
    +        res.getLIR().getLIRforBlock(currentBlock).add(op);
    +    }
    +
    +    public boolean hasBlockEnd(AbstractBlock block) {
    +        List ops = getResult().getLIR().getLIRforBlock(block);
    +        if (ops.size() == 0) {
    +            return false;
    +        }
    +        return ops.get(ops.size() - 1) instanceof BlockEndOp;
    +    }
    +
    +    public final void doBlockStart(AbstractBlock block) {
    +        if (printIRWithLIR) {
    +            TTY.print(block.toString());
    +        }
    +
    +        currentBlock = block;
    +
    +        // set up the list of LIR instructions
    +        assert res.getLIR().getLIRforBlock(block) == null : "LIR list already computed for this block";
    +        res.getLIR().setLIRforBlock(block, new ArrayList());
    +
    +        append(new LabelOp(new Label(block.getId()), block.isAligned()));
    +
    +        if (traceLevel >= 1) {
    +            TTY.println("BEGIN Generating LIR for block B" + block.getId());
    +        }
    +    }
    +
    +    public final void doBlockEnd(AbstractBlock block) {
    +
    +        if (traceLevel >= 1) {
    +            TTY.println("END Generating LIR for block B" + block.getId());
    +        }
    +
    +        currentBlock = null;
    +
    +        if (printIRWithLIR) {
    +            TTY.println();
    +        }
    +    }
    +
    +    public void emitIncomingValues(Value[] params) {
    +        ((LabelOp) res.getLIR().getLIRforBlock(currentBlock).get(0)).setIncomingValues(params);
    +    }
    +
    +    public abstract void emitJump(LabelRef label);
    +
    +    public abstract void emitCompareBranch(PlatformKind cmpKind, Value left, Value right, Condition cond, boolean unorderedIsTrue, LabelRef trueDestination, LabelRef falseDestination,
    +                    double trueDestinationProbability);
    +
    +    public abstract void emitOverflowCheckBranch(LabelRef overflow, LabelRef noOverflow, double overflowProbability);
    +
    +    public abstract void emitIntegerTestBranch(Value left, Value right, LabelRef trueDestination, LabelRef falseDestination, double trueSuccessorProbability);
    +
    +    public abstract Variable emitConditionalMove(PlatformKind cmpKind, Value leftVal, Value right, Condition cond, boolean unorderedIsTrue, Value trueValue, Value falseValue);
    +
    +    public abstract Variable emitIntegerTestMove(Value leftVal, Value right, Value trueValue, Value falseValue);
    +
    +    protected abstract void emitForeignCall(ForeignCallLinkage linkage, Value result, Value[] arguments, Value[] temps, LIRFrameState info);
    +
    +    public static AllocatableValue toStackKind(AllocatableValue value) {
    +        if (value.getKind().getStackKind() != value.getKind()) {
    +            // We only have stack-kinds in the LIR, so convert the operand kind for values from the
    +            // calling convention.
    +            if (isRegister(value)) {
    +                return asRegister(value).asValue(value.getKind().getStackKind());
    +            } else if (isStackSlot(value)) {
    +                return StackSlot.get(value.getKind().getStackKind(), asStackSlot(value).getRawOffset(), asStackSlot(value).getRawAddFrameSize());
    +            } else {
    +                throw GraalInternalError.shouldNotReachHere();
    +            }
    +        }
    +        return value;
    +    }
    +
    +    @Override
    +    public Variable emitForeignCall(ForeignCallLinkage linkage, LIRFrameState frameState, Value... args) {
    +        LIRFrameState state = null;
    +        if (linkage.canDeoptimize()) {
    +            if (frameState != null) {
    +                state = frameState;
    +            } else {
    +                assert needOnlyOopMaps();
    +                state = new LIRFrameState(null, null, null);
    +            }
    +        }
    +
    +        // move the arguments into the correct location
    +        CallingConvention linkageCc = linkage.getOutgoingCallingConvention();
    +        res.getFrameMap().callsMethod(linkageCc);
    +        assert linkageCc.getArgumentCount() == args.length : "argument count mismatch";
    +        Value[] argLocations = new Value[args.length];
    +        for (int i = 0; i < args.length; i++) {
    +            Value arg = args[i];
    +            AllocatableValue loc = linkageCc.getArgument(i);
    +            emitMove(loc, arg);
    +            argLocations[i] = loc;
    +        }
    +        res.setForeignCall(true);
    +        emitForeignCall(linkage, linkageCc.getReturn(), argLocations, linkage.getTemporaries(), state);
    +
    +        if (isLegal(linkageCc.getReturn())) {
    +            return emitMove(linkageCc.getReturn());
    +        } else {
    +            return null;
    +        }
    +    }
    +
    +    public void emitStrategySwitch(Constant[] keyConstants, double[] keyProbabilities, LabelRef[] keyTargets, LabelRef defaultTarget, Variable value) {
    +        int keyCount = keyConstants.length;
    +        SwitchStrategy strategy = SwitchStrategy.getBestStrategy(keyProbabilities, keyConstants, keyTargets);
    +        long valueRange = keyConstants[keyCount - 1].asLong() - keyConstants[0].asLong() + 1;
    +        double tableSwitchDensity = keyCount / (double) valueRange;
    +        /*
    +         * This heuristic tries to find a compromise between the effort for the best switch strategy
    +         * and the density of a tableswitch. If the effort for the strategy is at least 4, then a
    +         * tableswitch is preferred if better than a certain value that starts at 0.5 and lowers
    +         * gradually with additional effort.
    +         */
    +        if (strategy.getAverageEffort() < 4 || tableSwitchDensity < (1 / Math.sqrt(strategy.getAverageEffort()))) {
    +            emitStrategySwitch(strategy, value, keyTargets, defaultTarget);
    +        } else {
    +            int minValue = keyConstants[0].asInt();
    +            assert valueRange < Integer.MAX_VALUE;
    +            LabelRef[] targets = new LabelRef[(int) valueRange];
    +            for (int i = 0; i < valueRange; i++) {
    +                targets[i] = defaultTarget;
    +            }
    +            for (int i = 0; i < keyCount; i++) {
    +                targets[keyConstants[i].asInt() - minValue] = keyTargets[i];
    +            }
    +            emitTableSwitch(minValue, defaultTarget, targets, value);
    +        }
    +    }
    +
    +    public abstract void emitStrategySwitch(SwitchStrategy strategy, Variable key, LabelRef[] keyTargets, LabelRef defaultTarget);
    +
    +    protected abstract void emitTableSwitch(int lowKey, LabelRef defaultTarget, LabelRef[] targets, Value key);
    +
    +    public CallingConvention getCallingConvention() {
    +        return cc;
    +    }
    +
    +    @Override
    +    public void beforeRegisterAllocation() {
    +        insertConstantLoads();
    +    }
    +
    +    /**
    +     * Moves deferred {@linkplain LoadConstant loads} of constants into blocks dominating all usages
    +     * of the constant. Any operations inserted into a block are guaranteed to be immediately prior
    +     * to the first control flow instruction near the end of the block.
    +     */
    +    private void insertConstantLoads() {
    +        if (constantLoads != null) {
    +            // Remove loads where all usages are in the same block.
    +            for (Iterator> iter = constantLoads.entrySet().iterator(); iter.hasNext();) {
    +                LoadConstant lc = iter.next().getValue();
    +
    +                // Move loads of constant outside of loops
    +                if (OptScheduleOutOfLoops.getValue()) {
    +                    AbstractBlock outOfLoopDominator = lc.block;
    +                    while (outOfLoopDominator.getLoop() != null) {
    +                        outOfLoopDominator = outOfLoopDominator.getDominator();
    +                    }
    +                    if (outOfLoopDominator != lc.block) {
    +                        lc.unpin(res.getLIR());
    +                        lc.block = outOfLoopDominator;
    +                    }
    +                }
    +
    +                if (lc.index != -1) {
    +                    assert res.getLIR().getLIRforBlock(lc.block).get(lc.index) == lc.op;
    +                    iter.remove();
    +                }
    +            }
    +            if (constantLoads.isEmpty()) {
    +                return;
    +            }
    +
    +            // Sorting groups the loads per block.
    +            LoadConstant[] groupedByBlock = constantLoads.values().toArray(new LoadConstant[constantLoads.size()]);
    +            Arrays.sort(groupedByBlock);
    +
    +            int groupBegin = 0;
    +            while (true) {
    +                int groupEnd = groupBegin + 1;
    +                AbstractBlock block = groupedByBlock[groupBegin].block;
    +                while (groupEnd < groupedByBlock.length && groupedByBlock[groupEnd].block == block) {
    +                    groupEnd++;
    +                }
    +                int groupSize = groupEnd - groupBegin;
    +
    +                List ops = res.getLIR().getLIRforBlock(block);
    +                int lastIndex = ops.size() - 1;
    +                assert ops.get(lastIndex) instanceof BlockEndOp;
    +                int insertionIndex = lastIndex;
    +                for (int i = Math.max(0, lastIndex - MAX_EXCEPTION_EDGE_OP_DISTANCE_FROM_END); i < lastIndex; i++) {
    +                    if (getExceptionEdge(ops.get(i)) != null) {
    +                        insertionIndex = i;
    +                        break;
    +                    }
    +                }
    +
    +                if (groupSize == 1) {
    +                    ops.add(insertionIndex, groupedByBlock[groupBegin].op);
    +                } else {
    +                    assert groupSize > 1;
    +                    List moves = new ArrayList<>(groupSize);
    +                    for (int i = groupBegin; i < groupEnd; i++) {
    +                        moves.add(groupedByBlock[i].op);
    +                    }
    +                    ops.addAll(insertionIndex, moves);
    +                }
    +
    +                if (groupEnd == groupedByBlock.length) {
    +                    break;
    +                }
    +                groupBegin = groupEnd;
    +            }
    +            constantLoads = null;
    +        }
    +    }
    +
    +    /**
    +     * Gets a garbage value for a given kind.
    +     */
    +    protected Constant zapValueForKind(PlatformKind kind) {
    +        long dead = 0xDEADDEADDEADDEADL;
    +        switch ((Kind) kind) {
    +            case Boolean:
    +                return Constant.FALSE;
    +            case Byte:
    +                return Constant.forByte((byte) dead);
    +            case Char:
    +                return Constant.forChar((char) dead);
    +            case Short:
    +                return Constant.forShort((short) dead);
    +            case Int:
    +                return Constant.forInt((int) dead);
    +            case Double:
    +                return Constant.forDouble(Double.longBitsToDouble(dead));
    +            case Float:
    +                return Constant.forFloat(Float.intBitsToFloat((int) dead));
    +            case Long:
    +                return Constant.forLong(dead);
    +            case Object:
    +                return Constant.NULL_OBJECT;
    +            default:
    +                throw new IllegalArgumentException(kind.toString());
    +        }
    +    }
    +
    +    /**
    +     * Default implementation: Return the Java stack kind for each stamp.
    +     */
    +    public PlatformKind getPlatformKind(Stamp stamp) {
    +        return stamp.getPlatformKind(this);
    +    }
    +
    +    public PlatformKind getIntegerKind(int bits) {
    +        if (bits <= 8) {
    +            return Kind.Byte;
    +        } else if (bits <= 16) {
    +            return Kind.Short;
    +        } else if (bits <= 32) {
    +            return Kind.Int;
    +        } else {
    +            assert bits <= 64;
    +            return Kind.Long;
    +        }
    +    }
    +
    +    public PlatformKind getFloatingKind(int bits) {
    +        switch (bits) {
    +            case 32:
    +                return Kind.Float;
    +            case 64:
    +                return Kind.Double;
    +            default:
    +                throw GraalInternalError.shouldNotReachHere();
    +        }
    +    }
    +
    +    public PlatformKind getObjectKind() {
    +        return Kind.Object;
    +    }
    +
    +    public abstract void emitBitCount(Variable result, Value operand);
    +
    +    public abstract void emitBitScanForward(Variable result, Value operand);
    +
    +    public abstract void emitBitScanReverse(Variable result, Value operand);
    +
    +    public abstract void emitByteSwap(Variable result, Value operand);
    +
    +    public abstract void emitArrayEquals(Kind kind, Variable result, Value array1, Value array2, Value length);
    +
    +    public AbstractBlock getCurrentBlock() {
    +        return currentBlock;
    +    }
    +
    +    void setCurrentBlock(AbstractBlock block) {
    +        currentBlock = block;
    +    }
    +
    +    public LIRGenerationResult getResult() {
    +        return res;
    +    }
    +
    +    public Map getConstantLoads() {
    +        return constantLoads;
    +    }
    +
    +    public void setConstantLoads(Map constantLoads) {
    +        this.constantLoads = constantLoads;
    +    }
    +}
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/gen/LIRGeneratorTool.java
    --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/gen/LIRGeneratorTool.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -0,0 +1,119 @@
    +/*
    + * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
    + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    + *
    + * This code is free software; you can redistribute it and/or modify it
    + * under the terms of the GNU General Public License version 2 only, as
    + * published by the Free Software Foundation.
    + *
    + * This code is distributed in the hope that it will be useful, but WITHOUT
    + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    + * version 2 for more details (a copy is included in the LICENSE file that
    + * accompanied this code).
    + *
    + * You should have received a copy of the GNU General Public License version
    + * 2 along with this work; if not, write to the Free Software Foundation,
    + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    + *
    + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    + * or visit www.oracle.com if you need additional information or have any
    + * questions.
    + */
    +package com.oracle.graal.lir.gen;
    +
    +import com.oracle.graal.api.code.*;
    +import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.*;
    +import com.oracle.graal.lir.*;
    +
    +public interface LIRGeneratorTool extends ArithmeticLIRGenerator {
    +
    +    TargetDescription target();
    +
    +    MetaAccessProvider getMetaAccess();
    +
    +    CodeCacheProvider getCodeCache();
    +
    +    ForeignCallsProvider getForeignCalls();
    +
    +    Value emitLoad(PlatformKind kind, Value address, LIRFrameState state);
    +
    +    void emitStore(PlatformKind kind, Value address, Value input, LIRFrameState state);
    +
    +    Value emitCompareAndSwap(Value address, Value expectedValue, Value newValue, Value trueValue, Value falseValue);
    +
    +    /**
    +     * Emit an atomic read-and-add instruction.
    +     *
    +     * @param address address of the value to be read and written
    +     * @param delta the value to be added
    +     */
    +    default Value emitAtomicReadAndAdd(Value address, Value delta) {
    +        throw GraalInternalError.unimplemented();
    +    }
    +
    +    /**
    +     * Emit an atomic read-and-write instruction.
    +     *
    +     * @param address address of the value to be read and written
    +     * @param newValue the new value to be written
    +     */
    +    default Value emitAtomicReadAndWrite(Value address, Value newValue) {
    +        throw GraalInternalError.unimplemented();
    +    }
    +
    +    void emitDeoptimize(Value actionAndReason, Value failedSpeculation, LIRFrameState state);
    +
    +    Value emitForeignCall(ForeignCallLinkage linkage, LIRFrameState state, Value... args);
    +
    +    /**
    +     * Checks whether the supplied constant can be used without loading it into a register for most
    +     * operations, i.e., for commonly used arithmetic, logical, and comparison operations.
    +     *
    +     * @param c The constant to check.
    +     * @return True if the constant can be used directly, false if the constant needs to be in a
    +     *         register.
    +     */
    +    boolean canInlineConstant(Constant c);
    +
    +    boolean canStoreConstant(Constant c, boolean isCompressed);
    +
    +    RegisterAttributes attributes(Register register);
    +
    +    AllocatableValue newVariable(PlatformKind kind);
    +
    +    AllocatableValue emitMove(Value input);
    +
    +    void emitMove(AllocatableValue dst, Value src);
    +
    +    /**
    +     * Emits an op that loads the address of some raw data.
    +     *
    +     * @param dst the variable into which the address is loaded
    +     * @param data the data to be installed with the generated code
    +     */
    +    void emitData(AllocatableValue dst, byte[] data);
    +
    +    Value emitAddress(Value base, long displacement, Value index, int scale);
    +
    +    Value emitAddress(StackSlot slot);
    +
    +    void emitMembar(int barriers);
    +
    +    void emitUnwind(Value operand);
    +
    +    /**
    +     * Called just before register allocation is performed on the LIR owned by this generator.
    +     * Overriding implementations of this method must call the overridden method.
    +     */
    +    void beforeRegisterAllocation();
    +
    +    void emitIncomingValues(Value[] params);
    +
    +    /**
    +     * Emits a return instruction. Implementations need to insert a move if the input is not in the
    +     * correct location.
    +     */
    +    void emitReturn(Value input);
    +}
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.loop/src/com/oracle/graal/loop/BasicInductionVariable.java
    --- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/BasicInductionVariable.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/BasicInductionVariable.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,10 +22,10 @@
      */
     package com.oracle.graal.loop;
     
    -import com.oracle.graal.graph.*;
    +import com.oracle.graal.compiler.common.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.calc.*;
    -import com.oracle.graal.nodes.type.*;
     
     public class BasicInductionVariable extends InductionVariable {
     
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.loop/src/com/oracle/graal/loop/CountedLoopInfo.java
    --- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/CountedLoopInfo.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/CountedLoopInfo.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -25,11 +25,11 @@
     import static com.oracle.graal.nodes.calc.IntegerArithmeticNode.*;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.loop.InductionVariable.Direction;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.calc.*;
     import com.oracle.graal.nodes.extended.*;
    -import com.oracle.graal.nodes.type.*;
     
     public class CountedLoopInfo {
     
    @@ -37,9 +37,9 @@
         private InductionVariable iv;
         private ValueNode end;
         private boolean oneOff;
    -    private AbstractBeginNode body;
    +    private BeginNode body;
     
    -    CountedLoopInfo(LoopEx loop, InductionVariable iv, ValueNode end, boolean oneOff, AbstractBeginNode body) {
    +    CountedLoopInfo(LoopEx loop, InductionVariable iv, ValueNode end, boolean oneOff, BeginNode body) {
             this.loop = loop;
             this.iv = iv;
             this.end = end;
    @@ -117,7 +117,7 @@
             return oneOff;
         }
     
    -    public AbstractBeginNode getBody() {
    +    public BeginNode getBody() {
             return body;
         }
     
    @@ -143,14 +143,14 @@
             CompareNode cond; // we use a negated guard with a < condition to achieve a >=
             ConstantNode one = ConstantNode.forIntegerStamp(stamp, 1, graph);
             if (iv.direction() == Direction.Up) {
    -            IntegerArithmeticNode v1 = sub(graph, ConstantNode.forIntegerStamp(stamp, IntegerStamp.defaultMaxValue(stamp.getBits(), stamp.isUnsigned()), graph), sub(graph, iv.strideNode(), one));
    +            IntegerArithmeticNode v1 = sub(graph, ConstantNode.forIntegerStamp(stamp, IntegerStamp.defaultMaxValue(stamp.getBits()), graph), sub(graph, iv.strideNode(), one));
                 if (oneOff) {
                     v1 = sub(graph, v1, one);
                 }
                 cond = graph.unique(new IntegerLessThanNode(v1, end));
             } else {
                 assert iv.direction() == Direction.Down;
    -            IntegerArithmeticNode v1 = add(graph, ConstantNode.forIntegerStamp(stamp, IntegerStamp.defaultMinValue(stamp.getBits(), stamp.isUnsigned()), graph), sub(graph, one, iv.strideNode()));
    +            IntegerArithmeticNode v1 = add(graph, ConstantNode.forIntegerStamp(stamp, IntegerStamp.defaultMinValue(stamp.getBits()), graph), sub(graph, one, iv.strideNode()));
                 if (oneOff) {
                     v1 = add(graph, v1, one);
                 }
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.loop/src/com/oracle/graal/loop/DerivedOffsetInductionVariable.java
    --- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/DerivedOffsetInductionVariable.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/DerivedOffsetInductionVariable.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,10 +22,10 @@
      */
     package com.oracle.graal.loop;
     
    -import com.oracle.graal.graph.*;
    +import com.oracle.graal.compiler.common.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.calc.*;
    -import com.oracle.graal.nodes.type.*;
     
     public class DerivedOffsetInductionVariable extends InductionVariable {
     
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.loop/src/com/oracle/graal/loop/DerivedScaledInductionVariable.java
    --- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/DerivedScaledInductionVariable.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/DerivedScaledInductionVariable.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,9 +22,9 @@
      */
     package com.oracle.graal.loop;
     
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.calc.*;
    -import com.oracle.graal.nodes.type.*;
     
     public class DerivedScaledInductionVariable extends InductionVariable {
     
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.loop/src/com/oracle/graal/loop/InductionVariable.java
    --- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/InductionVariable.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/InductionVariable.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,9 +22,9 @@
      */
     package com.oracle.graal.loop;
     
    -import com.oracle.graal.graph.*;
    +import com.oracle.graal.compiler.common.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.nodes.*;
    -import com.oracle.graal.nodes.type.*;
     
     /**
      * This class describes a value node that is an induction variable in a counted loop.
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopEx.java
    --- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopEx.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopEx.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -25,6 +25,9 @@
     import java.util.*;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.*;
    +import com.oracle.graal.compiler.common.calc.*;
    +import com.oracle.graal.compiler.common.cfg.*;
     import com.oracle.graal.debug.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.graph.iterators.*;
    @@ -36,19 +39,19 @@
     
     public class LoopEx {
     
    -    private final Loop lirLoop;
    +    private final Loop lirLoop;
         private LoopFragmentInside inside;
         private LoopFragmentWhole whole;
         private CountedLoopInfo counted; // TODO (gd) detect
         private LoopsData data;
         private InductionVariables ivs;
     
    -    LoopEx(Loop lirLoop, LoopsData data) {
    +    LoopEx(Loop lirLoop, LoopsData data) {
             this.lirLoop = lirLoop;
             this.data = data;
         }
     
    -    public Loop lirLoop() {
    +    public Loop lirLoop() {
             return lirLoop;
         }
     
    @@ -88,7 +91,7 @@
         }
     
         public LoopBeginNode loopBegin() {
    -        return lirLoop().loopBegin();
    +        return (LoopBeginNode) lirLoop().header.getBeginNode();
         }
     
         public FixedNode predecessor() {
    @@ -123,7 +126,7 @@
             return (isCounted() ? "CountedLoop [" + counted() + "] " : "Loop ") + "(depth=" + lirLoop().depth + ") " + loopBegin();
         }
     
    -    private class InvariantPredicate extends NodePredicate {
    +    private class InvariantPredicate implements NodePredicate {
     
             @Override
             public boolean apply(Node n) {
    @@ -222,9 +225,9 @@
             return data;
         }
     
    -    public NodeBitMap nodesInLoopFrom(AbstractBeginNode point, AbstractBeginNode until) {
    -        Collection blocks = new LinkedList<>();
    -        Collection exits = new LinkedList<>();
    +    public NodeBitMap nodesInLoopFrom(BeginNode point, BeginNode until) {
    +        Collection blocks = new LinkedList<>();
    +        Collection exits = new LinkedList<>();
             Queue work = new LinkedList<>();
             ControlFlowGraph cfg = loopsData().controlFlowGraph();
             work.add(cfg.blockFor(point));
    @@ -235,7 +238,7 @@
                     continue;
                 }
                 if (lirLoop().exits.contains(b)) {
    -                exits.add(b.getBeginNode());
    +                exits.add((LoopExitNode) b.getBeginNode());
                 } else if (lirLoop().blocks.contains(b)) {
                     blocks.add(b.getBeginNode());
                     work.addAll(b.getDominated());
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragment.java
    --- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragment.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragment.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -24,14 +24,14 @@
     
     import java.util.*;
     
    +import com.oracle.graal.compiler.common.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.graph.Graph.DuplicationReplacement;
     import com.oracle.graal.graph.iterators.*;
     import com.oracle.graal.nodes.*;
    -import com.oracle.graal.nodes.VirtualState.VirtualClosure;
     import com.oracle.graal.nodes.cfg.*;
     import com.oracle.graal.nodes.java.*;
    -import com.oracle.graal.nodes.util.*;
    +import com.oracle.graal.nodes.spi.*;
     import com.oracle.graal.nodes.virtual.*;
     
     public abstract class LoopFragment {
    @@ -79,6 +79,15 @@
             duplicationMap.put(oldNode, newNode);
         }
     
    +    /**
    +     * Gets the corresponding value in this fragment. Should be called on duplicate fragments with a
    +     * node from the original fragment as argument.
    +     *
    +     * @param b original value
    +     * @return corresponding value in the peel
    +     */
    +    protected abstract ValueNode prim(ValueNode b);
    +
         public boolean isDuplicate() {
             return original != null;
         }
    @@ -141,13 +150,13 @@
             }
         }
     
    -    protected static NodeBitMap computeNodes(Graph graph, Iterable blocks) {
    -        return computeNodes(graph, blocks, Collections. emptyList());
    +    protected static NodeBitMap computeNodes(Graph graph, Iterable blocks) {
    +        return computeNodes(graph, blocks, Collections.emptyList());
         }
     
    -    protected static NodeBitMap computeNodes(Graph graph, Iterable blocks, Iterable earlyExits) {
    +    protected static NodeBitMap computeNodes(Graph graph, Iterable blocks, Iterable earlyExits) {
             final NodeBitMap nodes = graph.createNodeBitMap(true);
    -        for (AbstractBeginNode b : blocks) {
    +        for (BeginNode b : blocks) {
                 if (b.isDeleted()) {
                     continue;
                 }
    @@ -156,30 +165,21 @@
                     if (n instanceof Invoke) {
                         nodes.mark(((Invoke) n).callTarget());
                     }
    -                if (n instanceof StateSplit) {
    -                    FrameState stateAfter = ((StateSplit) n).stateAfter();
    -                    if (stateAfter != null) {
    -                        nodes.mark(stateAfter);
    -                    }
    +                if (n instanceof NodeWithState) {
    +                    NodeWithState withState = (NodeWithState) n;
    +                    withState.states().forEach(state -> state.applyToVirtual(node -> nodes.mark(node)));
                     }
                     nodes.mark(n);
                 }
             }
    -        for (AbstractBeginNode earlyExit : earlyExits) {
    +        for (LoopExitNode earlyExit : earlyExits) {
                 if (earlyExit.isDeleted()) {
                     continue;
                 }
     
                 FrameState stateAfter = earlyExit.stateAfter();
                 if (stateAfter != null) {
    -                nodes.mark(stateAfter);
    -                stateAfter.applyToVirtual(new VirtualClosure() {
    -
    -                    @Override
    -                    public void apply(VirtualState node) {
    -                        nodes.mark(node);
    -                    }
    -                });
    +                stateAfter.applyToVirtual(node -> nodes.mark(node));
                 }
                 nodes.mark(earlyExit);
                 for (ProxyNode proxy : earlyExit.proxies()) {
    @@ -188,7 +188,7 @@
             }
     
             final NodeBitMap notloopNodes = graph.createNodeBitMap(true);
    -        for (AbstractBeginNode b : blocks) {
    +        for (BeginNode b : blocks) {
                 if (b.isDeleted()) {
                     continue;
                 }
    @@ -245,19 +245,19 @@
             return false;
         }
     
    -    public static NodeIterable toHirBlocks(final Iterable blocks) {
    -        return new AbstractNodeIterable() {
    +    public static NodeIterable toHirBlocks(final Iterable blocks) {
    +        return new NodeIterable() {
     
    -            public Iterator iterator() {
    +            public Iterator iterator() {
                     final Iterator it = blocks.iterator();
    -                return new Iterator() {
    +                return new Iterator() {
     
                         @Override
                         public void remove() {
                             throw new UnsupportedOperationException();
                         }
     
    -                    public AbstractBeginNode next() {
    +                    public BeginNode next() {
                             return it.next().getBeginNode();
                         }
     
    @@ -270,6 +270,31 @@
             };
         }
     
    +    public static NodeIterable toHirExits(final Iterable blocks) {
    +        return new NodeIterable() {
    +
    +            public Iterator iterator() {
    +                final Iterator it = blocks.iterator();
    +                return new Iterator() {
    +
    +                    @Override
    +                    public void remove() {
    +                        throw new UnsupportedOperationException();
    +                    }
    +
    +                    public LoopExitNode next() {
    +                        return (LoopExitNode) it.next().getBeginNode();
    +                    }
    +
    +                    public boolean hasNext() {
    +                        return it.hasNext();
    +                    }
    +                };
    +            }
    +
    +        };
    +    }
    +
         /**
          * Merges the early exits (i.e. loop exits) that were duplicated as part of this fragment, with
          * the original fragment's exits.
    @@ -277,59 +302,56 @@
         protected void mergeEarlyExits() {
             assert isDuplicate();
             StructuredGraph graph = graph();
    -        for (AbstractBeginNode earlyExit : LoopFragment.toHirBlocks(original().loop().lirLoop().exits)) {
    -            FixedNode next = earlyExit.next();
    -            if (earlyExit.isDeleted() || !this.original().contains(earlyExit)) {
    +        for (BeginNode earlyExit : LoopFragment.toHirBlocks(original().loop().lirLoop().exits)) {
    +            LoopExitNode loopEarlyExit = (LoopExitNode) earlyExit;
    +            FixedNode next = loopEarlyExit.next();
    +            if (loopEarlyExit.isDeleted() || !this.original().contains(loopEarlyExit)) {
                     continue;
                 }
    -            AbstractBeginNode newEarlyExit = getDuplicatedNode(earlyExit);
    +            BeginNode newEarlyExit = getDuplicatedNode(loopEarlyExit);
                 if (newEarlyExit == null) {
                     continue;
                 }
    -            boolean newEarlyExitIsBegin = newEarlyExit instanceof BeginNode;
                 MergeNode merge = graph.add(new MergeNode());
                 AbstractEndNode originalEnd = graph.add(new EndNode());
                 AbstractEndNode newEnd = graph.add(new EndNode());
                 merge.addForwardEnd(originalEnd);
                 merge.addForwardEnd(newEnd);
    -            earlyExit.setNext(originalEnd);
    +            loopEarlyExit.setNext(originalEnd);
                 newEarlyExit.setNext(newEnd);
                 merge.setNext(next);
     
    -            FrameState exitState = earlyExit.stateAfter();
    +            FrameState exitState = loopEarlyExit.stateAfter();
                 FrameState state = null;
                 if (exitState != null) {
                     state = exitState;
                     exitState = exitState.duplicateWithVirtualState();
    -                earlyExit.setStateAfter(exitState);
    +                loopEarlyExit.setStateAfter(exitState);
                     merge.setStateAfter(state);
                     /*
                      * Using the old exit's state as the merge's state is necessary because some of the
                      * VirtualState nodes contained in the old exit's state may be shared by other
                      * dominated VirtualStates. Those dominated virtual states need to see the
                      * proxy->phi update that are applied below.
    -                 * 
    +                 *
                      * We now update the original fragment's nodes accordingly:
                      */
    -                state.applyToVirtual(new VirtualClosure() {
    -                    public void apply(VirtualState node) {
    -                        original.nodes.clear(node);
    -                    }
    -                });
    -                exitState.applyToVirtual(new VirtualClosure() {
    -                    public void apply(VirtualState node) {
    -                        original.nodes.mark(node);
    -                    }
    -                });
    +                state.applyToVirtual(node -> original.nodes.clear(node));
    +                exitState.applyToVirtual(node -> original.nodes.mark(node));
    +            }
    +            FrameState finalExitState = exitState;
    +
    +            for (Node anchored : loopEarlyExit.anchored().snapshot()) {
    +                anchored.replaceFirstInput(loopEarlyExit, merge);
                 }
     
    -            for (Node anchored : earlyExit.anchored().snapshot()) {
    -                anchored.replaceFirstInput(earlyExit, merge);
    -            }
    -
    -            for (final ProxyNode vpn : earlyExit.proxies().snapshot()) {
    +            boolean newEarlyExitIsLoopExit = newEarlyExit instanceof LoopExitNode;
    +            for (final ProxyNode vpn : loopEarlyExit.proxies().snapshot()) {
    +                if (vpn.usages().isEmpty()) {
    +                    continue;
    +                }
                     final ValueNode replaceWith;
    -                ProxyNode newVpn = getDuplicatedNode(vpn);
    +                ValueNode newVpn = prim(newEarlyExitIsLoopExit ? vpn : vpn.value());
                     if (newVpn != null) {
                         PhiNode phi;
                         if (vpn instanceof ValueProxyNode) {
    @@ -342,32 +364,23 @@
                             throw GraalInternalError.shouldNotReachHere();
                         }
                         phi.addInput(vpn);
    -                    phi.addInput(newEarlyExitIsBegin ? newVpn.value() : newVpn);
    +                    phi.addInput(newVpn);
                         replaceWith = phi;
                     } else {
                         replaceWith = vpn.value();
                     }
    -                for (Node usage : vpn.usages().snapshot()) {
    -                    if (!merge.isPhiAtMerge(usage)) {
    -                        if (usage instanceof VirtualState) {
    -                            VirtualState stateUsage = (VirtualState) usage;
    -                            if (exitState.isPartOfThisState(stateUsage)) {
    -                                continue;
    -                            }
    -                        }
    -                        usage.replaceFirstInput(vpn, replaceWith);
    +                vpn.replaceAtMatchingUsages(replaceWith, usage -> {
    +                    if (merge.isPhiAtMerge(usage)) {
    +                        return false;
                         }
    -                }
    -            }
    -            if (newEarlyExitIsBegin) {
    -                FrameState stateAtNewEarlyExit = newEarlyExit.stateAfter();
    -                if (stateAtNewEarlyExit != null) {
    -                    newEarlyExit.setStateAfter(null);
    -                    GraphUtil.killWithUnusedFloatingInputs(stateAtNewEarlyExit);
    -                }
    -                for (ProxyNode proxy : newEarlyExit.proxies().snapshot()) {
    -                    GraphUtil.killWithUnusedFloatingInputs(proxy);
    -                }
    +                    if (usage instanceof VirtualState) {
    +                        VirtualState stateUsage = (VirtualState) usage;
    +                        if (finalExitState.isPartOfThisState(stateUsage)) {
    +                            return false;
    +                        }
    +                    }
    +                    return true;
    +                });
                 }
             }
         }
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragmentInside.java
    --- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragmentInside.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragmentInside.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -24,12 +24,12 @@
     
     import java.util.*;
     
    +import com.oracle.graal.compiler.common.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.graph.Graph.DuplicationReplacement;
     import com.oracle.graal.graph.iterators.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.VirtualState.NodeClosure;
    -import com.oracle.graal.nodes.util.*;
     
     public class LoopFragmentInside extends LoopFragment {
     
    @@ -88,18 +88,13 @@
     
             patchNodes(dataFixBefore);
     
    -        AbstractBeginNode end = mergeEnds();
    -
    -        original().patchPeeling(this);
    +        BeginNode end = mergeEnds();
     
             mergeEarlyExits();
     
    -        AbstractBeginNode entry = getDuplicatedNode(loop.loopBegin());
    -        FrameState state = entry.stateAfter();
    -        if (state != null) {
    -            entry.setStateAfter(null);
    -            GraphUtil.killWithUnusedFloatingInputs(state);
    -        }
    +        original().patchPeeling(this);
    +
    +        BeginNode entry = getDuplicatedNode(loop.loopBegin());
             loop.entryPoint().replaceAtPredecessor(entry);
             end.setNext(loop.entryPoint());
         }
    @@ -111,13 +106,31 @@
                 whole.nodes(); // init nodes bitmap in whole
                 nodes = whole.nodes.copy();
                 // remove the phis
    -            for (PhiNode phi : loop().loopBegin().phis()) {
    +            LoopBeginNode loopBegin = loop().loopBegin();
    +            for (PhiNode phi : loopBegin.phis()) {
                     nodes.clear(phi);
                 }
    +            for (LoopExitNode exit : exits()) {
    +                FrameState exitState = exit.stateAfter();
    +                if (exitState != null) {
    +                    exitState.applyToVirtual(v -> {
    +                        if (v.usages().filter(n -> nodes.isMarked(n) && !(n instanceof VirtualState && exitState.isPartOfThisState((VirtualState) n))).isEmpty()) {
    +                            nodes.clear(v);
    +                        }
    +                    });
    +                }
    +                for (ProxyNode proxy : exit.proxies()) {
    +                    nodes.clear(proxy);
    +                }
    +            }
             }
             return nodes;
         }
     
    +    public NodeIterable exits() {
    +        return loop().loopBegin().loopExits();
    +    }
    +
         @Override
         protected DuplicationReplacement getDuplicationReplacement() {
             final LoopBeginNode loopBegin = loop().loopBegin();
    @@ -183,7 +196,22 @@
             LoopBeginNode loopBegin = loop().loopBegin();
             StructuredGraph graph = loopBegin.graph();
             List newPhis = new LinkedList<>();
    +
    +        NodeBitMap usagesToPatch = nodes.copy();
    +        for (LoopExitNode exit : exits()) {
    +            FrameState exitState = exit.stateAfter();
    +            if (exitState != null) {
    +                exitState.applyToVirtual(v -> usagesToPatch.mark(v));
    +            }
    +            for (ProxyNode proxy : exit.proxies()) {
    +                usagesToPatch.mark(proxy);
    +            }
    +        }
    +
             for (PhiNode phi : loopBegin.phis().snapshot()) {
    +            if (phi.usages().isEmpty()) {
    +                continue;
    +            }
                 ValueNode first;
                 if (loopBegin.loopEnds().count() == 1) {
                     ValueNode b = phi.valueAt(loopBegin.loopEnds().first()); // back edge value
    @@ -201,9 +229,8 @@
                 peel.putDuplicatedNode(phi, newPhi);
                 newPhis.add(newPhi);
                 for (Node usage : phi.usages().snapshot()) {
    -                if (peel.getDuplicatedNode(usage) != null) { // patch only usages that should use
    -                                                             // the new phi ie usages that were
    -                                                             // peeled
    +                // patch only usages that should use the new phi ie usages that were peeled
    +                if (usagesToPatch.isMarked(usage)) {
                         usage.replaceFirstInput(phi, newPhi);
                     }
                 }
    @@ -229,7 +256,8 @@
          * @param b original value
          * @return corresponding value in the peel
          */
    -    private ValueNode prim(ValueNode b) {
    +    @Override
    +    protected ValueNode prim(ValueNode b) {
             assert isDuplicate();
             LoopBeginNode loopBegin = original().loop().loopBegin();
             if (loopBegin.isPhiAtMerge(b)) {
    @@ -246,7 +274,7 @@
             }
         }
     
    -    private AbstractBeginNode mergeEnds() {
    +    private BeginNode mergeEnds() {
             assert isDuplicate();
             List endsToMerge = new LinkedList<>();
             Map reverseEnds = new HashMap<>(); // map peel's exit to the
    @@ -260,7 +288,7 @@
                 }
             }
             mergedInitializers = new IdentityHashMap<>();
    -        AbstractBeginNode newExit;
    +        BeginNode newExit;
             StructuredGraph graph = graph();
             if (endsToMerge.size() == 1) {
                 AbstractEndNode end = endsToMerge.get(0);
    @@ -283,6 +311,9 @@
                 }
     
                 for (final PhiNode phi : loopBegin.phis().snapshot()) {
    +                if (phi.usages().isEmpty()) {
    +                    continue;
    +                }
                     final PhiNode firstPhi = patchPhi(graph, phi, newExitMerge);
                     for (AbstractEndNode end : newExitMerge.forwardEnds()) {
                         LoopEndNode loopEnd = reverseEnds.get(end);
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragmentWhole.java
    --- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragmentWhole.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragmentWhole.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,6 +22,7 @@
      */
     package com.oracle.graal.loop;
     
    +import com.oracle.graal.compiler.common.cfg.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.graph.Graph.DuplicationReplacement;
     import com.oracle.graal.graph.iterators.*;
    @@ -56,13 +57,18 @@
         @Override
         public NodeIterable nodes() {
             if (nodes == null) {
    -            Loop lirLoop = loop().lirLoop();
    -            nodes = LoopFragment.computeNodes(graph(), LoopFragment.toHirBlocks(lirLoop.blocks), LoopFragment.toHirBlocks(lirLoop.exits));
    +            Loop lirLoop = loop().lirLoop();
    +            nodes = LoopFragment.computeNodes(graph(), LoopFragment.toHirBlocks(lirLoop.blocks), LoopFragment.toHirExits(lirLoop.exits));
             }
             return nodes;
         }
     
         @Override
    +    protected ValueNode prim(ValueNode b) {
    +        return getDuplicatedNode(b);
    +    }
    +
    +    @Override
         protected DuplicationReplacement getDuplicationReplacement() {
             final FixedNode entry = loop().entryPoint();
             final Graph graph = this.graph();
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopPolicies.java
    --- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopPolicies.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopPolicies.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,7 +22,7 @@
      */
     package com.oracle.graal.loop;
     
    -import static com.oracle.graal.phases.GraalOptions.*;
    +import static com.oracle.graal.compiler.common.GraalOptions.*;
     
     import com.oracle.graal.debug.*;
     import com.oracle.graal.graph.*;
    @@ -64,12 +64,12 @@
     
         public static boolean shouldUnswitch(LoopEx loop, ControlSplitNode controlSplit) {
             Block postDomBlock = loop.loopsData().controlFlowGraph().blockFor(controlSplit).getPostdominator();
    -        AbstractBeginNode postDom = postDomBlock != null ? postDomBlock.getBeginNode() : null;
    +        BeginNode postDom = postDomBlock != null ? postDomBlock.getBeginNode() : null;
             int loopTotal = loop.size();
             int inBranchTotal = 0;
             double maxProbability = 0;
             for (Node successor : controlSplit.successors()) {
    -            AbstractBeginNode branch = (AbstractBeginNode) successor;
    +            BeginNode branch = (BeginNode) successor;
                 inBranchTotal += loop.nodesInLoopFrom(branch, postDom).cardinality(); // this may count
                                                                                       // twice because
                                                                                       // of fall-through
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopTransformations.java
    --- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopTransformations.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopTransformations.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,7 +22,7 @@
      */
     package com.oracle.graal.loop;
     
    -import static com.oracle.graal.phases.GraalOptions.*;
    +import static com.oracle.graal.compiler.common.GraalOptions.*;
     
     import com.oracle.graal.api.code.*;
     import com.oracle.graal.graph.Graph.Mark;
    @@ -63,6 +63,7 @@
                 Mark mark = graph.getMark();
                 peel(loop);
                 canonicalizer.applyIncremental(graph, context, mark);
    +            loopBegin.removeDeadPhis();
                 loop.invalidateFragments();
                 if (iterations++ > UNROLL_LIMIT || graph.getNodeCount() > MaximumDesiredSize.getValue() * 3) {
                     throw new BailoutException("FullUnroll : Graph seems to grow out of proportion");
    @@ -81,19 +82,19 @@
             // original loop is used as first successor
             Position firstPosition = successors.nextPosition();
             NodeClass controlSplitClass = controlSplitNode.getNodeClass();
    -        controlSplitClass.set(newControlSplit, firstPosition, AbstractBeginNode.begin(originalLoop.entryPoint()));
    +        controlSplitClass.set(newControlSplit, firstPosition, BeginNode.begin(originalLoop.entryPoint()));
     
             StructuredGraph graph = controlSplitNode.graph();
             while (successors.hasNext()) {
                 Position position = successors.nextPosition();
                 // create a new loop duplicate, connect it and simplify it
                 LoopFragmentWhole duplicateLoop = originalLoop.duplicate();
    -            controlSplitClass.set(newControlSplit, position, AbstractBeginNode.begin(duplicateLoop.entryPoint()));
    +            controlSplitClass.set(newControlSplit, position, BeginNode.begin(duplicateLoop.entryPoint()));
                 ControlSplitNode duplicatedControlSplit = duplicateLoop.getDuplicatedNode(controlSplitNode);
    -            graph.removeSplitPropagate(duplicatedControlSplit, (AbstractBeginNode) controlSplitClass.get(duplicatedControlSplit, position));
    +            graph.removeSplitPropagate(duplicatedControlSplit, (BeginNode) controlSplitClass.get(duplicatedControlSplit, position));
             }
             // original loop is simplified last to avoid deleting controlSplitNode too early
    -        graph.removeSplitPropagate(controlSplitNode, (AbstractBeginNode) controlSplitClass.get(controlSplitNode, firstPosition));
    +        graph.removeSplitPropagate(controlSplitNode, (BeginNode) controlSplitClass.get(controlSplitNode, firstPosition));
             // TODO (gd) probabilities need some amount of fixup.. (probably also in other transforms)
         }
     
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopsData.java
    --- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopsData.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopsData.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -24,6 +24,7 @@
     
     import java.util.*;
     
    +import com.oracle.graal.compiler.common.cfg.*;
     import com.oracle.graal.debug.*;
     import com.oracle.graal.debug.Debug.Scope;
     import com.oracle.graal.nodes.*;
    @@ -31,7 +32,7 @@
     
     public class LoopsData {
     
    -    private Map lirLoopToEx = new IdentityHashMap<>();
    +    private Map, LoopEx> lirLoopToEx = new IdentityHashMap<>();
         private Map loopBeginToEx = new IdentityHashMap<>();
         private ControlFlowGraph cfg;
     
    @@ -42,14 +43,14 @@
                 throw Debug.handle(e);
             }
     
    -        for (Loop lirLoop : cfg.getLoops()) {
    +        for (Loop lirLoop : cfg.getLoops()) {
                 LoopEx ex = new LoopEx(lirLoop, this);
                 lirLoopToEx.put(lirLoop, ex);
                 loopBeginToEx.put(ex.loopBegin(), ex);
             }
         }
     
    -    public LoopEx loop(Loop lirLoop) {
    +    public LoopEx loop(Loop lirLoop) {
             return lirLoopToEx.get(lirLoop);
         }
     
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.loop/src/com/oracle/graal/loop/phases/LoopTransformHighPhase.java
    --- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/phases/LoopTransformHighPhase.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/phases/LoopTransformHighPhase.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,7 +22,7 @@
      */
     package com.oracle.graal.loop.phases;
     
    -import static com.oracle.graal.phases.GraalOptions.*;
    +import static com.oracle.graal.compiler.common.GraalOptions.*;
     
     import com.oracle.graal.debug.*;
     import com.oracle.graal.loop.*;
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.loop/src/com/oracle/graal/loop/phases/LoopTransformLowPhase.java
    --- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/phases/LoopTransformLowPhase.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/phases/LoopTransformLowPhase.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,7 +22,7 @@
      */
     package com.oracle.graal.loop.phases;
     
    -import static com.oracle.graal.phases.GraalOptions.*;
    +import static com.oracle.graal.compiler.common.GraalOptions.*;
     
     import com.oracle.graal.debug.*;
     import com.oracle.graal.debug.Debug.Scope;
    @@ -78,7 +78,7 @@
             sb.append(loop).append(" at ").append(controlSplit).append(" [");
             NodeClassIterator it = controlSplit.successors().iterator();
             while (it.hasNext()) {
    -            sb.append(controlSplit.probability((AbstractBeginNode) it.next()));
    +            sb.append(controlSplit.probability((BeginNode) it.next()));
                 if (it.hasNext()) {
                     sb.append(", ");
                 }
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes.test/src/com/oracle/graal/nodes/test/IntegerStampTest.java
    --- a/graal/com.oracle.graal.nodes.test/src/com/oracle/graal/nodes/test/IntegerStampTest.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes.test/src/com/oracle/graal/nodes/test/IntegerStampTest.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -27,6 +27,7 @@
     import org.junit.*;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.type.*;
     
    @@ -44,83 +45,83 @@
     
         @Test
         public void testBooleanConstant() {
    -        assertEquals(new IntegerStamp(32, false, 1, 1, 0x1, 0x1), ConstantNode.forBoolean(true, graph).stamp());
    -        assertEquals(new IntegerStamp(32, false, 0, 0, 0x0, 0x0), ConstantNode.forBoolean(false, graph).stamp());
    +        assertEquals(new IntegerStamp(32, 1, 1, 0x1, 0x1), ConstantNode.forBoolean(true, graph).stamp());
    +        assertEquals(new IntegerStamp(32, 0, 0, 0x0, 0x0), ConstantNode.forBoolean(false, graph).stamp());
         }
     
         @Test
         public void testByteConstant() {
    -        assertEquals(new IntegerStamp(32, false, 0, 0, 0x0, 0x0), ConstantNode.forByte((byte) 0, graph).stamp());
    -        assertEquals(new IntegerStamp(32, false, 16, 16, 0x10, 0x10), ConstantNode.forByte((byte) 16, graph).stamp());
    -        assertEquals(new IntegerStamp(32, false, -16, -16, 0xfffffff0L, 0xfffffff0L), ConstantNode.forByte((byte) -16, graph).stamp());
    -        assertEquals(new IntegerStamp(32, false, 127, 127, 0x7f, 0x7f), ConstantNode.forByte((byte) 127, graph).stamp());
    -        assertEquals(new IntegerStamp(32, false, -128, -128, 0xffffff80L, 0xffffff80L), ConstantNode.forByte((byte) -128, graph).stamp());
    +        assertEquals(new IntegerStamp(32, 0, 0, 0x0, 0x0), ConstantNode.forByte((byte) 0, graph).stamp());
    +        assertEquals(new IntegerStamp(32, 16, 16, 0x10, 0x10), ConstantNode.forByte((byte) 16, graph).stamp());
    +        assertEquals(new IntegerStamp(32, -16, -16, 0xfffffff0L, 0xfffffff0L), ConstantNode.forByte((byte) -16, graph).stamp());
    +        assertEquals(new IntegerStamp(32, 127, 127, 0x7f, 0x7f), ConstantNode.forByte((byte) 127, graph).stamp());
    +        assertEquals(new IntegerStamp(32, -128, -128, 0xffffff80L, 0xffffff80L), ConstantNode.forByte((byte) -128, graph).stamp());
         }
     
         @Test
         public void testShortConstant() {
    -        assertEquals(new IntegerStamp(32, false, 0, 0, 0x0, 0x0), ConstantNode.forShort((short) 0, graph).stamp());
    -        assertEquals(new IntegerStamp(32, false, 128, 128, 0x80, 0x80), ConstantNode.forShort((short) 128, graph).stamp());
    -        assertEquals(new IntegerStamp(32, false, -128, -128, 0xffffff80L, 0xffffff80L), ConstantNode.forShort((short) -128, graph).stamp());
    -        assertEquals(new IntegerStamp(32, false, 32767, 32767, 0x7fff, 0x7fff), ConstantNode.forShort((short) 32767, graph).stamp());
    -        assertEquals(new IntegerStamp(32, false, -32768, -32768, 0xffff8000L, 0xffff8000L), ConstantNode.forShort((short) -32768, graph).stamp());
    +        assertEquals(new IntegerStamp(32, 0, 0, 0x0, 0x0), ConstantNode.forShort((short) 0, graph).stamp());
    +        assertEquals(new IntegerStamp(32, 128, 128, 0x80, 0x80), ConstantNode.forShort((short) 128, graph).stamp());
    +        assertEquals(new IntegerStamp(32, -128, -128, 0xffffff80L, 0xffffff80L), ConstantNode.forShort((short) -128, graph).stamp());
    +        assertEquals(new IntegerStamp(32, 32767, 32767, 0x7fff, 0x7fff), ConstantNode.forShort((short) 32767, graph).stamp());
    +        assertEquals(new IntegerStamp(32, -32768, -32768, 0xffff8000L, 0xffff8000L), ConstantNode.forShort((short) -32768, graph).stamp());
         }
     
         @Test
         public void testCharConstant() {
    -        assertEquals(new IntegerStamp(32, false, 0, 0, 0x0, 0x0), ConstantNode.forChar((char) 0, graph).stamp());
    -        assertEquals(new IntegerStamp(32, false, 'A', 'A', 'A', 'A'), ConstantNode.forChar('A', graph).stamp());
    -        assertEquals(new IntegerStamp(32, false, 128, 128, 0x80, 0x80), ConstantNode.forChar((char) 128, graph).stamp());
    -        assertEquals(new IntegerStamp(32, false, 65535, 65535, 0xffff, 0xffff), ConstantNode.forChar((char) 65535, graph).stamp());
    +        assertEquals(new IntegerStamp(32, 0, 0, 0x0, 0x0), ConstantNode.forChar((char) 0, graph).stamp());
    +        assertEquals(new IntegerStamp(32, 'A', 'A', 'A', 'A'), ConstantNode.forChar('A', graph).stamp());
    +        assertEquals(new IntegerStamp(32, 128, 128, 0x80, 0x80), ConstantNode.forChar((char) 128, graph).stamp());
    +        assertEquals(new IntegerStamp(32, 65535, 65535, 0xffff, 0xffff), ConstantNode.forChar((char) 65535, graph).stamp());
         }
     
         @Test
         public void testIntConstant() {
    -        assertEquals(new IntegerStamp(32, false, 0, 0, 0x0, 0x0), ConstantNode.forInt(0, graph).stamp());
    -        assertEquals(new IntegerStamp(32, false, 128, 128, 0x80, 0x80), ConstantNode.forInt(128, graph).stamp());
    -        assertEquals(new IntegerStamp(32, false, -128, -128, 0xffffff80L, 0xffffff80L), ConstantNode.forInt(-128, graph).stamp());
    -        assertEquals(new IntegerStamp(32, false, Integer.MAX_VALUE, Integer.MAX_VALUE, 0x7fffffff, 0x7fffffff), ConstantNode.forInt(Integer.MAX_VALUE, graph).stamp());
    -        assertEquals(new IntegerStamp(32, false, Integer.MIN_VALUE, Integer.MIN_VALUE, 0x80000000L, 0x80000000L), ConstantNode.forInt(Integer.MIN_VALUE, graph).stamp());
    +        assertEquals(new IntegerStamp(32, 0, 0, 0x0, 0x0), ConstantNode.forInt(0, graph).stamp());
    +        assertEquals(new IntegerStamp(32, 128, 128, 0x80, 0x80), ConstantNode.forInt(128, graph).stamp());
    +        assertEquals(new IntegerStamp(32, -128, -128, 0xffffff80L, 0xffffff80L), ConstantNode.forInt(-128, graph).stamp());
    +        assertEquals(new IntegerStamp(32, Integer.MAX_VALUE, Integer.MAX_VALUE, 0x7fffffff, 0x7fffffff), ConstantNode.forInt(Integer.MAX_VALUE, graph).stamp());
    +        assertEquals(new IntegerStamp(32, Integer.MIN_VALUE, Integer.MIN_VALUE, 0x80000000L, 0x80000000L), ConstantNode.forInt(Integer.MIN_VALUE, graph).stamp());
         }
     
         @Test
         public void testLongConstant() {
    -        assertEquals(new IntegerStamp(64, false, 0, 0, 0x0, 0x0), ConstantNode.forLong(0, graph).stamp());
    -        assertEquals(new IntegerStamp(64, false, 128, 128, 0x80, 0x80), ConstantNode.forLong(128, graph).stamp());
    -        assertEquals(new IntegerStamp(64, false, -128, -128, 0xffffffffffffff80L, 0xffffffffffffff80L), ConstantNode.forLong(-128, graph).stamp());
    -        assertEquals(new IntegerStamp(64, false, Long.MAX_VALUE, Long.MAX_VALUE, 0x7fffffffffffffffL, 0x7fffffffffffffffL), ConstantNode.forLong(Long.MAX_VALUE, graph).stamp());
    -        assertEquals(new IntegerStamp(64, false, Long.MIN_VALUE, Long.MIN_VALUE, 0x8000000000000000L, 0x8000000000000000L), ConstantNode.forLong(Long.MIN_VALUE, graph).stamp());
    +        assertEquals(new IntegerStamp(64, 0, 0, 0x0, 0x0), ConstantNode.forLong(0, graph).stamp());
    +        assertEquals(new IntegerStamp(64, 128, 128, 0x80, 0x80), ConstantNode.forLong(128, graph).stamp());
    +        assertEquals(new IntegerStamp(64, -128, -128, 0xffffffffffffff80L, 0xffffffffffffff80L), ConstantNode.forLong(-128, graph).stamp());
    +        assertEquals(new IntegerStamp(64, Long.MAX_VALUE, Long.MAX_VALUE, 0x7fffffffffffffffL, 0x7fffffffffffffffL), ConstantNode.forLong(Long.MAX_VALUE, graph).stamp());
    +        assertEquals(new IntegerStamp(64, Long.MIN_VALUE, Long.MIN_VALUE, 0x8000000000000000L, 0x8000000000000000L), ConstantNode.forLong(Long.MIN_VALUE, graph).stamp());
         }
     
         @Test
         public void testPositiveRanges() {
    -        assertEquals(new IntegerStamp(32, false, 0, 0, 0, 0), StampFactory.forInteger(Kind.Int, 0, 0));
    -        assertEquals(new IntegerStamp(32, false, 0, 1, 0, 1), StampFactory.forInteger(Kind.Int, 0, 1));
    -        assertEquals(new IntegerStamp(32, false, 0, 0x123, 0, 0x1ff), StampFactory.forInteger(Kind.Int, 0, 0x123));
    -        assertEquals(new IntegerStamp(32, false, 0x120, 0x123, 0x120, 0x123), StampFactory.forInteger(Kind.Int, 0x120, 0x123));
    -        assertEquals(new IntegerStamp(32, false, 10000, 15000, 0x2000, 0x3fff), StampFactory.forInteger(Kind.Int, 10000, 15000));
    -        assertEquals(new IntegerStamp(64, false, 0, 1, 0, 1), StampFactory.forInteger(Kind.Long, 0, 1));
    -        assertEquals(new IntegerStamp(64, false, 10000, 15000, 0x2000, 0x3fff), StampFactory.forInteger(Kind.Long, 10000, 15000));
    -        assertEquals(new IntegerStamp(64, false, 140000000000L, 150000000000L, 0x2000000000L, 0x23ffffffffL), StampFactory.forInteger(Kind.Long, 140000000000L, 150000000000L));
    +        assertEquals(new IntegerStamp(32, 0, 0, 0, 0), StampFactory.forInteger(Kind.Int, 0, 0));
    +        assertEquals(new IntegerStamp(32, 0, 1, 0, 1), StampFactory.forInteger(Kind.Int, 0, 1));
    +        assertEquals(new IntegerStamp(32, 0, 0x123, 0, 0x1ff), StampFactory.forInteger(Kind.Int, 0, 0x123));
    +        assertEquals(new IntegerStamp(32, 0x120, 0x123, 0x120, 0x123), StampFactory.forInteger(Kind.Int, 0x120, 0x123));
    +        assertEquals(new IntegerStamp(32, 10000, 15000, 0x2000, 0x3fff), StampFactory.forInteger(Kind.Int, 10000, 15000));
    +        assertEquals(new IntegerStamp(64, 0, 1, 0, 1), StampFactory.forInteger(Kind.Long, 0, 1));
    +        assertEquals(new IntegerStamp(64, 10000, 15000, 0x2000, 0x3fff), StampFactory.forInteger(Kind.Long, 10000, 15000));
    +        assertEquals(new IntegerStamp(64, 140000000000L, 150000000000L, 0x2000000000L, 0x23ffffffffL), StampFactory.forInteger(Kind.Long, 140000000000L, 150000000000L));
         }
     
         @Test
         public void testNegativeRanges() {
    -        assertEquals(new IntegerStamp(32, false, -2, -1, 0xfffffffeL, 0xffffffffL), StampFactory.forInteger(Kind.Int, -2, -1));
    -        assertEquals(new IntegerStamp(32, false, -20, -10, 0xffffffe0L, 0xffffffffL), StampFactory.forInteger(Kind.Int, -20, -10));
    -        assertEquals(new IntegerStamp(32, false, -10000, 0, 0, 0xffffffffL), StampFactory.forInteger(Kind.Int, -10000, 0));
    -        assertEquals(new IntegerStamp(32, false, -10000, -1, 0xffffc000L, 0xffffffffL), StampFactory.forInteger(Kind.Int, -10000, -1));
    -        assertEquals(new IntegerStamp(32, false, -10010, -10000, 0xffffd8e0L, 0xffffd8ffL), StampFactory.forInteger(Kind.Int, -10010, -10000));
    -        assertEquals(new IntegerStamp(64, false, -2, -1, 0xfffffffffffffffeL, 0xffffffffffffffffL), StampFactory.forInteger(Kind.Long, -2, -1));
    -        assertEquals(new IntegerStamp(64, false, -10010, -10000, 0xffffffffffffd8e0L, 0xffffffffffffd8ffL), StampFactory.forInteger(Kind.Long, -10010, -10000));
    -        assertEquals(new IntegerStamp(64, false, -150000000000L, -140000000000L, 0xffffffdc00000000L, 0xffffffdfffffffffL), StampFactory.forInteger(Kind.Long, -150000000000L, -140000000000L));
    +        assertEquals(new IntegerStamp(32, -2, -1, 0xfffffffeL, 0xffffffffL), StampFactory.forInteger(Kind.Int, -2, -1));
    +        assertEquals(new IntegerStamp(32, -20, -10, 0xffffffe0L, 0xffffffffL), StampFactory.forInteger(Kind.Int, -20, -10));
    +        assertEquals(new IntegerStamp(32, -10000, 0, 0, 0xffffffffL), StampFactory.forInteger(Kind.Int, -10000, 0));
    +        assertEquals(new IntegerStamp(32, -10000, -1, 0xffffc000L, 0xffffffffL), StampFactory.forInteger(Kind.Int, -10000, -1));
    +        assertEquals(new IntegerStamp(32, -10010, -10000, 0xffffd8e0L, 0xffffd8ffL), StampFactory.forInteger(Kind.Int, -10010, -10000));
    +        assertEquals(new IntegerStamp(64, -2, -1, 0xfffffffffffffffeL, 0xffffffffffffffffL), StampFactory.forInteger(Kind.Long, -2, -1));
    +        assertEquals(new IntegerStamp(64, -10010, -10000, 0xffffffffffffd8e0L, 0xffffffffffffd8ffL), StampFactory.forInteger(Kind.Long, -10010, -10000));
    +        assertEquals(new IntegerStamp(64, -150000000000L, -140000000000L, 0xffffffdc00000000L, 0xffffffdfffffffffL), StampFactory.forInteger(Kind.Long, -150000000000L, -140000000000L));
         }
     
         @Test
         public void testMixedRanges() {
    -        assertEquals(new IntegerStamp(32, false, -1, 0, 0, 0xffffffffL), StampFactory.forInteger(Kind.Int, -1, 0));
    -        assertEquals(new IntegerStamp(32, false, -10000, 1000, 0, 0xffffffffL), StampFactory.forInteger(Kind.Int, -10000, 1000));
    -        assertEquals(new IntegerStamp(64, false, -10000, 1000, 0, 0xffffffffffffffffL), StampFactory.forInteger(Kind.Long, -10000, 1000));
    +        assertEquals(new IntegerStamp(32, -1, 0, 0, 0xffffffffL), StampFactory.forInteger(Kind.Int, -1, 0));
    +        assertEquals(new IntegerStamp(32, -10000, 1000, 0, 0xffffffffL), StampFactory.forInteger(Kind.Int, -10000, 1000));
    +        assertEquals(new IntegerStamp(64, -10000, 1000, 0, 0xffffffffffffffffL), StampFactory.forInteger(Kind.Long, -10000, 1000));
         }
     
         @Test
    @@ -159,15 +160,15 @@
     
         @Test
         public void testXor() {
    -        assertEquals(new IntegerStamp(32, false, 0, 0xff, 0, 0xff), StampTool.xor(new IntegerStamp(32, false, 0, 0, 0, 0), new IntegerStamp(32, false, 0, 0xff, 0, 0xff)));
    -        assertEquals(new IntegerStamp(32, false, 0x10, 0x1f, 0x10, 0x1f), StampTool.xor(new IntegerStamp(32, false, 0, 0, 0, 0), new IntegerStamp(32, false, 0x10, 0x1f, 0x10, 0x1f)));
    -        assertEquals(new IntegerStamp(32, false, 0x0, 0xf, 0x0, 0xf), StampTool.xor(new IntegerStamp(32, false, 0x10, 0x10, 0x10, 0x10), new IntegerStamp(32, false, 0x10, 0x1f, 0x10, 0x1f)));
    -        assertEquals(new IntegerStamp(32, false, 0x10, 0x1f, 0x10, 0x1f), StampTool.xor(new IntegerStamp(32, false, 0x10, 0x10, 0x10, 0x10), new IntegerStamp(32, false, 0x0, 0xf, 0x0, 0xf)));
    +        assertEquals(new IntegerStamp(32, 0, 0xff, 0, 0xff), StampTool.xor(new IntegerStamp(32, 0, 0, 0, 0), new IntegerStamp(32, 0, 0xff, 0, 0xff)));
    +        assertEquals(new IntegerStamp(32, 0x10, 0x1f, 0x10, 0x1f), StampTool.xor(new IntegerStamp(32, 0, 0, 0, 0), new IntegerStamp(32, 0x10, 0x1f, 0x10, 0x1f)));
    +        assertEquals(new IntegerStamp(32, 0x0, 0xf, 0x0, 0xf), StampTool.xor(new IntegerStamp(32, 0x10, 0x10, 0x10, 0x10), new IntegerStamp(32, 0x10, 0x1f, 0x10, 0x1f)));
    +        assertEquals(new IntegerStamp(32, 0x10, 0x1f, 0x10, 0x1f), StampTool.xor(new IntegerStamp(32, 0x10, 0x10, 0x10, 0x10), new IntegerStamp(32, 0x0, 0xf, 0x0, 0xf)));
         }
     
         @Test
         public void testNot() {
    -        assertEquals(new IntegerStamp(32, false, -11, -1, 0xffff_fff0L, 0xffff_ffffL), StampTool.not(new IntegerStamp(32, false, 0, 10, 0, 0xf)));
    +        assertEquals(new IntegerStamp(32, -11, -1, 0xffff_fff0L, 0xffff_ffffL), StampTool.not(new IntegerStamp(32, 0, 10, 0, 0xf)));
         }
     
         @Test
    @@ -258,13 +259,13 @@
     
         @Test
         public void testAnd() {
    -        assertEquals(new IntegerStamp(32, false, Integer.MIN_VALUE, 0x40000000L, 0, 0xc0000000L), StampTool.and(StampFactory.forKind(Kind.Int), StampFactory.forConstant(Constant.forInt(0xc0000000))));
    +        assertEquals(new IntegerStamp(32, Integer.MIN_VALUE, 0x40000000L, 0, 0xc0000000L), StampTool.and(StampFactory.forKind(Kind.Int), StampFactory.forConstant(Constant.forInt(0xc0000000))));
         }
     
         private static void testSignExtendShort(long lower, long upper) {
    -        Stamp shortStamp = StampFactory.forInteger(16, false, lower, upper);
    +        Stamp shortStamp = StampFactory.forInteger(16, lower, upper);
             Stamp intStamp = StampTool.signExtend(shortStamp, 32);
    -        assertEquals(StampFactory.forInteger(32, false, lower, upper), intStamp);
    +        assertEquals(StampFactory.forInteger(32, lower, upper), intStamp);
         }
     
         @Test
    @@ -278,9 +279,9 @@
         }
     
         private static void testZeroExtendShort(long lower, long upper, long newLower, long newUpper) {
    -        Stamp shortStamp = StampFactory.forInteger(16, false, lower, upper);
    +        Stamp shortStamp = StampFactory.forInteger(16, lower, upper);
             Stamp intStamp = StampTool.zeroExtend(shortStamp, 32);
    -        assertEquals(StampFactory.forInteger(32, false, newLower, newUpper), intStamp);
    +        assertEquals(StampFactory.forInteger(32, newLower, newUpper), intStamp);
         }
     
         @Test
    @@ -292,36 +293,4 @@
             testZeroExtendShort(-1, 1, 0, 0xFFFF);
             testZeroExtendShort(Short.MIN_VALUE, Short.MAX_VALUE, 0, 0xFFFF);
         }
    -
    -    private static void testSignExtendChar(long lower, long upper, long newLower, long newUpper) {
    -        Stamp charStamp = StampFactory.forInteger(16, true, lower, upper);
    -        Stamp uintStamp = StampTool.signExtend(charStamp, 32);
    -        assertEquals(StampFactory.forInteger(32, true, newLower, newUpper), uintStamp);
    -    }
    -
    -    @Test
    -    public void testSignExtendUnsigned() {
    -        testSignExtendChar(5, 7, 5, 7);
    -        testSignExtendChar(0, 42, 0, 42);
    -        testSignExtendChar(5, 0xF000, 5, 0xFFFFF000L);
    -        testSignExtendChar(0, 0xF000, 0, 0xFFFFF000L);
    -        testSignExtendChar(0xF000, Character.MAX_VALUE, 0xFFFFF000L, 0xFFFFFFFFL);
    -        testSignExtendChar(Character.MIN_VALUE, Character.MAX_VALUE, 0, 0xFFFFFFFFL);
    -    }
    -
    -    private static void testZeroExtendChar(long lower, long upper) {
    -        Stamp charStamp = StampFactory.forInteger(16, true, lower, upper);
    -        Stamp uintStamp = StampTool.zeroExtend(charStamp, 32);
    -        assertEquals(StampFactory.forInteger(32, true, lower, upper), uintStamp);
    -    }
    -
    -    @Test
    -    public void testZeroExtendUnsigned() {
    -        testZeroExtendChar(5, 7);
    -        testZeroExtendChar(0, 42);
    -        testZeroExtendChar(5, 0xF000);
    -        testZeroExtendChar(0, 0xF000);
    -        testZeroExtendChar(0xF000, Character.MAX_VALUE);
    -        testZeroExtendChar(Character.MIN_VALUE, Character.MAX_VALUE);
    -    }
     }
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes.test/src/com/oracle/graal/nodes/test/ObjectStampJoinTest.java
    --- a/graal/com.oracle.graal.nodes.test/src/com/oracle/graal/nodes/test/ObjectStampJoinTest.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes.test/src/com/oracle/graal/nodes/test/ObjectStampJoinTest.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -25,6 +25,7 @@
     import org.junit.*;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.compiler.test.*;
     import com.oracle.graal.nodes.type.*;
     
    @@ -80,7 +81,7 @@
         public void testJoin3() {
             Stamp d = StampFactory.declared(getType(D.class));
             Stamp c = StampFactory.declared(getType(C.class));
    -        Assert.assertTrue(ObjectStamp.isObjectAlwaysNull(join(c, d)));
    +        Assert.assertTrue(StampTool.isObjectAlwaysNull(join(c, d)));
         }
     
         @Test
    @@ -95,9 +96,9 @@
             Stamp dExact = StampFactory.exact(getType(D.class));
             Stamp c = StampFactory.declared(getType(C.class));
             Stamp join = join(c, dExact);
    -        Assert.assertTrue(ObjectStamp.isObjectAlwaysNull(join));
    -        Assert.assertNull(ObjectStamp.typeOrNull(join));
    -        Assert.assertFalse(ObjectStamp.isExactType(join));
    +        Assert.assertTrue(StampTool.isObjectAlwaysNull(join));
    +        Assert.assertNull(StampTool.typeOrNull(join));
    +        Assert.assertFalse(StampTool.isExactType(join));
         }
     
         @Test
    @@ -106,8 +107,8 @@
             Stamp alwaysNull = StampFactory.alwaysNull();
             Stamp join = join(alwaysNull, dExactNonNull);
             Assert.assertFalse(join.isLegal());
    -        Assert.assertFalse(ObjectStamp.isObjectNonNull(join));
    -        Assert.assertFalse(ObjectStamp.isObjectAlwaysNull(join));
    +        Assert.assertFalse(StampTool.isObjectNonNull(join));
    +        Assert.assertFalse(StampTool.isObjectAlwaysNull(join));
         }
     
         @Test
    @@ -115,9 +116,9 @@
             Stamp aExact = StampFactory.exact(getType(A.class));
             Stamp e = StampFactory.declared(getType(E.class));
             Stamp join = join(aExact, e);
    -        Assert.assertTrue(ObjectStamp.isObjectAlwaysNull(join));
    -        Assert.assertNull(ObjectStamp.typeOrNull(join));
    -        Assert.assertFalse(ObjectStamp.isExactType(join));
    +        Assert.assertTrue(StampTool.isObjectAlwaysNull(join));
    +        Assert.assertNull(StampTool.typeOrNull(join));
    +        Assert.assertFalse(StampTool.isExactType(join));
         }
     
         @Test
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractBeginNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractBeginNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    @@ -1,194 +0,0 @@
    -/*
    - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
    - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    - *
    - * This code is free software; you can redistribute it and/or modify it
    - * under the terms of the GNU General Public License version 2 only, as
    - * published by the Free Software Foundation.
    - *
    - * This code is distributed in the hope that it will be useful, but WITHOUT
    - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    - * version 2 for more details (a copy is included in the LICENSE file that
    - * accompanied this code).
    - *
    - * You should have received a copy of the GNU General Public License version
    - * 2 along with this work; if not, write to the Free Software Foundation,
    - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    - *
    - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    - * or visit www.oracle.com if you need additional information or have any
    - * questions.
    - */
    -package com.oracle.graal.nodes;
    -
    -import static com.oracle.graal.graph.iterators.NodePredicates.*;
    -
    -import java.util.*;
    -
    -import com.oracle.graal.graph.*;
    -import com.oracle.graal.graph.iterators.*;
    -import com.oracle.graal.graph.spi.*;
    -import com.oracle.graal.nodes.extended.*;
    -import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
    -
    -@NodeInfo(allowedUsageTypes = {InputType.Guard, InputType.Anchor})
    -public abstract class AbstractBeginNode extends FixedWithNextNode implements StateSplit, LIRLowerable, Simplifiable, GuardingNode, AnchoringNode, IterableNodeType {
    -
    -    @Input(InputType.State) private FrameState stateAfter;
    -
    -    public FrameState stateAfter() {
    -        return stateAfter;
    -    }
    -
    -    public void setStateAfter(FrameState x) {
    -        assert x == null || x.isAlive() : "frame state must be in a graph";
    -        updateUsages(stateAfter, x);
    -        stateAfter = x;
    -    }
    -
    -    public boolean hasSideEffect() {
    -        return false;
    -    }
    -
    -    protected AbstractBeginNode() {
    -        super(StampFactory.forVoid());
    -    }
    -
    -    protected AbstractBeginNode(Stamp stamp) {
    -        super(stamp);
    -    }
    -
    -    public static AbstractBeginNode begin(FixedNode with) {
    -        if (with instanceof AbstractBeginNode) {
    -            return (AbstractBeginNode) with;
    -        }
    -        AbstractBeginNode begin = with.graph().add(new BeginNode());
    -        begin.setNext(with);
    -        return begin;
    -    }
    -
    -    @Override
    -    public void simplify(SimplifierTool tool) {
    -        FixedNode prev = (FixedNode) this.predecessor();
    -        if (prev == null) {
    -            // This is the start node.
    -        } else if (prev instanceof ControlSplitNode) {
    -            // This begin node is necessary.
    -        } else {
    -            // This begin node can be removed and all guards moved up to the preceding begin node.
    -            prepareDelete();
    -            tool.addToWorkList(next());
    -            graph().removeFixed(this);
    -        }
    -    }
    -
    -    public static AbstractBeginNode prevBegin(FixedNode from) {
    -        Node prevBegin = from;
    -        while (prevBegin != null) {
    -            if (prevBegin instanceof AbstractBeginNode) {
    -                return (AbstractBeginNode) prevBegin;
    -            }
    -            prevBegin = prevBegin.predecessor();
    -        }
    -        return null;
    -    }
    -
    -    private void evacuateGuards(FixedNode evacuateFrom) {
    -        if (!usages().isEmpty()) {
    -            AbstractBeginNode prevBegin = prevBegin(evacuateFrom);
    -            assert prevBegin != null;
    -            for (Node anchored : anchored().snapshot()) {
    -                anchored.replaceFirstInput(this, prevBegin);
    -            }
    -        }
    -    }
    -
    -    public void prepareDelete() {
    -        prepareDelete((FixedNode) predecessor());
    -    }
    -
    -    public void prepareDelete(FixedNode evacuateFrom) {
    -        removeProxies();
    -        evacuateGuards(evacuateFrom);
    -    }
    -
    -    public void removeProxies() {
    -        for (ProxyNode vpn : proxies().snapshot()) {
    -            // can not use graph.replaceFloating because vpn.value may be null during killCFG
    -            vpn.replaceAtUsages(vpn.value());
    -            vpn.safeDelete();
    -        }
    -    }
    -
    -    @Override
    -    public boolean verify() {
    -        assertTrue(predecessor() != null || this == graph().start() || this instanceof MergeNode, "begin nodes must be connected");
    -        return super.verify();
    -    }
    -
    -    @Override
    -    public void generate(NodeLIRBuilderTool gen) {
    -        // nop
    -    }
    -
    -    public NodeIterable guards() {
    -        return usages().filter(GuardNode.class);
    -    }
    -
    -    public NodeIterable anchored() {
    -        return usages().filter(isNotA(ProxyNode.class));
    -    }
    -
    -    public NodeIterable proxies() {
    -        return usages().filter(ProxyNode.class);
    -    }
    -
    -    public NodeIterable getBlockNodes() {
    -        return new AbstractNodeIterable() {
    -
    -            @Override
    -            public Iterator iterator() {
    -                return new BlockNodeIterator(AbstractBeginNode.this);
    -            }
    -        };
    -    }
    -
    -    private class BlockNodeIterator implements Iterator {
    -
    -        private FixedNode current;
    -
    -        public BlockNodeIterator(FixedNode next) {
    -            this.current = next;
    -        }
    -
    -        @Override
    -        public boolean hasNext() {
    -            return current != null;
    -        }
    -
    -        @Override
    -        public FixedNode next() {
    -            FixedNode ret = current;
    -            if (ret == null) {
    -                throw new NoSuchElementException();
    -            }
    -            if (!(current instanceof FixedWithNextNode) || (current instanceof AbstractBeginNode && current != AbstractBeginNode.this)) {
    -                current = null;
    -            } else {
    -                current = ((FixedWithNextNode) current).next();
    -            }
    -            return ret;
    -        }
    -
    -        @Override
    -        public void remove() {
    -            throw new UnsupportedOperationException();
    -        }
    -    }
    -
    -    public FrameState getState() {
    -        return stateAfter();
    -    }
    -}
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractDeoptimizeNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractDeoptimizeNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractDeoptimizeNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,8 +23,8 @@
     package com.oracle.graal.nodes;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
    -import com.oracle.graal.nodes.type.*;
     
     /**
      * This node represents an unconditional explicit request for immediate deoptimization.
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractEndNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractEndNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractEndNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -24,9 +24,9 @@
     
     import java.util.*;
     
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
     
     public abstract class AbstractEndNode extends FixedNode implements IterableNodeType, LIRLowerable {
     
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractFixedGuardNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractFixedGuardNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractFixedGuardNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,10 +23,10 @@
     package com.oracle.graal.nodes;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.graph.spi.*;
     import com.oracle.graal.nodes.extended.*;
    -import com.oracle.graal.nodes.type.*;
     import com.oracle.graal.nodes.util.*;
     
     public abstract class AbstractFixedGuardNode extends DeoptimizingFixedWithNextNode implements Simplifiable, GuardingNode {
    @@ -89,7 +89,7 @@
             DeoptimizeNode deopt = graph().add(new DeoptimizeNode(action, reason));
             deopt.setStateBefore(stateBefore());
             IfNode ifNode;
    -        AbstractBeginNode noDeoptSuccessor;
    +        BeginNode noDeoptSuccessor;
             if (negated) {
                 ifNode = graph().add(new IfNode(condition, deopt, next, 0));
                 noDeoptSuccessor = ifNode.falseSuccessor();
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractLocalNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractLocalNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractLocalNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,8 +22,8 @@
      */
     package com.oracle.graal.nodes;
     
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.nodes.calc.*;
    -import com.oracle.graal.nodes.type.*;
     
     public abstract class AbstractLocalNode extends FloatingNode {
     
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractMemoryCheckpoint.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractMemoryCheckpoint.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractMemoryCheckpoint.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,8 +22,8 @@
      */
     package com.oracle.graal.nodes;
     
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.nodes.extended.*;
    -import com.oracle.graal.nodes.type.*;
     
     /**
      * Provides an implementation of {@link StateSplit}.
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractStateSplit.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractStateSplit.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractStateSplit.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,8 +22,8 @@
      */
     package com.oracle.graal.nodes;
     
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
    -import com.oracle.graal.nodes.type.*;
     
     /**
      * Provides an implementation of {@link StateSplit}.
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/BeginNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/BeginNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/BeginNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 2013, 2013, Oracle and/or its affiliates. All rights reserved.
    + * 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
    @@ -22,11 +22,153 @@
      */
     package com.oracle.graal.nodes;
     
    -import com.oracle.graal.nodes.type.*;
    +import static com.oracle.graal.graph.iterators.NodePredicates.*;
    +
    +import java.util.*;
     
    -public final class BeginNode extends AbstractBeginNode {
    +import com.oracle.graal.compiler.common.type.*;
    +import com.oracle.graal.graph.*;
    +import com.oracle.graal.graph.iterators.*;
    +import com.oracle.graal.graph.spi.*;
    +import com.oracle.graal.nodes.extended.*;
    +import com.oracle.graal.nodes.spi.*;
    +
    +@NodeInfo(allowedUsageTypes = {InputType.Guard, InputType.Anchor})
    +public class BeginNode extends FixedWithNextNode implements LIRLowerable, Simplifiable, GuardingNode, AnchoringNode, IterableNodeType {
     
         public BeginNode() {
             super(StampFactory.forVoid());
         }
    +
    +    public BeginNode(Stamp stamp) {
    +        super(stamp);
    +    }
    +
    +    public static BeginNode begin(FixedNode with) {
    +        if (with instanceof BeginNode) {
    +            return (BeginNode) with;
    +        }
    +        BeginNode begin = with.graph().add(new BeginNode());
    +        begin.setNext(with);
    +        return begin;
    +    }
    +
    +    @Override
    +    public void simplify(SimplifierTool tool) {
    +        FixedNode prev = (FixedNode) this.predecessor();
    +        if (prev == null) {
    +            // This is the start node.
    +        } else if (prev instanceof ControlSplitNode) {
    +            // This begin node is necessary.
    +        } else {
    +            // This begin node can be removed and all guards moved up to the preceding begin node.
    +            prepareDelete();
    +            tool.addToWorkList(next());
    +            graph().removeFixed(this);
    +        }
    +    }
    +
    +    public static BeginNode prevBegin(FixedNode from) {
    +        Node prevBegin = from;
    +        while (prevBegin != null) {
    +            if (prevBegin instanceof BeginNode) {
    +                return (BeginNode) prevBegin;
    +            }
    +            prevBegin = prevBegin.predecessor();
    +        }
    +        return null;
    +    }
    +
    +    private void evacuateGuards(FixedNode evacuateFrom) {
    +        if (!usages().isEmpty()) {
    +            BeginNode prevBegin = prevBegin(evacuateFrom);
    +            assert prevBegin != null;
    +            for (Node anchored : anchored().snapshot()) {
    +                anchored.replaceFirstInput(this, prevBegin);
    +            }
    +        }
    +    }
    +
    +    public void prepareDelete() {
    +        prepareDelete((FixedNode) predecessor());
    +    }
    +
    +    public void prepareDelete(FixedNode evacuateFrom) {
    +        removeProxies();
    +        evacuateGuards(evacuateFrom);
    +    }
    +
    +    public void removeProxies() {
    +        for (ProxyNode vpn : proxies().snapshot()) {
    +            // can not use graph.replaceFloating because vpn.value may be null during killCFG
    +            vpn.replaceAtUsages(vpn.value());
    +            vpn.safeDelete();
    +        }
    +    }
    +
    +    @Override
    +    public boolean verify() {
    +        assertTrue(predecessor() != null || this == graph().start() || this instanceof MergeNode, "begin nodes must be connected");
    +        return super.verify();
    +    }
    +
    +    @Override
    +    public void generate(NodeLIRBuilderTool gen) {
    +        // nop
    +    }
    +
    +    public NodeIterable guards() {
    +        return usages().filter(GuardNode.class);
    +    }
    +
    +    public NodeIterable anchored() {
    +        return usages().filter(isNotA(ProxyNode.class));
    +    }
    +
    +    public NodeIterable proxies() {
    +        return usages().filter(ProxyNode.class);
    +    }
    +
    +    public NodeIterable getBlockNodes() {
    +        return new NodeIterable() {
    +
    +            @Override
    +            public Iterator iterator() {
    +                return new BlockNodeIterator(BeginNode.this);
    +            }
    +        };
    +    }
    +
    +    private class BlockNodeIterator implements Iterator {
    +
    +        private FixedNode current;
    +
    +        public BlockNodeIterator(FixedNode next) {
    +            this.current = next;
    +        }
    +
    +        @Override
    +        public boolean hasNext() {
    +            return current != null;
    +        }
    +
    +        @Override
    +        public FixedNode next() {
    +            FixedNode ret = current;
    +            if (ret == null) {
    +                throw new NoSuchElementException();
    +            }
    +            if (!(current instanceof FixedWithNextNode) || (current instanceof BeginNode && current != BeginNode.this)) {
    +                current = null;
    +            } else {
    +                current = ((FixedWithNextNode) current).next();
    +            }
    +            return ret;
    +        }
    +
    +        @Override
    +        public void remove() {
    +            throw new UnsupportedOperationException();
    +        }
    +    }
     }
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/BeginStateSplitNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/BeginStateSplitNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/BeginStateSplitNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,16 +22,19 @@
      */
     package com.oracle.graal.nodes;
     
    -import com.oracle.graal.nodes.type.*;
    +import com.oracle.graal.compiler.common.type.*;
    +import com.oracle.graal.graph.*;
     
     /**
    - * Base class for {@link AbstractBeginNode}s that are associated with a frame state.
    - * 
    - * TODO (dnsimon) this not needed until {@link AbstractBeginNode} no longer implements
    - * {@link StateSplit} which is not possible until loop peeling works without requiring begin nodes
    - * to have frames states.
    + * Base class for {@link BeginNode}s that are associated with a frame state.
    + *
    + * TODO (dnsimon) this not needed until {@link BeginNode} no longer implements {@link StateSplit}
    + * which is not possible until loop peeling works without requiring begin nodes to have frames
    + * states.
      */
    -public abstract class BeginStateSplitNode extends AbstractBeginNode implements StateSplit {
    +public abstract class BeginStateSplitNode extends BeginNode implements StateSplit {
    +
    +    @Input(InputType.State) private FrameState stateAfter;
     
         public BeginStateSplitNode() {
         }
    @@ -40,6 +43,16 @@
             super(stamp);
         }
     
    +    public FrameState stateAfter() {
    +        return stateAfter;
    +    }
    +
    +    public void setStateAfter(FrameState x) {
    +        assert x == null || x.isAlive() : "frame state must be in a graph";
    +        updateUsages(stateAfter, x);
    +        stateAfter = x;
    +    }
    +
         /**
          * A begin node has no side effect.
          */
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/BinaryLogicNode.java
    --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/BinaryLogicNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -0,0 +1,71 @@
    +/*
    + * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
    + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    + *
    + * This code is free software; you can redistribute it and/or modify it
    + * under the terms of the GNU General Public License version 2 only, as
    + * published by the Free Software Foundation.
    + *
    + * This code is distributed in the hope that it will be useful, but WITHOUT
    + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    + * version 2 for more details (a copy is included in the LICENSE file that
    + * accompanied this code).
    + *
    + * You should have received a copy of the GNU General Public License version
    + * 2 along with this work; if not, write to the Free Software Foundation,
    + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    + *
    + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    + * or visit www.oracle.com if you need additional information or have any
    + * questions.
    + */
    +package com.oracle.graal.nodes;
    +
    +import com.oracle.graal.nodes.extended.*;
    +import com.oracle.graal.nodes.spi.*;
    +
    +public abstract class BinaryLogicNode extends LogicNode implements LIRLowerable, MemoryArithmeticLIRLowerable {
    +
    +    @Input private ValueNode x;
    +    @Input private ValueNode y;
    +
    +    public ValueNode x() {
    +        return x;
    +    }
    +
    +    public ValueNode y() {
    +        return y;
    +    }
    +
    +    protected void setX(ValueNode x) {
    +        updateUsages(this.x, x);
    +        this.x = x;
    +    }
    +
    +    protected void setY(ValueNode y) {
    +        updateUsages(this.y, y);
    +        this.y = y;
    +    }
    +
    +    public BinaryLogicNode(ValueNode x, ValueNode y) {
    +        assert x != null && y != null && x.getKind() == y.getKind();
    +        this.x = x;
    +        this.y = y;
    +    }
    +
    +    @Override
    +    public boolean verify() {
    +        assertTrue(x.stamp().isCompatible(y.stamp()), "stamps not compatible: %s, %s", x.stamp(), y.stamp());
    +        return super.verify();
    +    }
    +
    +    @Override
    +    public void generate(NodeLIRBuilderTool gen) {
    +    }
    +
    +    @Override
    +    public boolean generate(MemoryArithmeticLIRLowerer gen, Access access) {
    +        return false;
    +    }
    +}
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/BreakpointNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/BreakpointNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/BreakpointNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,9 +22,9 @@
      */
     package com.oracle.graal.nodes;
     
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
     
     /**
      * A node that results in a platform dependent breakpoint instruction being emitted. A number of
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/CallTargetNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/CallTargetNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/CallTargetNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -24,11 +24,11 @@
     
     import java.util.*;
     
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
     
    -@NodeInfo(allowedUsageTypes = {InputType.Association})
    +@NodeInfo(allowedUsageTypes = {InputType.Extension})
     public abstract class CallTargetNode extends ValueNode implements LIRLowerable {
     
         @Input private final NodeInputList arguments;
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ConditionAnchorNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ConditionAnchorNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ConditionAnchorNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,13 +22,13 @@
      */
     package com.oracle.graal.nodes;
     
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.graph.spi.*;
     import com.oracle.graal.nodes.extended.*;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
     
    -@NodeInfo(nameTemplate = "ConditionAnchor(!={p#negated})")
    +@NodeInfo(nameTemplate = "ConditionAnchor(!={p#negated})", allowedUsageTypes = {InputType.Guard})
     public final class ConditionAnchorNode extends FixedWithNextNode implements Canonicalizable, Lowerable, GuardingNode {
     
         @Input(InputType.Condition) private LogicNode condition;
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ConstantNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ConstantNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ConstantNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -25,12 +25,13 @@
     import java.util.*;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.debug.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.graph.iterators.*;
     import com.oracle.graal.nodes.calc.*;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
     
     /**
      * The {@code ConstantNode} represents a {@link Constant constant}.
    @@ -175,7 +176,8 @@
         public static ConstantNode forPrimitive(Stamp stamp, Constant constant, StructuredGraph graph) {
             if (stamp instanceof IntegerStamp) {
                 assert constant.getKind().isNumericInteger() && stamp.getStackKind() == constant.getKind().getStackKind();
    -            return forIntegerStamp(stamp, constant.asLong(), graph);
    +            IntegerStamp istamp = (IntegerStamp) stamp;
    +            return forIntegerBits(istamp.getBits(), constant, graph);
             } else {
                 assert constant.getKind().isNumericFloat() && stamp.getStackKind() == constant.getKind();
                 return forPrimitive(constant, graph);
    @@ -262,35 +264,22 @@
             return unique(graph, createPrimitive(Constant.forInt(i)));
         }
     
    -    /**
    -     * Returns a node for an object constant.
    -     *
    -     * @param o the object value for which to create the instruction
    -     * @return a node representing the object
    -     */
    -    public static ConstantNode forObject(Object o, MetaAccessProvider metaAccess, StructuredGraph graph) {
    -        assert !(o instanceof Constant) : "wrapping a Constant into a Constant";
    -        Constant constant = Constant.forObject(o);
    -        return unique(graph, new ConstantNode(constant, StampFactory.forConstant(constant, metaAccess)));
    +    private static ConstantNode unique(StructuredGraph graph, ConstantNode node) {
    +        return graph.unique(node);
         }
     
    -    private static ConstantNode unique(StructuredGraph graph, ConstantNode node) {
    -        return graph.unique(node);
    +    private static ConstantNode forIntegerBits(int bits, Constant constant, StructuredGraph graph) {
    +        long value = constant.asLong();
    +        long bounds = SignExtendNode.signExtend(value, bits);
    +        return unique(graph, new ConstantNode(constant, StampFactory.forInteger(bits, bounds, bounds)));
         }
     
         /**
          * Returns a node for a constant integer that's not directly representable as Java primitive
          * (e.g. short).
          */
    -    public static ConstantNode forIntegerBits(int bits, boolean unsigned, long value, StructuredGraph graph) {
    -        Constant constant = Constant.forPrimitiveInt(bits, value);
    -        long bounds;
    -        if (unsigned) {
    -            bounds = ZeroExtendNode.zeroExtend(value, bits);
    -        } else {
    -            bounds = SignExtendNode.signExtend(value, bits);
    -        }
    -        return unique(graph, new ConstantNode(constant, StampFactory.forInteger(bits, unsigned, bounds, bounds)));
    +    public static ConstantNode forIntegerBits(int bits, long value, StructuredGraph graph) {
    +        return forIntegerBits(bits, Constant.forPrimitiveInt(bits, value), graph);
         }
     
         /**
    @@ -299,7 +288,7 @@
         public static ConstantNode forIntegerStamp(Stamp stamp, long value, StructuredGraph graph) {
             if (stamp instanceof IntegerStamp) {
                 IntegerStamp intStamp = (IntegerStamp) stamp;
    -            return forIntegerBits(intStamp.getBits(), intStamp.isUnsigned(), value, graph);
    +            return forIntegerBits(intStamp.getBits(), value, graph);
             } else {
                 return forIntegerKind(stamp.getStackKind(), value, graph);
             }
    @@ -351,7 +340,7 @@
                 case Long:
                     return ConstantNode.forLong(0L, graph);
                 case Object:
    -                return ConstantNode.forObject(null, null, graph);
    +                return ConstantNode.forConstant(Constant.NULL_OBJECT, null, graph);
                 default:
                     return null;
             }
    @@ -360,14 +349,14 @@
         @Override
         public Map getDebugProperties(Map map) {
             Map properties = super.getDebugProperties(map);
    -        properties.put("rawvalue", value.getKind() == Kind.Object ? value.getKind().format(value.asBoxedValue()) : value.asBoxedValue());
    +        properties.put("rawvalue", value.toValueString());
             return properties;
         }
     
         @Override
         public String toString(Verbosity verbosity) {
             if (verbosity == Verbosity.Name) {
    -            return super.toString(Verbosity.Name) + "(" + value.getKind().format(value.asBoxedValue()) + ")";
    +            return super.toString(Verbosity.Name) + "(" + value.toValueString() + ")";
             } else {
                 return super.toString(verbosity);
             }
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ControlSinkNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ControlSinkNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ControlSinkNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,7 +22,7 @@
      */
     package com.oracle.graal.nodes;
     
    -import com.oracle.graal.nodes.type.*;
    +import com.oracle.graal.compiler.common.type.*;
     
     public abstract class ControlSinkNode extends FixedNode {
     
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ControlSplitNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ControlSplitNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ControlSplitNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,8 +22,8 @@
      */
     package com.oracle.graal.nodes;
     
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
    -import com.oracle.graal.nodes.type.*;
     
     /**
      * The {@code ControlSplitNode} is a base class for all instructions that split the control flow
    @@ -35,7 +35,7 @@
             super(stamp);
         }
     
    -    public abstract double probability(AbstractBeginNode successor);
    +    public abstract double probability(BeginNode successor);
     
    -    public abstract void setProbability(AbstractBeginNode successor, double value);
    +    public abstract void setProbability(BeginNode successor, double value);
     }
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptimizeNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptimizeNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptimizeNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -63,7 +63,7 @@
     
         @Override
         public void generate(NodeLIRBuilderTool gen) {
    -        gen.getLIRGeneratorTool().emitDeoptimize(gen.getLIRGeneratorTool().getMetaAccess().encodeDeoptActionAndReason(action, reason, debugId), speculation, this);
    +        gen.getLIRGeneratorTool().emitDeoptimize(gen.getLIRGeneratorTool().getMetaAccess().encodeDeoptActionAndReason(action, reason, debugId), speculation, gen.state(this));
         }
     
         @Override
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptimizingFixedWithNextNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptimizingFixedWithNextNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptimizingFixedWithNextNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,8 +22,8 @@
      */
     package com.oracle.graal.nodes;
     
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
    -import com.oracle.graal.nodes.type.*;
     
     public abstract class DeoptimizingFixedWithNextNode extends FixedWithNextNode implements DeoptimizingNode.DeoptBefore {
     
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DirectCallTargetNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DirectCallTargetNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DirectCallTargetNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -26,7 +26,7 @@
     
     import com.oracle.graal.api.code.*;
     import com.oracle.graal.api.meta.*;
    -import com.oracle.graal.nodes.type.*;
    +import com.oracle.graal.compiler.common.type.*;
     
     public class DirectCallTargetNode extends LoweredCallTargetNode {
     
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DispatchBeginNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DispatchBeginNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DispatchBeginNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,7 +22,7 @@
      */
     package com.oracle.graal.nodes;
     
    -import com.oracle.graal.nodes.type.*;
    +import com.oracle.graal.compiler.common.type.*;
     
     /**
      * The entry node of an exception dispatcher block.
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DynamicDeoptimizeNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DynamicDeoptimizeNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DynamicDeoptimizeNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -55,7 +55,7 @@
         }
     
         public void generate(NodeLIRBuilderTool generator) {
    -        generator.getLIRGeneratorTool().emitDeoptimize(generator.operand(actionAndReason), generator.operand(speculation), this);
    +        generator.getLIRGeneratorTool().emitDeoptimize(generator.operand(actionAndReason), generator.operand(speculation), generator.state(this));
         }
     
         @Override
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/EntryMarkerNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/EntryMarkerNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/EntryMarkerNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,6 +22,7 @@
      */
     package com.oracle.graal.nodes;
     
    +import com.oracle.graal.compiler.common.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.graph.spi.*;
     import com.oracle.graal.nodes.spi.*;
    @@ -31,7 +32,7 @@
      * by the graph builder.
      */
     @NodeInfo(allowedUsageTypes = {InputType.Association})
    -public class EntryMarkerNode extends AbstractBeginNode implements IterableNodeType, Simplifiable, LIRLowerable {
    +public class EntryMarkerNode extends BeginStateSplitNode implements IterableNodeType, Simplifiable, LIRLowerable {
     
         @Override
         public void simplify(SimplifierTool tool) {
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,7 +22,7 @@
      */
     package com.oracle.graal.nodes;
     
    -import com.oracle.graal.nodes.type.*;
    +import com.oracle.graal.compiler.common.type.*;
     
     public abstract class FixedNode extends ValueNode {
     
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedWithNextNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedWithNextNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedWithNextNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,7 +22,7 @@
      */
     package com.oracle.graal.nodes;
     
    -import com.oracle.graal.nodes.type.*;
    +import com.oracle.graal.compiler.common.type.*;
     
     /**
      * Base class of all nodes that are fixed within the control flow graph and have an immediate
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FloatingAnchoredNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FloatingAnchoredNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FloatingAnchoredNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,10 +22,10 @@
      */
     package com.oracle.graal.nodes;
     
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.nodes.calc.*;
     import com.oracle.graal.nodes.extended.*;
    -import com.oracle.graal.nodes.type.*;
     
     public abstract class FloatingAnchoredNode extends FloatingNode {
     
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FloatingGuardedNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FloatingGuardedNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FloatingGuardedNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,10 +22,10 @@
      */
     package com.oracle.graal.nodes;
     
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.nodes.calc.*;
     import com.oracle.graal.nodes.extended.*;
    -import com.oracle.graal.nodes.type.*;
     
     public abstract class FloatingGuardedNode extends FloatingNode implements GuardedNode {
     
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FrameState.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FrameState.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FrameState.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -51,35 +51,6 @@
     
         private boolean duringCall;
     
    -    /**
    -     * This BCI should be used for frame states that are built for code with no meaningful BCI.
    -     */
    -    public static final int UNKNOWN_BCI = -4;
    -
    -    /**
    -     * When a node whose frame state has this BCI value is inlined, its frame state will be replaced
    -     * with the frame state before the inlined invoke node.
    -     */
    -    public static final int BEFORE_BCI = -1;
    -
    -    /**
    -     * When a node whose frame state has this BCI value is inlined, its frame state will be replaced
    -     * with the frame state {@linkplain Invoke#stateAfter() after} the inlined invoke node.
    -     */
    -    public static final int AFTER_BCI = -2;
    -
    -    /**
    -     * When a node whose frame state has this BCI value is inlined, its frame state will be replaced
    -     * with the frame state at the exception edge of the inlined invoke node.
    -     */
    -    public static final int AFTER_EXCEPTION_BCI = -3;
    -
    -    /**
    -     * This BCI should be used for frame states that cannot be the target of a deoptimization, like
    -     * snippet frame states.
    -     */
    -    public static final int INVALID_FRAMESTATE_BCI = -5;
    -
         @Input(InputType.State) private FrameState outerFrameState;
     
         /**
    @@ -135,7 +106,8 @@
          */
         public FrameState(int bci) {
             this(null, bci, Collections. emptyList(), 0, 0, false, false, Collections. emptyList(), Collections. emptyList());
    -        assert bci == BEFORE_BCI || bci == AFTER_BCI || bci == AFTER_EXCEPTION_BCI || bci == UNKNOWN_BCI || bci == INVALID_FRAMESTATE_BCI;
    +        assert bci == BytecodeFrame.BEFORE_BCI || bci == BytecodeFrame.AFTER_BCI || bci == BytecodeFrame.AFTER_EXCEPTION_BCI || bci == BytecodeFrame.UNKNOWN_BCI ||
    +                        bci == BytecodeFrame.INVALID_FRAMESTATE_BCI;
         }
     
         public FrameState(ResolvedJavaMethod method, int bci, ValueNode[] locals, List stack, ValueNode[] locks, MonitorIdNode[] monitorIds, boolean rethrowException, boolean duringCall) {
    @@ -395,6 +367,19 @@
                     properties.put("sourceLine", ste.getLineNumber());
                 }
             }
    +        if (bci == BytecodeFrame.AFTER_BCI) {
    +            properties.put("bci", "AFTER_BCI");
    +        } else if (bci == BytecodeFrame.AFTER_EXCEPTION_BCI) {
    +            properties.put("bci", "AFTER_EXCEPTION_BCI");
    +        } else if (bci == BytecodeFrame.INVALID_FRAMESTATE_BCI) {
    +            properties.put("bci", "INVALID_FRAMESTATE_BCI");
    +        } else if (bci == BytecodeFrame.BEFORE_BCI) {
    +            properties.put("bci", "BEFORE_BCI");
    +        } else if (bci == BytecodeFrame.UNKNOWN_BCI) {
    +            properties.put("bci", "UNKNOWN_BCI");
    +        } else if (bci == BytecodeFrame.UNWIND_BCI) {
    +            properties.put("bci", "UNWIND_BCI");
    +        }
             properties.put("locksSize", values.size() - stackSize - localsSize);
             return properties;
         }
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,10 +23,10 @@
     package com.oracle.graal.nodes;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.graph.spi.*;
     import com.oracle.graal.nodes.extended.*;
    -import com.oracle.graal.nodes.type.*;
     
     /**
      * A guard is a node that deoptimizes based on a conditional expression. Guards are not attached to
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardPhiNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardPhiNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardPhiNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,9 +22,9 @@
      */
     package com.oracle.graal.nodes;
     
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.nodes.extended.*;
    -import com.oracle.graal.nodes.type.*;
     
     @NodeInfo(nameTemplate = "GuardPhi({i#values})", allowedUsageTypes = {InputType.Guard})
     public class GuardPhiNode extends PhiNode implements GuardingNode {
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardProxyNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardProxyNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardProxyNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,22 +22,26 @@
      */
     package com.oracle.graal.nodes;
     
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.nodes.extended.*;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
     
     @NodeInfo(allowedUsageTypes = {InputType.Guard})
    -public class GuardProxyNode extends ProxyNode implements GuardingNode, Proxy {
    +public class GuardProxyNode extends ProxyNode implements GuardingNode, Proxy, LIRLowerable {
     
         @Input(InputType.Guard) private GuardingNode value;
     
    -    public GuardProxyNode(GuardingNode value, AbstractBeginNode proxyPoint) {
    +    public GuardProxyNode(GuardingNode value, BeginNode proxyPoint) {
             super(StampFactory.forVoid(), proxyPoint);
             this.value = value;
         }
     
         @Override
    +    public void generate(NodeLIRBuilderTool generator) {
    +    }
    +
    +    @Override
         public ValueNode value() {
             return value.asNode();
         }
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardedValueNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardedValueNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardedValueNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,11 +23,11 @@
     package com.oracle.graal.nodes;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.graph.spi.*;
     import com.oracle.graal.nodes.extended.*;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
     
     /**
      * A node that changes the type of its input, usually narrowing it. For example, a GuardedValueNode
    @@ -77,7 +77,7 @@
     
         @Override
         public Node canonical(CanonicalizerTool tool) {
    -        if (getGuard() == graph().start()) {
    +        if (getGuard() == graph().start() || getGuard() == null) {
                 if (stamp().equals(object().stamp())) {
                     return object();
                 } else {
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardingPiNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardingPiNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardingPiNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,6 +23,7 @@
     package com.oracle.graal.nodes;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.graph.spi.*;
     import com.oracle.graal.nodes.calc.*;
    @@ -87,7 +88,7 @@
         @Override
         public void virtualize(VirtualizerTool tool) {
             State state = tool.getObjectState(object);
    -        if (state != null && state.getState() == EscapeState.Virtual && ObjectStamp.typeOrNull(this) != null && ObjectStamp.typeOrNull(this).isAssignableFrom(state.getVirtualObject().type())) {
    +        if (state != null && state.getState() == EscapeState.Virtual && StampTool.typeOrNull(this) != null && StampTool.typeOrNull(this).isAssignableFrom(state.getVirtualObject().type())) {
                 tool.replaceWithVirtual(state.getVirtualObject());
             }
         }
    diff -r 518a7f487c4f -r 9363fffa8b07 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 Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -27,6 +27,8 @@
     import com.oracle.graal.api.meta.*;
     import com.oracle.graal.api.meta.JavaTypeProfile.ProfiledType;
     import com.oracle.graal.api.meta.ProfilingInfo.TriState;
    +import com.oracle.graal.compiler.common.calc.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.debug.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.graph.iterators.*;
    @@ -35,7 +37,6 @@
     import com.oracle.graal.nodes.extended.*;
     import com.oracle.graal.nodes.java.*;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
     import com.oracle.graal.nodes.util.*;
     
     /**
    @@ -44,8 +45,8 @@
      */
     public final class IfNode extends ControlSplitNode implements Simplifiable, LIRLowerable, MemoryArithmeticLIRLowerable {
     
    -    @Successor private AbstractBeginNode trueSuccessor;
    -    @Successor private AbstractBeginNode falseSuccessor;
    +    @Successor private BeginNode trueSuccessor;
    +    @Successor private BeginNode falseSuccessor;
         @Input(InputType.Condition) private LogicNode condition;
         private double trueSuccessorProbability;
     
    @@ -59,10 +60,10 @@
         }
     
         public IfNode(LogicNode condition, FixedNode trueSuccessor, FixedNode falseSuccessor, double trueSuccessorProbability) {
    -        this(condition, AbstractBeginNode.begin(trueSuccessor), AbstractBeginNode.begin(falseSuccessor), trueSuccessorProbability);
    +        this(condition, BeginNode.begin(trueSuccessor), BeginNode.begin(falseSuccessor), trueSuccessorProbability);
         }
     
    -    public IfNode(LogicNode condition, AbstractBeginNode trueSuccessor, AbstractBeginNode falseSuccessor, double trueSuccessorProbability) {
    +    public IfNode(LogicNode condition, BeginNode trueSuccessor, BeginNode falseSuccessor, double trueSuccessorProbability) {
             super(StampFactory.forVoid());
             this.condition = condition;
             this.falseSuccessor = falseSuccessor;
    @@ -76,7 +77,7 @@
          *
          * @return the true successor
          */
    -    public AbstractBeginNode trueSuccessor() {
    +    public BeginNode trueSuccessor() {
             return trueSuccessor;
         }
     
    @@ -85,16 +86,16 @@
          *
          * @return the false successor
          */
    -    public AbstractBeginNode falseSuccessor() {
    +    public BeginNode falseSuccessor() {
             return falseSuccessor;
         }
     
    -    public void setTrueSuccessor(AbstractBeginNode node) {
    +    public void setTrueSuccessor(BeginNode node) {
             updatePredecessor(trueSuccessor, node);
             trueSuccessor = node;
         }
     
    -    public void setFalseSuccessor(AbstractBeginNode node) {
    +    public void setFalseSuccessor(BeginNode node) {
             updatePredecessor(falseSuccessor, node);
             falseSuccessor = node;
         }
    @@ -105,7 +106,7 @@
          * @param istrue {@code true} if the true successor is requested, {@code false} otherwise
          * @return the corresponding successor
          */
    -    public AbstractBeginNode successor(boolean istrue) {
    +    public BeginNode successor(boolean istrue) {
             return istrue ? trueSuccessor : falseSuccessor;
         }
     
    @@ -115,12 +116,12 @@
         }
     
         @Override
    -    public double probability(AbstractBeginNode successor) {
    +    public double probability(BeginNode successor) {
             return successor == trueSuccessor ? trueSuccessorProbability : 1 - trueSuccessorProbability;
         }
     
         @Override
    -    public void setProbability(AbstractBeginNode successor, double value) {
    +    public void setProbability(BeginNode successor, double value) {
             assert successor == trueSuccessor || successor == falseSuccessor;
             setTrueSuccessorProbability(successor == trueSuccessor ? value : 1 - value);
         }
    @@ -146,8 +147,8 @@
         @Override
         public void simplify(SimplifierTool tool) {
             if (condition() instanceof LogicNegationNode) {
    -            AbstractBeginNode trueSucc = trueSuccessor();
    -            AbstractBeginNode falseSucc = falseSuccessor();
    +            BeginNode trueSucc = trueSuccessor();
    +            BeginNode falseSucc = falseSuccessor();
                 setTrueSuccessor(null);
                 setFalseSuccessor(null);
                 LogicNegationNode negation = (LogicNegationNode) condition();
    @@ -156,6 +157,41 @@
                 this.safeDelete();
                 return;
             }
    +        if (trueSuccessor().usages().isEmpty() && falseSuccessor().usages().isEmpty()) {
    +            // push similar nodes upwards through the if, thereby deduplicating them
    +            do {
    +                BeginNode trueSucc = trueSuccessor();
    +                BeginNode falseSucc = falseSuccessor();
    +                if (trueSucc.getClass() == BeginNode.class && falseSucc.getClass() == BeginNode.class && trueSucc.next() instanceof FixedWithNextNode && falseSucc.next() instanceof FixedWithNextNode) {
    +                    FixedWithNextNode trueNext = (FixedWithNextNode) trueSucc.next();
    +                    FixedWithNextNode falseNext = (FixedWithNextNode) falseSucc.next();
    +                    NodeClass nodeClass = trueNext.getNodeClass();
    +                    if (trueNext.getClass() == falseNext.getClass()) {
    +                        if (nodeClass.inputsEqual(trueNext, falseNext) && nodeClass.valueEqual(trueNext, falseNext)) {
    +                            falseNext.replaceAtUsages(trueNext);
    +                            graph().removeFixed(falseNext);
    +                            FixedNode next = trueNext.next();
    +                            trueNext.setNext(null);
    +                            trueNext.replaceAtPredecessor(next);
    +                            graph().addBeforeFixed(this, trueNext);
    +                            for (Node usage : trueNext.usages().snapshot()) {
    +                                if (usage.getNodeClass().valueNumberable() && !usage.getNodeClass().isLeafNode()) {
    +                                    Node newNode = graph().findDuplicate(usage);
    +                                    if (newNode != null) {
    +                                        usage.replaceAtUsages(newNode);
    +                                        usage.safeDelete();
    +                                    }
    +                                }
    +                                if (usage.isAlive()) {
    +                                    tool.addToWorkList(usage);
    +                                }
    +                            }
    +                            continue;
    +                        }
    +                    }
    +                }
    +            } while (false);
    +        }
     
             if (condition() instanceof LogicConstantNode) {
                 LogicConstantNode c = (LogicConstantNode) condition();
    @@ -182,7 +218,7 @@
             }
     
             if (falseSuccessor().usages().isEmpty() && (!(falseSuccessor() instanceof LoopExitNode)) && falseSuccessor().next() instanceof IfNode) {
    -            AbstractBeginNode intermediateBegin = falseSuccessor();
    +            BeginNode intermediateBegin = falseSuccessor();
                 IfNode nextIf = (IfNode) intermediateBegin.next();
                 double probabilityB = (1.0 - this.trueSuccessorProbability) * nextIf.trueSuccessorProbability;
                 if (this.trueSuccessorProbability < probabilityB) {
    @@ -191,7 +227,7 @@
                     if (prepareForSwap(tool.getConstantReflection(), condition(), nextIf.condition(), this.trueSuccessorProbability, probabilityB)) {
                         // Reording is allowed from (if1 => begin => if2) to (if2 => begin => if1).
                         assert intermediateBegin.next() == nextIf;
    -                    AbstractBeginNode bothFalseBegin = nextIf.falseSuccessor();
    +                    BeginNode bothFalseBegin = nextIf.falseSuccessor();
                         nextIf.setFalseSuccessor(null);
                         intermediateBegin.setNext(null);
                         this.setFalseSuccessor(null);
    @@ -547,8 +583,8 @@
             List trueEnds = new ArrayList<>(mergePredecessors.size());
             Map phiValues = new HashMap<>(mergePredecessors.size());
     
    -        AbstractBeginNode oldFalseSuccessor = falseSuccessor();
    -        AbstractBeginNode oldTrueSuccessor = trueSuccessor();
    +        BeginNode oldFalseSuccessor = falseSuccessor();
    +        BeginNode oldTrueSuccessor = trueSuccessor();
     
             setFalseSuccessor(null);
             setTrueSuccessor(null);
    @@ -637,7 +673,7 @@
          * @param oldMerge the merge being removed
          * @param phiValues the values of the phi at the merge, keyed by the merge ends
          */
    -    private void connectEnds(List ends, Map phiValues, AbstractBeginNode successor, MergeNode oldMerge, SimplifierTool tool) {
    +    private void connectEnds(List ends, Map phiValues, BeginNode successor, MergeNode oldMerge, SimplifierTool tool) {
             if (!ends.isEmpty()) {
                 if (ends.size() == 1) {
                     AbstractEndNode end = ends.get(0);
    @@ -703,8 +739,8 @@
         }
     
         private void removeEmptyIf(SimplifierTool tool) {
    -        AbstractBeginNode originalTrueSuccessor = trueSuccessor();
    -        AbstractBeginNode originalFalseSuccessor = falseSuccessor();
    +        BeginNode originalTrueSuccessor = trueSuccessor();
    +        BeginNode originalFalseSuccessor = falseSuccessor();
             assert originalTrueSuccessor.next() instanceof AbstractEndNode && originalFalseSuccessor.next() instanceof AbstractEndNode;
     
             AbstractEndNode trueEnd = (AbstractEndNode) originalTrueSuccessor.next();
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IndirectCallTargetNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IndirectCallTargetNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IndirectCallTargetNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -26,7 +26,7 @@
     
     import com.oracle.graal.api.code.*;
     import com.oracle.graal.api.meta.*;
    -import com.oracle.graal.nodes.type.*;
    +import com.oracle.graal.compiler.common.type.*;
     
     public class IndirectCallTargetNode extends LoweredCallTargetNode {
     
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InfopointNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InfopointNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InfopointNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,9 +23,9 @@
     package com.oracle.graal.nodes;
     
     import com.oracle.graal.api.code.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
     
     /**
      * Nodes of this type are inserted into the graph to denote points of interest to debugging.
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/Invoke.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/Invoke.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/Invoke.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,6 +22,7 @@
      */
     package com.oracle.graal.nodes;
     
    +import com.oracle.graal.api.meta.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.nodes.extended.*;
     import com.oracle.graal.nodes.spi.*;
    @@ -52,4 +53,36 @@
         boolean isPolymorphic();
     
         void setPolymorphic(boolean value);
    +
    +    /**
    +     * Returns the {@linkplain ResolvedJavaMethod method} from which this invoke is executed. This
    +     * is the caller method and in the case of inlining may be different from the method of the
    +     * graph this node is in.
    +     *
    +     * @return the method from which this invoke is executed.
    +     */
    +    default ResolvedJavaMethod getContextMethod() {
    +        FrameState state = stateAfter();
    +        if (state == null) {
    +            state = stateDuring();
    +        }
    +        return state.method();
    +    }
    +
    +    /**
    +     * Returns the {@linkplain ResolvedJavaType type} from which this invoke is executed. This is
    +     * the declaring type of the caller method.
    +     *
    +     * @return the type from which this invoke is executed.
    +     */
    +    default ResolvedJavaType getContextType() {
    +        return getContextMethod().getDeclaringClass();
    +    }
    +
    +    @Override
    +    default void computeStateDuring(FrameState stateAfter) {
    +        FrameState newStateDuring = stateAfter.duplicateModified(bci(), stateAfter.rethrowException(), asNode().getKind());
    +        newStateDuring.setDuringCall(true);
    +        setStateDuring(newStateDuring);
    +    }
     }
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -25,11 +25,11 @@
     import java.util.*;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.nodes.extended.*;
     import com.oracle.graal.nodes.java.*;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
     import com.oracle.graal.nodes.util.*;
     
     /**
    @@ -38,7 +38,7 @@
     @NodeInfo(nameTemplate = "Invoke#{p#targetMethod/s}", allowedUsageTypes = {InputType.Memory})
     public final class InvokeNode extends AbstractMemoryCheckpoint implements Invoke, LIRLowerable, MemoryCheckpoint.Single {
     
    -    @Input(InputType.Association) private CallTargetNode callTarget;
    +    @Input(InputType.Extension) private CallTargetNode callTarget;
         @Input(InputType.State) private FrameState stateDuring;
         @Input(InputType.Guard) private GuardingNode guard;
         private final int bci;
    @@ -185,13 +185,6 @@
         }
     
         @Override
    -    public void computeStateDuring(FrameState stateAfter) {
    -        FrameState newStateDuring = stateAfter.duplicateModified(bci(), stateAfter.rethrowException(), getKind());
    -        newStateDuring.setDuringCall(true);
    -        setStateDuring(newStateDuring);
    -    }
    -
    -    @Override
         public GuardingNode getGuard() {
             return guard;
         }
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeWithExceptionNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeWithExceptionNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeWithExceptionNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -36,9 +36,9 @@
     
         private static final double EXCEPTION_PROBA = 1e-5;
     
    -    @Successor private AbstractBeginNode next;
    +    @Successor private BeginNode next;
         @Successor private DispatchBeginNode exceptionEdge;
    -    @Input(InputType.Association) private CallTargetNode callTarget;
    +    @Input(InputType.Extension) private CallTargetNode callTarget;
         @Input(InputType.State) private FrameState stateDuring;
         @Input(InputType.State) private FrameState stateAfter;
         @Input(InputType.Guard) private GuardingNode guard;
    @@ -66,11 +66,11 @@
             exceptionEdge = x;
         }
     
    -    public AbstractBeginNode next() {
    +    public BeginNode next() {
             return next;
         }
     
    -    public void setNext(AbstractBeginNode x) {
    +    public void setNext(BeginNode x) {
             updatePredecessor(next, x);
             next = x;
         }
    @@ -163,7 +163,7 @@
         }
     
         public void killExceptionEdge() {
    -        AbstractBeginNode edge = exceptionEdge();
    +        BeginNode edge = exceptionEdge();
             setExceptionEdge(null);
             GraphUtil.killCFG(edge);
         }
    @@ -196,12 +196,12 @@
         }
     
         @Override
    -    public double probability(AbstractBeginNode successor) {
    +    public double probability(BeginNode successor) {
             return successor == next ? 1 - exceptionProbability : exceptionProbability;
         }
     
         @Override
    -    public void setProbability(AbstractBeginNode successor, double value) {
    +    public void setProbability(BeginNode successor, double value) {
             assert successor == next || successor == exceptionEdge;
             this.exceptionProbability = successor == next ? 1 - value : value;
         }
    @@ -223,13 +223,6 @@
         }
     
         @Override
    -    public void computeStateDuring(FrameState tempStateAfter) {
    -        FrameState newStateDuring = tempStateAfter.duplicateModified(bci(), tempStateAfter.rethrowException(), getKind());
    -        newStateDuring.setDuringCall(true);
    -        setStateDuring(newStateDuring);
    -    }
    -
    -    @Override
         public GuardingNode getGuard() {
             return guard;
         }
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/KillingBeginNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/KillingBeginNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/KillingBeginNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -27,7 +27,7 @@
     import com.oracle.graal.nodes.extended.*;
     
     @NodeInfo(allowedUsageTypes = {InputType.Memory})
    -public class KillingBeginNode extends AbstractBeginNode implements MemoryCheckpoint.Single {
    +public class KillingBeginNode extends BeginNode implements MemoryCheckpoint.Single {
     
         private LocationIdentity locationIdentity;
     
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LogicNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LogicNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LogicNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -24,9 +24,9 @@
     
     import static com.oracle.graal.graph.InputType.*;
     
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.nodes.calc.*;
    -import com.oracle.graal.nodes.type.*;
     
     @NodeInfo(allowedUsageTypes = {Condition})
     public abstract class LogicNode extends FloatingNode {
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopBeginNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopBeginNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopBeginNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -178,7 +178,7 @@
             // nothing yet
         }
     
    -    public boolean isLoopExit(AbstractBeginNode begin) {
    +    public boolean isLoopExit(BeginNode begin) {
             return begin instanceof LoopExitNode && ((LoopExitNode) begin).loopBegin() == this;
         }
     
    @@ -201,4 +201,27 @@
             updateUsagesInterface(this.overflowGuard, overflowGuard);
             this.overflowGuard = overflowGuard;
         }
    +
    +    /**
    +     * Removes dead {@linkplain PhiNode phi nodes} hanging from this node.
    +     *
    +     * This method uses the heuristic that any node which not a phi node of this LoopBeginNode is
    +     * alive. This allows the removal of dead phi loops.
    +     */
    +    public void removeDeadPhis() {
    +        Set alive = new HashSet<>();
    +        for (PhiNode phi : phis()) {
    +            NodePredicate isAlive = u -> !isPhiAtMerge(u) || alive.contains(u);
    +            if (phi.usages().filter(isAlive).isNotEmpty()) {
    +                alive.add(phi);
    +                for (PhiNode keptAlive : phi.values().filter(PhiNode.class).filter(isAlive.negate())) {
    +                    alive.add(keptAlive);
    +                }
    +            }
    +        }
    +        for (PhiNode phi : phis().filter(((NodePredicate) alive::contains).negate()).snapshot()) {
    +            phi.replaceAtUsages(null);
    +            phi.safeDelete();
    +        }
    +    }
     }
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoweredCallTargetNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoweredCallTargetNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoweredCallTargetNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -26,7 +26,7 @@
     
     import com.oracle.graal.api.code.*;
     import com.oracle.graal.api.meta.*;
    -import com.oracle.graal.nodes.type.*;
    +import com.oracle.graal.compiler.common.type.*;
     
     public abstract class LoweredCallTargetNode extends CallTargetNode {
     
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MemoryMapNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MemoryMapNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MemoryMapNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -25,12 +25,12 @@
     import java.util.*;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.nodes.calc.*;
     import com.oracle.graal.nodes.extended.*;
    -import com.oracle.graal.nodes.type.*;
     
    -@NodeInfo(allowedUsageTypes = {InputType.Association})
    +@NodeInfo(allowedUsageTypes = {InputType.Extension})
     public abstract class MemoryMapNode extends FloatingNode {
     
         public MemoryMapNode() {
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MemoryPhiNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MemoryPhiNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MemoryPhiNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,9 +23,9 @@
     package com.oracle.graal.nodes;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.nodes.extended.*;
    -import com.oracle.graal.nodes.type.*;
     
     /**
      * The {@code PhiNode} represents the merging of dataflow in the memory graph.
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MemoryProxyNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MemoryProxyNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MemoryProxyNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,10 +23,10 @@
     package com.oracle.graal.nodes;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.nodes.extended.*;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
     
     @NodeInfo(allowedUsageTypes = {InputType.Memory})
     public class MemoryProxyNode extends ProxyNode implements MemoryProxy, LIRLowerable {
    @@ -34,7 +34,7 @@
         @Input(InputType.Memory) private MemoryNode value;
         private final LocationIdentity identity;
     
    -    public MemoryProxyNode(MemoryNode value, AbstractBeginNode exit, LocationIdentity identity) {
    +    public MemoryProxyNode(MemoryNode value, BeginNode exit, LocationIdentity identity) {
             super(StampFactory.forVoid(), exit);
             this.value = value;
             this.identity = identity;
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MergeNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MergeNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MergeNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -124,26 +124,18 @@
         }
     
         public NodeIterable phis() {
    -        return this.usages().filter(PhiNode.class).filter(new NodePredicate() {
    -
    -            @Override
    -            public boolean apply(Node n) {
    -                return ((PhiNode) n).merge() == MergeNode.this;
    -            }
    -        });
    +        return this.usages().filter(PhiNode.class).filter(this::isPhiAtMerge);
         }
     
         @Override
         public NodeIterable anchored() {
    -        return super.anchored().filter(isNotA(PhiNode.class).or(new NodePredicate() {
    -
    -            @Override
    -            public boolean apply(Node n) {
    -                return ((PhiNode) n).merge() != MergeNode.this;
    -            }
    -        }));
    +        return super.anchored().filter(n -> !isPhiAtMerge(n));
         }
     
    +    /**
    +     * This simplify method can deal with a null value for tool, so that it can be used outside of
    +     * canonicalization.
    +     */
         @Override
         public void simplify(SimplifierTool tool) {
             FixedNode next = next();
    @@ -163,10 +155,8 @@
                     return;
                 }
                 for (PhiNode phi : phis()) {
    -                for (Node usage : phi.usages().filter(isNotA(FrameState.class))) {
    -                    if (!merge.isPhiAtMerge(usage)) {
    -                        return;
    -                    }
    +                if (phi.usages().filter(isNotA(FrameState.class)).and(node -> !merge.isPhiAtMerge(node)).isNotEmpty()) {
    +                    return;
                     }
                 }
                 Debug.log("Split %s into ends for %s.", this, merge);
    @@ -194,7 +184,9 @@
                     this.removeEnd(end);
                     end.replaceAtPredecessor(newEnd);
                     end.safeDelete();
    -                tool.addToWorkList(newEnd.predecessor()); // ?
    +                if (tool != null) {
    +                    tool.addToWorkList(newEnd.predecessor());
    +                }
                 }
                 graph().reduceTrivialMerge(this);
             } else if (next instanceof ReturnNode) {
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ParameterNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ParameterNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ParameterNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,8 +22,8 @@
      */
     package com.oracle.graal.nodes;
     
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
    -import com.oracle.graal.nodes.type.*;
     
     /**
      * The {@code Parameter} instruction is a placeholder for an incoming argument to a function call.
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PhiNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PhiNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PhiNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,10 +22,10 @@
      */
     package com.oracle.graal.nodes;
     
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.graph.spi.*;
     import com.oracle.graal.nodes.calc.*;
    -import com.oracle.graal.nodes.type.*;
     
     public abstract class PhiNode extends FloatingNode {
     
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PiArrayNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PiArrayNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PiArrayNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,11 +22,11 @@
      */
     package com.oracle.graal.nodes;
     
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.graph.spi.*;
     import com.oracle.graal.nodes.java.*;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
     
     /**
      * A {@link PiNode} that also provides an array length in addition to a more refined stamp. A usage
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PiNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PiNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PiNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -25,6 +25,7 @@
     //JaCoCo Exclude
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.graph.spi.*;
     import com.oracle.graal.nodes.extended.*;
    @@ -58,7 +59,7 @@
         }
     
         public PiNode(ValueNode object, ResolvedJavaType toType, boolean exactType, boolean nonNull) {
    -        this(object, StampFactory.object(toType, exactType, nonNull || ObjectStamp.isObjectNonNull(object.stamp())));
    +        this(object, StampFactory.object(toType, exactType, nonNull || StampTool.isObjectNonNull(object.stamp())));
         }
     
         @Override
    @@ -79,7 +80,7 @@
         @Override
         public void virtualize(VirtualizerTool tool) {
             State state = tool.getObjectState(object);
    -        if (state != null && state.getState() == EscapeState.Virtual && ObjectStamp.typeOrNull(this) != null && ObjectStamp.typeOrNull(this).isAssignableFrom(state.getVirtualObject().type())) {
    +        if (state != null && state.getState() == EscapeState.Virtual && StampTool.typeOrNull(this) != null && StampTool.typeOrNull(this).isAssignableFrom(state.getVirtualObject().type())) {
                 tool.replaceWithVirtual(state.getVirtualObject());
             }
         }
    @@ -108,6 +109,10 @@
             return piCast(object, toType, true, true);
         }
     
    +    public static  T piCastExact(Object object, @ConstantNodeParameter Class toType) {
    +        return piCast(object, toType, true, false);
    +    }
    +
         public static  T piCast(Object object, @ConstantNodeParameter Class toType) {
             return piCast(object, toType, false, false);
         }
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ProxyNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ProxyNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ProxyNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,11 +23,11 @@
     package com.oracle.graal.nodes;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.graph.Node.ValueNumberable;
     import com.oracle.graal.nodes.calc.*;
     import com.oracle.graal.nodes.extended.*;
    -import com.oracle.graal.nodes.type.*;
     
     /**
      * A proxy is inserted at loop exits for any value that is created inside the loop (i.e. was not
    @@ -35,9 +35,9 @@
      */
     public abstract class ProxyNode extends FloatingNode implements IterableNodeType, ValueNumberable {
     
    -    @Input(InputType.Association) private AbstractBeginNode proxyPoint;
    +    @Input(InputType.Association) private BeginNode proxyPoint;
     
    -    public ProxyNode(Stamp stamp, AbstractBeginNode proxyPoint) {
    +    public ProxyNode(Stamp stamp, BeginNode proxyPoint) {
             super(stamp);
             assert proxyPoint != null;
             this.proxyPoint = proxyPoint;
    @@ -45,7 +45,7 @@
     
         public abstract ValueNode value();
     
    -    public AbstractBeginNode proxyPoint() {
    +    public BeginNode proxyPoint() {
             return proxyPoint;
         }
     
    @@ -57,15 +57,15 @@
             return super.verify();
         }
     
    -    public static MemoryProxyNode forMemory(MemoryNode value, AbstractBeginNode exit, LocationIdentity location, StructuredGraph graph) {
    +    public static MemoryProxyNode forMemory(MemoryNode value, BeginNode exit, LocationIdentity location, StructuredGraph graph) {
             return graph.unique(new MemoryProxyNode(value, exit, location));
         }
     
    -    public static ValueProxyNode forValue(ValueNode value, AbstractBeginNode exit, StructuredGraph graph) {
    +    public static ValueProxyNode forValue(ValueNode value, BeginNode exit, StructuredGraph graph) {
             return graph.unique(new ValueProxyNode(value, exit));
         }
     
    -    public static GuardProxyNode forGuard(GuardingNode value, AbstractBeginNode exit, StructuredGraph graph) {
    +    public static GuardProxyNode forGuard(GuardingNode value, BeginNode exit, StructuredGraph graph) {
             return graph.unique(new GuardProxyNode(value, exit));
         }
     }
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ReturnNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ReturnNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ReturnNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,14 +22,14 @@
      */
     package com.oracle.graal.nodes;
     
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
     
     public final class ReturnNode extends ControlSinkNode implements LIRLowerable, IterableNodeType {
     
         @Input private ValueNode result;
    -    @Input(InputType.Association) private MemoryMapNode memoryMap;
    +    @Input(InputType.Extension) private MemoryMapNode memoryMap;
     
         public ValueNode result() {
             return result;
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/SafepointNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/SafepointNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/SafepointNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,8 +22,8 @@
      */
     package com.oracle.graal.nodes;
     
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
     
     /**
      * Marks a position in the graph where a safepoint should be emitted.
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StateSplit.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StateSplit.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StateSplit.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -29,6 +29,8 @@
      */
     public interface StateSplit extends NodeWithState {
     
    +    FixedNode asNode();
    +
         /**
          * Gets the {@link FrameState} corresponding to the state of the JVM after execution of this
          * node.
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -79,16 +79,14 @@
         private boolean isAfterFloatingReadPhase = false;
     
         /**
    -     * Creates a new Graph containing a single {@link AbstractBeginNode} as the {@link #start()
    -     * start} node.
    +     * Creates a new Graph containing a single {@link BeginNode} as the {@link #start() start} node.
          */
         public StructuredGraph() {
             this(null, null);
         }
     
         /**
    -     * Creates a new Graph containing a single {@link AbstractBeginNode} as the {@link #start()
    -     * start} node.
    +     * Creates a new Graph containing a single {@link BeginNode} as the {@link #start() start} node.
          */
         public StructuredGraph(String name, ResolvedJavaMethod method) {
             this(name, method, uniqueGraphIds.incrementAndGet(), INVOCATION_ENTRY_BCI);
    @@ -255,8 +253,8 @@
          */
         public void removeFixed(FixedWithNextNode node) {
             assert node != null;
    -        if (node instanceof AbstractBeginNode) {
    -            ((AbstractBeginNode) node).prepareDelete();
    +        if (node instanceof BeginNode) {
    +            ((BeginNode) node).prepareDelete();
             }
             assert node.usages().isEmpty() : node + " " + node.usages();
             FixedNode next = node.next();
    @@ -295,7 +293,7 @@
             node.safeDelete();
         }
     
    -    public void removeSplit(ControlSplitNode node, AbstractBeginNode survivingSuccessor) {
    +    public void removeSplit(ControlSplitNode node, BeginNode survivingSuccessor) {
             assert node != null;
             assert node.usages().isEmpty();
             assert survivingSuccessor != null;
    @@ -304,7 +302,7 @@
             node.safeDelete();
         }
     
    -    public void removeSplitPropagate(ControlSplitNode node, AbstractBeginNode survivingSuccessor) {
    +    public void removeSplitPropagate(ControlSplitNode node, BeginNode survivingSuccessor) {
             assert node != null;
             assert node.usages().isEmpty();
             assert survivingSuccessor != null;
    @@ -321,7 +319,7 @@
             }
         }
     
    -    public void replaceSplit(ControlSplitNode node, Node replacement, AbstractBeginNode survivingSuccessor) {
    +    public void replaceSplit(ControlSplitNode node, Node replacement, BeginNode survivingSuccessor) {
             if (replacement instanceof FixedWithNextNode) {
                 replaceSplitWithFixed(node, (FixedWithNextNode) replacement, survivingSuccessor);
             } else {
    @@ -331,7 +329,7 @@
             }
         }
     
    -    public void replaceSplitWithFixed(ControlSplitNode node, FixedWithNextNode replacement, AbstractBeginNode survivingSuccessor) {
    +    public void replaceSplitWithFixed(ControlSplitNode node, FixedWithNextNode replacement, BeginNode survivingSuccessor) {
             assert node != null && replacement != null && node.isAlive() && replacement.isAlive() : "cannot replace " + node + " with " + replacement;
             assert survivingSuccessor != null;
             node.clearSuccessors();
    @@ -339,7 +337,7 @@
             node.replaceAndDelete(replacement);
         }
     
    -    public void replaceSplitWithFloating(ControlSplitNode node, FloatingNode replacement, AbstractBeginNode survivingSuccessor) {
    +    public void replaceSplitWithFloating(ControlSplitNode node, FloatingNode replacement, BeginNode survivingSuccessor) {
             assert node != null && replacement != null && node.isAlive() && replacement.isAlive() : "cannot replace " + node + " with " + replacement;
             assert survivingSuccessor != null;
             node.clearSuccessors();
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/TypeProfileProxyNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/TypeProfileProxyNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/TypeProfileProxyNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -75,7 +75,7 @@
     
         @Override
         public Node canonical(CanonicalizerTool tool) {
    -        if (ObjectStamp.isExactType(object)) {
    +        if (StampTool.isExactType(object)) {
                 // The profile is useless - we know the type!
                 return object;
             } else if (object instanceof TypeProfileProxyNode) {
    @@ -96,8 +96,8 @@
                     Debug.log("Improved profile via other profile.");
                     return TypeProfileProxyNode.create(object, newProfile);
                 }
    -        } else if (ObjectStamp.typeOrNull(object) != null) {
    -            ResolvedJavaType type = ObjectStamp.typeOrNull(object);
    +        } else if (StampTool.typeOrNull(object) != null) {
    +            ResolvedJavaType type = StampTool.typeOrNull(object);
                 ResolvedJavaType uniqueConcrete = type.findUniqueConcreteSubtype();
                 if (uniqueConcrete != null) {
                     // Profile is useless => remove.
    @@ -109,7 +109,7 @@
                     return this;
                 }
                 lastCheckedType = type;
    -            JavaTypeProfile newProfile = this.profile.restrict(type, ObjectStamp.isObjectNonNull(object));
    +            JavaTypeProfile newProfile = this.profile.restrict(type, StampTool.isObjectNonNull(object));
                 if (newProfile != this.profile) {
                     Debug.log("Improved profile via static type information.");
                     if (newProfile.getTypes().length == 0) {
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/UnwindNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/UnwindNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/UnwindNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,8 +23,8 @@
     package com.oracle.graal.nodes;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
     
     /**
      * Unwinds the current frame to an exception handler in the caller frame.
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValueNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValueNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValueNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,9 +23,9 @@
     package com.oracle.graal.nodes;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.graph.iterators.*;
    -import com.oracle.graal.nodes.type.*;
     
     /**
      * This class represents a value within the graph, including local variables, phis, and all other
    @@ -92,13 +92,7 @@
             return this instanceof ConstantNode;
         }
     
    -    private static final NodePredicate IS_CONSTANT = new NodePredicate() {
    -
    -        @Override
    -        public boolean apply(Node n) {
    -            return n instanceof ValueNode && ((ValueNode) n).isConstant();
    -        }
    -    };
    +    private static final NodePredicate IS_CONSTANT = node -> node instanceof ConstantNode;
     
         public static NodePredicate isConstantPredicate() {
             return IS_CONSTANT;
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValuePhiNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValuePhiNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValuePhiNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,6 +22,7 @@
      */
     package com.oracle.graal.nodes;
     
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.graph.spi.*;
     import com.oracle.graal.nodes.type.*;
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValueProxyNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValueProxyNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValueProxyNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -30,7 +30,7 @@
     
         @Input private ValueNode value;
     
    -    public ValueProxyNode(ValueNode value, AbstractBeginNode proxyPoint) {
    +    public ValueProxyNode(ValueNode value, BeginNode proxyPoint) {
             super(value.stamp(), proxyPoint);
             this.value = value;
         }
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/AndNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/AndNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/AndNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,8 +23,10 @@
     package com.oracle.graal.nodes.calc;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.graph.spi.*;
    +import com.oracle.graal.lir.gen.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.extended.*;
     import com.oracle.graal.nodes.spi.*;
    @@ -67,6 +69,13 @@
                 if ((rawY & mask) == 0) {
                     return ConstantNode.forIntegerStamp(stamp(), 0, graph());
                 }
    +            if (x() instanceof SignExtendNode) {
    +                SignExtendNode ext = (SignExtendNode) x();
    +                if (rawY == ((1L << ext.getInputBits()) - 1)) {
    +                    ValueNode result = graph().unique(new ZeroExtendNode(ext.getInput(), ext.getResultBits()));
    +                    return result;
    +                }
    +            }
                 if (x().stamp() instanceof IntegerStamp) {
                     IntegerStamp xStamp = (IntegerStamp) x().stamp();
                     if (((xStamp.upMask() | xStamp.downMask()) & ~rawY) == 0) {
    @@ -81,8 +90,8 @@
         }
     
         @Override
    -    public void generate(NodeLIRBuilderTool gen) {
    -        gen.setResult(this, gen.getLIRGeneratorTool().emitAnd(gen.operand(x()), gen.operand(y())));
    +    public void generate(NodeMappableLIRBuilder builder, ArithmeticLIRGenerator gen) {
    +        builder.setResult(this, gen.emitAnd(builder.operand(x()), builder.operand(y())));
         }
     
         @Override
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/BinaryNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/BinaryNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/BinaryNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,10 +22,10 @@
      */
     package com.oracle.graal.nodes.calc;
     
    -import com.oracle.graal.graph.*;
    +import com.oracle.graal.compiler.common.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.iterators.*;
     import com.oracle.graal.nodes.*;
    -import com.oracle.graal.nodes.type.*;
     
     /**
      * The {@code BinaryNode} class is the base of arithmetic and logic operations with two inputs.
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/BitLogicNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/BitLogicNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/BitLogicNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,6 +22,7 @@
      */
     package com.oracle.graal.nodes.calc;
     
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.spi.*;
     import com.oracle.graal.nodes.type.*;
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/CompareNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/CompareNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/CompareNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,11 +23,11 @@
     package com.oracle.graal.nodes.calc;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.*;
    +import com.oracle.graal.compiler.common.calc.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.graph.spi.*;
     import com.oracle.graal.nodes.*;
    -import com.oracle.graal.nodes.extended.*;
    -import com.oracle.graal.nodes.spi.*;
     
     /* TODO (thomaswue/gdub) For high-level optimization purpose the compare node should be a boolean *value* (it is currently only a helper node)
      * But in the back-end the comparison should not always be materialized (for example in x86 the comparison result will not be in a register but in a flag)
    @@ -35,49 +35,32 @@
      * Compare should probably be made a value (so that it can be canonicalized for example) and in later stages some Compare usage should be transformed
      * into variants that do not materialize the value (CompareIf, CompareGuard...)
      */
    -public abstract class CompareNode extends LogicNode implements Canonicalizable, LIRLowerable, MemoryArithmeticLIRLowerable {
    -
    -    @Input private ValueNode x;
    -    @Input private ValueNode y;
    -
    -    public ValueNode x() {
    -        return x;
    -    }
    -
    -    public ValueNode y() {
    -        return y;
    -    }
    +public abstract class CompareNode extends BinaryLogicNode implements Canonicalizable {
     
         /**
          * Constructs a new Compare instruction.
    -     * 
    +     *
          * @param x the instruction producing the first input to the instruction
          * @param y the instruction that produces the second input to this instruction
          */
         public CompareNode(ValueNode x, ValueNode y) {
    -        assert x != null && y != null && x.getKind() == y.getKind();
    -        this.x = x;
    -        this.y = y;
    +        super(x, y);
         }
     
         /**
          * Gets the condition (comparison operation) for this instruction.
    -     * 
    +     *
          * @return the condition
          */
         public abstract Condition condition();
     
         /**
          * Checks whether unordered inputs mean true or false (only applies to float operations).
    -     * 
    +     *
          * @return {@code true} if unordered inputs produce true
          */
         public abstract boolean unorderedIsTrue();
     
    -    @Override
    -    public void generate(NodeLIRBuilderTool gen) {
    -    }
    -
         private LogicNode optimizeConditional(Constant constant, ConditionalNode conditionalNode, ConstantReflectionProvider constantReflection, Condition cond) {
             Constant trueConstant = conditionalNode.trueValue().asConstant();
             Constant falseConstant = conditionalNode.falseValue().asConstant();
    @@ -102,16 +85,6 @@
             return this;
         }
     
    -    protected void setX(ValueNode x) {
    -        updateUsages(this.x, x);
    -        this.x = x;
    -    }
    -
    -    protected void setY(ValueNode y) {
    -        updateUsages(this.y, y);
    -        this.y = y;
    -    }
    -
         protected LogicNode optimizeNormalizeCmp(Constant constant, NormalizeCompareNode normalizeNode, boolean mirrored) {
             throw new GraalInternalError("NormalizeCompareNode connected to %s (%s %s %s)", this, constant, normalizeNode, mirrored);
         }
    @@ -193,14 +166,4 @@
     
             return graph.unique(comparison);
         }
    -
    -    public boolean generate(MemoryArithmeticLIRLowerer gen, Access access) {
    -        return false;
    -    }
    -
    -    @Override
    -    public boolean verify() {
    -        assertTrue(x.stamp().isCompatible(y.stamp()), "stamps not compatible: %s, %s", x.stamp(), y.stamp());
    -        return super.verify();
    -    }
     }
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/Condition.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/Condition.java	Wed Apr 23 15:22:20 2014 +0200
    +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    @@ -1,634 +0,0 @@
    -/*
    - * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
    - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    - *
    - * This code is free software; you can redistribute it and/or modify it
    - * under the terms of the GNU General Public License version 2 only, as
    - * published by the Free Software Foundation.
    - *
    - * This code is distributed in the hope that it will be useful, but WITHOUT
    - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    - * version 2 for more details (a copy is included in the LICENSE file that
    - * accompanied this code).
    - *
    - * You should have received a copy of the GNU General Public License version
    - * 2 along with this work; if not, write to the Free Software Foundation,
    - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    - *
    - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    - * or visit www.oracle.com if you need additional information or have any
    - * questions.
    - */
    -package com.oracle.graal.nodes.calc;
    -
    -import com.oracle.graal.api.code.*;
    -import com.oracle.graal.api.meta.*;
    -import com.oracle.graal.graph.*;
    -
    -/**
    - * Condition codes used in conditionals.
    - */
    -public enum Condition {
    -    /**
    -     * Equal.
    -     */
    -    EQ("=="),
    -
    -    /**
    -     * Not equal.
    -     */
    -    NE("!="),
    -
    -    /**
    -     * Signed less than.
    -     */
    -    LT("<"),
    -
    -    /**
    -     * Signed less than or equal.
    -     */
    -    LE("<="),
    -
    -    /**
    -     * Signed greater than.
    -     */
    -    GT(">"),
    -
    -    /**
    -     * Signed greater than or equal.
    -     */
    -    GE(">="),
    -
    -    /**
    -     * Unsigned greater than or equal ("above than or equal").
    -     */
    -    AE("|>=|"),
    -
    -    /**
    -     * Unsigned less than or equal ("below than or equal").
    -     */
    -    BE("|<=|"),
    -
    -    /**
    -     * Unsigned greater than ("above than").
    -     */
    -    AT("|>|"),
    -
    -    /**
    -     * Unsigned less than ("below than").
    -     */
    -    BT("|<|");
    -
    -    public final String operator;
    -
    -    private Condition(String operator) {
    -        this.operator = operator;
    -    }
    -
    -    public boolean check(int left, int right) {
    -        switch (this) {
    -            case EQ:
    -                return left == right;
    -            case NE:
    -                return left != right;
    -            case LT:
    -                return left < right;
    -            case LE:
    -                return left <= right;
    -            case GT:
    -                return left > right;
    -            case GE:
    -                return left >= right;
    -            case AE:
    -                return UnsignedMath.aboveOrEqual(left, right);
    -            case BE:
    -                return UnsignedMath.belowOrEqual(left, right);
    -            case AT:
    -                return UnsignedMath.aboveThan(left, right);
    -            case BT:
    -                return UnsignedMath.belowThan(left, right);
    -        }
    -        throw new IllegalArgumentException(this.toString());
    -    }
    -
    -    /**
    -     * Given a condition and its negation, this method returns true for one of the two and false for
    -     * the other one. This can be used to keep comparisons in a canonical form.
    -     * 
    -     * @return true if this condition is considered to be the canonical form, false otherwise.
    -     */
    -    public boolean isCanonical() {
    -        switch (this) {
    -            case EQ:
    -                return true;
    -            case NE:
    -                return false;
    -            case LT:
    -                return true;
    -            case LE:
    -                return false;
    -            case GT:
    -                return false;
    -            case GE:
    -                return false;
    -            case BT:
    -                return true;
    -            case BE:
    -                return false;
    -            case AT:
    -                return false;
    -            case AE:
    -                return false;
    -        }
    -        throw new IllegalArgumentException(this.toString());
    -    }
    -
    -    /**
    -     * Returns true if the condition needs to be mirrored to get to a canonical condition. The
    -     * result of the mirroring operation might still need to be negated to achieve a canonical form.
    -     */
    -    public boolean canonicalMirror() {
    -        switch (this) {
    -            case EQ:
    -                return false;
    -            case NE:
    -                return false;
    -            case LT:
    -                return false;
    -            case LE:
    -                return true;
    -            case GT:
    -                return true;
    -            case GE:
    -                return false;
    -            case BT:
    -                return false;
    -            case BE:
    -                return true;
    -            case AT:
    -                return true;
    -            case AE:
    -                return false;
    -        }
    -        throw new IllegalArgumentException(this.toString());
    -    }
    -
    -    /**
    -     * Returns true if the condition needs to be negated to get to a canonical condition. The result
    -     * of the negation might still need to be mirrored to achieve a canonical form.
    -     */
    -    public boolean canonicalNegate() {
    -        switch (this) {
    -            case EQ:
    -                return false;
    -            case NE:
    -                return true;
    -            case LT:
    -                return false;
    -            case LE:
    -                return true;
    -            case GT:
    -                return false;
    -            case GE:
    -                return true;
    -            case BT:
    -                return false;
    -            case BE:
    -                return true;
    -            case AT:
    -                return false;
    -            case AE:
    -                return true;
    -        }
    -        throw new IllegalArgumentException(this.toString());
    -    }
    -
    -    /**
    -     * Negate this conditional.
    -     * 
    -     * @return the condition that represents the negation
    -     */
    -    public final Condition negate() {
    -        switch (this) {
    -            case EQ:
    -                return NE;
    -            case NE:
    -                return EQ;
    -            case LT:
    -                return GE;
    -            case LE:
    -                return GT;
    -            case GT:
    -                return LE;
    -            case GE:
    -                return LT;
    -            case BT:
    -                return AE;
    -            case BE:
    -                return AT;
    -            case AT:
    -                return BE;
    -            case AE:
    -                return BT;
    -        }
    -        throw new IllegalArgumentException(this.toString());
    -    }
    -
    -    public boolean implies(Condition other) {
    -        if (other == this) {
    -            return true;
    -        }
    -        switch (this) {
    -            case EQ:
    -                return other == LE || other == GE || other == BE || other == AE;
    -            case NE:
    -                return false;
    -            case LT:
    -                return other == LE || other == NE;
    -            case LE:
    -                return false;
    -            case GT:
    -                return other == GE || other == NE;
    -            case GE:
    -                return false;
    -            case BT:
    -                return other == BE || other == NE;
    -            case BE:
    -                return false;
    -            case AT:
    -                return other == AE || other == NE;
    -            case AE:
    -                return false;
    -        }
    -        throw new IllegalArgumentException(this.toString());
    -    }
    -
    -    /**
    -     * Mirror this conditional (i.e. commute "a op b" to "b op' a")
    -     * 
    -     * @return the condition representing the equivalent commuted operation
    -     */
    -    public final Condition mirror() {
    -        switch (this) {
    -            case EQ:
    -                return EQ;
    -            case NE:
    -                return NE;
    -            case LT:
    -                return GT;
    -            case LE:
    -                return GE;
    -            case GT:
    -                return LT;
    -            case GE:
    -                return LE;
    -            case BT:
    -                return AT;
    -            case BE:
    -                return AE;
    -            case AT:
    -                return BT;
    -            case AE:
    -                return BE;
    -        }
    -        throw new IllegalArgumentException();
    -    }
    -
    -    /**
    -     * Returns true if this condition represents an unsigned comparison. EQ and NE are not
    -     * considered to be unsigned.
    -     */
    -    public final boolean isUnsigned() {
    -        return this == Condition.BT || this == Condition.BE || this == Condition.AT || this == Condition.AE;
    -    }
    -
    -    /**
    -     * Checks if this conditional operation is commutative.
    -     * 
    -     * @return {@code true} if this operation is commutative
    -     */
    -    public final boolean isCommutative() {
    -        return this == EQ || this == NE;
    -    }
    -
    -    /**
    -     * Attempts to fold a comparison between two constants and return the result.
    -     * 
    -     * @param lt the constant on the left side of the comparison
    -     * @param rt the constant on the right side of the comparison
    -     * @param constantReflection needed to compare constants
    -     * @return {@link Boolean#TRUE} if the comparison is known to be true, {@link Boolean#FALSE} if
    -     *         the comparison is known to be false
    -     */
    -    public boolean foldCondition(Constant lt, Constant rt, ConstantReflectionProvider constantReflection) {
    -        assert !lt.getKind().isNumericFloat() && !rt.getKind().isNumericFloat();
    -        return foldCondition(lt, rt, constantReflection, false);
    -    }
    -
    -    /**
    -     * Attempts to fold a comparison between two constants and return the result.
    -     * 
    -     * @param lt the constant on the left side of the comparison
    -     * @param rt the constant on the right side of the comparison
    -     * @param constantReflection needed to compare constants
    -     * @param unorderedIsTrue true if an undecided float comparison should result in "true"
    -     * @return true if the comparison is known to be true, false if the comparison is known to be
    -     *         false
    -     */
    -    public boolean foldCondition(Constant lt, Constant rt, ConstantReflectionProvider constantReflection, boolean unorderedIsTrue) {
    -        switch (lt.getKind()) {
    -            case Boolean:
    -            case Byte:
    -            case Char:
    -            case Short:
    -            case Int: {
    -                int x = lt.asInt();
    -                int y = rt.asInt();
    -                switch (this) {
    -                    case EQ:
    -                        return x == y;
    -                    case NE:
    -                        return x != y;
    -                    case LT:
    -                        return x < y;
    -                    case LE:
    -                        return x <= y;
    -                    case GT:
    -                        return x > y;
    -                    case GE:
    -                        return x >= y;
    -                    case AE:
    -                        return UnsignedMath.aboveOrEqual(x, y);
    -                    case BE:
    -                        return UnsignedMath.belowOrEqual(x, y);
    -                    case AT:
    -                        return UnsignedMath.aboveThan(x, y);
    -                    case BT:
    -                        return UnsignedMath.belowThan(x, y);
    -                    default:
    -                        throw new GraalInternalError("expected condition: %s", this);
    -                }
    -            }
    -            case Long: {
    -                long x = lt.asLong();
    -                long y = rt.asLong();
    -                switch (this) {
    -                    case EQ:
    -                        return x == y;
    -                    case NE:
    -                        return x != y;
    -                    case LT:
    -                        return x < y;
    -                    case LE:
    -                        return x <= y;
    -                    case GT:
    -                        return x > y;
    -                    case GE:
    -                        return x >= y;
    -                    case AE:
    -                        return UnsignedMath.aboveOrEqual(x, y);
    -                    case BE:
    -                        return UnsignedMath.belowOrEqual(x, y);
    -                    case AT:
    -                        return UnsignedMath.aboveThan(x, y);
    -                    case BT:
    -                        return UnsignedMath.belowThan(x, y);
    -                    default:
    -                        throw new GraalInternalError("expected condition: %s", this);
    -                }
    -            }
    -            case Object: {
    -                Boolean equal = constantReflection.constantEquals(lt, rt);
    -                if (equal != null) {
    -                    switch (this) {
    -                        case EQ:
    -                            return equal.booleanValue();
    -                        case NE:
    -                            return !equal.booleanValue();
    -                        default:
    -                            throw new GraalInternalError("expected condition: %s", this);
    -                    }
    -                }
    -            }
    -            case Float: {
    -                float x = lt.asFloat();
    -                float y = rt.asFloat();
    -                if (Float.isNaN(x) || Float.isNaN(y)) {
    -                    return unorderedIsTrue;
    -                }
    -                switch (this) {
    -                    case EQ:
    -                        return x == y;
    -                    case NE:
    -                        return x != y;
    -                    case LT:
    -                        return x < y;
    -                    case LE:
    -                        return x <= y;
    -                    case GT:
    -                        return x > y;
    -                    case GE:
    -                        return x >= y;
    -                    default:
    -                        throw new GraalInternalError("expected condition: %s", this);
    -                }
    -            }
    -            case Double: {
    -                double x = lt.asDouble();
    -                double y = rt.asDouble();
    -                if (Double.isNaN(x) || Double.isNaN(y)) {
    -                    return unorderedIsTrue;
    -                }
    -                switch (this) {
    -                    case EQ:
    -                        return x == y;
    -                    case NE:
    -                        return x != y;
    -                    case LT:
    -                        return x < y;
    -                    case LE:
    -                        return x <= y;
    -                    case GT:
    -                        return x > y;
    -                    case GE:
    -                        return x >= y;
    -                    default:
    -                        throw new GraalInternalError("expected condition: %s", this);
    -                }
    -            }
    -            default:
    -                throw new GraalInternalError("expected value kind %s while folding condition: %s", lt.getKind(), this);
    -        }
    -    }
    -
    -    public Condition join(Condition other) {
    -        if (other == this) {
    -            return this;
    -        }
    -        switch (this) {
    -            case EQ:
    -                if (other == LE || other == GE || other == BE || other == AE) {
    -                    return EQ;
    -                } else {
    -                    return null;
    -                }
    -            case NE:
    -                if (other == LT || other == GT || other == BT || other == AT) {
    -                    return other;
    -                } else if (other == LE) {
    -                    return LT;
    -                } else if (other == GE) {
    -                    return GT;
    -                } else if (other == BE) {
    -                    return BT;
    -                } else if (other == AE) {
    -                    return AT;
    -                } else {
    -                    return null;
    -                }
    -            case LE:
    -                if (other == GE || other == EQ) {
    -                    return EQ;
    -                } else if (other == NE || other == LT) {
    -                    return LT;
    -                } else {
    -                    return null;
    -                }
    -            case LT:
    -                if (other == NE || other == LE) {
    -                    return LT;
    -                } else {
    -                    return null;
    -                }
    -            case GE:
    -                if (other == LE || other == EQ) {
    -                    return EQ;
    -                } else if (other == NE || other == GT) {
    -                    return GT;
    -                } else {
    -                    return null;
    -                }
    -            case GT:
    -                if (other == NE || other == GE) {
    -                    return GT;
    -                } else {
    -                    return null;
    -                }
    -            case BE:
    -                if (other == AE || other == EQ) {
    -                    return EQ;
    -                } else if (other == NE || other == BT) {
    -                    return BT;
    -                } else {
    -                    return null;
    -                }
    -            case BT:
    -                if (other == NE || other == BE) {
    -                    return BT;
    -                } else {
    -                    return null;
    -                }
    -            case AE:
    -                if (other == BE || other == EQ) {
    -                    return EQ;
    -                } else if (other == NE || other == AT) {
    -                    return AT;
    -                } else {
    -                    return null;
    -                }
    -            case AT:
    -                if (other == NE || other == AE) {
    -                    return AT;
    -                } else {
    -                    return null;
    -                }
    -        }
    -        throw new IllegalArgumentException(this.toString());
    -    }
    -
    -    public Condition meet(Condition other) {
    -        if (other == this) {
    -            return this;
    -        }
    -        switch (this) {
    -            case EQ:
    -                if (other == LE || other == GE || other == BE || other == AE) {
    -                    return other;
    -                } else if (other == LT) {
    -                    return LE;
    -                } else if (other == GT) {
    -                    return GE;
    -                } else if (other == BT) {
    -                    return BE;
    -                } else if (other == AT) {
    -                    return AE;
    -                } else {
    -                    return null;
    -                }
    -            case NE:
    -                if (other == LT || other == GT || other == BT || other == AT) {
    -                    return NE;
    -                } else {
    -                    return null;
    -                }
    -            case LE:
    -                if (other == EQ || other == LT) {
    -                    return LE;
    -                } else {
    -                    return null;
    -                }
    -            case LT:
    -                if (other == EQ || other == LE) {
    -                    return LE;
    -                } else if (other == NE || other == GT) {
    -                    return NE;
    -                } else {
    -                    return null;
    -                }
    -            case GE:
    -                if (other == EQ || other == GT) {
    -                    return GE;
    -                } else {
    -                    return null;
    -                }
    -            case GT:
    -                if (other == EQ || other == GE) {
    -                    return GE;
    -                } else if (other == NE || other == LT) {
    -                    return NE;
    -                } else {
    -                    return null;
    -                }
    -            case BE:
    -                if (other == EQ || other == BT) {
    -                    return BE;
    -                } else {
    -                    return null;
    -                }
    -            case BT:
    -                if (other == EQ || other == BE) {
    -                    return BE;
    -                } else if (other == NE || other == AT) {
    -                    return NE;
    -                } else {
    -                    return null;
    -                }
    -            case AE:
    -                if (other == EQ || other == AT) {
    -                    return AE;
    -                } else {
    -                    return null;
    -                }
    -            case AT:
    -                if (other == EQ || other == AE) {
    -                    return AE;
    -                } else if (other == NE || other == BT) {
    -                    return NE;
    -                } else {
    -                    return null;
    -                }
    -        }
    -        throw new IllegalArgumentException(this.toString());
    -    }
    -}
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ConditionalNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ConditionalNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ConditionalNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -25,12 +25,13 @@
     import static com.oracle.graal.nodes.calc.CompareNode.*;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.calc.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.graph.spi.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.java.*;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
     
     /**
      * The {@code ConditionalNode} class represents a comparison that yields one of two values. Note
    @@ -128,7 +129,7 @@
         public static native boolean materializeCondition(@ConstantNodeParameter Condition condition, long x, long y);
     
         @NodeIntrinsic
    -    public static boolean materializeIsInstance(Class mirror, Object object) {
    +    public static boolean materializeIsInstance(Class mirror, Object object) {
             return mirror.isInstance(object);
         }
     }
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ConvertNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ConvertNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ConvertNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -24,8 +24,8 @@
     
     import com.oracle.graal.api.code.*;
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.nodes.*;
    -import com.oracle.graal.nodes.type.*;
     
     /**
      * Represents a conversion between primitive types.
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FixedBinaryNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FixedBinaryNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FixedBinaryNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,8 +22,8 @@
      */
     package com.oracle.graal.nodes.calc;
     
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.nodes.*;
    -import com.oracle.graal.nodes.type.*;
     
     public abstract class FixedBinaryNode extends DeoptimizingFixedWithNextNode {
     
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatAddNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatAddNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatAddNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,12 +23,13 @@
     package com.oracle.graal.nodes.calc;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.graph.spi.*;
    +import com.oracle.graal.lir.gen.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.extended.*;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
     
     @NodeInfo(shortName = "+")
     public final class FloatAddNode extends FloatArithmeticNode implements Canonicalizable {
    @@ -65,20 +66,20 @@
         }
     
         @Override
    -    public void generate(NodeLIRBuilderTool gen) {
    -        Value op1 = gen.operand(x());
    -        Value op2 = gen.operand(y());
    -        if (!y().isConstant() && !livesLonger(this, y(), gen)) {
    +    public void generate(NodeMappableLIRBuilder builder, ArithmeticLIRGenerator gen) {
    +        Value op1 = builder.operand(x());
    +        Value op2 = builder.operand(y());
    +        if (!y().isConstant() && !livesLonger(this, y(), builder)) {
                 Value op = op1;
                 op1 = op2;
                 op2 = op;
             }
    -        gen.setResult(this, gen.getLIRGeneratorTool().emitAdd(op1, op2));
    +        builder.setResult(this, gen.emitAdd(op1, op2));
         }
     
    -    public static boolean livesLonger(ValueNode after, ValueNode value, NodeLIRBuilderTool gen) {
    +    public static boolean livesLonger(ValueNode after, ValueNode value, NodeMappableLIRBuilder builder) {
             for (Node usage : value.usages()) {
    -            if (usage != after && usage instanceof ValueNode && gen.hasOperand(((ValueNode) usage))) {
    +            if (usage != after && usage instanceof ValueNode && builder.hasOperand(((ValueNode) usage))) {
                     return true;
                 }
             }
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatArithmeticNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatArithmeticNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatArithmeticNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,9 +22,9 @@
      */
     package com.oracle.graal.nodes.calc;
     
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
     
     public abstract class FloatArithmeticNode extends BinaryNode implements ArithmeticLIRLowerable, MemoryArithmeticLIRLowerable {
     
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatConvertNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatConvertNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatConvertNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,12 +23,15 @@
     package com.oracle.graal.nodes.calc;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.*;
    +import com.oracle.graal.compiler.common.calc.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.graph.spi.*;
    +import com.oracle.graal.lir.gen.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.extended.*;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
     
     /**
      * A {@code FloatConvert} converts between integers and floating point numbers according to Java
    @@ -36,46 +39,6 @@
      */
     public class FloatConvertNode extends ConvertNode implements Canonicalizable, Lowerable, ArithmeticLIRLowerable, MemoryArithmeticLIRLowerable {
     
    -    public enum FloatConvert {
    -        F2I,
    -        D2I,
    -        F2L,
    -        D2L,
    -        I2F,
    -        L2F,
    -        D2F,
    -        I2D,
    -        L2D,
    -        F2D;
    -
    -        public FloatConvert reverse() {
    -            switch (this) {
    -                case D2F:
    -                    return F2D;
    -                case D2I:
    -                    return I2D;
    -                case D2L:
    -                    return L2D;
    -                case F2D:
    -                    return D2F;
    -                case F2I:
    -                    return I2F;
    -                case F2L:
    -                    return L2F;
    -                case I2D:
    -                    return D2I;
    -                case I2F:
    -                    return F2I;
    -                case L2D:
    -                    return D2L;
    -                case L2F:
    -                    return F2L;
    -                default:
    -                    throw GraalInternalError.shouldNotReachHere();
    -            }
    -        }
    -    }
    -
         private final FloatConvert op;
     
         public FloatConvertNode(FloatConvert op, ValueNode input) {
    @@ -201,17 +164,11 @@
             tool.getLowerer().lower(this, tool);
         }
     
    -    public void generate(NodeLIRBuilderTool gen) {
    -        gen.setResult(this, gen.getLIRGeneratorTool().emitFloatConvert(op, gen.operand(getInput())));
    +    public void generate(NodeMappableLIRBuilder builder, ArithmeticLIRGenerator gen) {
    +        builder.setResult(this, gen.emitFloatConvert(op, builder.operand(getInput())));
         }
     
         public boolean generate(MemoryArithmeticLIRLowerer gen, Access access) {
    -        Kind kind = access.accessLocation().getValueKind();
    -        if (kind != kind.getStackKind()) {
    -            // Doesn't work for subword operations
    -            return false;
    -        }
    -
             Value result = gen.emitFloatConvertMemory(getOp(), access);
             if (result != null) {
                 gen.setResult(this, result);
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatDivNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatDivNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatDivNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,12 +23,13 @@
     package com.oracle.graal.nodes.calc;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.graph.spi.*;
    +import com.oracle.graal.lir.gen.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.extended.*;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
     
     @NodeInfo(shortName = "/")
     public final class FloatDivNode extends FloatArithmeticNode implements Canonicalizable {
    @@ -57,8 +58,8 @@
         }
     
         @Override
    -    public void generate(NodeLIRBuilderTool gen) {
    -        gen.setResult(this, gen.getLIRGeneratorTool().emitDiv(gen.operand(x()), gen.operand(y()), null));
    +    public void generate(NodeMappableLIRBuilder builder, ArithmeticLIRGenerator gen) {
    +        builder.setResult(this, gen.emitDiv(builder.operand(x()), builder.operand(y()), null));
         }
     
         @Override
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatEqualsNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatEqualsNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatEqualsNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,9 +22,10 @@
      */
     package com.oracle.graal.nodes.calc;
     
    +import com.oracle.graal.compiler.common.calc.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.nodes.*;
    -import com.oracle.graal.nodes.type.*;
     
     @NodeInfo(shortName = "==")
     public final class FloatEqualsNode extends CompareNode {
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatLessThanNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatLessThanNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatLessThanNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,10 +22,11 @@
      */
     package com.oracle.graal.nodes.calc;
     
    +import com.oracle.graal.compiler.common.calc.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.graph.spi.*;
     import com.oracle.graal.nodes.*;
    -import com.oracle.graal.nodes.type.*;
     
     @NodeInfo(shortName = "<")
     public final class FloatLessThanNode extends CompareNode {
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatMulNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatMulNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatMulNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,12 +23,13 @@
     package com.oracle.graal.nodes.calc;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.graph.spi.*;
    +import com.oracle.graal.lir.gen.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.extended.*;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
     
     @NodeInfo(shortName = "*")
     public final class FloatMulNode extends FloatArithmeticNode implements Canonicalizable {
    @@ -60,15 +61,15 @@
         }
     
         @Override
    -    public void generate(NodeLIRBuilderTool gen) {
    -        Value op1 = gen.operand(x());
    -        Value op2 = gen.operand(y());
    -        if (!y().isConstant() && !FloatAddNode.livesLonger(this, y(), gen)) {
    +    public void generate(NodeMappableLIRBuilder builder, ArithmeticLIRGenerator gen) {
    +        Value op1 = builder.operand(x());
    +        Value op2 = builder.operand(y());
    +        if (!y().isConstant() && !FloatAddNode.livesLonger(this, y(), builder)) {
                 Value op = op1;
                 op1 = op2;
                 op2 = op;
             }
    -        gen.setResult(this, gen.getLIRGeneratorTool().emitMul(op1, op2));
    +        builder.setResult(this, gen.emitMul(op1, op2));
         }
     
         @Override
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatRemNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatRemNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatRemNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,12 +23,13 @@
     package com.oracle.graal.nodes.calc;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.graph.spi.*;
    +import com.oracle.graal.lir.gen.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.extended.*;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
     
     @NodeInfo(shortName = "%")
     public final class FloatRemNode extends FloatArithmeticNode implements Canonicalizable {
    @@ -57,8 +58,8 @@
         }
     
         @Override
    -    public void generate(NodeLIRBuilderTool gen) {
    -        gen.setResult(this, gen.getLIRGeneratorTool().emitRem(gen.operand(x()), gen.operand(y()), null));
    +    public void generate(NodeMappableLIRBuilder builder, ArithmeticLIRGenerator gen) {
    +        builder.setResult(this, gen.emitRem(builder.operand(x()), builder.operand(y()), null));
         }
     
         @Override
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatSubNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatSubNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatSubNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,12 +23,13 @@
     package com.oracle.graal.nodes.calc;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.graph.spi.*;
    +import com.oracle.graal.lir.gen.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.extended.*;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
     
     @NodeInfo(shortName = "-")
     public final class FloatSubNode extends FloatArithmeticNode implements Canonicalizable {
    @@ -76,8 +77,8 @@
         }
     
         @Override
    -    public void generate(NodeLIRBuilderTool gen) {
    -        gen.setResult(this, gen.getLIRGeneratorTool().emitSub(gen.operand(x()), gen.operand(y())));
    +    public void generate(NodeMappableLIRBuilder builder, ArithmeticLIRGenerator gen) {
    +        builder.setResult(this, gen.emitSub(builder.operand(x()), builder.operand(y())));
         }
     
         @Override
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatingNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatingNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatingNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,9 +22,9 @@
      */
     package com.oracle.graal.nodes.calc;
     
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.nodes.*;
    -import com.oracle.graal.nodes.type.*;
     
     public abstract class FloatingNode extends ValueNode implements Node.ValueNumberable {
     
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerAddNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerAddNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerAddNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,8 +23,10 @@
     package com.oracle.graal.nodes.calc;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.graph.spi.*;
    +import com.oracle.graal.lir.gen.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.extended.*;
     import com.oracle.graal.nodes.spi.*;
    @@ -89,16 +91,16 @@
         }
     
         @Override
    -    public void generate(NodeLIRBuilderTool gen) {
    -        Value op1 = gen.operand(x());
    +    public void generate(NodeMappableLIRBuilder builder, ArithmeticLIRGenerator gen) {
    +        Value op1 = builder.operand(x());
             assert op1 != null : x() + ", this=" + this;
    -        Value op2 = gen.operand(y());
    -        if (!y().isConstant() && !FloatAddNode.livesLonger(this, y(), gen)) {
    +        Value op2 = builder.operand(y());
    +        if (!y().isConstant() && !FloatAddNode.livesLonger(this, y(), builder)) {
                 Value op = op1;
                 op1 = op2;
                 op2 = op;
             }
    -        gen.setResult(this, gen.getLIRGeneratorTool().emitAdd(op1, op2));
    +        builder.setResult(this, gen.emitAdd(op1, op2));
         }
     
         @Override
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerArithmeticNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerArithmeticNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerArithmeticNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,6 +22,7 @@
      */
     package com.oracle.graal.nodes.calc;
     
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.spi.*;
     import com.oracle.graal.nodes.type.*;
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerBelowThanNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerBelowThanNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerBelowThanNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,10 +23,11 @@
     package com.oracle.graal.nodes.calc;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.calc.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.graph.spi.*;
     import com.oracle.graal.nodes.*;
    -import com.oracle.graal.nodes.type.*;
     
     @NodeInfo(shortName = "|<|")
     public final class IntegerBelowThanNode extends CompareNode {
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerConvertNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerConvertNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerConvertNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,10 +23,10 @@
     package com.oracle.graal.nodes.calc;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.spi.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
     
     /**
      * An {@code IntegerConvert} converts an integer to an integer of different width.
    @@ -67,7 +67,7 @@
                     return getInput();
                 } else if (getInput().isConstant()) {
                     Constant ret = evalConst(getInput().asConstant());
    -                return ConstantNode.forIntegerBits(resultBits, false, ret.asLong(), graph());
    +                return ConstantNode.forIntegerBits(resultBits, ret.asLong(), graph());
                 }
             }
     
    @@ -86,19 +86,11 @@
                 result = graph.unique(new NarrowNode(input, toStamp.getBits()));
             } else {
                 // toStamp.getBits() > fromStamp.getBits()
    -            if (fromStamp.isUnsigned()) {
    -                result = graph.unique(new ZeroExtendNode(input, toStamp.getBits()));
    -            } else {
    -                result = graph.unique(new SignExtendNode(input, toStamp.getBits()));
    -            }
    +            result = graph.unique(new SignExtendNode(input, toStamp.getBits()));
             }
     
             IntegerStamp resultStamp = (IntegerStamp) result.stamp();
             assert toStamp.getBits() == resultStamp.getBits();
    -        if (toStamp.isUnsigned() == resultStamp.isUnsigned()) {
    -            return result;
    -        } else {
    -            return graph.unique(new ReinterpretNode(toStamp, result));
    -        }
    +        return result;
         }
     }
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerDivNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerDivNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerDivNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,6 +23,7 @@
     package com.oracle.graal.nodes.calc;
     
     import com.oracle.graal.api.code.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.graph.spi.*;
     import com.oracle.graal.nodes.*;
    @@ -107,7 +108,7 @@
     
         @Override
         public void generate(NodeLIRBuilderTool gen) {
    -        gen.setResult(this, gen.getLIRGeneratorTool().emitDiv(gen.operand(x()), gen.operand(y()), this));
    +        gen.setResult(this, gen.getLIRGeneratorTool().emitDiv(gen.operand(x()), gen.operand(y()), gen.state(this)));
         }
     
         @Override
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerEqualsNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerEqualsNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerEqualsNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,10 +23,11 @@
     package com.oracle.graal.nodes.calc;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.calc.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.graph.spi.*;
     import com.oracle.graal.nodes.*;
    -import com.oracle.graal.nodes.type.*;
     import com.oracle.graal.nodes.util.*;
     
     @NodeInfo(shortName = "==")
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerLessThanNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerLessThanNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerLessThanNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,10 +23,11 @@
     package com.oracle.graal.nodes.calc;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.calc.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.graph.spi.*;
     import com.oracle.graal.nodes.*;
    -import com.oracle.graal.nodes.type.*;
     
     @NodeInfo(shortName = "<")
     public final class IntegerLessThanNode extends CompareNode {
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerMulNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerMulNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerMulNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -24,12 +24,13 @@
     
     import com.oracle.graal.api.code.*;
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.graph.spi.*;
    +import com.oracle.graal.lir.gen.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.extended.*;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
     
     @NodeInfo(shortName = "*")
     public class IntegerMulNode extends IntegerArithmeticNode implements Canonicalizable, NarrowableArithmeticNode {
    @@ -75,15 +76,15 @@
         }
     
         @Override
    -    public void generate(NodeLIRBuilderTool gen) {
    -        Value op1 = gen.operand(x());
    -        Value op2 = gen.operand(y());
    -        if (!y().isConstant() && !FloatAddNode.livesLonger(this, y(), gen)) {
    +    public void generate(NodeMappableLIRBuilder builder, ArithmeticLIRGenerator gen) {
    +        Value op1 = builder.operand(x());
    +        Value op2 = builder.operand(y());
    +        if (!y().isConstant() && !FloatAddNode.livesLonger(this, y(), builder)) {
                 Value op = op1;
                 op1 = op2;
                 op2 = op;
             }
    -        gen.setResult(this, gen.getLIRGeneratorTool().emitMul(op1, op2));
    +        builder.setResult(this, gen.emitMul(op1, op2));
         }
     
         @Override
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerRemNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerRemNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerRemNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,11 +23,11 @@
     package com.oracle.graal.nodes.calc;
     
     import com.oracle.graal.api.code.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.graph.spi.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
     
     @NodeInfo(shortName = "%")
     public class IntegerRemNode extends FixedBinaryNode implements Canonicalizable, Lowerable, LIRLowerable {
    @@ -62,7 +62,7 @@
     
         @Override
         public void generate(NodeLIRBuilderTool gen) {
    -        gen.setResult(this, gen.getLIRGeneratorTool().emitRem(gen.operand(x()), gen.operand(y()), this));
    +        gen.setResult(this, gen.getLIRGeneratorTool().emitRem(gen.operand(x()), gen.operand(y()), gen.state(this)));
         }
     
         @Override
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerSubNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerSubNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerSubNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,8 +23,10 @@
     package com.oracle.graal.nodes.calc;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.graph.spi.*;
    +import com.oracle.graal.lir.gen.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.extended.*;
     import com.oracle.graal.nodes.spi.*;
    @@ -117,8 +119,8 @@
         }
     
         @Override
    -    public void generate(NodeLIRBuilderTool gen) {
    -        gen.setResult(this, gen.getLIRGeneratorTool().emitSub(gen.operand(x()), gen.operand(y())));
    +    public void generate(NodeMappableLIRBuilder builder, ArithmeticLIRGenerator gen) {
    +        builder.setResult(this, gen.emitSub(builder.operand(x()), builder.operand(y())));
         }
     
         @Override
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerTestNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerTestNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerTestNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,45 +22,26 @@
      */
     package com.oracle.graal.nodes.calc;
     
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.graph.spi.*;
     import com.oracle.graal.nodes.*;
    -import com.oracle.graal.nodes.extended.*;
    -import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
     
     /**
      * This node will perform a "test" operation on its arguments. Its result is equivalent to the
      * expression "(x & y) == 0", meaning that it will return true if (and only if) no bit is set in
      * both x and y.
      */
    -public class IntegerTestNode extends LogicNode implements Canonicalizable, LIRLowerable, MemoryArithmeticLIRLowerable {
    -
    -    @Input private ValueNode x;
    -    @Input private ValueNode y;
    -
    -    public ValueNode x() {
    -        return x;
    -    }
    -
    -    public ValueNode y() {
    -        return y;
    -    }
    +public class IntegerTestNode extends BinaryLogicNode implements Canonicalizable {
     
         /**
          * Constructs a new Test instruction.
    -     * 
    +     *
          * @param x the instruction producing the first input to the instruction
          * @param y the instruction that produces the second input to this instruction
          */
         public IntegerTestNode(ValueNode x, ValueNode y) {
    -        assert x != null && y != null && x.stamp().isCompatible(y.stamp());
    -        this.x = x;
    -        this.y = y;
    -    }
    -
    -    @Override
    -    public void generate(NodeLIRBuilderTool gen) {
    +        super(x, y);
         }
     
         @Override
    @@ -73,13 +54,10 @@
                 IntegerStamp yStamp = (IntegerStamp) y().stamp();
                 if ((xStamp.upMask() & yStamp.upMask()) == 0) {
                     return LogicConstantNode.tautology(graph());
    +            } else if ((xStamp.downMask() & yStamp.downMask()) != 0) {
    +                return LogicConstantNode.contradiction(graph());
                 }
             }
             return this;
         }
    -
    -    @Override
    -    public boolean generate(MemoryArithmeticLIRLowerer gen, Access access) {
    -        return false;
    -    }
     }
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IsNullNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IsNullNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IsNullNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,6 +23,7 @@
     package com.oracle.graal.nodes.calc;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.graph.spi.*;
     import com.oracle.graal.nodes.*;
    @@ -68,7 +69,7 @@
                 assert constant.getKind() == Kind.Object;
                 return LogicConstantNode.forBoolean(constant.isNull(), graph());
             }
    -        if (ObjectStamp.isObjectNonNull(object.stamp())) {
    +        if (StampTool.isObjectNonNull(object.stamp())) {
                 return LogicConstantNode.contradiction(graph());
             }
             return this;
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/LeftShiftNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/LeftShiftNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/LeftShiftNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,8 +23,10 @@
     package com.oracle.graal.nodes.calc;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.graph.spi.*;
    +import com.oracle.graal.lir.gen.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.spi.*;
     import com.oracle.graal.nodes.type.*;
    @@ -92,7 +94,7 @@
         }
     
         @Override
    -    public void generate(NodeLIRBuilderTool gen) {
    -        gen.setResult(this, gen.getLIRGeneratorTool().emitShl(gen.operand(x()), gen.operand(y())));
    +    public void generate(NodeMappableLIRBuilder builder, ArithmeticLIRGenerator gen) {
    +        builder.setResult(this, gen.emitShl(builder.operand(x()), builder.operand(y())));
         }
     }
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NarrowNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NarrowNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NarrowNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,8 +23,10 @@
     package com.oracle.graal.nodes.calc;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.graph.spi.*;
    +import com.oracle.graal.lir.gen.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.extended.*;
     import com.oracle.graal.nodes.spi.*;
    @@ -50,13 +52,7 @@
     
         @Override
         public Constant reverse(Constant input) {
    -        IntegerStamp stamp = (IntegerStamp) stamp();
    -        long result;
    -        if (stamp.isUnsigned()) {
    -            result = ZeroExtendNode.zeroExtend(input.asLong(), getResultBits());
    -        } else {
    -            result = SignExtendNode.signExtend(input.asLong(), getResultBits());
    -        }
    +        long result = SignExtendNode.signExtend(input.asLong(), getResultBits());
             return Constant.forPrimitiveInt(getInputBits(), result);
         }
     
    @@ -110,8 +106,8 @@
         }
     
         @Override
    -    public void generate(NodeLIRBuilderTool gen) {
    -        gen.setResult(this, gen.getLIRGeneratorTool().emitNarrow(gen.operand(getInput()), getResultBits()));
    +    public void generate(NodeMappableLIRBuilder builder, ArithmeticLIRGenerator gen) {
    +        builder.setResult(this, gen.emitNarrow(builder.operand(getInput()), getResultBits()));
         }
     
         @Override
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NegateNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NegateNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NegateNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,8 +23,10 @@
     package com.oracle.graal.nodes.calc;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.graph.spi.*;
    +import com.oracle.graal.lir.gen.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.spi.*;
     import com.oracle.graal.nodes.type.*;
    @@ -88,7 +90,7 @@
         }
     
         @Override
    -    public void generate(NodeLIRBuilderTool gen) {
    -        gen.setResult(this, gen.getLIRGeneratorTool().emitNegate(gen.operand(x())));
    +    public void generate(NodeMappableLIRBuilder builder, ArithmeticLIRGenerator gen) {
    +        builder.setResult(this, gen.emitNegate(builder.operand(x())));
         }
     }
    diff -r 518a7f487c4f -r 9363fffa8b07 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 Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NormalizeCompareNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,9 +23,9 @@
     package com.oracle.graal.nodes.calc;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
     
     /**
      * Returns -1, 0, or 1 if either x < y, x == y, or x > y. If the comparison is undecided (one
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NotNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NotNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NotNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,8 +23,10 @@
     package com.oracle.graal.nodes.calc;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.graph.spi.*;
    +import com.oracle.graal.lir.gen.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.spi.*;
     import com.oracle.graal.nodes.type.*;
    @@ -73,7 +75,7 @@
         }
     
         @Override
    -    public void generate(NodeLIRBuilderTool gen) {
    -        gen.setResult(this, gen.getLIRGeneratorTool().emitNot(gen.operand(x())));
    +    public void generate(NodeMappableLIRBuilder builder, ArithmeticLIRGenerator gen) {
    +        builder.setResult(this, gen.emitNot(builder.operand(x())));
         }
     }
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ObjectEqualsNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ObjectEqualsNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ObjectEqualsNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,6 +23,7 @@
     package com.oracle.graal.nodes.calc;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.calc.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.graph.spi.*;
     import com.oracle.graal.nodes.*;
    @@ -60,9 +61,9 @@
                 return LogicConstantNode.tautology(graph());
             }
     
    -        if (ObjectStamp.isObjectAlwaysNull(x())) {
    +        if (StampTool.isObjectAlwaysNull(x())) {
                 return graph().unique(new IsNullNode(y()));
    -        } else if (ObjectStamp.isObjectAlwaysNull(y())) {
    +        } else if (StampTool.isObjectAlwaysNull(y())) {
                 return graph().unique(new IsNullNode(x()));
             }
             if (x().stamp().alwaysDistinct(y().stamp())) {
    @@ -75,9 +76,9 @@
         private void virtualizeNonVirtualComparison(State state, ValueNode other, VirtualizerTool tool) {
             if (!state.getVirtualObject().hasIdentity() && state.getVirtualObject().entryKind(0) == Kind.Boolean) {
                 if (other.isConstant()) {
    -                Object otherValue = other.asConstant().asObject();
    -                if (otherValue == Boolean.TRUE || otherValue == Boolean.FALSE) {
    -                    int expectedValue = (otherValue == Boolean.TRUE) ? 1 : 0;
    +                Constant otherUnboxed = tool.getConstantReflectionProvider().unboxPrimitive(other.asConstant());
    +                if (otherUnboxed != null && otherUnboxed.getKind() == Kind.Boolean) {
    +                    int expectedValue = otherUnboxed.asBoolean() ? 1 : 0;
                         IntegerEqualsNode equals = new IntegerEqualsNode(state.getEntry(0), ConstantNode.forInt(expectedValue, graph()));
                         tool.addNode(equals);
                         tool.replaceWithValue(equals);
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/OrNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/OrNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/OrNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,8 +23,10 @@
     package com.oracle.graal.nodes.calc;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.graph.spi.*;
    +import com.oracle.graal.lir.gen.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.extended.*;
     import com.oracle.graal.nodes.spi.*;
    @@ -73,8 +75,8 @@
         }
     
         @Override
    -    public void generate(NodeLIRBuilderTool gen) {
    -        gen.setResult(this, gen.getLIRGeneratorTool().emitOr(gen.operand(x()), gen.operand(y())));
    +    public void generate(NodeMappableLIRBuilder builder, ArithmeticLIRGenerator gen) {
    +        builder.setResult(this, gen.emitOr(builder.operand(x()), builder.operand(y())));
         }
     
         @Override
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ReinterpretNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ReinterpretNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ReinterpretNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,12 +23,14 @@
     package com.oracle.graal.nodes.calc;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.graph.spi.*;
    +import com.oracle.graal.lir.gen.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.extended.*;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
     
     /**
      * The {@code ReinterpretNode} class represents a reinterpreting conversion that changes the stamp
    @@ -102,9 +104,9 @@
         }
     
         @Override
    -    public void generate(NodeLIRBuilderTool gen) {
    -        PlatformKind kind = gen.getLIRGeneratorTool().getPlatformKind(stamp());
    -        gen.setResult(this, gen.getLIRGeneratorTool().emitReinterpret(kind, gen.operand(value())));
    +    public void generate(NodeMappableLIRBuilder builder, ArithmeticLIRGenerator gen) {
    +        PlatformKind kind = gen.getPlatformKind(stamp());
    +        builder.setResult(this, gen.emitReinterpret(kind, builder.operand(value())));
         }
     
         @Override
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/RightShiftNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/RightShiftNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/RightShiftNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,11 +23,12 @@
     package com.oracle.graal.nodes.calc;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.graph.spi.*;
    +import com.oracle.graal.lir.gen.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
     
     @NodeInfo(shortName = ">>")
     public final class RightShiftNode extends ShiftNode implements Canonicalizable {
    @@ -98,7 +99,7 @@
         }
     
         @Override
    -    public void generate(NodeLIRBuilderTool gen) {
    -        gen.setResult(this, gen.getLIRGeneratorTool().emitShr(gen.operand(x()), gen.operand(y())));
    +    public void generate(NodeMappableLIRBuilder builder, ArithmeticLIRGenerator gen) {
    +        builder.setResult(this, gen.emitShr(builder.operand(x()), builder.operand(y())));
         }
     }
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ShiftNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ShiftNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ShiftNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,9 +23,9 @@
     package com.oracle.graal.nodes.calc;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
     
     /**
      * The {@code ShiftOp} class represents shift operations.
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/SignExtendNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/SignExtendNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/SignExtendNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,8 +23,10 @@
     package com.oracle.graal.nodes.calc;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.graph.spi.*;
    +import com.oracle.graal.lir.gen.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.extended.*;
     import com.oracle.graal.nodes.spi.*;
    @@ -105,13 +107,13 @@
         }
     
         @Override
    -    public void generate(NodeLIRBuilderTool gen) {
    -        gen.setResult(this, gen.getLIRGeneratorTool().emitSignExtend(gen.operand(getInput()), getInputBits(), getResultBits()));
    +    public void generate(NodeMappableLIRBuilder builder, ArithmeticLIRGenerator gen) {
    +        builder.setResult(this, gen.emitSignExtend(builder.operand(getInput()), getInputBits(), getResultBits()));
         }
     
         @Override
         public boolean generate(MemoryArithmeticLIRLowerer gen, Access access) {
    -        Value result = gen.emitSignExtendMemory(access, access.accessLocation().getValueKind().getBitCount(), getResultBits());
    +        Value result = gen.emitSignExtendMemory(access, getInputBits(), getResultBits());
             if (result != null) {
                 gen.setResult(this, result);
             }
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedDivNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedDivNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedDivNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -24,11 +24,11 @@
     
     import com.oracle.graal.api.code.*;
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.graph.spi.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
     
     @NodeInfo(shortName = "|/|")
     public class UnsignedDivNode extends FixedBinaryNode implements Canonicalizable, Lowerable, LIRLowerable {
    @@ -72,7 +72,7 @@
     
         @Override
         public void generate(NodeLIRBuilderTool gen) {
    -        gen.setResult(this, gen.getLIRGeneratorTool().emitUDiv(gen.operand(x()), gen.operand(y()), this));
    +        gen.setResult(this, gen.getLIRGeneratorTool().emitUDiv(gen.operand(x()), gen.operand(y()), gen.state(this)));
         }
     
         @Override
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedRemNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedRemNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedRemNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -24,11 +24,11 @@
     
     import com.oracle.graal.api.code.*;
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.graph.spi.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
     
     @NodeInfo(shortName = "|%|")
     public class UnsignedRemNode extends FixedBinaryNode implements Canonicalizable, Lowerable, LIRLowerable {
    @@ -71,7 +71,7 @@
     
         @Override
         public void generate(NodeLIRBuilderTool gen) {
    -        gen.setResult(this, gen.getLIRGeneratorTool().emitURem(gen.operand(x()), gen.operand(y()), this));
    +        gen.setResult(this, gen.getLIRGeneratorTool().emitURem(gen.operand(x()), gen.operand(y()), gen.state(this)));
         }
     
         @Override
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedRightShiftNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedRightShiftNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedRightShiftNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,8 +23,10 @@
     package com.oracle.graal.nodes.calc;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.graph.spi.*;
    +import com.oracle.graal.lir.gen.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.spi.*;
     import com.oracle.graal.nodes.type.*;
    @@ -92,7 +94,7 @@
         }
     
         @Override
    -    public void generate(NodeLIRBuilderTool gen) {
    -        gen.setResult(this, gen.getLIRGeneratorTool().emitUShr(gen.operand(x()), gen.operand(y())));
    +    public void generate(NodeMappableLIRBuilder builder, ArithmeticLIRGenerator gen) {
    +        builder.setResult(this, gen.emitUShr(builder.operand(x()), builder.operand(y())));
         }
     }
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/XorNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/XorNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/XorNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,8 +23,10 @@
     package com.oracle.graal.nodes.calc;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.graph.spi.*;
    +import com.oracle.graal.lir.gen.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.extended.*;
     import com.oracle.graal.nodes.spi.*;
    @@ -72,8 +74,8 @@
         }
     
         @Override
    -    public void generate(NodeLIRBuilderTool gen) {
    -        gen.setResult(this, gen.getLIRGeneratorTool().emitXor(gen.operand(x()), gen.operand(y())));
    +    public void generate(NodeMappableLIRBuilder builder, ArithmeticLIRGenerator gen) {
    +        builder.setResult(this, gen.emitXor(builder.operand(x()), builder.operand(y())));
         }
     
         @Override
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ZeroExtendNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ZeroExtendNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ZeroExtendNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,8 +23,10 @@
     package com.oracle.graal.nodes.calc;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.graph.spi.*;
    +import com.oracle.graal.lir.gen.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.extended.*;
     import com.oracle.graal.nodes.spi.*;
    @@ -75,6 +77,19 @@
                 ZeroExtendNode other = (ZeroExtendNode) getInput();
                 return graph().unique(new ZeroExtendNode(other.getInput(), getResultBits()));
             }
    +        if (getInput() instanceof NarrowNode) {
    +            NarrowNode narrow = (NarrowNode) getInput();
    +            Stamp inputStamp = narrow.getInput().stamp();
    +            if (inputStamp instanceof IntegerStamp && inputStamp.isCompatible(stamp())) {
    +                IntegerStamp istamp = (IntegerStamp) inputStamp;
    +                long mask = IntegerStamp.defaultMask(PrimitiveStamp.getBits(narrow.stamp()));
    +                if (((istamp.upMask() | istamp.downMask()) & ~mask) == 0) {
    +                    // The original value is in the range of the masked zero extended result so
    +                    // simply return the original input.
    +                    return narrow.getInput();
    +                }
    +            }
    +        }
     
             return this;
         }
    @@ -85,8 +100,8 @@
         }
     
         @Override
    -    public void generate(NodeLIRBuilderTool gen) {
    -        gen.setResult(this, gen.getLIRGeneratorTool().emitZeroExtend(gen.operand(getInput()), getInputBits(), getResultBits()));
    +    public void generate(NodeMappableLIRBuilder builder, ArithmeticLIRGenerator gen) {
    +        builder.setResult(this, gen.emitZeroExtend(builder.operand(getInput()), getInputBits(), getResultBits()));
         }
     
         @Override
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/AbstractBlock.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/AbstractBlock.java	Wed Apr 23 15:22:20 2014 +0200
    +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    @@ -1,58 +0,0 @@
    -/*
    - * Copyright (c) 2014, 2014, 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.cfg;
    -
    -import java.util.*;
    -
    -public interface AbstractBlock> {
    -
    -    int getId();
    -
    -    Loop getLoop();
    -
    -    int getLoopDepth();
    -
    -    boolean isLoopHeader();
    -
    -    boolean isLoopEnd();
    -
    -    boolean isExceptionEntry();
    -
    -    List getPredecessors();
    -
    -    int getPredecessorCount();
    -
    -    List getSuccessors();
    -
    -    int getSuccessorCount();
    -
    -    int getLinearScanNumber();
    -
    -    void setLinearScanNumber(int linearScanNumber);
    -
    -    boolean isAligned();
    -
    -    void setAlign(boolean align);
    -
    -    T getDominator();
    -}
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/AbstractBlockBase.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/AbstractBlockBase.java	Wed Apr 23 15:22:20 2014 +0200
    +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    @@ -1,92 +0,0 @@
    -/*
    - * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
    - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    - *
    - * This code is free software; you can redistribute it and/or modify it
    - * under the terms of the GNU General Public License version 2 only, as
    - * published by the Free Software Foundation.
    - *
    - * This code is distributed in the hope that it will be useful, but WITHOUT
    - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    - * version 2 for more details (a copy is included in the LICENSE file that
    - * accompanied this code).
    - *
    - * You should have received a copy of the GNU General Public License version
    - * 2 along with this work; if not, write to the Free Software Foundation,
    - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    - *
    - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    - * or visit www.oracle.com if you need additional information or have any
    - * questions.
    - */
    -package com.oracle.graal.nodes.cfg;
    -
    -import java.util.*;
    -
    -public abstract class AbstractBlockBase> implements AbstractBlock {
    -
    -    protected int id;
    -
    -    protected List predecessors;
    -    protected List successors;
    -
    -    protected T dominator;
    -
    -    private boolean align;
    -    private int linearScanNumber;
    -
    -    protected AbstractBlockBase() {
    -        this.id = ControlFlowGraph.BLOCK_ID_INITIAL;
    -        this.linearScanNumber = -1;
    -    }
    -
    -    public int getId() {
    -        return id;
    -    }
    -
    -    public void setId(int id) {
    -        this.id = id;
    -    }
    -
    -    public List getPredecessors() {
    -        return predecessors;
    -    }
    -
    -    public List getSuccessors() {
    -        return successors;
    -    }
    -
    -    public T getDominator() {
    -        return dominator;
    -    }
    -
    -    @Override
    -    public String toString() {
    -        return "B" + id;
    -    }
    -
    -    public int getPredecessorCount() {
    -        return getPredecessors().size();
    -    }
    -
    -    public int getSuccessorCount() {
    -        return getSuccessors().size();
    -    }
    -
    -    public int getLinearScanNumber() {
    -        return linearScanNumber;
    -    }
    -
    -    public void setLinearScanNumber(int linearScanNumber) {
    -        this.linearScanNumber = linearScanNumber;
    -    }
    -
    -    public boolean isAligned() {
    -        return align;
    -    }
    -
    -    public void setAlign(boolean align) {
    -        this.align = align;
    -    }
    -}
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/AbstractControlFlowGraph.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/AbstractControlFlowGraph.java	Wed Apr 23 15:22:20 2014 +0200
    +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    @@ -1,32 +0,0 @@
    -/*
    - * Copyright (c) 2014, 2014, 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.cfg;
    -
    -public interface AbstractControlFlowGraph> {
    -
    -    T[] getBlocks();
    -
    -    Loop[] getLoops();
    -
    -    T getStartBlock();
    -}
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/Block.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/Block.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/Block.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -24,24 +24,25 @@
     
     import java.util.*;
     
    +import com.oracle.graal.compiler.common.cfg.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.java.*;
     
     public final class Block extends AbstractBlockBase {
     
    -    protected final AbstractBeginNode beginNode;
    +    protected final BeginNode beginNode;
     
         protected FixedNode endNode;
    -    protected Loop loop;
    +    protected Loop loop;
     
         protected List dominated;
         protected Block postdominator;
     
    -    protected Block(AbstractBeginNode node) {
    +    protected Block(BeginNode node) {
             this.beginNode = node;
         }
     
    -    public AbstractBeginNode getBeginNode() {
    +    public BeginNode getBeginNode() {
             return beginNode;
         }
     
    @@ -49,7 +50,7 @@
             return endNode;
         }
     
    -    public Loop getLoop() {
    +    public Loop getLoop() {
             return loop;
         }
     
    @@ -70,11 +71,11 @@
         }
     
         public Block getFirstPredecessor() {
    -        return predecessors.get(0);
    +        return getPredecessors().get(0);
         }
     
         public Block getFirstSuccessor() {
    -        return successors.get(0);
    +        return getSuccessors().get(0);
         }
     
         public Block getEarliestPostDominated() {
    @@ -122,7 +123,7 @@
                 } else {
                     cur = ((FixedWithNextNode) cur).next();
                 }
    -            assert !(cur instanceof AbstractBeginNode);
    +            assert !(cur instanceof BeginNode);
                 return result;
             }
     
    @@ -167,10 +168,10 @@
             if (block == this) {
                 return true;
             }
    -        if (dominator == null) {
    +        if (getDominator() == null) {
                 return false;
             }
    -        return dominator.isDominatedBy(block);
    +        return getDominator().isDominatedBy(block);
         }
     
     }
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/BlockMap.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/BlockMap.java	Wed Apr 23 15:22:20 2014 +0200
    +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    @@ -1,41 +0,0 @@
    -/*
    - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
    - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    - *
    - * This code is free software; you can redistribute it and/or modify it
    - * under the terms of the GNU General Public License version 2 only, as
    - * published by the Free Software Foundation.
    - *
    - * This code is distributed in the hope that it will be useful, but WITHOUT
    - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    - * version 2 for more details (a copy is included in the LICENSE file that
    - * accompanied this code).
    - *
    - * You should have received a copy of the GNU General Public License version
    - * 2 along with this work; if not, write to the Free Software Foundation,
    - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    - *
    - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    - * or visit www.oracle.com if you need additional information or have any
    - * questions.
    - */
    -package com.oracle.graal.nodes.cfg;
    -
    -public class BlockMap {
    -
    -    private final T[] data;
    -
    -    @SuppressWarnings("unchecked")
    -    public BlockMap(AbstractControlFlowGraph cfg) {
    -        data = (T[]) new Object[cfg.getBlocks().length];
    -    }
    -
    -    public T get(AbstractBlock block) {
    -        return data[block.getId()];
    -    }
    -
    -    public void put(AbstractBlock block, T value) {
    -        data[block.getId()] = value;
    -    }
    -}
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/BlocksToDoubles.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/BlocksToDoubles.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/BlocksToDoubles.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -24,6 +24,7 @@
     
     import java.util.*;
     
    +import com.oracle.graal.compiler.common.cfg.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.util.*;
     
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/CFGVerifier.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/CFGVerifier.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/CFGVerifier.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -24,6 +24,8 @@
     
     import java.util.*;
     
    +import com.oracle.graal.compiler.common.cfg.*;
    +
     public class CFGVerifier {
     
         public static boolean verify(ControlFlowGraph cfg) {
    @@ -84,13 +86,13 @@
             }
     
             if (cfg.getLoops() != null) {
    -            for (Loop loop : cfg.getLoops()) {
    +            for (Loop loop : cfg.getLoops()) {
                     assert loop.header.isLoopHeader();
     
                     for (Block block : loop.blocks) {
                         assert block.getId() >= loop.header.getId();
     
    -                    Loop blockLoop = block.getLoop();
    +                    Loop blockLoop = block.getLoop();
                         while (blockLoop != loop) {
                             assert blockLoop != null;
                             blockLoop = blockLoop.parent;
    @@ -109,7 +111,7 @@
                     for (Block block : loop.exits) {
                         assert block.getId() >= loop.header.getId();
     
    -                    Loop blockLoop = block.getLoop();
    +                    Loop blockLoop = block.getLoop();
                         while (blockLoop != null) {
                             blockLoop = blockLoop.parent;
                             assert blockLoop != loop;
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/ControlFlowGraph.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/ControlFlowGraph.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/ControlFlowGraph.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -24,6 +24,8 @@
     
     import java.util.*;
     
    +import com.oracle.graal.compiler.common.*;
    +import com.oracle.graal.compiler.common.cfg.*;
     import com.oracle.graal.debug.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.nodes.*;
    @@ -34,7 +36,7 @@
     
         private final NodeMap nodeToBlock;
         private Block[] reversePostOrder;
    -    private Loop[] loops;
    +    private List> loops;
     
         public static ControlFlowGraph compute(StructuredGraph graph, boolean connectBlocks, boolean computeLoops, boolean computeDominators, boolean computePostdominators) {
             ControlFlowGraph cfg = new ControlFlowGraph(graph);
    @@ -106,7 +108,7 @@
             return nodeToBlock.get(node);
         }
     
    -    public Loop[] getLoops() {
    +    public List> getLoops() {
             return loops;
         }
     
    @@ -117,15 +119,12 @@
             }
         }
     
    -    protected static final int BLOCK_ID_INITIAL = -1;
    -    protected static final int BLOCK_ID_VISITED = -2;
    -
         private void identifyBlock(Block block) {
             Node cur = block.getBeginNode();
             Node last;
     
             // assign proxies of a loop exit to this block
    -        if (cur instanceof AbstractBeginNode) {
    +        if (cur instanceof BeginNode) {
                 for (Node usage : cur.usages()) {
                     if (usage instanceof ProxyNode) {
                         nodeToBlock.set(usage, block);
    @@ -146,7 +145,7 @@
     
                 last = cur;
                 cur = cur.successors().first();
    -        } while (cur != null && !(cur instanceof AbstractBeginNode));
    +        } while (cur != null && !(cur instanceof BeginNode));
     
             block.endNode = (FixedNode) last;
         }
    @@ -154,7 +153,7 @@
         private void identifyBlocks() {
             // Find all block headers
             int numBlocks = 0;
    -        for (AbstractBeginNode begin : graph.getNodes(AbstractBeginNode.class)) {
    +        for (BeginNode begin : graph.getNodes(BeginNode.class)) {
                 Block block = new Block(begin);
                 numBlocks++;
                 identifyBlock(block);
    @@ -167,16 +166,16 @@
     
             do {
                 Block block = stack.get(stack.size() - 1);
    -            if (block.id == BLOCK_ID_INITIAL) {
    +            if (block.getId() == BLOCK_ID_INITIAL) {
                     // First time we see this block: push all successors.
                     for (Node suxNode : block.getEndNode().cfgSuccessors()) {
                         Block suxBlock = blockFor(suxNode);
    -                    if (suxBlock.id == BLOCK_ID_INITIAL) {
    +                    if (suxBlock.getId() == BLOCK_ID_INITIAL) {
                             stack.add(suxBlock);
                         }
                     }
    -                block.id = BLOCK_ID_VISITED;
    -            } else if (block.id == BLOCK_ID_VISITED) {
    +                block.setId(BLOCK_ID_VISITED);
    +            } else if (block.getId() == BLOCK_ID_VISITED) {
                     // Second time we see this block: All successors have been processed, so add block
                     // to postorder list.
                     stack.remove(stack.size() - 1);
    @@ -192,7 +191,7 @@
             reversePostOrder = new Block[numBlocks];
             for (int i = 0; i < numBlocks; i++) {
                 Block block = postOrder.get(numBlocks - i - 1);
    -            block.id = i;
    +            block.setId(i);
                 reversePostOrder[i] = block;
             }
         }
    @@ -203,42 +202,42 @@
                 List predecessors = new ArrayList<>(4);
                 for (Node predNode : block.getBeginNode().cfgPredecessors()) {
                     Block predBlock = nodeToBlock.get(predNode);
    -                if (predBlock.id >= 0) {
    +                if (predBlock.getId() >= 0) {
                         predecessors.add(predBlock);
                     }
                 }
                 if (block.getBeginNode() instanceof LoopBeginNode) {
                     for (LoopEndNode predNode : ((LoopBeginNode) block.getBeginNode()).orderedLoopEnds()) {
                         Block predBlock = nodeToBlock.get(predNode);
    -                    if (predBlock.id >= 0) {
    +                    if (predBlock.getId() >= 0) {
                             predecessors.add(predBlock);
                         }
                     }
                 }
    -            block.predecessors = predecessors;
    +            block.setPredecessors(predecessors);
     
                 List successors = new ArrayList<>(4);
                 for (Node suxNode : block.getEndNode().cfgSuccessors()) {
                     Block suxBlock = nodeToBlock.get(suxNode);
    -                assert suxBlock.id >= 0;
    +                assert suxBlock.getId() >= 0;
                     successors.add(suxBlock);
                 }
                 if (block.getEndNode() instanceof LoopEndNode) {
                     Block suxBlock = nodeToBlock.get(((LoopEndNode) block.getEndNode()).loopBegin());
    -                assert suxBlock.id >= 0;
    +                assert suxBlock.getId() >= 0;
                     successors.add(suxBlock);
                 }
    -            block.successors = successors;
    +            block.setSuccessors(successors);
             }
         }
     
         private void computeLoopInformation() {
    -        ArrayList loopsList = new ArrayList<>();
    +        loops = new ArrayList<>();
             for (Block block : reversePostOrder) {
                 Node beginNode = block.getBeginNode();
                 if (beginNode instanceof LoopBeginNode) {
    -                Loop loop = new Loop(block.getLoop(), loopsList.size(), block);
    -                loopsList.add(loop);
    +                Loop loop = new HIRLoop(block.getLoop(), loops.size(), block);
    +                loops.add(loop);
     
                     LoopBeginNode loopBegin = (LoopBeginNode) beginNode;
                     for (LoopEndNode end : loopBegin.loopEnds()) {
    @@ -256,7 +255,7 @@
                     for (Block b : loop.blocks) {
                         for (Block sux : b.getSuccessors()) {
                             if (sux.loop != loop) {
    -                            AbstractBeginNode begin = sux.getBeginNode();
    +                            BeginNode begin = sux.getBeginNode();
                                 if (!(begin instanceof LoopExitNode && ((LoopExitNode) begin).loopBegin() == loopBegin)) {
                                     Debug.log("Unexpected loop exit with %s, including whole branch in the loop", sux);
                                     unexpected.add(sux);
    @@ -269,10 +268,9 @@
                     }
                 }
             }
    -        loops = loopsList.toArray(new Loop[loopsList.size()]);
         }
     
    -    private static void addBranchToLoop(Loop l, Block b) {
    +    private static void addBranchToLoop(Loop l, Block b) {
             if (l.blocks.contains(b)) {
                 return;
             }
    @@ -283,7 +281,7 @@
             }
         }
     
    -    private static void computeLoopBlocks(Block block, Loop loop) {
    +    private static void computeLoopBlocks(Block block, Loop loop) {
             if (block.getLoop() == loop) {
                 return;
             }
    @@ -316,22 +314,22 @@
         }
     
         private static void setDominator(Block block, Block dominator) {
    -        block.dominator = dominator;
    +        block.setDominator(dominator);
             if (dominator.dominated == null) {
                 dominator.dominated = new ArrayList<>();
             }
             dominator.dominated.add(block);
         }
     
    -    public static Block commonDominator(Block a, Block b) {
    +    public static > T commonDominator(T a, T b) {
             if (a == null) {
                 return b;
             }
             if (b == null) {
                 return a;
             }
    -        Block iterA = a;
    -        Block iterB = b;
    +        T iterA = a;
    +        T iterB = b;
             while (iterA != iterB) {
                 if (iterA.getId() > iterB.getId()) {
                     iterA = iterA.getDominator();
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/HIRLoop.java
    --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/HIRLoop.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -0,0 +1,38 @@
    +/*
    + * Copyright (c) 2014, 2014, 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.cfg;
    +
    +import com.oracle.graal.compiler.common.cfg.*;
    +import com.oracle.graal.nodes.*;
    +
    +public class HIRLoop extends Loop {
    +
    +    protected HIRLoop(Loop parent, int index, Block header) {
    +        super(parent, index, header);
    +    }
    +
    +    @Override
    +    public long numBackedges() {
    +        return ((LoopBeginNode) header.getBeginNode()).loopEnds().count();
    +    }
    +}
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/Loop.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/Loop.java	Wed Apr 23 15:22:20 2014 +0200
    +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    @@ -1,63 +0,0 @@
    -/*
    - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
    - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    - *
    - * This code is free software; you can redistribute it and/or modify it
    - * under the terms of the GNU General Public License version 2 only, as
    - * published by the Free Software Foundation.
    - *
    - * This code is distributed in the hope that it will be useful, but WITHOUT
    - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    - * version 2 for more details (a copy is included in the LICENSE file that
    - * accompanied this code).
    - *
    - * You should have received a copy of the GNU General Public License version
    - * 2 along with this work; if not, write to the Free Software Foundation,
    - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    - *
    - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    - * or visit www.oracle.com if you need additional information or have any
    - * questions.
    - */
    -package com.oracle.graal.nodes.cfg;
    -
    -import java.util.*;
    -
    -import com.oracle.graal.nodes.*;
    -
    -public class Loop {
    -
    -    public final Loop parent;
    -    public final List children;
    -
    -    public final int depth;
    -    public final int index;
    -    public final Block header;
    -    public final List blocks;
    -    public final List exits;
    -
    -    protected Loop(Loop parent, int index, Block header) {
    -        this.parent = parent;
    -        if (parent != null) {
    -            this.depth = parent.depth + 1;
    -            parent.children.add(this);
    -        } else {
    -            this.depth = 1;
    -        }
    -        this.index = index;
    -        this.header = header;
    -        this.blocks = new ArrayList<>();
    -        this.children = new ArrayList<>();
    -        this.exits = new ArrayList<>();
    -    }
    -
    -    @Override
    -    public String toString() {
    -        return "loop " + index + " depth " + depth + (parent != null ? " outer " + parent.index : "");
    -    }
    -
    -    public LoopBeginNode loopBegin() {
    -        return (LoopBeginNode) header.getBeginNode();
    -    }
    -}
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/debug/DynamicCounterNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/debug/DynamicCounterNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/debug/DynamicCounterNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,9 +22,9 @@
      */
     package com.oracle.graal.nodes.debug;
     
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
     
     /**
      * This node can be used to add a counter to the code that will estimate the dynamic number of calls
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/AbstractWriteNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/AbstractWriteNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/AbstractWriteNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,9 +23,9 @@
     package com.oracle.graal.nodes.extended;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.nodes.*;
    -import com.oracle.graal.nodes.type.*;
     
     @NodeInfo(allowedUsageTypes = {InputType.Memory})
     public abstract class AbstractWriteNode extends FixedAccessNode implements StateSplit, MemoryCheckpoint.Single, MemoryAccess, GuardingNode {
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/AddLocationNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/AddLocationNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/AddLocationNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,12 +23,13 @@
     package com.oracle.graal.nodes.extended;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.graph.spi.*;
    +import com.oracle.graal.lir.gen.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.calc.*;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
     
     /**
      * Location node that is the sum of two other location nodes. Can represent locations in the form of
    @@ -107,9 +108,9 @@
         }
     
         @Override
    -    public Value generateAddress(NodeLIRBuilderTool gen, Value base) {
    -        Value xAddr = getX().generateAddress(gen, base);
    -        return getY().generateAddress(gen, xAddr);
    +    public Value generateAddress(NodeMappableLIRBuilder builder, LIRGeneratorTool gen, Value base) {
    +        Value xAddr = getX().generateAddress(builder, gen, base);
    +        return getY().generateAddress(builder, gen, xAddr);
         }
     
         @NodeIntrinsic
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ArrayRangeWriteNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ArrayRangeWriteNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ArrayRangeWriteNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,8 +22,8 @@
      */
     package com.oracle.graal.nodes.extended;
     
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.nodes.*;
    -import com.oracle.graal.nodes.type.*;
     
     /**
      * Base class for nodes that modify a range of an array.
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BoxNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BoxNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BoxNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -25,6 +25,7 @@
     import java.util.*;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.graph.spi.*;
     import com.oracle.graal.nodes.*;
    @@ -77,7 +78,7 @@
         @Override
         public void virtualize(VirtualizerTool tool) {
             ValueNode v = tool.getReplacedValue(getValue());
    -        ResolvedJavaType type = ObjectStamp.typeOrNull(stamp());
    +        ResolvedJavaType type = StampTool.typeOrNull(stamp());
     
             VirtualBoxingNode newVirtual = new VirtualBoxingNode(type, boxingKind);
             assert newVirtual.getFields().length == 1;
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BranchProbabilityNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BranchProbabilityNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BranchProbabilityNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,6 +22,8 @@
      */
     package com.oracle.graal.nodes.extended;
     
    +import com.oracle.graal.compiler.common.*;
    +import com.oracle.graal.compiler.common.calc.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.graph.spi.*;
     import com.oracle.graal.nodes.*;
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BytecodeExceptionNode.java
    --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BytecodeExceptionNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -0,0 +1,70 @@
    +/*
    + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
    + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    + *
    + * This code is free software; you can redistribute it and/or modify it
    + * under the terms of the GNU General Public License version 2 only, as
    + * published by the Free Software Foundation.
    + *
    + * This code is distributed in the hope that it will be useful, but WITHOUT
    + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    + * version 2 for more details (a copy is included in the LICENSE file that
    + * accompanied this code).
    + *
    + * You should have received a copy of the GNU General Public License version
    + * 2 along with this work; if not, write to the Free Software Foundation,
    + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    + *
    + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    + * or visit www.oracle.com if you need additional information or have any
    + * questions.
    + */
    +package com.oracle.graal.nodes.extended;
    +
    +import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
    +import com.oracle.graal.graph.*;
    +import com.oracle.graal.nodes.*;
    +import com.oracle.graal.nodes.spi.*;
    +
    +/**
    + * A node that represents an exception thrown implicitly by a Java bytecode. It can be lowered to
    + * either a {@linkplain ForeignCallDescriptor foreign} call or a pre-allocated exception object.
    + */
    +public class BytecodeExceptionNode extends AbstractMemoryCheckpoint implements Lowerable, MemoryCheckpoint.Single {
    +
    +    private final Class exceptionClass;
    +    @Input private final NodeInputList arguments;
    +    @Input private FrameState deoptState;
    +
    +    public BytecodeExceptionNode(MetaAccessProvider metaAccess, Class exceptionClass, ValueNode... arguments) {
    +        super(StampFactory.exactNonNull(metaAccess.lookupJavaType(exceptionClass)));
    +        this.exceptionClass = exceptionClass;
    +        this.arguments = new NodeInputList<>(this, arguments);
    +    }
    +
    +    public Class getExceptionClass() {
    +        return exceptionClass;
    +    }
    +
    +    @Override
    +    public String toString(Verbosity verbosity) {
    +        if (verbosity == Verbosity.Name) {
    +            return super.toString(verbosity) + "#" + exceptionClass.getSimpleName();
    +        }
    +        return super.toString(verbosity);
    +    }
    +
    +    public LocationIdentity getLocationIdentity() {
    +        return LocationIdentity.ANY_LOCATION;
    +    }
    +
    +    public void lower(LoweringTool tool) {
    +        tool.getLowerer().lower(this, tool);
    +    }
    +
    +    public NodeInputList getArguments() {
    +        return arguments;
    +    }
    +}
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ComputeAddressNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ComputeAddressNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ComputeAddressNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,11 +23,11 @@
     package com.oracle.graal.nodes.extended;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.calc.*;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
     
     public class ComputeAddressNode extends FloatingNode implements LIRLowerable {
     
    @@ -50,7 +50,7 @@
     
         @Override
         public void generate(NodeLIRBuilderTool gen) {
    -        Value addr = getLocation().generateAddress(gen, gen.operand(getObject()));
    +        Value addr = getLocation().generateAddress(gen, gen.getLIRGeneratorTool(), gen.operand(getObject()));
             gen.setResult(this, addr);
         }
     }
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ConstantLocationNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ConstantLocationNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ConstantLocationNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,9 +23,10 @@
     package com.oracle.graal.nodes.extended;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
    +import com.oracle.graal.lir.gen.*;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
     
     /**
      * Location node that has a constant displacement. Can represent addresses of the form [base + disp]
    @@ -65,7 +66,7 @@
         }
     
         @Override
    -    public Value generateAddress(NodeLIRBuilderTool gen, Value base) {
    -        return gen.getLIRGeneratorTool().emitAddress(base, getDisplacement(), Value.ILLEGAL, 0);
    +    public Value generateAddress(NodeMappableLIRBuilder builder, LIRGeneratorTool gen, Value base) {
    +        return gen.emitAddress(base, getDisplacement(), Value.ILLEGAL, 0);
         }
     }
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/DeferredForeignCallNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/DeferredForeignCallNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    @@ -1,71 +0,0 @@
    -/*
    - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
    - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    - *
    - * This code is free software; you can redistribute it and/or modify it
    - * under the terms of the GNU General Public License version 2 only, as
    - * published by the Free Software Foundation.
    - *
    - * This code is distributed in the hope that it will be useful, but WITHOUT
    - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    - * version 2 for more details (a copy is included in the LICENSE file that
    - * accompanied this code).
    - *
    - * You should have received a copy of the GNU General Public License version
    - * 2 along with this work; if not, write to the Free Software Foundation,
    - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    - *
    - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    - * or visit www.oracle.com if you need additional information or have any
    - * questions.
    - */
    -package com.oracle.graal.nodes.extended;
    -
    -import com.oracle.graal.api.meta.*;
    -import com.oracle.graal.graph.*;
    -import com.oracle.graal.nodes.*;
    -import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
    -
    -/**
    - * A node that will be lowered to a {@linkplain ForeignCallDescriptor foreign} call.
    - */
    -@NodeInfo(nameTemplate = "DeferredForeignCall#{p#descriptor/s}")
    -public class DeferredForeignCallNode extends AbstractMemoryCheckpoint implements Lowerable, MemoryCheckpoint.Single {
    -
    -    @Input private final NodeInputList arguments;
    -    @Input(InputType.State) private FrameState deoptState;
    -
    -    private final ForeignCallDescriptor descriptor;
    -
    -    public DeferredForeignCallNode(ForeignCallDescriptor descriptor, ValueNode... arguments) {
    -        super(StampFactory.forKind(Kind.fromJavaClass(descriptor.getResultType())));
    -        this.arguments = new NodeInputList<>(this, arguments);
    -        this.descriptor = descriptor;
    -    }
    -
    -    public ForeignCallDescriptor getDescriptor() {
    -        return descriptor;
    -    }
    -
    -    @Override
    -    public String toString(Verbosity verbosity) {
    -        if (verbosity == Verbosity.Name) {
    -            return super.toString(verbosity) + "#" + descriptor;
    -        }
    -        return super.toString(verbosity);
    -    }
    -
    -    public LocationIdentity getLocationIdentity() {
    -        return LocationIdentity.ANY_LOCATION;
    -    }
    -
    -    public void lower(LoweringTool tool) {
    -        tool.getLowerer().lower(this, tool);
    -    }
    -
    -    public NodeInputList getArguments() {
    -        return arguments;
    -    }
    -}
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FixedAccessNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FixedAccessNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FixedAccessNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,9 +22,9 @@
      */
     package com.oracle.graal.nodes.extended;
     
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.nodes.*;
    -import com.oracle.graal.nodes.type.*;
     
     /**
      * Accesses a value at an memory address specified by an {@linkplain #object object} and a
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FixedValueAnchorNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FixedValueAnchorNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FixedValueAnchorNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,9 +22,9 @@
      */
     package com.oracle.graal.nodes.extended;
     
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
     
     public final class FixedValueAnchorNode extends FixedWithNextNode implements LIRLowerable, ValueProxy {
     
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatableAccessNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatableAccessNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatableAccessNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,8 +23,8 @@
     package com.oracle.graal.nodes.extended;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.nodes.*;
    -import com.oracle.graal.nodes.type.*;
     
     /**
      * An {@link FixedAccessNode} that can be converted to a {@link FloatingAccessNode}.
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingAccessNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingAccessNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingAccessNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,9 +23,9 @@
     package com.oracle.graal.nodes.extended;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.nodes.*;
    -import com.oracle.graal.nodes.type.*;
     
     public abstract class FloatingAccessNode extends FloatingGuardedNode implements Access, MemoryAccess {
     
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingReadNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingReadNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingReadNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,11 +23,11 @@
     package com.oracle.graal.nodes.extended;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.graph.spi.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
     
     /**
      * A floating read of a value from memory specified in terms of an object base and an object
    @@ -61,9 +61,9 @@
     
         @Override
         public void generate(NodeLIRBuilderTool gen) {
    -        Value address = location().generateAddress(gen, gen.operand(object()));
    +        Value address = location().generateAddress(gen, gen.getLIRGeneratorTool(), gen.operand(object()));
             PlatformKind readKind = gen.getLIRGeneratorTool().getPlatformKind(stamp());
    -        gen.setResult(this, gen.getLIRGeneratorTool().emitLoad(readKind, address, this));
    +        gen.setResult(this, gen.getLIRGeneratorTool().emitLoad(readKind, address, null));
         }
     
         @Override
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ForeignCallNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ForeignCallNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ForeignCallNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -26,10 +26,10 @@
     
     import com.oracle.graal.api.code.*;
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
     
     /**
      * Node for a {@linkplain ForeignCallDescriptor foreign} call.
    @@ -94,7 +94,7 @@
         public void generate(NodeLIRBuilderTool gen) {
             ForeignCallLinkage linkage = gen.getLIRGeneratorTool().getForeignCalls().lookupForeignCall(descriptor);
             Value[] operands = operands(gen);
    -        Value result = gen.getLIRGeneratorTool().emitForeignCall(linkage, this, operands);
    +        Value result = gen.getLIRGeneratorTool().emitForeignCall(linkage, gen.state(this), operands);
             if (result != null) {
                 gen.setResult(this, result);
             }
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/IndexedLocationNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/IndexedLocationNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/IndexedLocationNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,11 +23,12 @@
     package com.oracle.graal.nodes.extended;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.graph.spi.*;
    +import com.oracle.graal.lir.gen.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
     
     /**
      * Location node that has a displacement and a scaled index. Can represent locations in the form of
    @@ -96,7 +97,7 @@
         }
     
         @Override
    -    public Value generateAddress(NodeLIRBuilderTool gen, Value base) {
    -        return gen.getLIRGeneratorTool().emitAddress(base, displacement, gen.operand(getIndex()), getIndexScaling());
    +    public Value generateAddress(NodeMappableLIRBuilder builder, LIRGeneratorTool gen, Value base) {
    +        return gen.emitAddress(base, displacement, builder.operand(getIndex()), getIndexScaling());
         }
     }
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/IntegerSwitchNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/IntegerSwitchNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/IntegerSwitchNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -25,10 +25,10 @@
     import java.util.*;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.spi.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
     import com.oracle.graal.nodes.util.*;
     
     /**
    @@ -49,7 +49,7 @@
          * @param keyProbabilities the probabilities of the keys
          * @param keySuccessors the successor index for each key
          */
    -    public IntegerSwitchNode(ValueNode value, AbstractBeginNode[] successors, int[] keys, double[] keyProbabilities, int[] keySuccessors) {
    +    public IntegerSwitchNode(ValueNode value, BeginNode[] successors, int[] keys, double[] keyProbabilities, int[] keySuccessors) {
             super(value, successors, keySuccessors, keyProbabilities);
             assert keySuccessors.length == keys.length + 1;
             assert keySuccessors.length == keyProbabilities.length;
    @@ -76,7 +76,7 @@
          * @param keySuccessors the successor index for each key
          */
         public IntegerSwitchNode(ValueNode value, int successorCount, int[] keys, double[] keyProbabilities, int[] keySuccessors) {
    -        this(value, new AbstractBeginNode[successorCount], keys, keyProbabilities, keySuccessors);
    +        this(value, new BeginNode[successorCount], keys, keyProbabilities, keySuccessors);
         }
     
         @Override
    @@ -139,7 +139,7 @@
                         tool.addToWorkList(defaultSuccessor());
                         graph().removeSplitPropagate(this, defaultSuccessor());
                     } else if (validKeys != keys.length) {
    -                    ArrayList newSuccessors = new ArrayList<>(blockSuccessorCount());
    +                    ArrayList newSuccessors = new ArrayList<>(blockSuccessorCount());
                         int[] newKeys = new int[validKeys];
                         int[] newKeySuccessors = new int[validKeys + 1];
                         double[] newKeyProbabilities = new double[validKeys + 1];
    @@ -172,14 +172,14 @@
                         }
     
                         for (int i = 0; i < blockSuccessorCount(); i++) {
    -                        AbstractBeginNode successor = blockSuccessor(i);
    +                        BeginNode successor = blockSuccessor(i);
                             if (!newSuccessors.contains(successor)) {
                                 tool.deleteBranch(successor);
                             }
                             setBlockSuccessor(i, null);
                         }
     
    -                    AbstractBeginNode[] successorsArray = newSuccessors.toArray(new AbstractBeginNode[newSuccessors.size()]);
    +                    BeginNode[] successorsArray = newSuccessors.toArray(new BeginNode[newSuccessors.size()]);
                         IntegerSwitchNode newSwitch = graph().add(new IntegerSwitchNode(value(), successorsArray, newKeys, newKeyProbabilities, newKeySuccessors));
                         ((FixedWithNextNode) predecessor()).setNext(newSwitch);
                         GraphUtil.killWithUnusedFloatingInputs(this);
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/JavaReadNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/JavaReadNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/JavaReadNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,9 +22,9 @@
      */
     package com.oracle.graal.nodes.extended;
     
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
     
     /**
      * Read a raw memory location according to Java field or array read semantics. It will perform read
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadHubNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadHubNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadHubNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -24,11 +24,11 @@
     
     import com.oracle.graal.api.meta.*;
     import com.oracle.graal.api.meta.ResolvedJavaType.Representation;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.graph.spi.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
     
     /**
      * Loads an object's {@linkplain Representation#ObjectHub hub}. The object is not null-checked by
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadMethodNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadMethodNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadMethodNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,12 +22,10 @@
      */
     package com.oracle.graal.nodes.extended;
     
    -import java.lang.reflect.*;
    -
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
     
     /**
      * Loads a method from the virtual method table of a given hub.
    @@ -45,8 +43,8 @@
             super(kind == Kind.Object ? StampFactory.objectNonNull() : StampFactory.forKind(kind));
             this.hub = hub;
             this.method = method;
    -        assert !Modifier.isAbstract(method.getModifiers()) : "Cannot load abstract method from a hub";
    -        assert !Modifier.isStatic(method.getModifiers()) : "Cannot load a static method from a hub";
    +        assert !method.isAbstract() : "Cannot load abstract method from a hub";
    +        assert !method.isStatic() : "Cannot load a static method from a hub";
             assert method.isInVirtualMethodTable();
         }
     
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LocationNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LocationNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LocationNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,11 +23,12 @@
     package com.oracle.graal.nodes.extended;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.graph.Node.ValueNumberable;
    +import com.oracle.graal.lir.gen.*;
     import com.oracle.graal.nodes.calc.*;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
     
     /**
      * A location for a memory access in terms of the kind of value accessed and how to access it. All
    @@ -62,5 +63,5 @@
             // nothing to do...
         }
     
    -    public abstract Value generateAddress(NodeLIRBuilderTool gen, Value base);
    +    public abstract Value generateAddress(NodeMappableLIRBuilder builder, LIRGeneratorTool gen, Value base);
     }
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/MembarNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/MembarNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/MembarNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,7 +22,7 @@
      */
     package com.oracle.graal.nodes.extended;
     
    -import static com.oracle.graal.graph.UnsafeAccess.*;
    +import static com.oracle.graal.compiler.common.UnsafeAccess.*;
     
     import java.lang.reflect.*;
     
    @@ -30,10 +30,11 @@
     
     import com.oracle.graal.api.code.*;
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
     
     /**
      * Creates a memory barrier.
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/NullCheckNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/NullCheckNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/NullCheckNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,9 +22,9 @@
      */
     package com.oracle.graal.nodes.extended;
     
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
     
     public class NullCheckNode extends DeoptimizingFixedWithNextNode implements LIRLowerable {
     
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/OSRLocalNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/OSRLocalNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/OSRLocalNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,9 +22,9 @@
      */
     package com.oracle.graal.nodes.extended;
     
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.nodes.*;
    -import com.oracle.graal.nodes.type.*;
     
     @NodeInfo(nameTemplate = "OSRLocal({p#index})")
     public class OSRLocalNode extends AbstractLocalNode implements IterableNodeType {
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,6 +23,7 @@
     package com.oracle.graal.nodes.extended;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.graph.spi.*;
     import com.oracle.graal.nodes.*;
    @@ -54,15 +55,18 @@
     
         @Override
         public void generate(NodeLIRBuilderTool gen) {
    -        Value address = location().generateAddress(gen, gen.operand(object()));
    +        Value address = location().generateAddress(gen, gen.getLIRGeneratorTool(), gen.operand(object()));
             PlatformKind readKind = gen.getLIRGeneratorTool().getPlatformKind(stamp());
    -        gen.setResult(this, gen.getLIRGeneratorTool().emitLoad(readKind, address, this));
    +        gen.setResult(this, gen.getLIRGeneratorTool().emitLoad(readKind, address, gen.state(this)));
         }
     
         @Override
         public Node canonical(CanonicalizerTool tool) {
             if (object() instanceof PiNode && ((PiNode) object()).getGuard() == getGuard()) {
    -            return graph().add(new ReadNode(((PiNode) object()).getOriginalNode(), location(), stamp(), getGuard(), getBarrierType(), isCompressible()));
    +            ReadNode readNode = graph().add(new ReadNode(((PiNode) object()).getOriginalNode(), location(), stamp(), getGuard(), getBarrierType(), isCompressible()));
    +            readNode.setNullCheck(getNullCheck());
    +            readNode.setStateBefore(stateBefore());
    +            return readNode;
             }
             return canonicalizeRead(this, location(), object(), tool, isCompressible());
         }
    @@ -90,26 +94,22 @@
                 }
             }
             if (tool.canonicalizeReads()) {
    -            if (metaAccess != null && object != null && object.isConstant()) {
    +            if (metaAccess != null && object != null && object.isConstant() && !compressible) {
                     if ((location.getLocationIdentity() == LocationIdentity.FINAL_LOCATION || location.getLocationIdentity() == LocationIdentity.ARRAY_LENGTH_LOCATION) &&
                                     location instanceof ConstantLocationNode) {
                         long displacement = ((ConstantLocationNode) location).getDisplacement();
    -                    Kind kind = location.getValueKind();
    -                    if (object.getKind() == Kind.Object) {
    -                        Object base = object.asConstant().asObject();
    -                        if (base != null) {
    -                            Constant constant = tool.getConstantReflection().readUnsafeConstant(kind, base, displacement, compressible);
    -                            if (constant != null) {
    -                                return ConstantNode.forConstant(constant, metaAccess, read.graph());
    -                            }
    +                    Constant base = object.asConstant();
    +                    if (base != null) {
    +                        Constant constant;
    +                        if (read.stamp() instanceof PrimitiveStamp) {
    +                            PrimitiveStamp stamp = (PrimitiveStamp) read.stamp();
    +                            constant = tool.getConstantReflection().readRawConstant(stamp.getStackKind(), base, displacement, stamp.getBits());
    +                        } else {
    +                            assert read.stamp() instanceof ObjectStamp;
    +                            constant = tool.getConstantReflection().readUnsafeConstant(Kind.Object, base, displacement);
                             }
    -                    } else if (object.getKind().isNumericInteger()) {
    -                        long base = object.asConstant().asLong();
    -                        if (base != 0L) {
    -                            Constant constant = tool.getConstantReflection().readUnsafeConstant(kind, null, base + displacement, compressible);
    -                            if (constant != null) {
    -                                return ConstantNode.forConstant(constant, metaAccess, read.graph());
    -                            }
    +                        if (constant != null) {
    +                            return ConstantNode.forConstant(read.stamp(), constant, metaAccess, read.graph());
                             }
                         }
                     }
    @@ -144,7 +144,7 @@
             }
     
             ObjectStamp valueStamp = (ObjectStamp) parent.object().stamp();
    -        ResolvedJavaType valueType = ObjectStamp.typeOrNull(valueStamp);
    +        ResolvedJavaType valueType = StampTool.typeOrNull(valueStamp);
             if (valueType != null && field.getDeclaringClass().isAssignableFrom(valueType)) {
                 if (piStamp.nonNull() == valueStamp.nonNull() && piStamp.alwaysNull() == valueStamp.alwaysNull()) {
                     replaceFirstInput(parent, parent.object());
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/SnippetLocationNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/SnippetLocationNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    @@ -1,112 +0,0 @@
    -/*
    - * Copyright (c) 2013, 2013, Oracle and/or its affiliates. All rights reserved.
    - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    - *
    - * This code is free software; you can redistribute it and/or modify it
    - * under the terms of the GNU General Public License version 2 only, as
    - * published by the Free Software Foundation.
    - *
    - * This code is distributed in the hope that it will be useful, but WITHOUT
    - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    - * version 2 for more details (a copy is included in the LICENSE file that
    - * accompanied this code).
    - *
    - * You should have received a copy of the GNU General Public License version
    - * 2 along with this work; if not, write to the Free Software Foundation,
    - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    - *
    - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    - * or visit www.oracle.com if you need additional information or have any
    - * questions.
    - */
    -package com.oracle.graal.nodes.extended;
    -
    -import static com.oracle.graal.api.meta.LocationIdentity.*;
    -
    -import com.oracle.graal.api.meta.*;
    -import com.oracle.graal.graph.*;
    -import com.oracle.graal.graph.spi.*;
    -import com.oracle.graal.nodes.*;
    -import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
    -
    -/**
    - * Location node that can be used inside a snippet without having the elements (including the
    - * location identity and kind) as a snippet constant. Can represent locations in the form of [base +
    - * index * scale + disp]. When the location is created, all elements (base, index, scale, disp) are
    - * nodes. Both scale and disp must eventually canonicalize to {@link ConstantNode constants} so that
    - * this node can be canonicalized to a {@link IndexedLocationNode} or {@link ConstantLocationNode}.
    - */
    -public final class SnippetLocationNode extends LocationNode implements Canonicalizable {
    -
    -    @Input private ValueNode valueKind;
    -    @Input(InputType.Association) private ValueNode locationIdentity;
    -    @Input private ValueNode displacement;
    -    @Input private ValueNode index;
    -    @Input private ValueNode indexScaling;
    -
    -    public static SnippetLocationNode create(ValueNode identity, ValueNode kind, ValueNode displacement, ValueNode index, ValueNode indexScaling, Graph graph) {
    -        return graph.unique(new SnippetLocationNode(identity, kind, displacement, index, indexScaling));
    -    }
    -
    -    private SnippetLocationNode(ValueNode locationIdentity, ValueNode kind, ValueNode displacement) {
    -        this(locationIdentity, kind, displacement, null, null);
    -    }
    -
    -    private SnippetLocationNode(ValueNode locationIdentity, ValueNode kind, ValueNode displacement, ValueNode index, ValueNode indexScaling) {
    -        super(StampFactory.object());
    -        this.valueKind = kind;
    -        this.locationIdentity = locationIdentity;
    -        this.displacement = displacement;
    -        this.index = index;
    -        this.indexScaling = indexScaling;
    -    }
    -
    -    @Override
    -    public Kind getValueKind() {
    -        if (valueKind.isConstant()) {
    -            return (Kind) valueKind.asConstant().asObject();
    -        }
    -        throw new GraalInternalError("Cannot access kind yet because it is not constant: " + valueKind);
    -    }
    -
    -    @Override
    -    public LocationIdentity getLocationIdentity() {
    -        if (locationIdentity.isConstant()) {
    -            return (LocationIdentity) locationIdentity.asConstant().asObject();
    -        }
    -        // We do not know our actual location identity yet, so be conservative.
    -        return ANY_LOCATION;
    -    }
    -
    -    @Override
    -    public Node canonical(CanonicalizerTool tool) {
    -        if (valueKind.isConstant() && locationIdentity.isConstant() && displacement.isConstant() && (indexScaling == null || indexScaling.isConstant())) {
    -            Kind constKind = (Kind) valueKind.asConstant().asObject();
    -            LocationIdentity constLocation = (LocationIdentity) locationIdentity.asConstant().asObject();
    -            long constDisplacement = displacement.asConstant().asLong();
    -            int constIndexScaling = indexScaling == null ? 0 : indexScaling.asConstant().asInt();
    -
    -            if (index == null || constIndexScaling == 0) {
    -                return ConstantLocationNode.create(constLocation, constKind, constDisplacement, graph());
    -            } else if (index.isConstant()) {
    -                return ConstantLocationNode.create(constLocation, constKind, index.asConstant().asLong() * constIndexScaling + constDisplacement, graph());
    -            } else {
    -                return IndexedLocationNode.create(constLocation, constKind, constDisplacement, index, graph(), constIndexScaling);
    -            }
    -        }
    -        return this;
    -    }
    -
    -    @Override
    -    public Value generateAddress(NodeLIRBuilderTool gen, Value base) {
    -        throw new GraalInternalError("locationIdentity must be a constant so that this node can be canonicalized: " + locationIdentity);
    -    }
    -
    -    @NodeIntrinsic
    -    public static native Location constantLocation(LocationIdentity identity, Kind kind, long displacement);
    -
    -    @NodeIntrinsic
    -    public static native Location indexedLocation(LocationIdentity identity, Kind kind, long displacement, int index, int indexScaling);
    -}
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/StoreHubNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/StoreHubNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/StoreHubNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,9 +22,9 @@
      */
     package com.oracle.graal.nodes.extended;
     
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
     
     public final class StoreHubNode extends FixedWithNextNode implements Lowerable {
     
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/SwitchNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/SwitchNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/SwitchNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -25,16 +25,17 @@
     import java.util.*;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.nodes.*;
    -import com.oracle.graal.nodes.type.*;
     
     /**
      * The {@code SwitchNode} class is the base of both lookup and table switches.
      */
     public abstract class SwitchNode extends ControlSplitNode {
     
    -    @Successor private final NodeSuccessorList successors;
    +    @Successor private final NodeSuccessorList successors;
         @Input private ValueNode value;
         private double[] keyProbabilities;
         private int[] keySuccessors;
    @@ -45,7 +46,7 @@
          * @param value the instruction that provides the value to be switched over
          * @param successors the list of successors of this switch
          */
    -    public SwitchNode(ValueNode value, AbstractBeginNode[] successors, int[] keySuccessors, double[] keyProbabilities) {
    +    public SwitchNode(ValueNode value, BeginNode[] successors, int[] keySuccessors, double[] keyProbabilities) {
             super(StampFactory.forVoid());
             assert value.getKind() == Kind.Int || value.getKind() == Kind.Long || value.getKind() == Kind.Object : value.getKind() + " key not supported by SwitchNode";
             assert keySuccessors.length == keyProbabilities.length;
    @@ -76,7 +77,7 @@
         }
     
         @Override
    -    public double probability(AbstractBeginNode successor) {
    +    public double probability(BeginNode successor) {
             double sum = 0;
             for (int i = 0; i < keySuccessors.length; i++) {
                 if (successors.get(keySuccessors[i]) == successor) {
    @@ -87,7 +88,7 @@
         }
     
         @Override
    -    public void setProbability(AbstractBeginNode successor, double value) {
    +    public void setProbability(BeginNode successor, double value) {
             double changeInProbability = 0;
             int nonZeroProbabilityCases = 0;
             for (int i = 0; i < keySuccessors.length; i++) {
    @@ -139,7 +140,7 @@
         /**
          * Returns the successor for the key at the given index.
          */
    -    public AbstractBeginNode keySuccessor(int i) {
    +    public BeginNode keySuccessor(int i) {
             return successors.get(keySuccessors[i]);
         }
     
    @@ -157,11 +158,11 @@
             return keySuccessors[keySuccessors.length - 1];
         }
     
    -    public AbstractBeginNode blockSuccessor(int i) {
    +    public BeginNode blockSuccessor(int i) {
             return successors.get(i);
         }
     
    -    public void setBlockSuccessor(int i, AbstractBeginNode s) {
    +    public void setBlockSuccessor(int i, BeginNode s) {
             successors.set(i, s);
         }
     
    @@ -174,7 +175,7 @@
          * 
          * @return the default successor
          */
    -    public AbstractBeginNode defaultSuccessor() {
    +    public BeginNode defaultSuccessor() {
             if (defaultSuccessorIndex() == -1) {
                 throw new GraalInternalError("unexpected");
             }
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnboxNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnboxNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnboxNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,12 +23,12 @@
     package com.oracle.graal.nodes.extended;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.graph.spi.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.calc.*;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
     
     public class UnboxNode extends FloatingNode implements Virtualizable, Lowerable, Canonicalizable {
     
    @@ -70,28 +70,9 @@
         public Node canonical(CanonicalizerTool tool) {
             if (value.isConstant()) {
                 Constant constant = value.asConstant();
    -            Object o = constant.asObject();
    -            if (o != null) {
    -                switch (boxingKind) {
    -                    case Boolean:
    -                        return ConstantNode.forBoolean((Boolean) o, graph());
    -                    case Byte:
    -                        return ConstantNode.forByte((Byte) o, graph());
    -                    case Char:
    -                        return ConstantNode.forChar((Character) o, graph());
    -                    case Short:
    -                        return ConstantNode.forShort((Short) o, graph());
    -                    case Int:
    -                        return ConstantNode.forInt((Integer) o, graph());
    -                    case Long:
    -                        return ConstantNode.forLong((Long) o, graph());
    -                    case Float:
    -                        return ConstantNode.forFloat((Float) o, graph());
    -                    case Double:
    -                        return ConstantNode.forDouble((Double) o, graph());
    -                    default:
    -                        ValueNodeUtil.shouldNotReachHere();
    -                }
    +            Constant unboxed = tool.getConstantReflection().unboxPrimitive(constant);
    +            if (unboxed != null && unboxed.getKind() == boxingKind) {
    +                return ConstantNode.forConstant(unboxed, tool.getMetaAccess(), graph());
                 }
             } else if (value instanceof BoxNode) {
                 BoxNode box = (BoxNode) value;
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeAccessNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeAccessNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeAccessNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,6 +23,7 @@
     package com.oracle.graal.nodes.extended;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.graph.spi.*;
     import com.oracle.graal.nodes.*;
    @@ -66,7 +67,7 @@
                 long constantOffset = offset().asConstant().asLong();
     
                 // Try to canonicalize to a field access.
    -            ResolvedJavaType receiverType = ObjectStamp.typeOrNull(object());
    +            ResolvedJavaType receiverType = StampTool.typeOrNull(object());
                 if (receiverType != null) {
                     ResolvedJavaField field = receiverType.findInstanceFieldWithOffset(constantOffset);
                     // No need for checking that the receiver is non-null. The field access includes
    @@ -78,8 +79,20 @@
                     }
                 }
             }
    +        if (this.getLocationIdentity() == LocationIdentity.ANY_LOCATION) {
    +            ResolvedJavaType receiverType = StampTool.typeOrNull(object());
    +            // Try to build a better location identity.
    +            if (receiverType != null && receiverType.isArray()) {
    +                LocationIdentity identity = NamedLocationIdentity.getArrayLocation(receiverType.getComponentType().getKind());
    +                assert !graph().isAfterFloatingReadPhase() : "cannot add more precise memory location after floating read phase";
    +                return cloneAsArrayAccess(offset(), identity);
    +            }
    +        }
    +
             return this;
         }
     
         protected abstract ValueNode cloneAsFieldAccess(ResolvedJavaField field);
    +
    +    protected abstract ValueNode cloneAsArrayAccess(ValueNode location, LocationIdentity identity);
     }
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeCastNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeCastNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeCastNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,6 +23,7 @@
     package com.oracle.graal.nodes.extended;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.graph.spi.*;
     import com.oracle.graal.nodes.*;
    @@ -50,7 +51,7 @@
         }
     
         public UnsafeCastNode(ValueNode object, ResolvedJavaType toType, boolean exactType, boolean nonNull) {
    -        this(object, toType.getKind() == Kind.Object ? StampFactory.object(toType, exactType, nonNull || ObjectStamp.isObjectNonNull(object.stamp())) : StampFactory.forKind(toType.getKind()));
    +        this(object, toType.getKind() == Kind.Object ? StampFactory.object(toType, exactType, nonNull || StampTool.isObjectNonNull(object.stamp())) : StampFactory.forKind(toType.getKind()));
         }
     
         @Override
    @@ -59,36 +60,27 @@
         }
     
         @Override
    +    public boolean inferStamp() {
    +        if (stamp() instanceof ObjectStamp && object.stamp() instanceof ObjectStamp) {
    +            return updateStamp(((ObjectStamp) object.stamp()).castTo((ObjectStamp) stamp()));
    +        }
    +        return updateStamp(object.stamp().join(stamp()));
    +    }
    +
    +    @Override
         public Node canonical(CanonicalizerTool tool) {
             assert getKind() == Kind.Object && object.getKind() == Kind.Object;
    -
    -        ObjectStamp my = (ObjectStamp) stamp();
    -        ObjectStamp other = (ObjectStamp) object.stamp();
    -
    -        if (my.type() == null || other.type() == null) {
    -            return this;
    -        }
    -        if (my.isExactType() && !other.isExactType()) {
    +        if (stamp().equals(object.stamp())) {
    +            return object;
    +        } else {
                 return this;
             }
    -        if (my.nonNull() && !other.nonNull()) {
    -            return this;
    -        }
    -        if (!my.type().isAssignableFrom(other.type())) {
    -            return this;
    -        }
    -        /*
    -         * The unsafe cast does not add any new type information, so it can be removed. Note that
    -         * this means that the unsafe cast cannot be used to "drop" type information (in which case
    -         * it must not be canonicalized in any case).
    -         */
    -        return object;
         }
     
         @Override
         public void virtualize(VirtualizerTool tool) {
             State state = tool.getObjectState(object);
    -        if (state != null && state.getState() == EscapeState.Virtual && ObjectStamp.typeOrNull(this) != null && ObjectStamp.typeOrNull(this).isAssignableFrom(state.getVirtualObject().type())) {
    +        if (state != null && state.getState() == EscapeState.Virtual && StampTool.typeOrNull(this) != null && StampTool.typeOrNull(this).isAssignableFrom(state.getVirtualObject().type())) {
                 tool.replaceWithVirtual(state.getVirtualObject());
             }
         }
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeLoadNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeLoadNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeLoadNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,14 +22,14 @@
      */
     package com.oracle.graal.nodes.extended;
     
    -import static com.oracle.graal.graph.UnsafeAccess.*;
    +import static com.oracle.graal.compiler.common.UnsafeAccess.*;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.java.*;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
     
     /**
      * Load of a value from a location specified as an offset relative to an object. No null check is
    @@ -79,6 +79,11 @@
             return this.graph().add(new LoadFieldNode(object(), field));
         }
     
    +    @Override
    +    protected ValueNode cloneAsArrayAccess(ValueNode location, LocationIdentity identity) {
    +        return this.graph().add(new UnsafeLoadNode(object(), location, accessKind(), identity));
    +    }
    +
         @SuppressWarnings({"unchecked", "unused"})
         @NodeIntrinsic
         public static  T load(Object object, long offset, @ConstantNodeParameter Kind kind, @ConstantNodeParameter LocationIdentity locationIdentity) {
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeStoreNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeStoreNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeStoreNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,14 +22,14 @@
      */
     package com.oracle.graal.nodes.extended;
     
    -import static com.oracle.graal.graph.UnsafeAccess.*;
    +import static com.oracle.graal.compiler.common.UnsafeAccess.*;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.java.*;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
     
     /**
      * Store of a value at a location specified as an offset relative to an object. No null check is
    @@ -108,6 +108,11 @@
             return storeFieldNode;
         }
     
    +    @Override
    +    protected ValueNode cloneAsArrayAccess(ValueNode location, LocationIdentity identity) {
    +        return this.graph().add(new UnsafeStoreNode(object(), location, value, accessKind(), identity));
    +    }
    +
         public FrameState getState() {
             return stateAfter;
         }
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ValueAnchorNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ValueAnchorNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ValueAnchorNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
      * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
      *
      * This code is free software; you can redistribute it and/or modify it
    @@ -22,19 +22,19 @@
      */
     package com.oracle.graal.nodes.extended;
     
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.graph.spi.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.calc.*;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
     import com.oracle.graal.nodes.util.*;
     
     /**
      * The ValueAnchor instruction keeps non-CFG (floating) nodes above a certain point in the graph.
      */
    -@NodeInfo(allowedUsageTypes = {InputType.Anchor})
    -public final class ValueAnchorNode extends FixedWithNextNode implements LIRLowerable, Simplifiable, Virtualizable, AnchoringNode {
    +@NodeInfo(allowedUsageTypes = {InputType.Anchor, InputType.Guard})
    +public final class ValueAnchorNode extends FixedWithNextNode implements LIRLowerable, Simplifiable, Virtualizable, AnchoringNode, GuardingNode {
     
         @Input(InputType.Guard) private ValueNode anchored;
     
    @@ -91,7 +91,7 @@
     
         @Override
         public void virtualize(VirtualizerTool tool) {
    -        if (anchored != null && !(anchored instanceof AbstractBeginNode)) {
    +        if (anchored != null && !(anchored instanceof BeginNode)) {
                 State state = tool.getObjectState(anchored);
                 if (state == null || state.getState() != EscapeState.Virtual) {
                     return;
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -44,7 +44,7 @@
     
         @Override
         public void generate(NodeLIRBuilderTool gen) {
    -        Value address = location().generateAddress(gen, gen.operand(object()));
    +        Value address = location().generateAddress(gen, gen.getLIRGeneratorTool(), gen.operand(object()));
             // It's possible a constant was forced for other usages so inspect the value directly and
             // use a constant if it can be directly stored.
             Value v;
    @@ -54,7 +54,7 @@
                 v = gen.operand(value());
             }
             PlatformKind writeKind = gen.getLIRGeneratorTool().getPlatformKind(value().stamp());
    -        gen.getLIRGeneratorTool().emitStore(writeKind, address, v, this);
    +        gen.getLIRGeneratorTool().emitStore(writeKind, address, v, gen.state(this));
         }
     
         @Override
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AbstractNewArrayNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AbstractNewArrayNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AbstractNewArrayNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,10 +22,10 @@
      */
     package com.oracle.graal.nodes.java;
     
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.spi.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
     
     /**
      * The {@code AbstractNewArrayNode} is used for all 1-dimensional array allocations.
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AbstractNewObjectNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AbstractNewObjectNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AbstractNewObjectNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -24,12 +24,12 @@
     
     import java.util.*;
     
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.graph.spi.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.extended.*;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
     
     /**
      * The {@code AbstractNewObjectNode} is the base class for the new instance and new array nodes.
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessArrayNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessArrayNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessArrayNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,8 +22,8 @@
      */
     package com.oracle.graal.nodes.java;
     
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.nodes.*;
    -import com.oracle.graal.nodes.type.*;
     
     /**
      * This the base class of all array operations.
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessFieldNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessFieldNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessFieldNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,12 +22,10 @@
      */
     package com.oracle.graal.nodes.java;
     
    -import java.lang.reflect.*;
    -
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
     
     /**
      * The base class of all instructions that access fields.
    @@ -70,7 +68,7 @@
          * @return {@code true} if this field access is to a static field
          */
         public boolean isStatic() {
    -        return Modifier.isStatic(field.getModifiers());
    +        return field.isStatic();
         }
     
         /**
    @@ -79,7 +77,7 @@
          * @return {@code true} if the field is resolved and declared volatile
          */
         public boolean isVolatile() {
    -        return Modifier.isVolatile(field.getModifiers());
    +        return field.isVolatile();
         }
     
         @Override
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessIndexedNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessIndexedNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessIndexedNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,9 +23,9 @@
     package com.oracle.graal.nodes.java;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
     
     /**
      * The {@code AccessIndexedNode} class is the base class of instructions that read or write elements
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessMonitorNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessMonitorNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessMonitorNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,10 +23,10 @@
     package com.oracle.graal.nodes.java;
     
     import com.oracle.graal.api.code.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.extended.*;
    -import com.oracle.graal.nodes.type.*;
     
     /**
      * The {@code AccessMonitorNode} is the base class of both monitor acquisition and release.
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ArrayLengthNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ArrayLengthNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ArrayLengthNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,11 +23,12 @@
     package com.oracle.graal.nodes.java;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.graph.spi.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
    +import com.oracle.graal.nodes.util.*;
     
     /**
      * The {@code ArrayLength} instruction gets the length of an array.
    @@ -57,22 +58,34 @@
         /**
          * Gets the length of an array if possible.
          *
    -     * @param graph TODO
    -     * @param array an array
    -     *
          * @return a node representing the length of {@code array} or null if it is not available
          */
    -    public static ValueNode readArrayLength(StructuredGraph graph, ValueNode array, ConstantReflectionProvider constantReflection) {
    -        if (array instanceof ArrayLengthProvider) {
    -            ValueNode length = ((ArrayLengthProvider) array).length();
    +    public static ValueNode readArrayLength(StructuredGraph graph, ValueNode originalArray, ConstantReflectionProvider constantReflection) {
    +        ArrayLengthProvider foundArrayLengthProvider = null;
    +        ValueNode result = originalArray;
    +        while (true) {
    +            if (result instanceof ArrayLengthProvider) {
    +                foundArrayLengthProvider = (ArrayLengthProvider) result;
    +                break;
    +            }
    +            if (result instanceof ValueProxy) {
    +                result = ((ValueProxy) result).getOriginalNode();
    +            } else {
    +                break;
    +            }
    +        }
    +
    +        if (foundArrayLengthProvider != null) {
    +            ValueNode length = foundArrayLengthProvider.length();
                 if (length != null) {
                     return length;
                 }
             }
    +        ValueNode array = GraphUtil.unproxify(originalArray);
             if (constantReflection != null && array.isConstant() && !array.isNullConstant()) {
                 Constant constantValue = array.asConstant();
                 if (constantValue != null && constantValue.isNonNull()) {
    -                Integer constantLength = constantReflection.lookupArrayLength(constantValue);
    +                Integer constantLength = constantReflection.readArrayLength(constantValue);
                     if (constantLength != null) {
                         return ConstantNode.forInt(constantLength, graph);
                     }
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AtomicReadAndAddNode.java
    --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AtomicReadAndAddNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -0,0 +1,88 @@
    +/*
    + * Copyright (c) 2014, 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 static com.oracle.graal.compiler.common.UnsafeAccess.*;
    +
    +import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
    +import com.oracle.graal.graph.*;
    +import com.oracle.graal.nodes.*;
    +import com.oracle.graal.nodes.extended.*;
    +import com.oracle.graal.nodes.spi.*;
    +
    +import sun.misc.*;
    +
    +/**
    + * Represents an atomic read-and-add operation like {@link Unsafe#getAndAddInt(Object, long, int)}.
    + */
    +@NodeInfo(allowedUsageTypes = {InputType.Memory})
    +public class AtomicReadAndAddNode extends AbstractMemoryCheckpoint implements LIRLowerable, MemoryCheckpoint.Single {
    +
    +    @Input private ValueNode object;
    +    @Input private ValueNode offset;
    +    @Input private ValueNode delta;
    +
    +    private final LocationIdentity locationIdentity;
    +
    +    public AtomicReadAndAddNode(ValueNode object, ValueNode offset, ValueNode delta, LocationIdentity locationIdentity) {
    +        super(StampFactory.forKind(delta.getKind()));
    +        this.object = object;
    +        this.offset = offset;
    +        this.delta = delta;
    +        this.locationIdentity = locationIdentity;
    +    }
    +
    +    public ValueNode object() {
    +        return object;
    +    }
    +
    +    public ValueNode offset() {
    +        return offset;
    +    }
    +
    +    public ValueNode delta() {
    +        return delta;
    +    }
    +
    +    public LocationIdentity getLocationIdentity() {
    +        return locationIdentity;
    +    }
    +
    +    public void generate(NodeLIRBuilderTool gen) {
    +        LocationNode location = IndexedLocationNode.create(getLocationIdentity(), delta.getKind(), 0, offset, graph(), 1);
    +        Value address = location.generateAddress(gen, gen.getLIRGeneratorTool(), gen.operand(object()));
    +        Value result = gen.getLIRGeneratorTool().emitAtomicReadAndAdd(address, gen.operand(delta));
    +        gen.setResult(this, result);
    +    }
    +
    +    @NodeIntrinsic
    +    public static int getAndAddInt(Object object, long offset, int delta, @ConstantNodeParameter @SuppressWarnings("unused") LocationIdentity locationIdentity) {
    +        return unsafe.getAndAddInt(object, offset, delta);
    +    }
    +
    +    @NodeIntrinsic
    +    public static long getAndAddLong(Object object, long offset, long delta, @ConstantNodeParameter @SuppressWarnings("unused") LocationIdentity locationIdentity) {
    +        return unsafe.getAndAddLong(object, offset, delta);
    +    }
    +}
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AtomicReadAndWriteNode.java
    --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AtomicReadAndWriteNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -0,0 +1,99 @@
    +/*
    + * Copyright (c) 2014, 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 static com.oracle.graal.compiler.common.UnsafeAccess.*;
    +
    +import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
    +import com.oracle.graal.nodes.*;
    +import com.oracle.graal.nodes.extended.*;
    +import com.oracle.graal.nodes.spi.*;
    +
    +import sun.misc.*;
    +
    +/**
    + * Represents an atomic read-and-write operation like {@link Unsafe#getAndSetInt(Object, long, int)}
    + * .
    + */
    +public class AtomicReadAndWriteNode extends AbstractMemoryCheckpoint implements Lowerable, MemoryCheckpoint.Single {
    +
    +    @Input private ValueNode object;
    +    @Input private ValueNode offset;
    +    @Input private ValueNode newValue;
    +
    +    private final Kind valueKind;
    +    private final LocationIdentity locationIdentity;
    +
    +    public AtomicReadAndWriteNode(ValueNode object, ValueNode offset, ValueNode newValue, Kind valueKind, LocationIdentity locationIdentity) {
    +        super(StampFactory.forKind(newValue.getKind()));
    +        this.object = object;
    +        this.offset = offset;
    +        this.newValue = newValue;
    +        this.valueKind = valueKind;
    +        this.locationIdentity = locationIdentity;
    +    }
    +
    +    public ValueNode object() {
    +        return object;
    +    }
    +
    +    public ValueNode offset() {
    +        return offset;
    +    }
    +
    +    public ValueNode newValue() {
    +        return newValue;
    +    }
    +
    +    public Kind getValueKind() {
    +        return valueKind;
    +    }
    +
    +    public LocationIdentity getLocationIdentity() {
    +        return locationIdentity;
    +    }
    +
    +    public void lower(LoweringTool tool) {
    +        tool.getLowerer().lower(this, tool);
    +    }
    +
    +    @NodeIntrinsic
    +    public static int getAndSetInt(Object object, long offset, int newValue, @SuppressWarnings("unused") @ConstantNodeParameter Kind valueKind,
    +                    @ConstantNodeParameter @SuppressWarnings("unused") LocationIdentity locationIdentity) {
    +        return unsafe.getAndSetInt(object, offset, newValue);
    +    }
    +
    +    @NodeIntrinsic
    +    public static long getAndSetLong(Object object, long offset, long newValue, @SuppressWarnings("unused") @ConstantNodeParameter Kind valueKind,
    +                    @ConstantNodeParameter @SuppressWarnings("unused") LocationIdentity locationIdentity) {
    +        return unsafe.getAndSetLong(object, offset, newValue);
    +    }
    +
    +    @NodeIntrinsic
    +    public static Object getAndSetObject(Object object, long offset, Object newValue, @SuppressWarnings("unused") @ConstantNodeParameter Kind valueKind,
    +                    @ConstantNodeParameter @SuppressWarnings("unused") LocationIdentity locationIdentity) {
    +        return unsafe.getAndSetObject(object, offset, newValue);
    +    }
    +
    +}
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastDynamicNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastDynamicNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastDynamicNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -73,13 +73,14 @@
         public Node canonical(CanonicalizerTool tool) {
             assert object() != null : this;
     
    -        if (ObjectStamp.isObjectAlwaysNull(object())) {
    +        if (StampTool.isObjectAlwaysNull(object())) {
                 return object();
             }
    -        if (hub.isConstant() && hub.asConstant().getKind() == Kind.Object && hub.asConstant().asObject() instanceof Class) {
    -            Class clazz = (Class) hub.asConstant().asObject();
    -            ResolvedJavaType t = tool.getMetaAccess().lookupJavaType(clazz);
    -            return graph().add(new CheckCastNode(t, object(), null, forStoreCheck));
    +        if (hub.isConstant()) {
    +            ResolvedJavaType t = tool.getConstantReflection().asJavaType(hub.asConstant());
    +            if (t != null) {
    +                return graph().add(new CheckCastNode(t, object(), null, forStoreCheck));
    +            }
             }
             return this;
         }
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -28,6 +28,7 @@
     
     import com.oracle.graal.api.meta.*;
     import com.oracle.graal.api.meta.ProfilingInfo.TriState;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.graph.spi.*;
     import com.oracle.graal.nodes.*;
    @@ -106,7 +107,7 @@
                 // This is a check cast that will always fail
                 condition = LogicConstantNode.contradiction(graph());
                 stamp = StampFactory.declared(type);
    -        } else if (ObjectStamp.isObjectNonNull(object)) {
    +        } else if (StampTool.isObjectNonNull(object)) {
                 condition = graph().addWithoutUnique(new InstanceOfNode(type, object, profile));
             } else {
                 if (profile != null && profile.getNullSeen() == TriState.FALSE) {
    @@ -141,7 +142,7 @@
         public Node canonical(CanonicalizerTool tool) {
             assert object() != null : this;
     
    -        ResolvedJavaType objectType = ObjectStamp.typeOrNull(object());
    +        ResolvedJavaType objectType = StampTool.typeOrNull(object());
             if (objectType != null && type.isAssignableFrom(objectType)) {
                 // we don't have to check for null types here because they will also pass the
                 // checkcast.
    @@ -160,7 +161,7 @@
                 }
             }
     
    -        if (ObjectStamp.isObjectAlwaysNull(object())) {
    +        if (StampTool.isObjectAlwaysNull(object())) {
                 return object();
             }
             if (tool.assumptions() != null && tool.assumptions().useOptimisticAssumptions()) {
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CompareAndSwapNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CompareAndSwapNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CompareAndSwapNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
      * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
      *
      * This code is free software; you can redistribute it and/or modify it
    @@ -22,14 +22,14 @@
      */
     package com.oracle.graal.nodes.java;
     
    -import static com.oracle.graal.graph.UnsafeAccess.*;
    +import static com.oracle.graal.compiler.common.UnsafeAccess.*;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.extended.*;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
     
     /**
      * Represents an atomic compare-and-swap operation The result is a boolean that contains whether the
    @@ -42,7 +42,22 @@
         @Input private ValueNode offset;
         @Input private ValueNode expected;
         @Input private ValueNode newValue;
    +
    +    private final Kind valueKind;
         private final int displacement;
    +    private final LocationIdentity locationIdentity;
    +
    +    public CompareAndSwapNode(ValueNode object, int displacement, ValueNode offset, ValueNode expected, ValueNode newValue, Kind valueKind, LocationIdentity locationIdentity) {
    +        super(StampFactory.forKind(Kind.Boolean.getStackKind()));
    +        assert expected.stamp().isCompatible(newValue.stamp());
    +        this.object = object;
    +        this.offset = offset;
    +        this.expected = expected;
    +        this.newValue = newValue;
    +        this.displacement = displacement;
    +        this.valueKind = valueKind;
    +        this.locationIdentity = locationIdentity;
    +    }
     
         public ValueNode object() {
             return object;
    @@ -64,19 +79,13 @@
             return displacement;
         }
     
    -    public CompareAndSwapNode(ValueNode object, int displacement, ValueNode offset, ValueNode expected, ValueNode newValue) {
    -        super(StampFactory.forKind(Kind.Boolean.getStackKind()));
    -        assert expected.stamp().isCompatible(newValue.stamp());
    -        this.object = object;
    -        this.offset = offset;
    -        this.expected = expected;
    -        this.newValue = newValue;
    -        this.displacement = displacement;
    +    public Kind getValueKind() {
    +        return valueKind;
         }
     
         @Override
         public LocationIdentity getLocationIdentity() {
    -        return LocationIdentity.ANY_LOCATION;
    +        return locationIdentity;
         }
     
         @Override
    @@ -86,17 +95,20 @@
     
         // specialized on value type until boxing/unboxing is sorted out in intrinsification
         @NodeIntrinsic
    -    public static boolean compareAndSwap(Object object, @ConstantNodeParameter int displacement, long offset, Object expected, Object newValue) {
    +    public static boolean compareAndSwap(Object object, @ConstantNodeParameter int displacement, long offset, Object expected, Object newValue,
    +                    @SuppressWarnings("unused") @ConstantNodeParameter Kind valueKind, @SuppressWarnings("unused") @ConstantNodeParameter LocationIdentity locationIdentity) {
             return unsafe.compareAndSwapObject(object, displacement + offset, expected, newValue);
         }
     
         @NodeIntrinsic
    -    public static boolean compareAndSwap(Object object, @ConstantNodeParameter int displacement, long offset, long expected, long newValue) {
    +    public static boolean compareAndSwap(Object object, @ConstantNodeParameter int displacement, long offset, long expected, long newValue,
    +                    @SuppressWarnings("unused") @ConstantNodeParameter Kind valueKind, @SuppressWarnings("unused") @ConstantNodeParameter LocationIdentity locationIdentity) {
             return unsafe.compareAndSwapLong(object, displacement + offset, expected, newValue);
         }
     
         @NodeIntrinsic
    -    public static boolean compareAndSwap(Object object, @ConstantNodeParameter int displacement, long offset, int expected, int newValue) {
    +    public static boolean compareAndSwap(Object object, @ConstantNodeParameter int displacement, long offset, int expected, int newValue,
    +                    @SuppressWarnings("unused") @ConstantNodeParameter Kind valueKind, @SuppressWarnings("unused") @ConstantNodeParameter LocationIdentity locationIdentity) {
             return unsafe.compareAndSwapInt(object, displacement + offset, expected, newValue);
         }
     }
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/DynamicNewArrayNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/DynamicNewArrayNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/DynamicNewArrayNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -26,10 +26,10 @@
     import java.util.*;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.graph.spi.*;
     import com.oracle.graal.nodes.*;
    -import com.oracle.graal.nodes.type.*;
     
     /**
      * The {@code DynamicNewArrayNode} is used for allocation of arrays when the type is not a
    @@ -55,9 +55,8 @@
         @Override
         public void simplify(SimplifierTool tool) {
             if (isAlive() && elementType.isConstant()) {
    -            Class elementClass = (Class) elementType.asConstant().asObject();
    -            if (elementClass != null && !(elementClass.equals(void.class))) {
    -                ResolvedJavaType javaType = tool.getMetaAccess().lookupJavaType(elementClass);
    +            ResolvedJavaType javaType = tool.getConstantReflection().asJavaType(elementType.asConstant());
    +            if (javaType != null && !javaType.equals(tool.getMetaAccess().lookupJavaType(void.class))) {
                     NewArrayNode newArray = graph().add(new NewArrayNode(javaType, length(), fillContents()));
                     List snapshot = inputs().snapshot();
                     graph().replaceFixedWithFixed(this, newArray);
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/DynamicNewInstanceNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/DynamicNewInstanceNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/DynamicNewInstanceNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,10 +23,10 @@
     package com.oracle.graal.nodes.java;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.graph.spi.*;
     import com.oracle.graal.nodes.*;
    -import com.oracle.graal.nodes.type.*;
     
     public class DynamicNewInstanceNode extends AbstractNewObjectNode implements Canonicalizable {
     
    @@ -40,13 +40,9 @@
         @Override
         public Node canonical(CanonicalizerTool tool) {
             if (clazz.isConstant()) {
    -            Constant clazzConstant = clazz.asConstant();
    -            if (clazzConstant.getKind() == Kind.Object && clazzConstant.asObject() instanceof Class) {
    -                Class staticClass = (Class) clazzConstant.asObject();
    -                ResolvedJavaType type = tool.getMetaAccess().lookupJavaType(staticClass);
    -                if (type.isInitialized()) {
    -                    return graph().add(new NewInstanceNode(type, fillContents()));
    -                }
    +            ResolvedJavaType type = tool.getConstantReflection().asJavaType(clazz.asConstant());
    +            if (type != null && type.isInitialized()) {
    +                return graph().add(new NewInstanceNode(type, fillContents()));
                 }
             }
             return this;
    @@ -57,5 +53,5 @@
         }
     
         @NodeIntrinsic
    -    public static native Object allocateInstance(Class clazz, @ConstantNodeParameter boolean fillContents);
    +    public static native Object allocateInstance(Class clazz, @ConstantNodeParameter boolean fillContents);
     }
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ExceptionObjectNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ExceptionObjectNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ExceptionObjectNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -26,12 +26,12 @@
     
     import com.oracle.graal.api.code.*;
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.graph.spi.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.extended.*;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
     
     /**
      * The entry to an exception handler with the exception coming from a call (as opposed to a local
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfDynamicNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfDynamicNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfDynamicNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -47,8 +47,8 @@
             this.mirror = mirror;
             this.object = object;
             assert mirror.getKind() == Kind.Object : mirror.getKind();
    -        assert ObjectStamp.isExactType(mirror);
    -        assert ObjectStamp.typeOrNull(mirror).getName().equals("Ljava/lang/Class;");
    +        assert StampTool.isExactType(mirror);
    +        assert StampTool.typeOrNull(mirror).getName().equals("Ljava/lang/Class;");
         }
     
         @Override
    @@ -60,12 +60,13 @@
         public Node canonical(CanonicalizerTool tool) {
             assert object() != null : this;
             if (mirror().isConstant()) {
    -            Class clazz = (Class) mirror().asConstant().asObject();
    -            ResolvedJavaType t = tool.getMetaAccess().lookupJavaType(clazz);
    -            if (t.isPrimitive()) {
    -                return LogicConstantNode.contradiction(graph());
    -            } else {
    -                return graph().unique(new InstanceOfNode(t, object(), null));
    +            ResolvedJavaType t = tool.getConstantReflection().asJavaType(mirror().asConstant());
    +            if (t != null) {
    +                if (t.isPrimitive()) {
    +                    return LogicConstantNode.contradiction(graph());
    +                } else {
    +                    return graph().unique(new InstanceOfNode(t, object(), null));
    +                }
                 }
             }
             return this;
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,12 +23,12 @@
     package com.oracle.graal.nodes.java;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.graph.spi.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.calc.*;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
     
     /**
      * The {@code InstanceOfNode} represents an instanceof test.
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadExceptionObjectNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadExceptionObjectNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadExceptionObjectNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,9 +23,9 @@
     package com.oracle.graal.nodes.java;
     
     import com.oracle.graal.api.code.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
     
     /**
      * Loads an exception object passed by the runtime from a callee to an exception handler in a
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadFieldNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadFieldNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadFieldNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,11 +22,11 @@
      */
     package com.oracle.graal.nodes.java;
     
    -import java.lang.reflect.*;
    +import static com.oracle.graal.graph.iterators.NodePredicates.*;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
    -import com.oracle.graal.graph.iterators.*;
     import com.oracle.graal.graph.spi.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.spi.*;
    @@ -60,7 +60,7 @@
     
         @Override
         public Node canonical(CanonicalizerTool tool) {
    -        if (usages().isEmpty() && !isVolatile() && (isStatic() || ObjectStamp.isObjectNonNull(object().stamp()))) {
    +        if (usages().isEmpty() && !isVolatile() && (isStatic() || StampTool.isObjectNonNull(object().stamp()))) {
                 return null;
             }
             MetaAccessProvider metaAccess = tool.getMetaAccess();
    @@ -97,7 +97,7 @@
         }
     
         private PhiNode asPhi(MetaAccessProvider metaAccess) {
    -        if (!isStatic() && Modifier.isFinal(field.getModifiers()) && object() instanceof ValuePhiNode && ((ValuePhiNode) object()).values().filter(NodePredicates.isNotA(ConstantNode.class)).isEmpty()) {
    +        if (!isStatic() && field.isFinal() && object() instanceof ValuePhiNode && ((ValuePhiNode) object()).values().filter(isNotA(ConstantNode.class)).isEmpty()) {
                 PhiNode phi = (PhiNode) object();
                 Constant[] constants = new Constant[phi.valueCount()];
                 for (int i = 0; i < phi.valueCount(); i++) {
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadIndexedNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadIndexedNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadIndexedNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,6 +23,7 @@
     package com.oracle.graal.nodes.java;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.spi.*;
     import com.oracle.graal.nodes.type.*;
    @@ -44,7 +45,7 @@
         }
     
         private static Stamp createStamp(ValueNode array, Kind kind) {
    -        ResolvedJavaType type = ObjectStamp.typeOrNull(array);
    +        ResolvedJavaType type = StampTool.typeOrNull(array);
             if (kind == Kind.Object && type != null) {
                 return StampFactory.declared(type.getComponentType());
             } else {
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoweredAtomicReadAndWriteNode.java
    --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoweredAtomicReadAndWriteNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -0,0 +1,84 @@
    +/*
    + * Copyright (c) 2014, 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.graph.*;
    +import com.oracle.graal.nodes.*;
    +import com.oracle.graal.nodes.extended.*;
    +import com.oracle.graal.nodes.spi.*;
    +
    +import sun.misc.*;
    +
    +/**
    + * Represents the lowered version of an atomic read-and-write operation like
    + * {@link Unsafe#getAndSetInt(Object, long, int)} .
    + */
    +@NodeInfo(allowedUsageTypes = {InputType.Memory})
    +public class LoweredAtomicReadAndWriteNode extends FixedAccessNode implements StateSplit, LIRLowerable, MemoryCheckpoint.Single {
    +
    +    @Input private ValueNode newValue;
    +    @Input(InputType.State) private FrameState stateAfter;
    +
    +    public LoweredAtomicReadAndWriteNode(ValueNode object, LocationNode location, ValueNode newValue, BarrierType barrierType, boolean compressible) {
    +        super(object, location, newValue.stamp(), barrierType, compressible);
    +        this.newValue = newValue;
    +    }
    +
    +    public FrameState stateAfter() {
    +        return stateAfter;
    +    }
    +
    +    public void setStateAfter(FrameState x) {
    +        assert x == null || x.isAlive() : "frame state must be in a graph";
    +        updateUsages(stateAfter, x);
    +        stateAfter = x;
    +    }
    +
    +    public boolean hasSideEffect() {
    +        return true;
    +    }
    +
    +    public LocationIdentity getLocationIdentity() {
    +        return location().getLocationIdentity();
    +    }
    +
    +    public void generate(NodeLIRBuilderTool gen) {
    +        Value address = location().generateAddress(gen, gen.getLIRGeneratorTool(), gen.operand(object()));
    +        Value result = gen.getLIRGeneratorTool().emitAtomicReadAndWrite(address, gen.operand(newValue));
    +        gen.setResult(this, result);
    +    }
    +
    +    public MemoryCheckpoint asMemoryCheckpoint() {
    +        return this;
    +    }
    +
    +    public MemoryPhiNode asMemoryPhi() {
    +        return null;
    +    }
    +
    +    public boolean canNullCheck() {
    +        return false;
    +    }
    +
    +}
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoweredCompareAndSwapNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoweredCompareAndSwapNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoweredCompareAndSwapNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,11 +23,11 @@
     package com.oracle.graal.nodes.java;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.extended.*;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
     
     /**
      * Represents the lowered version of an atomic compare-and-swap operation{@code CompareAndSwapNode}.
    @@ -79,7 +79,10 @@
     
         @Override
         public void generate(NodeLIRBuilderTool gen) {
    -        gen.visitCompareAndSwap(this, location().generateAddress(gen, gen.operand(object())));
    +        assert getNewValue().stamp().isCompatible(getExpectedValue().stamp());
    +        Value address = location().generateAddress(gen, gen.getLIRGeneratorTool(), gen.operand(object()));
    +        Value result = gen.getLIRGeneratorTool().emitCompareAndSwap(address, gen.operand(getExpectedValue()), gen.operand(getNewValue()), Constant.INT_1, Constant.INT_0);
    +        gen.setResult(this, result);
         }
     
         public MemoryCheckpoint asMemoryCheckpoint() {
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,9 +22,8 @@
      */
     package com.oracle.graal.nodes.java;
     
    -import java.lang.reflect.*;
    -
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.graph.spi.*;
     import com.oracle.graal.nodes.*;
    @@ -55,7 +54,7 @@
     
         /**
          * Gets the target method for this invocation instruction.
    -     * 
    +     *
          * @return the target method
          */
         public ResolvedJavaMethod targetMethod() {
    @@ -76,7 +75,7 @@
     
         /**
          * Gets the instruction that produces the receiver object for this invocation, if any.
    -     * 
    +     *
          * @return the instruction that produces the receiver object for this invocation if any,
          *         {@code null} if this invocation does not take a receiver object
          */
    @@ -86,7 +85,7 @@
     
         /**
          * Checks whether this is an invocation of a static method.
    -     * 
    +     *
          * @return {@code true} if the invocation is a static invocation
          */
         public boolean isStatic() {
    @@ -108,12 +107,12 @@
                 assertTrue(n instanceof Invoke, "call target can only be used from an invoke (%s)", n);
             }
             if (invokeKind == InvokeKind.Special || invokeKind == InvokeKind.Static) {
    -            assertFalse(Modifier.isAbstract(targetMethod.getModifiers()), "special calls or static calls are only allowed for concrete methods (%s)", targetMethod);
    +            assertFalse(targetMethod.isAbstract(), "special calls or static calls are only allowed for concrete methods (%s)", targetMethod);
             }
             if (invokeKind == InvokeKind.Static) {
    -            assertTrue(Modifier.isStatic(targetMethod.getModifiers()), "static calls are only allowed for static methods (%s)", targetMethod);
    +            assertTrue(targetMethod.isStatic(), "static calls are only allowed for static methods (%s)", targetMethod);
             } else {
    -            assertFalse(Modifier.isStatic(targetMethod.getModifiers()), "static calls are only allowed for non-static methods (%s)", targetMethod);
    +            assertFalse(targetMethod.isStatic(), "static calls are only allowed for non-static methods (%s)", targetMethod);
             }
             return super.verify();
         }
    @@ -138,18 +137,17 @@
                     return this;
                 }
     
    -            // check if the exact type of the receiver can be determined
    +            assert targetMethod.getDeclaringClass().asExactType() == null : "should have been handled by canBeStaticallyBound";
    +
    +            // check if the type of the receiver can narrow the result
                 ValueNode receiver = receiver();
    -            ResolvedJavaType exact = targetMethod.getDeclaringClass().asExactType();
    -            if (exact == null && ObjectStamp.isExactType(receiver)) {
    -                exact = ObjectStamp.typeOrNull(receiver);
    -            }
    -            if (exact != null) {
    +            ResolvedJavaType type = StampTool.typeOrNull(receiver);
    +            if (type != null) {
                     // either the holder class is exact, or the receiver object has an exact type
    -                ResolvedJavaMethod exactMethod = exact.resolveMethod(targetMethod);
    -                if (exactMethod != null) {
    +                ResolvedJavaMethod resolvedMethod = type.resolveMethod(targetMethod);
    +                if (resolvedMethod != null && (resolvedMethod.canBeStaticallyBound() || StampTool.isExactType(receiver))) {
                         invokeKind = InvokeKind.Special;
    -                    targetMethod = exactMethod;
    +                    targetMethod = resolvedMethod;
                         return this;
                     }
                 }
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MonitorExitNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MonitorExitNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MonitorExitNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,6 +22,7 @@
      */
     package com.oracle.graal.nodes.java;
     
    +import com.oracle.graal.api.code.*;
     import com.oracle.graal.api.meta.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.graph.spi.*;
    @@ -58,7 +59,7 @@
     
         @Override
         public void simplify(SimplifierTool tool) {
    -        if (escapedReturnValue != null && stateAfter() != null && stateAfter().bci != FrameState.AFTER_BCI) {
    +        if (escapedReturnValue != null && stateAfter() != null && stateAfter().bci != BytecodeFrame.AFTER_BCI) {
                 ValueNode returnValue = escapedReturnValue;
                 setEscapedReturnValue(null);
                 tool.removeIfUnused(returnValue);
    @@ -74,7 +75,7 @@
         public void virtualize(VirtualizerTool tool) {
             State state = tool.getObjectState(object());
             // the monitor exit for a synchronized method should never be virtualized
    -        assert stateAfter().bci != FrameState.AFTER_BCI || state == null;
    +        assert stateAfter().bci != BytecodeFrame.AFTER_BCI || state == null;
             if (state != null && state.getState() == EscapeState.Virtual && state.getVirtualObject().hasIdentity()) {
                 MonitorIdNode removedLock = state.removeLock();
                 assert removedLock == getMonitorId() : "mismatch at " + this + ": " + removedLock + " vs. " + getMonitorId();
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MonitorIdNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MonitorIdNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MonitorIdNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,10 +22,10 @@
      */
     package com.oracle.graal.nodes.java;
     
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
     
     /**
      * This node describes one locking scope; it ties the monitor enter, monitor exit and the frame
    diff -r 518a7f487c4f -r 9363fffa8b07 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 Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewArrayNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -25,6 +25,7 @@
     import java.util.*;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.spi.*;
     import com.oracle.graal.nodes.type.*;
    @@ -54,7 +55,7 @@
          * @return the element type of the array
          */
         public ResolvedJavaType elementType() {
    -        return ObjectStamp.typeOrNull(this).getComponentType();
    +        return StampTool.typeOrNull(this).getComponentType();
         }
     
         @Override
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewInstanceNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewInstanceNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewInstanceNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -26,10 +26,10 @@
     import java.util.*;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
     import com.oracle.graal.nodes.virtual.*;
     
     /**
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewMultiArrayNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewMultiArrayNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewMultiArrayNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,10 +23,10 @@
     package com.oracle.graal.nodes.java;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
     
     /**
      * The {@code NewMultiArrayNode} represents an allocation of a multi-dimensional object array.
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/RegisterFinalizerNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/RegisterFinalizerNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/RegisterFinalizerNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -24,11 +24,11 @@
     
     import com.oracle.graal.api.code.*;
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.graph.spi.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
     
     /**
      * This node is used to perform the finalizer registration at the end of the java.lang.Object
    @@ -53,7 +53,7 @@
         @Override
         public void generate(NodeLIRBuilderTool gen) {
             ForeignCallLinkage linkage = gen.getLIRGeneratorTool().getForeignCalls().lookupForeignCall(REGISTER_FINALIZER);
    -        gen.getLIRGeneratorTool().emitForeignCall(linkage, this, gen.operand(object()));
    +        gen.getLIRGeneratorTool().emitForeignCall(linkage, gen.state(this), gen.operand(object()));
         }
     
         @Override
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/SelfReplacingMethodCallTargetNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/SelfReplacingMethodCallTargetNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/SelfReplacingMethodCallTargetNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,9 +22,8 @@
      */
     package com.oracle.graal.nodes.java;
     
    -import java.lang.reflect.*;
    -
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.spi.*;
    @@ -65,7 +64,7 @@
     
         @Override
         public void lower(LoweringTool tool) {
    -        InvokeKind invokeKind = Modifier.isStatic(replacementTargetMethod.getModifiers()) ? InvokeKind.Static : InvokeKind.Special;
    +        InvokeKind invokeKind = replacementTargetMethod.isStatic() ? InvokeKind.Static : InvokeKind.Special;
             MethodCallTargetNode replacement = graph().add(
                             new MethodCallTargetNode(invokeKind, replacementTargetMethod, replacementArguments.toArray(new ValueNode[replacementArguments.size()]), replacementReturnType));
     
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/StoreFieldNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/StoreFieldNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/StoreFieldNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,10 +23,10 @@
     package com.oracle.graal.nodes.java;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
     import com.oracle.graal.nodes.virtual.*;
     
     /**
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/StoreIndexedNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/StoreIndexedNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/StoreIndexedNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,6 +23,7 @@
     package com.oracle.graal.nodes.java;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.spi.*;
    @@ -75,8 +76,8 @@
                 int index = indexValue.isConstant() ? indexValue.asConstant().asInt() : -1;
                 if (index >= 0 && index < arrayState.getVirtualObject().entryCount()) {
                     ResolvedJavaType componentType = arrayState.getVirtualObject().type().getComponentType();
    -                if (componentType.isPrimitive() || ObjectStamp.isObjectAlwaysNull(value) || componentType.getSuperclass() == null ||
    -                                (ObjectStamp.typeOrNull(value) != null && componentType.isAssignableFrom(ObjectStamp.typeOrNull(value)))) {
    +                if (componentType.isPrimitive() || StampTool.isObjectAlwaysNull(value) || componentType.getSuperclass() == null ||
    +                                (StampTool.typeOrNull(value) != null && componentType.isAssignableFrom(StampTool.typeOrNull(value)))) {
                         tool.setVirtualEntry(arrayState, index, value(), false);
                         tool.delete();
                     }
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/TypeSwitchNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/TypeSwitchNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/TypeSwitchNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -26,11 +26,11 @@
     
     import com.oracle.graal.api.meta.*;
     import com.oracle.graal.api.meta.ResolvedJavaType.Representation;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.spi.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.extended.*;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
     import com.oracle.graal.nodes.util.*;
     
     /**
    @@ -51,7 +51,7 @@
          * @param keyProbabilities the probabilities of the keys
          * @param keySuccessors the successor index for each key
          */
    -    public TypeSwitchNode(ValueNode value, AbstractBeginNode[] successors, ResolvedJavaType[] keys, double[] keyProbabilities, int[] keySuccessors) {
    +    public TypeSwitchNode(ValueNode value, BeginNode[] successors, ResolvedJavaType[] keys, double[] keyProbabilities, int[] keySuccessors) {
             super(value, successors, keySuccessors, keyProbabilities);
             assert successors.length <= keys.length + 1;
             assert keySuccessors.length == keyProbabilities.length;
    @@ -134,7 +134,7 @@
                         tool.addToWorkList(defaultSuccessor());
                         graph().removeSplitPropagate(this, defaultSuccessor());
                     } else if (validKeys != keys.length) {
    -                    ArrayList newSuccessors = new ArrayList<>(blockSuccessorCount());
    +                    ArrayList newSuccessors = new ArrayList<>(blockSuccessorCount());
                         ResolvedJavaType[] newKeys = new ResolvedJavaType[validKeys];
                         int[] newKeySuccessors = new int[validKeys + 1];
                         double[] newKeyProbabilities = new double[validKeys + 1];
    @@ -167,14 +167,14 @@
                         }
     
                         for (int i = 0; i < blockSuccessorCount(); i++) {
    -                        AbstractBeginNode successor = blockSuccessor(i);
    +                        BeginNode successor = blockSuccessor(i);
                             if (!newSuccessors.contains(successor)) {
                                 tool.deleteBranch(successor);
                             }
                             setBlockSuccessor(i, null);
                         }
     
    -                    AbstractBeginNode[] successorsArray = newSuccessors.toArray(new AbstractBeginNode[newSuccessors.size()]);
    +                    BeginNode[] successorsArray = newSuccessors.toArray(new BeginNode[newSuccessors.size()]);
                         TypeSwitchNode newSwitch = graph().add(new TypeSwitchNode(value(), successorsArray, newKeys, newKeyProbabilities, newKeySuccessors));
                         ((FixedWithNextNode) predecessor()).setNext(newSwitch);
                         GraphUtil.killWithUnusedFloatingInputs(this);
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/ArithmeticLIRGenerator.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/ArithmeticLIRGenerator.java	Wed Apr 23 15:22:20 2014 +0200
    +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    @@ -1,102 +0,0 @@
    -/*
    - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
    - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    - *
    - * This code is free software; you can redistribute it and/or modify it
    - * under the terms of the GNU General Public License version 2 only, as
    - * published by the Free Software Foundation.
    - *
    - * This code is distributed in the hope that it will be useful, but WITHOUT
    - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    - * version 2 for more details (a copy is included in the LICENSE file that
    - * accompanied this code).
    - *
    - * You should have received a copy of the GNU General Public License version
    - * 2 along with this work; if not, write to the Free Software Foundation,
    - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    - *
    - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    - * or visit www.oracle.com if you need additional information or have any
    - * questions.
    - */
    -package com.oracle.graal.nodes.spi;
    -
    -import com.oracle.graal.api.meta.*;
    -import com.oracle.graal.nodes.*;
    -import com.oracle.graal.nodes.calc.FloatConvertNode.FloatConvert;
    -import com.oracle.graal.nodes.type.*;
    -
    -/**
    - * This interface can be used to generate LIR for arithmetic operations.
    - */
    -public interface ArithmeticLIRGenerator {
    -    /**
    -     * TODO remove reference to {@link Stamp}.
    -     */
    -    PlatformKind getPlatformKind(Stamp stamp);
    -
    -    Value emitNegate(Value input);
    -
    -    Value emitAdd(Value a, Value b);
    -
    -    Value emitSub(Value a, Value b);
    -
    -    Value emitMul(Value a, Value b);
    -
    -    /**
    -     * TODO remove {@link DeoptimizeNode}.
    -     */
    -    Value emitDiv(Value a, Value b, DeoptimizingNode deopting);
    -
    -    /**
    -     * TODO remove {@link DeoptimizeNode}.
    -     */
    -    Value emitRem(Value a, Value b, DeoptimizingNode deopting);
    -
    -    /**
    -     * TODO remove {@link DeoptimizeNode}.
    -     */
    -    Value emitUDiv(Value a, Value b, DeoptimizingNode deopting);
    -
    -    /**
    -     * TODO remove {@link DeoptimizeNode}.
    -     */
    -    Value emitURem(Value a, Value b, DeoptimizingNode deopting);
    -
    -    Value emitNot(Value input);
    -
    -    Value emitAnd(Value a, Value b);
    -
    -    Value emitOr(Value a, Value b);
    -
    -    Value emitXor(Value a, Value b);
    -
    -    Value emitShl(Value a, Value b);
    -
    -    Value emitShr(Value a, Value b);
    -
    -    Value emitUShr(Value a, Value b);
    -
    -    Value emitFloatConvert(FloatConvert op, Value inputVal);
    -
    -    Value emitReinterpret(PlatformKind to, Value inputVal);
    -
    -    Value emitNarrow(Value inputVal, int bits);
    -
    -    Value emitSignExtend(Value inputVal, int fromBits, int toBits);
    -
    -    Value emitZeroExtend(Value inputVal, int fromBits, int toBits);
    -
    -    Value emitMathAbs(Value input);
    -
    -    Value emitMathSqrt(Value input);
    -
    -    Value emitMathLog(Value input, boolean base10);
    -
    -    Value emitMathCos(Value input);
    -
    -    Value emitMathSin(Value input);
    -
    -    Value emitMathTan(Value input);
    -}
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/ArithmeticLIRLowerable.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/ArithmeticLIRLowerable.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/ArithmeticLIRLowerable.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,8 +23,9 @@
     package com.oracle.graal.nodes.spi;
     
     import com.oracle.graal.api.code.*;
    +import com.oracle.graal.lir.gen.*;
     
     public interface ArithmeticLIRLowerable extends ArithmeticOperation {
     
    -    void generate(NodeLIRBuilderTool gen);
    +    void generate(NodeMappableLIRBuilder builder, ArithmeticLIRGenerator gen);
     }
    diff -r 518a7f487c4f -r 9363fffa8b07 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 Apr 23 15:22:20 2014 +0200
    +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    @@ -1,97 +0,0 @@
    -/*
    - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
    - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    - *
    - * This code is free software; you can redistribute it and/or modify it
    - * under the terms of the GNU General Public License version 2 only, as
    - * published by the Free Software Foundation.
    - *
    - * This code is distributed in the hope that it will be useful, but WITHOUT
    - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    - * version 2 for more details (a copy is included in the LICENSE file that
    - * accompanied this code).
    - *
    - * You should have received a copy of the GNU General Public License version
    - * 2 along with this work; if not, write to the Free Software Foundation,
    - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    - *
    - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    - * or visit www.oracle.com if you need additional information or have any
    - * questions.
    - */
    -package com.oracle.graal.nodes.spi;
    -
    -import com.oracle.graal.api.code.*;
    -import com.oracle.graal.api.meta.*;
    -import com.oracle.graal.nodes.*;
    -import com.oracle.graal.nodes.extended.*;
    -
    -public interface LIRGeneratorTool extends ArithmeticLIRGenerator {
    -
    -    TargetDescription target();
    -
    -    MetaAccessProvider getMetaAccess();
    -
    -    CodeCacheProvider getCodeCache();
    -
    -    ForeignCallsProvider getForeignCalls();
    -
    -    Value emitLoad(PlatformKind kind, Value address, Access access);
    -
    -    void emitStore(PlatformKind kind, Value address, Value input, Access access);
    -
    -    void emitDeoptimize(Value actionAndReason, Value failedSpeculation, DeoptimizingNode deopting);
    -
    -    Value emitForeignCall(ForeignCallLinkage linkage, DeoptimizingNode info, Value... args);
    -
    -    /**
    -     * Checks whether the supplied constant can be used without loading it into a register for most
    -     * operations, i.e., for commonly used arithmetic, logical, and comparison operations.
    -     *
    -     * @param c The constant to check.
    -     * @return True if the constant can be used directly, false if the constant needs to be in a
    -     *         register.
    -     */
    -    boolean canInlineConstant(Constant c);
    -
    -    boolean canStoreConstant(Constant c, boolean isCompressed);
    -
    -    RegisterAttributes attributes(Register register);
    -
    -    AllocatableValue newVariable(PlatformKind kind);
    -
    -    AllocatableValue emitMove(Value input);
    -
    -    void emitMove(AllocatableValue dst, Value src);
    -
    -    /**
    -     * Emits an op that loads the address of some raw data.
    -     *
    -     * @param dst the variable into which the address is loaded
    -     * @param data the data to be installed with the generated code
    -     */
    -    void emitData(AllocatableValue dst, byte[] data);
    -
    -    Value emitAddress(Value base, long displacement, Value index, int scale);
    -
    -    Value emitAddress(StackSlot slot);
    -
    -    void emitMembar(int barriers);
    -
    -    void emitUnwind(Value operand);
    -
    -    /**
    -     * Called just before register allocation is performed on the LIR owned by this generator.
    -     * Overriding implementations of this method must call the overridden method.
    -     */
    -    void beforeRegisterAllocation();
    -
    -    void emitIncomingValues(Value[] params);
    -
    -    /**
    -     * Emits a return instruction. Implementations need to insert a move if the input is not in the
    -     * correct location.
    -     */
    -    void emitReturn(Value input);
    -}
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LIRTypeTool.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LIRTypeTool.java	Wed Apr 23 15:22:20 2014 +0200
    +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    @@ -1,37 +0,0 @@
    -/*
    - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
    - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    - *
    - * This code is free software; you can redistribute it and/or modify it
    - * under the terms of the GNU General Public License version 2 only, as
    - * published by the Free Software Foundation.
    - *
    - * This code is distributed in the hope that it will be useful, but WITHOUT
    - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    - * version 2 for more details (a copy is included in the LICENSE file that
    - * accompanied this code).
    - *
    - * You should have received a copy of the GNU General Public License version
    - * 2 along with this work; if not, write to the Free Software Foundation,
    - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    - *
    - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    - * or visit www.oracle.com if you need additional information or have any
    - * questions.
    - */
    -package com.oracle.graal.nodes.spi;
    -
    -import com.oracle.graal.api.meta.*;
    -
    -/**
    - * This interface can be used to access platform and VM specific kinds.
    - */
    -public interface LIRTypeTool {
    -
    -    PlatformKind getIntegerKind(int bits, boolean unsigned);
    -
    -    PlatformKind getFloatingKind(int bits);
    -
    -    PlatformKind getObjectKind();
    -}
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/MemoryArithmeticLIRLowerer.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/MemoryArithmeticLIRLowerer.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/MemoryArithmeticLIRLowerer.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -25,10 +25,10 @@
     import java.util.*;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.calc.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.nodes.*;
    -import com.oracle.graal.nodes.calc.FloatConvertNode.FloatConvert;
     import com.oracle.graal.nodes.extended.*;
    -import com.oracle.graal.nodes.type.*;
     
     /**
      * This interface can be used to generate LIR for arithmetic operations where one of the operations
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/NodeLIRBuilderTool.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/NodeLIRBuilderTool.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/NodeLIRBuilderTool.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -26,13 +26,17 @@
     
     import com.oracle.graal.api.code.*;
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.lir.*;
    +import com.oracle.graal.lir.gen.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.calc.*;
     import com.oracle.graal.nodes.extended.*;
    -import com.oracle.graal.nodes.java.*;
     
     public interface NodeLIRBuilderTool extends NodeMappableLIRBuilder {
     
    +    // TODO (je) remove and move into the Node
    +    LIRFrameState state(DeoptimizingNode deopt);
    +
         void emitNullCheck(ValueNode v, DeoptimizingNode deopting);
     
         void emitIf(IfNode i);
    @@ -50,8 +54,6 @@
     
         void visitLoopEnd(LoopEndNode i);
     
    -    void visitCompareAndSwap(LoweredCompareAndSwapNode i, Value address);
    -
         // These methods define the contract a runtime specific backend must provide.
     
         void visitSafepointNode(SafepointNode i);
    @@ -62,7 +64,7 @@
     
         LIRGeneratorTool getLIRGeneratorTool();
     
    -    void emitOverflowCheckBranch(AbstractBeginNode overflowSuccessor, AbstractBeginNode next, double probability);
    +    void emitOverflowCheckBranch(BeginNode overflowSuccessor, BeginNode next, double probability);
     
         Value[] visitInvokeArguments(CallingConvention cc, Collection arguments);
     
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/NodeWithState.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/NodeWithState.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/NodeWithState.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,6 +23,7 @@
     package com.oracle.graal.nodes.spi;
     
     import com.oracle.graal.graph.*;
    +import com.oracle.graal.graph.iterators.*;
     import com.oracle.graal.nodes.*;
     
     /**
    @@ -31,4 +32,8 @@
     public interface NodeWithState {
     
         Node asNode();
    +
    +    default NodeIterable states() {
    +        return asNode().inputs().filter(FrameState.class);
    +    }
     }
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/VirtualizerTool.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/VirtualizerTool.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/VirtualizerTool.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -41,12 +41,17 @@
     public interface VirtualizerTool {
     
         /**
    -     * @return the {@link MetaAccessProvider} associated with the current compilation, which might
    -     *         be required for creating constants, etc.
    +     * @return the {@link MetaAccessProvider} associated with the current compilation.
          */
         MetaAccessProvider getMetaAccessProvider();
     
         /**
    +     * @return the {@link ConstantReflectionProvider} associated with the current compilation, which
    +     *         can be used to access {@link Constant}s.
    +     */
    +    ConstantReflectionProvider getConstantReflectionProvider();
    +
    +    /**
          * @return the {@link Assumptions} associated with the current compilation, which can be used to
          *         make type assumptions during virtualization.
          */
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/FloatStamp.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/FloatStamp.java	Wed Apr 23 15:22:20 2014 +0200
    +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    @@ -1,234 +0,0 @@
    -/*
    - * Copyright (c) 2012, 2014, 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.type;
    -
    -import com.oracle.graal.api.meta.*;
    -import com.oracle.graal.graph.*;
    -import com.oracle.graal.nodes.spi.*;
    -
    -public class FloatStamp extends PrimitiveStamp {
    -
    -    private final double lowerBound;
    -    private final double upperBound;
    -    private final boolean nonNaN;
    -
    -    protected FloatStamp(int bits) {
    -        this(bits, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, false);
    -    }
    -
    -    protected FloatStamp(int bits, double lowerBound, double upperBound, boolean nonNaN) {
    -        super(bits);
    -        this.lowerBound = lowerBound;
    -        this.upperBound = upperBound;
    -        this.nonNaN = nonNaN;
    -    }
    -
    -    @Override
    -    public Stamp unrestricted() {
    -        return new FloatStamp(getBits());
    -    }
    -
    -    @Override
    -    public Stamp illegal() {
    -        return new FloatStamp(getBits(), Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY, true);
    -    }
    -
    -    @Override
    -    public boolean isLegal() {
    -        return lowerBound <= upperBound || !nonNaN;
    -    }
    -
    -    @Override
    -    public Kind getStackKind() {
    -        if (getBits() > 32) {
    -            return Kind.Double;
    -        } else {
    -            return Kind.Float;
    -        }
    -    }
    -
    -    @Override
    -    public PlatformKind getPlatformKind(LIRTypeTool tool) {
    -        return tool.getFloatingKind(getBits());
    -    }
    -
    -    @Override
    -    public ResolvedJavaType javaType(MetaAccessProvider metaAccess) {
    -        switch (getBits()) {
    -            case 32:
    -                return metaAccess.lookupJavaType(Float.TYPE);
    -            case 64:
    -                return metaAccess.lookupJavaType(Double.TYPE);
    -            default:
    -                throw GraalInternalError.shouldNotReachHere();
    -        }
    -    }
    -
    -    /**
    -     * The (inclusive) lower bound on the value described by this stamp.
    -     */
    -    public double lowerBound() {
    -        return lowerBound;
    -    }
    -
    -    /**
    -     * The (inclusive) upper bound on the value described by this stamp.
    -     */
    -    public double upperBound() {
    -        return upperBound;
    -    }
    -
    -    public boolean isNonNaN() {
    -        return nonNaN;
    -    }
    -
    -    public boolean isUnrestricted() {
    -        return lowerBound == Double.NEGATIVE_INFINITY && upperBound == Double.POSITIVE_INFINITY && !nonNaN;
    -    }
    -
    -    public boolean contains(double value) {
    -        if (Double.isNaN(value)) {
    -            return !nonNaN;
    -        } else {
    -            return value >= lowerBound && value <= upperBound;
    -        }
    -    }
    -
    -    @Override
    -    public String toString() {
    -        StringBuilder str = new StringBuilder();
    -        str.append('f');
    -        str.append(getBits());
    -        str.append(nonNaN ? "!" : "");
    -        if (lowerBound == upperBound) {
    -            str.append(" [").append(lowerBound).append(']');
    -        } else if (lowerBound != Double.NEGATIVE_INFINITY || upperBound != Double.POSITIVE_INFINITY) {
    -            str.append(" [").append(lowerBound).append(" - ").append(upperBound).append(']');
    -        }
    -        return str.toString();
    -    }
    -
    -    @Override
    -    public Stamp meet(Stamp otherStamp) {
    -        if (otherStamp == this) {
    -            return this;
    -        }
    -        if (!(otherStamp instanceof FloatStamp)) {
    -            return StampFactory.illegal(Kind.Illegal);
    -        }
    -        FloatStamp other = (FloatStamp) otherStamp;
    -        assert getBits() == other.getBits();
    -        double meetUpperBound = Math.max(upperBound, other.upperBound);
    -        double meetLowerBound = Math.min(lowerBound, other.lowerBound);
    -        boolean meetNonNaN = nonNaN && other.nonNaN;
    -        if (meetLowerBound == lowerBound && meetUpperBound == upperBound && meetNonNaN == nonNaN) {
    -            return this;
    -        } else if (meetLowerBound == other.lowerBound && meetUpperBound == other.upperBound && meetNonNaN == other.nonNaN) {
    -            return other;
    -        } else {
    -            return new FloatStamp(getBits(), meetLowerBound, meetUpperBound, meetNonNaN);
    -        }
    -    }
    -
    -    @Override
    -    public Stamp join(Stamp otherStamp) {
    -        if (otherStamp == this) {
    -            return this;
    -        }
    -        if (!(otherStamp instanceof FloatStamp)) {
    -            return StampFactory.illegal(Kind.Illegal);
    -        }
    -        FloatStamp other = (FloatStamp) otherStamp;
    -        assert getBits() == other.getBits();
    -        double joinUpperBound = Math.min(upperBound, other.upperBound);
    -        double joinLowerBound = Math.max(lowerBound, other.lowerBound);
    -        boolean joinNonNaN = nonNaN || other.nonNaN;
    -        if (joinLowerBound == lowerBound && joinUpperBound == upperBound && joinNonNaN == nonNaN) {
    -            return this;
    -        } else if (joinLowerBound == other.lowerBound && joinUpperBound == other.upperBound && joinNonNaN == other.nonNaN) {
    -            return other;
    -        } else {
    -            return new FloatStamp(getBits(), joinLowerBound, joinUpperBound, joinNonNaN);
    -        }
    -    }
    -
    -    @Override
    -    public int hashCode() {
    -        final int prime = 31;
    -        int result = 1;
    -        long temp;
    -        result = prime * result + super.hashCode();
    -        temp = Double.doubleToLongBits(lowerBound);
    -        result = prime * result + (int) (temp ^ (temp >>> 32));
    -        result = prime * result + (nonNaN ? 1231 : 1237);
    -        temp = Double.doubleToLongBits(upperBound);
    -        result = prime * result + (int) (temp ^ (temp >>> 32));
    -        return result;
    -    }
    -
    -    @Override
    -    public boolean isCompatible(Stamp stamp) {
    -        if (this == stamp) {
    -            return true;
    -        }
    -        if (stamp instanceof FloatStamp) {
    -            FloatStamp other = (FloatStamp) stamp;
    -            return getBits() == other.getBits();
    -        }
    -        return false;
    -    }
    -
    -    @Override
    -    public boolean equals(Object obj) {
    -        if (this == obj) {
    -            return true;
    -        }
    -        if (obj == null || getClass() != obj.getClass() || !super.equals(obj)) {
    -            return false;
    -        }
    -        FloatStamp other = (FloatStamp) obj;
    -        if (Double.doubleToLongBits(lowerBound) != Double.doubleToLongBits(other.lowerBound)) {
    -            return false;
    -        }
    -        if (Double.doubleToLongBits(upperBound) != Double.doubleToLongBits(other.upperBound)) {
    -            return false;
    -        }
    -        if (nonNaN != other.nonNaN) {
    -            return false;
    -        }
    -        return true;
    -    }
    -
    -    @Override
    -    public Constant asConstant() {
    -        if (nonNaN && lowerBound == upperBound) {
    -            switch (getBits()) {
    -                case 32:
    -                    return Constant.forFloat((float) lowerBound);
    -                case 64:
    -                    return Constant.forDouble(lowerBound);
    -            }
    -        }
    -        return null;
    -    }
    -}
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/IllegalStamp.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/IllegalStamp.java	Wed Apr 23 15:22:20 2014 +0200
    +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    @@ -1,92 +0,0 @@
    -/*
    - * Copyright (c) 2012, 2014, 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.type;
    -
    -import com.oracle.graal.api.meta.*;
    -import com.oracle.graal.graph.*;
    -import com.oracle.graal.nodes.spi.*;
    -
    -/**
    - * This stamp represents the illegal type. Values with this type can not exist at run time.
    - */
    -public final class IllegalStamp extends Stamp {
    -
    -    private IllegalStamp() {
    -    }
    -
    -    @Override
    -    public Kind getStackKind() {
    -        return Kind.Illegal;
    -    }
    -
    -    @Override
    -    public PlatformKind getPlatformKind(LIRTypeTool tool) {
    -        throw GraalInternalError.shouldNotReachHere("illegal stamp should not reach backend");
    -    }
    -
    -    @Override
    -    public Stamp unrestricted() {
    -        return this;
    -    }
    -
    -    @Override
    -    public Stamp illegal() {
    -        return this;
    -    }
    -
    -    @Override
    -    public ResolvedJavaType javaType(MetaAccessProvider metaAccess) {
    -        throw GraalInternalError.shouldNotReachHere("illegal stamp has no Java type");
    -    }
    -
    -    @Override
    -    public Stamp meet(Stamp other) {
    -        return this;
    -    }
    -
    -    @Override
    -    public Stamp join(Stamp other) {
    -        return this;
    -    }
    -
    -    @Override
    -    public boolean isCompatible(Stamp stamp) {
    -        return false;
    -    }
    -
    -    @Override
    -    public String toString() {
    -        return "ILLEGAL";
    -    }
    -
    -    @Override
    -    public boolean isLegal() {
    -        return false;
    -    }
    -
    -    private static IllegalStamp instance = new IllegalStamp();
    -
    -    static IllegalStamp getInstance() {
    -        return instance;
    -    }
    -}
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/IntegerStamp.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/IntegerStamp.java	Wed Apr 23 15:22:20 2014 +0200
    +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    @@ -1,348 +0,0 @@
    -/*
    - * Copyright (c) 2012, 2014, 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.type;
    -
    -import java.util.*;
    -
    -import com.oracle.graal.api.meta.*;
    -import com.oracle.graal.graph.*;
    -import com.oracle.graal.nodes.*;
    -import com.oracle.graal.nodes.spi.*;
    -
    -/**
    - * Describes the possible values of a {@link ValueNode} that produces an int or long result.
    - *
    - * The description consists of (inclusive) lower and upper bounds and up (may be set) and down
    - * (always set) bit-masks.
    - */
    -public class IntegerStamp extends PrimitiveStamp {
    -
    -    private final boolean unsigned;
    -
    -    private final long lowerBound;
    -    private final long upperBound;
    -    private final long downMask;
    -    private final long upMask;
    -
    -    public IntegerStamp(int bits, boolean unsigned, long lowerBound, long upperBound, long downMask, long upMask) {
    -        super(bits);
    -        this.unsigned = unsigned;
    -        this.lowerBound = lowerBound;
    -        this.upperBound = upperBound;
    -        this.downMask = downMask;
    -        this.upMask = upMask;
    -        assert lowerBound >= defaultMinValue(bits, unsigned) : this;
    -        assert upperBound <= defaultMaxValue(bits, unsigned) : this;
    -        assert (downMask & defaultMask(bits)) == downMask : this;
    -        assert (upMask & defaultMask(bits)) == upMask : this;
    -    }
    -
    -    @Override
    -    public Stamp unrestricted() {
    -        return new IntegerStamp(getBits(), unsigned, defaultMinValue(getBits(), unsigned), defaultMaxValue(getBits(), unsigned), 0, defaultMask(getBits()));
    -    }
    -
    -    @Override
    -    public Stamp illegal() {
    -        return new IntegerStamp(getBits(), unsigned, defaultMaxValue(getBits(), unsigned), defaultMinValue(getBits(), unsigned), defaultMask(getBits()), 0);
    -    }
    -
    -    @Override
    -    public boolean isLegal() {
    -        if (unsigned) {
    -            return Long.compareUnsigned(lowerBound, upperBound) <= 0;
    -        } else {
    -            return lowerBound <= upperBound;
    -        }
    -    }
    -
    -    @Override
    -    public Kind getStackKind() {
    -        if (getBits() > 32) {
    -            return Kind.Long;
    -        } else {
    -            return Kind.Int;
    -        }
    -    }
    -
    -    @Override
    -    public PlatformKind getPlatformKind(LIRTypeTool tool) {
    -        return tool.getIntegerKind(getBits(), unsigned);
    -    }
    -
    -    @Override
    -    public ResolvedJavaType javaType(MetaAccessProvider metaAccess) {
    -        switch (getBits()) {
    -            case 1:
    -                assert unsigned;
    -                return metaAccess.lookupJavaType(Boolean.TYPE);
    -            case 8:
    -                assert !unsigned;
    -                return metaAccess.lookupJavaType(Byte.TYPE);
    -            case 16:
    -                if (unsigned) {
    -                    return metaAccess.lookupJavaType(Character.TYPE);
    -                } else {
    -                    return metaAccess.lookupJavaType(Short.TYPE);
    -                }
    -            case 32:
    -                assert !unsigned;
    -                return metaAccess.lookupJavaType(Integer.TYPE);
    -            case 64:
    -                assert !unsigned;
    -                return metaAccess.lookupJavaType(Long.TYPE);
    -            default:
    -                throw GraalInternalError.shouldNotReachHere();
    -        }
    -    }
    -
    -    /**
    -     * Check whether the value described by this stamp is unsigned.
    -     */
    -    public boolean isUnsigned() {
    -        return unsigned;
    -    }
    -
    -    /**
    -     * The (inclusive) lower bound on the value described by this stamp.
    -     */
    -    public long lowerBound() {
    -        return lowerBound;
    -    }
    -
    -    /**
    -     * The (inclusive) upper bound on the value described by this stamp.
    -     */
    -    public long upperBound() {
    -        return upperBound;
    -    }
    -
    -    /**
    -     * This bit-mask describes the bits that are always set in the value described by this stamp.
    -     */
    -    public long downMask() {
    -        return downMask;
    -    }
    -
    -    /**
    -     * This bit-mask describes the bits that can be set in the value described by this stamp.
    -     */
    -    public long upMask() {
    -        return upMask;
    -    }
    -
    -    public boolean isUnrestricted() {
    -        return lowerBound == defaultMinValue(getBits(), unsigned) && upperBound == defaultMaxValue(getBits(), unsigned) && downMask == 0 && upMask == defaultMask(getBits());
    -    }
    -
    -    public boolean contains(long value) {
    -        return value >= lowerBound && value <= upperBound && (value & downMask) == downMask && (value & upMask) == (value & defaultMask(getBits()));
    -    }
    -
    -    public boolean isPositive() {
    -        return lowerBound() >= 0;
    -    }
    -
    -    public boolean isNegative() {
    -        return upperBound() <= 0;
    -    }
    -
    -    public boolean isStrictlyPositive() {
    -        return lowerBound() > 0;
    -    }
    -
    -    public boolean isStrictlyNegative() {
    -        return upperBound() < 0;
    -    }
    -
    -    public boolean canBePositive() {
    -        return upperBound() > 0;
    -    }
    -
    -    public boolean canBeNegative() {
    -        return lowerBound() < 0;
    -    }
    -
    -    @Override
    -    public String toString() {
    -        StringBuilder str = new StringBuilder();
    -        str.append(unsigned ? 'u' : 'i');
    -        str.append(getBits());
    -        if (lowerBound == upperBound) {
    -            str.append(" [").append(lowerBound).append(']');
    -        } else if (lowerBound != defaultMinValue(getBits(), unsigned) || upperBound != defaultMaxValue(getBits(), unsigned)) {
    -            str.append(" [").append(lowerBound).append(" - ").append(upperBound).append(']');
    -        }
    -        if (downMask != 0) {
    -            str.append(" \u21ca");
    -            new Formatter(str).format("%016x", downMask);
    -        }
    -        if (upMask != defaultMask(getBits())) {
    -            str.append(" \u21c8");
    -            new Formatter(str).format("%016x", upMask);
    -        }
    -        return str.toString();
    -    }
    -
    -    private Stamp createStamp(IntegerStamp other, long newUpperBound, long newLowerBound, long newDownMask, long newUpMask) {
    -        assert getBits() == other.getBits() && unsigned == other.unsigned;
    -        if (newLowerBound > newUpperBound || (newDownMask & (~newUpMask)) != 0) {
    -            return illegal();
    -        } else if (newLowerBound == lowerBound && newUpperBound == upperBound && newDownMask == downMask && newUpMask == upMask) {
    -            return this;
    -        } else if (newLowerBound == other.lowerBound && newUpperBound == other.upperBound && newDownMask == other.downMask && newUpMask == other.upMask) {
    -            return other;
    -        } else {
    -            return new IntegerStamp(getBits(), unsigned, newLowerBound, newUpperBound, newDownMask, newUpMask);
    -        }
    -    }
    -
    -    @Override
    -    public Stamp meet(Stamp otherStamp) {
    -        if (otherStamp == this) {
    -            return this;
    -        }
    -        if (!(otherStamp instanceof IntegerStamp)) {
    -            return StampFactory.illegal(Kind.Illegal);
    -        }
    -        IntegerStamp other = (IntegerStamp) otherStamp;
    -        return createStamp(other, Math.max(upperBound, other.upperBound), Math.min(lowerBound, other.lowerBound), downMask & other.downMask, upMask | other.upMask);
    -    }
    -
    -    @Override
    -    public Stamp join(Stamp otherStamp) {
    -        if (otherStamp == this) {
    -            return this;
    -        }
    -        if (!(otherStamp instanceof IntegerStamp)) {
    -            return StampFactory.illegal(Kind.Illegal);
    -        }
    -        IntegerStamp other = (IntegerStamp) otherStamp;
    -        long newDownMask = downMask | other.downMask;
    -        long newLowerBound = Math.max(lowerBound, other.lowerBound) | newDownMask;
    -        return createStamp(other, Math.min(upperBound, other.upperBound), newLowerBound, newDownMask, upMask & other.upMask);
    -    }
    -
    -    @Override
    -    public boolean isCompatible(Stamp stamp) {
    -        if (this == stamp) {
    -            return true;
    -        }
    -        if (stamp instanceof IntegerStamp) {
    -            IntegerStamp other = (IntegerStamp) stamp;
    -            return getBits() == other.getBits() && unsigned == other.unsigned;
    -        }
    -        return false;
    -    }
    -
    -    @Override
    -    public int hashCode() {
    -        final int prime = 31;
    -        int result = 1;
    -        result = prime * result + super.hashCode();
    -        result = prime * result + (int) (lowerBound ^ (lowerBound >>> 32));
    -        result = prime * result + (int) (upperBound ^ (upperBound >>> 32));
    -        result = prime * result + (int) (downMask ^ (downMask >>> 32));
    -        result = prime * result + (int) (upMask ^ (upMask >>> 32));
    -        return result;
    -    }
    -
    -    @Override
    -    public boolean equals(Object obj) {
    -        if (this == obj) {
    -            return true;
    -        }
    -        if (obj == null || getClass() != obj.getClass() || !super.equals(obj)) {
    -            return false;
    -        }
    -        IntegerStamp other = (IntegerStamp) obj;
    -        if (lowerBound != other.lowerBound || upperBound != other.upperBound || downMask != other.downMask || upMask != other.upMask) {
    -            return false;
    -        }
    -        return true;
    -    }
    -
    -    public static long defaultMask(int bits) {
    -        assert 0 < bits && bits <= 64;
    -        if (bits == 64) {
    -            return 0xffffffffffffffffL;
    -        } else {
    -            return (1L << bits) - 1;
    -        }
    -    }
    -
    -    public static long defaultMinValue(int bits, boolean unsigned) {
    -        if (unsigned) {
    -            return 0;
    -        } else {
    -            return -1L << (bits - 1);
    -        }
    -    }
    -
    -    public static long defaultMaxValue(int bits, boolean unsigned) {
    -        return defaultMask(unsigned ? bits : bits - 1);
    -    }
    -
    -    public static long upMaskFor(int bits, long lowerBound, long upperBound) {
    -        long mask = lowerBound | upperBound;
    -        if (mask == 0) {
    -            return 0;
    -        } else {
    -            return ((-1L) >>> Long.numberOfLeadingZeros(mask)) & defaultMask(bits);
    -        }
    -    }
    -
    -    /**
    -     * Checks if the 2 stamps represent values of the same sign. Returns true if the two stamps are
    -     * both positive of null or if they are both strictly negative
    -     *
    -     * @return true if the two stamps are both positive of null or if they are both strictly
    -     *         negative
    -     */
    -    public static boolean sameSign(IntegerStamp s1, IntegerStamp s2) {
    -        return s1.isPositive() && s2.isPositive() || s1.isStrictlyNegative() && s2.isStrictlyNegative();
    -    }
    -
    -    @Override
    -    public Constant asConstant() {
    -        if (lowerBound == upperBound) {
    -            switch (getBits()) {
    -                case 1:
    -                    return Constant.forBoolean(lowerBound != 0);
    -                case 8:
    -                    return Constant.forByte((byte) lowerBound);
    -                case 16:
    -                    if (unsigned) {
    -                        return Constant.forChar((char) lowerBound);
    -                    } else {
    -                        return Constant.forShort((short) lowerBound);
    -                    }
    -                case 32:
    -                    return Constant.forInt((int) lowerBound);
    -                case 64:
    -                    return Constant.forLong(lowerBound);
    -            }
    -        }
    -        return null;
    -    }
    -}
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/ObjectStamp.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/ObjectStamp.java	Wed Apr 23 15:22:20 2014 +0200
    +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    @@ -1,336 +0,0 @@
    -/*
    - * Copyright (c) 2012, 2014, 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.type;
    -
    -import java.lang.reflect.*;
    -import java.util.*;
    -
    -import com.oracle.graal.api.meta.*;
    -import com.oracle.graal.nodes.*;
    -import com.oracle.graal.nodes.spi.*;
    -
    -public class ObjectStamp extends Stamp {
    -
    -    private final ResolvedJavaType type;
    -    private final boolean exactType;
    -    private final boolean nonNull;
    -    private final boolean alwaysNull;
    -
    -    public ObjectStamp(ResolvedJavaType type, boolean exactType, boolean nonNull, boolean alwaysNull) {
    -        this.type = type;
    -        this.exactType = exactType;
    -        this.nonNull = nonNull;
    -        this.alwaysNull = alwaysNull;
    -    }
    -
    -    @Override
    -    public Stamp unrestricted() {
    -        return StampFactory.object();
    -    }
    -
    -    @Override
    -    public Stamp illegal() {
    -        return new ObjectStamp(null, true, true, false);
    -    }
    -
    -    @Override
    -    public boolean isLegal() {
    -        return !exactType || (type != null && (isConcreteType(type)));
    -    }
    -
    -    @Override
    -    public Kind getStackKind() {
    -        return Kind.Object;
    -    }
    -
    -    @Override
    -    public PlatformKind getPlatformKind(LIRTypeTool tool) {
    -        return tool.getObjectKind();
    -    }
    -
    -    @Override
    -    public ResolvedJavaType javaType(MetaAccessProvider metaAccess) {
    -        if (type != null) {
    -            return type;
    -        }
    -        return metaAccess.lookupJavaType(Object.class);
    -    }
    -
    -    public boolean nonNull() {
    -        return nonNull;
    -    }
    -
    -    public boolean alwaysNull() {
    -        return alwaysNull;
    -    }
    -
    -    public ResolvedJavaType type() {
    -        return type;
    -    }
    -
    -    public boolean isExactType() {
    -        return exactType;
    -    }
    -
    -    @Override
    -    public String toString() {
    -        StringBuilder str = new StringBuilder();
    -        str.append('a');
    -        str.append(nonNull ? "!" : "").append(exactType ? "#" : "").append(' ').append(type == null ? "-" : type.getName()).append(alwaysNull ? " NULL" : "");
    -        return str.toString();
    -    }
    -
    -    @Override
    -    public Stamp meet(Stamp otherStamp) {
    -        if (this == otherStamp) {
    -            return this;
    -        }
    -        if (!(otherStamp instanceof ObjectStamp)) {
    -            return StampFactory.illegal(Kind.Illegal);
    -        }
    -        ObjectStamp other = (ObjectStamp) otherStamp;
    -        ResolvedJavaType meetType;
    -        boolean meetExactType;
    -        boolean meetNonNull;
    -        boolean meetAlwaysNull;
    -        if (other.alwaysNull) {
    -            meetType = type();
    -            meetExactType = exactType;
    -            meetNonNull = false;
    -            meetAlwaysNull = alwaysNull;
    -        } else if (alwaysNull) {
    -            meetType = other.type();
    -            meetExactType = other.exactType;
    -            meetNonNull = false;
    -            meetAlwaysNull = other.alwaysNull;
    -        } else {
    -            meetType = meetTypes(type(), other.type());
    -            meetExactType = exactType && other.exactType;
    -            if (meetExactType && type != null && other.type != null) {
    -                // meeting two valid exact types may result in a non-exact type
    -                meetExactType = Objects.equals(meetType, type) && Objects.equals(meetType, other.type);
    -            }
    -            meetNonNull = nonNull && other.nonNull;
    -            meetAlwaysNull = false;
    -        }
    -
    -        if (Objects.equals(meetType, type) && meetExactType == exactType && meetNonNull == nonNull && meetAlwaysNull == alwaysNull) {
    -            return this;
    -        } else if (Objects.equals(meetType, other.type) && meetExactType == other.exactType && meetNonNull == other.nonNull && meetAlwaysNull == other.alwaysNull) {
    -            return other;
    -        } else {
    -            return new ObjectStamp(meetType, meetExactType, meetNonNull, meetAlwaysNull);
    -        }
    -    }
    -
    -    @Override
    -    public Stamp join(Stamp otherStamp) {
    -        return join0(otherStamp, false);
    -    }
    -
    -    @Override
    -    public boolean isCompatible(Stamp other) {
    -        if (this == other) {
    -            return true;
    -        }
    -        if (other instanceof ObjectStamp) {
    -            return true;
    -        }
    -        return false;
    -    }
    -
    -    /**
    -     * Returns the stamp representing the type of this stamp after a cast to the type represented by
    -     * the {@code to} stamp. While this is very similar to a {@link #join} operation, in the case
    -     * where both types are not obviously related, the cast operation will prefer the type of the
    -     * {@code to} stamp. This is necessary as long as ObjectStamps are not able to accurately
    -     * represent intersection types.
    -     *
    -     * For example when joining the {@link RandomAccess} type with the {@link AbstractList} type,
    -     * without intersection types, this would result in the most generic type ({@link Object} ). For
    -     * this reason, in some cases a {@code castTo} operation is preferable in order to keep at least
    -     * the {@link AbstractList} type.
    -     *
    -     * @param to the stamp this stamp should be casted to
    -     * @return This stamp casted to the {@code to} stamp
    -     */
    -    public Stamp castTo(ObjectStamp to) {
    -        return join0(to, true);
    -    }
    -
    -    private Stamp join0(Stamp otherStamp, boolean castToOther) {
    -        if (this == otherStamp) {
    -            return this;
    -        }
    -        if (!(otherStamp instanceof ObjectStamp)) {
    -            return StampFactory.illegal(Kind.Illegal);
    -        }
    -        ObjectStamp other = (ObjectStamp) otherStamp;
    -        if (!isLegal()) {
    -            return this;
    -        } else if (!other.isLegal()) {
    -            return other;
    -        }
    -
    -        ResolvedJavaType joinType;
    -        boolean joinAlwaysNull = alwaysNull || other.alwaysNull;
    -        boolean joinNonNull = nonNull || other.nonNull;
    -        boolean joinExactType = exactType || other.exactType;
    -        if (Objects.equals(type, other.type)) {
    -            joinType = type;
    -        } else if (type == null && other.type == null) {
    -            joinType = null;
    -        } else if (type == null) {
    -            joinType = other.type;
    -        } else if (other.type == null) {
    -            joinType = type;
    -        } else {
    -            // both types are != null and different
    -            if (type.isAssignableFrom(other.type)) {
    -                joinType = other.type;
    -                if (exactType) {
    -                    joinAlwaysNull = true;
    -                }
    -            } else if (other.type.isAssignableFrom(type)) {
    -                joinType = type;
    -                if (other.exactType) {
    -                    joinAlwaysNull = true;
    -                }
    -            } else {
    -                if (castToOther) {
    -                    joinType = other.type;
    -                    joinExactType = other.exactType;
    -                } else {
    -                    joinType = null;
    -                }
    -                if (joinExactType || (!type.isInterface() && !other.type.isInterface())) {
    -                    joinAlwaysNull = true;
    -                }
    -            }
    -        }
    -        if (joinAlwaysNull) {
    -            joinType = null;
    -            joinExactType = false;
    -        }
    -        if (joinExactType && joinType == null) {
    -            return StampFactory.illegal(Kind.Object);
    -        }
    -        if (joinAlwaysNull && joinNonNull) {
    -            return StampFactory.illegal(Kind.Object);
    -        } else if (joinExactType && !isConcreteType(joinType)) {
    -            return StampFactory.illegal(Kind.Object);
    -        }
    -        if (Objects.equals(joinType, type) && joinExactType == exactType && joinNonNull == nonNull && joinAlwaysNull == alwaysNull) {
    -            return this;
    -        } else if (Objects.equals(joinType, other.type) && joinExactType == other.exactType && joinNonNull == other.nonNull && joinAlwaysNull == other.alwaysNull) {
    -            return other;
    -        } else {
    -            return new ObjectStamp(joinType, joinExactType, joinNonNull, joinAlwaysNull);
    -        }
    -    }
    -
    -    public static boolean isConcreteType(ResolvedJavaType type) {
    -        return !(Modifier.isAbstract(type.getModifiers()) && !type.isArray());
    -    }
    -
    -    private static ResolvedJavaType meetTypes(ResolvedJavaType a, ResolvedJavaType b) {
    -        if (Objects.equals(a, b)) {
    -            return a;
    -        } else if (a == null || b == null) {
    -            return null;
    -        } else {
    -            return a.findLeastCommonAncestor(b);
    -        }
    -    }
    -
    -    @Override
    -    public int hashCode() {
    -        final int prime = 31;
    -        int result = 1;
    -        result = prime * result + (exactType ? 1231 : 1237);
    -        result = prime * result + (nonNull ? 1231 : 1237);
    -        result = prime * result + (alwaysNull ? 1231 : 1237);
    -        result = prime * result + ((type == null) ? 0 : type.hashCode());
    -        return result;
    -    }
    -
    -    @Override
    -    public boolean equals(Object obj) {
    -        if (this == obj) {
    -            return true;
    -        }
    -        if (obj == null || getClass() != obj.getClass()) {
    -            return false;
    -        }
    -        ObjectStamp other = (ObjectStamp) obj;
    -        if (exactType != other.exactType || nonNull != other.nonNull || alwaysNull != other.alwaysNull) {
    -            return false;
    -        }
    -        if (type == null) {
    -            if (other.type != null) {
    -                return false;
    -            }
    -        } else if (!type.equals(other.type)) {
    -            return false;
    -        }
    -        return true;
    -    }
    -
    -    public static boolean isObjectAlwaysNull(ValueNode node) {
    -        return isObjectAlwaysNull(node.stamp());
    -    }
    -
    -    public static boolean isObjectAlwaysNull(Stamp stamp) {
    -        return (stamp instanceof ObjectStamp && ((ObjectStamp) stamp).isLegal() && ((ObjectStamp) stamp).alwaysNull());
    -    }
    -
    -    public static boolean isObjectNonNull(ValueNode node) {
    -        return isObjectNonNull(node.stamp());
    -    }
    -
    -    public static boolean isObjectNonNull(Stamp stamp) {
    -        return stamp instanceof ObjectStamp && ((ObjectStamp) stamp).isLegal() && ((ObjectStamp) stamp).nonNull();
    -    }
    -
    -    public static ResolvedJavaType typeOrNull(ValueNode node) {
    -        return typeOrNull(node.stamp());
    -    }
    -
    -    public static ResolvedJavaType typeOrNull(Stamp stamp) {
    -        if (stamp instanceof ObjectStamp) {
    -            return ((ObjectStamp) stamp).type();
    -        }
    -        return null;
    -    }
    -
    -    public static boolean isExactType(ValueNode node) {
    -        return isExactType(node.stamp());
    -    }
    -
    -    public static boolean isExactType(Stamp stamp) {
    -        if (stamp instanceof ObjectStamp) {
    -            return ((ObjectStamp) stamp).isExactType();
    -        }
    -        return false;
    -    }
    -}
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/PrimitiveStamp.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/PrimitiveStamp.java	Wed Apr 23 15:22:20 2014 +0200
    +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    @@ -1,72 +0,0 @@
    -/*
    - * Copyright (c) 2014, 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.type;
    -
    -import com.oracle.graal.nodes.*;
    -
    -/**
    - * Describes the possible values of a {@link ValueNode} that produces a primitive value as result.
    - */
    -public abstract class PrimitiveStamp extends Stamp {
    -
    -    private final int bits;
    -
    -    protected PrimitiveStamp(int bits) {
    -        this.bits = bits;
    -    }
    -
    -    /**
    -     * The width in bits of the value described by this stamp.
    -     */
    -    public int getBits() {
    -        return bits;
    -    }
    -
    -    public static int getBits(Stamp stamp) {
    -        if (stamp instanceof PrimitiveStamp) {
    -            return ((PrimitiveStamp) stamp).getBits();
    -        } else {
    -            return 0;
    -        }
    -    }
    -
    -    @Override
    -    public int hashCode() {
    -        final int prime = 31;
    -        int result = 1;
    -        result = prime * result + bits;
    -        return result;
    -    }
    -
    -    @Override
    -    public boolean equals(Object obj) {
    -        if (this == obj) {
    -            return true;
    -        }
    -        if (obj instanceof PrimitiveStamp) {
    -            PrimitiveStamp other = (PrimitiveStamp) obj;
    -            return bits == other.bits;
    -        }
    -        return false;
    -    }
    -}
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/Stamp.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/Stamp.java	Wed Apr 23 15:22:20 2014 +0200
    +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    @@ -1,111 +0,0 @@
    -/*
    - * Copyright (c) 2011, 2014, 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.type;
    -
    -import com.oracle.graal.api.meta.*;
    -import com.oracle.graal.nodes.*;
    -import com.oracle.graal.nodes.spi.*;
    -
    -/**
    - * A stamp is the basis for a type system over the nodes in a graph.
    - */
    -public abstract class Stamp {
    -
    -    protected Stamp() {
    -    }
    -
    -    /**
    -     * Returns the type of the stamp, guaranteed to be non-null. In some cases, this requires the
    -     * lookup of class meta data, therefore the {@link MetaAccessProvider} is mandatory.
    -     */
    -    public abstract ResolvedJavaType javaType(MetaAccessProvider metaAccess);
    -
    -    public boolean alwaysDistinct(Stamp other) {
    -        return !join(other).isLegal();
    -    }
    -
    -    /**
    -     * Gets a Java {@link Kind} that can be used to store a value of this stamp on the Java bytecode
    -     * stack. Returns {@link Kind#Illegal} if a value of this stamp can not be stored on the
    -     * bytecode stack.
    -     */
    -    public abstract Kind getStackKind();
    -
    -    /**
    -     * Gets a platform dependent {@link PlatformKind} that can be used to store a value of this
    -     * stamp.
    -     */
    -    public abstract PlatformKind getPlatformKind(LIRTypeTool tool);
    -
    -    /**
    -     * Returns the union of this stamp and the given stamp. Typically used to create stamps for
    -     * {@link ValuePhiNode}s.
    -     *
    -     * @param other The stamp that will enlarge this stamp.
    -     * @return The union of this stamp and the given stamp.
    -     */
    -    public abstract Stamp meet(Stamp other);
    -
    -    /**
    -     * Returns the intersection of this stamp and the given stamp.
    -     *
    -     * @param other The stamp that will tighten this stamp.
    -     * @return The intersection of this stamp and the given stamp.
    -     */
    -    public abstract Stamp join(Stamp other);
    -
    -    /**
    -     * Returns a stamp of the same kind, but allowing the full value range of the kind.
    -     *
    -     * {@link #unrestricted()} is the neutral element of the {@link #join(Stamp)} operation.
    -     */
    -    public abstract Stamp unrestricted();
    -
    -    /**
    -     * Returns a stamp of the same kind, but with no allowed values.
    -     *
    -     * {@link #illegal()} is the neutral element of the {@link #meet(Stamp)} operation.
    -     */
    -    public abstract Stamp illegal();
    -
    -    /**
    -     * Test whether two stamps have the same base type.
    -     */
    -    public abstract boolean isCompatible(Stamp other);
    -
    -    /**
    -     * Test whether this stamp has legal values.
    -     */
    -    public abstract boolean isLegal();
    -
    -    /**
    -     * If this stamp represents a single value, the methods returns this single value. It returns
    -     * null otherwise.
    -     *
    -     * @return the constant corresponding to the single value of this stamp and null if this stamp
    -     *         can represent less or more than one value.
    -     */
    -    public Constant asConstant() {
    -        return null;
    -    }
    -}
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampFactory.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampFactory.java	Wed Apr 23 15:22:20 2014 +0200
    +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    @@ -1,254 +0,0 @@
    -/*
    - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
    - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    - *
    - * This code is free software; you can redistribute it and/or modify it
    - * under the terms of the GNU General Public License version 2 only, as
    - * published by the Free Software Foundation.
    - *
    - * This code is distributed in the hope that it will be useful, but WITHOUT
    - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    - * version 2 for more details (a copy is included in the LICENSE file that
    - * accompanied this code).
    - *
    - * You should have received a copy of the GNU General Public License version
    - * 2 along with this work; if not, write to the Free Software Foundation,
    - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    - *
    - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    - * or visit www.oracle.com if you need additional information or have any
    - * questions.
    - */
    -package com.oracle.graal.nodes.type;
    -
    -import com.oracle.graal.api.meta.*;
    -import com.oracle.graal.graph.*;
    -
    -public class StampFactory {
    -
    -    // JaCoCo Exclude
    -
    -    private static final Stamp[] stampCache = new Stamp[Kind.values().length];
    -    private static final Stamp[] illegalStampCache = new Stamp[Kind.values().length];
    -    private static final Stamp objectStamp = new ObjectStamp(null, false, false, false);
    -    private static final Stamp objectNonNullStamp = new ObjectStamp(null, false, true, false);
    -    private static final Stamp objectAlwaysNullStamp = new ObjectStamp(null, false, false, true);
    -    private static final Stamp nodeIntrinsicStamp = new ObjectStamp(null, false, false, false);
    -    private static final Stamp positiveInt = forInteger(Kind.Int, 0, Integer.MAX_VALUE, 0, Integer.MAX_VALUE);
    -
    -    private static void setCache(Kind kind, Stamp stamp) {
    -        stampCache[kind.ordinal()] = stamp;
    -    }
    -
    -    private static void setIntCache(Kind kind) {
    -        int bits = kind.getStackKind().getBitCount();
    -        long mask;
    -        if (kind.isUnsigned()) {
    -            mask = IntegerStamp.defaultMask(kind.getBitCount());
    -        } else {
    -            mask = IntegerStamp.defaultMask(bits);
    -        }
    -        setCache(kind, new IntegerStamp(bits, false, kind.getMinValue(), kind.getMaxValue(), 0, mask));
    -    }
    -
    -    private static void setFloatCache(Kind kind) {
    -        setCache(kind, new FloatStamp(kind.getBitCount()));
    -    }
    -
    -    static {
    -        setIntCache(Kind.Boolean);
    -        setIntCache(Kind.Byte);
    -        setIntCache(Kind.Short);
    -        setIntCache(Kind.Char);
    -        setIntCache(Kind.Int);
    -        setIntCache(Kind.Long);
    -
    -        setFloatCache(Kind.Float);
    -        setFloatCache(Kind.Double);
    -
    -        setCache(Kind.Object, objectStamp);
    -        setCache(Kind.Void, VoidStamp.getInstance());
    -
    -        for (Kind k : Kind.values()) {
    -            if (stampCache[k.ordinal()] != null) {
    -                illegalStampCache[k.ordinal()] = stampCache[k.ordinal()].illegal();
    -            } else {
    -                illegalStampCache[k.ordinal()] = IllegalStamp.getInstance();
    -            }
    -        }
    -    }
    -
    -    /**
    -     * Return a stamp for a Java kind, as it would be represented on the bytecode stack.
    -     */
    -    public static Stamp forKind(Kind kind) {
    -        assert stampCache[kind.ordinal()] != null : "unexpected forKind(" + kind + ")";
    -        return stampCache[kind.ordinal()];
    -    }
    -
    -    /**
    -     * Return the stamp for the {@code void} type. This will return a singleton instance than can be
    -     * compared using {@code ==}.
    -     */
    -    public static Stamp forVoid() {
    -        return VoidStamp.getInstance();
    -    }
    -
    -    /**
    -     * A stamp used only in the graph of intrinsics, e.g., snippets. It is then replaced by an
    -     * actual stamp when the intrinsic is used, i.e., when the snippet template is instantiated.
    -     */
    -    public static Stamp forNodeIntrinsic() {
    -        return nodeIntrinsicStamp;
    -    }
    -
    -    public static Stamp intValue() {
    -        return forKind(Kind.Int);
    -    }
    -
    -    public static Stamp positiveInt() {
    -        return positiveInt;
    -    }
    -
    -    public static Stamp illegal() {
    -        return illegal(Kind.Illegal);
    -    }
    -
    -    public static Stamp illegal(Kind kind) {
    -        return illegalStampCache[kind.ordinal()];
    -    }
    -
    -    public static IntegerStamp forInteger(Kind kind, long lowerBound, long upperBound, long downMask, long upMask) {
    -        return new IntegerStamp(kind.getBitCount(), kind.isUnsigned(), lowerBound, upperBound, downMask, upMask);
    -    }
    -
    -    public static IntegerStamp forInteger(Kind kind, long lowerBound, long upperBound) {
    -        return forInteger(kind.getBitCount(), kind.isUnsigned(), lowerBound, upperBound);
    -    }
    -
    -    public static IntegerStamp forInteger(int bits, boolean unsigned) {
    -        return new IntegerStamp(bits, unsigned, IntegerStamp.defaultMinValue(bits, unsigned), IntegerStamp.defaultMaxValue(bits, unsigned), 0, IntegerStamp.defaultMask(bits));
    -    }
    -
    -    public static IntegerStamp forInteger(int bits, boolean unsigned, long lowerBound, long upperBound) {
    -        long defaultMask = IntegerStamp.defaultMask(bits);
    -        if (lowerBound == upperBound) {
    -            return new IntegerStamp(bits, unsigned, lowerBound, lowerBound, lowerBound & defaultMask, lowerBound & defaultMask);
    -        }
    -        final long downMask;
    -        final long upMask;
    -        if (lowerBound >= 0) {
    -            int upperBoundLeadingZeros = Long.numberOfLeadingZeros(upperBound);
    -            long differentBits = lowerBound ^ upperBound;
    -            int sameBitCount = Long.numberOfLeadingZeros(differentBits << upperBoundLeadingZeros);
    -
    -            upMask = upperBound | -1L >>> (upperBoundLeadingZeros + sameBitCount);
    -            downMask = upperBound & ~(-1L >>> (upperBoundLeadingZeros + sameBitCount));
    -        } else {
    -            if (upperBound >= 0) {
    -                upMask = defaultMask;
    -                downMask = 0;
    -            } else {
    -                int lowerBoundLeadingOnes = Long.numberOfLeadingZeros(~lowerBound);
    -                long differentBits = lowerBound ^ upperBound;
    -                int sameBitCount = Long.numberOfLeadingZeros(differentBits << lowerBoundLeadingOnes);
    -
    -                upMask = lowerBound | -1L >>> (lowerBoundLeadingOnes + sameBitCount) | ~(-1L >>> lowerBoundLeadingOnes);
    -                downMask = lowerBound & ~(-1L >>> (lowerBoundLeadingOnes + sameBitCount)) | ~(-1L >>> lowerBoundLeadingOnes);
    -            }
    -        }
    -        return new IntegerStamp(bits, unsigned, lowerBound, upperBound, downMask & defaultMask, upMask & defaultMask);
    -    }
    -
    -    public static FloatStamp forFloat(Kind kind, double lowerBound, double upperBound, boolean nonNaN) {
    -        assert kind.isNumericFloat();
    -        return new FloatStamp(kind.getBitCount(), lowerBound, upperBound, nonNaN);
    -    }
    -
    -    public static Stamp forConstant(Constant value) {
    -        Kind kind = value.getKind();
    -        switch (kind) {
    -            case Boolean:
    -            case Byte:
    -            case Char:
    -            case Short:
    -            case Int:
    -            case Long:
    -                long mask = value.asLong() & IntegerStamp.defaultMask(kind.getBitCount());
    -                return forInteger(kind.getStackKind(), value.asLong(), value.asLong(), mask, mask);
    -            case Float:
    -                return forFloat(kind, value.asFloat(), value.asFloat(), !Float.isNaN(value.asFloat()));
    -            case Double:
    -                return forFloat(kind, value.asDouble(), value.asDouble(), !Double.isNaN(value.asDouble()));
    -            case Illegal:
    -                return illegal(Kind.Illegal);
    -            case Object:
    -                if (value.isNull()) {
    -                    return alwaysNull();
    -                } else {
    -                    return objectNonNull();
    -                }
    -            default:
    -                throw new GraalInternalError("unexpected kind: %s", kind);
    -        }
    -    }
    -
    -    public static Stamp forConstant(Constant value, MetaAccessProvider metaAccess) {
    -        assert value.getKind() == Kind.Object;
    -        if (value.getKind() == Kind.Object) {
    -            ResolvedJavaType type = value.isNull() ? null : metaAccess.lookupJavaType(value);
    -            return new ObjectStamp(type, value.isNonNull(), value.isNonNull(), value.isNull());
    -        } else {
    -            throw new GraalInternalError(Kind.Object + " expected, actual kind: %s", value.getKind());
    -        }
    -    }
    -
    -    public static Stamp object() {
    -        return objectStamp;
    -    }
    -
    -    public static Stamp objectNonNull() {
    -        return objectNonNullStamp;
    -    }
    -
    -    public static Stamp alwaysNull() {
    -        return objectAlwaysNullStamp;
    -    }
    -
    -    public static Stamp declared(ResolvedJavaType type) {
    -        return declared(type, false);
    -    }
    -
    -    public static Stamp declaredNonNull(ResolvedJavaType type) {
    -        return declared(type, true);
    -    }
    -
    -    public static Stamp declared(ResolvedJavaType type, boolean nonNull) {
    -        return object(type, false, nonNull);
    -    }
    -
    -    public static Stamp object(ResolvedJavaType type, boolean exactType, boolean nonNull) {
    -        assert type != null;
    -        assert type.getKind() == Kind.Object;
    -        ResolvedJavaType exact = type.asExactType();
    -        if (exact != null) {
    -            assert !exactType || type.equals(exact);
    -            return new ObjectStamp(exact, true, nonNull, false);
    -        } else {
    -            return new ObjectStamp(type, exactType, nonNull, false);
    -        }
    -    }
    -
    -    public static Stamp exactNonNull(ResolvedJavaType type) {
    -        if (ObjectStamp.isConcreteType(type)) {
    -            return new ObjectStamp(type, true, true, false);
    -        } else {
    -            return illegal(Kind.Object);
    -        }
    -    }
    -
    -    public static Stamp exact(ResolvedJavaType type) {
    -        return new ObjectStamp(type, true, false, false);
    -    }
    -}
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampProvider.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampProvider.java	Wed Apr 23 15:22:20 2014 +0200
    +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    @@ -1,28 +0,0 @@
    -/*
    - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
    - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    - *
    - * This code is free software; you can redistribute it and/or modify it
    - * under the terms of the GNU General Public License version 2 only, as
    - * published by the Free Software Foundation.
    - *
    - * This code is distributed in the hope that it will be useful, but WITHOUT
    - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    - * version 2 for more details (a copy is included in the LICENSE file that
    - * accompanied this code).
    - *
    - * You should have received a copy of the GNU General Public License version
    - * 2 along with this work; if not, write to the Free Software Foundation,
    - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    - *
    - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    - * or visit www.oracle.com if you need additional information or have any
    - * questions.
    - */
    -package com.oracle.graal.nodes.type;
    -
    -public interface StampProvider {
    -
    -    Stamp stamp();
    -}
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampTool.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampTool.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampTool.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -25,6 +25,8 @@
     import java.util.*;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
    +import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.calc.*;
     
     /**
    @@ -36,9 +38,9 @@
             if (stamp instanceof IntegerStamp) {
                 IntegerStamp integerStamp = (IntegerStamp) stamp;
                 int bits = integerStamp.getBits();
    -            if (integerStamp.lowerBound() != IntegerStamp.defaultMinValue(bits, false)) {
    +            if (integerStamp.lowerBound() != IntegerStamp.defaultMinValue(bits)) {
                     // TODO(ls) check if the mask calculation is correct...
    -                return StampFactory.forInteger(bits, false, -integerStamp.upperBound(), -integerStamp.lowerBound());
    +                return StampFactory.forInteger(bits, -integerStamp.upperBound(), -integerStamp.lowerBound());
                 }
             } else if (stamp instanceof FloatStamp) {
                 FloatStamp floatStamp = (FloatStamp) stamp;
    @@ -53,8 +55,7 @@
                 IntegerStamp integerStamp = (IntegerStamp) stamp;
                 int bits = integerStamp.getBits();
                 long defaultMask = IntegerStamp.defaultMask(bits);
    -            return new IntegerStamp(bits, integerStamp.isUnsigned(), ~integerStamp.upperBound(), ~integerStamp.lowerBound(), (~integerStamp.upMask()) & defaultMask, (~integerStamp.downMask()) &
    -                            defaultMask);
    +            return new IntegerStamp(bits, ~integerStamp.upperBound(), ~integerStamp.lowerBound(), (~integerStamp.upMask()) & defaultMask, (~integerStamp.downMask()) & defaultMask);
             }
             return stamp.unrestricted();
         }
    @@ -95,45 +96,36 @@
         }
     
         public static Stamp div(IntegerStamp stamp1, IntegerStamp stamp2) {
    -        assert stamp1.getBits() == stamp2.getBits() && stamp1.isUnsigned() == stamp2.isUnsigned();
    +        assert stamp1.getBits() == stamp2.getBits();
             if (stamp2.isStrictlyPositive()) {
                 long lowerBound = stamp1.lowerBound() / stamp2.lowerBound();
                 long upperBound = stamp1.upperBound() / stamp2.lowerBound();
    -            return StampFactory.forInteger(stamp1.getBits(), stamp1.isUnsigned(), lowerBound, upperBound);
    +            return StampFactory.forInteger(stamp1.getBits(), lowerBound, upperBound);
             }
             return stamp1.unrestricted();
         }
     
    -    private static boolean addOverflowsPositively(long x, long y, int bits, boolean unsigned) {
    +    private static boolean addOverflowsPositively(long x, long y, int bits) {
             long result = x + y;
             if (bits == 64) {
    -            if (unsigned) {
    -                return ((x | y) & ~result) < 0;
    -            } else {
    -                return (~x & ~y & result) < 0;
    -            }
    +            return (~x & ~y & result) < 0;
             } else {
    -            return result > IntegerStamp.defaultMaxValue(bits, unsigned);
    +            return result > IntegerStamp.defaultMaxValue(bits);
             }
         }
     
    -    private static boolean addOverflowsNegatively(long x, long y, int bits, boolean unsigned) {
    -        if (unsigned) {
    -            return false;
    -        }
    -
    +    private static boolean addOverflowsNegatively(long x, long y, int bits) {
             long result = x + y;
             if (bits == 64) {
                 return (x & y & ~result) < 0;
             } else {
    -            return result < IntegerStamp.defaultMinValue(bits, unsigned);
    +            return result < IntegerStamp.defaultMinValue(bits);
             }
         }
     
         public static IntegerStamp add(IntegerStamp stamp1, IntegerStamp stamp2) {
             int bits = stamp1.getBits();
    -        boolean unsigned = stamp1.isUnsigned();
    -        assert bits == stamp2.getBits() && unsigned == stamp2.isUnsigned();
    +        assert bits == stamp2.getBits();
     
             if (stamp1.isUnrestricted()) {
                 return stamp1;
    @@ -151,30 +143,23 @@
     
             long lowerBound;
             long upperBound;
    -        boolean lowerOverflowsPositively = addOverflowsPositively(stamp1.lowerBound(), stamp2.lowerBound(), bits, unsigned);
    -        boolean upperOverflowsPositively = addOverflowsPositively(stamp1.upperBound(), stamp2.upperBound(), bits, unsigned);
    -        boolean lowerOverflowsNegatively = addOverflowsNegatively(stamp1.lowerBound(), stamp2.lowerBound(), bits, unsigned);
    -        boolean upperOverflowsNegatively = addOverflowsNegatively(stamp1.upperBound(), stamp2.upperBound(), bits, unsigned);
    +        boolean lowerOverflowsPositively = addOverflowsPositively(stamp1.lowerBound(), stamp2.lowerBound(), bits);
    +        boolean upperOverflowsPositively = addOverflowsPositively(stamp1.upperBound(), stamp2.upperBound(), bits);
    +        boolean lowerOverflowsNegatively = addOverflowsNegatively(stamp1.lowerBound(), stamp2.lowerBound(), bits);
    +        boolean upperOverflowsNegatively = addOverflowsNegatively(stamp1.upperBound(), stamp2.upperBound(), bits);
             if ((lowerOverflowsNegatively && !upperOverflowsNegatively) || (!lowerOverflowsPositively && upperOverflowsPositively)) {
    -            lowerBound = IntegerStamp.defaultMinValue(bits, unsigned);
    -            upperBound = IntegerStamp.defaultMaxValue(bits, unsigned);
    +            lowerBound = IntegerStamp.defaultMinValue(bits);
    +            upperBound = IntegerStamp.defaultMaxValue(bits);
             } else {
    -            lowerBound = (stamp1.lowerBound() + stamp2.lowerBound()) & defaultMask;
    -            upperBound = (stamp1.upperBound() + stamp2.upperBound()) & defaultMask;
    -            if (!unsigned) {
    -                lowerBound = SignExtendNode.signExtend(lowerBound, bits);
    -                upperBound = SignExtendNode.signExtend(upperBound, bits);
    -            }
    +            lowerBound = SignExtendNode.signExtend((stamp1.lowerBound() + stamp2.lowerBound()) & defaultMask, bits);
    +            upperBound = SignExtendNode.signExtend((stamp1.upperBound() + stamp2.upperBound()) & defaultMask, bits);
             }
    -        IntegerStamp limit = StampFactory.forInteger(bits, unsigned, lowerBound, upperBound);
    +        IntegerStamp limit = StampFactory.forInteger(bits, lowerBound, upperBound);
             newUpMask &= limit.upMask();
    -        upperBound &= newUpMask;
    -        if (!unsigned) {
    -            upperBound = SignExtendNode.signExtend(upperBound, bits);
    -        }
    +        upperBound = SignExtendNode.signExtend(upperBound & newUpMask, bits);
             newDownMask |= limit.downMask();
             lowerBound |= newDownMask;
    -        return new IntegerStamp(bits, unsigned, lowerBound, upperBound, newDownMask, newUpMask);
    +        return new IntegerStamp(bits, lowerBound, upperBound, newDownMask, newUpMask);
         }
     
         public static Stamp sub(IntegerStamp stamp1, IntegerStamp stamp2) {
    @@ -195,11 +180,11 @@
                 upperBound = upMask;
             } else {
                 lowerBound = downMask | (-1L << (bits - 1));
    -            upperBound = IntegerStamp.defaultMaxValue(bits, false) & upMask;
    +            upperBound = IntegerStamp.defaultMaxValue(bits) & upMask;
             }
             lowerBound = IntegerConvertNode.convert(lowerBound, bits, false);
             upperBound = IntegerConvertNode.convert(upperBound, bits, false);
    -        return new IntegerStamp(bits, false, lowerBound, upperBound, downMask, upMask);
    +        return new IntegerStamp(bits, lowerBound, upperBound, downMask, upMask);
         }
     
         public static Stamp and(Stamp stamp1, Stamp stamp2) {
    @@ -265,7 +250,7 @@
                         lowerBound = value.lowerBound() >>> shiftCount;
                         upperBound = value.upperBound() >>> shiftCount;
                     }
    -                return new IntegerStamp(bits, value.isUnsigned(), lowerBound, upperBound, downMask, upMask);
    +                return new IntegerStamp(bits, lowerBound, upperBound, downMask, upMask);
                 }
             }
             long mask = IntegerStamp.upMaskFor(bits, value.lowerBound(), value.upperBound());
    @@ -312,17 +297,7 @@
                 long downMask = SignExtendNode.signExtend(inputStamp.downMask(), inputBits) & defaultMask;
                 long upMask = SignExtendNode.signExtend(inputStamp.upMask(), inputBits) & defaultMask;
     
    -            long lowerBound;
    -            long upperBound;
    -            if (inputStamp.isUnsigned()) {
    -                lowerBound = SignExtendNode.signExtend(inputStamp.lowerBound(), inputBits) & defaultMask;
    -                upperBound = SignExtendNode.signExtend(inputStamp.upperBound(), inputBits) & defaultMask;
    -            } else {
    -                lowerBound = inputStamp.lowerBound();
    -                upperBound = inputStamp.upperBound();
    -            }
    -
    -            return new IntegerStamp(resultBits, inputStamp.isUnsigned(), lowerBound, upperBound, downMask, upMask);
    +            return new IntegerStamp(resultBits, inputStamp.lowerBound(), inputStamp.upperBound(), downMask, upMask);
             } else {
                 return input.illegal();
             }
    @@ -346,7 +321,7 @@
                 long lowerBound = ZeroExtendNode.zeroExtend(inputStamp.lowerBound(), inputBits);
                 long upperBound = ZeroExtendNode.zeroExtend(inputStamp.upperBound(), inputBits);
     
    -            return new IntegerStamp(resultBits, inputStamp.isUnsigned(), lowerBound, upperBound, downMask, upMask);
    +            return new IntegerStamp(resultBits, lowerBound, upperBound, downMask, upMask);
             } else {
                 return input.illegal();
             }
    @@ -355,7 +330,6 @@
         public static Stamp narrowingConversion(Stamp input, int resultBits) {
             if (input instanceof IntegerStamp) {
                 IntegerStamp inputStamp = (IntegerStamp) input;
    -            boolean unsigned = inputStamp.isUnsigned();
                 int inputBits = inputStamp.getBits();
                 assert resultBits <= inputBits;
                 if (resultBits == inputBits) {
    @@ -363,28 +337,24 @@
                 }
     
                 final long upperBound;
    -            if (inputStamp.lowerBound() < IntegerStamp.defaultMinValue(resultBits, unsigned)) {
    -                upperBound = IntegerStamp.defaultMaxValue(resultBits, unsigned);
    +            if (inputStamp.lowerBound() < IntegerStamp.defaultMinValue(resultBits)) {
    +                upperBound = IntegerStamp.defaultMaxValue(resultBits);
                 } else {
    -                upperBound = saturate(inputStamp.upperBound(), resultBits, unsigned);
    +                upperBound = saturate(inputStamp.upperBound(), resultBits);
                 }
                 final long lowerBound;
    -            if (inputStamp.upperBound() > IntegerStamp.defaultMaxValue(resultBits, unsigned)) {
    -                lowerBound = IntegerStamp.defaultMinValue(resultBits, unsigned);
    +            if (inputStamp.upperBound() > IntegerStamp.defaultMaxValue(resultBits)) {
    +                lowerBound = IntegerStamp.defaultMinValue(resultBits);
                 } else {
    -                lowerBound = saturate(inputStamp.lowerBound(), resultBits, unsigned);
    +                lowerBound = saturate(inputStamp.lowerBound(), resultBits);
                 }
     
                 long defaultMask = IntegerStamp.defaultMask(resultBits);
                 long newDownMask = inputStamp.downMask() & defaultMask;
                 long newUpMask = inputStamp.upMask() & defaultMask;
    -            long newLowerBound = (lowerBound | newDownMask) & newUpMask;
    -            long newUpperBound = (upperBound | newDownMask) & newUpMask;
    -            if (!unsigned) {
    -                newLowerBound = SignExtendNode.signExtend(newLowerBound, resultBits);
    -                newUpperBound = SignExtendNode.signExtend(newUpperBound, resultBits);
    -            }
    -            return new IntegerStamp(resultBits, unsigned, newLowerBound, newUpperBound, newDownMask, newUpMask);
    +            long newLowerBound = SignExtendNode.signExtend((lowerBound | newDownMask) & newUpMask, resultBits);
    +            long newUpperBound = SignExtendNode.signExtend((upperBound | newDownMask) & newUpMask, resultBits);
    +            return new IntegerStamp(resultBits, newLowerBound, newUpperBound, newDownMask, newUpMask);
             } else {
                 return input.illegal();
             }
    @@ -409,7 +379,7 @@
             long intMask = IntegerStamp.defaultMask(32);
             long newUpMask = signExtend(fromStamp.upMask() & defaultMask, toKind) & intMask;
             long newDownMask = signExtend(fromStamp.downMask() & defaultMask, toKind) & intMask;
    -        return new IntegerStamp(toKind.getStackKind().getBitCount(), false, (int) ((lowerBound | newDownMask) & newUpMask), (int) ((upperBound | newDownMask) & newUpMask), newDownMask, newUpMask);
    +        return new IntegerStamp(toKind.getStackKind().getBitCount(), (int) ((lowerBound | newDownMask) & newUpMask), (int) ((upperBound | newDownMask) & newUpMask), newDownMask, newUpMask);
         }
     
         private static long signExtend(long value, Kind valueKind) {
    @@ -420,13 +390,13 @@
             }
         }
     
    -    private static long saturate(long v, int bits, boolean unsigned) {
    +    private static long saturate(long v, int bits) {
             if (bits < 64) {
    -            long max = IntegerStamp.defaultMaxValue(bits, unsigned);
    +            long max = IntegerStamp.defaultMaxValue(bits);
                 if (v > max) {
                     return max;
                 }
    -            long min = IntegerStamp.defaultMinValue(bits, unsigned);
    +            long min = IntegerStamp.defaultMinValue(bits);
                 if (v < min) {
                     return min;
                 }
    @@ -471,15 +441,121 @@
                     }
                     // If the test succeeds then this proves that n is at greater than c so the bounds
                     // are [c+1..-n.upperBound)].
    -                return StampFactory.forInteger(x.getBits(), false, x.lowerBound() + 1, y.upperBound());
    +                return StampFactory.forInteger(x.getBits(), x.lowerBound() + 1, y.upperBound());
                 }
                 return null;
             }
             // n <| c, where c is a strictly positive constant
             if (y.lowerBound() == y.upperBound() && y.isStrictlyPositive()) {
                 // The test proves that n is positive and less than c, [0..c-1]
    -            return StampFactory.forInteger(y.getBits(), false, 0, y.lowerBound() - 1);
    +            return StampFactory.forInteger(y.getBits(), 0, y.lowerBound() - 1);
             }
             return null;
         }
    +
    +    /**
    +     * Checks whether this {@link ValueNode} represents a {@linkplain Stamp#isLegal() legal} Object
    +     * value which is known to be always null.
    +     *
    +     * @param node the node to check
    +     * @return true if this node represents a legal object value which is known to be always null
    +     */
    +    public static boolean isObjectAlwaysNull(ValueNode node) {
    +        return isObjectAlwaysNull(node.stamp());
    +    }
    +
    +    /**
    +     * Checks whether this {@link Stamp} represents a {@linkplain Stamp#isLegal() legal} Object
    +     * stamp whose values are known to be always null.
    +     *
    +     * @param stamp the stamp to check
    +     * @return true if this stamp represents a legal object stamp whose values are known to be
    +     *         always null
    +     */
    +    public static boolean isObjectAlwaysNull(Stamp stamp) {
    +        if (stamp instanceof ObjectStamp && stamp.isLegal()) {
    +            return ((ObjectStamp) stamp).alwaysNull();
    +        }
    +        return false;
    +    }
    +
    +    /**
    +     * Checks whether this {@link ValueNode} represents a {@linkplain Stamp#isLegal() legal} Object
    +     * value which is known to never be null.
    +     *
    +     * @param node the node to check
    +     * @return true if this node represents a legal object value which is known to never be null
    +     */
    +    public static boolean isObjectNonNull(ValueNode node) {
    +        return isObjectNonNull(node.stamp());
    +    }
    +
    +    /**
    +     * Checks whether this {@link Stamp} represents a {@linkplain Stamp#isLegal() legal} Object
    +     * stamp whose values known to be always null.
    +     *
    +     * @param stamp the stamp to check
    +     * @return true if this stamp represents a legal object stamp whose values are known to be
    +     *         always null
    +     */
    +    public static boolean isObjectNonNull(Stamp stamp) {
    +        if (stamp instanceof ObjectStamp && stamp.isLegal()) {
    +            return ((ObjectStamp) stamp).nonNull();
    +        }
    +        return false;
    +    }
    +
    +    /**
    +     * Returns the {@linkplain ResolvedJavaType java type} this {@linkplain ValueNode} has if it is
    +     * a {@linkplain Stamp#isLegal() legal} Object value.
    +     *
    +     * @param node the node to check
    +     * @return the javat type this value has if it is a legal Object type, null otherwise
    +     */
    +    public static ResolvedJavaType typeOrNull(ValueNode node) {
    +        return typeOrNull(node.stamp());
    +    }
    +
    +    /**
    +     * Returns the {@linkplain ResolvedJavaType java type} this {@linkplain Stamp} has if it is a
    +     * {@linkplain Stamp#isLegal() legal} Object stamp.
    +     *
    +     * @param stamp the stamp to check
    +     * @return the java type this stamp has if it is a legal Object stamp, null otherwise
    +     */
    +    public static ResolvedJavaType typeOrNull(Stamp stamp) {
    +        if (stamp instanceof ObjectStamp && stamp.isLegal()) {
    +            return ((ObjectStamp) stamp).type();
    +        }
    +        return null;
    +    }
    +
    +    /**
    +     * Checks whether this {@link ValueNode} represents a {@linkplain Stamp#isLegal() legal} Object
    +     * value whose java type is known exactly. If this method returns true then the
    +     * {@linkplain ResolvedJavaType java type} returned by {@link #typeOrNull(ValueNode)} is the
    +     * concrete dynamic/runtime java type of this value.
    +     *
    +     * @param node the node to check
    +     * @return true if this node represents a legal object value whose java type is known exactly
    +     */
    +    public static boolean isExactType(ValueNode node) {
    +        return isExactType(node.stamp());
    +    }
    +
    +    /**
    +     * Checks whether this {@link Stamp} represents a {@linkplain Stamp#isLegal() legal} Object
    +     * stamp whose {@linkplain ResolvedJavaType java type} is known exactly. If this method returns
    +     * true then the java type returned by {@link #typeOrNull(Stamp)} is the only concrete
    +     * dynamic/runtime java type possible for values of this stamp.
    +     *
    +     * @param stamp the stamp to check
    +     * @return true if this node represents a legal object stamp whose java type is known exactly
    +     */
    +    public static boolean isExactType(Stamp stamp) {
    +        if (stamp instanceof ObjectStamp && stamp.isLegal()) {
    +            return ((ObjectStamp) stamp).isExactType();
    +        }
    +        return false;
    +    }
     }
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/VoidStamp.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/VoidStamp.java	Wed Apr 23 15:22:20 2014 +0200
    +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    @@ -1,110 +0,0 @@
    -/*
    - * Copyright (c) 2014, 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.type;
    -
    -import com.oracle.graal.api.meta.*;
    -import com.oracle.graal.graph.*;
    -import com.oracle.graal.nodes.spi.*;
    -
    -/**
    - * Singleton stamp representing the value of type {@code void}.
    - */
    -public final class VoidStamp extends Stamp {
    -
    -    private VoidStamp() {
    -    }
    -
    -    @Override
    -    public Stamp unrestricted() {
    -        return this;
    -    }
    -
    -    @Override
    -    public Kind getStackKind() {
    -        return Kind.Void;
    -    }
    -
    -    @Override
    -    public PlatformKind getPlatformKind(LIRTypeTool tool) {
    -        throw GraalInternalError.shouldNotReachHere("void stamp has no value");
    -    }
    -
    -    @Override
    -    public ResolvedJavaType javaType(MetaAccessProvider metaAccess) {
    -        return metaAccess.lookupJavaType(Void.TYPE);
    -    }
    -
    -    @Override
    -    public String toString() {
    -        return "void";
    -    }
    -
    -    @Override
    -    public boolean alwaysDistinct(Stamp other) {
    -        return this != other;
    -    }
    -
    -    @Override
    -    public Stamp meet(Stamp other) {
    -        if (other instanceof IllegalStamp) {
    -            return other.join(this);
    -        }
    -        if (this == other) {
    -            return this;
    -        }
    -        return StampFactory.illegal(Kind.Illegal);
    -    }
    -
    -    @Override
    -    public Stamp join(Stamp other) {
    -        if (other instanceof IllegalStamp) {
    -            return other.join(this);
    -        }
    -        if (this == other) {
    -            return this;
    -        }
    -        return StampFactory.illegal(Kind.Illegal);
    -    }
    -
    -    @Override
    -    public boolean isCompatible(Stamp stamp) {
    -        return this == stamp;
    -    }
    -
    -    @Override
    -    public Stamp illegal() {
    -        // there is no illegal void stamp
    -        return this;
    -    }
    -
    -    @Override
    -    public boolean isLegal() {
    -        return true;
    -    }
    -
    -    private static VoidStamp instance = new VoidStamp();
    -
    -    static VoidStamp getInstance() {
    -        return instance;
    -    }
    -}
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/ComputeImmediateDominator.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/ComputeImmediateDominator.java	Wed Apr 23 15:22:20 2014 +0200
    +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    @@ -1,262 +0,0 @@
    -/*
    - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
    - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    - *
    - * This code is free software; you can redistribute it and/or modify it
    - * under the terms of the GNU General Public License version 2 only, as
    - * published by the Free Software Foundation.
    - *
    - * This code is distributed in the hope that it will be useful, but WITHOUT
    - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    - * version 2 for more details (a copy is included in the LICENSE file that
    - * accompanied this code).
    - *
    - * You should have received a copy of the GNU General Public License version
    - * 2 along with this work; if not, write to the Free Software Foundation,
    - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    - *
    - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    - * or visit www.oracle.com if you need additional information or have any
    - * questions.
    - */
    -package com.oracle.graal.nodes.util;
    -
    -import java.util.*;
    -
    -import com.oracle.graal.graph.*;
    -import com.oracle.graal.nodes.*;
    -
    -public final class ComputeImmediateDominator {
    -
    -    private final MergeNode dominated;
    -    private final Queue toExplore;
    -    private final Queue speculativeExplore;
    -    private final NodeMap infoMap;
    -    private final DominatorInfo fullInfo;
    -    private FixedNode dominator;
    -    private int nextBit = 1;
    -
    -    public ComputeImmediateDominator(MergeNode dominated) {
    -        this.dominated = dominated;
    -        this.toExplore = new LinkedList<>();
    -        this.speculativeExplore = new LinkedList<>();
    -        this.infoMap = dominated.graph().createNodeMap();
    -        fullInfo = new DominatorInfo(dominated, true);
    -
    -        this.processMerge(dominated, fullInfo);
    -        if (toExplore.size() == 1) {
    -            dominator = toExplore.remove();
    -        }
    -    }
    -
    -    public FixedNode compute() {
    -        try {
    -            while (dominator == null && (!toExplore.isEmpty() || !speculativeExplore.isEmpty())) {
    -                while (!toExplore.isEmpty()) {
    -                    exploreUp(toExplore.remove());
    -                    if (dominator != null) {
    -                        return dominator;
    -                    }
    -                }
    -                exploreUp(speculativeExplore.remove());
    -            }
    -            return dominator;
    -        } catch (Throwable t) {
    -            throw new GraalInternalError(t).addContext("Could not find a dominator").addContext(dominated);
    -        }
    -    }
    -
    -    private void exploreUp(FixedNode from) {
    -        FixedNode p = from;
    -        DominatorInfo info = infoMap.get(from);
    -        if (info.isExplored()) {
    -            return;
    -        }
    -        // TTY.println("exploreUp(" + from + ") with " + info);
    -        info.setExplored();
    -        while (p != null) {
    -            if (p instanceof MergeNode) {
    -                processMerge((MergeNode) p, info);
    -                p = null;
    -            } else if (p instanceof ControlSplitNode) {
    -                processControlSplit((ControlSplitNode) p, info);
    -                p = null;
    -            } else {
    -                p = (FixedNode) p.predecessor();
    -            }
    -        }
    -    }
    -
    -    private void processControlSplit(ControlSplitNode cs, DominatorInfo info) {
    -        // TTY.println("processControlSplit(" + cs + ", " + info + ")");
    -        DominatorInfo csInfo = infoMap.get(cs);
    -        if (csInfo == null) {
    -            csInfo = new DominatorInfo(cs, false);
    -            infoMap.set(cs, csInfo);
    -        }
    -        csInfo.add(info);
    -        FixedNode next = (FixedNode) cs.predecessor();
    -        if (checkControlSplitInfo(csInfo)) {
    -            return;
    -        }
    -        if (csInfo.isExplored()) {
    -            // TTY.println("  Already explored, propagate update");
    -            propagateUpdate(csInfo);
    -        } else {
    -            if (csInfo.parentCount() == cs.successors().count()) { // all paths leading to this CS
    -                                                                   // have been explored
    -                // TTY.println("  All parents explored, Enqueue");
    -                toExplore.add(next);
    -                speculativeExplore.remove(next);
    -            } else {
    -                // TTY.println("  Not all parents explored : Enqueue speculative");
    -                speculativeExplore.add(next);
    -            }
    -        }
    -        infoMap.set(next, csInfo);
    -    }
    -
    -    private boolean propagateUpdate(DominatorInfo di) {
    -        // TTY.println("   propagateUpdate(" + di + ")");
    -        for (DominatorInfo child : di.children()) {
    -            // TTY.println("      add to child " + child);
    -            if (child.add(di, false)) {
    -                if (child.equals(fullInfo)) {
    -                    // TTY.println("   Found DOM!");
    -                    dominator = child.node();
    -                    return true;
    -                }
    -                if (propagateUpdate(child)) {
    -                    return true;
    -                }
    -            }
    -        }
    -        return false;
    -    }
    -
    -    private boolean checkControlSplitInfo(DominatorInfo di) {
    -        // TTY.println("   checkControlSplitInfo(" + di + ")");
    -        if (di.equals(fullInfo)) {
    -            dominator = di.node();
    -            // TTY.println("   Found DOM!");
    -            return true;
    -        }
    -        return false;
    -    }
    -
    -    private void processMerge(MergeNode merge, DominatorInfo info) {
    -        // TTY.println("processMerge(" + merge + ", " + info + ")");
    -        for (AbstractEndNode end : merge.cfgPredecessors()) {
    -            toExplore.add(end);
    -            infoMap.set(end, info.createChild(end));
    -            // TTY.println("  Enqueue end : " + end + " with " + infoMap.get(end));
    -        }
    -    }
    -
    -    private class DominatorInfo {
    -
    -        private final FixedNode node;
    -        private final BitSet bits;
    -        private final BitSet ownBits;
    -        private final Collection children;
    -        private final Collection parents;
    -        private boolean explored;
    -
    -        public DominatorInfo(FixedNode node, boolean full) {
    -            this.node = node;
    -            this.bits = new BitSet();
    -            this.ownBits = new BitSet();
    -            this.children = new ArrayList<>(2);
    -            this.parents = new ArrayList<>(2);
    -            if (full) {
    -                addOwnBits(0);
    -            }
    -        }
    -
    -        public boolean isExplored() {
    -            return explored;
    -        }
    -
    -        public void setExplored() {
    -            explored = true;
    -        }
    -
    -        public DominatorInfo createChild(FixedNode childNode) {
    -            DominatorInfo di = new DominatorInfo(childNode, false);
    -            di.bits.or(bits);
    -            di.ownBits.or(ownBits);
    -            if (!children.isEmpty() || di.ownBits.isEmpty()) {
    -                int newBit = nextBit++;
    -                di.bits.xor(ownBits);
    -                di.bits.set(newBit);
    -                di.ownBits.clear();
    -                di.ownBits.set(newBit);
    -                addOwnBits(newBit);
    -            }
    -            children.add(di);
    -            di.parents.add(this);
    -            return di;
    -        }
    -
    -        private void addOwnBits(int newBit) {
    -            if (!bits.get(newBit)) {
    -                ownBits.set(newBit);
    -                bits.set(newBit);
    -                for (DominatorInfo parent : parents) {
    -                    parent.addOwnBits(newBit);
    -                }
    -            }
    -        }
    -
    -        public boolean add(DominatorInfo i) {
    -            return add(i, true);
    -        }
    -
    -        public boolean add(DominatorInfo i, boolean addParent) {
    -            boolean ret = true;
    -            if (addParent) {
    -                parents.add(i);
    -                i.children.add(this);
    -                bits.or(i.bits);
    -            } else {
    -                BitSet newBits = (BitSet) i.bits.clone();
    -                newBits.andNot(bits);
    -                newBits.andNot(i.ownBits);
    -                ret = !newBits.isEmpty();
    -                bits.or(newBits);
    -            }
    -            return ret;
    -        }
    -
    -        public int parentCount() {
    -            return parents.size();
    -        }
    -
    -        public FixedNode node() {
    -            return node;
    -        }
    -
    -        public Collection children() {
    -            return children;
    -        }
    -
    -        @Override
    -        public boolean equals(Object obj) {
    -            if (!(obj instanceof DominatorInfo)) {
    -                return false;
    -            }
    -            return ((DominatorInfo) obj).bits.equals(bits);
    -        }
    -
    -        @Override
    -        public String toString() {
    -            return bits + " (o" + ownBits + ") " + node;
    -        }
    -
    -        @Override
    -        public int hashCode() {
    -            return bits.hashCode();
    -        }
    -    }
    -}
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/GraphUtil.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/GraphUtil.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/GraphUtil.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -38,7 +38,6 @@
     
             @Override
             public final boolean apply(Node n) {
    -            // isA(FloatingNode.class).or(VirtualState.class).or(CallTargetNode.class)
                 return n instanceof FloatingNode || n instanceof VirtualState || n instanceof CallTargetNode;
             }
         };
    @@ -138,6 +137,11 @@
         }
     
         public static void removeFixedWithUnusedInputs(FixedWithNextNode fixed) {
    +        if (fixed instanceof StateSplit) {
    +            FrameState stateAfter = ((StateSplit) fixed).stateAfter();
    +            ((StateSplit) fixed).setStateAfter(null);
    +            killWithUnusedFloatingInputs(stateAfter);
    +        }
             FixedNode next = fixed.next();
             fixed.setNext(null);
             fixed.replaceAtPredecessor(next);
    @@ -164,7 +168,7 @@
         }
     
         public static void checkRedundantProxy(ProxyNode vpn) {
    -        AbstractBeginNode proxyPoint = vpn.proxyPoint();
    +        BeginNode proxyPoint = vpn.proxyPoint();
             if (proxyPoint instanceof LoopExitNode) {
                 LoopExitNode exit = (LoopExitNode) proxyPoint;
                 LoopBeginNode loopBegin = exit.loopBegin();
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/NodeIterators.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/NodeIterators.java	Wed Apr 23 15:22:20 2014 +0200
    +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    @@ -1,56 +0,0 @@
    -/*
    - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
    - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    - *
    - * This code is free software; you can redistribute it and/or modify it
    - * under the terms of the GNU General Public License version 2 only, as
    - * published by the Free Software Foundation.
    - *
    - * This code is distributed in the hope that it will be useful, but WITHOUT
    - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    - * version 2 for more details (a copy is included in the LICENSE file that
    - * accompanied this code).
    - *
    - * You should have received a copy of the GNU General Public License version
    - * 2 along with this work; if not, write to the Free Software Foundation,
    - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    - *
    - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    - * or visit www.oracle.com if you need additional information or have any
    - * questions.
    - */
    -package com.oracle.graal.nodes.util;
    -
    -import java.util.*;
    -
    -import com.oracle.graal.graph.iterators.*;
    -import com.oracle.graal.nodes.*;
    -
    -public class NodeIterators {
    -
    -    public static NodeIterable dominators(final FixedNode n) {
    -        return new AbstractNodeIterable() {
    -
    -            @Override
    -            public Iterator iterator() {
    -                return new NodeIterator() {
    -
    -                    FixedNode p = n;
    -
    -                    @Override
    -                    protected void forward() {
    -                        if (current == null) {
    -                            if (p instanceof MergeNode) {
    -                                current = new ComputeImmediateDominator((MergeNode) p).compute();
    -                            } else {
    -                                current = (FixedNode) p.predecessor();
    -                            }
    -                            p = current;
    -                        }
    -                    }
    -                };
    -            }
    -        };
    -    }
    -}
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/TreeIterators.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/TreeIterators.java	Wed Apr 23 15:22:20 2014 +0200
    +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    @@ -1,68 +0,0 @@
    -/*
    - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
    - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    - *
    - * This code is free software; you can redistribute it and/or modify it
    - * under the terms of the GNU General Public License version 2 only, as
    - * published by the Free Software Foundation.
    - *
    - * This code is distributed in the hope that it will be useful, but WITHOUT
    - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    - * version 2 for more details (a copy is included in the LICENSE file that
    - * accompanied this code).
    - *
    - * You should have received a copy of the GNU General Public License version
    - * 2 along with this work; if not, write to the Free Software Foundation,
    - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    - *
    - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    - * or visit www.oracle.com if you need additional information or have any
    - * questions.
    - */
    -package com.oracle.graal.nodes.util;
    -
    -import java.util.*;
    -
    -public class TreeIterators {
    -
    -    public abstract static class PrefixTreeIterator implements Iterator {
    -
    -        private Deque stack = new LinkedList<>();
    -
    -        public PrefixTreeIterator(T root) {
    -            stack.push(root);
    -        }
    -
    -        public PrefixTreeIterator(Iterable roots) {
    -            for (T root : roots) {
    -                stack.addLast(root);
    -            }
    -        }
    -
    -        @Override
    -        public boolean hasNext() {
    -            return !stack.isEmpty();
    -        }
    -
    -        @Override
    -        public T next() {
    -            T top = stack.pop();
    -            LinkedList list = new LinkedList<>();
    -            for (T child : children(top)) {
    -                list.addFirst(child);
    -            }
    -            for (T child : list) {
    -                stack.push(child);
    -            }
    -            return top;
    -        }
    -
    -        @Override
    -        public void remove() {
    -            throw new UnsupportedOperationException();
    -        }
    -
    -        protected abstract Iterable children(T node);
    -    }
    -}
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/AllocatedObjectNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/AllocatedObjectNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/AllocatedObjectNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,11 +22,11 @@
      */
     package com.oracle.graal.nodes.virtual;
     
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.calc.*;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
     
     /**
      * Selects one object from a {@link CommitAllocationNode}. The object is identified by its
    @@ -35,7 +35,7 @@
     public class AllocatedObjectNode extends FloatingNode implements Virtualizable, ArrayLengthProvider {
     
         @Input private VirtualObjectNode virtualObject;
    -    @Input(InputType.Association) private CommitAllocationNode commit;
    +    @Input(InputType.Extension) private CommitAllocationNode commit;
     
         public AllocatedObjectNode(VirtualObjectNode virtualObject) {
             super(StampFactory.exactNonNull(virtualObject.type()));
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/CommitAllocationNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/CommitAllocationNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/CommitAllocationNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -25,14 +25,14 @@
     import java.util.*;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.graph.spi.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.java.*;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
     
    -@NodeInfo(nameTemplate = "Alloc {i#virtualObjects}", allowedUsageTypes = {InputType.Association})
    +@NodeInfo(nameTemplate = "Alloc {i#virtualObjects}", allowedUsageTypes = {InputType.Extension})
     public final class CommitAllocationNode extends FixedWithNextNode implements VirtualizableAllocation, Lowerable, Simplifiable {
     
         @Input private final NodeInputList virtualObjects = new NodeInputList<>(this);
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualObjectNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualObjectNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualObjectNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,10 +23,10 @@
     package com.oracle.graal.nodes.virtual;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
     
     public abstract class VirtualObjectNode extends ValueNode implements LIRLowerable, IterableNodeType {
     
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.options/src/com/oracle/graal/options/OptionDescriptor.java
    --- a/graal/com.oracle.graal.options/src/com/oracle/graal/options/OptionDescriptor.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.options/src/com/oracle/graal/options/OptionDescriptor.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -29,13 +29,13 @@
     public class OptionDescriptor {
     
         protected final String name;
    -    protected final Class type;
    +    protected final Class type;
         protected final String help;
         protected final OptionValue option;
         protected final Class declaringClass;
         protected final String fieldName;
     
    -    public OptionDescriptor(String name, Class type, String help, Class declaringClass, String fieldName, OptionValue option) {
    +    public OptionDescriptor(String name, Class type, String help, Class declaringClass, String fieldName, OptionValue option) {
             this.name = name;
             this.type = type;
             this.help = help;
    @@ -48,7 +48,7 @@
         /**
          * Gets the type of values stored in the option.
          */
    -    public Class getType() {
    +    public Class getType() {
             return type;
         }
     
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.options/src/com/oracle/graal/options/OptionProcessor.java
    --- a/graal/com.oracle.graal.options/src/com/oracle/graal/options/OptionProcessor.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.options/src/com/oracle/graal/options/OptionProcessor.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -37,7 +37,7 @@
      * Processes static fields annotated with {@link Option}. An {@link Options} service is generated
      * for each top level class containing at least one such field. These service objects can be
      * retrieved as follows:
    - * 
    + *
      * 
      * ServiceLoader<Options> sl = ServiceLoader.loadInstalled(Options.class);
      * for (OptionDescriptor desc : sl) {
    @@ -184,11 +184,11 @@
                 out.println("        return options.iterator();");
                 out.println("    }");
                 if (needPrivateFieldAccessor) {
    -                out.println("    private static " + OptionValue.class.getSimpleName() + " field(Class declaringClass, String fieldName) {");
    +                out.println("    private static " + OptionValue.class.getSimpleName() + " field(Class declaringClass, String fieldName) {");
                     out.println("        try {");
                     out.println("            java.lang.reflect.Field field = declaringClass.getDeclaredField(fieldName);");
                     out.println("            field.setAccessible(true);");
    -                out.println("            return (" + OptionValue.class.getSimpleName() + ") field.get(null);");
    +                out.println("            return (" + OptionValue.class.getSimpleName() + ") field.get(null);");
                     out.println("        } catch (Exception e) {");
                     out.println("            throw (InternalError) new InternalError().initCause(e);");
                     out.println("        }");
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.options/src/com/oracle/graal/options/OptionValue.java
    --- a/graal/com.oracle.graal.options/src/com/oracle/graal/options/OptionValue.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.options/src/com/oracle/graal/options/OptionValue.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -139,7 +139,7 @@
     
         private long reads;
         private OptionValue next;
    -    private static OptionValue head;
    +    private static OptionValue head;
     
         private static final boolean ShowReadsHistogram = Boolean.getBoolean("graal.showOptionValueReadsHistogram");
     
    @@ -252,7 +252,7 @@
          * {@link OptionValue#override(OptionValue, Object)} or {@link OptionValue#override(Map)}.
          */
         public abstract static class OverrideScope implements AutoCloseable {
    -        abstract void addToInherited(Map inherited);
    +        abstract void addToInherited(Map, Object> inherited);
     
             abstract  T getOverride(OptionValue option);
     
    @@ -276,7 +276,7 @@
             }
     
             @Override
    -        void addToInherited(Map inherited) {
    +        void addToInherited(Map, Object> inherited) {
                 inherited.put(option, value);
             }
     
    @@ -304,7 +304,7 @@
     
         static class MultipleOverridesScope extends OverrideScope {
             final OverrideScope parent;
    -        final Map overrides;
    +        final Map, Object> overrides;
     
             public MultipleOverridesScope(OverrideScope parent, OptionValue option, Object value) {
                 this.parent = parent;
    @@ -348,7 +348,7 @@
             }
     
             @Override
    -        void addToInherited(Map inherited) {
    +        void addToInherited(Map, Object> inherited) {
                 if (parent != null) {
                     parent.addToInherited(inherited);
                 }
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java
    --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,10 +22,10 @@
      */
     package com.oracle.graal.phases.common;
     
    -import java.lang.reflect.*;
     import java.util.*;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.debug.*;
     import com.oracle.graal.debug.Debug.Scope;
     import com.oracle.graal.graph.*;
    @@ -151,7 +151,7 @@
                             break;
                         }
                     }
    -                if (type != null && type != ObjectStamp.typeOrNull(node)) {
    +                if (type != null && type != StampTool.typeOrNull(node)) {
                         newKnownTypes.put(node, type);
                     }
                 }
    @@ -234,15 +234,15 @@
     
             public ResolvedJavaType getNodeType(ValueNode node) {
                 ResolvedJavaType result = knownTypes.get(GraphUtil.unproxify(node));
    -            return result == null ? ObjectStamp.typeOrNull(node) : result;
    +            return result == null ? StampTool.typeOrNull(node) : result;
             }
     
             public boolean isNull(ValueNode value) {
    -            return ObjectStamp.isObjectAlwaysNull(value) || knownNull.contains(GraphUtil.unproxify(value));
    +            return StampTool.isObjectAlwaysNull(value) || knownNull.contains(GraphUtil.unproxify(value));
             }
     
             public boolean isNonNull(ValueNode value) {
    -            return ObjectStamp.isObjectNonNull(value) || knownNonNull.contains(GraphUtil.unproxify(value));
    +            return StampTool.isObjectNonNull(value) || knownNonNull.contains(GraphUtil.unproxify(value));
             }
     
             @Override
    @@ -407,7 +407,7 @@
                 }
             }
     
    -        private void registerControlSplitInfo(Node pred, AbstractBeginNode begin) {
    +        private void registerControlSplitInfo(Node pred, BeginNode begin) {
                 assert pred != null && begin != null;
                 if (begin instanceof LoopExitNode) {
                     state.clear();
    @@ -656,8 +656,8 @@
     
             @Override
             protected void node(FixedNode node) {
    -            if (node instanceof AbstractBeginNode) {
    -                AbstractBeginNode begin = (AbstractBeginNode) node;
    +            if (node instanceof BeginNode) {
    +                BeginNode begin = (BeginNode) node;
                     Node pred = node.predecessor();
     
                     if (pred != null) {
    @@ -710,7 +710,7 @@
                         replacementAnchor = BeginNode.prevBegin(checkCast);
                         PiNode piNode;
                         if (isNull) {
    -                        ConstantNode nullObject = ConstantNode.forObject(null, metaAccess, graph);
    +                        ConstantNode nullObject = ConstantNode.defaultForKind(Kind.Object, graph);
                             piNode = graph.unique(new PiNode(nullObject, StampFactory.forConstant(nullObject.getValue(), metaAccess), replacementAnchor.asNode()));
                         } else {
                             piNode = graph.unique(new PiNode(object, StampFactory.declared(type, nonNull), replacementAnchor.asNode()));
    @@ -742,7 +742,7 @@
     
                     LogicNode replacement = null;
                     ValueNode replacementAnchor = null;
    -                AbstractBeginNode survivingSuccessor = null;
    +                BeginNode survivingSuccessor = null;
                     if (state.trueConditions.containsKey(compare)) {
                         replacement = trueConstant;
                         replacementAnchor = state.trueConditions.get(compare);
    @@ -764,7 +764,7 @@
                     }
     
                     if (replacement != null) {
    -                    if (!(replacementAnchor instanceof AbstractBeginNode)) {
    +                    if (!(replacementAnchor instanceof BeginNode)) {
                             ValueAnchorNode anchor = graph.add(new ValueAnchorNode(replacementAnchor));
                             graph.addBeforeFixed(ifNode, anchor);
                         }
    @@ -811,10 +811,10 @@
                         ValueNode receiver = callTarget.receiver();
                         if (receiver != null && (callTarget.invokeKind() == InvokeKind.Interface || callTarget.invokeKind() == InvokeKind.Virtual)) {
                             ResolvedJavaType type = state.getNodeType(receiver);
    -                        if (!Objects.equals(type, ObjectStamp.typeOrNull(receiver))) {
    +                        if (!Objects.equals(type, StampTool.typeOrNull(receiver))) {
                                 ResolvedJavaMethod method = type.resolveMethod(callTarget.targetMethod());
                                 if (method != null) {
    -                                if (Modifier.isFinal(method.getModifiers()) || Modifier.isFinal(type.getModifiers())) {
    +                                if (method.canBeStaticallyBound() || type.isFinal()) {
                                         callTarget.setInvokeKind(InvokeKind.Special);
                                         callTarget.setTargetMethod(method);
                                     }
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConvertDeoptimizeToGuardPhase.java
    --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConvertDeoptimizeToGuardPhase.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConvertDeoptimizeToGuardPhase.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -47,11 +47,11 @@
      */
     public class ConvertDeoptimizeToGuardPhase extends Phase {
     
    -    private static AbstractBeginNode findBeginNode(FixedNode startNode) {
    +    private static BeginNode findBeginNode(FixedNode startNode) {
             Node n = startNode;
             while (true) {
    -            if (n instanceof AbstractBeginNode) {
    -                return (AbstractBeginNode) n;
    +            if (n instanceof BeginNode) {
    +                return (BeginNode) n;
                 } else {
                     n = n.predecessor();
                 }
    @@ -71,7 +71,7 @@
     
             for (FixedGuardNode fixedGuard : graph.getNodes(FixedGuardNode.class)) {
     
    -            AbstractBeginNode pred = BeginNode.prevBegin(fixedGuard);
    +            BeginNode pred = BeginNode.prevBegin(fixedGuard);
                 if (pred instanceof MergeNode) {
                     MergeNode merge = (MergeNode) pred;
                     if (fixedGuard.condition() instanceof CompareNode) {
    @@ -109,17 +109,17 @@
             new DeadCodeEliminationPhase().apply(graph);
         }
     
    -    private void visitDeoptBegin(AbstractBeginNode deoptBegin, DeoptimizationAction deoptAction, DeoptimizationReason deoptReason, StructuredGraph graph) {
    +    private void visitDeoptBegin(BeginNode deoptBegin, DeoptimizationAction deoptAction, DeoptimizationReason deoptReason, StructuredGraph graph) {
             if (deoptBegin instanceof MergeNode) {
                 MergeNode mergeNode = (MergeNode) deoptBegin;
                 Debug.log("Visiting %s", mergeNode);
    -            List begins = new ArrayList<>();
    +            List begins = new ArrayList<>();
                 for (AbstractEndNode end : mergeNode.forwardEnds()) {
    -                AbstractBeginNode newBeginNode = findBeginNode(end);
    +                BeginNode newBeginNode = findBeginNode(end);
                     assert !begins.contains(newBeginNode);
                     begins.add(newBeginNode);
                 }
    -            for (AbstractBeginNode begin : begins) {
    +            for (BeginNode begin : begins) {
                     assert !begin.isDeleted();
                     visitDeoptBegin(begin, deoptAction, deoptReason, graph);
                 }
    @@ -127,11 +127,11 @@
                 return;
             } else if (deoptBegin.predecessor() instanceof IfNode) {
                 IfNode ifNode = (IfNode) deoptBegin.predecessor();
    -            AbstractBeginNode otherBegin = ifNode.trueSuccessor();
    +            BeginNode otherBegin = ifNode.trueSuccessor();
                 LogicNode conditionNode = ifNode.condition();
                 FixedGuardNode guard = graph.add(new FixedGuardNode(conditionNode, deoptReason, deoptAction, deoptBegin == ifNode.trueSuccessor()));
                 FixedWithNextNode pred = (FixedWithNextNode) ifNode.predecessor();
    -            AbstractBeginNode survivingSuccessor;
    +            BeginNode survivingSuccessor;
                 if (deoptBegin == ifNode.trueSuccessor()) {
                     survivingSuccessor = ifNode.falseSuccessor();
                 } else {
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/DeoptimizationGroupingPhase.java
    --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/DeoptimizationGroupingPhase.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/DeoptimizationGroupingPhase.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -25,9 +25,10 @@
     import java.util.*;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.cfg.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.cfg.*;
    -import com.oracle.graal.nodes.type.*;
     import com.oracle.graal.phases.*;
     import com.oracle.graal.phases.tiers.*;
     
    @@ -92,9 +93,9 @@
     
         private static void exitLoops(AbstractDeoptimizeNode deopt, EndNode end, ControlFlowGraph cfg) {
             Block block = cfg.blockFor(deopt);
    -        Loop loop = block.getLoop();
    +        Loop loop = block.getLoop();
             while (loop != null) {
    -            end.graph().addBeforeFixed(end, end.graph().add(new LoopExitNode(loop.loopBegin())));
    +            end.graph().addBeforeFixed(end, end.graph().add(new LoopExitNode((LoopBeginNode) loop.header.getBeginNode())));
                 loop = loop.parent;
             }
         }
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ExpandLogicPhase.java
    --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ExpandLogicPhase.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ExpandLogicPhase.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,6 +22,7 @@
      */
     package com.oracle.graal.phases.common;
     
    +import com.oracle.graal.compiler.common.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.calc.*;
    @@ -54,8 +55,8 @@
         }
     
         private static void processIf(LogicNode x, boolean xNegated, LogicNode y, boolean yNegated, IfNode ifNode, double shortCircuitProbability) {
    -        AbstractBeginNode trueTarget = ifNode.trueSuccessor();
    -        AbstractBeginNode falseTarget = ifNode.falseSuccessor();
    +        BeginNode trueTarget = ifNode.trueSuccessor();
    +        BeginNode falseTarget = ifNode.falseSuccessor();
             double firstIfProbability = shortCircuitProbability;
             /*
              * P(Y | not(X)) = P(Y inter not(X)) / P(not(X)) = (P(X union Y) - P(X)) / (1 - P(X))
    @@ -77,9 +78,9 @@
             EndNode secondTrueEnd = graph.add(new EndNode());
             trueTargetMerge.addForwardEnd(firstTrueEnd);
             trueTargetMerge.addForwardEnd(secondTrueEnd);
    -        AbstractBeginNode firstTrueTarget = AbstractBeginNode.begin(firstTrueEnd);
    -        AbstractBeginNode secondTrueTarget = AbstractBeginNode.begin(secondTrueEnd);
    -        AbstractBeginNode secondIf = AbstractBeginNode.begin(graph.add(new IfNode(y, yNegated ? falseTarget : secondTrueTarget, yNegated ? secondTrueTarget : falseTarget, secondIfProbability)));
    +        BeginNode firstTrueTarget = BeginNode.begin(firstTrueEnd);
    +        BeginNode secondTrueTarget = BeginNode.begin(secondTrueEnd);
    +        BeginNode secondIf = BeginNode.begin(graph.add(new IfNode(y, yNegated ? falseTarget : secondTrueTarget, yNegated ? secondTrueTarget : falseTarget, secondIfProbability)));
             IfNode firstIf = graph.add(new IfNode(x, xNegated ? secondIf : firstTrueTarget, xNegated ? firstTrueTarget : secondIf, firstIfProbability));
             ifNode.replaceAtPredecessor(firstIf);
             ifNode.safeDelete();
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/FloatingReadPhase.java
    --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/FloatingReadPhase.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/FloatingReadPhase.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -191,7 +191,7 @@
             }
     
             @Override
    -        protected Set afterSplit(AbstractBeginNode node, Set oldState) {
    +        protected Set afterSplit(BeginNode node, Set oldState) {
                 return new HashSet<>(oldState);
             }
     
    @@ -292,7 +292,7 @@
             }
     
             @Override
    -        protected MemoryMapImpl afterSplit(AbstractBeginNode node, MemoryMapImpl oldState) {
    +        protected MemoryMapImpl afterSplit(BeginNode node, MemoryMapImpl oldState) {
                 MemoryMapImpl result = new MemoryMapImpl(oldState);
                 if (node.predecessor() instanceof InvokeWithExceptionNode) {
                     /*
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/FrameStateAssignmentPhase.java
    --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/FrameStateAssignmentPhase.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/FrameStateAssignmentPhase.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -24,6 +24,7 @@
     
     import java.util.*;
     
    +import com.oracle.graal.compiler.common.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.graph.iterators.*;
     import com.oracle.graal.nodes.*;
    @@ -92,7 +93,7 @@
             }
     
             @Override
    -        protected FrameState afterSplit(AbstractBeginNode node, FrameState oldState) {
    +        protected FrameState afterSplit(BeginNode node, FrameState oldState) {
                 return oldState;
             }
     
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/GuardLoweringPhase.java
    --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/GuardLoweringPhase.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/GuardLoweringPhase.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,12 +22,13 @@
      */
     package com.oracle.graal.phases.common;
     
    -import static com.oracle.graal.phases.GraalOptions.*;
    +import static com.oracle.graal.compiler.common.GraalOptions.*;
     
     import java.util.*;
     import java.util.Map.Entry;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.cfg.*;
     import com.oracle.graal.debug.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.nodes.*;
    @@ -154,12 +155,12 @@
     
             private void lowerToIf(GuardNode guard) {
                 StructuredGraph graph = guard.graph();
    -            AbstractBeginNode fastPath = graph.add(new BeginNode());
    +            BeginNode fastPath = graph.add(new BeginNode());
                 @SuppressWarnings("deprecation")
                 DeoptimizeNode deopt = graph.add(new DeoptimizeNode(guard.action(), guard.reason(), useGuardIdAsDebugId ? guard.getId() : 0, guard.getSpeculation()));
    -            AbstractBeginNode deoptBranch = AbstractBeginNode.begin(deopt);
    -            AbstractBeginNode trueSuccessor;
    -            AbstractBeginNode falseSuccessor;
    +            BeginNode deoptBranch = BeginNode.begin(deopt);
    +            BeginNode trueSuccessor;
    +            BeginNode falseSuccessor;
                 insertLoopExits(deopt);
                 if (guard.negated()) {
                     trueSuccessor = deoptBranch;
    @@ -174,10 +175,10 @@
             }
     
             private void insertLoopExits(DeoptimizeNode deopt) {
    -            Loop loop = block.getLoop();
    +            Loop loop = block.getLoop();
                 StructuredGraph graph = deopt.graph();
                 while (loop != null) {
    -                LoopExitNode exit = graph.add(new LoopExitNode(loop.loopBegin()));
    +                LoopExitNode exit = graph.add(new LoopExitNode((LoopBeginNode) loop.header.getBeginNode()));
                     graph.addBeforeFixed(deopt, exit);
                     loop = loop.parent;
                 }
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/IncrementalCanonicalizerPhase.java
    --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/IncrementalCanonicalizerPhase.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/IncrementalCanonicalizerPhase.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -40,6 +40,11 @@
             this.canonicalizer = canonicalizer;
         }
     
    +    public IncrementalCanonicalizerPhase(CanonicalizerPhase canonicalizer, BasePhase phase) {
    +        this.canonicalizer = canonicalizer;
    +        appendPhase(phase);
    +    }
    +
         @Override
         protected void run(StructuredGraph graph, C context) {
             Mark newNodesMark = graph.getMark();
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningPhase.java
    --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningPhase.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningPhase.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,13 +22,15 @@
      */
     package com.oracle.graal.phases.common;
     
    -import static com.oracle.graal.phases.GraalOptions.*;
    +import static com.oracle.graal.compiler.common.GraalOptions.*;
     import static com.oracle.graal.phases.common.InliningPhase.Options.*;
     
     import java.util.*;
     
     import com.oracle.graal.api.code.*;
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.debug.*;
     import com.oracle.graal.debug.Debug.Scope;
     import com.oracle.graal.graph.*;
    @@ -36,7 +38,6 @@
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.java.*;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
     import com.oracle.graal.nodes.util.*;
     import com.oracle.graal.options.*;
     import com.oracle.graal.phases.common.InliningUtil.InlineInfo;
    @@ -173,28 +174,30 @@
             Mark markBeforeInlining = callerGraph.getMark();
             InlineInfo callee = calleeInfo.callee();
             try {
    -            List invokeUsages = callee.invoke().asNode().usages().snapshot();
    -            callee.inline(new Providers(context), callerAssumptions);
    -            callerAssumptions.record(calleeInfo.assumptions());
    -            metricInliningRuns.increment();
    -            Debug.dump(callerGraph, "after %s", callee);
    +            try (Scope scope = Debug.scope("doInline", callerGraph)) {
    +                List invokeUsages = callee.invoke().asNode().usages().snapshot();
    +                callee.inline(new Providers(context), callerAssumptions);
    +                callerAssumptions.record(calleeInfo.assumptions());
    +                metricInliningRuns.increment();
    +                Debug.dump(callerGraph, "after %s", callee);
     
    -            if (OptCanonicalizer.getValue()) {
    -                Mark markBeforeCanonicalization = callerGraph.getMark();
    -                canonicalizer.applyIncremental(callerGraph, context, invokeUsages, markBeforeInlining);
    +                if (OptCanonicalizer.getValue()) {
    +                    Mark markBeforeCanonicalization = callerGraph.getMark();
    +                    canonicalizer.applyIncremental(callerGraph, context, invokeUsages, markBeforeInlining);
     
    -                // process invokes that are possibly created during canonicalization
    -                for (Node newNode : callerGraph.getNewNodes(markBeforeCanonicalization)) {
    -                    if (newNode instanceof Invoke) {
    -                        callerGraphInfo.pushInvoke((Invoke) newNode);
    +                    // process invokes that are possibly created during canonicalization
    +                    for (Node newNode : callerGraph.getNewNodes(markBeforeCanonicalization)) {
    +                        if (newNode instanceof Invoke) {
    +                            callerGraphInfo.pushInvoke((Invoke) newNode);
    +                        }
                         }
                     }
    -            }
    +
    +                callerGraphInfo.computeProbabilities();
     
    -            callerGraphInfo.computeProbabilities();
    -
    -            inliningCount++;
    -            metricInliningPerformed.increment();
    +                inliningCount++;
    +                metricInliningPerformed.increment();
    +            }
             } catch (BailoutException bailout) {
                 throw bailout;
             } catch (AssertionError | RuntimeException e) {
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java
    --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -24,11 +24,8 @@
     
     import static com.oracle.graal.api.meta.DeoptimizationAction.*;
     import static com.oracle.graal.api.meta.DeoptimizationReason.*;
    -import static com.oracle.graal.nodes.type.StampFactory.*;
    -import static com.oracle.graal.phases.GraalOptions.*;
    -import static java.lang.reflect.Modifier.*;
    -
    -import java.lang.reflect.*;
    +import static com.oracle.graal.compiler.common.GraalOptions.*;
    +import static com.oracle.graal.compiler.common.type.StampFactory.*;
     import java.util.*;
     
     import com.oracle.graal.api.code.*;
    @@ -36,6 +33,9 @@
     import com.oracle.graal.api.meta.*;
     import com.oracle.graal.api.meta.JavaTypeProfile.ProfiledType;
     import com.oracle.graal.api.meta.ResolvedJavaType.Representation;
    +import com.oracle.graal.compiler.common.*;
    +import com.oracle.graal.compiler.common.calc.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.debug.*;
     import com.oracle.graal.debug.Debug.Scope;
     import com.oracle.graal.graph.*;
    @@ -137,13 +137,12 @@
          */
         private static void printInlining(final ResolvedJavaMethod method, final Invoke invoke, final int inliningDepth, final boolean success, final String msg, final Object... args) {
             if (HotSpotPrintInlining.getValue()) {
    -            final int mod = method.getModifiers();
                 // 1234567
                 TTY.print("        ");     // print timestamp
                 // 1234
                 TTY.print("     ");        // print compilation number
                 // % s ! b n
    -            TTY.print("%c%c%c%c%c ", ' ', Modifier.isSynchronized(mod) ? 's' : ' ', ' ', ' ', Modifier.isNative(mod) ? 'n' : ' ');
    +            TTY.print("%c%c%c%c%c ", ' ', method.isSynchronized() ? 's' : ' ', ' ', ' ', method.isNative() ? 'n' : ' ');
                 TTY.print("     ");        // more indent
                 TTY.print("    ");         // initial inlining indent
                 for (int i = 0; i < inliningDepth; i++) {
    @@ -432,7 +431,7 @@
                 super(invoke);
                 this.concrete = concrete;
                 this.type = type;
    -            assert type.isArray() || !isAbstract(type.getModifiers()) : type;
    +            assert type.isArray() || !type.isAbstract() : type;
             }
     
             @Override
    @@ -646,7 +645,7 @@
                 }
     
                 // create one separate block for each invoked method
    -            AbstractBeginNode[] successors = new AbstractBeginNode[numberOfMethods + 1];
    +            BeginNode[] successors = new BeginNode[numberOfMethods + 1];
                 for (int i = 0; i < numberOfMethods; i++) {
                     successors[i] = createInvocationBlock(graph, invoke, returnMerge, returnValuePhi, exceptionMerge, exceptionObjectPhi, true);
                 }
    @@ -658,7 +657,7 @@
                 } else {
                     unknownTypeSux = graph.add(new DeoptimizeNode(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.TypeCheckedInliningViolated));
                 }
    -            successors[successors.length - 1] = AbstractBeginNode.begin(unknownTypeSux);
    +            successors[successors.length - 1] = BeginNode.begin(unknownTypeSux);
     
                 // replace the invoke exception edge
                 if (invoke instanceof InvokeWithExceptionNode) {
    @@ -684,7 +683,7 @@
     
                 // do the actual inlining for every invoke
                 for (int i = 0; i < numberOfMethods; i++) {
    -                AbstractBeginNode node = successors[i];
    +                BeginNode node = successors[i];
                     Invoke invokeForInlining = (Invoke) node.next();
     
                     ResolvedJavaType commonType;
    @@ -770,10 +769,10 @@
             private void inlineSingleMethod(StructuredGraph graph, MetaAccessProvider metaAccess, Assumptions assumptions) {
                 assert concretes.size() == 1 && inlineableElements.length == 1 && ptypes.size() > 1 && !shouldFallbackToInvoke() && notRecordedTypeProbability == 0;
     
    -            AbstractBeginNode calleeEntryNode = graph.add(new BeginNode());
    +            BeginNode calleeEntryNode = graph.add(new BeginNode());
     
    -            AbstractBeginNode unknownTypeSux = createUnknownTypeSuccessor(graph);
    -            AbstractBeginNode[] successors = new AbstractBeginNode[]{calleeEntryNode, unknownTypeSux};
    +            BeginNode unknownTypeSux = createUnknownTypeSuccessor(graph);
    +            BeginNode[] successors = new BeginNode[]{calleeEntryNode, unknownTypeSux};
                 createDispatchOnTypeBeforeInvoke(graph, successors, false, metaAccess);
     
                 calleeEntryNode.setNext(invoke.asNode());
    @@ -781,7 +780,7 @@
                 inline(invoke, methodAt(0), inlineableElementAt(0), assumptions, false);
             }
     
    -        private boolean createDispatchOnTypeBeforeInvoke(StructuredGraph graph, AbstractBeginNode[] successors, boolean invokeIsOnlySuccessor, MetaAccessProvider metaAccess) {
    +        private boolean createDispatchOnTypeBeforeInvoke(StructuredGraph graph, BeginNode[] successors, boolean invokeIsOnlySuccessor, MetaAccessProvider metaAccess) {
                 assert ptypes.size() >= 1;
                 ValueNode nonNullReceiver = nonNullReceiver(invoke);
                 Kind hubKind = ((MethodCallTargetNode) invoke.callTarget()).targetMethod().getDeclaringClass().getEncoding(Representation.ObjectHub).getKind();
    @@ -891,10 +890,10 @@
                 return costEstimateMethodDispatch < costEstimateTypeDispatch;
             }
     
    -        private static AbstractBeginNode createInvocationBlock(StructuredGraph graph, Invoke invoke, MergeNode returnMerge, PhiNode returnValuePhi, MergeNode exceptionMerge,
    -                        PhiNode exceptionObjectPhi, boolean useForInlining) {
    +        private static BeginNode createInvocationBlock(StructuredGraph graph, Invoke invoke, MergeNode returnMerge, PhiNode returnValuePhi, MergeNode exceptionMerge, PhiNode exceptionObjectPhi,
    +                        boolean useForInlining) {
                 Invoke duplicatedInvoke = duplicateInvokeForInlining(graph, invoke, exceptionMerge, exceptionObjectPhi, useForInlining);
    -            AbstractBeginNode calleeEntryNode = graph.add(new BeginNode());
    +            BeginNode calleeEntryNode = graph.add(new BeginNode());
                 calleeEntryNode.setNext(duplicatedInvoke.asNode());
     
                 AbstractEndNode endNode = graph.add(new EndNode());
    @@ -969,9 +968,9 @@
             }
     
             private void devirtualizeWithTypeSwitch(StructuredGraph graph, InvokeKind kind, ResolvedJavaMethod target, MetaAccessProvider metaAccess) {
    -            AbstractBeginNode invocationEntry = graph.add(new BeginNode());
    -            AbstractBeginNode unknownTypeSux = createUnknownTypeSuccessor(graph);
    -            AbstractBeginNode[] successors = new AbstractBeginNode[]{invocationEntry, unknownTypeSux};
    +            BeginNode invocationEntry = graph.add(new BeginNode());
    +            BeginNode unknownTypeSux = createUnknownTypeSuccessor(graph);
    +            BeginNode[] successors = new BeginNode[]{invocationEntry, unknownTypeSux};
                 createDispatchOnTypeBeforeInvoke(graph, successors, true, metaAccess);
     
                 invocationEntry.setNext(invoke.asNode());
    @@ -981,8 +980,8 @@
                 replaceInvokeCallTarget(invoke, graph, kind, target);
             }
     
    -        private static AbstractBeginNode createUnknownTypeSuccessor(StructuredGraph graph) {
    -            return AbstractBeginNode.begin(graph.add(new DeoptimizeNode(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.TypeCheckedInliningViolated)));
    +        private static BeginNode createUnknownTypeSuccessor(StructuredGraph graph) {
    +            return BeginNode.begin(graph.add(new DeoptimizeNode(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.TypeCheckedInliningViolated)));
             }
     
             @Override
    @@ -1111,7 +1110,7 @@
     
         private static InlineInfo getAssumptionInlineInfo(InliningData data, Invoke invoke, Replacements replacements, OptimisticOptimizations optimisticOpts, ResolvedJavaMethod concrete,
                         Assumption takenAssumption) {
    -        assert !Modifier.isAbstract(concrete.getModifiers());
    +        assert !concrete.isAbstract();
             if (!checkTargetConditions(data, replacements, invoke, concrete, optimisticOpts)) {
                 return null;
             }
    @@ -1119,7 +1118,7 @@
         }
     
         private static InlineInfo getExactInlineInfo(InliningData data, Invoke invoke, Replacements replacements, OptimisticOptimizations optimisticOpts, ResolvedJavaMethod targetMethod) {
    -        assert !Modifier.isAbstract(targetMethod.getModifiers());
    +        assert !targetMethod.isAbstract();
             if (!checkTargetConditions(data, replacements, invoke, targetMethod, optimisticOpts)) {
                 return null;
             }
    @@ -1149,7 +1148,7 @@
                 }
     
                 ResolvedJavaType type = ptypes[0].getType();
    -            assert type.isArray() || !isAbstract(type.getModifiers());
    +            assert type.isArray() || !type.isAbstract();
                 ResolvedJavaMethod concrete = type.resolveMethod(targetMethod);
                 if (!checkTargetConditions(data, replacements, invoke, concrete, optimisticOpts)) {
                     return null;
    @@ -1221,7 +1220,7 @@
                     if (index == -1) {
                         notRecordedTypeProbability += type.getProbability();
                     } else {
    -                    assert type.getType().isArray() || !isAbstract(type.getType().getModifiers()) : type + " " + concrete;
    +                    assert type.getType().isArray() || !type.getType().isAbstract() : type + " " + concrete;
                         usedTypes.add(type);
                         typesToConcretes.add(index);
                     }
    @@ -1274,9 +1273,9 @@
         private static boolean checkTargetConditions(InliningData data, Replacements replacements, Invoke invoke, ResolvedJavaMethod method, OptimisticOptimizations optimisticOpts) {
             if (method == null) {
                 return logNotInlinedMethodAndReturnFalse(invoke, data.inliningDepth(), method, "the method is not resolved");
    -        } else if (Modifier.isNative(method.getModifiers()) && (!Intrinsify.getValue() || !InliningUtil.canIntrinsify(replacements, method))) {
    +        } else if (method.isNative() && (!Intrinsify.getValue() || !InliningUtil.canIntrinsify(replacements, method))) {
                 return logNotInlinedMethodAndReturnFalse(invoke, data.inliningDepth(), method, "it is a non-intrinsic native method");
    -        } else if (Modifier.isAbstract(method.getModifiers())) {
    +        } else if (method.isAbstract()) {
                 return logNotInlinedMethodAndReturnFalse(invoke, data.inliningDepth(), method, "it is an abstract method");
             } else if (!method.getDeclaringClass().isInitialized()) {
                 return logNotInlinedMethodAndReturnFalse(invoke, data.inliningDepth(), method, "the method's class is not initialized");
    @@ -1347,7 +1346,7 @@
                 }
             }
     
    -        final AbstractBeginNode prevBegin = AbstractBeginNode.prevBegin(invokeNode);
    +        final BeginNode prevBegin = BeginNode.prevBegin(invokeNode);
             DuplicationReplacement localReplacement = new DuplicationReplacement() {
     
                 public Node replacement(Node node) {
    @@ -1386,7 +1385,7 @@
                 }
     
                 // get rid of memory kill
    -            AbstractBeginNode begin = invokeWithException.next();
    +            BeginNode begin = invokeWithException.next();
                 if (begin instanceof KillingBeginNode) {
                     BeginNode newBegin = new BeginNode();
                     graph.addAfterFixed(begin, graph.add(newBegin));
    @@ -1396,19 +1395,8 @@
             } else {
                 if (unwindNode != null) {
                     UnwindNode unwindDuplicate = (UnwindNode) duplicates.get(unwindNode);
    -                MonitorExitNode monitorExit = findPrecedingMonitorExit(unwindDuplicate);
    -                DeoptimizeNode deoptimizeNode = new DeoptimizeNode(DeoptimizationAction.InvalidateRecompile, DeoptimizationReason.NotCompiledExceptionHandler);
    -                unwindDuplicate.replaceAndDelete(graph.add(deoptimizeNode));
    -                // move the deopt upwards if there is a monitor exit that tries to use the
    -                // "after exception" frame state
    -                // (because there is no "after exception" frame state!)
    -                if (monitorExit != null) {
    -                    if (monitorExit.stateAfter() != null && monitorExit.stateAfter().bci == FrameState.AFTER_EXCEPTION_BCI) {
    -                        FrameState monitorFrameState = monitorExit.stateAfter();
    -                        graph.removeFixed(monitorExit);
    -                        monitorFrameState.safeDelete();
    -                    }
    -                }
    +                DeoptimizeNode deoptimizeNode = graph.add(new DeoptimizeNode(DeoptimizationAction.InvalidateRecompile, DeoptimizationReason.NotCompiledExceptionHandler));
    +                unwindDuplicate.replaceAndDelete(deoptimizeNode);
                 }
             }
     
    @@ -1417,22 +1405,25 @@
                 int callerLockDepth = stateAfter.nestedLockDepth();
                 for (FrameState original : inlineGraph.getNodes(FrameState.class)) {
                     FrameState frameState = (FrameState) duplicates.get(original);
    -                if (frameState != null) {
    -                    assert frameState.bci != FrameState.BEFORE_BCI : frameState;
    -                    if (frameState.bci == FrameState.AFTER_BCI) {
    +                if (frameState != null && frameState.isAlive()) {
    +                    assert frameState.bci != BytecodeFrame.BEFORE_BCI : frameState;
    +                    if (frameState.bci == BytecodeFrame.AFTER_BCI) {
                             frameState.replaceAndDelete(returnKind == Kind.Void ? stateAfter : stateAfter.duplicateModified(stateAfter.bci, stateAfter.rethrowException(), returnKind,
                                             frameState.stackAt(0)));
    -                    } else if (frameState.bci == FrameState.AFTER_EXCEPTION_BCI) {
    -                        if (frameState.isAlive()) {
    -                            assert stateAtExceptionEdge != null;
    +                    } else if (frameState.bci == BytecodeFrame.AFTER_EXCEPTION_BCI || (frameState.bci == BytecodeFrame.UNWIND_BCI && !frameState.method().isSynchronized())) {
    +                        if (stateAtExceptionEdge != null) {
                                 frameState.replaceAndDelete(stateAtExceptionEdge);
                             } else {
    -                            assert stateAtExceptionEdge == null;
    +                            handleMissingAfterExceptionFrameState(frameState);
                             }
    +                    } else if (frameState.bci == BytecodeFrame.UNWIND_BCI) {
    +                        handleMissingAfterExceptionFrameState(frameState);
                         } else {
                             // only handle the outermost frame states
                             if (frameState.outerFrameState() == null) {
    -                            assert frameState.bci == FrameState.INVALID_FRAMESTATE_BCI || frameState.method().equals(inlineGraph.method());
    +                            assert frameState.bci == BytecodeFrame.INVALID_FRAMESTATE_BCI || frameState.method().equals(inlineGraph.method());
    +                            assert frameState.bci != BytecodeFrame.AFTER_EXCEPTION_BCI && frameState.bci != BytecodeFrame.BEFORE_BCI && frameState.bci != BytecodeFrame.AFTER_EXCEPTION_BCI &&
    +                                            frameState.bci != BytecodeFrame.UNWIND_BCI : frameState.bci;
                                 if (outerFrameState == null) {
                                     outerFrameState = stateAfter.duplicateModified(invoke.bci(), stateAfter.rethrowException(), invokeNode.getKind());
                                     outerFrameState.setDuringCall(true);
    @@ -1479,6 +1470,39 @@
             return duplicates;
         }
     
    +    protected static void handleMissingAfterExceptionFrameState(FrameState nonReplacableFrameState) {
    +        Graph graph = nonReplacableFrameState.graph();
    +        NodeWorkList workList = graph.createNodeWorkList();
    +        workList.add(nonReplacableFrameState);
    +        for (Node node : workList) {
    +            FrameState fs = (FrameState) node;
    +            for (Node usage : fs.usages().snapshot()) {
    +                if (!usage.isAlive()) {
    +                    continue;
    +                }
    +                if (usage instanceof FrameState) {
    +                    workList.add(usage);
    +                } else {
    +                    StateSplit stateSplit = (StateSplit) usage;
    +                    FixedNode fixedStateSplit = stateSplit.asNode();
    +                    if (fixedStateSplit instanceof MergeNode) {
    +                        MergeNode merge = (MergeNode) fixedStateSplit;
    +                        while (merge.isAlive()) {
    +                            AbstractEndNode end = merge.forwardEnds().first();
    +                            DeoptimizeNode deoptimizeNode = graph.add(new DeoptimizeNode(DeoptimizationAction.InvalidateRecompile, DeoptimizationReason.NotCompiledExceptionHandler));
    +                            end.replaceAtPredecessor(deoptimizeNode);
    +                            GraphUtil.killCFG(end);
    +                        }
    +                    } else {
    +                        DeoptimizeNode deoptimizeNode = graph.add(new DeoptimizeNode(DeoptimizationAction.InvalidateRecompile, DeoptimizationReason.NotCompiledExceptionHandler));
    +                        fixedStateSplit.replaceAtPredecessor(deoptimizeNode);
    +                        GraphUtil.killCFG(fixedStateSplit);
    +                    }
    +                }
    +            }
    +        }
    +    }
    +
         public static ValueNode mergeReturns(MergeNode merge, List returnNodes) {
             PhiNode returnValuePhi = null;
     
    @@ -1504,7 +1528,7 @@
             for (Node node : duplicates.values()) {
                 if (node instanceof FrameState) {
                     FrameState frameState = (FrameState) node;
    -                assert frameState.bci == FrameState.AFTER_BCI || frameState.bci == FrameState.INVALID_FRAMESTATE_BCI : node.toString(Verbosity.Debugger);
    +                assert frameState.bci == BytecodeFrame.AFTER_BCI || frameState.bci == BytecodeFrame.INVALID_FRAMESTATE_BCI : node.toString(Verbosity.Debugger);
                 }
             }
             return true;
    @@ -1518,7 +1542,7 @@
             assert !callTarget.isStatic() : callTarget.targetMethod();
             StructuredGraph graph = callTarget.graph();
             ValueNode firstParam = callTarget.arguments().get(0);
    -        if (firstParam.getKind() == Kind.Object && !ObjectStamp.isObjectNonNull(firstParam)) {
    +        if (firstParam.getKind() == Kind.Object && !StampTool.isObjectNonNull(firstParam)) {
                 IsNullNode condition = graph.unique(new IsNullNode(firstParam));
                 Stamp stamp = firstParam.stamp().join(objectNonNull());
                 GuardingPiNode nonNullReceiver = graph.add(new GuardingPiNode(firstParam, condition, true, NullCheckException, InvalidateReprofile, stamp));
    @@ -1566,7 +1590,7 @@
             try {
                 return macroNodeClass.getConstructor(Invoke.class).newInstance(invoke);
             } catch (ReflectiveOperationException | IllegalArgumentException | SecurityException e) {
    -            throw new GraalInternalError(e).addContext(invoke.asNode()).addContext("macroSubstitution", macroNodeClass);
    +            throw new GraalGraphInternalError(e).addContext(invoke.asNode()).addContext("macroSubstitution", macroNodeClass);
             }
         }
     }
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoopSafepointInsertionPhase.java
    --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoopSafepointInsertionPhase.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoopSafepointInsertionPhase.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,7 +22,7 @@
      */
     package com.oracle.graal.phases.common;
     
    -import static com.oracle.graal.phases.GraalOptions.*;
    +import static com.oracle.graal.compiler.common.GraalOptions.*;
     
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.phases.*;
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoweringPhase.java
    --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoweringPhase.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoweringPhase.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,12 +22,13 @@
      */
     package com.oracle.graal.phases.common;
     
    -import static com.oracle.graal.phases.GraalOptions.*;
    +import static com.oracle.graal.compiler.common.GraalOptions.*;
     
     import java.util.*;
     
     import com.oracle.graal.api.code.*;
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.Graph.Mark;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.graph.iterators.*;
    @@ -36,7 +37,6 @@
     import com.oracle.graal.nodes.cfg.*;
     import com.oracle.graal.nodes.extended.*;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
     import com.oracle.graal.phases.*;
     import com.oracle.graal.phases.schedule.*;
     import com.oracle.graal.phases.tiers.*;
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/NonNullParametersPhase.java
    --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/NonNullParametersPhase.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/NonNullParametersPhase.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,8 +22,8 @@
      */
     package com.oracle.graal.phases.common;
     
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.nodes.*;
    -import com.oracle.graal.nodes.type.*;
     import com.oracle.graal.phases.*;
     
     /**
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/OptimizeGuardAnchorsPhase.java
    --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/OptimizeGuardAnchorsPhase.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/OptimizeGuardAnchorsPhase.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -55,11 +55,11 @@
         @Override
         protected void run(StructuredGraph graph) {
             LazyCFG cfg = new LazyCFG(graph);
    -        for (AbstractBeginNode begin : graph.getNodes(AbstractBeginNode.class)) {
    +        for (BeginNode begin : graph.getNodes(BeginNode.class)) {
                 if (!(begin instanceof StartNode || begin.predecessor() instanceof ControlSplitNode)) {
                     NodeIterable guards = begin.guards();
                     if (guards.isNotEmpty()) {
    -                    AbstractBeginNode newAnchor = computeOptimalAnchor(cfg.get(), begin);
    +                    BeginNode newAnchor = computeOptimalAnchor(cfg.get(), begin);
                         // newAnchor == begin is possible because postdominator computation assumes that
                         // loops never end
                         if (newAnchor != begin) {
    @@ -76,14 +76,14 @@
             }
         }
     
    -    public static AbstractBeginNode getOptimalAnchor(LazyCFG cfg, AbstractBeginNode begin) {
    +    public static BeginNode getOptimalAnchor(LazyCFG cfg, BeginNode begin) {
             if (begin instanceof StartNode || begin.predecessor() instanceof ControlSplitNode) {
                 return begin;
             }
             return computeOptimalAnchor(cfg.get(), begin);
         }
     
    -    private static AbstractBeginNode computeOptimalAnchor(ControlFlowGraph cfg, AbstractBeginNode begin) {
    +    private static BeginNode computeOptimalAnchor(ControlFlowGraph cfg, BeginNode begin) {
             Block anchor = cfg.blockFor(begin);
             while (anchor.getDominator() != null && anchor.getDominator().getPostdominator() == anchor) {
                 anchor = anchor.getDominator();
    @@ -92,7 +92,7 @@
         }
     
         private static void optimizeAtControlSplit(ControlSplitNode controlSplit, LazyCFG cfg) {
    -        AbstractBeginNode successor = findMinimumUsagesSuccessor(controlSplit);
    +        BeginNode successor = findMinimumUsagesSuccessor(controlSplit);
             int successorCount = controlSplit.successors().count();
             List otherGuards = new ArrayList<>(successorCount - 1);
             for (GuardNode guard : successor.guards().snapshot()) {
    @@ -109,7 +109,7 @@
                 }
     
                 if (otherGuards.size() == successorCount - 1) {
    -                AbstractBeginNode anchor = computeOptimalAnchor(cfg.get(), AbstractBeginNode.prevBegin(controlSplit));
    +                BeginNode anchor = computeOptimalAnchor(cfg.get(), BeginNode.prevBegin(controlSplit));
                     GuardNode newGuard = controlSplit.graph().unique(new GuardNode(guard.condition(), anchor, guard.reason(), guard.action(), guard.negated(), guard.getSpeculation()));
                     for (GuardNode otherGuard : otherGuards) {
                         otherGuard.replaceAndDelete(newGuard);
    @@ -126,12 +126,12 @@
                             conditonGuard.getSpeculation().equals(guard.getSpeculation());
         }
     
    -    private static AbstractBeginNode findMinimumUsagesSuccessor(ControlSplitNode controlSplit) {
    +    private static BeginNode findMinimumUsagesSuccessor(ControlSplitNode controlSplit) {
             NodeClassIterator successors = controlSplit.successors().iterator();
    -        AbstractBeginNode min = (AbstractBeginNode) successors.next();
    +        BeginNode min = (BeginNode) successors.next();
             int minUsages = min.usages().count();
             while (successors.hasNext()) {
    -            AbstractBeginNode successor = (AbstractBeginNode) successors.next();
    +            BeginNode successor = (BeginNode) successors.next();
                 int count = successor.usages().count();
                 if (count < minUsages) {
                     minUsages = count;
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ProfileCompiledMethodsPhase.java
    --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ProfileCompiledMethodsPhase.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ProfileCompiledMethodsPhase.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -24,6 +24,7 @@
     
     import java.util.*;
     
    +import com.oracle.graal.compiler.common.cfg.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.calc.*;
    @@ -43,11 +44,11 @@
      * for each node would be too costly, so this phase takes the compromise that it trusts split
      * probabilities, but not loop frequencies. This means that it will insert counters at the start of
      * a method and at each loop header.
    - * 
    + *
      * A schedule is created so that floating nodes can also be taken into account. The weight of a node
      * is determined heuristically in the
      * {@link ProfileCompiledMethodsPhase#getNodeWeight(ScheduledNode)} method.
    - * 
    + *
      * Additionally, there's a second counter that's only increased for code sections without invokes.
      */
     public class ProfileCompiledMethodsPhase extends Phase {
    @@ -65,18 +66,18 @@
             schedule.apply(graph, false);
     
             ControlFlowGraph cfg = ControlFlowGraph.compute(graph, true, true, true, true);
    -        for (Loop loop : cfg.getLoops()) {
    -            double loopProbability = probabilities.get(loop.loopBegin());
    +        for (Loop loop : cfg.getLoops()) {
    +            double loopProbability = probabilities.get(loop.header.getBeginNode());
                 if (loopProbability > (1D / Integer.MAX_VALUE)) {
    -                addSectionCounters(loop.loopBegin(), loop.blocks, loop.children, schedule, probabilities);
    +                addSectionCounters(loop.header.getBeginNode(), loop.blocks, loop.children, schedule, probabilities);
                 }
             }
    -        addSectionCounters(graph.start(), Arrays.asList(cfg.getBlocks()), Arrays.asList(cfg.getLoops()), schedule, probabilities);
    +        addSectionCounters(graph.start(), Arrays.asList(cfg.getBlocks()), cfg.getLoops(), schedule, probabilities);
         }
     
    -    private static void addSectionCounters(FixedWithNextNode start, Collection sectionBlocks, Collection childLoops, SchedulePhase schedule, NodesToDoubles probabilities) {
    +    private static void addSectionCounters(FixedWithNextNode start, Collection sectionBlocks, Collection> childLoops, SchedulePhase schedule, NodesToDoubles probabilities) {
             HashSet blocks = new HashSet<>(sectionBlocks);
    -        for (Loop loop : childLoops) {
    +        for (Loop loop : childLoops) {
                 blocks.removeAll(loop.blocks);
             }
             double weight = getSectionWeight(schedule, probabilities, blocks) / probabilities.get(start);
    @@ -108,7 +109,7 @@
         private static double getNodeWeight(ScheduledNode node) {
             if (node instanceof MergeNode) {
                 return ((MergeNode) node).phiPredecessorCount();
    -        } else if (node instanceof AbstractBeginNode || node instanceof AbstractEndNode || node instanceof MonitorIdNode || node instanceof ConstantNode || node instanceof ParameterNode ||
    +        } else if (node instanceof BeginNode || node instanceof AbstractEndNode || node instanceof MonitorIdNode || node instanceof ConstantNode || node instanceof ParameterNode ||
                             node instanceof CallTargetNode || node instanceof ValueProxy || node instanceof VirtualObjectNode || node instanceof ReinterpretNode) {
                 return 0;
             } else if (node instanceof AccessMonitorNode) {
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ReadEliminationPhase.java
    --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ReadEliminationPhase.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ReadEliminationPhase.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,6 +22,7 @@
      */
     package com.oracle.graal.phases.common;
     
    +import com.oracle.graal.compiler.common.*;
     import com.oracle.graal.debug.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.nodes.*;
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/TailDuplicationPhase.java
    --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/TailDuplicationPhase.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/TailDuplicationPhase.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,10 +22,12 @@
      */
     package com.oracle.graal.phases.common;
     
    -import static com.oracle.graal.phases.GraalOptions.*;
    +import static com.oracle.graal.compiler.common.GraalOptions.*;
     
     import java.util.*;
     
    +import com.oracle.graal.compiler.common.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.debug.*;
     import com.oracle.graal.graph.Graph.DuplicationReplacement;
     import com.oracle.graal.graph.Graph.Mark;
    @@ -37,7 +39,6 @@
     import com.oracle.graal.nodes.extended.*;
     import com.oracle.graal.nodes.java.*;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
     import com.oracle.graal.nodes.util.*;
     import com.oracle.graal.nodes.virtual.*;
     import com.oracle.graal.phases.*;
    @@ -293,7 +294,7 @@
                     // EndNode
                     FixedWithNextNode anchorDuplicate = (FixedWithNextNode) duplicates.get(anchor);
                     // move dependencies on the ValueAnchorNode to the previous BeginNode
    -                AbstractBeginNode prevBegin = AbstractBeginNode.prevBegin(forwardEnd);
    +                BeginNode prevBegin = BeginNode.prevBegin(forwardEnd);
                     anchorDuplicate.replaceAtUsages(InputType.Guard, prevBegin);
                     anchorDuplicate.replaceAtUsages(InputType.Anchor, prevBegin);
                     assert anchorDuplicate.usages().isEmpty();
    @@ -493,7 +494,7 @@
                             Position pos = iter.nextPosition();
                             if (pos.get(usage) == duplicated) {
                                 switch (pos.getInputType(usage)) {
    -                                case Association:
    +                                case Extension:
                                     case Condition:
                                     case State:
                                         // clone the offending node to the outside
    @@ -524,6 +525,7 @@
                                         }
                                         pos.set(usage, newPhi);
                                         break;
    +                                case Association:
                                     default:
                                         throw GraalInternalError.shouldNotReachHere();
                                 }
    @@ -541,7 +543,7 @@
                     Node input = pos.get(duplicated);
                     if (input != null && !duplicatedNodes.contains(input)) {
                         switch (pos.getInputType(duplicated)) {
    -                        case Association:
    +                        case Extension:
                             case Condition:
                             case State:
                                 if (input != merge) {
    @@ -549,6 +551,7 @@
                                     worklist.add(input);
                                 }
                                 break;
    +                        case Association:
                             case Guard:
                             case Anchor:
                             case Value:
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/UseTrappingNullChecksPhase.java
    --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/UseTrappingNullChecksPhase.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/UseTrappingNullChecksPhase.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -55,7 +55,7 @@
             }
             Node predecessor = deopt.predecessor();
             Node branch = null;
    -        while (predecessor instanceof AbstractBeginNode) {
    +        while (predecessor instanceof BeginNode) {
                 branch = predecessor;
                 predecessor = predecessor.predecessor();
             }
    @@ -73,8 +73,8 @@
     
         private static void replaceWithTrappingNullCheck(DeoptimizeNode deopt, IfNode ifNode, LogicNode condition) {
             IsNullNode isNullNode = (IsNullNode) condition;
    -        AbstractBeginNode nonTrappingContinuation = ifNode.falseSuccessor();
    -        AbstractBeginNode trappingContinuation = ifNode.trueSuccessor();
    +        BeginNode nonTrappingContinuation = ifNode.falseSuccessor();
    +        BeginNode trappingContinuation = ifNode.trueSuccessor();
             NullCheckNode trappingNullCheck = deopt.graph().add(new NullCheckNode(isNullNode.object()));
             trappingNullCheck.setStateBefore(deopt.stateBefore());
             deopt.graph().replaceSplit(ifNode, trappingNullCheck, nonTrappingContinuation);
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java
    --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java	Wed Apr 23 15:22:20 2014 +0200
    +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    @@ -1,283 +0,0 @@
    -/*
    - * Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved.
    - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    - *
    - * This code is free software; you can redistribute it and/or modify it
    - * under the terms of the GNU General Public License version 2 only, as
    - * published by the Free Software Foundation.
    - *
    - * This code is distributed in the hope that it will be useful, but WITHOUT
    - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    - * version 2 for more details (a copy is included in the LICENSE file that
    - * accompanied this code).
    - *
    - * You should have received a copy of the GNU General Public License version
    - * 2 along with this work; if not, write to the Free Software Foundation,
    - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    - *
    - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    - * or visit www.oracle.com if you need additional information or have any
    - * questions.
    - */
    -package com.oracle.graal.phases;
    -
    -import com.oracle.graal.options.*;
    -
    -/**
    - * This class encapsulates options that control the behavior of the Graal compiler.
    - */
    -// @formatter:off
    -public final class GraalOptions {
    -
    -    @Option(help = "Use baseline compiler configuration")
    -    public static final OptionValue UseBaselineCompiler = new OptionValue<>(false);
    -    @Option(help = "Enable use of compiler intrinsics")
    -    public static final OptionValue Intrinsify = new OptionValue<>(true);
    -    @Option(help = "Enable inlining of monomorphic calls")
    -    static final OptionValue InlineMonomorphicCalls = new OptionValue<>(true);
    -    @Option(help = "Enable inlining of polymorphic calls")
    -    static final OptionValue InlinePolymorphicCalls = new OptionValue<>(true);
    -    @Option(help = "Enable inlining of megamorphic calls")
    -    static final OptionValue InlineMegamorphicCalls = new OptionValue<>(true);
    -    @Option(help = "")
    -    public static final OptionValue MegamorphicInliningMinMethodProbability = new OptionValue<>(0.33D);
    -    @Option(help = "")
    -    public static final OptionValue MaximumDesiredSize = new OptionValue<>(20000);
    -    @Option(help = "")
    -    public static final OptionValue MaximumRecursiveInlining = new OptionValue<>(5);
    -
    -    // inlining settings
    -    @Option(help = "")
    -    public static final OptionValue BoostInliningForEscapeAnalysis = new OptionValue<>(2f);
    -    @Option(help = "")
    -    public static final OptionValue RelevanceCapForInlining = new OptionValue<>(1f);
    -    @Option(help = "")
    -    public static final OptionValue CapInheritedRelevance = new OptionValue<>(1f);
    -    @Option(help = "")
    -    public static final OptionValue IterativeInlining = new OptionValue<>(false);
    -
    -    @Option(help = "")
    -    public static final OptionValue TrivialInliningSize = new OptionValue<>(10);
    -    @Option(help = "")
    -    public static final OptionValue MaximumInliningSize = new OptionValue<>(300);
    -    @Option(help = "")
    -    public static final OptionValue SmallCompiledLowLevelGraphSize = new OptionValue<>(300);
    -    @Option(help = "")
    -    public static final OptionValue LimitInlinedInvokes = new OptionValue<>(5.0);
    -    @Option(help = "")
    -    public static final OptionValue InlineEverything = new OptionValue<>(false);
    -
    -    // escape analysis settings
    -    @Option(help = "")
    -    public static final OptionValue PartialEscapeAnalysis = new OptionValue<>(true);
    -    @Option(help = "")
    -    public static final OptionValue EscapeAnalysisIterations = new OptionValue<>(2);
    -    @Option(help = "")
    -    public static final OptionValue EscapeAnalyzeOnly = new OptionValue<>(null);
    -    @Option(help = "")
    -    public static final OptionValue MaximumEscapeAnalysisArrayLength = new OptionValue<>(32);
    -    @Option(help = "")
    -    public static final OptionValue PEAInliningHints = new OptionValue<>(false);
    -
    -    @Option(help = "")
    -    public static final OptionValue TailDuplicationProbability = new OptionValue<>(0.5);
    -    @Option(help = "")
    -    public static final OptionValue TailDuplicationTrivialSize = new OptionValue<>(1);
    -
    -    // profiling information
    -    @Option(help = "")
    -    public static final OptionValue DeoptsToDisableOptimisticOptimization = new OptionValue<>(40);
    -
    -    // graph caching
    -    @Option(help = "")
    -    public static final OptionValue CacheGraphs = new OptionValue<>(true);
    -
    -    //loop transform settings TODO (gd) tune
    -    @Option(help = "")
    -    public static final OptionValue LoopPeeling = new OptionValue<>(true);
    -    @Option(help = "")
    -    public static final OptionValue ReassociateInvariants = new OptionValue<>(true);
    -    @Option(help = "")
    -    public static final OptionValue FullUnroll = new OptionValue<>(true);
    -    @Option(help = "")
    -    public static final OptionValue LoopUnswitch = new OptionValue<>(true);
    -    @Option(help = "")
    -    public static final OptionValue FullUnrollMaxNodes = new OptionValue<>(300);
    -    @Option(help = "")
    -    public static final OptionValue ExactFullUnrollMaxNodes = new OptionValue<>(1200);
    -    @Option(help = "")
    -    public static final OptionValue MinimumPeelProbability = new OptionValue<>(0.35f);
    -    @Option(help = "")
    -    public static final OptionValue LoopMaxUnswitch = new OptionValue<>(3);
    -    @Option(help = "")
    -    public static final OptionValue LoopUnswitchMaxIncrease = new OptionValue<>(50);
    -    @Option(help = "")
    -    public static final OptionValue LoopUnswitchUncertaintyBoost = new OptionValue<>(5);
    -    @Option(help = "")
    -    public static final OptionValue UseLoopLimitChecks = new OptionValue<>(true);
    -
    -    // debugging settings
    -    @Option(help = "")
    -    public static final OptionValue ZapStackOnMethodEntry = new OptionValue<>(false);
    -    @Option(help = "")
    -    public static final OptionValue DeoptALot = new OptionValue<>(false);
    -    @Option(help = "")
    -    public static final OptionValue VerifyPhases = new OptionValue<>(false);
    -
    -    @Option(help = "")
    -    public static final OptionValue PrintFilter = new OptionValue<>(null);
    -
    -    // Debug settings:
    -    @Option(help = "")
    -    public static final OptionValue BootstrapReplacements = new OptionValue<>(false);
    -    @Option(help = "")
    -    public static final OptionValue GCDebugStartCycle = new OptionValue<>(-1);
    -    // Ideal graph visualizer output settings
    -    @Option(help = "Dump IdealGraphVisualizer output in binary format")
    -    public static final OptionValue PrintBinaryGraphs = new OptionValue<>(true);
    -    @Option(help = "Output probabilities for fixed nodes during binary graph dumping")
    -    public static final OptionValue PrintGraphProbabilities = new OptionValue<>(false);
    -    @Option(help = "Enable dumping to the C1Visualizer. Enabling this option implies PrintBackendCFG.")
    -    public static final OptionValue PrintCFG = new OptionValue<>(false);
    -    @Option(help = "Enable dumping LIR, register allocation and code generation info to the C1Visualizer.")
    -    public static final OptionValue PrintBackendCFG = new OptionValue<>(true);
    -    @Option(help = "")
    -    public static final OptionValue PrintIdealGraphFile = new OptionValue<>(false);
    -    @Option(help = "")
    -    public static final OptionValue PrintIdealGraphAddress = new OptionValue<>("127.0.0.1");
    -    @Option(help = "")
    -    public static final OptionValue PrintIdealGraphPort = new OptionValue<>(4444);
    -    @Option(help = "")
    -    public static final OptionValue PrintBinaryGraphPort = new OptionValue<>(4445);
    -
    -    // Other printing settings
    -    @Option(help = "")
    -    public static final OptionValue PrintCompilation = new OptionValue<>(false);
    -    @Option(help = "")
    -    public static final OptionValue PrintAfterCompilation = new OptionValue<>(false);
    -    @Option(help = "Print profiling information when parsing a method's bytecode")
    -    public static final OptionValue PrintProfilingInformation = new OptionValue<>(false);
    -    @Option(help = "")
    -    public static final OptionValue PrintCodeBytes = new OptionValue<>(false);
    -    @Option(help = "")
    -    public static final OptionValue PrintBailout = new OptionValue<>(false);
    -    @Option(help = "")
    -    public static final OptionValue TraceEscapeAnalysis = new OptionValue<>(false);
    -    @Option(help = "")
    -    public static final OptionValue ExitVMOnBailout = new OptionValue<>(false);
    -    @Option(help = "")
    -    public static final OptionValue ExitVMOnException = new OptionValue<>(true);
    -    @Option(help = "")
    -    public static final OptionValue PrintStackTraceOnException = new OptionValue<>(false);
    -    @Option(help = "Set a phase after which the decompiler dumps the graph, -G:Dump= required")
    -    public static final OptionValue DecompileAfterPhase = new OptionValue<>(null);
    -
    -    // HotSpot command line options
    -    @Option(help = "")
    -    public static final OptionValue HotSpotPrintCompilation = new OptionValue<>(false);
    -    @Option(help = "")
    -    public static final OptionValue HotSpotCIPrintCompilerName = new OptionValue<>(false);
    -    @Option(help = "")
    -    public static final OptionValue HotSpotPrintInlining = new OptionValue<>(false);
    -
    -    // Register allocator debugging
    -    @Option(help = "")
    -    public static final OptionValue RegisterPressure = new OptionValue<>(null);
    -
    -    // Code generator settings
    -    @Option(help = "")
    -    public static final OptionValue ConditionalElimination = new OptionValue<>(true);
    -    @Option(help = "")
    -    public static final OptionValue UseProfilingInformation = new OptionValue<>(true);
    -    @Option(help = "")
    -           static final OptionValue RemoveNeverExecutedCode = new OptionValue<>(true);
    -           @Option(help = "")
    -           static final OptionValue UseExceptionProbability = new OptionValue<>(true);
    -           @Option(help = "")
    -           static final OptionValue UseExceptionProbabilityForOperations = new OptionValue<>(true);
    -           @Option(help = "")
    -    public static final OptionValue OmitHotExceptionStacktrace = new OptionValue<>(false);
    -    @Option(help = "")
    -    public static final OptionValue GenSafepoints = new OptionValue<>(true);
    -    @Option(help = "")
    -    public static final OptionValue GenLoopSafepoints = new OptionValue<>(true);
    -    @Option(help = "")
    -           static final OptionValue UseTypeCheckHints = new OptionValue<>(true);
    -           @Option(help = "")
    -    public static final OptionValue InlineVTableStubs = new OptionValue<>(true);
    -    @Option(help = "")
    -    public static final OptionValue AlwaysInlineVTableStubs = new OptionValue<>(false);
    -    @Option(help = "")
    -    public static final OptionValue GenAssertionCode = new OptionValue<>(false);
    -    @Option(help = "")
    -    public static final OptionValue AlignCallsForPatching = new OptionValue<>(true);
    -    @Option(help = "")
    -    public static final OptionValue ResolveClassBeforeStaticInvoke = new OptionValue<>(false);
    -    @Option(help = "")
    -    public static final OptionValue CanOmitFrame = new OptionValue<>(true);
    -
    -    @Option(help = "")
    -    public static final OptionValue MemoryAwareScheduling = new OptionValue<>(true);
    -
    -    // Translating tableswitch instructions
    -    @Option(help = "")
    -    public static final OptionValue MinimumJumpTableSize = new OptionValue<>(5);
    -    @Option(help = "")
    -    public static final OptionValue RangeTestsSwitchDensity = new OptionValue<>(5);
    -    @Option(help = "")
    -    public static final OptionValue MinTableSwitchDensity = new OptionValue<>(0.5);
    -
    -    // Ahead of time compilation
    -    @Option(help = "Try to avoid emitting code where patching is required")
    -    public static final OptionValue ImmutableCode = new OptionValue<>(false);
    -
    -    @Option(help = "")
    -    public static final OptionValue CallArrayCopy = new OptionValue<>(true);
    -
    -    // Runtime settings
    -    @Option(help = "")
    -    public static final OptionValue SupportJsrBytecodes = new OptionValue<>(true);
    -
    -    @Option(help = "")
    -    public static final OptionValue OptAssumptions = new OptionValue<>(true);
    -    @Option(help = "")
    -    public static final OptionValue OptConvertDeoptsToGuards = new OptionValue<>(true);
    -    @Option(help = "")
    -    public static final OptionValue OptReadElimination = new OptionValue<>(true);
    -    @Option(help = "")
    -    public static final OptionValue OptCanonicalizer = new OptionValue<>(true);
    -    @Option(help = "")
    -    public static final OptionValue OptDeoptimizationGrouping = new OptionValue<>(true);
    -    @Option(help = "")
    -    public static final OptionValue OptScheduleOutOfLoops = new OptionValue<>(true);
    -    @Option(help = "")
    -    public static final OptionValue OptEliminateGuards = new OptionValue<>(true);
    -    @Option(help = "")
    -    public static final OptionValue OptImplicitNullChecks = new OptionValue<>(true);
    -    @Option(help = "")
    -    public static final OptionValue OptLivenessAnalysis = new OptionValue<>(true);
    -    @Option(help = "")
    -    public static final OptionValue OptLoopTransform = new OptionValue<>(true);
    -    @Option(help = "")
    -    public static final OptionValue OptFloatingReads = new OptionValue<>(true);
    -    @Option(help = "")
    -    public static final OptionValue OptTailDuplication = new OptionValue<>(true);
    -    @Option(help = "")
    -    public static final OptionValue OptEliminatePartiallyRedundantGuards = new OptionValue<>(true);
    -    @Option(help = "")
    -    public static final OptionValue OptFilterProfiledTypes = new OptionValue<>(true);
    -    @Option(help = "")
    -    public static final OptionValue OptDevirtualizeInvokesOptimistically = new OptionValue<>(true);
    -    @Option(help = "")
    -    public static final OptionValue OptPushThroughPi = new OptionValue<>(true);
    -    @Option(help = "Allow backend to emit arithmetic and compares directly against memory.")
    -    public static final OptionValue OptFoldMemory = new OptionValue<>(true);
    -
    -
    -    /**
    -     * Counts the various paths taken through snippets.
    -     */
    -    @Option(help = "")
    -    public static final OptionValue SnippetCounters = new OptionValue<>(false);
    -}
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.phases/src/com/oracle/graal/phases/OptimisticOptimizations.java
    --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/OptimisticOptimizations.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/OptimisticOptimizations.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -25,6 +25,7 @@
     import java.util.*;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.*;
     import com.oracle.graal.debug.*;
     
     public final class OptimisticOptimizations {
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/ComputeInliningRelevanceClosure.java
    --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/ComputeInliningRelevanceClosure.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/ComputeInliningRelevanceClosure.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -24,6 +24,7 @@
     
     import java.util.*;
     
    +import com.oracle.graal.compiler.common.cfg.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.cfg.*;
    @@ -105,26 +106,26 @@
             private Scope[] computeScopes() {
                 ControlFlowGraph cfg = ControlFlowGraph.compute(graph, true, true, false, false);
     
    -            Loop[] loops = cfg.getLoops();
    -            HashMap processedScopes = new HashMap<>();
    -            Scope[] result = new Scope[loops.length + 1];
    +            List> loops = cfg.getLoops();
    +            HashMap, Scope> processedScopes = new HashMap<>();
    +            Scope[] result = new Scope[loops.size() + 1];
                 Scope methodScope = new Scope(graph.start(), null);
                 processedScopes.put(null, methodScope);
     
                 result[0] = methodScope;
    -            for (int i = 0; i < loops.length; i++) {
    -                result[i + 1] = createScope(loops[i], processedScopes);
    +            for (int i = 0; i < loops.size(); i++) {
    +                result[i + 1] = createScope(loops.get(i), processedScopes);
                 }
     
                 return result;
             }
     
    -        private Scope createScope(Loop loop, HashMap processedLoops) {
    +        private Scope createScope(Loop loop, HashMap, Scope> processedLoops) {
                 Scope parent = processedLoops.get(loop.parent);
                 if (parent == null) {
                     parent = createScope(loop.parent, processedLoops);
                 }
    -            Scope result = new Scope(loop.loopBegin(), parent);
    +            Scope result = new Scope(loop.header.getBeginNode(), parent);
                 processedLoops.put(loop, result);
                 return result;
             }
    @@ -171,7 +172,7 @@
             int pathBeginCount = pathBeginNodes.size();
     
             for (Node sux : controlSplit.successors()) {
    -            double probability = controlSplit.probability((AbstractBeginNode) sux);
    +            double probability = controlSplit.probability((BeginNode) sux);
                 if (probability > maxProbability) {
                     maxProbability = probability;
                     maxSux = sux;
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/ComputeProbabilityClosure.java
    --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/ComputeProbabilityClosure.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/ComputeProbabilityClosure.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -223,7 +223,7 @@
             }
     
             @Override
    -        public void afterSplit(AbstractBeginNode node) {
    +        public void afterSplit(BeginNode node) {
                 assert node.predecessor() != null;
                 Node pred = node.predecessor();
                 ControlSplitNode x = (ControlSplitNode) pred;
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/InferStamps.java
    --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/InferStamps.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/InferStamps.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,10 +22,10 @@
      */
     package com.oracle.graal.phases.graph;
     
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
     
     public class InferStamps {
     
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/MergeableState.java
    --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/MergeableState.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/MergeableState.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -58,7 +58,7 @@
          * 
          * @param node the successor of the control split that is about to be visited
          */
    -    public void afterSplit(AbstractBeginNode node) {
    +    public void afterSplit(BeginNode node) {
             // empty default implementation
         }
     }
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/PostOrderNodeIterator.java
    --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/PostOrderNodeIterator.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/PostOrderNodeIterator.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -43,7 +43,7 @@
     public abstract class PostOrderNodeIterator> {
     
         private final NodeBitMap visitedEnds;
    -    private final Deque nodeQueue;
    +    private final Deque nodeQueue;
         private final IdentityHashMap nodeStates;
         private final FixedNode start;
     
    @@ -109,13 +109,13 @@
                 for (Node node : successors) {
                     if (node != null) {
                         nodeStates.put((FixedNode) node.predecessor(), state);
    -                    nodeQueue.addFirst((AbstractBeginNode) node);
    +                    nodeQueue.addFirst((BeginNode) node);
                     }
                 }
             } else {
                 for (Node node : x.successors()) {
                     if (node != null) {
    -                    nodeQueue.addFirst((AbstractBeginNode) node);
    +                    nodeQueue.addFirst((BeginNode) node);
                     }
                 }
             }
    @@ -124,7 +124,7 @@
         private FixedNode nextQueuedNode() {
             int maxIterations = nodeQueue.size();
             while (maxIterations-- > 0) {
    -            AbstractBeginNode node = nodeQueue.removeFirst();
    +            BeginNode node = nodeQueue.removeFirst();
                 if (node instanceof MergeNode) {
                     MergeNode merge = (MergeNode) node;
                     state = nodeStates.get(merge.forwardEndAt(0)).clone();
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/ReentrantBlockIterator.java
    --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/ReentrantBlockIterator.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/ReentrantBlockIterator.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -24,6 +24,7 @@
     
     import java.util.*;
     
    +import com.oracle.graal.compiler.common.cfg.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.cfg.*;
     
    @@ -45,14 +46,14 @@
     
             protected abstract StateT cloneState(StateT oldState);
     
    -        protected abstract List processLoop(Loop loop, StateT initialState);
    +        protected abstract List processLoop(Loop loop, StateT initialState);
         }
     
         private ReentrantBlockIterator() {
             // no instances allowed
         }
     
    -    public static  LoopInfo processLoop(BlockIteratorClosure closure, Loop loop, StateT initialState) {
    +    public static  LoopInfo processLoop(BlockIteratorClosure closure, Loop loop, StateT initialState) {
             IdentityHashMap blockEndStates = apply(closure, loop.header, initialState, new HashSet<>(loop.blocks));
     
             LoopInfo info = new LoopInfo<>();
    @@ -101,8 +102,8 @@
                                 states.put(current.getEndNode(), state);
                             } else {
                                 // recurse into the loop
    -                            Loop loop = successor.getLoop();
    -                            LoopBeginNode loopBegin = loop.loopBegin();
    +                            Loop loop = successor.getLoop();
    +                            LoopBeginNode loopBegin = (LoopBeginNode) loop.header.getBeginNode();
                                 assert successor.getBeginNode() == loopBegin;
     
                                 List exitStates = closure.processLoop(loop, state);
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/ReentrantNodeIterator.java
    --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/ReentrantNodeIterator.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/ReentrantNodeIterator.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -41,7 +41,7 @@
     
             protected abstract StateT merge(MergeNode merge, List states);
     
    -        protected abstract StateT afterSplit(AbstractBeginNode node, StateT oldState);
    +        protected abstract StateT afterSplit(BeginNode node, StateT oldState);
     
             protected abstract Map processLoop(LoopBeginNode loop, StateT initialState);
     
    @@ -81,7 +81,7 @@
         }
     
         public static  Map apply(NodeIteratorClosure closure, FixedNode start, StateT initialState, Set boundary) {
    -        Deque nodeQueue = new ArrayDeque<>();
    +        Deque nodeQueue = new ArrayDeque<>();
             IdentityHashMap blockEndStates = new IdentityHashMap<>();
     
             StateT state = initialState;
    @@ -146,14 +146,14 @@
                                 continue;
                             } else {
                                 while (successors.hasNext()) {
    -                                AbstractBeginNode successor = (AbstractBeginNode) successors.next();
    +                                BeginNode successor = (BeginNode) successors.next();
                                     StateT successorState = closure.afterSplit(successor, state);
                                     if (closure.continueIteration(successorState)) {
                                         blockEndStates.put(successor, successorState);
                                         nodeQueue.add(successor);
                                     }
                                 }
    -                            state = closure.afterSplit((AbstractBeginNode) firstSuccessor, state);
    +                            state = closure.afterSplit((BeginNode) firstSuccessor, state);
                                 current = closure.continueIteration(state) ? firstSuccessor : null;
                                 continue;
                             }
    @@ -167,7 +167,7 @@
                 } else {
                     current = nodeQueue.removeFirst();
                     state = blockEndStates.get(current);
    -                assert !(current instanceof MergeNode) && current instanceof AbstractBeginNode;
    +                assert !(current instanceof MergeNode) && current instanceof BeginNode;
                 }
             } while (true);
         }
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/StatelessPostOrderNodeIterator.java
    --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/StatelessPostOrderNodeIterator.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/StatelessPostOrderNodeIterator.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -36,7 +36,7 @@
     public abstract class StatelessPostOrderNodeIterator {
     
         private final NodeBitMap visitedEnds;
    -    private final Deque nodeQueue;
    +    private final Deque nodeQueue;
         private final FixedNode start;
     
         public StatelessPostOrderNodeIterator(FixedNode start) {
    @@ -76,7 +76,7 @@
                     controlSplit((ControlSplitNode) current);
                     for (Node node : current.successors()) {
                         if (node != null) {
    -                        nodeQueue.addFirst((AbstractBeginNode) node);
    +                        nodeQueue.addFirst((BeginNode) node);
                         }
                     }
                     current = nodeQueue.pollFirst();
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java
    --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,12 +23,14 @@
     package com.oracle.graal.phases.schedule;
     
     import static com.oracle.graal.api.meta.LocationIdentity.*;
    +import static com.oracle.graal.compiler.common.GraalOptions.*;
     import static com.oracle.graal.nodes.cfg.ControlFlowGraph.*;
    -import static com.oracle.graal.phases.GraalOptions.*;
     
     import java.util.*;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.*;
    +import com.oracle.graal.compiler.common.cfg.*;
     import com.oracle.graal.debug.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.graph.Node.Verbosity;
    @@ -152,7 +154,7 @@
             }
     
             @Override
    -        protected List processLoop(Loop loop, KillSet state) {
    +        protected List processLoop(Loop loop, KillSet state) {
                 LoopInfo info = ReentrantBlockIterator.processLoop(this, loop, cloneState(state));
     
                 assert loop.header.getBeginNode() instanceof LoopBeginNode;
    @@ -201,7 +203,7 @@
                 }
             }
     
    -        AbstractBeginNode startNode = cfg.getStartBlock().getBeginNode();
    +        BeginNode startNode = cfg.getStartBlock().getBeginNode();
             assert startNode instanceof StartNode;
     
             KillSet accm = foundExcludeNode ? set : excludedLocations;
    @@ -649,12 +651,7 @@
              * implies that the inputs' blocks have a total ordering via their dominance relation. So in
              * order to find the earliest block placement for this node we need to find the input block
              * that is dominated by all other input blocks.
    -         * 
    -         * While iterating over the inputs a set of dominator blocks of the current earliest
    -         * placement is maintained. When the block of an input is not within this set, it becomes
    -         * the current earliest placement and the list of dominator blocks is updated.
              */
    -        BitSet dominators = new BitSet(cfg.getBlocks().length);
     
             if (node.predecessor() != null) {
                 throw new SchedulingError();
    @@ -667,12 +664,24 @@
                 } else {
                     inputEarliest = earliestBlock(input);
                 }
    -            if (!dominators.get(inputEarliest.getId())) {
    +            if (earliest == null) {
                     earliest = inputEarliest;
    -                do {
    -                    dominators.set(inputEarliest.getId());
    -                    inputEarliest = inputEarliest.getDominator();
    -                } while (inputEarliest != null && !dominators.get(inputEarliest.getId()));
    +            } else if (earliest != inputEarliest) {
    +                // Find out whether earliest or inputEarliest is earlier.
    +                Block a = earliest.getDominator();
    +                Block b = inputEarliest;
    +                while (true) {
    +                    if (a == inputEarliest || b == null) {
    +                        // Nothing to change, the previous earliest block is still earliest.
    +                        break;
    +                    } else if (b == earliest || a == null) {
    +                        // New earliest is the earliest.
    +                        earliest = inputEarliest;
    +                        break;
    +                    }
    +                    a = a.getDominator();
    +                    b = b.getDominator();
    +                }
                 }
             }
             if (earliest == null) {
    @@ -753,7 +762,7 @@
                         // If a FrameState is an outer FrameState this method behaves as if the inner
                         // FrameState was the actual usage, by recursing.
                         blocksForUsage(node, unscheduledUsage, closure, strategy);
    -                } else if (unscheduledUsage instanceof AbstractBeginNode) {
    +                } else if (unscheduledUsage instanceof BeginNode) {
                         // Only FrameStates can be connected to BeginNodes.
                         if (!(usage instanceof FrameState)) {
                             throw new SchedulingError(usage.toString());
    @@ -922,7 +931,7 @@
                 }
                 if (canNotMove) {
                     if (b.getEndNode() instanceof ControlSplitNode) {
    -                    throw new GraalInternalError("Schedule is not possible : needs to move a node after the last node of the block which can not be move").addContext(lastSorted).addContext(
    +                    throw new GraalGraphInternalError("Schedule is not possible : needs to move a node after the last node of the block which can not be move").addContext(lastSorted).addContext(
                                         b.getEndNode());
                     }
     
    @@ -977,13 +986,21 @@
                 stateAfter = ((StateSplit) i).stateAfter();
             }
     
    +        if (i instanceof LoopExitNode) {
    +            for (ProxyNode proxy : ((LoopExitNode) i).proxies()) {
    +                addToLatestSorting(b, proxy, sortedInstructions, visited, reads, beforeLastLocation);
    +            }
    +        }
    +
             for (Node input : i.inputs()) {
                 if (input instanceof FrameState) {
                     if (input != stateAfter) {
                         addUnscheduledToLatestSorting(b, (FrameState) input, sortedInstructions, visited, reads, beforeLastLocation);
                     }
                 } else {
    -                addToLatestSorting(b, (ScheduledNode) input, sortedInstructions, visited, reads, beforeLastLocation);
    +                if (!(i instanceof ProxyNode && input instanceof LoopExitNode)) {
    +                    addToLatestSorting(b, (ScheduledNode) input, sortedInstructions, visited, reads, beforeLastLocation);
    +                }
                 }
             }
     
    @@ -1047,7 +1064,7 @@
                     }
                 }
     
    -            if (instruction instanceof AbstractBeginNode) {
    +            if (instruction instanceof BeginNode) {
                     ArrayList proxies = (instruction instanceof LoopExitNode) ? new ArrayList<>() : null;
                     for (ScheduledNode inBlock : blockToNodesMap.get(b)) {
                         if (!visited.isMarked(inBlock)) {
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/Suites.java
    --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/Suites.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/Suites.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -26,7 +26,7 @@
     
     import java.util.*;
     
    -import com.oracle.graal.graph.*;
    +import com.oracle.graal.compiler.common.*;
     import com.oracle.graal.options.*;
     import com.oracle.graal.phases.*;
     
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.phases/src/com/oracle/graal/phases/util/GraphOrder.java
    --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/util/GraphOrder.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/util/GraphOrder.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -24,10 +24,13 @@
     
     import java.util.*;
     
    +import com.oracle.graal.compiler.common.*;
    +import com.oracle.graal.compiler.common.cfg.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.VirtualState.NodeClosure;
     import com.oracle.graal.nodes.cfg.*;
    +import com.oracle.graal.nodes.virtual.*;
     import com.oracle.graal.phases.graph.*;
     import com.oracle.graal.phases.graph.ReentrantBlockIterator.BlockIteratorClosure;
     import com.oracle.graal.phases.schedule.*;
    @@ -58,16 +61,10 @@
                 } else {
                     for (Node input : node.inputs()) {
                         if (!visited.isMarked(input)) {
    -                        if (input instanceof FrameState && node instanceof StateSplit && input == ((StateSplit) node).stateAfter()) {
    -                            // nothing to do - after frame states are known, allowed cycles
    +                        if (input instanceof FrameState) {
    +                            // nothing to do - frame states are known, allowed cycles
                             } else {
    -                            /*
    -                             * TODO assertion does not hold for Substrate VM (in general for all
    -                             * notDataflow inputs)
    -                             * 
    -                             * assert false : "unexpected cycle detected at input " + node + " -> "
    -                             * + input;
    -                             */
    +                            assert false : "unexpected cycle detected at input " + node + " -> " + input;
                             }
                         }
                     }
    @@ -125,8 +122,7 @@
                     }
                 }
             } catch (GraalInternalError e) {
    -            e.addContext(node);
    -            throw e;
    +            throw GraalGraphInternalError.transformAndAddContext(e, node);
             }
         }
     
    @@ -146,7 +142,7 @@
                 BlockIteratorClosure closure = new BlockIteratorClosure() {
     
                     @Override
    -                protected List processLoop(Loop loop, NodeBitMap initialState) {
    +                protected List processLoop(Loop loop, NodeBitMap initialState) {
                         return ReentrantBlockIterator.processLoop(this, loop, initialState).exitStates;
                     }
     
    @@ -162,11 +158,15 @@
                         FrameState pendingStateAfter = null;
                         for (final ScheduledNode node : list) {
                             FrameState stateAfter = node instanceof StateSplit ? ((StateSplit) node).stateAfter() : null;
    +                        if (node instanceof InfopointNode) {
    +                            stateAfter = ((InfopointNode) node).getState();
    +                        }
     
                             if (pendingStateAfter != null && node instanceof FixedNode) {
                                 pendingStateAfter.applyToNonVirtual(new NodeClosure() {
                                     public void apply(Node usage, Node nonVirtualNode) {
    -                                    assert currentState.isMarked(nonVirtualNode) : nonVirtualNode + " not available at virtualstate " + usage + " before " + node + " in block " + block + " \n" + list;
    +                                    assert currentState.isMarked(nonVirtualNode) || nonVirtualNode instanceof VirtualObjectNode : nonVirtualNode + " not available at virtualstate " + usage +
    +                                                    " before " + node + " in block " + block + " \n" + list;
                                     }
                                 });
                                 pendingStateAfter = null;
    @@ -186,15 +186,23 @@
                                     }
                                 }
                             } else if (node instanceof LoopExitNode) {
    -                            // the contents of the loop are only accessible via proxies at the exit
    -                            currentState.clearAll();
    -                            currentState.markAll(loopEntryStates.get(((LoopExitNode) node).loopBegin()));
    +                            if (!graph.isAfterFloatingReadPhase()) {
    +                                // loop contents are only accessible via proxies at the exit
    +                                currentState.clearAll();
    +                                currentState.markAll(loopEntryStates.get(((LoopExitNode) node).loopBegin()));
    +                            }
                                 // Loop proxies aren't scheduled, so they need to be added explicitly
                                 currentState.markAll(((LoopExitNode) node).proxies());
                             } else {
                                 for (Node input : node.inputs()) {
                                     if (input != stateAfter) {
    -                                    assert currentState.isMarked(input) : input + " not available at " + node + " in block " + block + "\n" + list;
    +                                    if (input instanceof FrameState) {
    +                                        ((FrameState) input).applyToNonVirtual((usage, nonVirtual) -> {
    +                                            assert currentState.isMarked(nonVirtual) : nonVirtual + " not available at " + node + " in block " + block + "\n" + list;
    +                                        });
    +                                    } else {
    +                                        assert currentState.isMarked(input) || input instanceof VirtualObjectNode : input + " not available at " + node + " in block " + block + "\n" + list;
    +                                    }
                                     }
                                 }
                             }
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.phases/src/com/oracle/graal/phases/util/Providers.java
    --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/util/Providers.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/util/Providers.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -24,13 +24,14 @@
     
     import com.oracle.graal.api.code.*;
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.spi.*;
     import com.oracle.graal.nodes.spi.*;
     import com.oracle.graal.phases.tiers.*;
     
     /**
      * A set of providers, some of which may not be present (i.e., null).
      */
    -public class Providers {
    +public class Providers implements CodeGenProviders {
     
         private final MetaAccessProvider metaAccess;
         private final CodeCacheProvider codeCache;
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.phases/src/com/oracle/graal/phases/verify/VerifyUsageWithEquals.java
    --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/verify/VerifyUsageWithEquals.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/verify/VerifyUsageWithEquals.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,6 +23,7 @@
     package com.oracle.graal.phases.verify;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.calc.*;
     import com.oracle.graal.nodes.type.*;
    @@ -45,7 +46,7 @@
         private boolean isAssignableType(ValueNode node, MetaAccessProvider metaAccess) {
             if (node.stamp() instanceof ObjectStamp) {
                 ResolvedJavaType valueType = metaAccess.lookupJavaType(klass);
    -            ResolvedJavaType nodeType = ObjectStamp.typeOrNull(node);
    +            ResolvedJavaType nodeType = StampTool.typeOrNull(node);
     
                 if (nodeType != null && valueType.isAssignableFrom(nodeType)) {
                     return true;
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.printer/src/com/oracle/graal/printer/BinaryGraphPrinter.java
    --- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/BinaryGraphPrinter.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/BinaryGraphPrinter.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,7 +22,7 @@
      */
     package com.oracle.graal.printer;
     
    -import static com.oracle.graal.phases.GraalOptions.*;
    +import static com.oracle.graal.compiler.common.GraalOptions.*;
     
     import java.io.*;
     import java.nio.*;
    @@ -31,6 +31,7 @@
     import java.util.Map.Entry;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.cfg.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.graph.NodeClass.Position;
     import com.oracle.graal.nodes.*;
    @@ -282,7 +283,7 @@
             } else if (object instanceof Enum) {
                 writeByte(POOL_ENUM);
                 writePoolObject(object.getClass());
    -            writeInt(((Enum) object).ordinal());
    +            writeInt(((Enum) object).ordinal());
             } else if (object instanceof JavaType) {
                 JavaType type = (JavaType) object;
                 writeByte(POOL_CLASS);
    @@ -296,13 +297,13 @@
                 Collection directInputPositions = nodeClass.getFirstLevelInputPositions();
                 writeShort((char) directInputPositions.size());
                 for (Position pos : directInputPositions) {
    -                writeByte(pos.subIndex == NodeClass.NOT_ITERABLE ? 0 : 1);
    +                writeByte(pos.getSubIndex() == NodeClass.NOT_ITERABLE ? 0 : 1);
                     writePoolObject(nodeClass.getName(pos));
                 }
                 Collection directSuccessorPositions = nodeClass.getFirstLevelSuccessorPositions();
                 writeShort((char) directSuccessorPositions.size());
                 for (Position pos : directSuccessorPositions) {
    -                writeByte(pos.subIndex == NodeClass.NOT_ITERABLE ? 0 : 1);
    +                writeByte(pos.getSubIndex() == NodeClass.NOT_ITERABLE ? 0 : 1);
                     writePoolObject(nodeClass.getName(pos));
                 }
             } else if (object instanceof ResolvedJavaMethod) {
    @@ -432,7 +433,7 @@
         private void writeEdges(Node node, Collection positions) throws IOException {
             NodeClass nodeClass = node.getNodeClass();
             for (Position pos : positions) {
    -            if (pos.subIndex == NodeClass.NOT_ITERABLE) {
    +            if (pos.getSubIndex() == NodeClass.NOT_ITERABLE) {
                     Node edge = nodeClass.get(node, pos);
                     writeNodeRef(edge);
                 } else {
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CFGPrinter.java
    --- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CFGPrinter.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CFGPrinter.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -31,12 +31,14 @@
     import com.oracle.graal.api.meta.*;
     import com.oracle.graal.compiler.alloc.*;
     import com.oracle.graal.compiler.alloc.Interval.UsePosList;
    +import com.oracle.graal.compiler.common.cfg.*;
     import com.oracle.graal.compiler.gen.*;
     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.java.BciBlockMapping.BciBlock;
     import com.oracle.graal.lir.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.calc.*;
    @@ -53,10 +55,11 @@
         protected NodeLIRBuilder nodeLirGenerator;
         protected ControlFlowGraph cfg;
         protected SchedulePhase schedule;
    +    protected ResolvedJavaMethod method;
     
         /**
          * Creates a control flow graph printer.
    -     * 
    +     *
          * @param out where the output generated via this printer shown be written
          */
         public CFGPrinter(OutputStream out) {
    @@ -65,7 +68,7 @@
     
         /**
          * Prints the control flow graph denoted by a given block map.
    -     * 
    +     *
          * @param label A label describing the compilation phase that produced the control flow graph.
          * @param blockMap A data structure describing the blocks in a method and how they are
          *            connected.
    @@ -125,7 +128,7 @@
     
         /**
          * Prints the specified list of blocks.
    -     * 
    +     *
          * @param label A label describing the compilation phase that produced the control flow graph.
          * @param blocks The list of blocks to be printed.
          */
    @@ -154,6 +157,12 @@
                 printBlock(block, printNodes);
             }
             end("cfg");
    +        // NOTE: we do this only because the c1visualizer does not recognize the bytecode block if
    +        // it is proceeding the cfg blocks. Currently we have no direct influence on the emit order.
    +        // As a workaround we dump the bytecode after every cfg.
    +        if (method != null) {
    +            printBytecodes(new BytecodeDisassembler(false).disassemble(method));
    +        }
     
             latestScheduling = null;
         }
    @@ -204,8 +213,13 @@
             begin("block");
     
             out.print("name \"").print(blockToString(block)).println('"');
    -        out.println("from_bci -1");
    -        out.println("to_bci -1");
    +        if (block instanceof BciBlock) {
    +            out.print("from_bci ").println(((BciBlock) block).startBci);
    +            out.print("to_bci ").println(((BciBlock) block).endBci);
    +        } else {
    +            out.println("from_bci -1");
    +            out.println("to_bci -1");
    +        }
     
             out.print("predecessors ");
             for (AbstractBlock pred : block.getPredecessors()) {
    @@ -366,12 +380,12 @@
                     continue;
                 }
     
    -            if (pos.index != lastIndex) {
    +            if (pos.getIndex() != lastIndex) {
                     if (lastIndex != -1) {
                         out.print(suffix);
                     }
                     out.print(prefix).print(node.getNodeClass().getName(pos)).print(": ");
    -                lastIndex = pos.index;
    +                lastIndex = pos.getIndex();
                 }
                 out.print(nodeToString(node.getNodeClass().get(node, pos))).print(" ");
             }
    @@ -425,7 +439,7 @@
     
         /**
          * Prints the LIR for each instruction in a given block.
    -     * 
    +     *
          * @param block the block to print
          */
         private void printLIR(AbstractBlock block) {
    @@ -475,7 +489,7 @@
                 return "-";
             }
             String prefix;
    -        if (node instanceof AbstractBeginNode && (lir == null && schedule == null)) {
    +        if (node instanceof BeginNode && (lir == null && schedule == null)) {
                 prefix = "B";
             } else if (node instanceof ValueNode) {
                 ValueNode value = (ValueNode) node;
    diff -r 518a7f487c4f -r 9363fffa8b07 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 Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CFGPrinterObserver.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -29,6 +29,7 @@
     import com.oracle.graal.api.code.*;
     import com.oracle.graal.api.meta.*;
     import com.oracle.graal.compiler.alloc.*;
    +import com.oracle.graal.compiler.common.*;
     import com.oracle.graal.compiler.gen.*;
     import com.oracle.graal.debug.*;
     import com.oracle.graal.graph.*;
    @@ -131,6 +132,9 @@
             if (!checkMethodScope()) {
                 return;
             }
    +        if (curMethod instanceof ResolvedJavaMethod) {
    +            cfgPrinter.method = (ResolvedJavaMethod) curMethod;
    +        }
     
             if (object instanceof LIR) {
                 cfgPrinter.lir = (LIR) object;
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.printer/src/com/oracle/graal/printer/DebugEnvironment.java
    --- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/DebugEnvironment.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/DebugEnvironment.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,7 +23,7 @@
     package com.oracle.graal.printer;
     
     import static com.oracle.graal.compiler.GraalDebugConfig.*;
    -import static com.oracle.graal.phases.GraalOptions.*;
    +import static com.oracle.graal.compiler.common.GraalOptions.*;
     
     import java.io.*;
     import java.util.*;
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.printer/src/com/oracle/graal/printer/DecompilerDebugDumpHandler.java
    --- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/DecompilerDebugDumpHandler.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/DecompilerDebugDumpHandler.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,7 +22,7 @@
      */
     package com.oracle.graal.printer;
     
    -import static com.oracle.graal.phases.GraalOptions.*;
    +import static com.oracle.graal.compiler.common.GraalOptions.*;
     
     import java.io.*;
     import java.util.concurrent.atomic.*;
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.printer/src/com/oracle/graal/printer/GraphPrinterDumpHandler.java
    --- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/GraphPrinterDumpHandler.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/GraphPrinterDumpHandler.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,7 +23,7 @@
     package com.oracle.graal.printer;
     
     import static com.oracle.graal.compiler.GraalDebugConfig.*;
    -import static com.oracle.graal.phases.GraalOptions.*;
    +import static com.oracle.graal.compiler.common.GraalOptions.*;
     
     import java.io.*;
     import java.net.*;
    diff -r 518a7f487c4f -r 9363fffa8b07 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 Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/IdealGraphPrinter.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -171,7 +171,7 @@
                         printProperty(bit, "true");
                     }
                 }
    -            if (node.getClass() == AbstractBeginNode.class) {
    +            if (node.getClass() == BeginNode.class) {
                     printProperty("shortName", "B");
                 } else if (node.getClass() == AbstractEndNode.class) {
                     printProperty("shortName", "E");
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64ConvertSnippets.java
    --- a/graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64ConvertSnippets.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64ConvertSnippets.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -26,6 +26,7 @@
     import static com.oracle.graal.replacements.SnippetTemplate.*;
     
     import com.oracle.graal.api.code.*;
    +import com.oracle.graal.api.replacements.*;
     import com.oracle.graal.debug.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.calc.*;
    @@ -49,7 +50,7 @@
          * conversion. If the float value is a NaN, infinity or if the result of the conversion is
          * larger than {@link Integer#MAX_VALUE} then CVTTSS2SI returns {@link Integer#MIN_VALUE} and
          * extra tests are required on the float value to return the correct int value.
    -     * 
    +     *
          * @param input the float being converted
          * @param result the result produced by the CVTTSS2SI instruction
          */
    @@ -74,7 +75,7 @@
          * conversion. If the float value is a NaN or infinity then CVTTSS2SI returns
          * {@link Long#MIN_VALUE} and extra tests are required on the float value to return the correct
          * long value.
    -     * 
    +     *
          * @param input the float being converted
          * @param result the result produced by the CVTTSS2SI instruction
          */
    @@ -99,7 +100,7 @@
          * conversion. If the double value is a NaN, infinity or if the result of the conversion is
          * larger than {@link Integer#MAX_VALUE} then CVTTSD2SI returns {@link Integer#MIN_VALUE} and
          * extra tests are required on the double value to return the correct int value.
    -     * 
    +     *
          * @param input the double being converted
          * @param result the result produced by the CVTTSS2SI instruction
          */
    @@ -124,7 +125,7 @@
          * conversion. If the double value is a NaN, infinity or if the result of the conversion is
          * larger than {@link Long#MAX_VALUE} then CVTTSD2SI returns {@link Long#MIN_VALUE} and extra
          * tests are required on the double value to return the correct long value.
    -     * 
    +     *
          * @param input the double being converted
          * @param result the result produced by the CVTTSS2SI instruction
          */
    @@ -149,8 +150,8 @@
             private final SnippetInfo d2i;
             private final SnippetInfo d2l;
     
    -        public Templates(Providers providers, TargetDescription target) {
    -            super(providers, target);
    +        public Templates(Providers providers, SnippetReflectionProvider snippetReflection, TargetDescription target) {
    +            super(providers, snippetReflection, target);
     
                 f2i = snippet(AMD64ConvertSnippets.class, "f2i");
                 f2l = snippet(AMD64ConvertSnippets.class, "f2l");
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64FloatConvertNode.java
    --- a/graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64FloatConvertNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64FloatConvertNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,12 +23,13 @@
     package com.oracle.graal.replacements.amd64;
     
     import com.oracle.graal.api.meta.*;
    -import com.oracle.graal.graph.*;
    +import com.oracle.graal.compiler.common.*;
    +import com.oracle.graal.compiler.common.calc.*;
    +import com.oracle.graal.compiler.common.type.*;
    +import com.oracle.graal.lir.gen.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.calc.*;
    -import com.oracle.graal.nodes.calc.FloatConvertNode.FloatConvert;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
     
     /**
      * This node has the semantics of the AMD64 floating point conversions. It is used in the lowering
    @@ -51,7 +52,7 @@
             throw GraalInternalError.shouldNotReachHere();
         }
     
    -    public void generate(NodeLIRBuilderTool gen) {
    -        gen.setResult(this, gen.getLIRGeneratorTool().emitFloatConvert(op, gen.operand(value)));
    +    public void generate(NodeMappableLIRBuilder builder, ArithmeticLIRGenerator gen) {
    +        builder.setResult(this, gen.emitFloatConvert(op, builder.operand(value)));
         }
     }
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64Substitutions.java
    --- a/graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64Substitutions.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64Substitutions.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,7 +23,7 @@
     
     package com.oracle.graal.replacements.amd64;
     
    -import static com.oracle.graal.phases.GraalOptions.*;
    +import static com.oracle.graal.compiler.common.GraalOptions.*;
     
     import com.oracle.graal.api.code.*;
     import com.oracle.graal.api.meta.*;
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.replacements.hsail/src/com/oracle/graal/replacements/hsail/HSAILMathIntrinsicsNode.java
    --- a/graal/com.oracle.graal.replacements.hsail/src/com/oracle/graal/replacements/hsail/HSAILMathIntrinsicsNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.replacements.hsail/src/com/oracle/graal/replacements/hsail/HSAILMathIntrinsicsNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,14 +23,16 @@
     package com.oracle.graal.replacements.hsail;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.compiler.hsail.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.graph.spi.*;
    +import com.oracle.graal.lir.gen.*;
     import com.oracle.graal.lir.hsail.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.calc.*;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
     
     /**
      * This node implements HSAIL intrinsics for specific {@link Math} routines.
    @@ -49,7 +51,7 @@
     
         /**
          * Gets the parameter passed to the math operation that this node represents.
    -     * 
    +     *
          * @return the parameter
          */
         public ValueNode getParameter() {
    @@ -58,7 +60,7 @@
     
         /**
          * Returns the math operation represented by this node.
    -     * 
    +     *
          * @return the operation
          */
         public HSAILArithmetic operation() {
    @@ -67,7 +69,7 @@
     
         /**
          * Creates a new HSAILMathIntrinsicNode.
    -     * 
    +     *
          * @param x the argument to the math operation
          * @param op the math operation
          */
    @@ -81,30 +83,30 @@
          * Generates the LIR instructions for the math operation represented by this node.
          */
         @Override
    -    public void generate(NodeLIRBuilderTool gen) {
    -        Value input = gen.operand(getParameter());
    +    public void generate(NodeMappableLIRBuilder builder, ArithmeticLIRGenerator gen) {
    +        Value input = builder.operand(getParameter());
             Value result;
             switch (operation()) {
                 case ABS:
    -                result = gen.getLIRGeneratorTool().emitMathAbs(input);
    +                result = gen.emitMathAbs(input);
                     break;
                 case CEIL:
    -                result = ((HSAILLIRGenerator) (gen.getLIRGeneratorTool())).emitMathCeil(input);
    +                result = ((HSAILLIRGenerator) gen).emitMathCeil(input);
                     break;
                 case FLOOR:
    -                result = ((HSAILLIRGenerator) (gen.getLIRGeneratorTool())).emitMathFloor(input);
    +                result = ((HSAILLIRGenerator) gen).emitMathFloor(input);
                     break;
                 case RINT:
    -                result = ((HSAILLIRGenerator) (gen.getLIRGeneratorTool())).emitMathRint(input);
    +                result = ((HSAILLIRGenerator) gen).emitMathRint(input);
                     break;
                 case SQRT:
    -                result = gen.getLIRGeneratorTool().emitMathSqrt(input);
    +                result = gen.emitMathSqrt(input);
                     break;
     
                 default:
                     throw GraalInternalError.shouldNotReachHere();
             }
    -        gen.setResult(this, result);
    +        builder.setResult(this, result);
         }
     
         /**
    @@ -132,7 +134,7 @@
     
         /**
          * Node intrinsic for {@link Math} routines taking a single int parameter.
    -     * 
    +     *
          * @param value
          * @param op the math operation
          * @return the result of the operation
    @@ -142,7 +144,7 @@
     
         /**
          * Node intrinsic for {@link Math} routines taking a single double parameter.
    -     * 
    +     *
          * @param value the input parameter
          * @param op the math operation
          * @return the result of the operation
    @@ -152,7 +154,7 @@
     
         /**
          * Node intrinsic for {@link Math} routines taking a single float parameter.
    -     * 
    +     *
          * @param value the input parameter
          * @param op the math operation
          * @return the result of the operation
    @@ -162,10 +164,10 @@
     
         /**
          * Node intrinsic for {@link Math} routines taking a single double parameter.
    -     * 
    +     *
          * @param value the input parameter
          * @param op the math operation
    -     * 
    +     *
          * @return the result of the operation
          */
         @NodeIntrinsic
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/InstanceOfDynamicTest.java
    --- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/InstanceOfDynamicTest.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/InstanceOfDynamicTest.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -82,11 +82,11 @@
             return o.getClass().getName().length();
         }
     
    -    public static boolean isInstanceDynamic(Class c, Object o) {
    +    public static boolean isInstanceDynamic(Class c, Object o) {
             return c.isInstance(o);
         }
     
    -    public static int isInstanceIntDynamic(Class c, Object o) {
    +    public static int isInstanceIntDynamic(Class c, Object o) {
             if (c.isInstance(o)) {
                 return o.toString().length();
             }
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/InstanceOfTest.java
    --- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/InstanceOfTest.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/InstanceOfTest.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -116,7 +116,7 @@
     
         @LongTest
         public void test5() {
    -        Map map = new HashMap<>();
    +        Map map = new HashMap<>();
             test("isMap", profile(), map);
             test("isMap", profile(HashMap.class), map);
             test("isMap", profile(TreeMap.class, HashMap.class), map);
    @@ -129,7 +129,7 @@
     
         @LongTest
         public void test6() {
    -        Map map = new HashMap<>();
    +        Map map = new HashMap<>();
             test("isMapInt", profile(), map);
             test("isMapInt", profile(HashMap.class), map);
             test("isMapInt", profile(TreeMap.class, HashMap.class), map);
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/NewInstanceTest.java
    --- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/NewInstanceTest.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/NewInstanceTest.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -135,8 +135,8 @@
             return new String(value);
         }
     
    -    public static HashMap newHashMap(int initialCapacity) {
    -        return new HashMap(initialCapacity);
    +    public static HashMap newHashMap(int initialCapacity) {
    +        return new HashMap<>(initialCapacity);
         }
     
         static class SomeObject {
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/NewMultiArrayTest.java
    --- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/NewMultiArrayTest.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/NewMultiArrayTest.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -83,12 +83,12 @@
     
         ResolvedJavaType arrayType;
         ResolvedJavaType bottomType;
    -    Class bottomClass;
    +    Class bottomClass;
         int[] dimensions;
     
         @LongTest
         public void test1() {
    -        for (Class clazz : new Class[]{byte.class, char.class, short.class, int.class, float.class, long.class, double.class, String.class}) {
    +        for (Class clazz : new Class[]{byte.class, char.class, short.class, int.class, float.class, long.class, double.class, String.class}) {
                 bottomClass = clazz;
                 bottomType = getMetaAccess().lookupJavaType(clazz);
                 arrayType = bottomType;
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/ObjectAccessTest.java
    --- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/ObjectAccessTest.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/ObjectAccessTest.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -47,7 +47,7 @@
         private final ReplacementsImpl installer;
     
         public ObjectAccessTest() {
    -        installer = new ReplacementsImpl(getProviders(), new Assumptions(false), getTarget());
    +        installer = new ReplacementsImpl(getProviders(), getSnippetReflection(), new Assumptions(false), getTarget());
         }
     
         private static final ThreadLocal inliningPolicy = new ThreadLocal<>();
    @@ -127,7 +127,7 @@
             JavaWriteNode write = (JavaWriteNode) graph.start().next();
             Assert.assertEquals(graph.getParameter(2), write.value());
             Assert.assertEquals(graph.getParameter(0), write.object());
    -        Assert.assertEquals(FrameState.AFTER_BCI, write.stateAfter().bci);
    +        Assert.assertEquals(BytecodeFrame.AFTER_BCI, write.stateAfter().bci);
     
             IndexedLocationNode location = (IndexedLocationNode) write.location();
             Assert.assertEquals(kind, location.getValueKind());
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/PointerTest.java
    --- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/PointerTest.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/PointerTest.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -53,7 +53,7 @@
     
         public PointerTest() {
             target = getCodeCache().getTarget();
    -        installer = new ReplacementsImpl(getProviders(), new Assumptions(false), getTarget());
    +        installer = new ReplacementsImpl(getProviders(), getSnippetReflection(), new Assumptions(false), getTarget());
         }
     
         private static final ThreadLocal inliningPolicy = new ThreadLocal<>();
    @@ -139,7 +139,7 @@
     
             JavaWriteNode write = (JavaWriteNode) cast.next();
             Assert.assertEquals(graph.getParameter(2), write.value());
    -        Assert.assertEquals(FrameState.AFTER_BCI, write.stateAfter().bci);
    +        Assert.assertEquals(BytecodeFrame.AFTER_BCI, write.stateAfter().bci);
     
             Assert.assertEquals(cast, write.object());
             Assert.assertEquals(graph.getParameter(0), cast.getInput());
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/StandardMethodSubstitutionsTest.java
    --- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/StandardMethodSubstitutionsTest.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/StandardMethodSubstitutionsTest.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
      * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
      *
      * This code is free software; you can redistribute it and/or modify it
    @@ -22,16 +22,10 @@
      */
     package com.oracle.graal.replacements.test;
     
    -import static com.oracle.graal.graph.UnsafeAccess.*;
    -import static com.oracle.graal.replacements.UnsafeSubstitutions.*;
    -
     import java.lang.reflect.*;
    -import java.util.concurrent.atomic.*;
     
     import org.junit.*;
     
    -import sun.misc.*;
    -
     import com.oracle.graal.api.code.*;
     import com.oracle.graal.api.replacements.*;
     import com.oracle.graal.nodes.*;
    @@ -44,287 +38,6 @@
      */
     public class StandardMethodSubstitutionsTest extends MethodSubstitutionTest {
     
    -    static long off(Object o, String name) {
    -        try {
    -            return unsafe.objectFieldOffset(o.getClass().getDeclaredField(name));
    -        } catch (Exception e) {
    -            Assert.fail(e.toString());
    -            return 0L;
    -        }
    -    }
    -
    -    static class Foo {
    -
    -        boolean z;
    -        byte b;
    -        short s;
    -        char c;
    -        int i;
    -        long l;
    -        float f;
    -        double d;
    -        Object o;
    -
    -        void testGet(Field field, long offset, String getName, Object value) throws Exception {
    -            field.set(this, value);
    -            Method m1 = Unsafe.class.getDeclaredMethod(getName, Object.class, long.class);
    -            Method m2 = UnsafeSubstitutions.class.getDeclaredMethod(getName, Object.class, Object.class, long.class);
    -            Object expected = m1.invoke(unsafe, this, offset);
    -            Object actual = m2.invoke(null, unsafe, this, offset);
    -            Assert.assertEquals(expected, actual);
    -        }
    -
    -        void testDirect(Field field, long offset, String type, Object value) throws Exception {
    -            if (type.equals("Boolean") || type.equals("Object")) {
    -                // No direct memory access for these types
    -                return;
    -            }
    -
    -            long address = unsafe.allocateMemory(offset + 16);
    -
    -            String getName = "get" + type;
    -            String putName = "put" + type;
    -            Method m1 = Unsafe.class.getDeclaredMethod(putName, long.class, field.getType());
    -            Method m2 = Unsafe.class.getDeclaredMethod(getName, long.class);
    -
    -            Method m3 = UnsafeSubstitutions.class.getDeclaredMethod(putName, Object.class, long.class, field.getType());
    -            Method m4 = UnsafeSubstitutions.class.getDeclaredMethod(getName, Object.class, long.class);
    -
    -            m1.invoke(unsafe, address + offset, value);
    -            Object expected = m2.invoke(unsafe, address + offset);
    -
    -            m3.invoke(null, unsafe, address + offset, value);
    -            Object actual = m4.invoke(null, unsafe, address + offset);
    -
    -            unsafe.freeMemory(address);
    -            Assert.assertEquals(expected, actual);
    -        }
    -
    -        void testPut(Field field, long offset, String putName, Object value) throws Exception {
    -            Object initialValue = field.get(new Foo());
    -            field.set(this, initialValue);
    -
    -            try {
    -                Method m1 = Unsafe.class.getDeclaredMethod(putName, Object.class, long.class, field.getType());
    -                Method m2 = UnsafeSubstitutions.class.getDeclaredMethod(putName, Object.class, Object.class, long.class, field.getType());
    -                m1.invoke(unsafe, this, offset, value);
    -                Object expected = field.get(this);
    -                m2.invoke(null, unsafe, this, offset, value);
    -                Object actual = field.get(this);
    -                Assert.assertEquals(expected, actual);
    -            } catch (NoSuchMethodException e) {
    -                if (!putName.startsWith("putOrdered")) {
    -                    throw e;
    -                }
    -            }
    -        }
    -
    -        void test(String fieldName, String typeSuffix, Object value) {
    -            try {
    -                Field field = Foo.class.getDeclaredField(fieldName);
    -                long offset = unsafe.objectFieldOffset(field);
    -                testGet(field, offset, "get" + typeSuffix, value);
    -                testGet(field, offset, "get" + typeSuffix + "Volatile", value);
    -                testPut(field, offset, "put" + typeSuffix, value);
    -                testPut(field, offset, "put" + typeSuffix + "Volatile", value);
    -                testPut(field, offset, "putOrdered" + typeSuffix, value);
    -                testDirect(field, offset, typeSuffix, value);
    -            } catch (Exception e) {
    -                throw new AssertionError(e);
    -            }
    -        }
    -    }
    -
    -    @Test
    -    public void testUnsafeSubstitutions() throws Exception {
    -        test("unsafeCompareAndSwapInt");
    -        test("unsafeCompareAndSwapLong");
    -        test("unsafeCompareAndSwapObject");
    -
    -        test("unsafeGetBoolean");
    -        test("unsafeGetByte");
    -        test("unsafeGetShort");
    -        test("unsafeGetChar");
    -        test("unsafeGetInt");
    -        test("unsafeGetLong");
    -        test("unsafeGetFloat");
    -        test("unsafeGetDouble");
    -        test("unsafeGetObject");
    -
    -        test("unsafePutBoolean");
    -        test("unsafePutByte");
    -        test("unsafePutShort");
    -        test("unsafePutChar");
    -        test("unsafePutInt");
    -        test("unsafePutFloat");
    -        test("unsafePutDouble");
    -        test("unsafePutObject");
    -
    -        test("unsafeDirectMemoryRead");
    -        test("unsafeDirectMemoryWrite");
    -
    -        AtomicInteger a1 = new AtomicInteger(42);
    -        AtomicInteger a2 = new AtomicInteger(42);
    -        assertEquals(unsafe.compareAndSwapInt(a1, off(a1, "value"), 42, 53), compareAndSwapInt(unsafe, a2, off(a2, "value"), 42, 53));
    -        assertEquals(a1.get(), a2.get());
    -
    -        AtomicLong l1 = new AtomicLong(42);
    -        AtomicLong l2 = new AtomicLong(42);
    -        assertEquals(unsafe.compareAndSwapLong(l1, off(l1, "value"), 42, 53), compareAndSwapLong(unsafe, l2, off(l2, "value"), 42, 53));
    -        assertEquals(l1.get(), l2.get());
    -
    -        AtomicReference o1 = new AtomicReference<>("42");
    -        AtomicReference o2 = new AtomicReference<>("42");
    -        assertEquals(unsafe.compareAndSwapObject(o1, off(o1, "value"), "42", "53"), compareAndSwapObject(unsafe, o2, off(o2, "value"), "42", "53"));
    -        assertEquals(o1.get(), o2.get());
    -
    -        Foo f1 = new Foo();
    -        f1.test("z", "Boolean", Boolean.TRUE);
    -        f1.test("b", "Byte", Byte.MIN_VALUE);
    -        f1.test("s", "Short", Short.MAX_VALUE);
    -        f1.test("c", "Char", '!');
    -        f1.test("i", "Int", 1010010);
    -        f1.test("f", "Float", -34.5F);
    -        f1.test("l", "Long", 99999L);
    -        f1.test("d", "Double", 1234.5678D);
    -        f1.test("o", "Object", "object");
    -    }
    -
    -    @SuppressWarnings("all")
    -    public static boolean unsafeCompareAndSwapInt(Unsafe unsafe, Object obj, long offset) {
    -        return unsafe.compareAndSwapInt(obj, offset, 0, 1);
    -    }
    -
    -    @SuppressWarnings("all")
    -    public static boolean unsafeCompareAndSwapLong(Unsafe unsafe, Object obj, long offset) {
    -        return unsafe.compareAndSwapLong(obj, offset, 0, 1);
    -    }
    -
    -    @SuppressWarnings("all")
    -    public static boolean unsafeCompareAndSwapObject(Unsafe unsafe, Object obj, long offset) {
    -        return unsafe.compareAndSwapObject(obj, offset, null, new Object());
    -    }
    -
    -    @SuppressWarnings("all")
    -    public static boolean unsafeGetBoolean(Unsafe unsafe, Object obj, long offset) {
    -        return unsafe.getBoolean(obj, offset) && unsafe.getBooleanVolatile(obj, offset);
    -    }
    -
    -    @SuppressWarnings("all")
    -    public static int unsafeGetByte(Unsafe unsafe, Object obj, long offset) {
    -        return unsafe.getByte(obj, offset) + unsafe.getByteVolatile(obj, offset);
    -    }
    -
    -    @SuppressWarnings("all")
    -    public static int unsafeGetShort(Unsafe unsafe, Object obj, long offset) {
    -        return unsafe.getShort(obj, offset) + unsafe.getShortVolatile(obj, offset);
    -    }
    -
    -    @SuppressWarnings("all")
    -    public static int unsafeGetChar(Unsafe unsafe, Object obj, long offset) {
    -        return unsafe.getChar(obj, offset) + unsafe.getCharVolatile(obj, offset);
    -    }
    -
    -    @SuppressWarnings("all")
    -    public static int unsafeGetInt(Unsafe unsafe, Object obj, long offset) {
    -        return unsafe.getInt(obj, offset) + unsafe.getIntVolatile(obj, offset);
    -    }
    -
    -    @SuppressWarnings("all")
    -    public static long unsafeGetLong(Unsafe unsafe, Object obj, long offset) {
    -        return unsafe.getLong(obj, offset) + unsafe.getLongVolatile(obj, offset);
    -    }
    -
    -    @SuppressWarnings("all")
    -    public static float unsafeGetFloat(Unsafe unsafe, Object obj, long offset) {
    -        return unsafe.getFloat(obj, offset) + unsafe.getFloatVolatile(obj, offset);
    -    }
    -
    -    @SuppressWarnings("all")
    -    public static double unsafeGetDouble(Unsafe unsafe, Object obj, long offset) {
    -        return unsafe.getDouble(obj, offset) + unsafe.getDoubleVolatile(obj, offset);
    -    }
    -
    -    @SuppressWarnings("all")
    -    public static boolean unsafeGetObject(Unsafe unsafe, Object obj, long offset) {
    -        return unsafe.getObject(obj, offset) == unsafe.getObjectVolatile(obj, offset);
    -    }
    -
    -    @SuppressWarnings("all")
    -    public static void unsafePutBoolean(Unsafe unsafe, Object obj, long offset, boolean value) {
    -        unsafe.putBoolean(obj, offset, value);
    -        unsafe.putBooleanVolatile(obj, offset, value);
    -    }
    -
    -    @SuppressWarnings("all")
    -    public static void unsafePutByte(Unsafe unsafe, Object obj, long offset, byte value) {
    -        unsafe.putByte(obj, offset, value);
    -        unsafe.putByteVolatile(obj, offset, value);
    -    }
    -
    -    @SuppressWarnings("all")
    -    public static void unsafePutShort(Unsafe unsafe, Object obj, long offset, short value) {
    -        unsafe.putShort(obj, offset, value);
    -        unsafe.putShortVolatile(obj, offset, value);
    -    }
    -
    -    @SuppressWarnings("all")
    -    public static void unsafePutChar(Unsafe unsafe, Object obj, long offset, char value) {
    -        unsafe.putChar(obj, offset, value);
    -        unsafe.putCharVolatile(obj, offset, value);
    -    }
    -
    -    @SuppressWarnings("all")
    -    public static void unsafePutInt(Unsafe unsafe, Object obj, long offset, int value) {
    -        unsafe.putInt(obj, offset, value);
    -        unsafe.putIntVolatile(obj, offset, value);
    -        unsafe.putOrderedInt(obj, offset, value);
    -    }
    -
    -    @SuppressWarnings("all")
    -    public static void unsafePutLong(Unsafe unsafe, Object obj, long offset, long value) {
    -        unsafe.putLong(obj, offset, value);
    -        unsafe.putLongVolatile(obj, offset, value);
    -        unsafe.putOrderedLong(obj, offset, value);
    -    }
    -
    -    @SuppressWarnings("all")
    -    public static void unsafePutFloat(Unsafe unsafe, Object obj, long offset, float value) {
    -        unsafe.putFloat(obj, offset, value);
    -        unsafe.putFloatVolatile(obj, offset, value);
    -    }
    -
    -    @SuppressWarnings("all")
    -    public static void unsafePutDouble(Unsafe unsafe, Object obj, long offset, double value) {
    -        unsafe.putDouble(obj, offset, value);
    -        unsafe.putDoubleVolatile(obj, offset, value);
    -    }
    -
    -    @SuppressWarnings("all")
    -    public static void unsafePutObject(Unsafe unsafe, Object obj, long offset, Object value) {
    -        unsafe.putObject(obj, offset, value);
    -        unsafe.putObjectVolatile(obj, offset, value);
    -        unsafe.putOrderedObject(obj, offset, value);
    -    }
    -
    -    @SuppressWarnings("all")
    -    public static double unsafeDirectMemoryRead(Unsafe unsafe, long address) {
    -        // Unsafe.getBoolean(long) and Unsafe.getObject(long) do not exist
    -        return unsafe.getByte(address) + unsafe.getShort(address) + unsafe.getChar(address) + unsafe.getInt(address) + unsafe.getLong(address) + unsafe.getFloat(address) + unsafe.getDouble(address);
    -    }
    -
    -    @SuppressWarnings("all")
    -    public static void unsafeDirectMemoryWrite(Unsafe unsafe, long address, byte value) {
    -        // Unsafe.putBoolean(long) and Unsafe.putObject(long) do not exist
    -        unsafe.putByte(address, value);
    -        unsafe.putShort(address, value);
    -        unsafe.putChar(address, (char) value);
    -        unsafe.putInt(address, value);
    -        unsafe.putLong(address, value);
    -        unsafe.putFloat(address, value);
    -        unsafe.putDouble(address, value);
    -    }
    -
         @Test
         public void testMathSubstitutions() {
             assertInGraph(assertNotInGraph(test("mathAbs"), IfNode.class), MathIntrinsicNode.class);     // Java
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/TypeCheckTest.java
    --- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/TypeCheckTest.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/TypeCheckTest.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -48,11 +48,11 @@
             return super.getCode(method, graph, forceCompile);
         }
     
    -    protected JavaTypeProfile profile(Class... types) {
    +    protected JavaTypeProfile profile(Class... types) {
             return profile(TriState.FALSE, types);
         }
     
    -    protected JavaTypeProfile profile(TriState nullSeen, Class... types) {
    +    protected JavaTypeProfile profile(TriState nullSeen, Class... types) {
             if (types.length == 0) {
                 return null;
             }
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/UnsafeSubstitutionsTest.java
    --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    +++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/UnsafeSubstitutionsTest.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -0,0 +1,451 @@
    +/*
    + * Copyright (c) 2014, 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.replacements.test;
    +
    +import static com.oracle.graal.compiler.common.UnsafeAccess.*;
    +import static com.oracle.graal.replacements.UnsafeSubstitutions.*;
    +
    +import java.lang.reflect.*;
    +import java.util.concurrent.atomic.*;
    +
    +import org.junit.*;
    +
    +import sun.misc.*;
    +
    +import com.oracle.graal.api.code.*;
    +import com.oracle.graal.replacements.*;
    +
    +/**
    + * Tests the VM independent {@link UnsafeSubstitutions}.
    + */
    +public class UnsafeSubstitutionsTest extends MethodSubstitutionTest {
    +
    +    private static Object executeVarargsSafe(InstalledCode code, Object... args) {
    +        try {
    +            return code.executeVarargs(args);
    +        } catch (InvalidInstalledCodeException e) {
    +            throw new RuntimeException(e);
    +        }
    +    }
    +
    +    private static Object invokeSafe(Method method, Object receiver, Object... args) {
    +        method.setAccessible(true);
    +        try {
    +            return method.invoke(receiver, args);
    +        } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
    +            throw new RuntimeException(e);
    +        }
    +    }
    +
    +    public void testSubstitution(String testMethodName, Class holder, String methodName, Class[] parameterTypes, Object receiver, Object[] args1, Object[] args2) {
    +        Method originalMethod = getMethod(holder, methodName, parameterTypes);
    +        Method testMethod = getMethod(testMethodName);
    +
    +        // Force compilation
    +        InstalledCode code = getCode(getMetaAccess().lookupJavaMethod(testMethod), parse(testMethod));
    +        assert code != null;
    +
    +        // Verify that the original method and the substitution produce the same value
    +        {
    +            Object expected = invokeSafe(originalMethod, receiver, args1);
    +            Object actual = invokeSafe(testMethod, null, args2);
    +            assertEquals(expected, actual);
    +        }
    +
    +        // Verify that the generated code and the original produce the same value
    +        {
    +            Object expected = invokeSafe(originalMethod, receiver, args1);
    +            Object actual = executeVarargsSafe(code, args2);
    +            assertEquals(expected, actual);
    +        }
    +    }
    +
    +    static long off(Object o, String name) {
    +        try {
    +            return unsafe.objectFieldOffset(o.getClass().getDeclaredField(name));
    +        } catch (Exception e) {
    +            Assert.fail(e.toString());
    +            return 0L;
    +        }
    +    }
    +
    +    static class Foo {
    +
    +        boolean z;
    +        byte b;
    +        short s;
    +        char c;
    +        int i;
    +        long l;
    +        float f;
    +        double d;
    +        Object o;
    +
    +        void testGet(Field field, long offset, String getName, Object value) throws Exception {
    +            field.set(this, value);
    +            Method m1 = Unsafe.class.getDeclaredMethod(getName, Object.class, long.class);
    +            Method m2 = UnsafeSubstitutions.class.getDeclaredMethod(getName, Object.class, Object.class, long.class);
    +            Object expected = m1.invoke(unsafe, this, offset);
    +            Object actual = m2.invoke(null, unsafe, this, offset);
    +            Assert.assertEquals(expected, actual);
    +        }
    +
    +        void testDirect(Field field, long offset, String type, Object value) throws Exception {
    +            if (type.equals("Boolean") || type.equals("Object")) {
    +                // No direct memory access for these types
    +                return;
    +            }
    +
    +            long address = unsafe.allocateMemory(offset + 16);
    +
    +            String getName = "get" + type;
    +            String putName = "put" + type;
    +            Method m1 = Unsafe.class.getDeclaredMethod(putName, long.class, field.getType());
    +            Method m2 = Unsafe.class.getDeclaredMethod(getName, long.class);
    +
    +            Method m3 = UnsafeSubstitutions.class.getDeclaredMethod(putName, Object.class, long.class, field.getType());
    +            Method m4 = UnsafeSubstitutions.class.getDeclaredMethod(getName, Object.class, long.class);
    +
    +            m1.invoke(unsafe, address + offset, value);
    +            Object expected = m2.invoke(unsafe, address + offset);
    +
    +            m3.invoke(null, unsafe, address + offset, value);
    +            Object actual = m4.invoke(null, unsafe, address + offset);
    +
    +            unsafe.freeMemory(address);
    +            Assert.assertEquals(expected, actual);
    +        }
    +
    +        void testPut(Field field, long offset, String putName, Object value) throws Exception {
    +            Object initialValue = field.get(new Foo());
    +            field.set(this, initialValue);
    +
    +            try {
    +                Method m1 = Unsafe.class.getDeclaredMethod(putName, Object.class, long.class, field.getType());
    +                Method m2 = UnsafeSubstitutions.class.getDeclaredMethod(putName, Object.class, Object.class, long.class, field.getType());
    +                m1.invoke(unsafe, this, offset, value);
    +                Object expected = field.get(this);
    +                m2.invoke(null, unsafe, this, offset, value);
    +                Object actual = field.get(this);
    +                Assert.assertEquals(expected, actual);
    +            } catch (NoSuchMethodException e) {
    +                if (!putName.startsWith("putOrdered")) {
    +                    throw e;
    +                }
    +            }
    +        }
    +
    +        void test(String fieldName, String typeSuffix, Object value) {
    +            try {
    +                Field field = Foo.class.getDeclaredField(fieldName);
    +                long offset = unsafe.objectFieldOffset(field);
    +                testGet(field, offset, "get" + typeSuffix, value);
    +                testGet(field, offset, "get" + typeSuffix + "Volatile", value);
    +                testPut(field, offset, "put" + typeSuffix, value);
    +                testPut(field, offset, "put" + typeSuffix + "Volatile", value);
    +                testPut(field, offset, "putOrdered" + typeSuffix, value);
    +                testDirect(field, offset, typeSuffix, value);
    +            } catch (Exception e) {
    +                throw new AssertionError(e);
    +            }
    +        }
    +    }
    +
    +    @Test
    +    public void testUnsafeSubstitutions() throws Exception {
    +        test("unsafeCompareAndSwapInt");
    +        test("unsafeCompareAndSwapLong");
    +        test("unsafeCompareAndSwapObject");
    +
    +        test("unsafeGetBoolean");
    +        test("unsafeGetByte");
    +        test("unsafeGetShort");
    +        test("unsafeGetChar");
    +        test("unsafeGetInt");
    +        test("unsafeGetLong");
    +        test("unsafeGetFloat");
    +        test("unsafeGetDouble");
    +        test("unsafeGetObject");
    +
    +        test("unsafePutBoolean");
    +        test("unsafePutByte");
    +        test("unsafePutShort");
    +        test("unsafePutChar");
    +        test("unsafePutInt");
    +        test("unsafePutFloat");
    +        test("unsafePutDouble");
    +        test("unsafePutObject");
    +
    +        test("unsafeDirectMemoryRead");
    +        test("unsafeDirectMemoryWrite");
    +
    +        AtomicInteger a1 = new AtomicInteger(42);
    +        AtomicInteger a2 = new AtomicInteger(42);
    +        assertEquals(unsafe.compareAndSwapInt(a1, off(a1, "value"), 42, 53), compareAndSwapInt(unsafe, a2, off(a2, "value"), 42, 53));
    +        assertEquals(a1.get(), a2.get());
    +
    +        AtomicLong l1 = new AtomicLong(42);
    +        AtomicLong l2 = new AtomicLong(42);
    +        assertEquals(unsafe.compareAndSwapLong(l1, off(l1, "value"), 42, 53), compareAndSwapLong(unsafe, l2, off(l2, "value"), 42, 53));
    +        assertEquals(l1.get(), l2.get());
    +
    +        AtomicReference o1 = new AtomicReference<>("42");
    +        AtomicReference o2 = new AtomicReference<>("42");
    +        assertEquals(unsafe.compareAndSwapObject(o1, off(o1, "value"), "42", "53"), compareAndSwapObject(unsafe, o2, off(o2, "value"), "42", "53"));
    +        assertEquals(o1.get(), o2.get());
    +
    +        Foo f1 = new Foo();
    +        f1.test("z", "Boolean", Boolean.TRUE);
    +        f1.test("b", "Byte", Byte.MIN_VALUE);
    +        f1.test("s", "Short", Short.MAX_VALUE);
    +        f1.test("c", "Char", '!');
    +        f1.test("i", "Int", 1010010);
    +        f1.test("f", "Float", -34.5F);
    +        f1.test("l", "Long", 99999L);
    +        f1.test("d", "Double", 1234.5678D);
    +        f1.test("o", "Object", "object");
    +    }
    +
    +    @SuppressWarnings("all")
    +    public static boolean unsafeCompareAndSwapInt(Unsafe unsafe, Object obj, long offset) {
    +        return unsafe.compareAndSwapInt(obj, offset, 0, 1);
    +    }
    +
    +    @SuppressWarnings("all")
    +    public static boolean unsafeCompareAndSwapLong(Unsafe unsafe, Object obj, long offset) {
    +        return unsafe.compareAndSwapLong(obj, offset, 0, 1);
    +    }
    +
    +    @SuppressWarnings("all")
    +    public static boolean unsafeCompareAndSwapObject(Unsafe unsafe, Object obj, long offset) {
    +        return unsafe.compareAndSwapObject(obj, offset, null, new Object());
    +    }
    +
    +    @SuppressWarnings("all")
    +    public static boolean unsafeGetBoolean(Unsafe unsafe, Object obj, long offset) {
    +        return unsafe.getBoolean(obj, offset) && unsafe.getBooleanVolatile(obj, offset);
    +    }
    +
    +    @SuppressWarnings("all")
    +    public static int unsafeGetByte(Unsafe unsafe, Object obj, long offset) {
    +        return unsafe.getByte(obj, offset) + unsafe.getByteVolatile(obj, offset);
    +    }
    +
    +    @SuppressWarnings("all")
    +    public static int unsafeGetShort(Unsafe unsafe, Object obj, long offset) {
    +        return unsafe.getShort(obj, offset) + unsafe.getShortVolatile(obj, offset);
    +    }
    +
    +    @SuppressWarnings("all")
    +    public static int unsafeGetChar(Unsafe unsafe, Object obj, long offset) {
    +        return unsafe.getChar(obj, offset) + unsafe.getCharVolatile(obj, offset);
    +    }
    +
    +    @SuppressWarnings("all")
    +    public static int unsafeGetInt(Unsafe unsafe, Object obj, long offset) {
    +        return unsafe.getInt(obj, offset) + unsafe.getIntVolatile(obj, offset);
    +    }
    +
    +    @SuppressWarnings("all")
    +    public static long unsafeGetLong(Unsafe unsafe, Object obj, long offset) {
    +        return unsafe.getLong(obj, offset) + unsafe.getLongVolatile(obj, offset);
    +    }
    +
    +    @SuppressWarnings("all")
    +    public static float unsafeGetFloat(Unsafe unsafe, Object obj, long offset) {
    +        return unsafe.getFloat(obj, offset) + unsafe.getFloatVolatile(obj, offset);
    +    }
    +
    +    @SuppressWarnings("all")
    +    public static double unsafeGetDouble(Unsafe unsafe, Object obj, long offset) {
    +        return unsafe.getDouble(obj, offset) + unsafe.getDoubleVolatile(obj, offset);
    +    }
    +
    +    @SuppressWarnings("all")
    +    public static boolean unsafeGetObject(Unsafe unsafe, Object obj, long offset) {
    +        return unsafe.getObject(obj, offset) == unsafe.getObjectVolatile(obj, offset);
    +    }
    +
    +    @SuppressWarnings("all")
    +    public static void unsafePutBoolean(Unsafe unsafe, Object obj, long offset, boolean value) {
    +        unsafe.putBoolean(obj, offset, value);
    +        unsafe.putBooleanVolatile(obj, offset, value);
    +    }
    +
    +    @SuppressWarnings("all")
    +    public static void unsafePutByte(Unsafe unsafe, Object obj, long offset, byte value) {
    +        unsafe.putByte(obj, offset, value);
    +        unsafe.putByteVolatile(obj, offset, value);
    +    }
    +
    +    @SuppressWarnings("all")
    +    public static void unsafePutShort(Unsafe unsafe, Object obj, long offset, short value) {
    +        unsafe.putShort(obj, offset, value);
    +        unsafe.putShortVolatile(obj, offset, value);
    +    }
    +
    +    @SuppressWarnings("all")
    +    public static void unsafePutChar(Unsafe unsafe, Object obj, long offset, char value) {
    +        unsafe.putChar(obj, offset, value);
    +        unsafe.putCharVolatile(obj, offset, value);
    +    }
    +
    +    @SuppressWarnings("all")
    +    public static void unsafePutInt(Unsafe unsafe, Object obj, long offset, int value) {
    +        unsafe.putInt(obj, offset, value);
    +        unsafe.putIntVolatile(obj, offset, value);
    +        unsafe.putOrderedInt(obj, offset, value);
    +    }
    +
    +    @SuppressWarnings("all")
    +    public static void unsafePutLong(Unsafe unsafe, Object obj, long offset, long value) {
    +        unsafe.putLong(obj, offset, value);
    +        unsafe.putLongVolatile(obj, offset, value);
    +        unsafe.putOrderedLong(obj, offset, value);
    +    }
    +
    +    @SuppressWarnings("all")
    +    public static void unsafePutFloat(Unsafe unsafe, Object obj, long offset, float value) {
    +        unsafe.putFloat(obj, offset, value);
    +        unsafe.putFloatVolatile(obj, offset, value);
    +    }
    +
    +    @SuppressWarnings("all")
    +    public static void unsafePutDouble(Unsafe unsafe, Object obj, long offset, double value) {
    +        unsafe.putDouble(obj, offset, value);
    +        unsafe.putDoubleVolatile(obj, offset, value);
    +    }
    +
    +    @SuppressWarnings("all")
    +    public static void unsafePutObject(Unsafe unsafe, Object obj, long offset, Object value) {
    +        unsafe.putObject(obj, offset, value);
    +        unsafe.putObjectVolatile(obj, offset, value);
    +        unsafe.putOrderedObject(obj, offset, value);
    +    }
    +
    +    @SuppressWarnings("all")
    +    public static double unsafeDirectMemoryRead(Unsafe unsafe, long address) {
    +        // Unsafe.getBoolean(long) and Unsafe.getObject(long) do not exist
    +        return unsafe.getByte(address) + unsafe.getShort(address) + unsafe.getChar(address) + unsafe.getInt(address) + unsafe.getLong(address) + unsafe.getFloat(address) + unsafe.getDouble(address);
    +    }
    +
    +    @SuppressWarnings("all")
    +    public static void unsafeDirectMemoryWrite(Unsafe unsafe, long address, byte value) {
    +        // Unsafe.putBoolean(long) and Unsafe.putObject(long) do not exist
    +        unsafe.putByte(address, value);
    +        unsafe.putShort(address, value);
    +        unsafe.putChar(address, (char) value);
    +        unsafe.putInt(address, value);
    +        unsafe.putLong(address, value);
    +        unsafe.putFloat(address, value);
    +        unsafe.putDouble(address, value);
    +    }
    +
    +    @Test
    +    public void testGetAndAddInt() throws Exception {
    +        Foo f1 = new Foo();
    +        Foo f2 = new Foo();
    +        long offset = off(f1, "i");
    +        Class[] parameterTypes = new Class[]{Object.class, long.class, int.class};
    +        for (int delta = Integer.MAX_VALUE - 10; delta < Integer.MAX_VALUE; delta++) {
    +            Object[] args1 = new Object[]{f1, offset, delta};
    +            Object[] args2 = new Object[]{f2, offset, delta};
    +            testSubstitution("getAndAddInt", Unsafe.class, "getAndAddInt", parameterTypes, unsafe, args1, args2);
    +        }
    +    }
    +
    +    public static int getAndAddInt(Object obj, long offset, int delta) {
    +        return unsafe.getAndAddInt(obj, offset, delta);
    +    }
    +
    +    @Test
    +    public void testGetAndAddLong() throws Exception {
    +        Foo f1 = new Foo();
    +        Foo f2 = new Foo();
    +        long offset = off(f1, "l");
    +        Class[] parameterTypes = new Class[]{Object.class, long.class, long.class};
    +        for (long delta = Long.MAX_VALUE - 10; delta < Long.MAX_VALUE; delta++) {
    +            Object[] args1 = new Object[]{f1, offset, delta};
    +            Object[] args2 = new Object[]{f2, offset, delta};
    +            testSubstitution("getAndAddLong", Unsafe.class, "getAndAddLong", parameterTypes, unsafe, args1, args2);
    +        }
    +    }
    +
    +    public static long getAndAddLong(Object obj, long offset, long delta) {
    +        return unsafe.getAndAddLong(obj, offset, delta);
    +    }
    +
    +    @Test
    +    public void testGetAndSetInt() throws Exception {
    +        Foo f1 = new Foo();
    +        Foo f2 = new Foo();
    +        long offset = off(f1, "i");
    +        Class[] parameterTypes = new Class[]{Object.class, long.class, int.class};
    +        for (int delta = Integer.MAX_VALUE - 10; delta < Integer.MAX_VALUE; delta++) {
    +            Object[] args1 = new Object[]{f1, offset, delta};
    +            Object[] args2 = new Object[]{f2, offset, delta};
    +            testSubstitution("getAndSetInt", Unsafe.class, "getAndSetInt", parameterTypes, unsafe, args1, args2);
    +        }
    +    }
    +
    +    public static int getAndSetInt(Object obj, long offset, int newValue) {
    +        return unsafe.getAndSetInt(obj, offset, newValue);
    +    }
    +
    +    @Test
    +    public void testGetAndSetLong() throws Exception {
    +        Foo f1 = new Foo();
    +        Foo f2 = new Foo();
    +        long offset = off(f1, "l");
    +        Class[] parameterTypes = new Class[]{Object.class, long.class, long.class};
    +        for (long newValue = Long.MAX_VALUE - 10; newValue < Long.MAX_VALUE; newValue++) {
    +            Object[] args1 = new Object[]{f1, offset, newValue};
    +            Object[] args2 = new Object[]{f2, offset, newValue};
    +            testSubstitution("getAndSetLong", Unsafe.class, "getAndSetLong", parameterTypes, unsafe, args1, args2);
    +        }
    +    }
    +
    +    public static long getAndSetLong(Object obj, long offset, long newValue) {
    +        return unsafe.getAndSetLong(obj, offset, newValue);
    +    }
    +
    +    @Test
    +    public void testGetAndSetObject() throws Exception {
    +        Foo f1 = new Foo();
    +        Foo f2 = new Foo();
    +        long offset = off(f1, "o");
    +        Class[] parameterTypes = new Class[]{Object.class, long.class, Object.class};
    +        for (long i = 0; i < 10; i++) {
    +            Object o = new Object();
    +            Object[] args1 = new Object[]{f1, offset, o};
    +            Object[] args2 = new Object[]{f2, offset, o};
    +            testSubstitution("getAndSetObject", Unsafe.class, "getAndSetObject", parameterTypes, unsafe, args1, args2);
    +            System.gc();
    +        }
    +    }
    +
    +    public static Object getAndSetObject(Object obj, long offset, Object newValue) {
    +        return unsafe.getAndSetObject(obj, offset, newValue);
    +    }
    +
    +}
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/WordTest.java
    --- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/WordTest.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/WordTest.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -42,7 +42,7 @@
         private final ReplacementsImpl installer;
     
         public WordTest() {
    -        installer = new ReplacementsImpl(getProviders(), new Assumptions(false), getTarget());
    +        installer = new ReplacementsImpl(getProviders(), getSnippetReflection(), new Assumptions(false), getTarget());
         }
     
         private static final ThreadLocal inliningPolicy = new ThreadLocal<>();
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.replacements.verifier/src/com/oracle/graal/replacements/verifier/MethodSubstitutionVerifier.java
    --- a/graal/com.oracle.graal.replacements.verifier/src/com/oracle/graal/replacements/verifier/MethodSubstitutionVerifier.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.replacements.verifier/src/com/oracle/graal/replacements/verifier/MethodSubstitutionVerifier.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -89,17 +89,17 @@
             }
     
             String originalName = originalName(substitutionMethod, annotation);
    -        TypeMirror[] originalSignature = originalSignature(substitutionMethod, annotation);
    +        TypeMirror[] originalSignature = originalSignature(originalType, substitutionMethod, annotation);
             if (originalSignature == null) {
                 return;
             }
             ExecutableElement originalMethod = originalMethod(substitutionMethod, annotation, originalType, originalName, originalSignature);
             if (DEBUG && originalMethod != null) {
    -            env.getMessager().printMessage(Kind.ERROR, String.format("Found original method %s in type %s.", originalMethod, findEnclosingClass(originalMethod)));
    +            env.getMessager().printMessage(Kind.NOTE, String.format("Found original method %s in type %s.", originalMethod, findEnclosingClass(originalMethod)));
             }
         }
     
    -    private TypeMirror[] originalSignature(ExecutableElement method, AnnotationMirror annotation) {
    +    private TypeMirror[] originalSignature(TypeElement originalType, ExecutableElement method, AnnotationMirror annotation) {
             boolean isStatic = resolveAnnotationValue(Boolean.class, findAnnotationValue(annotation, ORIGINAL_IS_STATIC));
             AnnotationValue signatureValue = findAnnotationValue(annotation, ORIGINAL_SIGNATURE);
             String signatureString = resolveAnnotationValue(String.class, signatureValue);
    @@ -113,7 +113,11 @@
                         env.getMessager().printMessage(Kind.ERROR, "Method signature must be a static method with the 'this' object as its first parameter", method, annotation);
                         return null;
                     } else {
    -                    parameters.remove(0);
    +                    TypeMirror thisParam = parameters.remove(0);
    +                    if (!isSubtype(originalType.asType(), thisParam)) {
    +                        Name thisName = method.getParameters().get(0).getSimpleName();
    +                        env.getMessager().printMessage(Kind.ERROR, String.format("The type of %s must assignable from %s", thisName, originalType), method, annotation);
    +                    }
                     }
                 }
                 parameters.add(0, method.getReturnType());
    @@ -201,6 +205,26 @@
             return env.getTypeUtils().isSameType(original, substitution);
         }
     
    +    /**
    +     * Tests whether one type is a subtype of another. Any type is considered to be a subtype of
    +     * itself.
    +     *
    +     * @param t1 the first type
    +     * @param t2 the second type
    +     * @return {@code true} if and only if the first type is a subtype of the second
    +     */
    +    private boolean isSubtype(TypeMirror t1, TypeMirror t2) {
    +        TypeMirror t1Erased = t1;
    +        TypeMirror t2Erased = t2;
    +        if (needsErasure(t1Erased)) {
    +            t1Erased = env.getTypeUtils().erasure(t1Erased);
    +        }
    +        if (needsErasure(t2Erased)) {
    +            t2Erased = env.getTypeUtils().erasure(t2Erased);
    +        }
    +        return env.getTypeUtils().isSubtype(t1Erased, t2Erased);
    +    }
    +
         private static boolean needsErasure(TypeMirror typeMirror) {
             return typeMirror.getKind() != TypeKind.NONE && typeMirror.getKind() != TypeKind.VOID && !typeMirror.getKind().isPrimitive() && typeMirror.getKind() != TypeKind.OTHER &&
                             typeMirror.getKind() != TypeKind.NULL;
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/BoxingSnippets.java
    --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/BoxingSnippets.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/BoxingSnippets.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,21 +22,21 @@
      */
     package com.oracle.graal.replacements;
     
    -import static com.oracle.graal.phases.GraalOptions.*;
    +import static com.oracle.graal.compiler.common.GraalOptions.*;
     import static com.oracle.graal.replacements.SnippetTemplate.*;
     
    -import java.lang.reflect.*;
     import java.util.*;
     
     import com.oracle.graal.api.code.*;
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.api.replacements.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.debug.*;
     import com.oracle.graal.graph.Node.NodeIntrinsic;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.calc.*;
     import com.oracle.graal.nodes.extended.*;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
     import com.oracle.graal.nodes.util.*;
     import com.oracle.graal.phases.util.*;
     import com.oracle.graal.replacements.Snippet.Fold;
    @@ -56,7 +56,7 @@
     
             @Override
             public boolean shouldInline(ResolvedJavaMethod method, ResolvedJavaMethod caller) {
    -            if (Modifier.isNative(method.getModifiers())) {
    +            if (method.isNative()) {
                     return false;
                 }
                 if (method.getAnnotation(Fold.class) != null) {
    @@ -173,30 +173,13 @@
             return value.shortValue();
         }
     
    -    public static FloatingNode canonicalizeBoxing(BoxNode box, MetaAccessProvider metaAccess) {
    +    public static FloatingNode canonicalizeBoxing(BoxNode box, MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection) {
             ValueNode value = box.getValue();
             if (value.isConstant()) {
                 Constant sourceConstant = value.asConstant();
    -            switch (box.getBoxingKind()) {
    -                case Boolean:
    -                    return ConstantNode.forObject(Boolean.valueOf(sourceConstant.asInt() != 0), metaAccess, box.graph());
    -                case Byte:
    -                    return ConstantNode.forObject(Byte.valueOf((byte) sourceConstant.asInt()), metaAccess, box.graph());
    -                case Char:
    -                    return ConstantNode.forObject(Character.valueOf((char) sourceConstant.asInt()), metaAccess, box.graph());
    -                case Short:
    -                    return ConstantNode.forObject(Short.valueOf((short) sourceConstant.asInt()), metaAccess, box.graph());
    -                case Int:
    -                    return ConstantNode.forObject(Integer.valueOf(sourceConstant.asInt()), metaAccess, box.graph());
    -                case Long:
    -                    return ConstantNode.forObject(Long.valueOf(sourceConstant.asLong()), metaAccess, box.graph());
    -                case Float:
    -                    return ConstantNode.forObject(Float.valueOf(sourceConstant.asFloat()), metaAccess, box.graph());
    -                case Double:
    -                    return ConstantNode.forObject(Double.valueOf(sourceConstant.asDouble()), metaAccess, box.graph());
    -                default:
    -                    assert false : "Unexpected source kind for boxing";
    -                    break;
    +            Constant boxedConstant = constantReflection.boxPrimitive(sourceConstant);
    +            if (boxedConstant != null && boxedConstant.getKind() == box.getBoxingKind()) {
    +                return ConstantNode.forConstant(boxedConstant, metaAccess, box.graph());
                 }
             }
             return null;
    @@ -207,8 +190,8 @@
             private final EnumMap boxSnippets = new EnumMap<>(Kind.class);
             private final EnumMap unboxSnippets = new EnumMap<>(Kind.class);
     
    -        public Templates(Providers providers, TargetDescription target) {
    -            super(providers, target);
    +        public Templates(Providers providers, SnippetReflectionProvider snippetReflection, TargetDescription target) {
    +            super(providers, snippetReflection, target);
                 for (Kind kind : new Kind[]{Kind.Boolean, Kind.Byte, Kind.Char, Kind.Double, Kind.Float, Kind.Int, Kind.Long, Kind.Short}) {
                     boxSnippets.put(kind, snippet(BoxingSnippets.class, kind.getJavaName() + "ValueOf"));
                     unboxSnippets.put(kind, snippet(BoxingSnippets.class, kind.getJavaName() + "Value"));
    @@ -216,7 +199,7 @@
             }
     
             public void lower(BoxNode box, LoweringTool tool) {
    -            FloatingNode canonical = canonicalizeBoxing(box, providers.getMetaAccess());
    +            FloatingNode canonical = canonicalizeBoxing(box, providers.getMetaAccess(), providers.getConstantReflection());
                 // if in AOT mode, we don't want to embed boxed constants.
                 if (canonical != null && !ImmutableCode.getValue()) {
                     box.graph().replaceFloating(box, canonical);
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/CollapseFrameForSingleSideEffectPhase.java
    --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/CollapseFrameForSingleSideEffectPhase.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/CollapseFrameForSingleSideEffectPhase.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -24,6 +24,7 @@
     
     import java.util.*;
     
    +import com.oracle.graal.api.code.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.util.*;
    @@ -33,12 +34,12 @@
     import com.oracle.graal.phases.graph.ReentrantNodeIterator.NodeIteratorClosure;
     
     /**
    - * This phase ensures that there's a single {@linkplain FrameState#AFTER_BCI collapsed frame state}
    - * per path.
    + * This phase ensures that there's a single {@linkplain BytecodeFrame#AFTER_BCI collapsed frame
    + * state} per path.
      * 
      * Removes other frame states from {@linkplain StateSplit#hasSideEffect() non-side-effecting} nodes
    - * in the graph, and replaces them with {@linkplain FrameState#INVALID_FRAMESTATE_BCI invalid frame
    - * states}.
    + * in the graph, and replaces them with {@linkplain BytecodeFrame#INVALID_FRAMESTATE_BCI invalid
    + * frame states}.
      * 
      * The invalid frame states ensure that no deoptimization to a snippet frame state will happen.
      */
    @@ -65,7 +66,7 @@
                 return new IterationState(this, sideEffect.asNode(), null, true);
             }
     
    -        public IterationState addBranch(AbstractBeginNode begin) {
    +        public IterationState addBranch(BeginNode begin) {
                 return new IterationState(this, begin, null, this.invalid);
             }
     
    @@ -176,7 +177,7 @@
                     if (!unwindSideEffects.contains(returnSideEffect) && !maskedSideEffects.contains(returnSideEffect)) {
                         StateSplit split = (StateSplit) returnSideEffect;
                         if (split.stateAfter() != null) {
    -                        split.setStateAfter(graph.add(new FrameState(FrameState.AFTER_BCI)));
    +                        split.setStateAfter(graph.add(new FrameState(BytecodeFrame.AFTER_BCI)));
                         }
                     }
                 }
    @@ -185,14 +186,14 @@
                     if (!returnSideEffects.contains(unwindSideEffect) && !maskedSideEffects.contains(unwindSideEffect)) {
                         StateSplit split = (StateSplit) unwindSideEffect;
                         if (split.stateAfter() != null) {
    -                        split.setStateAfter(graph.add(new FrameState(FrameState.AFTER_EXCEPTION_BCI)));
    +                        split.setStateAfter(graph.add(new FrameState(BytecodeFrame.AFTER_EXCEPTION_BCI)));
                         }
                     }
                 }
             }
     
             @Override
    -        protected IterationState afterSplit(AbstractBeginNode node, IterationState oldState) {
    +        protected IterationState afterSplit(BeginNode node, IterationState oldState) {
                 return oldState.addBranch(node);
             }
     
    @@ -214,7 +215,7 @@
             }
     
             private static FrameState createInvalidFrameState(FixedNode node) {
    -            return node.graph().add(new FrameState(FrameState.INVALID_FRAMESTATE_BCI));
    +            return node.graph().add(new FrameState(BytecodeFrame.INVALID_FRAMESTATE_BCI));
             }
         }
     }
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/CompositeValueClassSubstitutions.java
    --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/CompositeValueClassSubstitutions.java	Wed Apr 23 15:22:20 2014 +0200
    +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    @@ -1,63 +0,0 @@
    -/*
    - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
    - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    - *
    - * This code is free software; you can redistribute it and/or modify it
    - * under the terms of the GNU General Public License version 2 only, as
    - * published by the Free Software Foundation.
    - *
    - * This code is distributed in the hope that it will be useful, but WITHOUT
    - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    - * version 2 for more details (a copy is included in the LICENSE file that
    - * accompanied this code).
    - *
    - * You should have received a copy of the GNU General Public License version
    - * 2 along with this work; if not, write to the Free Software Foundation,
    - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    - *
    - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    - * or visit www.oracle.com if you need additional information or have any
    - * questions.
    - */
    -package com.oracle.graal.replacements;
    -
    -import static com.oracle.graal.phases.GraalOptions.*;
    -
    -import com.oracle.graal.api.meta.*;
    -import com.oracle.graal.api.replacements.*;
    -import com.oracle.graal.lir.*;
    -import com.oracle.graal.nodes.*;
    -import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.replacements.nodes.*;
    -
    -/**
    - * Substitutions for improving the performance of {@link CompositeValueClass#getClass()}.
    - */
    -@ClassSubstitution(CompositeValueClass.class)
    -public class CompositeValueClassSubstitutions {
    -
    -    /**
    -     * A macro node for calls to {@link CompositeValueClass#get(Class)}. It can use the compiler's
    -     * knowledge about node classes to replace itself with a constant value for a constant
    -     * {@link Class} parameter.
    -     */
    -    public static class CompositeValueClassGetNode extends PureFunctionMacroNode {
    -
    -        public CompositeValueClassGetNode(Invoke invoke) {
    -            super(invoke);
    -        }
    -
    -        @SuppressWarnings("unchecked")
    -        @Override
    -        protected Constant evaluate(Constant param, MetaAccessProvider metaAccess) {
    -            if (param.isNull() || ImmutableCode.getValue()) {
    -                return null;
    -            }
    -            return Constant.forObject(CompositeValueClass.get((Class) param.asObject()));
    -        }
    -    }
    -
    -    @MacroSubstitution(isStatic = true, forced = true, macro = CompositeValueClassGetNode.class)
    -    private static native CompositeValueClass get(Class c);
    -}
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/GraalMethodSubstitutions.java
    --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/GraalMethodSubstitutions.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/GraalMethodSubstitutions.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,7 +22,7 @@
      */
     package com.oracle.graal.replacements;
     
    -import static com.oracle.graal.phases.GraalOptions.*;
    +import static com.oracle.graal.compiler.common.GraalOptions.*;
     
     import com.oracle.graal.api.code.*;
     import com.oracle.graal.api.meta.*;
    @@ -50,8 +50,6 @@
                 replacements.registerSubstitutions(CharacterSubstitutions.class);
                 replacements.registerSubstitutions(ShortSubstitutions.class);
                 replacements.registerSubstitutions(UnsignedMathSubstitutions.class);
    -            replacements.registerSubstitutions(NodeClassSubstitutions.class);
    -            replacements.registerSubstitutions(CompositeValueClassSubstitutions.class);
             }
         }
     }
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/GraphKit.java
    --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/GraphKit.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/GraphKit.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -27,6 +27,7 @@
     
     import com.oracle.graal.api.code.*;
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.api.replacements.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.java.*;
     import com.oracle.graal.nodes.*;
    @@ -95,7 +96,7 @@
         }
     
         public InvokeNode createInvoke(Class declaringClass, String name, ValueNode... args) {
    -        return createInvoke(declaringClass, name, InvokeKind.Static, null, FrameState.UNKNOWN_BCI, args);
    +        return createInvoke(declaringClass, name, InvokeKind.Static, null, BytecodeFrame.UNKNOWN_BCI, args);
         }
     
         /**
    @@ -124,7 +125,7 @@
          * arguments.
          */
         public InvokeNode createInvoke(ResolvedJavaMethod method, InvokeKind invokeKind, HIRFrameStateBuilder frameStateBuilder, int bci, ValueNode... args) {
    -        assert Modifier.isStatic(method.getModifiers()) == (invokeKind == InvokeKind.Static);
    +        assert method.isStatic() == (invokeKind == InvokeKind.Static);
             Signature signature = method.getSignature();
             JavaType returnType = signature.getReturnType(null);
             assert checkArgs(method, args);
    @@ -156,7 +157,7 @@
          */
         public boolean checkArgs(ResolvedJavaMethod method, ValueNode... args) {
             Signature signature = method.getSignature();
    -        boolean isStatic = Modifier.isStatic(method.getModifiers());
    +        boolean isStatic = method.isStatic();
             if (signature.getParameterCount(!isStatic) != args.length) {
                 throw new AssertionError(graph + ": wrong number of arguments to " + method);
             }
    @@ -179,16 +180,16 @@
         /**
          * Rewrite all word types in the graph.
          */
    -    public void rewriteWordTypes() {
    -        new WordTypeRewriterPhase(providers.getMetaAccess(), providers.getCodeCache().getTarget().wordKind).apply(graph);
    +    public void rewriteWordTypes(SnippetReflectionProvider snippetReflection) {
    +        new WordTypeRewriterPhase(providers.getMetaAccess(), snippetReflection, providers.getCodeCache().getTarget().wordKind).apply(graph);
         }
     
         /**
    -     * {@linkplain #inline(InvokeNode) Inlines} all invocations currently in the graph.
    +     * {@linkplain #inline Inlines} all invocations currently in the graph.
          */
    -    public void inlineInvokes() {
    +    public void inlineInvokes(SnippetReflectionProvider snippetReflection) {
             for (InvokeNode invoke : graph.getNodes().filter(InvokeNode.class).snapshot()) {
    -            inline(invoke);
    +            inline(invoke, snippetReflection);
             }
     
             // Clean up all code that is now dead after inlining.
    @@ -201,9 +202,9 @@
          * {@linkplain ReplacementsImpl#makeGraph processed} in the same manner as for snippets and
          * method substitutions.
          */
    -    public void inline(InvokeNode invoke) {
    +    public void inline(InvokeNode invoke, SnippetReflectionProvider snippetReflection) {
             ResolvedJavaMethod method = ((MethodCallTargetNode) invoke.callTarget()).targetMethod();
    -        ReplacementsImpl repl = new ReplacementsImpl(providers, new Assumptions(false), providers.getCodeCache().getTarget());
    +        ReplacementsImpl repl = new ReplacementsImpl(providers, snippetReflection, new Assumptions(false), providers.getCodeCache().getTarget());
             StructuredGraph calleeGraph = repl.makeGraph(method, null, method, null, FrameStateProcessing.CollapseFrameForSingleSideEffect);
             InliningUtil.inline(invoke, calleeGraph, false);
         }
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/InstanceOfSnippetsTemplates.java
    --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/InstanceOfSnippetsTemplates.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/InstanceOfSnippetsTemplates.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -27,6 +27,8 @@
     import java.util.*;
     
     import com.oracle.graal.api.code.*;
    +import com.oracle.graal.api.replacements.*;
    +import com.oracle.graal.compiler.common.calc.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.calc.*;
    @@ -53,8 +55,8 @@
      */
     public abstract class InstanceOfSnippetsTemplates extends AbstractTemplates {
     
    -    public InstanceOfSnippetsTemplates(Providers providers, TargetDescription target) {
    -        super(providers, target);
    +    public InstanceOfSnippetsTemplates(Providers providers, SnippetReflectionProvider snippetReflection, TargetDescription target) {
    +        super(providers, snippetReflection, target);
         }
     
         /**
    @@ -130,7 +132,7 @@
     
             /**
              * Gets the result of this instantiation as a condition.
    -         * 
    +         *
              * @param testValue the returned condition is true if the result is equal to this value
              */
             LogicNode asCondition(ValueNode testValue) {
    @@ -148,7 +150,7 @@
     
             /**
              * Gets the result of the instantiation as a materialized value.
    -         * 
    +         *
              * @param t the true value for the materialization
              * @param f the false value for the materialization
              */
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeClassSubstitutions.java
    --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeClassSubstitutions.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeClassSubstitutions.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,15 +22,11 @@
      */
     package com.oracle.graal.replacements;
     
    -import static com.oracle.graal.phases.GraalOptions.*;
    -
     import com.oracle.graal.api.meta.*;
     import com.oracle.graal.api.replacements.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.extended.*;
    -import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.replacements.nodes.*;
     
     /**
      * Substitutions for improving the performance of some critical methods in {@link NodeClass}
    @@ -42,33 +38,13 @@
     @ClassSubstitution(NodeClass.class)
     public class NodeClassSubstitutions {
     
    -    /**
    -     * A macro node for calls to {@link NodeClass#get(Class)}. It can use the compiler's knowledge
    -     * about node classes to replace itself with a constant value for a constant {@link Class}
    -     * parameter.
    -     */
    -    public static class NodeClassGetNode extends PureFunctionMacroNode {
    -
    -        public NodeClassGetNode(Invoke invoke) {
    -            super(invoke);
    -        }
    -
    -        @Override
    -        protected Constant evaluate(Constant param, MetaAccessProvider metaAccess) {
    -            return param.isNull() || ImmutableCode.getValue() ? null : Constant.forObject(NodeClass.get((Class) param.asObject()));
    -        }
    -    }
    -
    -    @MacroSubstitution(isStatic = true, forced = true, macro = NodeClassGetNode.class)
    -    private static native NodeClass get(Class c);
    -
         @MethodSubstitution
         private static Node getNode(Node node, long offset) {
             return PiNode.piCast(UnsafeLoadNode.load(node, offset, Kind.Object, LocationIdentity.ANY_LOCATION), Node.class);
         }
     
         @MethodSubstitution
    -    private static NodeList getNodeList(Node node, long offset) {
    +    private static NodeList getNodeList(Node node, long offset) {
             return PiNode.piCast(UnsafeLoadNode.load(node, offset, Kind.Object, LocationIdentity.ANY_LOCATION), NodeList.class);
         }
     
    @@ -78,7 +54,7 @@
         }
     
         @MethodSubstitution
    -    private static void putNodeList(Node node, long offset, NodeList value) {
    +    private static void putNodeList(Node node, long offset, NodeList value) {
             UnsafeStoreNode.store(node, offset, value, Kind.Object, LocationIdentity.ANY_LOCATION);
         }
     
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationPhase.java
    --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationPhase.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationPhase.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -29,6 +29,9 @@
     
     import com.oracle.graal.api.code.*;
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.api.replacements.*;
    +import com.oracle.graal.compiler.common.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.debug.*;
     import com.oracle.graal.debug.internal.*;
     import com.oracle.graal.graph.*;
    @@ -39,7 +42,6 @@
     import com.oracle.graal.nodes.calc.*;
     import com.oracle.graal.nodes.extended.*;
     import com.oracle.graal.nodes.java.*;
    -import com.oracle.graal.nodes.type.*;
     import com.oracle.graal.nodes.util.*;
     import com.oracle.graal.phases.*;
     import com.oracle.graal.phases.util.*;
    @@ -52,9 +54,11 @@
     public class NodeIntrinsificationPhase extends Phase {
     
         private final Providers providers;
    +    private final SnippetReflectionProvider snippetReflection;
     
    -    public NodeIntrinsificationPhase(Providers providers) {
    +    public NodeIntrinsificationPhase(Providers providers, SnippetReflectionProvider snippetReflection) {
             this.providers = providers;
    +        this.snippetReflection = snippetReflection;
         }
     
         @Override
    @@ -77,7 +81,7 @@
             NodeIntrinsic intrinsic = getIntrinsic(target);
             if (intrinsic != null) {
                 assert target.getAnnotation(Fold.class) == null;
    -            assert Modifier.isStatic(target.getModifiers()) : "node intrinsic must be static: " + target;
    +            assert target.isStatic() : "node intrinsic must be static: " + target;
     
                 ResolvedJavaType[] parameterTypes = resolveJavaTypes(signatureToTypes(target), declaringClass);
     
    @@ -167,25 +171,25 @@
                     }
                     ConstantNode constantNode = (ConstantNode) argument;
                     Constant constant = constantNode.asConstant();
    -                Object o = constant.asBoxedValue();
    -                if (o instanceof Class) {
    -                    reflectionCallArguments[i] = Constant.forObject(providers.getMetaAccess().lookupJavaType((Class) o));
    +                ResolvedJavaType type = providers.getConstantReflection().asJavaType(constant);
    +                if (type != null) {
    +                    reflectionCallArguments[i] = snippetReflection.forObject(type);
                         parameterTypes[i] = providers.getMetaAccess().lookupJavaType(ResolvedJavaType.class);
                     } else {
                         if (parameterTypes[i].getKind() == Kind.Boolean) {
    -                        reflectionCallArguments[i] = Constant.forObject(Boolean.valueOf(constant.asInt() != 0));
    +                        reflectionCallArguments[i] = snippetReflection.forObject(Boolean.valueOf(constant.asInt() != 0));
                         } else if (parameterTypes[i].getKind() == Kind.Byte) {
    -                        reflectionCallArguments[i] = Constant.forObject(Byte.valueOf((byte) constant.asInt()));
    +                        reflectionCallArguments[i] = snippetReflection.forObject(Byte.valueOf((byte) constant.asInt()));
                         } else if (parameterTypes[i].getKind() == Kind.Short) {
    -                        reflectionCallArguments[i] = Constant.forObject(Short.valueOf((short) constant.asInt()));
    +                        reflectionCallArguments[i] = snippetReflection.forObject(Short.valueOf((short) constant.asInt()));
                         } else if (parameterTypes[i].getKind() == Kind.Char) {
    -                        reflectionCallArguments[i] = Constant.forObject(Character.valueOf((char) constant.asInt()));
    +                        reflectionCallArguments[i] = snippetReflection.forObject(Character.valueOf((char) constant.asInt()));
                         } else {
                             reflectionCallArguments[i] = constant;
                         }
                     }
                 } else {
    -                reflectionCallArguments[i] = Constant.forObject(argument);
    +                reflectionCallArguments[i] = snippetReflection.forObject(argument);
                     parameterTypes[i] = providers.getMetaAccess().lookupJavaType(ValueNode.class);
                 }
             }
    @@ -226,7 +230,7 @@
             }
     
             try {
    -            ValueNode intrinsicNode = (ValueNode) constructor.newInstance(arguments).asObject();
    +            ValueNode intrinsicNode = (ValueNode) snippetReflection.asObject(constructor.newInstance(arguments));
     
                 if (setStampFromReturnType) {
                     intrinsicNode.setStamp(invokeStamp);
    @@ -267,11 +271,13 @@
                 if (getParameterAnnotation(InjectedNodeParameter.class, i, c) != null) {
                     injected = injected == null ? new Constant[1] : Arrays.copyOf(injected, injected.length + 1);
                     if (signature[i].equals(metaAccess.lookupJavaType(MetaAccessProvider.class))) {
    -                    injected[injected.length - 1] = Constant.forObject(metaAccess);
    +                    injected[injected.length - 1] = snippetReflection.forObject(metaAccess);
                     } else if (signature[i].equals(metaAccess.lookupJavaType(StructuredGraph.class))) {
    -                    injected[injected.length - 1] = Constant.forObject(graph);
    +                    injected[injected.length - 1] = snippetReflection.forObject(graph);
                     } else if (signature[i].equals(metaAccess.lookupJavaType(ForeignCallsProvider.class))) {
    -                    injected[injected.length - 1] = Constant.forObject(providers.getForeignCalls());
    +                    injected[injected.length - 1] = snippetReflection.forObject(providers.getForeignCalls());
    +                } else if (signature[i].equals(metaAccess.lookupJavaType(SnippetReflectionProvider.class))) {
    +                    injected[injected.length - 1] = snippetReflection.forObject(snippetReflection);
                     } else {
                         throw new GraalInternalError("Cannot handle injected argument of type %s in %s", toJavaName(signature[i]), format("%H.%n(%p)", c));
                     }
    @@ -311,9 +317,9 @@
                 arguments = Arrays.copyOf(nodeConstructorArguments, fixedArgs + 1);
                 arguments[fixedArgs] = componentType.newArray(nodeConstructorArguments.length - fixedArgs);
     
    -            Object varargs = arguments[fixedArgs].asObject();
    +            Object varargs = snippetReflection.asObject(arguments[fixedArgs]);
                 for (int i = fixedArgs; i < nodeConstructorArguments.length; i++) {
    -                Array.set(varargs, i - fixedArgs, nodeConstructorArguments[i].asBoxedValue());
    +                Array.set(varargs, i - fixedArgs, snippetReflection.asBoxedValue(nodeConstructorArguments[i]));
                 }
             } else {
                 return null;
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationVerificationPhase.java
    --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationVerificationPhase.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationVerificationPhase.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,6 +23,7 @@
     package com.oracle.graal.replacements;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.graph.Node.ConstantNodeParameter;
     import com.oracle.graal.graph.Node.NodeIntrinsic;
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java
    --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -24,7 +24,7 @@
     
     import static com.oracle.graal.api.meta.MetaUtil.*;
     import static com.oracle.graal.compiler.GraalCompiler.*;
    -import static com.oracle.graal.phases.GraalOptions.*;
    +import static com.oracle.graal.compiler.common.GraalOptions.*;
     
     import java.lang.reflect.*;
     import java.util.*;
    @@ -35,10 +35,12 @@
     import com.oracle.graal.api.code.*;
     import com.oracle.graal.api.meta.*;
     import com.oracle.graal.api.replacements.*;
    +import com.oracle.graal.compiler.common.*;
     import com.oracle.graal.debug.*;
     import com.oracle.graal.debug.Debug.Scope;
     import com.oracle.graal.debug.internal.*;
     import com.oracle.graal.graph.*;
    +import com.oracle.graal.graph.Graph.Mark;
     import com.oracle.graal.java.*;
     import com.oracle.graal.java.GraphBuilderPhase.Instance;
     import com.oracle.graal.nodes.*;
    @@ -56,6 +58,7 @@
     public class ReplacementsImpl implements Replacements {
     
         protected final Providers providers;
    +    protected final SnippetReflectionProvider snippetReflection;
         protected final TargetDescription target;
         protected final Assumptions assumptions;
     
    @@ -71,8 +74,9 @@
         private final Set forcedSubstitutions;
         private final Map, SnippetTemplateCache> snippetTemplateCache;
     
    -    public ReplacementsImpl(Providers providers, Assumptions assumptions, TargetDescription target) {
    +    public ReplacementsImpl(Providers providers, SnippetReflectionProvider snippetReflection, Assumptions assumptions, TargetDescription target) {
             this.providers = providers.copyWith(this);
    +        this.snippetReflection = snippetReflection;
             this.target = target;
             this.assumptions = assumptions;
             this.graphs = new ConcurrentHashMap<>();
    @@ -92,7 +96,7 @@
         @Override
         public StructuredGraph getSnippet(ResolvedJavaMethod method, ResolvedJavaMethod recursiveEntry) {
             assert method.getAnnotation(Snippet.class) != null : "Snippet must be annotated with @" + Snippet.class.getSimpleName();
    -        assert !Modifier.isAbstract(method.getModifiers()) && !Modifier.isNative(method.getModifiers()) : "Snippet must not be abstract or native";
    +        assert !method.isAbstract() && !method.isNative() : "Snippet must not be abstract or native";
     
             StructuredGraph graph = UseSnippetGraphCache ? graphs.get(method) : null;
             if (graph == null) {
    @@ -121,7 +125,7 @@
     
             // Do deferred intrinsification of node intrinsics
     
    -        new NodeIntrinsificationPhase(providers).apply(specializedSnippet);
    +        new NodeIntrinsificationPhase(providers, snippetReflection).apply(specializedSnippet);
             new CanonicalizerPhase(true).apply(specializedSnippet, new PhaseContext(providers, assumptions));
             NodeIntrinsificationVerificationPhase.verify(specializedSnippet);
         }
    @@ -232,7 +236,7 @@
             if (originalMember instanceof Method) {
                 original = metaAccess.lookupJavaMethod((Method) originalMember);
             } else {
    -            original = metaAccess.lookupJavaConstructor((Constructor) originalMember);
    +            original = metaAccess.lookupJavaConstructor((Constructor) originalMember);
             }
             if (Debug.isLogEnabled()) {
                 Debug.log("substitution: %s --> %s", MetaUtil.format("%H.%n(%p) %r", original), MetaUtil.format("%H.%n(%p) %r", substitute));
    @@ -255,7 +259,7 @@
             if (originalMethod instanceof Method) {
                 originalJavaMethod = metaAccess.lookupJavaMethod((Method) originalMethod);
             } else {
    -            originalJavaMethod = metaAccess.lookupJavaConstructor((Constructor) originalMethod);
    +            originalJavaMethod = metaAccess.lookupJavaConstructor((Constructor) originalMethod);
             }
             registeredMacroSubstitutions.put(originalJavaMethod, macro);
             return originalJavaMethod;
    @@ -364,7 +368,7 @@
              * Does final processing of a snippet graph.
              */
             protected void finalizeGraph(StructuredGraph graph) {
    -            new NodeIntrinsificationPhase(providers).apply(graph);
    +            new NodeIntrinsificationPhase(providers, snippetReflection).apply(graph);
                 if (!SnippetTemplate.hasConstantParameter(method)) {
                     NodeIntrinsificationVerificationPhase.verify(graph);
                 }
    @@ -412,8 +416,8 @@
                 try (Scope s = Debug.scope("buildInitialGraph", graph)) {
                     MetaAccessProvider metaAccess = providers.getMetaAccess();
                     createGraphBuilder(metaAccess, GraphBuilderConfiguration.getSnippetDefault(), OptimisticOptimizations.NONE).apply(graph);
    -                new WordTypeVerificationPhase(metaAccess, target.wordKind).apply(graph);
    -                new WordTypeRewriterPhase(metaAccess, target.wordKind).apply(graph);
    +                new WordTypeVerificationPhase(metaAccess, snippetReflection, target.wordKind).apply(graph);
    +                new WordTypeRewriterPhase(metaAccess, snippetReflection, target.wordKind).apply(graph);
     
                     if (OptCanonicalizer.getValue()) {
                         new CanonicalizerPhase(true).apply(graph, new PhaseContext(providers, assumptions));
    @@ -449,7 +453,7 @@
              * Called after all inlining for a given graph is complete.
              */
             protected void afterInlining(StructuredGraph graph) {
    -            new NodeIntrinsificationPhase(providers).apply(graph);
    +            new NodeIntrinsificationPhase(providers, snippetReflection).apply(graph);
                 new DeadCodeEliminationPhase().apply(graph);
                 if (OptCanonicalizer.getValue()) {
                     new CanonicalizerPhase(true).apply(graph, new PhaseContext(providers, assumptions));
    @@ -458,17 +462,30 @@
     
             private StructuredGraph buildGraph(final ResolvedJavaMethod methodToParse, final SnippetInliningPolicy policy, int inliningDepth) {
                 assert inliningDepth < MAX_GRAPH_INLINING_DEPTH : "inlining limit exceeded";
    -            assert isInlinableSnippet(methodToParse) : methodToParse;
    +            assert isInlinable(methodToParse) : methodToParse;
                 final StructuredGraph graph = buildInitialGraph(methodToParse);
                 try (Scope s = Debug.scope("buildGraph", graph)) {
    -
    +                Set doNotInline = null;
                     for (MethodCallTargetNode callTarget : graph.getNodes(MethodCallTargetNode.class)) {
    +                    if (doNotInline != null && doNotInline.contains(callTarget)) {
    +                        continue;
    +                    }
                         ResolvedJavaMethod callee = callTarget.targetMethod();
                         if (callee.equals(recursiveEntry)) {
    -                        if (isInlinableSnippet(substitutedMethod)) {
    +                        if (isInlinable(substitutedMethod)) {
                                 final StructuredGraph originalGraph = buildInitialGraph(substitutedMethod);
    +                            Mark mark = graph.getMark();
                                 InliningUtil.inline(callTarget.invoke(), originalGraph, true);
    -
    +                            for (MethodCallTargetNode inlinedCallTarget : graph.getNewNodes(mark).filter(MethodCallTargetNode.class)) {
    +                                if (doNotInline == null) {
    +                                    doNotInline = new HashSet<>();
    +                                }
    +                                // We do not want to do further inlining (now) for calls
    +                                // in the original method as this can cause unlimited
    +                                // recursive inlining given an eager inlining policy such
    +                                // as DefaultSnippetInliningPolicy.
    +                                doNotInline.add(inlinedCallTarget);
    +                            }
                                 Debug.dump(graph, "after inlining %s", callee);
                                 afterInline(graph, originalGraph, null);
                             }
    @@ -514,8 +531,8 @@
             }
         }
     
    -    private static boolean isInlinableSnippet(final ResolvedJavaMethod methodToParse) {
    -        return !Modifier.isAbstract(methodToParse.getModifiers()) && !Modifier.isNative(methodToParse.getModifiers());
    +    private static boolean isInlinable(final ResolvedJavaMethod method) {
    +        return !method.isAbstract() && !method.isNative();
         }
     
         private static String originalName(Method substituteMethod, String methodSubstitution) {
    @@ -533,7 +550,7 @@
          * @param optional if true, resolution failure returns null
          * @return the resolved class or null if resolution fails and {@code optional} is true
          */
    -    static Class resolveType(String className, boolean optional) {
    +    static Class resolveType(String className, boolean optional) {
             try {
                 // Need to use launcher class path to handle classes
                 // that are not on the boot class path
    @@ -547,7 +564,7 @@
             }
         }
     
    -    private static Class resolveType(JavaType type) {
    +    private static Class resolveType(JavaType type) {
             JavaType base = type;
             int dimensions = 0;
             while (base.getComponentType() != null) {
    @@ -555,15 +572,15 @@
                 dimensions++;
             }
     
    -        Class baseClass = base.getKind() != Kind.Object ? base.getKind().toJavaClass() : resolveType(toJavaName(base), false);
    +        Class baseClass = base.getKind() != Kind.Object ? base.getKind().toJavaClass() : resolveType(toJavaName(base), false);
             return dimensions == 0 ? baseClass : Array.newInstance(baseClass, new int[dimensions]).getClass();
         }
     
         static class JavaSignature {
    -        final Class returnType;
    -        final Class[] parameters;
    +        final Class returnType;
    +        final Class[] parameters;
     
    -        public JavaSignature(Class returnType, Class[] parameters) {
    +        public JavaSignature(Class returnType, Class[] parameters) {
                 this.parameters = parameters;
                 this.returnType = returnType;
             }
    @@ -582,8 +599,8 @@
         }
     
         private JavaSignature originalSignature(Method substituteMethod, String methodSubstitution, boolean isStatic) {
    -        Class[] parameters;
    -        Class returnType;
    +        Class[] parameters;
    +        Class returnType;
             if (methodSubstitution.isEmpty()) {
                 parameters = substituteMethod.getParameterTypes();
                 if (!isStatic) {
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/Snippet.java
    --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/Snippet.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/Snippet.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,8 +23,6 @@
     package com.oracle.graal.replacements;
     
     import java.lang.annotation.*;
    -import java.lang.reflect.*;
    -
     import com.oracle.graal.api.meta.*;
     import com.oracle.graal.graph.Node.NodeIntrinsic;
     import com.oracle.graal.replacements.nodes.*;
    @@ -89,7 +87,7 @@
     
             @Override
             public boolean shouldInline(ResolvedJavaMethod method, ResolvedJavaMethod caller) {
    -            if (Modifier.isNative(method.getModifiers())) {
    +            if (method.isNative()) {
                     return false;
                 }
                 if (method.getAnnotation(Fold.class) != null) {
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetCounter.java
    --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetCounter.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetCounter.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -24,13 +24,13 @@
     
     //JaCoCo Exclude
     
    -import static com.oracle.graal.graph.UnsafeAccess.*;
    +import static com.oracle.graal.compiler.common.UnsafeAccess.*;
     
     import java.io.*;
     import java.util.*;
     
     import com.oracle.graal.api.meta.*;
    -import com.oracle.graal.graph.*;
    +import com.oracle.graal.compiler.common.*;
     import com.oracle.graal.replacements.Snippet.Fold;
     import com.oracle.graal.replacements.nodes.*;
     
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java
    --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -35,6 +35,8 @@
     import com.oracle.graal.api.code.*;
     import com.oracle.graal.api.meta.*;
     import com.oracle.graal.api.replacements.*;
    +import com.oracle.graal.compiler.common.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.debug.*;
     import com.oracle.graal.debug.Debug.Scope;
     import com.oracle.graal.debug.internal.*;
    @@ -47,7 +49,6 @@
     import com.oracle.graal.nodes.extended.*;
     import com.oracle.graal.nodes.java.*;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
     import com.oracle.graal.nodes.util.*;
     import com.oracle.graal.phases.common.*;
     import com.oracle.graal.phases.common.FloatingReadPhase.MemoryMapImpl;
    @@ -101,7 +102,7 @@
                 this.method = method;
                 instantiationCounter = Debug.metric("SnippetInstantiationCount[%s]", method);
                 instantiationTimer = Debug.timer("SnippetInstantiationTime[%s]", method);
    -            assert Modifier.isStatic(method.getModifiers()) : "snippet method must be static: " + MetaUtil.format("%H.%n", method);
    +            assert method.isStatic() : "snippet method must be static: " + MetaUtil.format("%H.%n", method);
                 int count = method.getSignature().getParameterCount(false);
                 constantParameters = new boolean[count];
                 varargsParameters = new boolean[count];
    @@ -207,7 +208,7 @@
                 return this;
             }
     
    -        public Arguments addVarargs(String name, Class componentType, Stamp argStamp, Object value) {
    +        public Arguments addVarargs(String name, Class componentType, Stamp argStamp, Object value) {
                 assert check(name, false, true);
                 Varargs varargs = new Varargs(componentType, argStamp, value);
                 values[nextParamIdx] = varargs;
    @@ -276,17 +277,17 @@
          */
         static class Varargs {
     
    -        protected final Class componentType;
    +        protected final Class componentType;
             protected final Stamp stamp;
             protected final Object value;
             protected final int length;
     
    -        protected Varargs(Class componentType, Stamp stamp, Object value) {
    +        protected Varargs(Class componentType, Stamp stamp, Object value) {
                 this.componentType = componentType;
                 this.stamp = stamp;
                 this.value = value;
                 if (value instanceof List) {
    -                this.length = ((List) value).size();
    +                this.length = ((List) value).size();
                 } else {
                     this.length = Array.getLength(value);
                 }
    @@ -399,11 +400,13 @@
         public abstract static class AbstractTemplates implements SnippetTemplateCache {
     
             protected final Providers providers;
    +        protected final SnippetReflectionProvider snippetReflection;
             protected final TargetDescription target;
             private final ConcurrentHashMap templates;
     
    -        protected AbstractTemplates(Providers providers, TargetDescription target) {
    +        protected AbstractTemplates(Providers providers, SnippetReflectionProvider snippetReflection, TargetDescription target) {
                 this.providers = providers;
    +            this.snippetReflection = snippetReflection;
                 this.target = target;
                 if (UseSnippetTemplateCache) {
                     this.templates = new ConcurrentHashMap<>();
    @@ -443,7 +446,7 @@
                 if (template == null) {
                     SnippetTemplates.increment();
                     try (TimerCloseable a = SnippetTemplateCreationTime.start(); Scope s = Debug.scope("SnippetSpecialization", args.info.method)) {
    -                    template = new SnippetTemplate(providers, args);
    +                    template = new SnippetTemplate(providers, snippetReflection, args);
                         if (UseSnippetTemplateCache) {
                             templates.put(args.cacheKey, template);
                         }
    @@ -470,10 +473,14 @@
             return false;
         }
     
    +    private final SnippetReflectionProvider snippetReflection;
    +
         /**
          * Creates a snippet template.
          */
    -    protected SnippetTemplate(final Providers providers, Arguments args) {
    +    protected SnippetTemplate(final Providers providers, SnippetReflectionProvider snippetReflection, Arguments args) {
    +        this.snippetReflection = snippetReflection;
    +
             StructuredGraph snippetGraph = providers.getReplacements().getSnippet(args.info.method);
             instantiationTimer = Debug.timer("SnippetTemplateInstantiationTime[%#s]", args);
             instantiationCounter = Debug.metric("SnippetTemplateInstantiationCount[%#s]", args);
    @@ -502,7 +509,7 @@
                     if (arg instanceof Constant) {
                         constantArg = (Constant) arg;
                     } else {
    -                    constantArg = Constant.forBoxed(kind, arg);
    +                    constantArg = snippetReflection.forBoxed(kind, arg);
                     }
                     nodeReplacements.put(snippetGraph.getParameter(i), ConstantNode.forConstant(constantArg, metaAccess, snippetCopy));
                 } else if (args.info.isVarargsParameter(i)) {
    @@ -702,9 +709,7 @@
                 assert arg instanceof Constant : method + ": word constant parameters must be passed boxed in a Constant value: " + arg;
                 return true;
             }
    -        if (kind == Kind.Object) {
    -            assert arg == null || type.isInstance(Constant.forObject(arg)) : method + ": wrong value type for " + name + ": expected " + type.getName() + ", got " + arg.getClass().getName();
    -        } else {
    +        if (kind != Kind.Object) {
                 assert arg != null && kind.toBoxedJavaClass() == arg.getClass() : method + ": wrong value kind for " + name + ": expected " + kind + ", got " +
                                 (arg == null ? "null" : arg.getClass().getSimpleName());
             }
    @@ -803,10 +808,10 @@
                     ParameterNode[] params = (ParameterNode[]) parameter;
                     Varargs varargs = (Varargs) argument;
                     int length = params.length;
    -                List list = null;
    +                List list = null;
                     Object array = null;
                     if (varargs.value instanceof List) {
    -                    list = (List) varargs.value;
    +                    list = (List) varargs.value;
                         assert list.size() == length : length + " != " + list.size();
                     } else {
                         array = varargs.value;
    @@ -843,20 +848,10 @@
          */
         protected Constant forBoxed(Object argument, Kind localKind) {
             assert localKind == localKind.getStackKind();
    -        if (localKind == Kind.Int && !(argument instanceof Integer)) {
    -            if (argument instanceof Boolean) {
    -                return Constant.forBoxed(Kind.Boolean, argument);
    -            }
    -            if (argument instanceof Byte) {
    -                return Constant.forBoxed(Kind.Byte, argument);
    -            }
    -            if (argument instanceof Short) {
    -                return Constant.forBoxed(Kind.Short, argument);
    -            }
    -            assert argument instanceof Character;
    -            return Constant.forBoxed(Kind.Char, argument);
    +        if (localKind == Kind.Int) {
    +            return Constant.forBoxedPrimitive(argument);
             }
    -        return Constant.forBoxed(localKind, argument);
    +        return snippetReflection.forBoxed(localKind, argument);
         }
     
         /**
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/StringSubstitutions.java
    --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/StringSubstitutions.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/StringSubstitutions.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,12 +22,12 @@
      */
     package com.oracle.graal.replacements;
     
    -import static com.oracle.graal.graph.UnsafeAccess.*;
    +import static com.oracle.graal.compiler.common.UnsafeAccess.*;
     
     import java.lang.reflect.*;
     
     import com.oracle.graal.api.replacements.*;
    -import com.oracle.graal.graph.*;
    +import com.oracle.graal.compiler.common.*;
     import com.oracle.graal.replacements.nodes.*;
     
     import edu.umd.cs.findbugs.annotations.*;
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/UnsafeSubstitutions.java
    --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/UnsafeSubstitutions.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/UnsafeSubstitutions.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 2011, 2014, 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
    @@ -42,17 +42,17 @@
     
         @MethodSubstitution(isStatic = false)
         public static boolean compareAndSwapObject(@SuppressWarnings("unused") final Object thisObj, Object o, long offset, Object expected, Object x) {
    -        return CompareAndSwapNode.compareAndSwap(o, 0, offset, expected, x);
    +        return CompareAndSwapNode.compareAndSwap(o, 0, offset, expected, x, Kind.Object, LocationIdentity.ANY_LOCATION);
         }
     
         @MethodSubstitution(isStatic = false)
         public static boolean compareAndSwapInt(@SuppressWarnings("unused") final Object thisObj, Object o, long offset, int expected, int x) {
    -        return CompareAndSwapNode.compareAndSwap(o, 0, offset, expected, x);
    +        return CompareAndSwapNode.compareAndSwap(o, 0, offset, expected, x, Kind.Int, LocationIdentity.ANY_LOCATION);
         }
     
         @MethodSubstitution(isStatic = false)
         public static boolean compareAndSwapLong(@SuppressWarnings("unused") final Object thisObj, Object o, long offset, long expected, long x) {
    -        return CompareAndSwapNode.compareAndSwap(o, 0, offset, expected, x);
    +        return CompareAndSwapNode.compareAndSwap(o, 0, offset, expected, x, Kind.Long, LocationIdentity.ANY_LOCATION);
         }
     
         @MethodSubstitution(isStatic = false)
    @@ -387,7 +387,7 @@
         }
     
         @MethodSubstitution(isStatic = false)
    -    public static Object allocateInstance(final Unsafe thisObj, Class clazz) throws InstantiationException {
    +    public static Object allocateInstance(final Unsafe thisObj, Class clazz) throws InstantiationException {
             if (clazz.isPrimitive()) {
                 throw new InstantiationException(clazz.getName());
             }
    @@ -399,4 +399,47 @@
             }
             return DynamicNewInstanceNode.allocateInstance(clazz, true);
         }
    +
    +    /**
    +     * Guard for {@link Unsafe#getAndSetInt} method family.
    +     */
    +    public static class GetAndSetGuard implements SubstitutionGuard {
    +        public boolean execute() {
    +            // FIXME should return whether the current compilation target supports these
    +            String arch = System.getProperty("os.arch");
    +            switch (arch) {
    +                case "amd64":
    +                case "x86_64":
    +                    return true;
    +                default:
    +                    return false;
    +            }
    +        }
    +    }
    +
    +    @MethodSubstitution(isStatic = false, guard = GetAndSetGuard.class)
    +    public static int getAndAddInt(@SuppressWarnings("unused") final Object thisObj, Object o, long offset, int delta) {
    +        return AtomicReadAndAddNode.getAndAddInt(o, offset, delta, LocationIdentity.ANY_LOCATION);
    +    }
    +
    +    @MethodSubstitution(isStatic = false, guard = GetAndSetGuard.class)
    +    public static long getAndAddLong(@SuppressWarnings("unused") final Object thisObj, Object o, long offset, long delta) {
    +        return AtomicReadAndAddNode.getAndAddLong(o, offset, delta, LocationIdentity.ANY_LOCATION);
    +    }
    +
    +    @MethodSubstitution(isStatic = false, guard = GetAndSetGuard.class)
    +    public static int getAndSetInt(@SuppressWarnings("unused") final Object thisObj, Object o, long offset, int newValue) {
    +        return AtomicReadAndWriteNode.getAndSetInt(o, offset, newValue, Kind.Int, LocationIdentity.ANY_LOCATION);
    +    }
    +
    +    @MethodSubstitution(isStatic = false, guard = GetAndSetGuard.class)
    +    public static long getAndSetLong(@SuppressWarnings("unused") final Object thisObj, Object o, long offset, long newValue) {
    +        return AtomicReadAndWriteNode.getAndSetLong(o, offset, newValue, Kind.Long, LocationIdentity.ANY_LOCATION);
    +    }
    +
    +    @MethodSubstitution(isStatic = false, guard = GetAndSetGuard.class)
    +    public static Object getAndSetObject(@SuppressWarnings("unused") final Object thisObj, Object o, long offset, Object newValue) {
    +        return AtomicReadAndWriteNode.getAndSetObject(o, offset, newValue, Kind.Object, LocationIdentity.ANY_LOCATION);
    +    }
    +
     }
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/UnsignedMathSubstitutions.java
    --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/UnsignedMathSubstitutions.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/UnsignedMathSubstitutions.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,7 +22,7 @@
      */
     package com.oracle.graal.replacements;
     
    -import static com.oracle.graal.nodes.calc.Condition.*;
    +import static com.oracle.graal.compiler.common.calc.Condition.*;
     import static com.oracle.graal.nodes.calc.ConditionalNode.*;
     
     import com.oracle.graal.api.code.*;
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/ArrayEqualsNode.java
    --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/ArrayEqualsNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/ArrayEqualsNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,6 +23,7 @@
     package com.oracle.graal.replacements.nodes;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.compiler.gen.*;
     import com.oracle.graal.compiler.target.*;
     import com.oracle.graal.graph.*;
    @@ -30,7 +31,6 @@
     import com.oracle.graal.lir.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
     import com.oracle.graal.nodes.util.*;
     
     /**
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BitCountNode.java
    --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BitCountNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BitCountNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,6 +23,7 @@
     package com.oracle.graal.replacements.nodes;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.compiler.gen.*;
     import com.oracle.graal.compiler.target.*;
     import com.oracle.graal.graph.*;
    @@ -30,7 +31,6 @@
     import com.oracle.graal.lir.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.calc.*;
    -import com.oracle.graal.nodes.type.*;
     
     public class BitCountNode extends FloatingNode implements LIRGenLowerable, Canonicalizable {
     
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BitScanForwardNode.java
    --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BitScanForwardNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BitScanForwardNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,6 +23,7 @@
     package com.oracle.graal.replacements.nodes;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.compiler.gen.*;
     import com.oracle.graal.compiler.target.*;
     import com.oracle.graal.graph.*;
    @@ -30,7 +31,6 @@
     import com.oracle.graal.lir.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.calc.*;
    -import com.oracle.graal.nodes.type.*;
     
     public class BitScanForwardNode extends FloatingNode implements LIRGenLowerable, Canonicalizable {
     
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BitScanReverseNode.java
    --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BitScanReverseNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BitScanReverseNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,6 +23,7 @@
     package com.oracle.graal.replacements.nodes;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.compiler.gen.*;
     import com.oracle.graal.compiler.target.*;
     import com.oracle.graal.graph.*;
    @@ -30,7 +31,6 @@
     import com.oracle.graal.lir.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.calc.*;
    -import com.oracle.graal.nodes.type.*;
     
     public class BitScanReverseNode extends FloatingNode implements LIRGenLowerable, Canonicalizable {
     
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/DirectObjectStoreNode.java
    --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/DirectObjectStoreNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/DirectObjectStoreNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,11 +23,11 @@
     package com.oracle.graal.replacements.nodes;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.HeapAccess.BarrierType;
     import com.oracle.graal.nodes.extended.*;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
     
     /**
      * A special purpose store node that differs from {@link UnsafeStoreNode} in that it is not a
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/DirectReadNode.java
    --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/DirectReadNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/DirectReadNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,13 +22,13 @@
      */
     package com.oracle.graal.replacements.nodes;
     
    -import static com.oracle.graal.graph.UnsafeAccess.*;
    +import static com.oracle.graal.compiler.common.UnsafeAccess.*;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.extended.*;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
     
     /**
      * A special purpose store node that differs from {@link UnsafeStoreNode} in that it is not a
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/DirectStoreNode.java
    --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/DirectStoreNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/DirectStoreNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,13 +22,13 @@
      */
     package com.oracle.graal.replacements.nodes;
     
    -import static com.oracle.graal.graph.UnsafeAccess.*;
    +import static com.oracle.graal.compiler.common.UnsafeAccess.*;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.extended.*;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
     
     /**
      * A special purpose store node that differs from {@link UnsafeStoreNode} in that it is not a
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/ExplodeLoopNode.java
    --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/ExplodeLoopNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/ExplodeLoopNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -24,9 +24,9 @@
     
     import java.util.*;
     
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.nodes.*;
    -import com.oracle.graal.nodes.type.*;
     import com.oracle.graal.replacements.Snippet.VarargsParameter;
     
     /**
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/LoadSnippetVarargParameterNode.java
    --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/LoadSnippetVarargParameterNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/LoadSnippetVarargParameterNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,10 +22,10 @@
      */
     package com.oracle.graal.replacements.nodes;
     
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.graph.spi.*;
     import com.oracle.graal.nodes.*;
    -import com.oracle.graal.nodes.type.*;
     import com.oracle.graal.replacements.Snippet.VarargsParameter;
     
     /**
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MacroNode.java
    --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MacroNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MacroNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,9 +22,9 @@
      */
     package com.oracle.graal.replacements.nodes;
     
    -import static java.lang.reflect.Modifier.*;
    -
    +import com.oracle.graal.api.code.*;
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.*;
     import com.oracle.graal.debug.*;
     import com.oracle.graal.debug.Debug.Scope;
     import com.oracle.graal.graph.*;
    @@ -88,7 +88,7 @@
             StructuredGraph methodSubstitution = tool.getReplacements().getMethodSubstitution(getTargetMethod());
             if (methodSubstitution != null) {
                 methodSubstitution = methodSubstitution.copy();
    -            if (stateAfter() == null || stateAfter().bci == FrameState.AFTER_BCI) {
    +            if (stateAfter() == null || stateAfter().bci == BytecodeFrame.AFTER_BCI) {
                     /*
                      * handles the case of a MacroNode inside a snippet used for another MacroNode
                      * lowering
    @@ -135,7 +135,7 @@
             if (replacementGraph != null) {
                 // Pull out the receiver null check so that a replaced
                 // receiver can be lowered if necessary
    -            if (!isStatic(targetMethod.getModifiers())) {
    +            if (!targetMethod.isStatic()) {
                     ValueNode nonNullReceiver = InliningUtil.nonNullReceiver(invoke);
                     if (nonNullReceiver instanceof Lowerable) {
                         ((Lowerable) nonNullReceiver).lower(tool);
    @@ -172,7 +172,7 @@
                 if (!call.targetMethod().equals(getTargetMethod())) {
                     throw new GraalInternalError("unexpected invoke %s in snippet", getClass().getSimpleName());
                 }
    -            assert invoke.stateAfter().bci == FrameState.AFTER_BCI;
    +            assert invoke.stateAfter().bci == BytecodeFrame.AFTER_BCI;
                 // Here we need to fix the bci of the invoke
                 InvokeNode newInvoke = snippetGraph.add(new InvokeNode(invoke.callTarget(), getBci()));
                 newInvoke.setStateAfter(invoke.stateAfter());
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MathIntrinsicNode.java
    --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MathIntrinsicNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MathIntrinsicNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,12 +23,14 @@
     package com.oracle.graal.replacements.nodes;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.graph.spi.*;
    +import com.oracle.graal.lir.gen.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.calc.*;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
     
     public class MathIntrinsicNode extends FloatingNode implements Canonicalizable, ArithmeticLIRLowerable {
     
    @@ -61,35 +63,35 @@
         }
     
         @Override
    -    public void generate(NodeLIRBuilderTool gen) {
    -        Value input = gen.operand(x());
    +    public void generate(NodeMappableLIRBuilder builder, ArithmeticLIRGenerator gen) {
    +        Value input = builder.operand(x());
             Value result;
             switch (operation()) {
                 case ABS:
    -                result = gen.getLIRGeneratorTool().emitMathAbs(input);
    +                result = gen.emitMathAbs(input);
                     break;
                 case SQRT:
    -                result = gen.getLIRGeneratorTool().emitMathSqrt(input);
    +                result = gen.emitMathSqrt(input);
                     break;
                 case LOG:
    -                result = gen.getLIRGeneratorTool().emitMathLog(input, false);
    +                result = gen.emitMathLog(input, false);
                     break;
                 case LOG10:
    -                result = gen.getLIRGeneratorTool().emitMathLog(input, true);
    +                result = gen.emitMathLog(input, true);
                     break;
                 case SIN:
    -                result = gen.getLIRGeneratorTool().emitMathSin(input);
    +                result = gen.emitMathSin(input);
                     break;
                 case COS:
    -                result = gen.getLIRGeneratorTool().emitMathCos(input);
    +                result = gen.emitMathCos(input);
                     break;
                 case TAN:
    -                result = gen.getLIRGeneratorTool().emitMathTan(input);
    +                result = gen.emitMathTan(input);
                     break;
                 default:
                     throw GraalInternalError.shouldNotReachHere();
             }
    -        gen.setResult(this, result);
    +        builder.setResult(this, result);
         }
     
         public Constant evalConst(Constant... inputs) {
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MemoryAnchorNode.java
    --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MemoryAnchorNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MemoryAnchorNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,14 +22,15 @@
      */
     package com.oracle.graal.replacements.nodes;
     
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
    +import com.oracle.graal.graph.spi.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.extended.*;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
     
     @NodeInfo(allowedUsageTypes = {InputType.Memory})
    -public class MemoryAnchorNode extends FixedWithNextNode implements LIRLowerable, MemoryNode {
    +public class MemoryAnchorNode extends FixedWithNextNode implements LIRLowerable, MemoryNode, Canonicalizable {
     
         public MemoryAnchorNode() {
             super(StampFactory.forVoid());
    @@ -39,6 +40,11 @@
             // Nothing to emit, since this node is used for structural purposes only.
         }
     
    +    @Override
    +    public Node canonical(CanonicalizerTool tool) {
    +        return usages().isEmpty() ? null : this;
    +    }
    +
         public MemoryCheckpoint asMemoryCheckpoint() {
             return null;
         }
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/ReadRegisterNode.java
    --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/ReadRegisterNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/ReadRegisterNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -24,10 +24,10 @@
     
     import com.oracle.graal.api.code.*;
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
     
     /**
      * Access the value of a specific register.
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/ReverseBytesNode.java
    --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/ReverseBytesNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/ReverseBytesNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,6 +23,7 @@
     package com.oracle.graal.replacements.nodes;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.compiler.gen.*;
     import com.oracle.graal.compiler.target.*;
     import com.oracle.graal.graph.*;
    @@ -30,7 +31,6 @@
     import com.oracle.graal.lir.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.calc.*;
    -import com.oracle.graal.nodes.type.*;
     
     public class ReverseBytesNode extends FloatingNode implements LIRGenLowerable, Canonicalizable {
     
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/WriteRegisterNode.java
    --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/WriteRegisterNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/WriteRegisterNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -24,10 +24,10 @@
     
     import com.oracle.graal.api.code.*;
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
     
     /**
      * Changes the value of a specific register.
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.truffle.hotspot.amd64/src/com/oracle/graal/truffle/hotspot/amd64/AMD64OptimizedCallTargetInstrumentationFactory.java
    --- a/graal/com.oracle.graal.truffle.hotspot.amd64/src/com/oracle/graal/truffle/hotspot/amd64/AMD64OptimizedCallTargetInstrumentationFactory.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.truffle.hotspot.amd64/src/com/oracle/graal/truffle/hotspot/amd64/AMD64OptimizedCallTargetInstrumentationFactory.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -31,7 +31,6 @@
     import com.oracle.graal.asm.amd64.*;
     import com.oracle.graal.asm.amd64.AMD64Assembler.ConditionFlag;
     import com.oracle.graal.hotspot.*;
    -import com.oracle.graal.hotspot.amd64.*;
     import com.oracle.graal.hotspot.meta.*;
     import com.oracle.graal.lir.*;
     import com.oracle.graal.lir.asm.*;
    @@ -50,22 +49,9 @@
                     AMD64MacroAssembler asm = (AMD64MacroAssembler) this.asm;
                     Register thisRegister = codeCache.getRegisterConfig().getCallingConventionRegisters(Type.JavaCall, Kind.Object)[0];
                     Register spillRegister = AMD64.r10; // TODO(mg): fix me
    -                AMD64Address nMethodAddress = new AMD64Address(thisRegister, getFieldOffset("installedCode", OptimizedCallTarget.class));
    -                int verifiedEntryPoint = asm.position();
    -                if (config.useCompressedOops) {
    -                    asm.movl(spillRegister, nMethodAddress);
    -                    asm.nop(AMD64HotSpotBackend.PATCHED_VERIFIED_ENTRY_POINT_INSTRUCTION_SIZE - (asm.position() - verifiedEntryPoint));
    -                    AMD64HotSpotMove.decodePointer(asm, spillRegister, registers.getHeapBaseRegister(), config.getOopEncoding());
    -                } else {
    -                    asm.movq(spillRegister, nMethodAddress);
    -                    asm.nop(AMD64HotSpotBackend.PATCHED_VERIFIED_ENTRY_POINT_INSTRUCTION_SIZE - (asm.position() - verifiedEntryPoint));
    -                }
                     Label doProlog = new Label();
     
    -                asm.cmpq(spillRegister, 0);
    -                asm.jcc(ConditionFlag.Equal, doProlog);
    -
    -                AMD64Address codeBlobAddress = new AMD64Address(spillRegister, getFieldOffset("codeBlob", HotSpotInstalledCode.class));
    +                AMD64Address codeBlobAddress = new AMD64Address(thisRegister, getFieldOffset("address", InstalledCode.class));
                     asm.movq(spillRegister, codeBlobAddress);
                     asm.cmpq(spillRegister, 0);
                     asm.jcc(ConditionFlag.Equal, doProlog);
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotFrameInstance.java
    --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    +++ b/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotFrameInstance.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -0,0 +1,205 @@
    +/*
    + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
    + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    + *
    + * This code is free software; you can redistribute it and/or modify it
    + * under the terms of the GNU General Public License version 2 only, as
    + * published by the Free Software Foundation.
    + *
    + * This code is distributed in the hope that it will be useful, but WITHOUT
    + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    + * version 2 for more details (a copy is included in the LICENSE file that
    + * accompanied this code).
    + *
    + * You should have received a copy of the GNU General Public License version
    + * 2 along with this work; if not, write to the Free Software Foundation,
    + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    + *
    + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    + * or visit www.oracle.com if you need additional information or have any
    + * questions.
    + */
    +package com.oracle.graal.truffle.hotspot;
    +
    +import java.lang.reflect.*;
    +
    +import com.oracle.graal.api.code.stack.*;
    +import com.oracle.graal.compiler.common.*;
    +import com.oracle.graal.truffle.*;
    +import com.oracle.truffle.api.*;
    +import com.oracle.truffle.api.CompilerDirectives.SlowPath;
    +import com.oracle.truffle.api.frame.*;
    +import com.oracle.truffle.api.nodes.*;
    +
    +public abstract class HotSpotFrameInstance implements FrameInstance {
    +
    +    protected final InspectedFrame stackFrame;
    +
    +    public HotSpotFrameInstance(InspectedFrame stackFrame) {
    +        this.stackFrame = stackFrame;
    +    }
    +
    +    protected abstract int getNotifyIndex();
    +
    +    protected abstract int getCallTargetIndex();
    +
    +    protected abstract int getFrameIndex();
    +
    +    @SlowPath
    +    public Frame getFrame(FrameAccess access, boolean slowPath) {
    +        if (access == FrameAccess.NONE) {
    +            return null;
    +        }
    +        if (!slowPath && getNotifyIndex() != -1) {
    +            MaterializedFrameNotify notify = (MaterializedFrameNotify) stackFrame.getLocal(getNotifyIndex());
    +            if (notify != null) {
    +                if (access.ordinal() > notify.getOutsideFrameAccess().ordinal()) {
    +                    notify.setOutsideFrameAccess(access);
    +                }
    +                if (stackFrame.isVirtual(getFrameIndex())) {
    +                    stackFrame.materializeVirtualObjects(true);
    +                }
    +            }
    +        }
    +        switch (access) {
    +            case READ_ONLY: {
    +                Frame frame = (Frame) stackFrame.getLocal(getFrameIndex());
    +                // assert that it is really used read only
    +                assert (frame = new ReadOnlyFrame(frame)) != null;
    +                return frame;
    +            }
    +            case READ_WRITE:
    +            case MATERIALIZE:
    +                if (stackFrame.isVirtual(getFrameIndex())) {
    +                    stackFrame.materializeVirtualObjects(false);
    +                }
    +                return (Frame) stackFrame.getLocal(getFrameIndex());
    +            default:
    +                throw GraalInternalError.unimplemented();
    +        }
    +    }
    +
    +    public boolean isVirtualFrame() {
    +        return stackFrame.isVirtual(getFrameIndex());
    +    }
    +
    +    public abstract CallTarget getCallTarget();
    +
    +    public abstract CallTarget getTargetCallTarget();
    +
    +    public DirectCallNode getCallNode() {
    +        Object receiver = stackFrame.getLocal(getNotifyIndex());
    +        if (receiver instanceof DirectCallNode) {
    +            return (DirectCallNode) receiver;
    +        } else {
    +            return null;
    +        }
    +    }
    +
    +    /**
    +     * This class represents a frame that is taken from the
    +     * {@link OptimizedDirectCallNode#callProxy(MaterializedFrameNotify, CallTarget, VirtualFrame, Object[], boolean, boolean)}
    +     * method.
    +     */
    +    public static final class CallNodeFrame extends HotSpotFrameInstance {
    +        public static final Method METHOD;
    +        static {
    +            try {
    +                METHOD = OptimizedDirectCallNode.class.getDeclaredMethod("callProxy", MaterializedFrameNotify.class, CallTarget.class, VirtualFrame.class, Object[].class, boolean.class, boolean.class);
    +            } catch (NoSuchMethodException | SecurityException e) {
    +                throw new GraalInternalError(e);
    +            }
    +        }
    +        private static final int NOTIFY_INDEX = 0;
    +        private static final int CALL_TARGET_INDEX = 1;
    +        private static final int FRAME_INDEX = 2;
    +
    +        public CallNodeFrame(InspectedFrame stackFrame) {
    +            super(stackFrame);
    +        }
    +
    +        @Override
    +        protected int getNotifyIndex() {
    +            return NOTIFY_INDEX;
    +        }
    +
    +        @Override
    +        protected int getCallTargetIndex() {
    +            return CALL_TARGET_INDEX;
    +        }
    +
    +        @Override
    +        protected int getFrameIndex() {
    +            return FRAME_INDEX;
    +        }
    +
    +        @Override
    +        public CallTarget getCallTarget() {
    +            return getCallNode().getRootNode().getCallTarget();
    +        }
    +
    +        @Override
    +        public CallTarget getTargetCallTarget() {
    +            return (CallTarget) stackFrame.getLocal(getCallTargetIndex());
    +        }
    +    }
    +
    +    /**
    +     * This class represents a frame that is taken from the
    +     * {@link RootCallTarget#callProxy(VirtualFrame)} method.
    +     */
    +    @SuppressWarnings("javadoc")
    +    public static final class CallTargetFrame extends HotSpotFrameInstance {
    +        public static final Method METHOD;
    +        static {
    +            try {
    +                METHOD = OptimizedCallTarget.class.getDeclaredMethod("callProxy", VirtualFrame.class);
    +            } catch (NoSuchMethodException | SecurityException e) {
    +                throw new GraalInternalError(e);
    +            }
    +        }
    +        private static final int NOTIFY_INDEX = -1;
    +        private static final int CALL_TARGET_INDEX = 0;
    +        private static final int FRAME_INDEX = 1;
    +        private final boolean currentFrame;
    +
    +        public CallTargetFrame(InspectedFrame stackFrame, boolean currentFrame) {
    +            super(stackFrame);
    +            this.currentFrame = currentFrame;
    +        }
    +
    +        @Override
    +        public Frame getFrame(FrameAccess access, boolean slowPath) {
    +            if (!slowPath && currentFrame) {
    +                throw new UnsupportedOperationException("cannot access current frame as fast path");
    +            }
    +            return super.getFrame(access, slowPath);
    +        }
    +
    +        @Override
    +        protected int getNotifyIndex() {
    +            return NOTIFY_INDEX;
    +        }
    +
    +        @Override
    +        protected int getCallTargetIndex() {
    +            return CALL_TARGET_INDEX;
    +        }
    +
    +        @Override
    +        protected int getFrameIndex() {
    +            return FRAME_INDEX;
    +        }
    +
    +        @Override
    +        public CallTarget getCallTarget() {
    +            return (CallTarget) stackFrame.getLocal(getCallTargetIndex());
    +        }
    +
    +        @Override
    +        public CallTarget getTargetCallTarget() {
    +            return null;
    +        }
    +    }
    +}
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleReplacements.java
    --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    +++ b/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleReplacements.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -0,0 +1,43 @@
    +/*
    + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
    + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    + *
    + * This code is free software; you can redistribute it and/or modify it
    + * under the terms of the GNU General Public License version 2 only, as
    + * published by the Free Software Foundation.
    + *
    + * This code is distributed in the hope that it will be useful, but WITHOUT
    + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    + * version 2 for more details (a copy is included in the LICENSE file that
    + * accompanied this code).
    + *
    + * You should have received a copy of the GNU General Public License version
    + * 2 along with this work; if not, write to the Free Software Foundation,
    + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    + *
    + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    + * or visit www.oracle.com if you need additional information or have any
    + * questions.
    + */
    +package com.oracle.graal.truffle.hotspot;
    +
    +import com.oracle.graal.api.replacements.*;
    +import com.oracle.graal.api.runtime.*;
    +import com.oracle.graal.nodes.spi.*;
    +import com.oracle.graal.phases.util.*;
    +import com.oracle.graal.runtime.*;
    +import com.oracle.graal.truffle.*;
    +
    +public final class HotSpotTruffleReplacements extends TruffleReplacements {
    +
    +    private HotSpotTruffleReplacements(Providers providers, SnippetReflectionProvider snippetReflection) {
    +        super(providers, snippetReflection);
    +    }
    +
    +    public static Replacements makeInstance() {
    +        Providers providers = Graal.getRequiredCapability(RuntimeProvider.class).getHostBackend().getProviders();
    +        SnippetReflectionProvider snippetReflection = Graal.getRequiredCapability(SnippetReflectionProvider.class);
    +        return new HotSpotTruffleReplacements(providers, snippetReflection);
    +    }
    +}
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime.java
    --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    +++ b/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -0,0 +1,343 @@
    +/*
    + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
    + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    + *
    + * This code is free software; you can redistribute it and/or modify it
    + * under the terms of the GNU General Public License version 2 only, as
    + * published by the Free Software Foundation.
    + *
    + * This code is distributed in the hope that it will be useful, but WITHOUT
    + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    + * version 2 for more details (a copy is included in the LICENSE file that
    + * accompanied this code).
    + *
    + * You should have received a copy of the GNU General Public License version
    + * 2 along with this work; if not, write to the Free Software Foundation,
    + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    + *
    + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    + * or visit www.oracle.com if you need additional information or have any
    + * questions.
    + */
    +package com.oracle.graal.truffle.hotspot;
    +
    +import static com.oracle.graal.api.code.CodeUtil.*;
    +import static com.oracle.graal.compiler.GraalCompiler.*;
    +import static com.oracle.graal.truffle.TruffleCompilerOptions.*;
    +
    +import java.util.*;
    +import java.util.concurrent.*;
    +
    +import com.oracle.graal.api.code.*;
    +import com.oracle.graal.api.code.CallingConvention.Type;
    +import com.oracle.graal.api.code.stack.*;
    +import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.api.runtime.*;
    +import com.oracle.graal.compiler.*;
    +import com.oracle.graal.compiler.target.*;
    +import com.oracle.graal.debug.*;
    +import com.oracle.graal.debug.Debug.Scope;
    +import com.oracle.graal.hotspot.*;
    +import com.oracle.graal.hotspot.meta.*;
    +import com.oracle.graal.java.*;
    +import com.oracle.graal.lir.asm.*;
    +import com.oracle.graal.nodes.*;
    +import com.oracle.graal.nodes.spi.*;
    +import com.oracle.graal.phases.*;
    +import com.oracle.graal.phases.common.*;
    +import com.oracle.graal.phases.tiers.*;
    +import com.oracle.graal.phases.util.*;
    +import com.oracle.graal.printer.*;
    +import com.oracle.graal.runtime.*;
    +import com.oracle.graal.truffle.*;
    +import com.oracle.truffle.api.*;
    +import com.oracle.truffle.api.CompilerDirectives.*;
    +import com.oracle.truffle.api.frame.*;
    +import com.oracle.truffle.api.impl.*;
    +import com.oracle.truffle.api.nodes.*;
    +
    +/**
    + * Implementation of the Truffle runtime when running on top of Graal.
    + */
    +public final class HotSpotTruffleRuntime implements GraalTruffleRuntime {
    +
    +    public static HotSpotTruffleRuntime makeInstance() {
    +        return new HotSpotTruffleRuntime();
    +    }
    +
    +    private TruffleCompilerImpl truffleCompiler;
    +    private Replacements truffleReplacements;
    +    private StackIntrospection stackIntrospection;
    +    private ArrayList includes;
    +    private ArrayList excludes;
    +    private Map> compilations = new IdentityHashMap<>();
    +    private final ThreadPoolExecutor compileQueue;
    +
    +    private final ResolvedJavaMethod[] callNodeMethod;
    +    private final ResolvedJavaMethod[] callTargetMethod;
    +    private final ResolvedJavaMethod[] anyFrameMethod;
    +
    +    private HotSpotTruffleRuntime() {
    +        installOptimizedCallTargetCallMethod();
    +
    +        callNodeMethod = new ResolvedJavaMethod[]{getGraalProviders().getMetaAccess().lookupJavaMethod(HotSpotFrameInstance.CallNodeFrame.METHOD)};
    +        callTargetMethod = new ResolvedJavaMethod[]{getGraalProviders().getMetaAccess().lookupJavaMethod(HotSpotFrameInstance.CallTargetFrame.METHOD)};
    +        anyFrameMethod = new ResolvedJavaMethod[]{callNodeMethod[0], callTargetMethod[0]};
    +
    +        // Create compilation queue.
    +        CompilerThreadFactory factory = new CompilerThreadFactory("TruffleCompilerThread", new CompilerThreadFactory.DebugConfigAccess() {
    +            public GraalDebugConfig getDebugConfig() {
    +                if (Debug.isEnabled()) {
    +                    GraalDebugConfig debugConfig = DebugEnvironment.initialize(TTY.out().out());
    +                    debugConfig.dumpHandlers().add(new TruffleTreeDumpHandler());
    +                    return debugConfig;
    +                } else {
    +                    return null;
    +                }
    +            }
    +        });
    +        compileQueue = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue(), factory);
    +    }
    +
    +    public String getName() {
    +        return "Graal Truffle Runtime";
    +    }
    +
    +    public RootCallTarget createCallTarget(RootNode rootNode) {
    +        CompilationPolicy compilationPolicy;
    +        if (acceptForCompilation(rootNode)) {
    +            compilationPolicy = new CounterBasedCompilationPolicy();
    +        } else {
    +            compilationPolicy = new InterpreterOnlyCompilationPolicy();
    +        }
    +        return new OptimizedCallTarget(rootNode, this, TruffleMinInvokeThreshold.getValue(), TruffleCompilationThreshold.getValue(), compilationPolicy, new HotSpotSpeculationLog());
    +    }
    +
    +    public DirectCallNode createDirectCallNode(CallTarget target) {
    +        if (target instanceof OptimizedCallTarget) {
    +            return OptimizedDirectCallNode.create((OptimizedCallTarget) target);
    +        } else {
    +            return new DefaultDirectCallNode(target);
    +        }
    +    }
    +
    +    public IndirectCallNode createIndirectCallNode() {
    +        return new OptimizedIndirectCallNode();
    +    }
    +
    +    @Override
    +    public VirtualFrame createVirtualFrame(Object[] arguments, FrameDescriptor frameDescriptor) {
    +        return OptimizedCallTarget.createFrame(frameDescriptor, arguments);
    +    }
    +
    +    @Override
    +    public MaterializedFrame createMaterializedFrame(Object[] arguments) {
    +        return createMaterializedFrame(arguments, new FrameDescriptor());
    +    }
    +
    +    @Override
    +    public MaterializedFrame createMaterializedFrame(Object[] arguments, FrameDescriptor frameDescriptor) {
    +        return new FrameWithoutBoxing(frameDescriptor, arguments);
    +    }
    +
    +    @Override
    +    public Assumption createAssumption() {
    +        return createAssumption(null);
    +    }
    +
    +    @Override
    +    public Assumption createAssumption(String name) {
    +        return new OptimizedAssumption(name);
    +    }
    +
    +    public Replacements getReplacements() {
    +        if (truffleReplacements == null) {
    +            truffleReplacements = HotSpotTruffleReplacements.makeInstance();
    +        }
    +        return truffleReplacements;
    +    }
    +
    +    private boolean acceptForCompilation(RootNode rootNode) {
    +        if (TruffleCompileOnly.getValue() != null) {
    +            if (includes == null) {
    +                parseCompileOnly();
    +            }
    +
    +            String name = rootNode.toString();
    +            boolean included = includes.isEmpty();
    +            for (int i = 0; !included && i < includes.size(); i++) {
    +                if (name.contains(includes.get(i))) {
    +                    included = true;
    +                }
    +            }
    +            if (!included) {
    +                return false;
    +            }
    +            for (String exclude : excludes) {
    +                if (name.contains(exclude)) {
    +                    return false;
    +                }
    +            }
    +        }
    +        return true;
    +    }
    +
    +    private void parseCompileOnly() {
    +        includes = new ArrayList<>();
    +        excludes = new ArrayList<>();
    +
    +        String[] items = TruffleCompileOnly.getValue().split(",");
    +        for (String item : items) {
    +            if (item.startsWith("~")) {
    +                excludes.add(item.substring(1));
    +            } else {
    +                includes.add(item);
    +            }
    +        }
    +    }
    +
    +    public static void installOptimizedCallTargetCallMethod() {
    +        Providers providers = getGraalProviders();
    +        MetaAccessProvider metaAccess = providers.getMetaAccess();
    +        ResolvedJavaType type = metaAccess.lookupJavaType(OptimizedCallTarget.class);
    +        for (ResolvedJavaMethod method : type.getDeclaredMethods()) {
    +            if (method.getAnnotation(TruffleCallBoundary.class) != null) {
    +                CompilationResult compResult = compileMethod(method);
    +                CodeCacheProvider codeCache = providers.getCodeCache();
    +                try (Scope s = Debug.scope("CodeInstall", codeCache, method)) {
    +                    codeCache.setDefaultMethod(method, compResult);
    +                }
    +            }
    +        }
    +    }
    +
    +    private static CompilationResultBuilderFactory getOptimizedCallTargetInstrumentationFactory(String arch, ResolvedJavaMethod method) {
    +        for (OptimizedCallTargetInstrumentationFactory factory : ServiceLoader.loadInstalled(OptimizedCallTargetInstrumentationFactory.class)) {
    +            if (factory.getArchitecture().equals(arch)) {
    +                factory.setInstrumentedMethod(method);
    +                return factory;
    +            }
    +        }
    +        // No specialization of OptimizedCallTarget on this platform.
    +        return CompilationResultBuilderFactory.Default;
    +    }
    +
    +    private static CompilationResult compileMethod(ResolvedJavaMethod javaMethod) {
    +        Providers providers = getGraalProviders();
    +        MetaAccessProvider metaAccess = providers.getMetaAccess();
    +        SuitesProvider suitesProvider = Graal.getRequiredCapability(RuntimeProvider.class).getHostBackend().getSuites();
    +        Suites suites = suitesProvider.createSuites();
    +        suites.getHighTier().findPhase(InliningPhase.class).remove();
    +        StructuredGraph graph = new StructuredGraph(javaMethod);
    +        new GraphBuilderPhase.Instance(metaAccess, GraphBuilderConfiguration.getEagerDefault(), OptimisticOptimizations.ALL).apply(graph);
    +        PhaseSuite graphBuilderSuite = suitesProvider.getDefaultGraphBuilderSuite();
    +        CallingConvention cc = getCallingConvention(providers.getCodeCache(), Type.JavaCallee, graph.method(), false);
    +        Backend backend = Graal.getRequiredCapability(RuntimeProvider.class).getHostBackend();
    +        CompilationResultBuilderFactory factory = getOptimizedCallTargetInstrumentationFactory(backend.getTarget().arch.getName(), javaMethod);
    +        return compileGraph(graph, null, cc, javaMethod, providers, backend, providers.getCodeCache().getTarget(), null, graphBuilderSuite, OptimisticOptimizations.ALL, getProfilingInfo(graph), null,
    +                        suites, new CompilationResult(), factory);
    +    }
    +
    +    private static Providers getGraalProviders() {
    +        RuntimeProvider runtimeProvider = Graal.getRequiredCapability(RuntimeProvider.class);
    +        return runtimeProvider.getHostBackend().getProviders();
    +    }
    +
    +    @SlowPath
    +    public Iterable getStackTrace() {
    +        if (stackIntrospection == null) {
    +            stackIntrospection = Graal.getRequiredCapability(StackIntrospection.class);
    +        }
    +        final Iterator frames = stackIntrospection.getStackTrace(anyFrameMethod, anyFrameMethod, 1).iterator();
    +        class FrameIterator implements Iterator {
    +
    +            public boolean hasNext() {
    +                return frames.hasNext();
    +            }
    +
    +            public FrameInstance next() {
    +                InspectedFrame frame = frames.next();
    +                if (frame.getMethod().equals(callNodeMethod[0])) {
    +                    assert frames.hasNext();
    +                    InspectedFrame calltarget2 = frames.next();
    +                    assert calltarget2.getMethod().equals(callTargetMethod[0]);
    +                    return new HotSpotFrameInstance.CallNodeFrame(frame);
    +                } else {
    +                    assert frame.getMethod().equals(callTargetMethod[0]);
    +                    return new HotSpotFrameInstance.CallTargetFrame(frame, false);
    +                }
    +            }
    +        }
    +        return new Iterable() {
    +            public Iterator iterator() {
    +                return new FrameIterator();
    +            }
    +        };
    +    }
    +
    +    public FrameInstance getCurrentFrame() {
    +        if (stackIntrospection == null) {
    +            stackIntrospection = Graal.getRequiredCapability(StackIntrospection.class);
    +        }
    +        Iterator frames = stackIntrospection.getStackTrace(callTargetMethod, callTargetMethod, 0).iterator();
    +        if (frames.hasNext()) {
    +            return new HotSpotFrameInstance.CallTargetFrame(frames.next(), true);
    +        } else {
    +            System.out.println("no current frame found");
    +            return null;
    +        }
    +    }
    +
    +    public void compile(OptimizedCallTarget optimizedCallTarget, boolean mayBeAsynchronous) {
    +        if (truffleCompiler == null) {
    +            truffleCompiler = new TruffleCompilerImpl();
    +        }
    +        Runnable r = new Runnable() {
    +            @Override
    +            public void run() {
    +                try (Scope s = Debug.scope("Truffle", new TruffleDebugJavaMethod(optimizedCallTarget))) {
    +                    truffleCompiler.compileMethodImpl(optimizedCallTarget);
    +                    optimizedCallTarget.compilationFinished(null);
    +                } catch (Throwable e) {
    +                    optimizedCallTarget.compilationFinished(e);
    +                }
    +            }
    +        };
    +        if (mayBeAsynchronous) {
    +            Future future = compileQueue.submit(r);
    +            this.compilations.put(optimizedCallTarget, future);
    +        } else {
    +            r.run();
    +        }
    +    }
    +
    +    public boolean cancelInstalledTask(OptimizedCallTarget optimizedCallTarget) {
    +        Future codeTask = this.compilations.get(optimizedCallTarget);
    +        if (codeTask != null && isCompiling(optimizedCallTarget)) {
    +            this.compilations.remove(optimizedCallTarget);
    +            return codeTask.cancel(true);
    +        }
    +        return false;
    +    }
    +
    +    public boolean isCompiling(OptimizedCallTarget optimizedCallTarget) {
    +        Future codeTask = this.compilations.get(optimizedCallTarget);
    +        if (codeTask != null) {
    +            if (codeTask.isCancelled() || codeTask.isDone()) {
    +                this.compilations.remove(optimizedCallTarget);
    +                return false;
    +            }
    +            return true;
    +        }
    +        return false;
    +    }
    +
    +    public void invalidateInstalledCode(OptimizedCallTarget optimizedCallTarget) {
    +        HotSpotGraalRuntime.runtime().getCompilerToVM().invalidateInstalledCode(optimizedCallTarget);
    +    }
    +
    +    public void reinstallStubs() {
    +        installOptimizedCallTargetCallMethod();
    +    }
    +}
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/OptimizedCallTargetInstrumentation.java
    --- a/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/OptimizedCallTargetInstrumentation.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/OptimizedCallTargetInstrumentation.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -27,7 +27,7 @@
     import com.oracle.graal.api.code.*;
     import com.oracle.graal.api.code.CompilationResult.Mark;
     import com.oracle.graal.asm.*;
    -import com.oracle.graal.graph.*;
    +import com.oracle.graal.compiler.common.*;
     import com.oracle.graal.hotspot.*;
     import com.oracle.graal.hotspot.meta.HotSpotCodeCacheProvider.MarkId;
     import com.oracle.graal.hotspot.meta.*;
    @@ -55,7 +55,7 @@
             return mark;
         }
     
    -    protected static int getFieldOffset(String name, Class declaringClass) {
    +    protected static int getFieldOffset(String name, Class declaringClass) {
             try {
                 declaringClass.getDeclaredField(name).setAccessible(true);
                 Field field = declaringClass.getDeclaredField(name);
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/ReadOnlyFrame.java
    --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    +++ b/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/ReadOnlyFrame.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -0,0 +1,134 @@
    +/*
    + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
    + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    + *
    + * This code is free software; you can redistribute it and/or modify it
    + * under the terms of the GNU General Public License version 2 only, as
    + * published by the Free Software Foundation.
    + *
    + * This code is distributed in the hope that it will be useful, but WITHOUT
    + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    + * version 2 for more details (a copy is included in the LICENSE file that
    + * accompanied this code).
    + *
    + * You should have received a copy of the GNU General Public License version
    + * 2 along with this work; if not, write to the Free Software Foundation,
    + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    + *
    + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    + * or visit www.oracle.com if you need additional information or have any
    + * questions.
    + */
    +package com.oracle.graal.truffle.hotspot;
    +
    +import com.oracle.graal.compiler.common.*;
    +import com.oracle.truffle.api.frame.*;
    +
    +class ReadOnlyFrame implements Frame {
    +    private final Frame delegate;
    +
    +    public ReadOnlyFrame(Frame delegate) {
    +        this.delegate = delegate;
    +    }
    +
    +    public FrameDescriptor getFrameDescriptor() {
    +        return delegate.getFrameDescriptor();
    +    }
    +
    +    public Object[] getArguments() {
    +        return delegate.getArguments().clone();
    +    }
    +
    +    public Object getObject(FrameSlot slot) throws FrameSlotTypeException {
    +        return delegate.getObject(slot);
    +    }
    +
    +    public void setObject(FrameSlot slot, Object value) {
    +        throw GraalInternalError.shouldNotReachHere();
    +    }
    +
    +    public byte getByte(FrameSlot slot) throws FrameSlotTypeException {
    +        return delegate.getByte(slot);
    +    }
    +
    +    public void setByte(FrameSlot slot, byte value) {
    +        throw GraalInternalError.shouldNotReachHere();
    +    }
    +
    +    public boolean getBoolean(FrameSlot slot) throws FrameSlotTypeException {
    +        return delegate.getBoolean(slot);
    +    }
    +
    +    public void setBoolean(FrameSlot slot, boolean value) {
    +        throw GraalInternalError.shouldNotReachHere();
    +    }
    +
    +    public int getInt(FrameSlot slot) throws FrameSlotTypeException {
    +        return delegate.getInt(slot);
    +    }
    +
    +    public void setInt(FrameSlot slot, int value) {
    +        throw GraalInternalError.shouldNotReachHere();
    +    }
    +
    +    public long getLong(FrameSlot slot) throws FrameSlotTypeException {
    +        return delegate.getLong(slot);
    +    }
    +
    +    public void setLong(FrameSlot slot, long value) {
    +        throw GraalInternalError.shouldNotReachHere();
    +    }
    +
    +    public float getFloat(FrameSlot slot) throws FrameSlotTypeException {
    +        return delegate.getFloat(slot);
    +    }
    +
    +    public void setFloat(FrameSlot slot, float value) {
    +        throw GraalInternalError.shouldNotReachHere();
    +    }
    +
    +    public double getDouble(FrameSlot slot) throws FrameSlotTypeException {
    +        return delegate.getDouble(slot);
    +    }
    +
    +    public void setDouble(FrameSlot slot, double value) {
    +        throw GraalInternalError.shouldNotReachHere();
    +    }
    +
    +    public Object getValue(FrameSlot slot) {
    +        return delegate.getValue(slot);
    +    }
    +
    +    public MaterializedFrame materialize() {
    +        throw GraalInternalError.shouldNotReachHere();
    +    }
    +
    +    public boolean isObject(FrameSlot slot) {
    +        return delegate.isObject(slot);
    +    }
    +
    +    public boolean isByte(FrameSlot slot) {
    +        return delegate.isByte(slot);
    +    }
    +
    +    public boolean isBoolean(FrameSlot slot) {
    +        return delegate.isBoolean(slot);
    +    }
    +
    +    public boolean isInt(FrameSlot slot) {
    +        return delegate.isInt(slot);
    +    }
    +
    +    public boolean isLong(FrameSlot slot) {
    +        return delegate.isLong(slot);
    +    }
    +
    +    public boolean isFloat(FrameSlot slot) {
    +        return delegate.isFloat(slot);
    +    }
    +
    +    public boolean isDouble(FrameSlot slot) {
    +        return delegate.isDouble(slot);
    +    }
    +}
    \ No newline at end of file
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/PartialEvaluationTest.java
    --- a/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/PartialEvaluationTest.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/PartialEvaluationTest.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -51,7 +51,7 @@
     
         public PartialEvaluationTest() {
             // Make sure Truffle runtime is initialized.
    -        Assert.assertTrue(Truffle.getRuntime() instanceof GraalTruffleRuntime);
    +        Assert.assertTrue(Truffle.getRuntime() != null);
             this.truffleCompiler = new TruffleCompilerImpl();
     
             DebugEnvironment.initialize(System.out);
    @@ -64,7 +64,8 @@
         protected InstalledCode assertPartialEvalEquals(String methodName, RootNode root, Object[] arguments) {
             Assumptions assumptions = new Assumptions(true);
             StructuredGraph actual = partialEval(root, arguments, assumptions, true);
    -        InstalledCode result = truffleCompiler.compileMethodHelper(actual, assumptions, root.toString(), getSpeculationLog());
    +        InstalledCode result = new InstalledCode();
    +        truffleCompiler.compileMethodHelper(actual, assumptions, root.toString(), getSpeculationLog(), result);
             StructuredGraph expected = parseForComparison(methodName);
             removeFrameStates(actual);
             Assert.assertEquals(getCanonicalGraphString(expected, true, true), getCanonicalGraphString(actual, true, true));
    @@ -85,7 +86,7 @@
         }
     
         protected StructuredGraph partialEval(RootNode root, Object[] arguments, final Assumptions assumptions, final boolean canonicalizeReads) {
    -        final OptimizedCallTargetImpl compilable = (OptimizedCallTargetImpl) Truffle.getRuntime().createCallTarget(root);
    +        final OptimizedCallTarget compilable = (OptimizedCallTarget) Truffle.getRuntime().createCallTarget(root);
     
             // Executed AST so that all classes are loaded and initialized.
             compilable.call(arguments);
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/TruffleRuntimeTest.java
    --- a/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/TruffleRuntimeTest.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/TruffleRuntimeTest.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -28,8 +28,8 @@
     
     import com.oracle.graal.api.runtime.*;
     import com.oracle.graal.runtime.*;
    -import com.oracle.graal.truffle.*;
     import com.oracle.truffle.api.*;
    +import com.oracle.truffle.api.impl.*;
     
     public class TruffleRuntimeTest {
     
    @@ -46,6 +46,6 @@
         @Test
         public void testRuntimeIsGraalRuntime() {
             TruffleRuntime runtime = Truffle.getRuntime();
    -        assertEquals(GraalTruffleRuntime.class, runtime.getClass());
    +        assertTrue(runtime.getClass() != DefaultTruffleRuntime.class);
         }
     }
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/CompilationPolicy.java
    --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/CompilationPolicy.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/CompilationPolicy.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -26,4 +26,6 @@
     
         boolean shouldCompile(CompilationProfile profile);
     
    +    void recordCompilationFailure(Throwable t);
    +
     }
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/CompilationProfile.java
    --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/CompilationProfile.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/CompilationProfile.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -40,8 +40,6 @@
     
         private long previousTimestamp;
     
    -    private final String name;
    -
         private int callCount;
         private int callAndLoopCount;
         private int compilationCallThreshold;
    @@ -50,13 +48,17 @@
         private final int originalInvokeCounter;
         private final int originalCompilationThreshold;
     
    -    public CompilationProfile(final int compilationThreshold, final int initialInvokeCounter, final String name) {
    +    public CompilationProfile(final int compilationThreshold, final int initialInvokeCounter) {
             this.previousTimestamp = System.nanoTime();
             this.compilationCallThreshold = initialInvokeCounter;
             this.compilationCallAndLoopThreshold = compilationThreshold;
             this.originalInvokeCounter = initialInvokeCounter;
             this.originalCompilationThreshold = compilationThreshold;
    -        this.name = name;
    +    }
    +
    +    @Override
    +    public String toString() {
    +        return String.format("CompilationProfile(callCount=%d/%d, callAndLoopCount=%d/%d)", callCount, compilationCallThreshold, callAndLoopCount, compilationCallAndLoopThreshold);
         }
     
         public Map getDebugProperties() {
    @@ -81,10 +83,6 @@
             return previousTimestamp;
         }
     
    -    public String getName() {
    -        return this.name;
    -    }
    -
         public int getInvalidationCount() {
             return invalidationCount;
         }
    @@ -126,7 +124,7 @@
             this.previousTimestamp = timestamp;
         }
     
    -    void reportInvalidated() {
    +    public void reportInvalidated() {
             invalidationCount++;
             int reprofile = TruffleInvalidationReprofileCount.getValue();
             ensureProfiling(reprofile, reprofile);
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/CounterBasedCompilationPolicy.java
    --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/CounterBasedCompilationPolicy.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -0,0 +1,37 @@
    +/*
    + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
    + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    + *
    + * This code is free software; you can redistribute it and/or modify it
    + * under the terms of the GNU General Public License version 2 only, as
    + * published by the Free Software Foundation.
    + *
    + * This code is distributed in the hope that it will be useful, but WITHOUT
    + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    + * version 2 for more details (a copy is included in the LICENSE file that
    + * accompanied this code).
    + *
    + * You should have received a copy of the GNU General Public License version
    + * 2 along with this work; if not, write to the Free Software Foundation,
    + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    + *
    + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    + * or visit www.oracle.com if you need additional information or have any
    + * questions.
    + */
    +package com.oracle.graal.truffle;
    +
    +public class CounterBasedCompilationPolicy implements CompilationPolicy {
    +
    +    private boolean compilationFailed;
    +
    +    public boolean shouldCompile(CompilationProfile profile) {
    +        return !compilationFailed && profile.getCallCount() >= profile.getCompilationCallThreshold() && profile.getCallAndLoopCount() >= profile.getCompilationCallAndLoopThreshold();
    +    }
    +
    +    public void recordCompilationFailure(Throwable t) {
    +        compilationFailed = true;
    +    }
    +
    +}
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/DefaultCompilationPolicy.java
    --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/DefaultCompilationPolicy.java	Wed Apr 23 15:22:20 2014 +0200
    +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    @@ -1,31 +0,0 @@
    -/*
    - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
    - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    - *
    - * This code is free software; you can redistribute it and/or modify it
    - * under the terms of the GNU General Public License version 2 only, as
    - * published by the Free Software Foundation.
    - *
    - * This code is distributed in the hope that it will be useful, but WITHOUT
    - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    - * version 2 for more details (a copy is included in the LICENSE file that
    - * accompanied this code).
    - *
    - * You should have received a copy of the GNU General Public License version
    - * 2 along with this work; if not, write to the Free Software Foundation,
    - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    - *
    - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    - * or visit www.oracle.com if you need additional information or have any
    - * questions.
    - */
    -package com.oracle.graal.truffle;
    -
    -public class DefaultCompilationPolicy implements CompilationPolicy {
    -
    -    public boolean shouldCompile(CompilationProfile profile) {
    -        return profile.getCallCount() >= profile.getCompilationCallThreshold() && profile.getCallAndLoopCount() >= profile.getCompilationCallAndLoopThreshold();
    -    }
    -
    -}
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/DefaultInliningPolicy.java
    --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/DefaultInliningPolicy.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/DefaultInliningPolicy.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -27,29 +27,25 @@
     public class DefaultInliningPolicy implements TruffleInliningPolicy {
     
         private static final String REASON_RECURSION = "recursion";
    -    private static final String REASON_MAXIMUM_NODE_COUNT = "nodeCount * callSites  > " + TruffleInliningMaxCallerSize.getValue();
    +    private static final String REASON_MAXIMUM_NODE_COUNT = "deepNodeCount * callSites  > " + TruffleInliningMaxCallerSize.getValue();
         private static final String REASON_MAXIMUM_TOTAL_NODE_COUNT = "totalNodeCount > " + TruffleInliningMaxCallerSize.getValue();
     
         public double calculateScore(TruffleInliningProfile profile) {
             return profile.getFrequency() / profile.getDeepNodeCount();
         }
     
    -    public boolean isAllowed(TruffleInliningResult state, TruffleInliningProfile profile, int nodeCountBudget) {
    -        TruffleCallPath callPath = profile.getCallPath();
    -        OptimizedCallTarget inlineTarget = callPath.getCallTarget();
    -        for (TruffleCallPath path : callPath.getParent().toList()) {
    -            if (path.getCallTarget() == inlineTarget) {
    -                // recursive call found
    -                profile.setFailedReason(REASON_RECURSION);
    -                return false;
    -            }
    +    public boolean isAllowed(TruffleInliningProfile profile, int currentBudgetLeft) {
    +        if (profile.isRecursiveCall()) {
    +            // recursive call found
    +            profile.setFailedReason(REASON_RECURSION);
    +            return false;
             }
     
             if (profile.isForced()) {
                 return true;
             }
     
    -        if (nodeCountBudget - profile.getDeepNodeCount() < 0) {
    +        if (currentBudgetLeft - profile.getDeepNodeCount() < 0) {
                 profile.setFailedReason(REASON_MAXIMUM_TOTAL_NODE_COUNT);
                 return false;
             }
    @@ -62,9 +58,4 @@
     
             return true;
         }
    -
    -    public boolean isAllowedDeep(TruffleInliningResult state, TruffleInliningProfile profile, int nodeCountBudget) {
    -        return true;
    -    }
    -
     }
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/FrameWithoutBoxing.java
    --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/FrameWithoutBoxing.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/FrameWithoutBoxing.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -45,10 +45,11 @@
         public FrameWithoutBoxing(FrameDescriptor descriptor, Object[] arguments) {
             this.descriptor = descriptor;
             this.arguments = arguments;
    -        this.locals = new Object[descriptor.getSize()];
    +        int size = descriptor.getSize();
    +        this.locals = new Object[size];
             Arrays.fill(locals, descriptor.getTypeConversion().getDefaultValue());
    -        this.primitiveLocals = new long[descriptor.getSize()];
    -        this.tags = new byte[descriptor.getSize()];
    +        this.primitiveLocals = new long[size];
    +        this.tags = new byte[size];
         }
     
         @Override
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/GraalTruffleRuntime.java
    --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/GraalTruffleRuntime.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/GraalTruffleRuntime.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,193 +22,20 @@
      */
     package com.oracle.graal.truffle;
     
    -import static com.oracle.graal.api.code.CodeUtil.*;
    -import static com.oracle.graal.compiler.GraalCompiler.*;
    -import static com.oracle.graal.truffle.TruffleCompilerOptions.*;
    -
    -import java.lang.reflect.*;
    -import java.util.*;
    -
    -import com.oracle.graal.api.code.*;
    -import com.oracle.graal.api.code.CallingConvention.Type;
    -import com.oracle.graal.api.meta.*;
    -import com.oracle.graal.api.runtime.*;
    -import com.oracle.graal.compiler.target.*;
    -import com.oracle.graal.debug.*;
    -import com.oracle.graal.debug.Debug.Scope;
    -import com.oracle.graal.graph.*;
    -import com.oracle.graal.java.*;
    -import com.oracle.graal.lir.asm.*;
    -import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.phases.*;
    -import com.oracle.graal.phases.common.*;
    -import com.oracle.graal.phases.tiers.*;
    -import com.oracle.graal.phases.util.*;
    -import com.oracle.graal.runtime.*;
     import com.oracle.truffle.api.*;
    -import com.oracle.truffle.api.frame.*;
    -import com.oracle.truffle.api.impl.*;
    -import com.oracle.truffle.api.nodes.*;
    -
    -/**
    - * Implementation of the Truffle runtime when running on top of Graal.
    - */
    -public final class GraalTruffleRuntime implements TruffleRuntime {
    -
    -    public static GraalTruffleRuntime makeInstance() {
    -        return new GraalTruffleRuntime();
    -    }
    -
    -    private TruffleCompiler truffleCompiler;
    -    private Replacements truffleReplacements;
    -    private ArrayList includes;
    -    private ArrayList excludes;
     
    -    private GraalTruffleRuntime() {
    -        installOptimizedCallTargetCallMethod();
    -    }
    -
    -    public String getName() {
    -        return "Graal Truffle Runtime";
    -    }
    -
    -    public RootCallTarget createCallTarget(RootNode rootNode) {
    -        if (truffleCompiler == null) {
    -            truffleCompiler = new TruffleCompilerImpl();
    -        }
    -        return new OptimizedCallTargetImpl(rootNode, truffleCompiler, TruffleMinInvokeThreshold.getValue(), TruffleCompilationThreshold.getValue(), acceptForCompilation(rootNode));
    -    }
    -
    -    public CallNode createCallNode(CallTarget target) {
    -        if (target instanceof OptimizedCallTarget) {
    -            return OptimizedCallNode.create((OptimizedCallTarget) target);
    -        } else {
    -            return new DefaultCallNode(target);
    -        }
    -    }
    +public interface GraalTruffleRuntime extends TruffleRuntime {
     
    -    @Override
    -    public VirtualFrame createVirtualFrame(Object[] arguments, FrameDescriptor frameDescriptor) {
    -        return OptimizedCallTargetImpl.createFrame(frameDescriptor, arguments);
    -    }
    -
    -    @Override
    -    public MaterializedFrame createMaterializedFrame(Object[] arguments) {
    -        return createMaterializedFrame(arguments, new FrameDescriptor());
    -    }
    +    Replacements getReplacements();
     
    -    @Override
    -    public MaterializedFrame createMaterializedFrame(Object[] arguments, FrameDescriptor frameDescriptor) {
    -        return new FrameWithoutBoxing(frameDescriptor, arguments);
    -    }
    -
    -    @Override
    -    public Assumption createAssumption() {
    -        return createAssumption(null);
    -    }
    -
    -    @Override
    -    public Assumption createAssumption(String name) {
    -        return new OptimizedAssumption(name);
    -    }
    +    void compile(OptimizedCallTarget optimizedCallTarget, boolean mayBeAsynchronous);
     
    -    public Replacements getReplacements() {
    -        if (truffleReplacements == null) {
    -            truffleReplacements = TruffleReplacements.makeInstance();
    -        }
    -        return truffleReplacements;
    -    }
    -
    -    private boolean acceptForCompilation(RootNode rootNode) {
    -        if (TruffleCompileOnly.getValue() != null) {
    -            if (includes == null) {
    -                parseCompileOnly();
    -            }
    +    boolean cancelInstalledTask(OptimizedCallTarget optimizedCallTarget);
     
    -            String name = rootNode.toString();
    -            boolean included = includes.isEmpty();
    -            for (int i = 0; !included && i < includes.size(); i++) {
    -                if (name.contains(includes.get(i))) {
    -                    included = true;
    -                }
    -            }
    -            if (!included) {
    -                return false;
    -            }
    -            for (String exclude : excludes) {
    -                if (name.contains(exclude)) {
    -                    return false;
    -                }
    -            }
    -        }
    -        return true;
    -    }
    -
    -    private void parseCompileOnly() {
    -        includes = new ArrayList<>();
    -        excludes = new ArrayList<>();
    -
    -        String[] items = TruffleCompileOnly.getValue().split(",");
    -        for (String item : items) {
    -            if (item.startsWith("~")) {
    -                excludes.add(item.substring(1));
    -            } else {
    -                includes.add(item);
    -            }
    -        }
    -    }
    +    boolean isCompiling(OptimizedCallTarget optimizedCallTarget);
     
    -    public static void installOptimizedCallTargetCallMethod() {
    -        Providers providers = getGraalProviders();
    -        MetaAccessProvider metaAccess = providers.getMetaAccess();
    -        CodeCacheProvider codeCache = providers.getCodeCache();
    -        ResolvedJavaMethod resolvedCallMethod = metaAccess.lookupJavaMethod(getCallMethod());
    -        CompilationResult compResult = compileMethod(resolvedCallMethod);
    -        try (Scope s = Debug.scope("CodeInstall", codeCache, resolvedCallMethod)) {
    -            codeCache.setDefaultMethod(resolvedCallMethod, compResult);
    -        }
    -    }
    -
    -    private static Method getCallMethod() {
    -        Method method;
    -        try {
    -            method = OptimizedCallTargetImpl.class.getDeclaredMethod("call", new Class[]{Object[].class});
    -        } catch (NoSuchMethodException | SecurityException e) {
    -            throw GraalInternalError.shouldNotReachHere();
    -        }
    -        return method;
    -    }
    +    void invalidateInstalledCode(OptimizedCallTarget optimizedCallTarget);
     
    -    private static CompilationResultBuilderFactory getOptimizedCallTargetInstrumentationFactory(String arch, ResolvedJavaMethod method) {
    -        for (OptimizedCallTargetInstrumentationFactory factory : ServiceLoader.loadInstalled(OptimizedCallTargetInstrumentationFactory.class)) {
    -            if (factory.getArchitecture().equals(arch)) {
    -                factory.setInstrumentedMethod(method);
    -                return factory;
    -            }
    -        }
    -        // No specialization of OptimizedCallTarget on this platform.
    -        return CompilationResultBuilderFactory.Default;
    -    }
    -
    -    private static CompilationResult compileMethod(ResolvedJavaMethod javaMethod) {
    -        Providers providers = getGraalProviders();
    -        MetaAccessProvider metaAccess = providers.getMetaAccess();
    -        SuitesProvider suitesProvider = Graal.getRequiredCapability(RuntimeProvider.class).getHostBackend().getSuites();
    -        Suites suites = suitesProvider.createSuites();
    -        suites.getHighTier().findPhase(InliningPhase.class).remove();
    -        StructuredGraph graph = new StructuredGraph(javaMethod);
    -        new GraphBuilderPhase.Instance(metaAccess, GraphBuilderConfiguration.getEagerDefault(), OptimisticOptimizations.ALL).apply(graph);
    -        PhaseSuite graphBuilderSuite = suitesProvider.getDefaultGraphBuilderSuite();
    -        CallingConvention cc = getCallingConvention(providers.getCodeCache(), Type.JavaCallee, graph.method(), false);
    -        Backend backend = Graal.getRequiredCapability(RuntimeProvider.class).getHostBackend();
    -        CompilationResultBuilderFactory factory = getOptimizedCallTargetInstrumentationFactory(backend.getTarget().arch.getName(), javaMethod);
    -        return compileGraph(graph, null, cc, javaMethod, providers, backend, providers.getCodeCache().getTarget(), null, graphBuilderSuite, OptimisticOptimizations.ALL, getProfilingInfo(graph), null,
    -                        suites, new CompilationResult(), factory);
    -    }
    -
    -    private static Providers getGraalProviders() {
    -        RuntimeProvider runtimeProvider = Graal.getRequiredCapability(RuntimeProvider.class);
    -        return runtimeProvider.getHostBackend().getProviders();
    -    }
    +    void reinstallStubs();
     }
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/InterpreterOnlyCompilationPolicy.java
    --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/InterpreterOnlyCompilationPolicy.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -0,0 +1,34 @@
    +/*
    + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
    + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    + *
    + * This code is free software; you can redistribute it and/or modify it
    + * under the terms of the GNU General Public License version 2 only, as
    + * published by the Free Software Foundation.
    + *
    + * This code is distributed in the hope that it will be useful, but WITHOUT
    + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    + * version 2 for more details (a copy is included in the LICENSE file that
    + * accompanied this code).
    + *
    + * You should have received a copy of the GNU General Public License version
    + * 2 along with this work; if not, write to the Free Software Foundation,
    + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    + *
    + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    + * or visit www.oracle.com if you need additional information or have any
    + * questions.
    + */
    +package com.oracle.graal.truffle;
    +
    +public class InterpreterOnlyCompilationPolicy implements CompilationPolicy {
    +
    +    public boolean shouldCompile(CompilationProfile profile) {
    +        return false;
    +    }
    +
    +    public void recordCompilationFailure(Throwable t) {
    +    }
    +
    +}
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/MaterializedFrameNotify.java
    --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/MaterializedFrameNotify.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -0,0 +1,32 @@
    +/*
    + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
    + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    + *
    + * This code is free software; you can redistribute it and/or modify it
    + * under the terms of the GNU General Public License version 2 only, as
    + * published by the Free Software Foundation.
    + *
    + * This code is distributed in the hope that it will be useful, but WITHOUT
    + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    + * version 2 for more details (a copy is included in the LICENSE file that
    + * accompanied this code).
    + *
    + * You should have received a copy of the GNU General Public License version
    + * 2 along with this work; if not, write to the Free Software Foundation,
    + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    + *
    + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    + * or visit www.oracle.com if you need additional information or have any
    + * questions.
    + */
    +package com.oracle.graal.truffle;
    +
    +import com.oracle.truffle.api.frame.FrameInstance.*;
    +
    +public interface MaterializedFrameNotify {
    +
    +    FrameAccess getOutsideFrameAccess();
    +
    +    void setOutsideFrameAccess(FrameAccess outsideFrameAccess);
    +}
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedAssumption.java
    --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedAssumption.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedAssumption.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,7 +23,6 @@
     package com.oracle.graal.truffle;
     
     import java.lang.ref.*;
    -import java.util.*;
     
     import com.oracle.graal.api.code.*;
     import com.oracle.truffle.api.impl.*;
    @@ -31,7 +30,13 @@
     
     public final class OptimizedAssumption extends AbstractAssumption {
     
    -    List> dependentInstalledCode;
    +    private static class Entry {
    +        WeakReference installedCode;
    +        long version;
    +        Entry next;
    +    }
    +
    +    private Entry first;
     
         public OptimizedAssumption(String name) {
             super(name);
    @@ -47,25 +52,26 @@
         @Override
         public synchronized void invalidate() {
             if (isValid) {
    -            if (dependentInstalledCode != null) {
    -                for (WeakReference installedCodeReference : dependentInstalledCode) {
    -                    InstalledCode installedCode = installedCodeReference.get();
    -                    if (installedCode != null) {
    -                        installedCode.invalidate();
    -                    }
    +            Entry e = first;
    +            while (e != null) {
    +                InstalledCode installedCode = e.installedCode.get();
    +                if (installedCode != null && installedCode.getVersion() == e.version) {
    +                    installedCode.invalidate();
                     }
    -                dependentInstalledCode = null;
    +                e = e.next;
                 }
    +            first = null;
                 isValid = false;
             }
         }
     
         public synchronized void registerInstalledCode(InstalledCode installedCode) {
             if (isValid) {
    -            if (dependentInstalledCode == null) {
    -                dependentInstalledCode = new ArrayList<>();
    -            }
    -            dependentInstalledCode.add(new WeakReference<>(installedCode));
    +            Entry e = new Entry();
    +            e.installedCode = new WeakReference<>(installedCode);
    +            e.version = installedCode.getVersion();
    +            e.next = first;
    +            first = e;
             } else {
                 installedCode.invalidate();
             }
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallNode.java
    --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    @@ -1,190 +0,0 @@
    -/*
    - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
    - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    - *
    - * This code is free software; you can redistribute it and/or modify it
    - * under the terms of the GNU General Public License version 2 only, as
    - * published by the Free Software Foundation.
    - *
    - * This code is distributed in the hope that it will be useful, but WITHOUT
    - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    - * version 2 for more details (a copy is included in the LICENSE file that
    - * accompanied this code).
    - *
    - * You should have received a copy of the GNU General Public License version
    - * 2 along with this work; if not, write to the Free Software Foundation,
    - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    - *
    - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    - * or visit www.oracle.com if you need additional information or have any
    - * questions.
    - */
    -package com.oracle.graal.truffle;
    -
    -import java.util.concurrent.atomic.*;
    -
    -import com.oracle.truffle.api.*;
    -import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
    -import com.oracle.truffle.api.impl.*;
    -import com.oracle.truffle.api.nodes.*;
    -import com.oracle.truffle.api.nodes.NodeUtil.NodeCountFilter;
    -
    -/**
    - * Call target that is optimized by Graal upon surpassing a specific invocation threshold.
    - */
    -public final class OptimizedCallNode extends DefaultCallNode {
    -
    -    protected int callCount;
    -    private boolean trySplit = true;
    -    private boolean inliningForced;
    -    @CompilationFinal private OptimizedCallTarget splitCallTarget;
    -    private final AtomicInteger inliningCounter = new AtomicInteger(0);
    -
    -    private OptimizedCallNode(OptimizedCallTarget target) {
    -        super(target);
    -    }
    -
    -    @Override
    -    public boolean isSplittable() {
    -        return getCallTarget().getRootNode().isSplittable();
    -    }
    -
    -    @Override
    -    public OptimizedCallTarget getCallTarget() {
    -        return (OptimizedCallTarget) super.getCallTarget();
    -    }
    -
    -    public int getCallCount() {
    -        return callCount;
    -    }
    -
    -    @Override
    -    public OptimizedCallTarget getCurrentCallTarget() {
    -        return (OptimizedCallTarget) super.getCurrentCallTarget();
    -    }
    -
    -    @Override
    -    public OptimizedCallTarget getSplitCallTarget() {
    -        return splitCallTarget;
    -    }
    -
    -    public static OptimizedCallNode create(OptimizedCallTarget target) {
    -        return new OptimizedCallNode(target);
    -    }
    -
    -    @Override
    -    public Object call(Object[] arguments) {
    -        if (CompilerDirectives.inInterpreter()) {
    -            interpreterCall();
    -            if (inliningCounter.get() > 0 || inliningForced) {
    -                return getCurrentCallTarget().callInlined(arguments);
    -            }
    -        }
    -        return getCurrentCallTarget().call(arguments);
    -    }
    -
    -    private void interpreterCall() {
    -        callCount++;
    -        if (trySplit) {
    -            if (callCount == 1) {
    -                // on first call
    -                getCurrentCallTarget().incrementKnownCallSite();
    -            }
    -            if (callCount > 1) {
    -                trySplit = false;
    -                if (shouldSplit()) {
    -                    splitImpl(true);
    -                }
    -            }
    -        }
    -    }
    -
    -    void notifyInlining() {
    -        inliningCounter.incrementAndGet();
    -    }
    -
    -    void notifyInliningDone() {
    -        inliningCounter.decrementAndGet();
    -    }
    -
    -    @Override
    -    public void inline() {
    -        inliningForced = true;
    -    }
    -
    -    @Override
    -    public boolean isInlined() {
    -        return inliningForced;
    -    }
    -
    -    private void splitImpl(boolean heuristic) {
    -        CompilerAsserts.neverPartOfCompilation();
    -
    -        OptimizedCallTarget splitTarget = (OptimizedCallTarget) Truffle.getRuntime().createCallTarget(getCallTarget().getRootNode().split());
    -        splitTarget.setSplitSource(getCallTarget());
    -        if (heuristic) {
    -            OptimizedCallTarget.logSplit(this, getCallTarget(), splitTarget);
    -        }
    -        if (callCount >= 1) {
    -            getCallTarget().decrementKnownCallSite();
    -            splitTarget.incrementKnownCallSite();
    -        }
    -        this.splitCallTarget = splitTarget;
    -    }
    -
    -    private boolean shouldSplit() {
    -        if (splitCallTarget != null) {
    -            return false;
    -        }
    -        if (!TruffleCompilerOptions.TruffleSplittingEnabled.getValue()) {
    -            return false;
    -        }
    -        if (!isSplittable()) {
    -            return false;
    -        }
    -        OptimizedCallTarget splitTarget = getCallTarget();
    -        int nodeCount = OptimizedCallUtils.countNonTrivialNodes(null, new TruffleCallPath(splitTarget));
    -        if (nodeCount > TruffleCompilerOptions.TruffleSplittingMaxCalleeSize.getValue()) {
    -            return false;
    -        }
    -
    -        // disable recursive splitting for now
    -        OptimizedCallTarget root = (OptimizedCallTarget) getRootNode().getCallTarget();
    -        if (root == splitTarget || root.getSplitSource() == splitTarget) {
    -            // recursive call found
    -            return false;
    -        }
    -
    -        // max one child call and callCount > 2 and kind of small number of nodes
    -        if (isMaxSingleCall()) {
    -            return true;
    -        }
    -        return countPolymorphic() >= 1;
    -    }
    -
    -    private boolean isMaxSingleCall() {
    -        return NodeUtil.countNodes(getCurrentCallTarget().getRootNode(), new NodeCountFilter() {
    -            public boolean isCounted(Node node) {
    -                return node instanceof CallNode;
    -            }
    -        }) <= 1;
    -    }
    -
    -    private int countPolymorphic() {
    -        return NodeUtil.countNodes(getCallTarget().getRootNode(), new NodeCountFilter() {
    -            public boolean isCounted(Node node) {
    -                NodeCost cost = node.getCost();
    -                boolean polymorphic = cost == NodeCost.POLYMORPHIC || cost == NodeCost.MEGAMORPHIC;
    -                return polymorphic;
    -            }
    -        });
    -    }
    -
    -    @SuppressWarnings("unused")
    -    public void nodeReplaced(Node oldNode, Node newNode, CharSequence reason) {
    -        if (!isSplit() && isSplittable()) {
    -            trySplit = true;
    -        }
    -    }
    -}
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java
    --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,6 +22,7 @@
      */
     package com.oracle.graal.truffle;
     
    +import static com.oracle.graal.truffle.OptimizedCallTargetLog.*;
     import static com.oracle.graal.truffle.TruffleCompilerOptions.*;
     
     import java.io.*;
    @@ -30,56 +31,177 @@
     
     import com.oracle.graal.api.code.*;
     import com.oracle.graal.debug.*;
    -import com.oracle.graal.truffle.OptimizedCallUtils.InlinedNodeCountFilter;
     import com.oracle.truffle.api.*;
    +import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
     import com.oracle.truffle.api.frame.*;
    -import com.oracle.truffle.api.impl.*;
     import com.oracle.truffle.api.nodes.*;
     
     /**
      * Call target that is optimized by Graal upon surpassing a specific invocation threshold.
      */
    -public abstract class OptimizedCallTarget extends DefaultCallTarget implements LoopCountReceiver, ReplaceObserver {
    +public class OptimizedCallTarget extends InstalledCode implements RootCallTarget, LoopCountReceiver, ReplaceObserver {
     
         protected static final PrintStream OUT = TTY.out().out();
     
    -    protected InstalledCode installedCode;
    -    protected boolean compilationEnabled;
    +    protected final GraalTruffleRuntime runtime;
    +    private SpeculationLog speculationLog;
         protected int callCount;
    -    protected TruffleInliningResult inliningResult;
    +    protected boolean inliningPerformed;
         protected final CompilationProfile compilationProfile;
         protected final CompilationPolicy compilationPolicy;
    -    private final SpeculationLog speculationLog = new SpeculationLog();
         private OptimizedCallTarget splitSource;
    +    private final AtomicInteger callSitesKnown = new AtomicInteger(0);
    +    @CompilationFinal private Class[] profiledArgumentTypes;
    +    @CompilationFinal private Assumption profiledArgumentTypesAssumption;
    +    @CompilationFinal private Class profiledReturnType;
    +    @CompilationFinal private Assumption profiledReturnTypeAssumption;
     
    -    private final AtomicInteger callSitesKnown = new AtomicInteger(0);
    +    private final RootNode rootNode;
     
    -    public OptimizedCallTarget(RootNode rootNode, int invokeCounter, int compilationThreshold, boolean compilationEnabled, CompilationPolicy compilationPolicy) {
    -        super(rootNode);
    -        this.compilationEnabled = compilationEnabled;
    +    public final RootNode getRootNode() {
    +        return rootNode;
    +    }
    +
    +    public OptimizedCallTarget(RootNode rootNode, GraalTruffleRuntime runtime, int invokeCounter, int compilationThreshold, CompilationPolicy compilationPolicy, SpeculationLog speculationLog) {
    +        this.runtime = runtime;
    +        this.speculationLog = speculationLog;
    +        this.rootNode = rootNode;
    +        this.rootNode.adoptChildren();
    +        this.rootNode.setCallTarget(this);
             this.compilationPolicy = compilationPolicy;
    -        this.compilationProfile = new CompilationProfile(compilationThreshold, invokeCounter, rootNode.toString());
    +        this.compilationProfile = new CompilationProfile(compilationThreshold, invokeCounter);
             if (TruffleCallTargetProfiling.getValue()) {
                 registerCallTarget(this);
             }
         }
     
    +    public SpeculationLog getSpeculationLog() {
    +        return speculationLog;
    +    }
    +
    +    @Override
    +    public Object call(Object... args) {
    +        return callBoundary(args);
    +    }
    +
    +    public Object callDirect(Object... args) {
    +        if (profiledArgumentTypesAssumption == null) {
    +            CompilerDirectives.transferToInterpreter();
    +            profiledArgumentTypesAssumption = Truffle.getRuntime().createAssumption("Profiled Argument Types");
    +            profiledArgumentTypes = new Class[args.length];
    +        } else if (profiledArgumentTypes != null) {
    +            if (profiledArgumentTypes.length != args.length) {
    +                CompilerDirectives.transferToInterpreter();
    +                profiledArgumentTypesAssumption.invalidate();
    +                profiledArgumentTypes = null;
    +            }
    +        }
    +
    +        Object result = callBoundary(args);
    +        Class klass = profiledReturnType;
    +        if (klass != null && CompilerDirectives.inCompiledCode() && profiledReturnTypeAssumption.isValid()) {
    +            result = CompilerDirectives.unsafeCast(result, klass, true, true);
    +        }
    +        return result;
    +    }
    +
    +    @TruffleCallBoundary
    +    private Object callBoundary(Object[] args) {
    +        if (CompilerDirectives.inInterpreter()) {
    +            // We are called and we are still in Truffle interpreter mode.
    +            CompilerDirectives.transferToInterpreter();
    +            interpreterCall();
    +        } else {
    +            // We come here from compiled code (i.e., we have been inlined).
    +        }
    +
    +        return callRoot(args);
    +    }
    +
    +    @Override
    +    public void invalidate() {
    +        this.runtime.invalidateInstalledCode(this);
    +    }
    +
    +    protected void invalidate(Node oldNode, Node newNode, CharSequence reason) {
    +        if (isValid()) {
    +            CompilerAsserts.neverPartOfCompilation();
    +            invalidate();
    +            compilationProfile.reportInvalidated();
    +            logOptimizedInvalidated(this, oldNode, newNode, reason);
    +        }
    +        cancelInstalledTask(oldNode, newNode, reason);
    +    }
    +
    +    private void cancelInstalledTask(Node oldNode, Node newNode, CharSequence reason) {
    +        if (this.runtime.cancelInstalledTask(this)) {
    +            logOptimizingUnqueued(this, oldNode, newNode, reason);
    +            compilationProfile.reportInvalidated();
    +        }
    +    }
    +
    +    private void interpreterCall() {
    +        CompilerAsserts.neverPartOfCompilation();
    +        if (this.isValid()) {
    +            // Stubs were deoptimized => reinstall.
    +            this.runtime.reinstallStubs();
    +        } else {
    +            compilationProfile.reportInterpreterCall();
    +            if (TruffleCallTargetProfiling.getValue()) {
    +                callCount++;
    +            }
    +            if (compilationPolicy.shouldCompile(compilationProfile)) {
    +                compile();
    +            }
    +        }
    +    }
    +
    +    public void compile() {
    +        if (!runtime.isCompiling(this)) {
    +            performInlining();
    +            logOptimizingQueued(this);
    +            runtime.compile(this, TruffleBackgroundCompilation.getValue());
    +        }
    +    }
    +
    +    public void compilationFinished(Throwable t) {
    +        if (t == null) {
    +            // Compilation was successful.
    +        } else {
    +            compilationPolicy.recordCompilationFailure(t);
    +            logOptimizingFailed(this, t.getMessage());
    +            if (t instanceof BailoutException) {
    +                // Bailout => move on.
    +            } else {
    +                if (TruffleCompilationExceptionsAreFatal.getValue()) {
    +                    t.printStackTrace(OUT);
    +                    System.exit(-1);
    +                }
    +            }
    +        }
    +    }
    +
    +    protected final Object callProxy(VirtualFrame frame) {
    +        try {
    +            return getRootNode().execute(frame);
    +        } finally {
    +            // this assertion is needed to keep the values from being cleared as non-live locals
    +            assert frame != null && this != null;
    +        }
    +    }
    +
         public final int getKnownCallSiteCount() {
             return callSitesKnown.get();
         }
     
    -    public final void incrementKnownCallSite() {
    +    public final void incrementKnownCallSites() {
             callSitesKnown.incrementAndGet();
         }
     
    -    public final void decrementKnownCallSite() {
    +    public final void decrementKnownCallSites() {
             callSitesKnown.decrementAndGet();
         }
     
    -    public final TruffleInliningResult getInliningResult() {
    -        return inliningResult;
    -    }
    -
         public final OptimizedCallTarget getSplitSource() {
             return splitSource;
         }
    @@ -90,8 +212,8 @@
     
         @Override
         public String toString() {
    -        String superString = super.toString();
    -        if (installedCode != null) {
    +        String superString = rootNode.toString();
    +        if (isValid()) {
                 superString += " ";
             }
             if (splitSource != null) {
    @@ -104,66 +226,68 @@
             return compilationProfile;
         }
     
    -    @Override
    -    public abstract Object call(Object[] args);
    -
    -    public abstract InstalledCode compile();
    -
         public final Object callInlined(Object[] arguments) {
             if (CompilerDirectives.inInterpreter()) {
                 compilationProfile.reportInlinedCall();
             }
    -        return executeHelper(arguments);
    +        VirtualFrame frame = createFrame(getRootNode().getFrameDescriptor(), arguments);
    +        return callProxy(frame);
         }
     
         public final void performInlining() {
    -        if (!shouldInline()) {
    +        if (!TruffleFunctionInlining.getValue()) {
    +            return;
    +        }
    +        if (inliningPerformed) {
                 return;
             }
    -
    -        if (inliningResult != null) {
    -            return;
    -        }
    -
    -        TruffleInliningHandler handler = new TruffleInliningHandler(this, new DefaultInliningPolicy(), new HashMap());
    -        int startNodeCount = OptimizedCallUtils.countNonTrivialNodes(null, new TruffleCallPath(this));
    -        this.inliningResult = handler.inline(startNodeCount);
    -        logInliningDecision(this, inliningResult, handler);
    +        inliningPerformed = true;
    +        TruffleInliningHandler handler = new TruffleInliningHandler(new DefaultInliningPolicy());
    +        TruffleInliningResult result = handler.decideInlining(this, 0);
    +        performInlining(result);
    +        logInliningDecision(result);
         }
     
    -    protected boolean shouldCompile() {
    -        return compilationPolicy.shouldCompile(compilationProfile);
    -    }
    -
    -    protected static boolean shouldInline() {
    -        return TruffleFunctionInlining.getValue();
    -    }
    -
    -    protected final void cancelInlinedCallOptimization() {
    -        if (getInliningResult() != null) {
    -            for (TruffleCallPath path : getInliningResult()) {
    -                OptimizedCallNode top = path.getCallNode();
    -                top.notifyInlining();
    -                top.getCurrentCallTarget().cancelInstalledTask(top, top, "Inlined");
    +    private static void performInlining(TruffleInliningResult result) {
    +        for (TruffleInliningProfile profile : result) {
    +            profile.getCallNode().inline();
    +            TruffleInliningResult recursiveResult = profile.getRecursiveResult();
    +            if (recursiveResult != null) {
    +                performInlining(recursiveResult);
                 }
             }
         }
     
    -    protected final void onCompilationDone() {
    -        if (inliningResult != null) {
    -            for (TruffleCallPath path : inliningResult) {
    -                path.getCallNode().notifyInliningDone();
    +    public final Object callRoot(Object[] originalArguments) {
    +
    +        Object[] args = originalArguments;
    +        if (this.profiledArgumentTypesAssumption != null && CompilerDirectives.inCompiledCode() && profiledArgumentTypesAssumption.isValid()) {
    +            args = CompilerDirectives.unsafeCast(castArrayFixedLength(args, profiledArgumentTypes.length), Object[].class, true, true);
    +        }
    +
    +        VirtualFrame frame = createFrame(getRootNode().getFrameDescriptor(), args);
    +        Object result = callProxy(frame);
    +
    +        // Profile call return type
    +        if (profiledReturnTypeAssumption == null) {
    +            if (TruffleReturnTypeSpeculation.getValue()) {
    +                CompilerDirectives.transferToInterpreter();
    +                profiledReturnType = result.getClass();
    +                profiledReturnTypeAssumption = Truffle.getRuntime().createAssumption("Profiled Return Type");
    +            }
    +        } else if (profiledReturnType != null) {
    +            if (result == null || profiledReturnType != result.getClass()) {
    +                CompilerDirectives.transferToInterpreter();
    +                profiledReturnType = null;
    +                profiledReturnTypeAssumption.invalidate();
                 }
             }
    +
    +        return result;
         }
     
    -    protected abstract void cancelInstalledTask(Node oldNode, Node newNode, CharSequence reason);
    -
    -    protected abstract void invalidate(Node oldNode, Node newNode, CharSequence reason);
    -
    -    public final Object executeHelper(Object[] args) {
    -        VirtualFrame frame = createFrame(getRootNode().getFrameDescriptor(), args);
    -        return getRootNode().execute(frame);
    +    private static Object castArrayFixedLength(Object[] args, @SuppressWarnings("unused") int length) {
    +        return args;
         }
     
         public static FrameWithoutBoxing createFrame(FrameDescriptor descriptor, Object[] args) {
    @@ -181,244 +305,11 @@
             invalidate(oldNode, newNode, reason);
         }
     
    -    public SpeculationLog getSpeculationLog() {
    -        return speculationLog;
    -    }
    -
         public Map getDebugProperties() {
             Map properties = new LinkedHashMap<>();
    -        addASTSizeProperty(getInliningResult(), new TruffleCallPath(this), properties);
    +        addASTSizeProperty(this, properties);
             properties.putAll(getCompilationProfile().getDebugProperties());
             return properties;
     
         }
    -
    -    private static void logInliningDecision(OptimizedCallTarget target, TruffleInliningResult result, TruffleInliningHandler handler) {
    -        if (!TraceTruffleInlining.getValue()) {
    -            return;
    -        }
    -
    -        List profiles = handler.lookupProfiles(result, new TruffleCallPath(target));
    -
    -        Collections.sort(profiles); // sorts by hierarchy and source section
    -
    -        logInliningStart(target);
    -        for (TruffleInliningProfile profile : profiles) {
    -            TruffleCallPath path = profile.getCallPath();
    -            if (path.getRootCallTarget() == target) {
    -                String msg = result.isInlined(path) ? "inline success" : "inline failed";
    -                logInlinedImpl(msg, result, handler.getProfiles().get(path), path);
    -            }
    -        }
    -        logInliningDone(target);
    -    }
    -
    -    private static void logInlinedImpl(String status, TruffleInliningResult result, TruffleInliningProfile profile, TruffleCallPath path) {
    -        Map properties = new LinkedHashMap<>();
    -        addASTSizeProperty(result, path, properties);
    -        if (profile != null) {
    -            properties.putAll(profile.getDebugProperties());
    -        }
    -        log((path.getDepth() * 2), status, path.getCallTarget().toString(), properties);
    -    }
    -
    -    private static void logInliningStart(OptimizedCallTarget target) {
    -        if (TraceTruffleInlining.getValue()) {
    -            log(0, "inline start", target.toString(), target.getDebugProperties());
    -        }
    -    }
    -
    -    private static void logInliningDone(OptimizedCallTarget target) {
    -        if (TraceTruffleInlining.getValue()) {
    -            log(0, "inline done", target.toString(), target.getDebugProperties());
    -        }
    -    }
    -
    -    protected static void logOptimizingQueued(OptimizedCallTarget target) {
    -        if (TraceTruffleCompilationDetails.getValue()) {
    -            log(0, "opt queued", target.toString(), target.getDebugProperties());
    -        }
    -    }
    -
    -    protected static void logOptimizingUnqueued(OptimizedCallTarget target, Node oldNode, Node newNode, CharSequence reason) {
    -        if (TraceTruffleCompilationDetails.getValue()) {
    -            Map properties = new LinkedHashMap<>();
    -            addReplaceProperties(properties, oldNode, newNode);
    -            properties.put("Reason", reason);
    -            log(0, "opt unqueued", target.toString(), properties);
    -        }
    -    }
    -
    -    private static void addReplaceProperties(Map properties, Node oldNode, Node newNode) {
    -        if (oldNode != null && newNode != null) {
    -            properties.put("OldClass", oldNode.getClass().getSimpleName());
    -            properties.put("NewClass", newNode.getClass().getSimpleName());
    -            properties.put("Node", newNode);
    -        }
    -    }
    -
    -    static void logOptimizingStart(OptimizedCallTarget target) {
    -        if (TraceTruffleCompilationDetails.getValue()) {
    -            log(0, "opt start", target.toString(), target.getDebugProperties());
    -        }
    -    }
    -
    -    protected static void logOptimizedInvalidated(OptimizedCallTarget target, Node oldNode, Node newNode, CharSequence reason) {
    -        if (TraceTruffleCompilation.getValue()) {
    -            Map properties = new LinkedHashMap<>();
    -            addReplaceProperties(properties, oldNode, newNode);
    -            properties.put("Reason", reason);
    -            log(0, "opt invalidated", target.toString(), properties);
    -        }
    -    }
    -
    -    protected static void logOptimizingFailed(OptimizedCallTarget callSite, CharSequence reason) {
    -        Map properties = new LinkedHashMap<>();
    -        properties.put("Reason", reason);
    -        log(0, "opt fail", callSite.toString(), properties);
    -    }
    -
    -    static void logOptimizingDone(OptimizedCallTarget target, Map properties) {
    -        if (TraceTruffleCompilationDetails.getValue() || TraceTruffleCompilation.getValue()) {
    -            log(0, "opt done", target.toString(), properties);
    -        }
    -        if (TraceTruffleCompilationPolymorphism.getValue()) {
    -
    -            target.getRootNode().accept(new NodeVisitor() {
    -                public boolean visit(Node node) {
    -                    NodeCost kind = node.getCost();
    -                    if (kind == NodeCost.POLYMORPHIC || kind == NodeCost.MEGAMORPHIC) {
    -                        Map props = new LinkedHashMap<>();
    -                        props.put("simpleName", node.getClass().getSimpleName());
    -                        String msg = kind == NodeCost.MEGAMORPHIC ? "megamorphic" : "polymorphic";
    -                        log(0, msg, node.toString(), props);
    -                    }
    -                    if (node instanceof CallNode) {
    -                        CallNode callNode = (CallNode) node;
    -                        if (callNode.isInlined()) {
    -                            callNode.getCurrentRootNode().accept(this);
    -                        }
    -                    }
    -                    return true;
    -                }
    -            });
    -
    -        }
    -    }
    -
    -    private static int splitCount = 0;
    -
    -    static void logSplit(OptimizedCallNode callNode, OptimizedCallTarget target, OptimizedCallTarget newTarget) {
    -        if (TraceTruffleSplitting.getValue()) {
    -            Map properties = new LinkedHashMap<>();
    -            addASTSizeProperty(target.getInliningResult(), new TruffleCallPath(target), properties);
    -            properties.put("Split#", ++splitCount);
    -            properties.put("Source", callNode.getEncapsulatingSourceSection());
    -            log(0, "split", newTarget.toString(), properties);
    -        }
    -    }
    -
    -    static void addASTSizeProperty(TruffleInliningResult inliningResult, TruffleCallPath countedPath, Map properties) {
    -        int polymorphicCount = OptimizedCallUtils.countNodes(inliningResult, countedPath, new InlinedNodeCountFilter() {
    -            public boolean isCounted(TruffleCallPath path, Node node) {
    -                return node.getCost() == NodeCost.POLYMORPHIC;
    -            }
    -        });
    -
    -        int megamorphicCount = OptimizedCallUtils.countNodes(inliningResult, countedPath, new InlinedNodeCountFilter() {
    -            public boolean isCounted(TruffleCallPath path, Node node) {
    -                return node.getCost() == NodeCost.MEGAMORPHIC;
    -            }
    -        });
    -
    -        String value = String.format("%4d (%d/%d)", OptimizedCallUtils.countNonTrivialNodes(inliningResult, countedPath), polymorphicCount, megamorphicCount);
    -        properties.put("ASTSize", value);
    -    }
    -
    -    static void log(int indent, String msg, String details, Map properties) {
    -        StringBuilder sb = new StringBuilder();
    -        sb.append(String.format("[truffle] %-16s ", msg));
    -        for (int i = 0; i < indent; i++) {
    -            sb.append(' ');
    -        }
    -        sb.append(String.format("%-" + (60 - indent) + "s", details));
    -        if (properties != null) {
    -            for (String property : properties.keySet()) {
    -                Object value = properties.get(property);
    -                if (value == null) {
    -                    continue;
    -                }
    -                sb.append('|');
    -                sb.append(property);
    -
    -                StringBuilder propertyBuilder = new StringBuilder();
    -                if (value instanceof Integer) {
    -                    propertyBuilder.append(String.format("%6d", value));
    -                } else if (value instanceof Double) {
    -                    propertyBuilder.append(String.format("%8.2f", value));
    -                } else {
    -                    propertyBuilder.append(value);
    -                }
    -
    -                int length = Math.max(1, 20 - property.length());
    -                sb.append(String.format(" %" + length + "s ", propertyBuilder.toString()));
    -            }
    -        }
    -        OUT.println(sb.toString());
    -    }
    -
    -    private static void printProfiling() {
    -        List sortedCallTargets = new ArrayList<>(OptimizedCallTarget.callTargets.keySet());
    -        Collections.sort(sortedCallTargets, new Comparator() {
    -
    -            @Override
    -            public int compare(OptimizedCallTarget o1, OptimizedCallTarget o2) {
    -                return o2.callCount - o1.callCount;
    -            }
    -        });
    -
    -        int totalCallCount = 0;
    -        int totalInlinedCallSiteCount = 0;
    -        int totalNodeCount = 0;
    -        int totalInvalidationCount = 0;
    -
    -        OUT.println();
    -        OUT.printf("%-50s | %-10s | %s / %s | %s | %s\n", "Call Target", "Call Count", "Calls Sites Inlined", "Not Inlined", "Node Count", "Inv");
    -        for (OptimizedCallTarget callTarget : sortedCallTargets) {
    -            if (callTarget.callCount == 0) {
    -                continue;
    -            }
    -
    -            int nodeCount = OptimizedCallUtils.countNonTrivialNodes(callTarget.getInliningResult(), new TruffleCallPath(callTarget));
    -            String comment = callTarget.installedCode == null ? " int" : "";
    -            comment += callTarget.compilationEnabled ? "" : " fail";
    -            OUT.printf("%-50s | %10d | %15d | %10d | %3d%s\n", callTarget.getRootNode(), callTarget.callCount, nodeCount, nodeCount, callTarget.getCompilationProfile().getInvalidationCount(), comment);
    -
    -            totalCallCount += callTarget.callCount;
    -            totalInlinedCallSiteCount += nodeCount;
    -            totalNodeCount += nodeCount;
    -            totalInvalidationCount += callTarget.getCompilationProfile().getInvalidationCount();
    -        }
    -        OUT.printf("%-50s | %10d | %15d | %10d | %3d\n", "Total", totalCallCount, totalInlinedCallSiteCount, totalNodeCount, totalInvalidationCount);
    -    }
    -
    -    private static void registerCallTarget(OptimizedCallTarget callTarget) {
    -        callTargets.put(callTarget, 0);
    -    }
    -
    -    private static Map callTargets;
    -    static {
    -        if (TruffleCallTargetProfiling.getValue()) {
    -            callTargets = new WeakHashMap<>();
    -
    -            Runtime.getRuntime().addShutdownHook(new Thread() {
    -
    -                @Override
    -                public void run() {
    -                    printProfiling();
    -                }
    -            });
    -        }
    -    }
    -
     }
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTargetImpl.java
    --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTargetImpl.java	Wed Apr 23 15:22:20 2014 +0200
    +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    @@ -1,181 +0,0 @@
    -/*
    - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
    - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    - *
    - * This code is free software; you can redistribute it and/or modify it
    - * under the terms of the GNU General Public License version 2 only, as
    - * published by the Free Software Foundation.
    - *
    - * This code is distributed in the hope that it will be useful, but WITHOUT
    - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    - * version 2 for more details (a copy is included in the LICENSE file that
    - * accompanied this code).
    - *
    - * You should have received a copy of the GNU General Public License version
    - * 2 along with this work; if not, write to the Free Software Foundation,
    - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    - *
    - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    - * or visit www.oracle.com if you need additional information or have any
    - * questions.
    - */
    -package com.oracle.graal.truffle;
    -
    -import static com.oracle.graal.truffle.TruffleCompilerOptions.*;
    -
    -import java.util.concurrent.*;
    -
    -import com.oracle.graal.api.code.*;
    -import com.oracle.truffle.api.*;
    -import com.oracle.truffle.api.nodes.*;
    -
    -/**
    - * Call target for running truffle on a standard VM (and not in SubstrateVM).
    - */
    -public final class OptimizedCallTargetImpl extends OptimizedCallTarget {
    -
    -    protected final TruffleCompiler compiler;
    -    private Future installedCodeTask;
    -
    -    OptimizedCallTargetImpl(RootNode rootNode, TruffleCompiler compiler, int invokeCounter, int compilationThreshold, boolean compilationEnabled) {
    -        super(rootNode, invokeCounter, compilationThreshold, compilationEnabled, TruffleUseTimeForCompilationDecision.getValue() ? new TimedCompilationPolicy() : new DefaultCompilationPolicy());
    -        this.compiler = compiler;
    -    }
    -
    -    public boolean isOptimized() {
    -        return installedCode != null || installedCodeTask != null;
    -    }
    -
    -    @CompilerDirectives.SlowPath
    -    @Override
    -    public Object call(Object[] args) {
    -        return CompilerDirectives.inInterpreter() ? callHelper(args) : executeHelper(args);
    -    }
    -
    -    private Object callHelper(Object[] args) {
    -        if (installedCode != null && installedCode.isValid()) {
    -            reinstallCallMethodShortcut();
    -        }
    -        if (TruffleCallTargetProfiling.getValue()) {
    -            callCount++;
    -        }
    -        if (CompilerDirectives.injectBranchProbability(CompilerDirectives.FASTPATH_PROBABILITY, installedCode != null)) {
    -            try {
    -                return installedCode.executeVarargs(new Object[]{this, args});
    -            } catch (InvalidInstalledCodeException ex) {
    -                return compiledCodeInvalidated(args);
    -            }
    -        } else {
    -            return interpreterCall(args);
    -        }
    -    }
    -
    -    private static void reinstallCallMethodShortcut() {
    -        if (TraceTruffleCompilation.getValue()) {
    -            OUT.println("[truffle] reinstall OptimizedCallTarget.call code with frame prolog shortcut.");
    -        }
    -        GraalTruffleRuntime.installOptimizedCallTargetCallMethod();
    -    }
    -
    -    private Object compiledCodeInvalidated(Object[] args) {
    -        invalidate(null, null, "Compiled code invalidated");
    -        return call(args);
    -    }
    -
    -    @Override
    -    protected void invalidate(Node oldNode, Node newNode, CharSequence reason) {
    -        InstalledCode m = this.installedCode;
    -        if (m != null) {
    -            CompilerAsserts.neverPartOfCompilation();
    -            installedCode = null;
    -            inliningResult = null;
    -            compilationProfile.reportInvalidated();
    -            logOptimizedInvalidated(this, oldNode, newNode, reason);
    -        }
    -        cancelInstalledTask(oldNode, newNode, reason);
    -    }
    -
    -    @Override
    -    protected void cancelInstalledTask(Node oldNode, Node newNode, CharSequence reason) {
    -        Future task = this.installedCodeTask;
    -        if (task != null) {
    -            task.cancel(true);
    -            this.installedCodeTask = null;
    -            logOptimizingUnqueued(this, oldNode, newNode, reason);
    -            compilationProfile.reportInvalidated();
    -        }
    -    }
    -
    -    private Object interpreterCall(Object[] args) {
    -        CompilerAsserts.neverPartOfCompilation();
    -        compilationProfile.reportInterpreterCall();
    -
    -        if (compilationEnabled && compilationPolicy.shouldCompile(compilationProfile)) {
    -            InstalledCode code = compile();
    -            if (code != null && code.isValid()) {
    -                this.installedCode = code;
    -                try {
    -                    return code.executeVarargs(new Object[]{this, args});
    -                } catch (InvalidInstalledCodeException ex) {
    -                    return compiledCodeInvalidated(args);
    -                }
    -            }
    -        }
    -        return executeHelper(args);
    -    }
    -
    -    private boolean isCompiling() {
    -        Future codeTask = this.installedCodeTask;
    -        if (codeTask != null) {
    -            if (codeTask.isCancelled()) {
    -                installedCodeTask = null;
    -                return false;
    -            }
    -            return true;
    -        }
    -        return false;
    -    }
    -
    -    @Override
    -    public InstalledCode compile() {
    -        if (isCompiling()) {
    -            if (installedCodeTask.isDone()) {
    -                return receiveInstalledCode();
    -            }
    -            return null;
    -        } else {
    -            performInlining();
    -            cancelInlinedCallOptimization();
    -            logOptimizingQueued(this);
    -            this.installedCodeTask = compiler.compile(this);
    -            if (!TruffleBackgroundCompilation.getValue()) {
    -                return receiveInstalledCode();
    -            }
    -            return null;
    -        }
    -    }
    -
    -    private InstalledCode receiveInstalledCode() {
    -        try {
    -            return installedCodeTask.get();
    -        } catch (InterruptedException | ExecutionException e) {
    -            compilationEnabled = false;
    -            logOptimizingFailed(this, e.getMessage());
    -            if (e.getCause() instanceof BailoutException) {
    -                // Bailout => move on.
    -            } else {
    -                if (TraceTruffleCompilationExceptions.getValue()) {
    -                    e.printStackTrace(OUT);
    -                }
    -                if (TruffleCompilationExceptionsAreFatal.getValue()) {
    -                    System.exit(-1);
    -                }
    -            }
    -            return null;
    -        } finally {
    -            onCompilationDone();
    -        }
    -    }
    -
    -}
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTargetLog.java
    --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTargetLog.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -0,0 +1,284 @@
    +/*
    + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
    + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    + *
    + * This code is free software; you can redistribute it and/or modify it
    + * under the terms of the GNU General Public License version 2 only, as
    + * published by the Free Software Foundation.
    + *
    + * This code is distributed in the hope that it will be useful, but WITHOUT
    + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    + * version 2 for more details (a copy is included in the LICENSE file that
    + * accompanied this code).
    + *
    + * You should have received a copy of the GNU General Public License version
    + * 2 along with this work; if not, write to the Free Software Foundation,
    + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    + *
    + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    + * or visit www.oracle.com if you need additional information or have any
    + * questions.
    + */
    +package com.oracle.graal.truffle;
    +
    +import static com.oracle.graal.truffle.TruffleCompilerOptions.*;
    +
    +import java.io.*;
    +import java.util.*;
    +
    +import com.oracle.graal.debug.*;
    +import com.oracle.truffle.api.nodes.*;
    +import com.oracle.truffle.api.nodes.NodeUtil.NodeCountFilter;
    +
    +public final class OptimizedCallTargetLog {
    +
    +    protected static final PrintStream OUT = TTY.out().out();
    +
    +    private static Map callTargets;
    +    static {
    +        if (TruffleCallTargetProfiling.getValue()) {
    +            callTargets = new WeakHashMap<>();
    +
    +            Runtime.getRuntime().addShutdownHook(new Thread() {
    +
    +                @Override
    +                public void run() {
    +                    printProfiling();
    +                }
    +            });
    +        }
    +    }
    +
    +    private OptimizedCallTargetLog() {
    +    }
    +
    +    public static void logInliningDecision(TruffleInliningResult result) {
    +        if (!TraceTruffleInlining.getValue()) {
    +            return;
    +        }
    +
    +        logInliningStart(result.getCallTarget());
    +        logInliningDecisionRecursive(result, 0);
    +        logInliningDone(result.getCallTarget());
    +    }
    +
    +    private static void logInliningDecisionRecursive(TruffleInliningResult result, int depth) {
    +        List callNodes = searchCallNodes(result.getCallTarget());
    +        for (OptimizedDirectCallNode callNode : callNodes) {
    +            TruffleInliningProfile profile = result.getProfiles().get(callNode);
    +            boolean inlined = result.isInlined(callNode);
    +            String msg = inlined ? "inline success" : "inline failed";
    +            logInlinedImpl(msg, callNode, profile, depth);
    +            if (profile.getRecursiveResult() != null && inlined) {
    +                logInliningDecisionRecursive(profile.getRecursiveResult(), depth + 1);
    +            }
    +        }
    +    }
    +
    +    private static List searchCallNodes(final OptimizedCallTarget target) {
    +        final List callNodes = new ArrayList<>();
    +        target.getRootNode().accept(new NodeVisitor() {
    +            public boolean visit(Node node) {
    +                if (node instanceof OptimizedDirectCallNode) {
    +                    callNodes.add((OptimizedDirectCallNode) node);
    +                }
    +                return true;
    +            }
    +        });
    +        return callNodes;
    +    }
    +
    +    private static void logInlinedImpl(String status, OptimizedDirectCallNode callNode, TruffleInliningProfile profile, int depth) {
    +        Map properties = new LinkedHashMap<>();
    +        addASTSizeProperty(callNode.getCurrentCallTarget(), properties);
    +        if (profile != null) {
    +            properties.putAll(profile.getDebugProperties());
    +        }
    +        log((depth * 2), status, callNode.getCurrentCallTarget().toString(), properties);
    +    }
    +
    +    private static void logInliningStart(OptimizedCallTarget target) {
    +        if (TraceTruffleInlining.getValue()) {
    +            log(0, "inline start", target.toString(), target.getDebugProperties());
    +        }
    +    }
    +
    +    private static void logInliningDone(OptimizedCallTarget target) {
    +        if (TraceTruffleInlining.getValue()) {
    +            log(0, "inline done", target.toString(), target.getDebugProperties());
    +        }
    +    }
    +
    +    public static void logOptimizingQueued(OptimizedCallTarget target) {
    +        if (TraceTruffleCompilationDetails.getValue()) {
    +            log(0, "opt queued", target.toString(), target.getDebugProperties());
    +        }
    +    }
    +
    +    public static void logOptimizingUnqueued(OptimizedCallTarget target, Node oldNode, Node newNode, CharSequence reason) {
    +        if (TraceTruffleCompilationDetails.getValue()) {
    +            Map properties = new LinkedHashMap<>();
    +            addReplaceProperties(properties, oldNode, newNode);
    +            properties.put("Reason", reason);
    +            log(0, "opt unqueued", target.toString(), properties);
    +        }
    +    }
    +
    +    private static void addReplaceProperties(Map properties, Node oldNode, Node newNode) {
    +        if (oldNode != null && newNode != null) {
    +            properties.put("OldClass", oldNode.getClass().getSimpleName());
    +            properties.put("NewClass", newNode.getClass().getSimpleName());
    +            properties.put("Node", newNode);
    +        }
    +    }
    +
    +    static void logOptimizingStart(OptimizedCallTarget target) {
    +        if (TraceTruffleCompilationDetails.getValue()) {
    +            log(0, "opt start", target.toString(), target.getDebugProperties());
    +        }
    +    }
    +
    +    public static void logOptimizedInvalidated(OptimizedCallTarget target, Node oldNode, Node newNode, CharSequence reason) {
    +        if (TraceTruffleCompilation.getValue()) {
    +            Map properties = new LinkedHashMap<>();
    +            addReplaceProperties(properties, oldNode, newNode);
    +            properties.put("Reason", reason);
    +            log(0, "opt invalidated", target.toString(), properties);
    +        }
    +    }
    +
    +    public static void logOptimizingFailed(OptimizedCallTarget callSite, CharSequence reason) {
    +        Map properties = new LinkedHashMap<>();
    +        properties.put("Reason", reason);
    +        log(0, "opt fail", callSite.toString(), properties);
    +    }
    +
    +    static void logOptimizingDone(OptimizedCallTarget target, Map properties) {
    +        if (TraceTruffleCompilationDetails.getValue() || TraceTruffleCompilation.getValue()) {
    +            log(0, "opt done", target.toString(), properties);
    +        }
    +        if (TraceTruffleCompilationPolymorphism.getValue()) {
    +
    +            target.getRootNode().accept(new NodeVisitor() {
    +                public boolean visit(Node node) {
    +                    NodeCost kind = node.getCost();
    +                    if (kind == NodeCost.POLYMORPHIC || kind == NodeCost.MEGAMORPHIC) {
    +                        Map props = new LinkedHashMap<>();
    +                        props.put("simpleName", node.getClass().getSimpleName());
    +                        String msg = kind == NodeCost.MEGAMORPHIC ? "megamorphic" : "polymorphic";
    +                        log(0, msg, node.toString(), props);
    +                    }
    +                    if (node instanceof DirectCallNode) {
    +                        DirectCallNode callNode = (DirectCallNode) node;
    +                        if (callNode.isInlined()) {
    +                            callNode.getCurrentRootNode().accept(this);
    +                        }
    +                    }
    +                    return true;
    +                }
    +            });
    +
    +        }
    +    }
    +
    +    private static int splitCount = 0;
    +
    +    static void logSplit(OptimizedDirectCallNode callNode, OptimizedCallTarget target, OptimizedCallTarget newTarget) {
    +        if (TraceTruffleSplitting.getValue()) {
    +            Map properties = new LinkedHashMap<>();
    +            addASTSizeProperty(target, properties);
    +            properties.put("Split#", ++splitCount);
    +            properties.put("Source", callNode.getEncapsulatingSourceSection());
    +            log(0, "split", newTarget.toString(), properties);
    +        }
    +    }
    +
    +    static void addASTSizeProperty(OptimizedCallTarget target, Map properties) {
    +        int polymorphicCount = NodeUtil.countNodes(target.getRootNode(), new NodeCountFilter() {
    +            public boolean isCounted(Node node) {
    +                return node.getCost() == NodeCost.POLYMORPHIC;
    +            }
    +        }, true);
    +
    +        int megamorphicCount = NodeUtil.countNodes(target.getRootNode(), new NodeCountFilter() {
    +            public boolean isCounted(Node node) {
    +                return node.getCost() == NodeCost.MEGAMORPHIC;
    +            }
    +        }, true);
    +
    +        String value = String.format("%4d (%d/%d)", OptimizedCallUtils.countNonTrivialNodes(target, true), polymorphicCount, megamorphicCount);
    +        properties.put("ASTSize", value);
    +    }
    +
    +    static void log(int indent, String msg, String details, Map properties) {
    +        StringBuilder sb = new StringBuilder();
    +        sb.append(String.format("[truffle] %-16s ", msg));
    +        for (int i = 0; i < indent; i++) {
    +            sb.append(' ');
    +        }
    +        sb.append(String.format("%-" + (60 - indent) + "s", details));
    +        if (properties != null) {
    +            for (String property : properties.keySet()) {
    +                Object value = properties.get(property);
    +                if (value == null) {
    +                    continue;
    +                }
    +                sb.append('|');
    +                sb.append(property);
    +
    +                StringBuilder propertyBuilder = new StringBuilder();
    +                if (value instanceof Integer) {
    +                    propertyBuilder.append(String.format("%6d", value));
    +                } else if (value instanceof Double) {
    +                    propertyBuilder.append(String.format("%8.2f", value));
    +                } else {
    +                    propertyBuilder.append(value);
    +                }
    +
    +                int length = Math.max(1, 20 - property.length());
    +                sb.append(String.format(" %" + length + "s ", propertyBuilder.toString()));
    +            }
    +        }
    +        OUT.println(sb.toString());
    +    }
    +
    +    private static void printProfiling() {
    +        List sortedCallTargets = new ArrayList<>(callTargets.keySet());
    +        Collections.sort(sortedCallTargets, new Comparator() {
    +
    +            @Override
    +            public int compare(OptimizedCallTarget o1, OptimizedCallTarget o2) {
    +                return o2.callCount - o1.callCount;
    +            }
    +        });
    +
    +        int totalCallCount = 0;
    +        int totalInlinedCallSiteCount = 0;
    +        int totalNodeCount = 0;
    +        int totalInvalidationCount = 0;
    +
    +        OUT.println();
    +        OUT.printf("%-50s | %-10s | %s / %s | %s | %s\n", "Call Target", "Call Count", "Calls Sites Inlined", "Not Inlined", "Node Count", "Inv");
    +        for (OptimizedCallTarget callTarget : sortedCallTargets) {
    +            if (callTarget.callCount == 0) {
    +                continue;
    +            }
    +
    +            int nodeCount = OptimizedCallUtils.countNonTrivialNodes(callTarget, true);
    +            String comment = callTarget.isValid() ? "" : " int";
    +            OUT.printf("%-50s | %10d | %15d | %10d | %3d%s\n", callTarget.getRootNode(), callTarget.callCount, nodeCount, nodeCount, callTarget.getCompilationProfile().getInvalidationCount(), comment);
    +
    +            totalCallCount += callTarget.callCount;
    +            totalInlinedCallSiteCount += nodeCount;
    +            totalNodeCount += nodeCount;
    +            totalInvalidationCount += callTarget.getCompilationProfile().getInvalidationCount();
    +        }
    +        OUT.printf("%-50s | %10d | %15d | %10d | %3d\n", "Total", totalCallCount, totalInlinedCallSiteCount, totalNodeCount, totalInvalidationCount);
    +    }
    +
    +    public static void registerCallTarget(OptimizedCallTarget callTarget) {
    +        callTargets.put(callTarget, 0);
    +    }
    +
    +}
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallUtils.java
    --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallUtils.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallUtils.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,98 +23,35 @@
     package com.oracle.graal.truffle;
     
     import com.oracle.truffle.api.nodes.*;
    +import com.oracle.truffle.api.nodes.NodeUtil.NodeCountFilter;
     
     class OptimizedCallUtils {
     
    -    public abstract static class InlinedCallVisitor implements NodeVisitor {
    -
    -        private TruffleCallPath currentPath;
    -        private final TruffleInliningResult inliningDecision;
    -
    -        public InlinedCallVisitor(TruffleInliningResult inliningDecision, TruffleCallPath initialPath) {
    -            this.inliningDecision = inliningDecision;
    -            this.currentPath = initialPath;
    -        }
    -
    -        public final TruffleInliningResult getInliningDecision() {
    -            return inliningDecision;
    -        }
    -
    -        public final boolean visit(Node node) {
    -            if (node instanceof OptimizedCallNode) {
    -                OptimizedCallNode callNode = ((OptimizedCallNode) node);
    -                this.currentPath = new TruffleCallPath(this.currentPath, callNode);
    -                try {
    -                    boolean result = visit(currentPath, node);
    -                    TruffleInliningResult decision = inliningDecision;
    -                    if (decision != null && decision.isInlined(currentPath)) {
    -                        callNode.getCurrentRootNode().accept(this);
    -                    }
    -                    return result;
    -                } finally {
    -                    this.currentPath = this.currentPath.getParent();
    -                }
    -            } else {
    -                return visit(currentPath, node);
    +    public static int countCalls(OptimizedCallTarget target) {
    +        return NodeUtil.countNodes(target.getRootNode(), new NodeCountFilter() {
    +            public boolean isCounted(Node node) {
    +                return node instanceof DirectCallNode;
                 }
    -        }
    -
    -        public abstract boolean visit(TruffleCallPath path, Node node);
    -
    +        }, true);
         }
     
    -    public static int countNodes(TruffleInliningResult decision, TruffleCallPath path, InlinedNodeCountFilter filter) {
    -        InlinedNodeCountVisitor nodeCount = new InlinedNodeCountVisitor(decision, path, filter);
    -        path.getCallTarget().getRootNode().accept(nodeCount);
    -        return nodeCount.nodeCount;
    -    }
    -
    -    public static int countCalls(TruffleInliningResult decision, TruffleCallPath path) {
    -        InlinedNodeCountVisitor nodeCount = new InlinedNodeCountVisitor(decision, path, new InlinedNodeCountFilter() {
    -            public boolean isCounted(TruffleCallPath p, Node node) {
    -                return node instanceof CallNode;
    +    public static int countCallsInlined(OptimizedCallTarget target) {
    +        return NodeUtil.countNodes(target.getRootNode(), new NodeCountFilter() {
    +            public boolean isCounted(Node node) {
    +                return (node instanceof OptimizedDirectCallNode) && ((OptimizedDirectCallNode) node).isInlined();
                 }
    -        });
    -        path.getCallTarget().getRootNode().accept(nodeCount);
    -        return nodeCount.nodeCount;
    -    }
    -
    -    public interface InlinedNodeCountFilter {
    -
    -        boolean isCounted(TruffleCallPath path, Node node);
    +        }, true);
         }
     
    -    private static final class InlinedNodeCountVisitor extends InlinedCallVisitor {
    -
    -        private final InlinedNodeCountFilter filter;
    -        int nodeCount;
    -
    -        private InlinedNodeCountVisitor(TruffleInliningResult decision, TruffleCallPath initialPath, InlinedNodeCountFilter filter) {
    -            super(decision, initialPath);
    -            this.filter = filter;
    -        }
    -
    -        @Override
    -        public boolean visit(TruffleCallPath path, Node node) {
    -            if (filter == null || filter.isCounted(path, node)) {
    -                nodeCount++;
    -            }
    -            return true;
    -        }
    -
    -    }
    -
    -    static int countNonTrivialNodes(TruffleInliningResult state, TruffleCallPath path) {
    -        return countNodes(state, path, new InlinedNodeCountFilter() {
    -
    -            public boolean isCounted(TruffleCallPath p, Node node) {
    +    public static int countNonTrivialNodes(final OptimizedCallTarget target, final boolean inlined) {
    +        return NodeUtil.countNodes(target.getRootNode(), new NodeCountFilter() {
    +            public boolean isCounted(Node node) {
                     NodeCost cost = node.getCost();
                     if (cost != null && cost != NodeCost.NONE && cost != NodeCost.UNINITIALIZED) {
                         return true;
                     }
                     return false;
                 }
    -        });
    +        }, inlined);
         }
    -
     }
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedDirectCallNode.java
    --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedDirectCallNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -0,0 +1,222 @@
    +/*
    + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
    + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    + *
    + * This code is free software; you can redistribute it and/or modify it
    + * under the terms of the GNU General Public License version 2 only, as
    + * published by the Free Software Foundation.
    + *
    + * This code is distributed in the hope that it will be useful, but WITHOUT
    + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    + * version 2 for more details (a copy is included in the LICENSE file that
    + * accompanied this code).
    + *
    + * You should have received a copy of the GNU General Public License version
    + * 2 along with this work; if not, write to the Free Software Foundation,
    + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    + *
    + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    + * or visit www.oracle.com if you need additional information or have any
    + * questions.
    + */
    +package com.oracle.graal.truffle;
    +
    +import com.oracle.truffle.api.*;
    +import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
    +import com.oracle.truffle.api.frame.FrameInstance.FrameAccess;
    +import com.oracle.truffle.api.frame.*;
    +import com.oracle.truffle.api.nodes.*;
    +import com.oracle.truffle.api.nodes.NodeUtil.NodeCountFilter;
    +
    +/**
    + * A call node with a constant {@link CallTarget} that can be optimized by Graal.
    + */
    +public final class OptimizedDirectCallNode extends DirectCallNode implements MaterializedFrameNotify {
    +
    +    private int callCount;
    +    private boolean trySplit = true;
    +    private boolean inliningForced;
    +
    +    @CompilationFinal private boolean inlined;
    +    @CompilationFinal private OptimizedCallTarget splitCallTarget;
    +    @CompilationFinal private FrameAccess outsideFrameAccess = FrameAccess.NONE;
    +
    +    private OptimizedDirectCallNode(OptimizedCallTarget target) {
    +        super(target);
    +    }
    +
    +    @Override
    +    public Object call(VirtualFrame frame, Object[] arguments) {
    +        if (CompilerDirectives.inInterpreter()) {
    +            onInterpreterCall();
    +        }
    +        return callProxy(this, getCurrentCallTarget(), frame, arguments, inlined, true);
    +    }
    +
    +    public static Object callProxy(MaterializedFrameNotify notify, CallTarget callTarget, VirtualFrame frame, Object[] arguments, boolean inlined, boolean direct) {
    +        try {
    +            if (notify.getOutsideFrameAccess() != FrameAccess.NONE) {
    +                CompilerDirectives.materialize(frame);
    +            }
    +            if (inlined) {
    +                return ((OptimizedCallTarget) callTarget).callInlined(arguments);
    +            } else if (direct) {
    +                return ((OptimizedCallTarget) callTarget).callDirect(arguments);
    +            } else {
    +                return callTarget.call(arguments);
    +            }
    +        } finally {
    +            // this assertion is needed to keep the values from being cleared as non-live locals
    +            assert notify != null & callTarget != null & frame != null;
    +        }
    +    }
    +
    +    @Override
    +    public boolean isInlinable() {
    +        return true;
    +    }
    +
    +    @Override
    +    public void forceInlining() {
    +        inliningForced = true;
    +    }
    +
    +    @Override
    +    public boolean isInliningForced() {
    +        return inliningForced;
    +    }
    +
    +    @Override
    +    public FrameAccess getOutsideFrameAccess() {
    +        return outsideFrameAccess;
    +    }
    +
    +    @Override
    +    public void setOutsideFrameAccess(FrameAccess outsideFrameAccess) {
    +        this.outsideFrameAccess = outsideFrameAccess;
    +    }
    +
    +    @Override
    +    public boolean isSplittable() {
    +        return getCallTarget().getRootNode().isSplittable();
    +    }
    +
    +    @Override
    +    public OptimizedCallTarget getCallTarget() {
    +        return (OptimizedCallTarget) super.getCallTarget();
    +    }
    +
    +    public int getCallCount() {
    +        return callCount;
    +    }
    +
    +    @Override
    +    public OptimizedCallTarget getCurrentCallTarget() {
    +        return (OptimizedCallTarget) super.getCurrentCallTarget();
    +    }
    +
    +    @Override
    +    public OptimizedCallTarget getSplitCallTarget() {
    +        return splitCallTarget;
    +    }
    +
    +    private void onInterpreterCall() {
    +        callCount++;
    +        if (trySplit) {
    +            if (callCount == 1) {
    +                // on first call
    +                getCurrentCallTarget().incrementKnownCallSites();
    +            }
    +            if (callCount > 1 && !inlined) {
    +                trySplit = false;
    +                if (shouldSplit()) {
    +                    splitImpl(true);
    +                }
    +            }
    +        }
    +    }
    +
    +    /* Called by the runtime system if this CallNode is really going to be inlined. */
    +    void inline() {
    +        inlined = true;
    +    }
    +
    +    @Override
    +    public boolean isInlined() {
    +        return inlined;
    +    }
    +
    +    @Override
    +    public boolean split() {
    +        splitImpl(false);
    +        return true;
    +    }
    +
    +    private void splitImpl(boolean heuristic) {
    +        CompilerAsserts.neverPartOfCompilation();
    +
    +        OptimizedCallTarget splitTarget = (OptimizedCallTarget) Truffle.getRuntime().createCallTarget(getCallTarget().getRootNode().split());
    +        splitTarget.setSplitSource(getCallTarget());
    +        if (heuristic) {
    +            OptimizedCallTargetLog.logSplit(this, getCallTarget(), splitTarget);
    +        }
    +        if (callCount >= 1) {
    +            getCallTarget().decrementKnownCallSites();
    +            splitTarget.incrementKnownCallSites();
    +        }
    +        this.splitCallTarget = splitTarget;
    +    }
    +
    +    private boolean shouldSplit() {
    +        if (splitCallTarget != null) {
    +            return false;
    +        }
    +        if (!TruffleCompilerOptions.TruffleSplittingEnabled.getValue()) {
    +            return false;
    +        }
    +        if (!isSplittable()) {
    +            return false;
    +        }
    +        OptimizedCallTarget splitTarget = getCallTarget();
    +        int nodeCount = OptimizedCallUtils.countNonTrivialNodes(splitTarget, false);
    +        if (nodeCount > TruffleCompilerOptions.TruffleSplittingMaxCalleeSize.getValue()) {
    +            return false;
    +        }
    +
    +        // disable recursive splitting for now
    +        OptimizedCallTarget root = (OptimizedCallTarget) getRootNode().getCallTarget();
    +        if (root == splitTarget || root.getSplitSource() == splitTarget) {
    +            // recursive call found
    +            return false;
    +        }
    +
    +        // max one child call and callCount > 2 and kind of small number of nodes
    +        if (isMaxSingleCall()) {
    +            return true;
    +        }
    +        return countPolymorphic() >= 1;
    +    }
    +
    +    private boolean isMaxSingleCall() {
    +        return NodeUtil.countNodes(getCurrentCallTarget().getRootNode(), new NodeCountFilter() {
    +            public boolean isCounted(Node node) {
    +                return node instanceof DirectCallNode;
    +            }
    +        }) <= 1;
    +    }
    +
    +    private int countPolymorphic() {
    +        return NodeUtil.countNodes(getCurrentCallTarget().getRootNode(), new NodeCountFilter() {
    +            public boolean isCounted(Node node) {
    +                NodeCost cost = node.getCost();
    +                boolean polymorphic = cost == NodeCost.POLYMORPHIC || cost == NodeCost.MEGAMORPHIC;
    +                return polymorphic;
    +            }
    +        });
    +    }
    +
    +    public static OptimizedDirectCallNode create(OptimizedCallTarget target) {
    +        return new OptimizedDirectCallNode(target);
    +    }
    +}
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedIndirectCallNode.java
    --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedIndirectCallNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -0,0 +1,53 @@
    +/*
    + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
    + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    + *
    + * This code is free software; you can redistribute it and/or modify it
    + * under the terms of the GNU General Public License version 2 only, as
    + * published by the Free Software Foundation.
    + *
    + * This code is distributed in the hope that it will be useful, but WITHOUT
    + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    + * version 2 for more details (a copy is included in the LICENSE file that
    + * accompanied this code).
    + *
    + * You should have received a copy of the GNU General Public License version
    + * 2 along with this work; if not, write to the Free Software Foundation,
    + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    + *
    + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    + * or visit www.oracle.com if you need additional information or have any
    + * questions.
    + */
    +package com.oracle.graal.truffle;
    +
    +import com.oracle.truffle.api.*;
    +import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
    +import com.oracle.truffle.api.frame.FrameInstance.FrameAccess;
    +import com.oracle.truffle.api.frame.*;
    +import com.oracle.truffle.api.nodes.*;
    +
    +/**
    + * A call node with a constant {@link CallTarget} that can be optimized by Graal.
    + */
    +public final class OptimizedIndirectCallNode extends IndirectCallNode implements MaterializedFrameNotify {
    +
    +    @CompilationFinal private FrameAccess outsideFrameAccess = FrameAccess.NONE;
    +
    +    @Override
    +    public Object call(VirtualFrame frame, CallTarget target, Object[] arguments) {
    +        return OptimizedDirectCallNode.callProxy(this, target, frame, arguments, false, false);
    +    }
    +
    +    @Override
    +    public FrameAccess getOutsideFrameAccess() {
    +        return outsideFrameAccess;
    +    }
    +
    +    @Override
    +    public void setOutsideFrameAccess(FrameAccess outsideFrameAccess) {
    +        this.outsideFrameAccess = outsideFrameAccess;
    +    }
    +
    +}
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java
    --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,19 +22,20 @@
      */
     package com.oracle.graal.truffle;
     
    -import static com.oracle.graal.phases.GraalOptions.*;
    +import static com.oracle.graal.compiler.common.GraalOptions.*;
     import static com.oracle.graal.truffle.TruffleCompilerOptions.*;
     
    -import java.lang.reflect.*;
     import java.util.*;
     
     import com.oracle.graal.api.code.*;
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.api.replacements.*;
    +import com.oracle.graal.api.runtime.*;
     import com.oracle.graal.debug.*;
     import com.oracle.graal.debug.Debug.Scope;
     import com.oracle.graal.debug.internal.*;
    +import com.oracle.graal.graph.Graph.Mark;
     import com.oracle.graal.graph.*;
    -import com.oracle.graal.graph.Graph.Mark;
     import com.oracle.graal.graph.Node;
     import com.oracle.graal.graph.spi.*;
     import com.oracle.graal.loop.*;
    @@ -42,7 +43,6 @@
     import com.oracle.graal.nodes.java.*;
     import com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
     import com.oracle.graal.nodes.util.*;
     import com.oracle.graal.nodes.virtual.*;
     import com.oracle.graal.phases.*;
    @@ -67,14 +67,12 @@
         private final CanonicalizerPhase canonicalizer;
         private Set constantReceivers;
         private final TruffleCache truffleCache;
    -    private final ResolvedJavaType frameType;
     
         public PartialEvaluator(Providers providers, TruffleCache truffleCache) {
             this.providers = providers;
             CustomCanonicalizer customCanonicalizer = new PartialEvaluatorCanonicalizer(providers.getMetaAccess(), providers.getConstantReflection());
             this.canonicalizer = new CanonicalizerPhase(!ImmutableCode.getValue(), customCanonicalizer);
             this.truffleCache = truffleCache;
    -        this.frameType = providers.getMetaAccess().lookupJavaType(FrameWithoutBoxing.class);
         }
     
         public StructuredGraph createGraph(final OptimizedCallTarget callTarget, final Assumptions assumptions) {
    @@ -84,18 +82,25 @@
                 throw Debug.handle(e);
             }
     
    -        if (TraceTruffleCompilationHistogram.getValue()) {
    +        if (TraceTruffleCompilationHistogram.getValue() || TraceTruffleCompilationDetails.getValue()) {
                 constantReceivers = new HashSet<>();
             }
     
    -        final StructuredGraph graph = truffleCache.createRootGraph();
    +        final StructuredGraph graph = truffleCache.createRootGraph(callTarget.toString());
             assert graph != null : "no graph for root method";
     
             try (Scope s = Debug.scope("CreateGraph", graph); Indent indent = Debug.logAndIndent("createGraph %s", graph.method())) {
     
                 // Replace thisNode with constant.
                 ParameterNode thisNode = graph.getParameter(0);
    -            thisNode.replaceAndDelete(ConstantNode.forObject(callTarget, providers.getMetaAccess(), graph));
    +
    +            /*
    +             * Converting the call target to a Constant using the SnippetReflectionProvider is a
    +             * workaround, we should think about a better solution. Since object constants are
    +             * VM-specific, only the hosting VM knows how to do the conversion.
    +             */
    +            SnippetReflectionProvider snippetReflection = Graal.getRequiredCapability(SnippetReflectionProvider.class);
    +            thisNode.replaceAndDelete(ConstantNode.forConstant(snippetReflection.forObject(callTarget), providers.getMetaAccess(), graph));
     
                 // Canonicalize / constant propagate.
                 PhaseContext baseContext = new PhaseContext(providers, assumptions);
    @@ -104,15 +109,10 @@
                 // Intrinsify methods.
                 new ReplaceIntrinsicsPhase(providers.getReplacements()).apply(graph);
     
    -            NewFrameNode newFrameNode = graph.getNodes(NewFrameNode.class).first();
    -            if (newFrameNode == null) {
    -                throw GraalInternalError.shouldNotReachHere("frame not found");
    -            }
    -
                 Debug.dump(graph, "Before inlining");
     
                 // Make sure frame does not escape.
    -            expandTree(callTarget, graph, assumptions);
    +            expandTree(graph, assumptions);
     
                 if (Thread.currentThread().isInterrupted()) {
                     return null;
    @@ -123,7 +123,16 @@
                 if (TraceTruffleCompilationHistogram.getValue() && constantReceivers != null) {
                     DebugHistogram histogram = Debug.createHistogram("Expanded Truffle Nodes");
                     for (Constant c : constantReceivers) {
    -                    histogram.add(c.asObject().getClass().getSimpleName());
    +                    String javaName = MetaUtil.toJavaName(providers.getMetaAccess().lookupJavaType(c), false);
    +
    +                    // The DSL uses nested classes with redundant names - only show the inner class
    +                    int index = javaName.indexOf('$');
    +                    if (index != -1) {
    +                        javaName = javaName.substring(index + 1);
    +                    }
    +
    +                    histogram.add(javaName);
    +
                     }
                     new DebugHistogramAsciiPrinter(TTY.out().out()).print(histogram);
                 }
    @@ -166,25 +175,23 @@
             return graph;
         }
     
    -    private void expandTree(OptimizedCallTarget target, StructuredGraph graph, Assumptions assumptions) {
    +    private void expandTree(StructuredGraph graph, Assumptions assumptions) {
             PhaseContext phaseContext = new PhaseContext(providers, assumptions);
             TruffleExpansionLogger expansionLogger = null;
             if (TraceTruffleExpansion.getValue()) {
    -            expansionLogger = new TruffleExpansionLogger(graph);
    +            expansionLogger = new TruffleExpansionLogger(providers, graph);
             }
    -        boolean inliningEnabled = target.getInliningResult() != null && target.getInliningResult().size() > 0;
    -        Map methodTargetToStack = new HashMap<>();
             boolean changed;
             do {
                 changed = false;
                 for (MethodCallTargetNode methodCallTargetNode : graph.getNodes(MethodCallTargetNode.class)) {
                     InvokeKind kind = methodCallTargetNode.invokeKind();
                     try (Indent id1 = Debug.logAndIndent("try inlining %s, kind = %s", methodCallTargetNode.targetMethod(), kind)) {
    -                    if (kind == InvokeKind.Static || (kind == InvokeKind.Special && (methodCallTargetNode.receiver().isConstant() || isFrame(methodCallTargetNode.receiver())))) {
    -                        if (TraceTruffleCompilationHistogram.getValue() && kind == InvokeKind.Special) {
    -                            ConstantNode constantNode = (ConstantNode) methodCallTargetNode.arguments().first();
    -                            constantReceivers.add(constantNode.asConstant());
    +                    if (kind == InvokeKind.Static || kind == InvokeKind.Special) {
    +                        if ((TraceTruffleCompilationHistogram.getValue() || TraceTruffleCompilationDetails.getValue()) && kind == InvokeKind.Special && methodCallTargetNode.receiver().isConstant()) {
    +                            constantReceivers.add(methodCallTargetNode.receiver().asConstant());
                             }
    +
                             Replacements replacements = providers.getReplacements();
                             Class macroSubstitution = replacements.getMacroSubstitution(methodCallTargetNode.targetMethod());
                             if (macroSubstitution != null) {
    @@ -193,41 +200,25 @@
                                 continue;
                             }
     
    -                        if (TraceTruffleCompilationDetails.getValue() && kind == InvokeKind.Special) {
    -                            ConstantNode constantNode = (ConstantNode) methodCallTargetNode.arguments().first();
    -                            constantReceivers.add(constantNode.asConstant());
    -                        }
    -
                             StructuredGraph inlineGraph = replacements.getMethodSubstitution(methodCallTargetNode.targetMethod());
    -                        if (inliningEnabled && inlineGraph == null) {
    -                            inlineGraph = expandInlinableCallNode(target, methodTargetToStack, assumptions, phaseContext, methodCallTargetNode);
    -                        }
    -
    -                        if (inlineGraph == null && !Modifier.isNative(methodCallTargetNode.targetMethod().getModifiers())) {
    +                        if (inlineGraph == null && !methodCallTargetNode.targetMethod().isNative() && methodCallTargetNode.targetMethod().canBeInlined()) {
                                 inlineGraph = parseGraph(methodCallTargetNode.targetMethod(), methodCallTargetNode.arguments(), assumptions, phaseContext, false);
                             }
     
                             if (inlineGraph != null) {
                                 try (Indent indent = Debug.logAndIndent("inline graph %s", methodCallTargetNode.targetMethod())) {
    -                                if (inliningEnabled) {
    -                                    preExpandTruffleCallPath(inlineGraph, methodTargetToStack, methodTargetToStack.get(methodCallTargetNode));
    -                                }
    +
                                     int nodeCountBefore = graph.getNodeCount();
                                     Mark mark = graph.getMark();
                                     if (TraceTruffleExpansion.getValue()) {
                                         expansionLogger.preExpand(methodCallTargetNode, inlineGraph);
                                     }
                                     List invokeUsages = methodCallTargetNode.invoke().asNode().usages().snapshot();
    -                                // try (Indent in2 = Debug.logAndIndent(false, "do inlining")) {
                                     Map inlined = InliningUtil.inline(methodCallTargetNode.invoke(), inlineGraph, false);
                                     if (TraceTruffleExpansion.getValue()) {
                                         expansionLogger.postExpand(inlined);
                                     }
    -                                if (inliningEnabled) {
    -                                    postExpandTruffleCallPath(methodTargetToStack, inlined);
    -                                }
                                     if (Debug.isDumpEnabled()) {
    -                                    Debug.log("dump enabled");
                                         int nodeCountAfter = graph.getNodeCount();
                                         Debug.dump(graph, "After inlining %s %+d (%d)", methodCallTargetNode.targetMethod().toString(), nodeCountAfter - nodeCountBefore, nodeCountAfter);
                                     }
    @@ -250,73 +241,6 @@
             }
         }
     
    -    private static void preExpandTruffleCallPath(StructuredGraph inlineGraph, Map methodTargetToCallPath, TruffleCallPath truffleCallPath) {
    -        for (MethodCallTargetNode methodTargetNode : inlineGraph.getNodes(MethodCallTargetNode.class)) {
    -            methodTargetToCallPath.put(methodTargetNode, truffleCallPath);
    -        }
    -    }
    -
    -    private static void postExpandTruffleCallPath(Map methodCallTargetToCallPath, Map nodeUpdates) {
    -        for (Object key : methodCallTargetToCallPath.keySet().toArray()) {
    -            if (nodeUpdates.containsKey(key)) {
    -                methodCallTargetToCallPath.put(nodeUpdates.get(key), methodCallTargetToCallPath.get(key));
    -                methodCallTargetToCallPath.remove(key);
    -            }
    -        }
    -    }
    -
    -    private StructuredGraph expandInlinableCallNode(OptimizedCallTarget target, Map methodCallToCallPath, Assumptions assumptions, PhaseContext phaseContext,
    -                    MethodCallTargetNode methodCallTargetNode) {
    -
    -        ValueNode receiverNode = methodCallTargetNode.receiver();
    -        if (receiverNode == null || !receiverNode.isConstant() || !receiverNode.asConstant().getKind().isObject()) {
    -            return null;
    -        }
    -
    -        ResolvedJavaMethod method = methodCallTargetNode.targetMethod();
    -        if (!method.getName().equals("call") || method.getSignature().getParameterCount(false) != 1) {
    -            return null;
    -        }
    -
    -        Object receiverValue = receiverNode.asConstant().asObject();
    -        if (receiverValue instanceof OptimizedCallNode) {
    -            OptimizedCallNode callNode = (OptimizedCallNode) receiverValue;
    -            TruffleCallPath callPath = methodCallToCallPath.get(methodCallTargetNode);
    -            if (callPath == null) {
    -                callPath = new TruffleCallPath(target);
    -            }
    -            callPath = new TruffleCallPath(callPath, callNode);
    -            methodCallToCallPath.put(methodCallTargetNode, callPath);
    -            // let the normal expansion do the work
    -            return null;
    -        } else if (receiverValue instanceof OptimizedCallTarget) {
    -            TruffleCallPath path = methodCallToCallPath.get(methodCallTargetNode);
    -            // path unknown. direct call to OptimizedCallTarget without OptimizedCallNode?
    -            if (path == null) {
    -                return null;
    -            }
    -
    -            TruffleInliningResult decision = target.getInliningResult();
    -            if (decision == null) { // no inlining decision. inlining disabled?
    -                return null;
    -            }
    -
    -            if (!decision.isInlined(path)) {
    -                // the OptimizedCallTarget has decided not to inline this call path
    -                return null;
    -            }
    -
    -            // inline truffle call
    -            return parseGraph(methodCallTargetNode.targetMethod(), methodCallTargetNode.arguments(), assumptions, phaseContext, true);
    -        }
    -
    -        return null;
    -    }
    -
    -    private boolean isFrame(ValueNode receiver) {
    -        return receiver instanceof NewFrameNode || Objects.equals(ObjectStamp.typeOrNull(receiver.stamp()), frameType);
    -    }
    -
         private StructuredGraph parseGraph(final ResolvedJavaMethod targetMethod, final NodeInputList arguments, final Assumptions assumptions, final PhaseContext phaseContext,
                         boolean ignoreSlowPath) {
     
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluatorCanonicalizer.java
    --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluatorCanonicalizer.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluatorCanonicalizer.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,10 +22,6 @@
      */
     package com.oracle.graal.truffle;
     
    -import java.lang.reflect.*;
    -
    -import sun.misc.*;
    -
     import com.oracle.graal.api.meta.*;
     import com.oracle.graal.graph.Node;
     import com.oracle.graal.nodes.*;
    @@ -44,14 +40,12 @@
             this.constantReflection = constantReflection;
         }
     
    -    private static final Unsafe unsafe = Unsafe.getUnsafe();
    -
         @Override
         public Node canonicalize(Node node) {
             if (node instanceof LoadFieldNode) {
                 LoadFieldNode loadFieldNode = (LoadFieldNode) node;
                 if (!loadFieldNode.isStatic() && loadFieldNode.object().isConstant() && !loadFieldNode.object().isNullConstant()) {
    -                if (Modifier.isFinal(loadFieldNode.field().getModifiers()) || (loadFieldNode.getKind() == Kind.Object && loadFieldNode.field().getAnnotation(Child.class) != null) ||
    +                if (loadFieldNode.field().isFinal() || (loadFieldNode.getKind() == Kind.Object && loadFieldNode.field().getAnnotation(Child.class) != null) ||
                                     loadFieldNode.field().getAnnotation(CompilerDirectives.CompilationFinal.class) != null) {
                         Constant constant = loadFieldNode.field().readValue(loadFieldNode.object().asConstant());
                         assert verifyFieldValue(loadFieldNode.field(), constant);
    @@ -60,14 +54,11 @@
                 }
             } else if (node instanceof LoadIndexedNode) {
                 LoadIndexedNode loadIndexedNode = (LoadIndexedNode) node;
    -            if (loadIndexedNode.array().isConstant() && !loadIndexedNode.array().isNullConstant() && loadIndexedNode.index().isConstant()) {
    -                Object array = loadIndexedNode.array().asConstant().asObject();
    -                long index = loadIndexedNode.index().asConstant().asLong();
    -                if (index >= 0 && index < Array.getLength(array)) {
    -                    int arrayBaseOffset = unsafe.arrayBaseOffset(array.getClass());
    -                    int arrayIndexScale = unsafe.arrayIndexScale(array.getClass());
    -                    Constant constant = constantReflection.readUnsafeConstant(loadIndexedNode.elementKind(), array, arrayBaseOffset + index * arrayIndexScale,
    -                                    loadIndexedNode.elementKind() == Kind.Object);
    +            if (loadIndexedNode.array().isConstant() && loadIndexedNode.index().isConstant()) {
    +                int index = loadIndexedNode.index().asConstant().asInt();
    +
    +                Constant constant = constantReflection.readArrayElement(loadIndexedNode.array().asConstant(), index);
    +                if (constant != null) {
                         return ConstantNode.forConstant(constant, metaAccess, loadIndexedNode.graph());
                     }
                 }
    @@ -75,9 +66,10 @@
             return node;
         }
     
    -    private static boolean verifyFieldValue(ResolvedJavaField field, Constant constant) {
    -        assert field.getAnnotation(Child.class) == null || constant.isNull() || constant.asObject() instanceof com.oracle.truffle.api.nodes.Node : "@Child field value must be a Node: " + field +
    -                        ", but was: " + constant.asObject();
    +    private boolean verifyFieldValue(ResolvedJavaField field, Constant constant) {
    +        assert field.getAnnotation(Child.class) == null || constant.isNull() ||
    +                        metaAccess.lookupJavaType(com.oracle.truffle.api.nodes.Node.class).isAssignableFrom(metaAccess.lookupJavaType(constant)) : "@Child field value must be a Node: " + field +
    +                        ", but was: " + constant;
             return true;
         }
     }
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TimedCompilationPolicy.java
    --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TimedCompilationPolicy.java	Wed Apr 23 15:22:20 2014 +0200
    +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    @@ -1,51 +0,0 @@
    -/*
    - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
    - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    - *
    - * This code is free software; you can redistribute it and/or modify it
    - * under the terms of the GNU General Public License version 2 only, as
    - * published by the Free Software Foundation.
    - *
    - * This code is distributed in the hope that it will be useful, but WITHOUT
    - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    - * version 2 for more details (a copy is included in the LICENSE file that
    - * accompanied this code).
    - *
    - * You should have received a copy of the GNU General Public License version
    - * 2 along with this work; if not, write to the Free Software Foundation,
    - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    - *
    - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    - * or visit www.oracle.com if you need additional information or have any
    - * questions.
    - */
    -package com.oracle.graal.truffle;
    -
    -import static com.oracle.graal.truffle.TruffleCompilerOptions.*;
    -
    -import java.io.*;
    -
    -public class TimedCompilationPolicy extends DefaultCompilationPolicy {
    -
    -    @Override
    -    public boolean shouldCompile(CompilationProfile profile) {
    -        if (super.shouldCompile(profile)) {
    -            long timestamp = System.nanoTime();
    -            long prevTimestamp = profile.getPreviousTimestamp();
    -            long timespan = (timestamp - prevTimestamp);
    -            if (timespan < (TruffleCompilationDecisionTime.getValue())) {
    -                return true;
    -            }
    -            // TODO shouldCompile should not modify the compilation profile
    -            // maybe introduce another method?
    -            profile.reportTiminingFailed(timestamp);
    -            if (TruffleCompilationDecisionTimePrintFail.getValue()) {
    -                PrintStream out = System.out;
    -                out.println(profile.getName() + ": timespan  " + (timespan / 1000000) + " ms  larger than threshold");
    -            }
    -        }
    -        return false;
    -    }
    -
    -}
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCache.java
    --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCache.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCache.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -31,9 +31,9 @@
     public interface TruffleCache {
     
         /**
    -     * Creates the graph for the root method, i.e. {@link OptimizedCallTarget#executeHelper}.
    +     * Creates the graph for the root method, i.e. {@link OptimizedCallTarget#callBoundary}.
          */
    -    StructuredGraph createRootGraph();
    +    StructuredGraph createRootGraph(String name);
     
         /**
          * Returns a cached graph for a method with given arguments.
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCacheImpl.java
    --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCacheImpl.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCacheImpl.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,9 +22,8 @@
      */
     package com.oracle.graal.truffle;
     
    -import static com.oracle.graal.phases.GraalOptions.*;
    +import static com.oracle.graal.compiler.common.GraalOptions.*;
     
    -import java.lang.reflect.*;
     import java.util.*;
     import java.util.Map.Entry;
     
    @@ -65,7 +64,7 @@
         private final HashMap, Long> lastUsed = new HashMap<>();
         private final StructuredGraph markerGraph = new StructuredGraph();
         private final ResolvedJavaType stringBuilderClass;
    -    private final ResolvedJavaMethod executeHelperMethod;
    +    private final ResolvedJavaMethod callBoundaryMethod;
         private long counter;
     
         public TruffleCacheImpl(Providers providers, GraphBuilderConfiguration config, GraphBuilderConfiguration configForRootGraph, OptimisticOptimizations optimisticOptimizations) {
    @@ -75,14 +74,14 @@
             this.optimisticOptimizations = optimisticOptimizations;
             this.stringBuilderClass = providers.getMetaAccess().lookupJavaType(StringBuilder.class);
             try {
    -            executeHelperMethod = providers.getMetaAccess().lookupJavaMethod(OptimizedCallTarget.class.getDeclaredMethod("executeHelper", Object[].class));
    +            callBoundaryMethod = providers.getMetaAccess().lookupJavaMethod(OptimizedCallTarget.class.getDeclaredMethod("callRoot", Object[].class));
             } catch (NoSuchMethodException ex) {
                 throw new RuntimeException(ex);
             }
         }
     
    -    public StructuredGraph createRootGraph() {
    -        StructuredGraph graph = new StructuredGraph(executeHelperMethod);
    +    public StructuredGraph createRootGraph(String name) {
    +        StructuredGraph graph = new StructuredGraph(name, callBoundaryMethod);
             new GraphBuilderPhase.Instance(providers.getMetaAccess(), configForRootGraph, TruffleCompilerImpl.Optimizations).apply(graph);
             return graph;
         }
    @@ -251,7 +250,7 @@
             if (methodCallTargetNode.targetMethod().isConstructor()) {
                 ResolvedJavaType runtimeException = providers.getMetaAccess().lookupJavaType(RuntimeException.class);
                 ResolvedJavaType controlFlowException = providers.getMetaAccess().lookupJavaType(ControlFlowException.class);
    -            ResolvedJavaType exceptionType = Objects.requireNonNull(ObjectStamp.typeOrNull(methodCallTargetNode.receiver().stamp()));
    +            ResolvedJavaType exceptionType = Objects.requireNonNull(StampTool.typeOrNull(methodCallTargetNode.receiver().stamp()));
                 if (runtimeException.isAssignableFrom(methodCallTargetNode.targetMethod().getDeclaringClass()) && !controlFlowException.isAssignableFrom(exceptionType)) {
                     DeoptimizeNode deoptNode = methodCallTargetNode.graph().add(new DeoptimizeNode(DeoptimizationAction.InvalidateRecompile, DeoptimizationReason.UnreachedCode));
                     FixedNode invokeNode = methodCallTargetNode.invoke().asNode();
    @@ -264,9 +263,10 @@
         }
     
         private boolean shouldInline(final MethodCallTargetNode methodCallTargetNode) {
    -        return (methodCallTargetNode.invokeKind() == InvokeKind.Special || methodCallTargetNode.invokeKind() == InvokeKind.Static) &&
    -                        !Modifier.isNative(methodCallTargetNode.targetMethod().getModifiers()) && methodCallTargetNode.targetMethod().getAnnotation(ExplodeLoop.class) == null &&
    +        boolean result = (methodCallTargetNode.invokeKind() == InvokeKind.Special || methodCallTargetNode.invokeKind() == InvokeKind.Static) && methodCallTargetNode.targetMethod().canBeInlined() &&
    +                        !methodCallTargetNode.targetMethod().isNative() && methodCallTargetNode.targetMethod().getAnnotation(ExplodeLoop.class) == null &&
                             methodCallTargetNode.targetMethod().getAnnotation(CompilerDirectives.SlowPath.class) == null &&
                             !methodCallTargetNode.targetMethod().getDeclaringClass().equals(stringBuilderClass);
    +        return result;
         }
     }
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCallBoundary.java
    --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCallBoundary.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -0,0 +1,31 @@
    +/*
    + * Copyright (c) 2014, 2014, Oracle and/or its affiliates. All rights reserved.
    + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    + *
    + * This code is free software; you can redistribute it and/or modify it
    + * under the terms of the GNU General Public License version 2 only, as
    + * published by the Free Software Foundation.
    + *
    + * This code is distributed in the hope that it will be useful, but WITHOUT
    + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    + * version 2 for more details (a copy is included in the LICENSE file that
    + * accompanied this code).
    + *
    + * You should have received a copy of the GNU General Public License version
    + * 2 along with this work; if not, write to the Free Software Foundation,
    + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    + *
    + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    + * or visit www.oracle.com if you need additional information or have any
    + * questions.
    + */
    +package com.oracle.graal.truffle;
    +
    +import java.lang.annotation.*;
    +
    +@Retention(RetentionPolicy.RUNTIME)
    +@Target(ElementType.METHOD)
    +public @interface TruffleCallBoundary {
    +
    +}
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCallPath.java
    --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCallPath.java	Wed Apr 23 15:22:20 2014 +0200
    +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    @@ -1,219 +0,0 @@
    -/*
    - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
    - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    - *
    - * This code is free software; you can redistribute it and/or modify it
    - * under the terms of the GNU General Public License version 2 only, as
    - * published by the Free Software Foundation.
    - *
    - * This code is distributed in the hope that it will be useful, but WITHOUT
    - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    - * version 2 for more details (a copy is included in the LICENSE file that
    - * accompanied this code).
    - *
    - * You should have received a copy of the GNU General Public License version
    - * 2 along with this work; if not, write to the Free Software Foundation,
    - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    - *
    - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    - * or visit www.oracle.com if you need additional information or have any
    - * questions.
    - */
    -package com.oracle.graal.truffle;
    -
    -import java.util.*;
    -
    -import com.oracle.truffle.api.*;
    -
    -public final class TruffleCallPath implements Iterable, Comparable {
    -
    -    private final OptimizedCallNode callNode;
    -    private final TruffleCallPath parent;
    -    private final OptimizedCallTarget rootCallTarget;
    -
    -    public TruffleCallPath(OptimizedCallTarget parent) {
    -        this.rootCallTarget = Objects.requireNonNull(parent);
    -        this.callNode = null;
    -        this.parent = null;
    -    }
    -
    -    public TruffleCallPath(TruffleCallPath parent, OptimizedCallNode node) {
    -        this.parent = Objects.requireNonNull(parent);
    -        assert !parent.containsPath(this) : "cyclic path detected";
    -        this.callNode = Objects.requireNonNull(node);
    -        this.rootCallTarget = parent.getRootCallTarget();
    -    }
    -
    -    public boolean isRoot() {
    -        return parent == null && rootCallTarget != null;
    -    }
    -
    -    private boolean containsPath(TruffleCallPath p) {
    -        return p == this || (getParent() != null && this.getParent().containsPath(p));
    -    }
    -
    -    public OptimizedCallTarget getRootCallTarget() {
    -        return rootCallTarget;
    -    }
    -
    -    @Override
    -    public String toString() {
    -        return (parent != null ? (parent.toString() + " -> ") : "") + getCallTarget().toString();
    -    }
    -
    -    public Iterator iterator() {
    -        return toList().iterator();
    -    }
    -
    -    public OptimizedCallTarget getCallTarget() {
    -        return parent == null ? rootCallTarget : callNode.getCurrentCallTarget();
    -    }
    -
    -    public List toList() {
    -        List list = new ArrayList<>();
    -        toListImpl(list);
    -        return list;
    -    }
    -
    -    private void toListImpl(List list) {
    -        if (parent != null) {
    -            parent.toListImpl(list);
    -        }
    -        list.add(this);
    -    }
    -
    -    public TruffleCallPath getParent() {
    -        return parent;
    -    }
    -
    -    public OptimizedCallNode getCallNode() {
    -        return callNode;
    -    }
    -
    -    public int getDepth() {
    -        return parent == null ? 0 : (parent.getDepth() + 1);
    -    }
    -
    -    public int compareTo(TruffleCallPath o) {
    -        return Objects.compare(this, o, new PathComparator());
    -    }
    -
    -    private static class PathComparator implements Comparator {
    -        public int compare(TruffleCallPath c1, TruffleCallPath c2) {
    -            if (c1 == c2) {
    -                return 0;
    -            }
    -
    -            Iterator p1 = c1.toList().iterator();
    -            Iterator p2 = c2.toList().iterator();
    -
    -            int cmp = 0;
    -            while (cmp == 0 && (p1.hasNext() || p2.hasNext())) {
    -                TruffleCallPath o1;
    -                TruffleCallPath o2;
    -                if (p1.hasNext()) {
    -                    o1 = p1.next();
    -                } else {
    -                    return -1;
    -                }
    -                if (p2.hasNext()) {
    -                    o2 = p2.next();
    -                } else {
    -                    return 1;
    -                }
    -
    -                if (o1 == o2) {
    -                    continue;
    -                }
    -
    -                SourceSection s1;
    -                if (o1.callNode != null) {
    -                    s1 = o1.callNode.getEncapsulatingSourceSection();
    -                } else {
    -                    s1 = o1.getCallTarget().getRootNode().getSourceSection();
    -                }
    -
    -                SourceSection s2;
    -                if (o2.callNode != null) {
    -                    s2 = o2.callNode.getEncapsulatingSourceSection();
    -                } else {
    -                    s2 = o2.getCallTarget().getRootNode().getSourceSection();
    -                }
    -                cmp = compareSourceSection(s2, s1);
    -
    -                if (cmp == 0) {
    -                    cmp = o1.getCallTarget().toString().compareTo(o2.getCallTarget().toString());
    -                }
    -            }
    -            return cmp;
    -        }
    -    }
    -
    -    private static int compareSourceSection(SourceSection s1, SourceSection s2) {
    -        return Objects.compare(s1, s2, new Comparator() {
    -            public int compare(SourceSection o1, SourceSection o2) {
    -                if (o1 == o2) {
    -                    return 0;
    -                }
    -                if (o1 == null || o2 == null) {
    -                    return 0;
    -                }
    -                int cmp = 0;
    -                if (o1.getSource() != null && o2.getSource() != null && !Objects.equals(o1.getSource().getName(), o2.getSource().getName())) {
    -                    cmp = o2.getSource().getName().compareTo(o1.getSource().getName());
    -                }
    -                if (cmp == 0) {
    -                    cmp = o2.getStartLine() - o1.getStartLine();
    -                }
    -                if (cmp == 0) {
    -                    cmp = o2.getStartColumn() - o1.getStartColumn();
    -                }
    -                return cmp;
    -            }
    -        });
    -    }
    -
    -    @Override
    -    public int hashCode() {
    -        final int prime = 31;
    -        int result = 1;
    -        result = prime * result + ((callNode == null) ? 0 : callNode.hashCode());
    -        result = prime * result + ((parent == null) ? 0 : parent.hashCode());
    -        result = prime * result + ((rootCallTarget == null) ? 0 : rootCallTarget.hashCode());
    -        return result;
    -    }
    -
    -    @Override
    -    public boolean equals(Object obj) {
    -        if (obj instanceof TruffleCallPath) {
    -            TruffleCallPath other = (TruffleCallPath) obj;
    -            if (other.callNode != callNode) {
    -                return false;
    -            }
    -            if (!Objects.equals(other.parent, parent)) {
    -                return false;
    -            }
    -            if (!Objects.equals(other.rootCallTarget, rootCallTarget)) {
    -                return false;
    -            }
    -            return true;
    -        }
    -        return false;
    -    }
    -
    -    public TruffleCallPath append(TruffleCallPath path) {
    -        if (getCallTarget() != path.getRootCallTarget()) {
    -            throw new IllegalArgumentException("Pathes are not compatible and can therfore not be appended.");
    -        }
    -
    -        TruffleCallPath append = this;
    -        for (TruffleCallPath childPath : path) {
    -            if (!childPath.isRoot()) {
    -                append = new TruffleCallPath(append, childPath.getCallNode());
    -            }
    -        }
    -        return append;
    -    }
    -
    -}
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompiler.java
    --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompiler.java	Wed Apr 23 15:22:20 2014 +0200
    +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    @@ -1,36 +0,0 @@
    -/*
    - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
    - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    - *
    - * This code is free software; you can redistribute it and/or modify it
    - * under the terms of the GNU General Public License version 2 only, as
    - * published by the Free Software Foundation.
    - *
    - * This code is distributed in the hope that it will be useful, but WITHOUT
    - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    - * version 2 for more details (a copy is included in the LICENSE file that
    - * accompanied this code).
    - *
    - * You should have received a copy of the GNU General Public License version
    - * 2 along with this work; if not, write to the Free Software Foundation,
    - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    - *
    - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    - * or visit www.oracle.com if you need additional information or have any
    - * questions.
    - */
    -package com.oracle.graal.truffle;
    -
    -import java.util.concurrent.*;
    -
    -import com.oracle.graal.api.code.*;
    -
    -/**
    - * Interface of the Truffle compiler producing an {@link InstalledCode} object from the partial
    - * evaluation starting with the AST represented by the given {@link OptimizedCallTarget} node.
    - */
    -public interface TruffleCompiler {
    -
    -    Future compile(OptimizedCallTarget node);
    -}
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java
    --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -27,14 +27,12 @@
     import static com.oracle.graal.truffle.TruffleCompilerOptions.*;
     
     import java.util.*;
    -import java.util.concurrent.*;
     
     import com.oracle.graal.api.code.*;
     import com.oracle.graal.api.code.Assumptions.Assumption;
     import com.oracle.graal.api.code.CallingConvention.Type;
     import com.oracle.graal.api.meta.*;
     import com.oracle.graal.api.runtime.*;
    -import com.oracle.graal.compiler.*;
     import com.oracle.graal.compiler.target.*;
     import com.oracle.graal.debug.*;
     import com.oracle.graal.debug.Debug.Scope;
    @@ -55,7 +53,7 @@
     /**
      * Implementation of the Truffle compiler using Graal.
      */
    -public class TruffleCompilerImpl implements TruffleCompiler {
    +public class TruffleCompilerImpl {
     
         private final Providers providers;
         private final Suites suites;
    @@ -64,9 +62,8 @@
         private final GraphBuilderConfiguration config;
         private final RuntimeProvider runtime;
         private final TruffleCache truffleCache;
    -    private final ThreadPoolExecutor compileQueue;
     
    -    private static final Class[] SKIPPED_EXCEPTION_CLASSES = new Class[]{UnexpectedResultException.class, SlowPathException.class, ArithmeticException.class};
    +    private static final Class[] SKIPPED_EXCEPTION_CLASSES = new Class[]{UnexpectedResultException.class, SlowPathException.class, ArithmeticException.class};
     
         public static final OptimisticOptimizations Optimizations = OptimisticOptimizations.ALL.remove(OptimisticOptimizations.Optimization.UseExceptionProbability,
                         OptimisticOptimizations.Optimization.RemoveNeverExecutedCode, OptimisticOptimizations.Optimization.UseTypeCheckedInlining, OptimisticOptimizations.Optimization.UseTypeCheckHints);
    @@ -78,20 +75,6 @@
             this.providers = backend.getProviders().copyWith(truffleReplacements);
             this.suites = backend.getSuites().getDefaultSuites();
     
    -        // Create compilation queue.
    -        CompilerThreadFactory factory = new CompilerThreadFactory("TruffleCompilerThread", new CompilerThreadFactory.DebugConfigAccess() {
    -            public GraalDebugConfig getDebugConfig() {
    -                if (Debug.isEnabled()) {
    -                    GraalDebugConfig debugConfig = DebugEnvironment.initialize(TTY.out().out());
    -                    debugConfig.dumpHandlers().add(new TruffleTreeDumpHandler());
    -                    return debugConfig;
    -                } else {
    -                    return null;
    -                }
    -            }
    -        });
    -        compileQueue = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue(), factory);
    -
             ResolvedJavaType[] skippedExceptionTypes = getSkippedExceptionTypes(providers.getMetaAccess());
             GraphBuilderConfiguration eagerConfig = GraphBuilderConfiguration.getEagerDefault();
             eagerConfig.setSkippedExceptionTypes(skippedExceptionTypes);
    @@ -115,28 +98,15 @@
             return skippedExceptionTypes;
         }
     
    -    public Future compile(final OptimizedCallTarget compilable) {
    -        return compileQueue.submit(new Callable() {
    -            @Override
    -            public InstalledCode call() throws Exception {
    -                try (Scope s = Debug.scope("Truffle", new TruffleDebugJavaMethod(compilable))) {
    -                    return compileMethodImpl((OptimizedCallTargetImpl) compilable);
    -                } catch (Throwable e) {
    -                    throw Debug.handle(e);
    -                }
    -            }
    -        });
    -    }
    -
         public static final DebugTimer PartialEvaluationTime = Debug.timer("PartialEvaluationTime");
         public static final DebugTimer CompilationTime = Debug.timer("CompilationTime");
         public static final DebugTimer CodeInstallationTime = Debug.timer("CodeInstallation");
     
    -    private InstalledCode compileMethodImpl(final OptimizedCallTargetImpl compilable) {
    +    public void compileMethodImpl(final OptimizedCallTarget compilable) {
             final StructuredGraph graph;
     
             if (TraceTruffleCompilation.getValue()) {
    -            OptimizedCallTargetImpl.logOptimizingStart(compilable);
    +            OptimizedCallTargetLog.logOptimizingStart(compilable);
             }
     
             long timeCompilationStarted = System.nanoTime();
    @@ -146,49 +116,39 @@
             }
     
             if (Thread.currentThread().isInterrupted()) {
    -            return null;
    +            return;
             }
     
             long timePartialEvaluationFinished = System.nanoTime();
             int nodeCountPartialEval = graph.getNodeCount();
    -        InstalledCode compiledMethod = compileMethodHelper(graph, assumptions, compilable.toString(), compilable.getSpeculationLog());
    +        CompilationResult compilationResult = compileMethodHelper(graph, assumptions, compilable.toString(), compilable.getSpeculationLog(), compilable);
             long timeCompilationFinished = System.nanoTime();
             int nodeCountLowered = graph.getNodeCount();
     
    -        if (compiledMethod == null) {
    -            throw new BailoutException("Could not install method, code cache is full!");
    -        }
    -
    -        if (!compiledMethod.isValid()) {
    -            return null;
    -        }
    -
             if (TraceTruffleCompilation.getValue()) {
    -            byte[] code = compiledMethod.getCode();
    -            int calls = OptimizedCallUtils.countCalls(compilable.getInliningResult(), new TruffleCallPath(compilable));
    -            int inlinedCalls = (compilable.getInliningResult() != null ? compilable.getInliningResult().size() : 0);
    +            int calls = OptimizedCallUtils.countCalls(compilable);
    +            int inlinedCalls = OptimizedCallUtils.countCallsInlined(compilable);
                 int dispatchedCalls = calls - inlinedCalls;
                 Map properties = new LinkedHashMap<>();
    -            OptimizedCallTarget.addASTSizeProperty(compilable.getInliningResult(), new TruffleCallPath(compilable), properties);
    +            OptimizedCallTargetLog.addASTSizeProperty(compilable, properties);
                 properties.put("Time", String.format("%5.0f(%4.0f+%-4.0f)ms", //
                                 (timeCompilationFinished - timeCompilationStarted) / 1e6, //
                                 (timePartialEvaluationFinished - timeCompilationStarted) / 1e6, //
                                 (timeCompilationFinished - timePartialEvaluationFinished) / 1e6));
                 properties.put("CallNodes", String.format("I %5d/D %5d", inlinedCalls, dispatchedCalls));
                 properties.put("GraalNodes", String.format("%5d/%5d", nodeCountPartialEval, nodeCountLowered));
    -            properties.put("CodeSize", code != null ? code.length : 0);
    +            properties.put("CodeSize", compilationResult.getTargetCodeSize());
                 properties.put("Source", formatSourceSection(compilable.getRootNode().getSourceSection()));
     
    -            OptimizedCallTargetImpl.logOptimizingDone(compilable, properties);
    +            OptimizedCallTargetLog.logOptimizingDone(compilable, properties);
             }
    -        return compiledMethod;
         }
     
         private static String formatSourceSection(SourceSection sourceSection) {
             return sourceSection != null ? sourceSection.toString() : "n/a";
         }
     
    -    public InstalledCode compileMethodHelper(StructuredGraph graph, Assumptions assumptions, String name, SpeculationLog speculationLog) {
    +    public CompilationResult compileMethodHelper(StructuredGraph graph, Assumptions assumptions, String name, SpeculationLog speculationLog, InstalledCode predefinedInstalledCode) {
             try (Scope s = Debug.scope("TruffleFinal")) {
                 Debug.dump(graph, "After TruffleTier");
             } catch (Throwable e) {
    @@ -224,7 +184,7 @@
     
             InstalledCode installedCode;
             try (Scope s = Debug.scope("CodeInstall", providers.getCodeCache()); TimerCloseable a = CodeInstallationTime.start()) {
    -            installedCode = providers.getCodeCache().addMethod(graph.method(), result, speculationLog);
    +            installedCode = providers.getCodeCache().addMethod(graph.method(), result, speculationLog, predefinedInstalledCode);
             } catch (Throwable e) {
                 throw Debug.handle(e);
             }
    @@ -236,7 +196,7 @@
             if (Debug.isLogEnabled()) {
                 Debug.log(providers.getCodeCache().disassemble(result, installedCode));
             }
    -        return installedCode;
    +        return result;
         }
     
         private PhaseSuite createGraphBuilderSuite() {
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerOptions.java
    --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerOptions.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerOptions.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -72,15 +72,15 @@
         @Option(help = "Enable asynchronous truffle compilation in background thread")
         public static final OptionValue TruffleBackgroundCompilation = new OptionValue<>(true);
         @Option(help = "")
    -    public static final OptionValue TruffleUseTimeForCompilationDecision = new OptionValue<>(false);
    -    @Option(help = "")
         public static final OptionValue TruffleCompilationDecisionTime = new OptionValue<>(100);
         @Option(help = "")
         public static final OptionValue TruffleCompilationDecisionTimePrintFail = new OptionValue<>(false);
    +    @Option(help = "")
    +    public static final OptionValue TruffleReturnTypeSpeculation = new OptionValue<>(true);
     
         // tracing
         @Option(help = "")
    -    public static final OptionValue TraceTruffleCompilation = new OptionValue<>(true);
    +    public static final OptionValue TraceTruffleCompilation = new OptionValue<>(false);
         @Option(help = "")
         public static final OptionValue TraceTruffleCompilationDetails = new OptionValue<>(false);
         @Option(help = "")
    @@ -94,9 +94,7 @@
         @Option(help = "")
         public static final OptionValue TraceTruffleCacheDetails = new OptionValue<>(false);
         @Option(help = "")
    -    public static final OptionValue TraceTruffleCompilationExceptions = new OptionValue<>(true);
    -    @Option(help = "")
    -    public static final OptionValue TruffleCompilationExceptionsAreFatal = new OptionValue<>(true);
    +    public static final OptionValue TruffleCompilationExceptionsAreFatal = new OptionValue<>(false);
         @Option(help = "")
         public static final OptionValue TraceTruffleInlining = new OptionValue<>(false);
         @Option(help = "")
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleExpansionLogger.java
    --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleExpansionLogger.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleExpansionLogger.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,7 +23,6 @@
     package com.oracle.graal.truffle;
     
     import java.io.*;
    -import java.lang.reflect.*;
     import java.util.*;
     import java.util.Map.Entry;
     
    @@ -31,13 +30,16 @@
     import com.oracle.graal.graph.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.java.*;
    +import com.oracle.graal.phases.util.*;
     
     public class TruffleExpansionLogger {
     
    +    private final Providers providers;
         private final ExpansionTree root;
         private final Map callToParentTree = new HashMap<>();
     
    -    public TruffleExpansionLogger(StructuredGraph graph) {
    +    public TruffleExpansionLogger(Providers providers, StructuredGraph graph) {
    +        this.providers = providers;
             root = new ExpansionTree(null, null, graph.method(), -1);
             registerParentInCalls(root, graph);
         }
    @@ -47,16 +49,16 @@
     
             int sourceMethodBci = callTarget.invoke().bci();
             ResolvedJavaMethod targetMethod = callTarget.targetMethod();
    -        Object targetReceiver = null;
    -        if (!Modifier.isStatic(sourceMethod.getModifiers()) && callTarget.receiver().isConstant()) {
    -            targetReceiver = callTarget.receiver().asConstant().asObject();
    +        ResolvedJavaType targetReceiverType = null;
    +        if (!sourceMethod.isStatic() && callTarget.receiver().isConstant()) {
    +            targetReceiverType = providers.getMetaAccess().lookupJavaType(callTarget.arguments().first().asConstant());
             }
     
    -        if (targetReceiver != null) {
    +        if (targetReceiverType != null) {
                 ExpansionTree parent = callToParentTree.get(callTarget);
                 assert parent != null;
                 callToParentTree.remove(callTarget);
    -            ExpansionTree tree = new ExpansionTree(parent, targetReceiver, targetMethod, sourceMethodBci);
    +            ExpansionTree tree = new ExpansionTree(parent, targetReceiverType, targetMethod, sourceMethodBci);
                 registerParentInCalls(tree, inliningGraph);
             }
         }
    @@ -94,14 +96,14 @@
         private static final class ExpansionTree implements Comparable {
     
             private final ExpansionTree parent;
    -        private final Object targetReceiver;
    +        private final ResolvedJavaType targetReceiverType;
             private final ResolvedJavaMethod targetMethod;
             private final int parentBci;
             private final List children = new ArrayList<>();
     
    -        public ExpansionTree(ExpansionTree parent, Object receiver, ResolvedJavaMethod targetMethod, int parentBci) {
    +        public ExpansionTree(ExpansionTree parent, ResolvedJavaType targetReceiverType, ResolvedJavaMethod targetMethod, int parentBci) {
                 this.parent = parent;
    -            this.targetReceiver = receiver;
    +            this.targetReceiverType = targetReceiverType;
                 this.targetMethod = targetMethod;
                 this.parentBci = parentBci;
                 if (parent != null) {
    @@ -141,9 +143,9 @@
                 }
     
                 String constantType = "";
    -            if (targetReceiver != null) {
    -                if (!targetReceiver.getClass().getSimpleName().equals(className)) {
    -                    constantType = "<" + targetReceiver.getClass().getSimpleName() + ">";
    +            if (targetReceiverType != null) {
    +                if (!targetReceiverType.getName().equals(className)) {
    +                    constantType = "<" + targetReceiverType.getName() + ">";
                     }
                 }
     
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleInliningHandler.java
    --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleInliningHandler.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleInliningHandler.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -24,164 +24,103 @@
     
     import java.util.*;
     
    -import com.oracle.graal.truffle.OptimizedCallUtils.InlinedCallVisitor;
     import com.oracle.truffle.api.nodes.*;
     
     public final class TruffleInliningHandler {
     
    -    private final ProfileScoreComparator inliningOrder = new ProfileScoreComparator();
    -
    -    private final OptimizedCallTarget callTarget;
    +    private static final int MAXIMUM_RECURSIVE_DEPTH = 15;
    +    private static final ProfileScoreComparator INLINING_SCORE = new ProfileScoreComparator();
         private final TruffleInliningPolicy policy;
    -    private final Map profiles;
    -    private final Map inliningResultCache;
    +    private final Map resultCache;
     
    -    public TruffleInliningHandler(OptimizedCallTarget callTarget, TruffleInliningPolicy policy, Map inliningResultCache) {
    -        this.callTarget = callTarget;
    +    public TruffleInliningHandler(TruffleInliningPolicy policy) {
             this.policy = policy;
    -        this.profiles = new HashMap<>();
    -        this.inliningResultCache = inliningResultCache;
    +        this.resultCache = new HashMap<>();
         }
     
    -    public TruffleInliningResult inline(int originalTotalNodeCount) {
    -        Set inlinedPathes = new HashSet<>();
    -        TruffleInliningResult result = new TruffleInliningResult(callTarget, inlinedPathes);
    -        TruffleCallPath startPath = new TruffleCallPath(callTarget);
    -
    -        PriorityQueue queue = new PriorityQueue<>(10, inliningOrder);
    -        queueCallSitesForInlining(result, startPath, queue);
    -
    -        int budget = TruffleCompilerOptions.TruffleInliningMaxCallerSize.getValue() - originalTotalNodeCount;
    -        int index = 0;
    -        while (!queue.isEmpty()) {
    -            TruffleInliningProfile profile = queue.poll();
    -            profile.setQueryIndex(index);
    -            budget = tryInline(queue, result, inlinedPathes, profile, budget);
    -            profiles.put(profile.getCallPath(), profile);
    -            index++;
    +    public TruffleInliningResult decideInlining(OptimizedCallTarget target, int depth) {
    +        if (resultCache.containsKey(target)) {
    +            return resultCache.get(target);
             }
    +        resultCache.put(target, null);
    +        TruffleInliningResult result = decideInliningImpl(target, depth);
    +        resultCache.put(target, result);
             return result;
         }
     
    -    private int tryInline(PriorityQueue queue, TruffleInliningResult result, Set inlinedPathes, TruffleInliningProfile profile, int budget) {
    -
    -        if (policy.isAllowed(result, profile, budget)) {
    -            int remainingBudget;
    -            inlinedPathes.add(profile.getCallPath());
    -            if (policy.isAllowedDeep(result, profile, budget)) {
    -                if (profile.getRecursiveResult() != null) {
    -                    TruffleInliningResult inliningResult = profile.getRecursiveResult();
    -                    for (TruffleCallPath recursiveInlinedPath : inliningResult) {
    -                        inlinedPathes.add(profile.getCallPath().append(recursiveInlinedPath));
    -                    }
    -                }
    -                remainingBudget = budget - profile.getDeepNodeCount();
    -            } else {
    -                remainingBudget = budget - profile.getNodeCount();
    +    private TruffleInliningResult decideInliningImpl(OptimizedCallTarget target, int depth) {
    +        List profiles = lookupProfiles(target, depth);
    +        Set inlined = new HashSet<>();
    +        Collections.sort(profiles, INLINING_SCORE);
    +        int budget = TruffleCompilerOptions.TruffleInliningMaxCallerSize.getValue() - OptimizedCallUtils.countNonTrivialNodes(target, true);
    +        int index = 0;
    +        for (TruffleInliningProfile profile : profiles) {
    +            profile.setQueryIndex(index++);
    +            if (policy.isAllowed(profile, budget)) {
    +                inlined.add(profile);
    +                budget -= profile.getDeepNodeCount();
                 }
    -
    -            queueCallSitesForInlining(result, profile.getCallPath(), queue);
    -            return remainingBudget;
             }
     
    -        return budget;
    +        int deepNodeCount = TruffleCompilerOptions.TruffleInliningMaxCallerSize.getValue() - budget;
    +        return new TruffleInliningResult(target, profiles, inlined, deepNodeCount);
    +    }
    +
    +    private List lookupProfiles(final OptimizedCallTarget target, int depth) {
    +        final List callNodes = new ArrayList<>();
    +        target.getRootNode().accept(new NodeVisitor() {
    +            public boolean visit(Node node) {
    +                if (node instanceof OptimizedDirectCallNode) {
    +                    callNodes.add((OptimizedDirectCallNode) node);
    +                }
    +                return true;
    +            }
    +        });
    +        final List profiles = new ArrayList<>();
    +        for (OptimizedDirectCallNode callNode : callNodes) {
    +            profiles.add(lookupProfile(target, callNode, depth));
    +        }
    +        return profiles;
    +    }
    +
    +    public TruffleInliningProfile lookupProfile(OptimizedCallTarget parentTarget, OptimizedDirectCallNode ocn, int depth) {
    +        OptimizedCallTarget target = ocn.getCurrentCallTarget();
    +
    +        int callSites = ocn.getCurrentCallTarget().getKnownCallSiteCount();
    +        int nodeCount = OptimizedCallUtils.countNonTrivialNodes(target, false);
    +        double frequency = calculateFrequency(parentTarget, ocn);
    +        boolean forced = ocn.isInliningForced();
    +
    +        int deepNodeCount;
    +        TruffleInliningResult recursiveResult;
    +        boolean recursiveCall = false;
    +        if (depth > MAXIMUM_RECURSIVE_DEPTH) {
    +            deepNodeCount = OptimizedCallUtils.countNonTrivialNodes(target, true);
    +            recursiveResult = null;
    +        } else {
    +            recursiveResult = decideInlining(ocn.getCurrentCallTarget(), depth + 1);
    +            if (recursiveResult == null) {
    +                recursiveCall = true;
    +                deepNodeCount = Integer.MAX_VALUE;
    +            } else {
    +                deepNodeCount = recursiveResult.getNodeCount();
    +            }
    +        }
    +
    +        TruffleInliningProfile profile = new TruffleInliningProfile(ocn, callSites, nodeCount, deepNodeCount, frequency, forced, recursiveCall, recursiveResult);
    +        profile.setScore(policy.calculateScore(profile));
    +        return profile;
         }
     
         public TruffleInliningPolicy getPolicy() {
             return policy;
         }
     
    -    public Map getProfiles() {
    -        return profiles;
    -    }
    -
    -    private void queueCallSitesForInlining(final TruffleInliningResult currentDecision, TruffleCallPath fromPath, final Collection queue) {
    -        fromPath.getCallTarget().getRootNode().accept(new InlinedCallVisitor(currentDecision, fromPath) {
    -            @Override
    -            public boolean visit(TruffleCallPath path, Node node) {
    -                if (node instanceof OptimizedCallNode) {
    -                    if (!currentDecision.isInlined(path)) {
    -                        addToQueue(queue, currentDecision, path);
    -                    }
    -                }
    -                return true;
    -            }
    -        });
    -    }
    -
    -    private void addToQueue(final Collection queue, final TruffleInliningResult currentDecision, TruffleCallPath path) {
    -        queue.add(lookupProfile(currentDecision, path));
    -    }
    -
    -    public List lookupProfiles(final TruffleInliningResult currentDecision, TruffleCallPath fromPath) {
    -        final List pathes = new ArrayList<>();
    -        fromPath.getCallTarget().getRootNode().accept(new InlinedCallVisitor(currentDecision, fromPath) {
    -            @Override
    -            public boolean visit(TruffleCallPath path, Node node) {
    -                if (node instanceof OptimizedCallNode) {
    -                    pathes.add(lookupProfile(currentDecision, path));
    -                }
    -                return true;
    -            }
    -        });
    -        return pathes;
    +    private static double calculateFrequency(OptimizedCallTarget target, OptimizedDirectCallNode ocn) {
    +        return (double) Math.max(1, ocn.getCallCount()) / (double) Math.max(1, target.getCompilationProfile().getCallCount());
         }
     
    -    public TruffleInliningProfile lookupProfile(TruffleInliningResult state, TruffleCallPath callPath) {
    -        TruffleInliningProfile profile = profiles.get(callPath);
    -        if (profile != null) {
    -            return profile;
    -        }
    -
    -        int callSites = callPath.getCallTarget().getKnownCallSiteCount();
    -        int nodeCount = OptimizedCallUtils.countNonTrivialNodes(state, callPath);
    -        double frequency = calculatePathFrequency(callPath);
    -        boolean forced = callPath.getCallNode().isInlined();
    -        TruffleInliningResult recursiveResult = lookupChildResult(callPath, nodeCount);
    -        int deepNodeCount = OptimizedCallUtils.countNonTrivialNodes(recursiveResult, new TruffleCallPath(callPath.getCallTarget()));
    -
    -        profile = new TruffleInliningProfile(callPath, callSites, nodeCount, deepNodeCount, frequency, forced, recursiveResult);
    -        profile.setScore(policy.calculateScore(profile));
    -        profiles.put(callPath, profile);
    -
    -        return profile;
    -    }
    -
    -    private TruffleInliningResult lookupChildResult(TruffleCallPath callPath, int nodeCount) {
    -        OptimizedCallTarget target = callPath.getCallTarget();
    -
    -        TruffleInliningResult recursiveResult = target.getInliningResult();
    -
    -        if (recursiveResult == null) {
    -            recursiveResult = inliningResultCache.get(callPath.getCallTarget());
    -
    -            if (recursiveResult == null) {
    -                if (inliningResultCache.containsKey(target)) {
    -                    // cancel on recursion
    -                    return new TruffleInliningResult(target, new HashSet());
    -                }
    -                inliningResultCache.put(target, null);
    -                TruffleInliningHandler handler = new TruffleInliningHandler(target, policy, inliningResultCache);
    -                recursiveResult = handler.inline(nodeCount);
    -                inliningResultCache.put(callPath.getCallTarget(), recursiveResult);
    -            }
    -        }
    -        return recursiveResult;
    -    }
    -
    -    private static double calculatePathFrequency(TruffleCallPath callPath) {
    -        int parentCallCount = -1;
    -        double f = 1.0d;
    -        for (TruffleCallPath path : callPath.toList()) {
    -            if (parentCallCount != -1) {
    -                f *= path.getCallNode().getCallCount() / (double) parentCallCount;
    -            }
    -            parentCallCount = path.getCallTarget().getCompilationProfile().getCallCount();
    -        }
    -        return f;
    -    }
    -
    -    private final class ProfileScoreComparator implements Comparator {
    +    private final static class ProfileScoreComparator implements Comparator {
     
             public int compare(TruffleInliningProfile o1, TruffleInliningProfile o2) {
                 return Double.compare(o2.getScore(), o1.getScore());
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleInliningPolicy.java
    --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleInliningPolicy.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleInliningPolicy.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -24,9 +24,7 @@
     
     public interface TruffleInliningPolicy {
     
    -    boolean isAllowed(TruffleInliningResult state, TruffleInliningProfile profile, int nodeCountBudget);
    -
    -    boolean isAllowedDeep(TruffleInliningResult state, TruffleInliningProfile profile, int nodeCountBudget);
    +    boolean isAllowed(TruffleInliningProfile profile, int currentBudgetLeft);
     
         double calculateScore(TruffleInliningProfile profile);
     
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleInliningProfile.java
    --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleInliningProfile.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleInliningProfile.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -24,34 +24,41 @@
     
     import java.util.*;
     
    -public class TruffleInliningProfile implements Comparable {
    +public class TruffleInliningProfile {
     
    -    private final TruffleCallPath callPath;
    -
    +    private final OptimizedDirectCallNode callNode;
         private final int nodeCount;
         private final int deepNodeCount;
         private final int callSites;
         private final double frequency;
         private final boolean forced;
    +    private final boolean recursiveCall;
         private final TruffleInliningResult recursiveResult;
     
         private String failedReason;
         private int queryIndex = -1;
         private double score;
     
    -    public TruffleInliningProfile(TruffleCallPath callPath, int callSites, int nodeCount, int deepNodeCount, double frequency, boolean forced, TruffleInliningResult recursiveResult) {
    -        if (callPath.isRoot()) {
    -            throw new IllegalArgumentException("Root call path not profilable.");
    -        }
    +    public TruffleInliningProfile(OptimizedDirectCallNode callNode, int callSites, int nodeCount, int deepNodeCount, double frequency, boolean forced, boolean recursiveCall,
    +                    TruffleInliningResult recursiveResult) {
    +        this.callNode = callNode;
             this.callSites = callSites;
    -        this.callPath = callPath;
             this.nodeCount = nodeCount;
             this.deepNodeCount = deepNodeCount;
             this.frequency = frequency;
    +        this.recursiveCall = recursiveCall;
             this.forced = forced;
             this.recursiveResult = recursiveResult;
         }
     
    +    public boolean isRecursiveCall() {
    +        return recursiveCall;
    +    }
    +
    +    public OptimizedDirectCallNode getCallNode() {
    +        return callNode;
    +    }
    +
         public int getCallSites() {
             return callSites;
         }
    @@ -100,21 +107,12 @@
             return deepNodeCount;
         }
     
    -    public TruffleCallPath getCallPath() {
    -        return callPath;
    -    }
    -
    -    public int compareTo(TruffleInliningProfile o) {
    -        return callPath.compareTo(o.callPath);
    -    }
    -
         public Map getDebugProperties() {
             Map properties = new LinkedHashMap<>();
    -        properties.put("callSites", callSites);
    -        properties.put("nodeCount", nodeCount);
    +        properties.put("nodeCount", String.format("%5d/%5d", deepNodeCount, nodeCount));
             properties.put("frequency", frequency);
    -        properties.put("score", score);
    -        properties.put(String.format("index=%3d, force=%s", queryIndex, (forced ? "Y" : "N")), "");
    +        properties.put("score", String.format("%8.4f", getScore()));
    +        properties.put(String.format("index=%3d, force=%s, callSites=%2d", queryIndex, (forced ? "Y" : "N"), callSites), "");
             properties.put("reason", failedReason);
             return properties;
         }
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleInliningResult.java
    --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleInliningResult.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleInliningResult.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -24,34 +24,49 @@
     
     import java.util.*;
     
    -public final class TruffleInliningResult implements Iterable {
    +public final class TruffleInliningResult implements Iterable {
     
         private final OptimizedCallTarget callTarget;
    -    private final Set inlinedPathes;
    +    private final Map profiles;
    +    private final Set inlined;
    +    private final int nodeCount;
     
    -    public TruffleInliningResult(OptimizedCallTarget callTarget, Set pathes) {
    +    public TruffleInliningResult(OptimizedCallTarget callTarget, List profiles, Set inlined, int nodeCount) {
             this.callTarget = callTarget;
    -        this.inlinedPathes = pathes;
    +        this.profiles = new HashMap<>();
    +        for (TruffleInliningProfile profile : profiles) {
    +            this.profiles.put(profile.getCallNode(), profile);
    +        }
    +        this.nodeCount = nodeCount;
    +        this.inlined = inlined;
    +    }
    +
    +    public Map getProfiles() {
    +        return profiles;
    +    }
    +
    +    public int getNodeCount() {
    +        return nodeCount;
         }
     
         public OptimizedCallTarget getCallTarget() {
             return callTarget;
         }
     
    -    public boolean isInlined(TruffleCallPath path) {
    -        return inlinedPathes.contains(path);
    +    public boolean isInlined(OptimizedDirectCallNode path) {
    +        return inlined.contains(profiles.get(path));
         }
     
         public int size() {
    -        return inlinedPathes.size();
    +        return inlined.size();
         }
     
    -    public Iterator iterator() {
    -        return Collections.unmodifiableSet(inlinedPathes).iterator();
    +    public Iterator iterator() {
    +        return Collections.unmodifiableSet(inlined).iterator();
         }
     
         @Override
         public String toString() {
    -        return inlinedPathes.toString();
    +        return inlined.toString();
         }
     }
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleReplacements.java
    --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleReplacements.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleReplacements.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -26,39 +26,33 @@
     
     import com.oracle.graal.api.meta.*;
     import com.oracle.graal.api.replacements.*;
    -import com.oracle.graal.api.runtime.*;
    -import com.oracle.graal.graph.*;
    +import com.oracle.graal.compiler.common.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.spi.*;
     import com.oracle.graal.phases.util.*;
     import com.oracle.graal.replacements.*;
    -import com.oracle.graal.runtime.*;
     import com.oracle.graal.truffle.substitutions.*;
     
     /**
      * Custom {@link Replacements} for Truffle compilation.
      */
    -public final class TruffleReplacements extends ReplacementsImpl {
    +public abstract class TruffleReplacements extends ReplacementsImpl {
     
         private final Replacements graalReplacements;
     
    -    private TruffleReplacements(Providers providers) {
    -        super(providers, providers.getReplacements().getAssumptions(), providers.getCodeCache().getTarget());
    +    protected TruffleReplacements(Providers providers, SnippetReflectionProvider snippetReflection) {
    +        super(providers, snippetReflection, providers.getReplacements().getAssumptions(), providers.getCodeCache().getTarget());
             this.graalReplacements = providers.getReplacements();
    +
    +        registerTruffleSubstitutions();
         }
     
    -    public static Replacements makeInstance() {
    -        Providers graalProviders = Graal.getRequiredCapability(RuntimeProvider.class).getHostBackend().getProviders();
    -        Replacements truffleReplacements = new TruffleReplacements(graalProviders);
    -
    -        truffleReplacements.registerSubstitutions(CompilerAssertsSubstitutions.class);
    -        truffleReplacements.registerSubstitutions(CompilerDirectivesSubstitutions.class);
    -        truffleReplacements.registerSubstitutions(ExactMathSubstitutions.class);
    -        truffleReplacements.registerSubstitutions(OptimizedAssumptionSubstitutions.class);
    -        truffleReplacements.registerSubstitutions(OptimizedCallTargetSubstitutions.class);
    -        truffleReplacements.registerSubstitutions(OptimizedCallTargetImplSubstitutions.class);
    -
    -        return truffleReplacements;
    +    protected void registerTruffleSubstitutions() {
    +        registerSubstitutions(CompilerAssertsSubstitutions.class);
    +        registerSubstitutions(CompilerDirectivesSubstitutions.class);
    +        registerSubstitutions(ExactMathSubstitutions.class);
    +        registerSubstitutions(OptimizedAssumptionSubstitutions.class);
    +        registerSubstitutions(OptimizedCallTargetSubstitutions.class);
         }
     
         @Override
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleTreeDumpHandler.java
    --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleTreeDumpHandler.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleTreeDumpHandler.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,8 +22,6 @@
      */
     package com.oracle.graal.truffle;
     
    -import java.util.*;
    -
     import com.oracle.graal.debug.*;
     import com.oracle.truffle.api.*;
     import com.oracle.truffle.api.nodes.*;
    @@ -46,7 +44,6 @@
                 final OptimizedCallTarget oct = (OptimizedCallTarget) callTarget;
     
                 visitor.beginGroup(callTarget.toString());
    -            dumpInlinedCalls(visitor, oct);
                 dumpFullTree(visitor, message, oct);
                 visitor.printToNetwork(false);
             }
    @@ -54,22 +51,17 @@
     
         private static void dumpFullTree(final GraphPrintVisitor visitor, final String message, final OptimizedCallTarget oct) {
             visitor.setChildSupplier(new ChildSupplier() {
    -            private TruffleCallPath currentPath = new TruffleCallPath(oct);
     
                 public Object startNode(Object callNode) {
    -                if (callNode instanceof OptimizedCallNode) {
    -                    currentPath = new TruffleCallPath(currentPath, (OptimizedCallNode) callNode);
    -                    if (oct.getInliningResult() != null && oct.getInliningResult().isInlined(currentPath)) {
    -                        return ((OptimizedCallNode) callNode).getCurrentRootNode();
    +                if (callNode instanceof OptimizedDirectCallNode) {
    +                    if (((OptimizedDirectCallNode) callNode).isInlined()) {
    +                        return ((OptimizedDirectCallNode) callNode).getCurrentRootNode();
                         }
                     }
                     return null;
                 }
     
                 public void endNode(Object callNode) {
    -                if (callNode instanceof OptimizedCallNode) {
    -                    currentPath = currentPath.getParent();
    -                }
                 }
             });
     
    @@ -77,23 +69,6 @@
             visitor.setChildSupplier(null);
         }
     
    -    private static void dumpInlinedCalls(final GraphPrintVisitor visitor, final OptimizedCallTarget oct) {
    -        final Set visitedRoots = new HashSet<>();
    -        oct.getRootNode().accept(new OptimizedCallUtils.InlinedCallVisitor(oct.getInliningResult(), new TruffleCallPath(oct)) {
    -            @Override
    -            public boolean visit(TruffleCallPath path, Node node) {
    -                if (node instanceof OptimizedCallNode) {
    -                    OptimizedCallTarget target = ((OptimizedCallNode) node).getCurrentCallTarget();
    -                    if (!visitedRoots.contains(target)) {
    -                        visitor.beginGraph("inlined " + target.toString()).visit(target.getRootNode());
    -                        visitedRoots.add(target);
    -                    }
    -                }
    -                return true;
    -            }
    -        });
    -    }
    -
         public void close() {
             // nothing to do
         }
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/AssumptionNode.java
    --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/AssumptionNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/AssumptionNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,6 +23,8 @@
     package com.oracle.graal.truffle.nodes;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.api.replacements.*;
    +import com.oracle.graal.api.runtime.*;
     import com.oracle.graal.graph.spi.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.replacements.nodes.*;
    @@ -39,13 +41,21 @@
             return arguments.first();
         }
     
    +    private static SnippetReflectionProvider getSnippetReflection() {
    +        /*
    +         * This class requires access to the objects encapsulated in Constants, and therefore breaks
    +         * the compiler-VM separation of object constants.
    +         */
    +        return Graal.getRequiredCapability(SnippetReflectionProvider.class);
    +    }
    +
         @Override
         public void simplify(SimplifierTool tool) {
             ValueNode assumption = getAssumption();
             if (tool.assumptions() != null && assumption.isConstant()) {
                 Constant c = assumption.asConstant();
                 assert c.getKind() == Kind.Object;
    -            Object object = c.asObject();
    +            Object object = getSnippetReflection().asObject(c);
                 OptimizedAssumption assumptionObject = (OptimizedAssumption) object;
                 StructuredGraph graph = graph();
                 if (assumptionObject.isValid()) {
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/BailoutNode.java
    --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/BailoutNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/BailoutNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -40,7 +40,7 @@
             ValueNode arg = arguments.get(0);
             String message = "";
             if (arg.isConstant()) {
    -            message = (String) arg.asConstant().asObject();
    +            message = arg.asConstant().toValueString();
             }
             throw new BailoutException(message);
         }
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/LoadIndexedFinalNode.java
    --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/LoadIndexedFinalNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/LoadIndexedFinalNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,11 +22,8 @@
      */
     package com.oracle.graal.truffle.nodes;
     
    -import java.lang.reflect.*;
    -
    -import sun.misc.*;
    -
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.graph.spi.*;
     import com.oracle.graal.nodes.*;
    @@ -52,13 +49,9 @@
     
         @Override
         public Node canonical(CanonicalizerTool tool) {
    -        if (array().isConstant() && !array().isNullConstant() && index().isConstant()) {
    -            Object array = array().asConstant().asObject();
    -            long index = index().asConstant().asLong();
    -            if (index >= 0 && index < Array.getLength(array)) {
    -                int arrayBaseOffset = Unsafe.getUnsafe().arrayBaseOffset(array.getClass());
    -                int arrayIndexScale = Unsafe.getUnsafe().arrayIndexScale(array.getClass());
    -                Constant constant = tool.getConstantReflection().readUnsafeConstant(elementKind(), array().asConstant(), arrayBaseOffset + index * arrayIndexScale, elementKind() == Kind.Object);
    +        if (array().isConstant() && index().isConstant()) {
    +            Constant constant = tool.getConstantReflection().readArrayElement(array().asConstant(), index().asConstant().asInt());
    +            if (constant != null) {
                     return ConstantNode.forConstant(constant, tool.getMetaAccess(), graph());
                 }
             }
    @@ -66,7 +59,7 @@
         }
     
         private static Stamp createStamp(ValueNode array, Kind kind) {
    -        ResolvedJavaType type = ObjectStamp.typeOrNull(array);
    +        ResolvedJavaType type = StampTool.typeOrNull(array);
             if (kind == Kind.Object && type != null) {
                 return StampFactory.declared(type.getComponentType());
             } else {
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/ObjectLocationIdentity.java
    --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/ObjectLocationIdentity.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -0,0 +1,59 @@
    +/*
    + * Copyright (c) 2013, 2013, Oracle and/or its affiliates. All rights reserved.
    + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    + *
    + * This code is free software; you can redistribute it and/or modify it
    + * under the terms of the GNU General Public License version 2 only, as
    + * published by the Free Software Foundation.
    + *
    + * This code is distributed in the hope that it will be useful, but WITHOUT
    + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    + * version 2 for more details (a copy is included in the LICENSE file that
    + * accompanied this code).
    + *
    + * You should have received a copy of the GNU General Public License version
    + * 2 along with this work; if not, write to the Free Software Foundation,
    + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    + *
    + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    + * or visit www.oracle.com if you need additional information or have any
    + * questions.
    + */
    +package com.oracle.graal.truffle.nodes;
    +
    +import java.util.*;
    +
    +import com.oracle.graal.api.meta.*;
    +
    +/**
    + * A {@link LocationIdentity} wrapping an object.
    + */
    +public final class ObjectLocationIdentity implements LocationIdentity {
    +
    +    private static HashMap map = new HashMap<>();
    +
    +    private Constant object;
    +
    +    public static LocationIdentity create(Constant object) {
    +        assert object.getKind() == Kind.Object && object.isNonNull();
    +        synchronized (map) {
    +            if (map.containsKey(object)) {
    +                return map.get(object);
    +            } else {
    +                ObjectLocationIdentity locationIdentity = new ObjectLocationIdentity(object);
    +                map.put(object, locationIdentity);
    +                return locationIdentity;
    +            }
    +        }
    +    }
    +
    +    private ObjectLocationIdentity(Constant object) {
    +        this.object = object;
    +    }
    +
    +    @Override
    +    public String toString() {
    +        return "Identity(" + object + ")";
    +    }
    +}
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerAddExactNode.java
    --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerAddExactNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerAddExactNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,6 +23,7 @@
     package com.oracle.graal.truffle.nodes.arithmetic;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.graph.spi.*;
     import com.oracle.graal.nodes.*;
    @@ -77,7 +78,7 @@
         }
     
         @Override
    -    public IntegerExactArithmeticSplitNode createSplit(AbstractBeginNode next, AbstractBeginNode deopt) {
    +    public IntegerExactArithmeticSplitNode createSplit(BeginNode next, BeginNode deopt) {
             return graph().add(new IntegerAddExactSplitNode(stamp(), x(), y(), next, deopt));
         }
     
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerAddExactSplitNode.java
    --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerAddExactSplitNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerAddExactSplitNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,13 +23,13 @@
     package com.oracle.graal.truffle.nodes.arithmetic;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
     
     public class IntegerAddExactSplitNode extends IntegerExactArithmeticSplitNode {
     
    -    public IntegerAddExactSplitNode(Stamp stamp, ValueNode x, ValueNode y, AbstractBeginNode next, AbstractBeginNode overflowSuccessor) {
    +    public IntegerAddExactSplitNode(Stamp stamp, ValueNode x, ValueNode y, BeginNode next, BeginNode overflowSuccessor) {
             super(stamp, x, y, next, overflowSuccessor);
         }
     
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerExactArithmeticNode.java
    --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerExactArithmeticNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerExactArithmeticNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -28,5 +28,5 @@
     
     interface IntegerExactArithmeticNode extends Lowerable, IterableNodeType {
     
    -    IntegerExactArithmeticSplitNode createSplit(AbstractBeginNode next, AbstractBeginNode deopt);
    +    IntegerExactArithmeticSplitNode createSplit(BeginNode next, BeginNode deopt);
     }
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerExactArithmeticSplitNode.java
    --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerExactArithmeticSplitNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerExactArithmeticSplitNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,19 +23,19 @@
     package com.oracle.graal.truffle.nodes.arithmetic;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.calc.*;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
     
     public abstract class IntegerExactArithmeticSplitNode extends ControlSplitNode implements LIRLowerable {
     
    -    @Successor private AbstractBeginNode overflowSuccessor;
    -    @Successor private AbstractBeginNode next;
    +    @Successor private BeginNode overflowSuccessor;
    +    @Successor private BeginNode next;
         @Input private ValueNode x;
         @Input private ValueNode y;
     
    -    public IntegerExactArithmeticSplitNode(Stamp stamp, ValueNode x, ValueNode y, AbstractBeginNode next, AbstractBeginNode overflowSuccessor) {
    +    public IntegerExactArithmeticSplitNode(Stamp stamp, ValueNode x, ValueNode y, BeginNode next, BeginNode overflowSuccessor) {
             super(stamp);
             this.x = x;
             this.y = y;
    @@ -44,20 +44,20 @@
         }
     
         @Override
    -    public double probability(AbstractBeginNode successor) {
    +    public double probability(BeginNode successor) {
             return successor == next ? 1 : 0;
         }
     
         @Override
    -    public void setProbability(AbstractBeginNode successor, double value) {
    +    public void setProbability(BeginNode successor, double value) {
             assert probability(successor) == value;
         }
     
    -    public AbstractBeginNode getNext() {
    +    public BeginNode getNext() {
             return next;
         }
     
    -    public AbstractBeginNode getOverflowSuccessor() {
    +    public BeginNode getOverflowSuccessor() {
             return overflowSuccessor;
         }
     
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerMulExactNode.java
    --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerMulExactNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerMulExactNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,12 +23,12 @@
     package com.oracle.graal.truffle.nodes.arithmetic;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.graph.spi.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.calc.*;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
     import com.oracle.truffle.api.*;
     
     /**
    @@ -74,7 +74,7 @@
         }
     
         @Override
    -    public IntegerExactArithmeticSplitNode createSplit(AbstractBeginNode next, AbstractBeginNode deopt) {
    +    public IntegerExactArithmeticSplitNode createSplit(BeginNode next, BeginNode deopt) {
             return graph().add(new IntegerMulExactSplitNode(stamp(), x(), y(), next, deopt));
         }
     
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerMulExactSplitNode.java
    --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerMulExactSplitNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerMulExactSplitNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,13 +23,13 @@
     package com.oracle.graal.truffle.nodes.arithmetic;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
     
     public class IntegerMulExactSplitNode extends IntegerExactArithmeticSplitNode {
     
    -    public IntegerMulExactSplitNode(Stamp stamp, ValueNode x, ValueNode y, AbstractBeginNode next, AbstractBeginNode overflowSuccessor) {
    +    public IntegerMulExactSplitNode(Stamp stamp, ValueNode x, ValueNode y, BeginNode next, BeginNode overflowSuccessor) {
             super(stamp, x, y, next, overflowSuccessor);
         }
     
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerSubExactNode.java
    --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerSubExactNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerSubExactNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,6 +23,7 @@
     package com.oracle.graal.truffle.nodes.arithmetic;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.graph.spi.*;
     import com.oracle.graal.nodes.*;
    @@ -77,7 +78,7 @@
         }
     
         @Override
    -    public IntegerExactArithmeticSplitNode createSplit(AbstractBeginNode next, AbstractBeginNode deopt) {
    +    public IntegerExactArithmeticSplitNode createSplit(BeginNode next, BeginNode deopt) {
             return graph().add(new IntegerSubExactSplitNode(stamp(), x(), y(), next, deopt));
         }
     
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerSubExactSplitNode.java
    --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerSubExactSplitNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerSubExactSplitNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,13 +23,13 @@
     package com.oracle.graal.truffle.nodes.arithmetic;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
     
     public class IntegerSubExactSplitNode extends IntegerExactArithmeticSplitNode {
     
    -    public IntegerSubExactSplitNode(Stamp stamp, ValueNode x, ValueNode y, AbstractBeginNode next, AbstractBeginNode overflowSuccessor) {
    +    public IntegerSubExactSplitNode(Stamp stamp, ValueNode x, ValueNode y, BeginNode next, BeginNode overflowSuccessor) {
             super(stamp, x, y, next, overflowSuccessor);
         }
     
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/ForceMaterializeNode.java
    --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/ForceMaterializeNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -0,0 +1,45 @@
    +/*
    + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
    + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    + *
    + * This code is free software; you can redistribute it and/or modify it
    + * under the terms of the GNU General Public License version 2 only, as
    + * published by the Free Software Foundation.
    + *
    + * This code is distributed in the hope that it will be useful, but WITHOUT
    + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    + * version 2 for more details (a copy is included in the LICENSE file that
    + * accompanied this code).
    + *
    + * You should have received a copy of the GNU General Public License version
    + * 2 along with this work; if not, write to the Free Software Foundation,
    + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    + *
    + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    + * or visit www.oracle.com if you need additional information or have any
    + * questions.
    + */
    +package com.oracle.graal.truffle.nodes.frame;
    +
    +import com.oracle.graal.compiler.common.type.*;
    +import com.oracle.graal.compiler.gen.*;
    +import com.oracle.graal.compiler.target.*;
    +import com.oracle.graal.nodes.*;
    +
    +public class ForceMaterializeNode extends FixedWithNextNode implements LIRGenLowerable {
    +
    +    @Input private ValueNode object;
    +
    +    public ForceMaterializeNode(ValueNode object) {
    +        super(StampFactory.forVoid());
    +        this.object = object;
    +    }
    +
    +    public void generate(NodeLIRBuilder generator) {
    +        // nothing to do
    +    }
    +
    +    @NodeIntrinsic
    +    public native static void force(Object object);
    +}
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/NewFrameNode.java
    --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/NewFrameNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/NewFrameNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -25,12 +25,15 @@
     import java.util.*;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.api.replacements.*;
    +import com.oracle.graal.api.runtime.*;
    +import com.oracle.graal.compiler.common.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.graph.spi.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.java.*;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
     import com.oracle.graal.nodes.util.*;
     import com.oracle.graal.nodes.virtual.*;
     import com.oracle.graal.truffle.*;
    @@ -64,9 +67,17 @@
             return arguments;
         }
     
    +    private static SnippetReflectionProvider getSnippetReflection() {
    +        /*
    +         * This class requires access to the objects encapsulated in Constants, and therefore breaks
    +         * the compiler-VM separation of object constants.
    +         */
    +        return Graal.getRequiredCapability(SnippetReflectionProvider.class);
    +    }
    +
         private FrameDescriptor getConstantFrameDescriptor() {
             assert descriptor.isConstant() && !descriptor.isNullConstant();
    -        return (FrameDescriptor) descriptor.asConstant().asObject();
    +        return (FrameDescriptor) getSnippetReflection().asObject(descriptor.asConstant());
         }
     
         private int getFrameSize() {
    @@ -151,7 +162,7 @@
     
             if (frameSize > 0) {
                 FrameDescriptor frameDescriptor = getConstantFrameDescriptor();
    -            ConstantNode objectDefault = ConstantNode.forObject(frameDescriptor.getTypeConversion().getDefaultValue(), tool.getMetaAccessProvider(), graph());
    +            ConstantNode objectDefault = ConstantNode.forConstant(getSnippetReflection().forObject(frameDescriptor.getTypeConversion().getDefaultValue()), tool.getMetaAccessProvider(), graph());
                 ConstantNode tagDefault = ConstantNode.forByte((byte) 0, graph());
                 for (int i = 0; i < frameSize; i++) {
                     objectArrayEntryState[i] = objectDefault;
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeLoadFinalNode.java
    --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeLoadFinalNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeLoadFinalNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,13 +23,15 @@
     package com.oracle.graal.truffle.nodes.typesystem;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.calc.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.graph.spi.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.calc.*;
     import com.oracle.graal.nodes.extended.*;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
    +import com.oracle.graal.truffle.nodes.*;
     import com.oracle.truffle.api.*;
     
     /**
    @@ -40,8 +42,8 @@
     public class CustomizedUnsafeLoadFinalNode extends FixedWithNextNode implements Canonicalizable, Virtualizable, Lowerable {
         @Input private ValueNode object;
         @Input private ValueNode offset;
    -    @Input(InputType.Condition) private ValueNode condition;
    -    @Input(InputType.Association) private ValueNode location;
    +    @Input private ValueNode condition;
    +    @Input private ValueNode location;
         private final Kind accessKind;
     
         public CustomizedUnsafeLoadFinalNode(ValueNode object, ValueNode offset, ValueNode condition, ValueNode location, Kind accessKind) {
    @@ -56,7 +58,7 @@
         @Override
         public Node canonical(CanonicalizerTool tool) {
             if (object.isConstant() && !object.isNullConstant() && offset.isConstant()) {
    -            Constant constant = tool.getConstantReflection().readUnsafeConstant(accessKind, object.asConstant().asObject(), offset.asConstant().asLong(), accessKind == Kind.Object);
    +            Constant constant = tool.getConstantReflection().readUnsafeConstant(accessKind, object.asConstant(), offset.asConstant().asLong());
                 return ConstantNode.forConstant(constant, tool.getMetaAccess(), graph());
             }
             return this;
    @@ -86,12 +88,11 @@
         @Override
         public void lower(LoweringTool tool) {
             CompareNode compare = CompareNode.createCompareNode(graph(), Condition.EQ, condition, ConstantNode.forBoolean(true, graph()));
    -        Object locationIdentityObject = location.asConstant().asObject();
             LocationIdentity locationIdentity;
    -        if (locationIdentityObject == null) {
    +        if (!location.isConstant() || location.asConstant().isNull()) {
                 locationIdentity = LocationIdentity.ANY_LOCATION;
             } else {
    -            locationIdentity = ObjectLocationIdentity.create(locationIdentityObject);
    +            locationIdentity = ObjectLocationIdentity.create(location.asConstant());
             }
             UnsafeLoadNode result = graph().add(new UnsafeLoadNode(object, offset, accessKind, locationIdentity, compare));
             graph().replaceFixedWithFixed(this, result);
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeLoadMacroNode.java
    --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeLoadMacroNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeLoadMacroNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,11 +23,13 @@
     package com.oracle.graal.truffle.nodes.typesystem;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.calc.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.graph.spi.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.calc.*;
     import com.oracle.graal.nodes.extended.*;
    +import com.oracle.graal.truffle.nodes.*;
     import com.oracle.graal.truffle.nodes.asserts.*;
     import com.oracle.truffle.api.*;
     
    @@ -54,12 +56,11 @@
                 ValueNode objectArgument = arguments.get(OBJECT_ARGUMENT_INDEX);
                 ValueNode offsetArgument = arguments.get(OFFSET_ARGUMENT_INDEX);
                 ValueNode conditionArgument = arguments.get(CONDITION_ARGUMENT_INDEX);
    -            Object locationIdentityObject = locationArgument.asConstant().asObject();
                 LocationIdentity locationIdentity;
    -            if (locationIdentityObject == null) {
    +            if (locationArgument.asConstant().isNull()) {
                     locationIdentity = LocationIdentity.ANY_LOCATION;
                 } else {
    -                locationIdentity = ObjectLocationIdentity.create(locationIdentityObject);
    +                locationIdentity = ObjectLocationIdentity.create(locationArgument.asConstant());
                 }
                 CompareNode compare = CompareNode.createCompareNode(graph(), Condition.EQ, conditionArgument, ConstantNode.forBoolean(true, graph()));
                 Kind returnKind = this.getTargetMethod().getSignature().getReturnKind();
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeStoreMacroNode.java
    --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeStoreMacroNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeStoreMacroNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -27,6 +27,7 @@
     import com.oracle.graal.graph.spi.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.extended.*;
    +import com.oracle.graal.truffle.nodes.*;
     import com.oracle.graal.truffle.nodes.asserts.*;
     import com.oracle.truffle.api.*;
     
    @@ -53,12 +54,11 @@
                 ValueNode objectArgument = arguments.get(OBJECT_ARGUMENT_INDEX);
                 ValueNode offsetArgument = arguments.get(OFFSET_ARGUMENT_INDEX);
                 ValueNode valueArgument = arguments.get(VALUE_ARGUMENT_INDEX);
    -            Object locationIdentityObject = locationArgument.asConstant().asObject();
                 LocationIdentity locationIdentity;
    -            if (locationIdentityObject == null) {
    +            if (locationArgument.asConstant().isNull()) {
                     locationIdentity = LocationIdentity.ANY_LOCATION;
                 } else {
    -                locationIdentity = ObjectLocationIdentity.create(locationIdentityObject);
    +                locationIdentity = ObjectLocationIdentity.create(locationArgument.asConstant());
                 }
     
                 UnsafeStoreNode unsafeStoreNode = graph().add(
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/UnsafeTypeCastMacroNode.java
    --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/UnsafeTypeCastMacroNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/UnsafeTypeCastMacroNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,12 +23,13 @@
     package com.oracle.graal.truffle.nodes.typesystem;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.calc.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.graph.spi.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.calc.*;
     import com.oracle.graal.nodes.extended.*;
    -import com.oracle.graal.nodes.type.*;
     import com.oracle.graal.truffle.nodes.asserts.*;
     import com.oracle.truffle.api.*;
     
    @@ -55,11 +56,10 @@
             if (classArgument.isConstant() && nonNullArgument.isConstant()) {
                 ValueNode objectArgument = arguments.get(OBJECT_ARGUMENT_INDEX);
                 ValueNode conditionArgument = arguments.get(CONDITION_ARGUMENT_INDEX);
    -            Class c = (Class) classArgument.asConstant().asObject();
    -            if (c == null) {
    +            ResolvedJavaType lookupJavaType = tool.getConstantReflection().asJavaType(classArgument.asConstant());
    +            if (lookupJavaType == null) {
                     return objectArgument;
                 }
    -            ResolvedJavaType lookupJavaType = tool.getMetaAccess().lookupJavaType(c);
                 Stamp stamp = StampFactory.declared(lookupJavaType, nonNullArgument.asConstant().asInt() != 0);
                 ConditionAnchorNode valueAnchorNode = graph().add(new ConditionAnchorNode(CompareNode.createCompareNode(graph(), Condition.EQ, conditionArgument, ConstantNode.forBoolean(true, graph()))));
                 UnsafeCastNode piCast = graph().unique(new UnsafeCastNode(objectArgument, stamp, valueAnchorNode));
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/CompilerDirectivesSubstitutions.java
    --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/CompilerDirectivesSubstitutions.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/CompilerDirectivesSubstitutions.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -31,6 +31,7 @@
     import com.oracle.graal.nodes.spi.*;
     import com.oracle.graal.truffle.*;
     import com.oracle.graal.truffle.nodes.*;
    +import com.oracle.graal.truffle.nodes.frame.*;
     import com.oracle.graal.truffle.nodes.typesystem.*;
     import com.oracle.truffle.api.*;
     import com.oracle.truffle.api.frame.*;
    @@ -54,6 +55,11 @@
         }
     
         @MethodSubstitution
    +    public static boolean inCompiledCode() {
    +        return true;
    +    }
    +
    +    @MethodSubstitution
         public static void interpreterOnly(@SuppressWarnings("unused") Runnable runnable) {
         }
     
    @@ -71,7 +77,7 @@
         public static native void bailout(String reason);
     
         @MacroSubstitution(macro = UnsafeTypeCastMacroNode.class, isStatic = true)
    -    public static native Object unsafeCast(Object value, Class clazz, boolean condition, boolean nonNull);
    +    public static native Object unsafeCast(Object value, Class clazz, boolean condition, boolean nonNull);
     
         @MethodSubstitution
         private static Class getUnsafeFrameType() {
    @@ -165,4 +171,10 @@
         public static Object unsafeGetFinalObject(Object receiver, long offset, boolean condition, Object locationIdentity) {
             return CustomizedUnsafeLoadFinalNode.load(receiver, offset, condition, locationIdentity, Kind.Object);
         }
    +
    +    @MethodSubstitution
    +    public static void materialize(Object obj) {
    +        ForceMaterializeNode.force(obj);
    +    }
    +
     }
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/OptimizedCallTargetImplSubstitutions.java
    --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/OptimizedCallTargetImplSubstitutions.java	Wed Apr 23 15:22:20 2014 +0200
    +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    @@ -1,41 +0,0 @@
    -/*
    - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
    - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    - *
    - * This code is free software; you can redistribute it and/or modify it
    - * under the terms of the GNU General Public License version 2 only, as
    - * published by the Free Software Foundation.
    - *
    - * This code is distributed in the hope that it will be useful, but WITHOUT
    - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    - * version 2 for more details (a copy is included in the LICENSE file that
    - * accompanied this code).
    - *
    - * You should have received a copy of the GNU General Public License version
    - * 2 along with this work; if not, write to the Free Software Foundation,
    - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    - *
    - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    - * or visit www.oracle.com if you need additional information or have any
    - * questions.
    - */
    -package com.oracle.graal.truffle.substitutions;
    -
    -import com.oracle.graal.api.replacements.*;
    -import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.truffle.*;
    -import com.oracle.graal.truffle.nodes.asserts.*;
    -
    -@ClassSubstitution(OptimizedCallTargetImpl.class)
    -public class OptimizedCallTargetImplSubstitutions {
    -
    -    @MacroSubstitution(macro = NeverInlineMacroNode.class, isStatic = false)
    -    public static native Object callHelper(OptimizedCallTarget target, Object[] args);
    -
    -    @MacroSubstitution(macro = NeverInlineMacroNode.class, isStatic = false)
    -    public static native Object interpreterCall(OptimizedCallTarget target, Object[] args);
    -
    -    @MacroSubstitution(macro = NeverInlineMacroNode.class, isStatic = false)
    -    public static native Object compiledCodeInvalidated(OptimizedCallTarget target, Object[] args);
    -}
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/OptimizedCallTargetSubstitutions.java
    --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/OptimizedCallTargetSubstitutions.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/OptimizedCallTargetSubstitutions.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,6 +23,8 @@
     package com.oracle.graal.truffle.substitutions;
     
     import com.oracle.graal.api.replacements.*;
    +import com.oracle.graal.compiler.common.type.*;
    +import com.oracle.graal.nodes.*;
     import com.oracle.graal.truffle.*;
     import com.oracle.graal.truffle.nodes.frame.*;
     import com.oracle.truffle.api.frame.*;
    @@ -34,4 +36,9 @@
         private static FrameWithoutBoxing createFrame(FrameDescriptor descriptor, Object[] args) {
             return NewFrameNode.allocate(FrameWithoutBoxing.class, descriptor, args);
         }
    +
    +    @MethodSubstitution
    +    private static Object castArrayFixedLength(Object[] args, int length) {
    +        return PiArrayNode.piArrayCast(args, length, StampFactory.forNodeIntrinsic());
    +    }
     }
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EarlyReadEliminationPhase.java
    --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EarlyReadEliminationPhase.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EarlyReadEliminationPhase.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,7 +22,7 @@
      */
     package com.oracle.graal.virtual.phases.ea;
     
    -import static com.oracle.graal.phases.GraalOptions.*;
    +import static com.oracle.graal.compiler.common.GraalOptions.*;
     
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.phases.common.*;
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsClosure.java
    --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsClosure.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsClosure.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,10 +22,12 @@
      */
     package com.oracle.graal.virtual.phases.ea;
     
    -import static com.oracle.graal.phases.GraalOptions.*;
    +import static com.oracle.graal.compiler.common.GraalOptions.*;
     
     import java.util.*;
     
    +import com.oracle.graal.compiler.common.*;
    +import com.oracle.graal.compiler.common.cfg.*;
     import com.oracle.graal.debug.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.nodes.*;
    @@ -43,7 +45,7 @@
     
         protected final NodeMap aliases;
         protected final BlockMap blockEffects;
    -    private final IdentityHashMap loopMergeEffects = new IdentityHashMap<>();
    +    private final IdentityHashMap, GraphEffectList> loopMergeEffects = new IdentityHashMap<>();
         private final IdentityHashMap loopEntryStates = new IdentityHashMap<>();
     
         private boolean changed;
    @@ -105,7 +107,7 @@
                 }
     
                 @Override
    -            protected List processLoop(Loop loop, Void initialState) {
    +            protected List processLoop(Loop loop, Void initialState) {
                     LoopInfo info = ReentrantBlockIterator.processLoop(this, loop, initialState);
                     apply(loopMergeEffects.get(loop), loop);
                     return info.exitStates;
    @@ -150,7 +152,7 @@
         }
     
         @Override
    -    protected final List processLoop(Loop loop, BlockT initialState) {
    +    protected final List processLoop(Loop loop, BlockT initialState) {
             BlockT loopEntryState = initialState;
             BlockT lastMergedState = cloneState(initialState);
             MergeProcessor mergeProcessor = createMergeProcessor(loop.header);
    @@ -174,7 +176,7 @@
                     loopMergeEffects.put(loop, mergeProcessor.afterMergeEffects);
     
                     assert info.exitStates.size() == loop.exits.size();
    -                loopEntryStates.put(loop.loopBegin(), loopEntryState);
    +                loopEntryStates.put((LoopBeginNode) loop.header.getBeginNode(), loopEntryState);
                     for (int i = 0; i < loop.exits.size(); i++) {
                         assert info.exitStates.get(i) != null : "no loop exit state at " + loop.exits.get(i) + " / " + loop.header;
                     }
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsPhase.java
    --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsPhase.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsPhase.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -90,7 +90,9 @@
                             listener.getChangedNodes().add(node);
                         }
                     }
    -                canonicalizer.applyIncremental(graph, context, listener.getChangedNodes());
    +                if (canonicalizer != null) {
    +                    canonicalizer.applyIncremental(graph, context, listener.getChangedNodes());
    +                }
                 }
                 changed = true;
             }
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/IterativeInliningPhase.java
    --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/IterativeInliningPhase.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/IterativeInliningPhase.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,8 +22,8 @@
      */
     package com.oracle.graal.virtual.phases.ea;
     
    +import static com.oracle.graal.compiler.common.GraalOptions.*;
     import static com.oracle.graal.debug.Debug.*;
    -import static com.oracle.graal.phases.GraalOptions.*;
     
     import java.util.*;
     
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PEReadEliminationBlockState.java
    --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PEReadEliminationBlockState.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PEReadEliminationBlockState.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -34,10 +34,10 @@
     
         static class ReadCacheEntry {
     
    -        public final ResolvedJavaField identity;
    +        public final LocationIdentity identity;
             public final ValueNode object;
     
    -        public ReadCacheEntry(ResolvedJavaField identity, ValueNode object) {
    +        public ReadCacheEntry(LocationIdentity identity, ValueNode object) {
                 this.identity = identity;
                 this.object = object;
             }
    @@ -95,7 +95,7 @@
             return super.equivalentTo(other);
         }
     
    -    public void addReadCache(ValueNode object, ResolvedJavaField identity, ValueNode value, PartialEscapeClosure closure) {
    +    public void addReadCache(ValueNode object, LocationIdentity identity, ValueNode value, PartialEscapeClosure closure) {
             ValueNode cacheObject;
             ObjectState obj = closure.getObjectState(this, object);
             if (obj != null) {
    @@ -107,7 +107,7 @@
             readCache.put(new ReadCacheEntry(identity, cacheObject), value);
         }
     
    -    public ValueNode getReadCache(ValueNode object, ResolvedJavaField identity, PartialEscapeClosure closure) {
    +    public ValueNode getReadCache(ValueNode object, LocationIdentity identity, PartialEscapeClosure closure) {
             ValueNode cacheObject;
             ObjectState obj = closure.getObjectState(this, object);
             if (obj != null) {
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PEReadEliminationClosure.java
    --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PEReadEliminationClosure.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PEReadEliminationClosure.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -39,8 +39,8 @@
     
     public class PEReadEliminationClosure extends PartialEscapeClosure {
     
    -    public PEReadEliminationClosure(SchedulePhase schedule, MetaAccessProvider metaAccess, Assumptions assumptions) {
    -        super(schedule, metaAccess, assumptions);
    +    public PEReadEliminationClosure(SchedulePhase schedule, MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection, Assumptions assumptions) {
    +        super(schedule, metaAccess, constantReflection, assumptions);
         }
     
         @Override
    @@ -83,6 +83,17 @@
                     } else {
                         processIdentity(state, ANY_LOCATION);
                     }
    +            } else if (node instanceof ArrayLengthNode) {
    +                ArrayLengthNode length = (ArrayLengthNode) node;
    +                ValueNode array = GraphUtil.unproxify(length.array());
    +                ValueNode cachedValue = state.getReadCache(array, ARRAY_LENGTH_LOCATION, this);
    +                if (cachedValue != null) {
    +                    effects.replaceAtUsages(length, cachedValue);
    +                    addScalarAlias(length, cachedValue);
    +                    deleted = true;
    +                } else {
    +                    state.addReadCache(array, ARRAY_LENGTH_LOCATION, length, this);
    +                }
                 } else if (node instanceof MemoryCheckpoint.Single) {
                     METRIC_MEMORYCHECKPOINT.increment();
                     LocationIdentity identity = ((MemoryCheckpoint.Single) node).getLocationIdentity();
    @@ -183,7 +194,7 @@
                 }
             }
     
    -        private void mergeReadCachePhi(PhiNode phi, ResolvedJavaField identity, List states) {
    +        private void mergeReadCachePhi(PhiNode phi, LocationIdentity identity, List states) {
                 ValueNode[] values = new ValueNode[phi.valueCount()];
                 for (int i = 0; i < phi.valueCount(); i++) {
                     ValueNode value = states.get(i).getReadCache(phi.valueAt(i), identity, PEReadEliminationClosure.this);
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java
    --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -26,6 +26,7 @@
     
     import com.oracle.graal.api.code.*;
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.debug.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.nodes.*;
    @@ -35,7 +36,6 @@
     import com.oracle.graal.nodes.java.*;
     import com.oracle.graal.nodes.spi.*;
     import com.oracle.graal.nodes.spi.Virtualizable.EscapeState;
    -import com.oracle.graal.nodes.type.*;
     import com.oracle.graal.nodes.virtual.*;
     import com.oracle.graal.phases.schedule.*;
     import com.oracle.graal.phases.util.*;
    @@ -63,8 +63,8 @@
          */
         public static final class Final extends PartialEscapeClosure {
     
    -        public Final(SchedulePhase schedule, MetaAccessProvider metaAccess, Assumptions assumptions) {
    -            super(schedule, metaAccess, assumptions);
    +        public Final(SchedulePhase schedule, MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection, Assumptions assumptions) {
    +            super(schedule, metaAccess, constantReflection, assumptions);
             }
     
             @Override
    @@ -78,10 +78,10 @@
             }
         }
     
    -    public PartialEscapeClosure(SchedulePhase schedule, MetaAccessProvider metaAccess, Assumptions assumptions) {
    +    public PartialEscapeClosure(SchedulePhase schedule, MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection, Assumptions assumptions) {
             super(schedule);
             this.usages = schedule.getCFG().graph.createNodeBitMap();
    -        this.tool = new VirtualizerToolImpl(metaAccess, assumptions, this);
    +        this.tool = new VirtualizerToolImpl(metaAccess, constantReflection, assumptions, this);
         }
     
         public Map getHints() {
    @@ -132,78 +132,75 @@
         }
     
         private void processNodeWithState(NodeWithState nodeWithState, final BlockT state, final GraphEffectList effects) {
    -        for (Node input : nodeWithState.asNode().inputs()) {
    -            if (input instanceof FrameState) {
    -                FrameState frameState = (FrameState) input;
    -                if (frameState.usages().count() > 1) {
    -                    FrameState copy = (FrameState) frameState.copyWithInputs();
    -                    nodeWithState.asNode().replaceFirstInput(frameState, copy);
    -                    frameState = copy;
    -                }
    -                final Set virtual = new ArraySet<>();
    -                frameState.applyToNonVirtual(new NodeClosure() {
    +        for (FrameState frameState : nodeWithState.states()) {
    +            if (frameState.usages().count() > 1) {
    +                FrameState copy = (FrameState) frameState.copyWithInputs();
    +                nodeWithState.asNode().replaceFirstInput(frameState, copy);
    +                frameState = copy;
    +            }
    +            final Set virtual = new ArraySet<>();
    +            frameState.applyToNonVirtual(new NodeClosure() {
     
    -                    @Override
    -                    public void apply(Node usage, ValueNode value) {
    -                        ObjectState valueObj = getObjectState(state, value);
    -                        if (valueObj != null) {
    -                            virtual.add(valueObj);
    -                            effects.replaceFirstInput(usage, value, valueObj.virtual);
    -                        } else if (value instanceof VirtualObjectNode) {
    -                            ObjectState virtualObj = null;
    -                            for (ObjectState obj : state.getStates()) {
    -                                if (value == obj.virtual) {
    -                                    virtualObj = obj;
    -                                    break;
    -                                }
    -                            }
    -                            if (virtualObj != null) {
    -                                virtual.add(virtualObj);
    +                @Override
    +                public void apply(Node usage, ValueNode value) {
    +                    ObjectState valueObj = getObjectState(state, value);
    +                    if (valueObj != null) {
    +                        virtual.add(valueObj);
    +                        effects.replaceFirstInput(usage, value, valueObj.virtual);
    +                    } else if (value instanceof VirtualObjectNode) {
    +                        ObjectState virtualObj = null;
    +                        for (ObjectState obj : state.getStates()) {
    +                            if (value == obj.virtual) {
    +                                virtualObj = obj;
    +                                break;
                                 }
                             }
    -                    }
    -                });
    -                for (ObjectState obj : state.getStates()) {
    -                    if (obj.isVirtual() && obj.hasLocks()) {
    -                        virtual.add(obj);
    +                        if (virtualObj != null) {
    +                            virtual.add(virtualObj);
    +                        }
                         }
                     }
    +            });
    +            for (ObjectState obj : state.getStates()) {
    +                if (obj.isVirtual() && obj.hasLocks()) {
    +                    virtual.add(obj);
    +                }
    +            }
     
    -                ArrayDeque queue = new ArrayDeque<>(virtual);
    -                while (!queue.isEmpty()) {
    -                    ObjectState obj = queue.removeLast();
    -                    if (obj.isVirtual()) {
    -                        for (ValueNode field : obj.getEntries()) {
    -                            if (field instanceof VirtualObjectNode) {
    -                                ObjectState fieldObj = state.getObjectState((VirtualObjectNode) field);
    -                                if (fieldObj.isVirtual() && !virtual.contains(fieldObj)) {
    -                                    virtual.add(fieldObj);
    -                                    queue.addLast(fieldObj);
    -                                }
    +            ArrayDeque queue = new ArrayDeque<>(virtual);
    +            while (!queue.isEmpty()) {
    +                ObjectState obj = queue.removeLast();
    +                if (obj.isVirtual()) {
    +                    for (ValueNode field : obj.getEntries()) {
    +                        if (field instanceof VirtualObjectNode) {
    +                            ObjectState fieldObj = state.getObjectState((VirtualObjectNode) field);
    +                            if (fieldObj.isVirtual() && !virtual.contains(fieldObj)) {
    +                                virtual.add(fieldObj);
    +                                queue.addLast(fieldObj);
                                 }
                             }
                         }
                     }
    -                for (ObjectState obj : virtual) {
    -                    EscapeObjectState v;
    -                    if (obj.isVirtual()) {
    -                        ValueNode[] fieldState = obj.getEntries().clone();
    -                        for (int i = 0; i < fieldState.length; i++) {
    -                            ObjectState valueObj = getObjectState(state, fieldState[i]);
    -                            if (valueObj != null) {
    -                                if (valueObj.isVirtual()) {
    -                                    fieldState[i] = valueObj.virtual;
    -                                } else {
    -                                    fieldState[i] = valueObj.getMaterializedValue();
    -                                }
    +            }
    +            for (ObjectState obj : virtual) {
    +                EscapeObjectState v;
    +                if (obj.isVirtual()) {
    +                    ValueNode[] fieldState = obj.getEntries().clone();
    +                    for (int i = 0; i < fieldState.length; i++) {
    +                        ObjectState valueObj = getObjectState(state, fieldState[i]);
    +                        if (valueObj != null) {
    +                            if (valueObj.isVirtual()) {
    +                                fieldState[i] = valueObj.virtual;
    +                            } else {
    +                                fieldState[i] = valueObj.getMaterializedValue();
                                 }
                             }
    -                        v = new VirtualObjectState(obj.virtual, fieldState);
    -                    } else {
    -                        v = new MaterializedObjectState(obj.virtual, obj.getMaterializedValue());
                         }
    -                    effects.addVirtualMapping(frameState, v);
    +                    v = new VirtualObjectState(obj.virtual, fieldState);
    +                } else {
    +                    v = new MaterializedObjectState(obj.virtual, obj.getMaterializedValue());
                     }
    +                effects.addVirtualMapping(frameState, v);
                 }
             }
         }
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapePhase.java
    --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapePhase.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapePhase.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,7 +22,7 @@
      */
     package com.oracle.graal.virtual.phases.ea;
     
    -import static com.oracle.graal.phases.GraalOptions.*;
    +import static com.oracle.graal.compiler.common.GraalOptions.*;
     import static com.oracle.graal.virtual.phases.ea.PartialEscapePhase.Options.*;
     
     import java.util.*;
    @@ -72,9 +72,9 @@
         @Override
         protected Closure createEffectsClosure(PhaseContext context, SchedulePhase schedule) {
             if (readElimination) {
    -            return new PEReadEliminationClosure(schedule, context.getMetaAccess(), context.getAssumptions());
    +            return new PEReadEliminationClosure(schedule, context.getMetaAccess(), context.getConstantReflection(), context.getAssumptions());
             } else {
    -            return new PartialEscapeClosure.Final(schedule, context.getMetaAccess(), context.getAssumptions());
    +            return new PartialEscapeClosure.Final(schedule, context.getMetaAccess(), context.getConstantReflection(), context.getAssumptions());
             }
         }
     
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/ReadEliminationClosure.java
    --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/ReadEliminationClosure.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/ReadEliminationClosure.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -27,12 +27,12 @@
     import java.util.*;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.cfg.*;
     import com.oracle.graal.nodes.extended.*;
     import com.oracle.graal.nodes.java.*;
    -import com.oracle.graal.nodes.type.*;
     import com.oracle.graal.nodes.util.*;
     import com.oracle.graal.phases.schedule.*;
     import com.oracle.graal.virtual.phases.ea.ReadEliminationBlockState.CacheEntry;
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/VirtualUtil.java
    --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/VirtualUtil.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/VirtualUtil.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,11 +22,12 @@
      */
     package com.oracle.graal.virtual.phases.ea;
     
    -import static com.oracle.graal.phases.GraalOptions.*;
    +import static com.oracle.graal.compiler.common.GraalOptions.*;
     
     import java.util.*;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.*;
     import com.oracle.graal.debug.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.nodes.*;
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/VirtualizerToolImpl.java
    --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/VirtualizerToolImpl.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/VirtualizerToolImpl.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,7 +22,7 @@
      */
     package com.oracle.graal.virtual.phases.ea;
     
    -import static com.oracle.graal.phases.GraalOptions.*;
    +import static com.oracle.graal.compiler.common.GraalOptions.*;
     
     import java.util.*;
     
    @@ -40,11 +40,13 @@
     class VirtualizerToolImpl implements VirtualizerTool {
     
         private final MetaAccessProvider metaAccess;
    +    private final ConstantReflectionProvider constantReflection;
         private final Assumptions assumptions;
         private final PartialEscapeClosure closure;
     
    -    VirtualizerToolImpl(MetaAccessProvider metaAccess, Assumptions assumptions, PartialEscapeClosure closure) {
    +    VirtualizerToolImpl(MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection, Assumptions assumptions, PartialEscapeClosure closure) {
             this.metaAccess = metaAccess;
    +        this.constantReflection = constantReflection;
             this.assumptions = assumptions;
             this.closure = closure;
         }
    @@ -60,12 +62,16 @@
             return metaAccess;
         }
     
    +    public ConstantReflectionProvider getConstantReflectionProvider() {
    +        return constantReflection;
    +    }
    +
         @Override
         public Assumptions getAssumptions() {
             return assumptions;
         }
     
    -    public void reset(PartialEscapeBlockState newState, ValueNode newCurrent, FixedNode newPosition, GraphEffectList newEffects) {
    +    public void reset(PartialEscapeBlockState newState, ValueNode newCurrent, FixedNode newPosition, GraphEffectList newEffects) {
             deleted = false;
             state = newState;
             current = newCurrent;
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.word/src/com/oracle/graal/word/Word.java
    --- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/Word.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/Word.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,13 +22,14 @@
      */
     package com.oracle.graal.word;
     
    -import static com.oracle.graal.graph.UnsafeAccess.*;
    +import static com.oracle.graal.compiler.common.UnsafeAccess.*;
     
     import java.lang.annotation.*;
     
     import com.oracle.graal.api.code.*;
     import com.oracle.graal.api.meta.*;
    -import com.oracle.graal.graph.*;
    +import com.oracle.graal.compiler.common.*;
    +import com.oracle.graal.compiler.common.calc.*;
     import com.oracle.graal.nodes.HeapAccess.BarrierType;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.calc.*;
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.word/src/com/oracle/graal/word/nodes/SnippetLocationNode.java
    --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    +++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/nodes/SnippetLocationNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -0,0 +1,121 @@
    +/*
    + * Copyright (c) 2013, 2013, Oracle and/or its affiliates. All rights reserved.
    + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    + *
    + * This code is free software; you can redistribute it and/or modify it
    + * under the terms of the GNU General Public License version 2 only, as
    + * published by the Free Software Foundation.
    + *
    + * This code is distributed in the hope that it will be useful, but WITHOUT
    + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    + * version 2 for more details (a copy is included in the LICENSE file that
    + * accompanied this code).
    + *
    + * You should have received a copy of the GNU General Public License version
    + * 2 along with this work; if not, write to the Free Software Foundation,
    + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    + *
    + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    + * or visit www.oracle.com if you need additional information or have any
    + * questions.
    + */
    +package com.oracle.graal.word.nodes;
    +
    +import static com.oracle.graal.api.meta.LocationIdentity.*;
    +
    +import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.api.replacements.*;
    +import com.oracle.graal.compiler.common.*;
    +import com.oracle.graal.compiler.common.type.*;
    +import com.oracle.graal.graph.*;
    +import com.oracle.graal.graph.spi.*;
    +import com.oracle.graal.lir.gen.*;
    +import com.oracle.graal.nodes.*;
    +import com.oracle.graal.nodes.extended.*;
    +import com.oracle.graal.nodes.spi.*;
    +
    +/**
    + * Location node that can be used inside a snippet without having the elements (including the
    + * location identity and kind) as a snippet constant. Can represent locations in the form of [base +
    + * index * scale + disp]. When the location is created, all elements (base, index, scale, disp) are
    + * nodes. Both scale and disp must eventually canonicalize to {@link ConstantNode constants} so that
    + * this node can be canonicalized to a {@link IndexedLocationNode} or {@link ConstantLocationNode}.
    + */
    +public final class SnippetLocationNode extends LocationNode implements Canonicalizable {
    +
    +    private final SnippetReflectionProvider snippetReflection;
    +
    +    @Input private ValueNode valueKind;
    +    @Input(InputType.Association) private ValueNode locationIdentity;
    +    @Input private ValueNode displacement;
    +    @Input private ValueNode index;
    +    @Input private ValueNode indexScaling;
    +
    +    public static SnippetLocationNode create(SnippetReflectionProvider snippetReflection, ValueNode identity, ValueNode kind, ValueNode displacement, ValueNode index, ValueNode indexScaling,
    +                    Graph graph) {
    +        return graph.unique(new SnippetLocationNode(snippetReflection, identity, kind, displacement, index, indexScaling));
    +    }
    +
    +    private SnippetLocationNode(@InjectedNodeParameter SnippetReflectionProvider snippetReflection, ValueNode locationIdentity, ValueNode kind, ValueNode displacement) {
    +        this(snippetReflection, locationIdentity, kind, displacement, null, null);
    +    }
    +
    +    private SnippetLocationNode(@InjectedNodeParameter SnippetReflectionProvider snippetReflection, ValueNode locationIdentity, ValueNode kind, ValueNode displacement, ValueNode index,
    +                    ValueNode indexScaling) {
    +        super(StampFactory.object());
    +        this.snippetReflection = snippetReflection;
    +        this.valueKind = kind;
    +        this.locationIdentity = locationIdentity;
    +        this.displacement = displacement;
    +        this.index = index;
    +        this.indexScaling = indexScaling;
    +    }
    +
    +    @Override
    +    public Kind getValueKind() {
    +        if (valueKind.isConstant()) {
    +            return (Kind) snippetReflection.asObject(valueKind.asConstant());
    +        }
    +        throw new GraalInternalError("Cannot access kind yet because it is not constant: " + valueKind);
    +    }
    +
    +    @Override
    +    public LocationIdentity getLocationIdentity() {
    +        if (locationIdentity.isConstant()) {
    +            return (LocationIdentity) snippetReflection.asObject(locationIdentity.asConstant());
    +        }
    +        // We do not know our actual location identity yet, so be conservative.
    +        return ANY_LOCATION;
    +    }
    +
    +    @Override
    +    public Node canonical(CanonicalizerTool tool) {
    +        if (valueKind.isConstant() && locationIdentity.isConstant() && displacement.isConstant() && (indexScaling == null || indexScaling.isConstant())) {
    +            Kind constKind = (Kind) snippetReflection.asObject(valueKind.asConstant());
    +            LocationIdentity constLocation = (LocationIdentity) snippetReflection.asObject(locationIdentity.asConstant());
    +            long constDisplacement = displacement.asConstant().asLong();
    +            int constIndexScaling = indexScaling == null ? 0 : indexScaling.asConstant().asInt();
    +
    +            if (index == null || constIndexScaling == 0) {
    +                return ConstantLocationNode.create(constLocation, constKind, constDisplacement, graph());
    +            } else if (index.isConstant()) {
    +                return ConstantLocationNode.create(constLocation, constKind, index.asConstant().asLong() * constIndexScaling + constDisplacement, graph());
    +            } else {
    +                return IndexedLocationNode.create(constLocation, constKind, constDisplacement, index, graph(), constIndexScaling);
    +            }
    +        }
    +        return this;
    +    }
    +
    +    @Override
    +    public Value generateAddress(NodeMappableLIRBuilder builder, LIRGeneratorTool gen, Value base) {
    +        throw new GraalInternalError("locationIdentity must be a constant so that this node can be canonicalized: " + locationIdentity);
    +    }
    +
    +    @NodeIntrinsic
    +    public static native Location constantLocation(LocationIdentity identity, Kind kind, long displacement);
    +
    +    @NodeIntrinsic
    +    public static native Location indexedLocation(LocationIdentity identity, Kind kind, long displacement, int index, int indexScaling);
    +}
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.word/src/com/oracle/graal/word/nodes/WordCastNode.java
    --- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/nodes/WordCastNode.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/nodes/WordCastNode.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -23,11 +23,11 @@
     package com.oracle.graal.word.nodes;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.graph.spi.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
     import com.oracle.graal.word.phases.*;
     
     /**
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeRewriterPhase.java
    --- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeRewriterPhase.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeRewriterPhase.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -27,6 +27,10 @@
     import java.lang.reflect.*;
     
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.api.replacements.*;
    +import com.oracle.graal.compiler.common.*;
    +import com.oracle.graal.compiler.common.calc.*;
    +import com.oracle.graal.compiler.common.type.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.HeapAccess.BarrierType;
    @@ -49,13 +53,15 @@
     public class WordTypeRewriterPhase extends Phase {
     
         protected final MetaAccessProvider metaAccess;
    +    protected final SnippetReflectionProvider snippetReflection;
         protected final ResolvedJavaType wordBaseType;
         protected final ResolvedJavaType wordImplType;
         protected final ResolvedJavaType objectAccessType;
         protected final Kind wordKind;
     
    -    public WordTypeRewriterPhase(MetaAccessProvider metaAccess, Kind wordKind) {
    +    public WordTypeRewriterPhase(MetaAccessProvider metaAccess, SnippetReflectionProvider snippetReflection, Kind wordKind) {
             this.metaAccess = metaAccess;
    +        this.snippetReflection = snippetReflection;
             this.wordKind = wordKind;
             this.wordBaseType = metaAccess.lookupJavaType(WordBase.class);
             this.wordImplType = metaAccess.lookupJavaType(Word.class);
    @@ -86,7 +92,7 @@
                 if (node.isConstant()) {
                     ConstantNode oldConstant = (ConstantNode) node;
                     assert oldConstant.getValue().getKind() == Kind.Object;
    -                WordBase value = (WordBase) oldConstant.getValue().asObject();
    +                WordBase value = (WordBase) snippetReflection.asObject(oldConstant.getValue());
                     ConstantNode newConstant = ConstantNode.forIntegerKind(wordKind, value.rawValue(), node.graph());
                     graph.replaceFloating(oldConstant, newConstant);
     
    @@ -138,7 +144,7 @@
          * own and not in the stamp, {@link #changeToWord} does not perform all necessary changes.
          */
         protected void rewriteAccessIndexed(StructuredGraph graph, AccessIndexedNode node) {
    -        ResolvedJavaType arrayType = ObjectStamp.typeOrNull(node.array());
    +        ResolvedJavaType arrayType = StampTool.typeOrNull(node.array());
             /*
              * There are cases where the array does not have a known type yet, i.e., the type is null.
              * In that case we assume it is not a word type.
    @@ -221,14 +227,14 @@
                     assert arguments.size() == 3;
                     Kind readKind = asKind(callTargetNode.returnType());
                     LocationNode location = makeLocation(graph, arguments.get(1), readKind, ANY_LOCATION);
    -                BarrierType barrierType = (BarrierType) arguments.get(2).asConstant().asObject();
    +                BarrierType barrierType = (BarrierType) snippetReflection.asObject(arguments.get(2).asConstant());
                     replace(invoke, readOp(graph, arguments.get(0), invoke, location, barrierType, true));
                     break;
                 }
                 case WRITE:
                 case INITIALIZE: {
                     assert arguments.size() == 3 || arguments.size() == 4;
    -                Kind writeKind = asKind(targetMethod.getSignature().getParameterType(Modifier.isStatic(targetMethod.getModifiers()) ? 2 : 1, targetMethod.getDeclaringClass()));
    +                Kind writeKind = asKind(targetMethod.getSignature().getParameterType(targetMethod.isStatic() ? 2 : 1, targetMethod.getDeclaringClass()));
                     LocationNode location;
                     if (arguments.size() == 3) {
                         location = makeLocation(graph, arguments.get(1), writeKind, LocationIdentity.ANY_LOCATION);
    @@ -359,10 +365,10 @@
     
         private LocationNode makeLocation(StructuredGraph graph, ValueNode offset, Kind readKind, ValueNode locationIdentity) {
             if (locationIdentity.isConstant()) {
    -            return makeLocation(graph, offset, readKind, (LocationIdentity) locationIdentity.asConstant().asObject());
    +            return makeLocation(graph, offset, readKind, (LocationIdentity) snippetReflection.asObject(locationIdentity.asConstant()));
             }
    -        return SnippetLocationNode.create(locationIdentity, ConstantNode.forObject(readKind, metaAccess, graph), ConstantNode.forLong(0, graph), fromSigned(graph, offset),
    -                        ConstantNode.forInt(1, graph), graph);
    +        return SnippetLocationNode.create(snippetReflection, locationIdentity, ConstantNode.forConstant(snippetReflection.forObject(readKind), metaAccess, graph), ConstantNode.forLong(0, graph),
    +                        fromSigned(graph, offset), ConstantNode.forInt(1, graph), graph);
         }
     
         protected LocationNode makeLocation(StructuredGraph graph, ValueNode offset, Kind readKind, LocationIdentity locationIdentity) {
    @@ -376,7 +382,7 @@
              * The read must not float outside its block otherwise it may float above an explicit zero
              * check on its base address.
              */
    -        read.setGuard(AbstractBeginNode.prevBegin(invoke.asNode()));
    +        read.setGuard(BeginNode.prevBegin(invoke.asNode()));
             return read;
         }
     
    @@ -397,7 +403,7 @@
         }
     
         protected boolean isWord(ValueNode node) {
    -        return isWord(ObjectStamp.typeOrNull(node));
    +        return isWord(StampTool.typeOrNull(node));
         }
     
         protected boolean isWord(ResolvedJavaType type) {
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeVerificationPhase.java
    --- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeVerificationPhase.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeVerificationPhase.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -22,9 +22,9 @@
      */
     package com.oracle.graal.word.phases;
     
    -import java.lang.reflect.*;
    -
     import com.oracle.graal.api.meta.*;
    +import com.oracle.graal.api.replacements.*;
    +import com.oracle.graal.compiler.common.*;
     import com.oracle.graal.graph.*;
     import com.oracle.graal.graph.Node.NodeIntrinsic;
     import com.oracle.graal.nodes.*;
    @@ -44,8 +44,8 @@
     
         private final WordTypeRewriterPhase wordAccess;
     
    -    public WordTypeVerificationPhase(MetaAccessProvider metaAccess, Kind wordKind) {
    -        this.wordAccess = new WordTypeRewriterPhase(metaAccess, wordKind);
    +    public WordTypeVerificationPhase(MetaAccessProvider metaAccess, SnippetReflectionProvider snippetReflection, Kind wordKind) {
    +        this.wordAccess = new WordTypeRewriterPhase(metaAccess, snippetReflection, wordKind);
         }
     
         @Override
    @@ -108,7 +108,7 @@
             if (method.getAnnotation(NodeIntrinsic.class) == null) {
                 Invoke invoke = (Invoke) callTarget.usages().first();
                 NodeInputList arguments = callTarget.arguments();
    -            boolean isStatic = Modifier.isStatic(method.getModifiers());
    +            boolean isStatic = method.isStatic();
                 int argc = 0;
                 if (!isStatic) {
                     ValueNode receiver = arguments.get(argc);
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/TypeSystem.java
    --- a/graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/TypeSystem.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/TypeSystem.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -61,12 +61,12 @@
      *
      * {@literal @}TypeSystem(types = {boolean.class, int.class, double.class})
      * public abstract class ExampleTypeSystem {
    - *
    + * 
      *     {@literal @}TypeCheck
      *     public boolean isInteger(Object value) {
      *         return value instanceof Integer || value instanceof Double;
      *     }
    - *
    + * 
      *     {@literal @}TypeCast
      *     public double asInteger(Object value) {
      *         return ((Number)value).doubleValue();
    @@ -85,6 +85,6 @@
         /**
          * The list of types as child elements of the {@link TypeSystem}. Each precedes its super type.
          */
    -    Class[] value();
    +    Class[] value();
     
     }
    diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/RootNodeTest.java
    --- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/RootNodeTest.java	Wed Apr 23 15:22:20 2014 +0200
    +++ b/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/RootNodeTest.java	Wed Apr 23 15:48:38 2014 +0200
    @@ -30,7 +30,7 @@
     
     /**
      * 

    Creating a Root Node

    - * + * *

    * A Truffle root node is the entry point into a Truffle tree that represents a guest language * method. It contains a {@link RootNode#execute(VirtualFrame)} method that can return a @@ -38,9 +38,9 @@ * must however never be called directly. Instead, the Truffle runtime must be used to create a * {@link CallTarget} object from a root node using the * {@link TruffleRuntime#createCallTarget(RootNode)} method. This call target object can then be - * executed using the {@link CallTarget#call()} method or one of its overloads. + * executed using the {@link CallTarget#call(Object...)} method or one of its overloads. *

    - * + * *

    * The next part of the Truffle API introduction is at * {@link com.oracle.truffle.api.test.ChildNodeTest}. diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/ThreadSafetyTest.java --- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/ThreadSafetyTest.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/ThreadSafetyTest.java Wed Apr 23 15:48:38 2014 +0200 @@ -24,7 +24,6 @@ import static org.junit.Assert.*; -import java.io.*; import java.util.*; import java.util.concurrent.*; import java.util.concurrent.atomic.*; @@ -50,7 +49,7 @@ RecursiveCallNode callNode = new RecursiveCallNode(new ConstNode(42)); TestRootNode rootNode2 = new TestRootNode(new RewritingNode(new RewritingNode(new RewritingNode(new RewritingNode(new RewritingNode(callNode)))))); final CallTarget target2 = runtime.createCallTarget(rootNode2); - callNode.setCallNode(runtime.createCallNode(target2)); + callNode.setCallNode(runtime.createDirectCallNode(target2)); NodeUtil.verify(rootNode2); testTarget(target1, 47, 1_000_000); @@ -68,8 +67,7 @@ assertEquals(expectedResult, result); ai.incrementAndGet(); } catch (Throwable t) { - PrintStream out = System.out; - out.println(t); + t.printStackTrace(System.out); } } }); @@ -165,7 +163,7 @@ } static class RecursiveCallNode extends ValueNode { - @Child CallNode callNode; + @Child DirectCallNode callNode; @Child private ValueNode valueNode; RecursiveCallNode(ValueNode value) { @@ -176,13 +174,13 @@ int execute(VirtualFrame frame) { int arg = (Integer) frame.getArguments()[0]; if (arg > 0) { - return (int) callNode.call(new Object[]{(arg - 1)}); + return (int) callNode.call(frame, new Object[]{(arg - 1)}); } else { return valueNode.execute(frame); } } - void setCallNode(CallNode callNode) { + void setCallNode(DirectCallNode callNode) { this.callNode = insert(callNode); } } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/CallTarget.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/CallTarget.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/CallTarget.java Wed Apr 23 15:48:38 2014 +0200 @@ -27,9 +27,7 @@ /** * Represents the target of a call. */ -public abstract class CallTarget { - - public static final Object[] NO_ARGUMENTS = new Object[0]; +public interface CallTarget { /** * Calls this target as a root method.. @@ -37,9 +35,5 @@ * @param arguments passed arguments as an object array * @return the return result of the call */ - public abstract Object call(Object[] arguments); - - public final Object call() { - return call(NO_ARGUMENTS); - } + Object call(Object... arguments); } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/CompilerDirectives.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/CompilerDirectives.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/CompilerDirectives.java Wed Apr 23 15:48:38 2014 +0200 @@ -84,6 +84,15 @@ } /** + * Returns a boolean value indicating whether the method is executed in the compiled code. + * + * @return {@code false} when executed in the interpreter, {@code true} in compiled code. + */ + public static boolean inCompiledCode() { + return false; + } + + /** * Directive for the compiler that the given runnable should only be executed in the interpreter * and ignored in the compiled code. * @@ -619,4 +628,13 @@ @Target({ElementType.TYPE}) public @interface ValueType { } + + /** + * Ensures that the given object is not virtual, i.e., not removed by Escape Analysis at the + * point of this call. + * + * @param obj the object to exclude from Escape Analysis + */ + public static void materialize(Object obj) { + } } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/ExecutionContext.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/ExecutionContext.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/ExecutionContext.java Wed Apr 23 15:48:38 2014 +0200 @@ -24,11 +24,12 @@ */ package com.oracle.truffle.api; -import com.oracle.truffle.api.debug.*; +import com.oracle.truffle.api.instrument.*; import com.oracle.truffle.api.source.*; /** - * Information about the runtime context of a Truffle program. + * Access to information and basic services in the runtime context for a Truffle-implemented guest + * language. *

    * Disclaimer: this interface is under development and will change. */ @@ -46,8 +47,20 @@ SourceManager getSourceManager(); /** - * Gets access to debugging services. Returns an inert instance if no services installed. + * Gets access to AST instrumentation services. + */ + Instrumentation instrumentation(); + + /** + * Access to information visualization services for the specific language. */ - DebugContext getDebugContext(); + Visualizer visualizer(); + /** + * Add instrumentation to subsequently constructed Truffle ASTs for the guest language; every + * one added will have the opportunity to add instrumentation. + * + * @throws IllegalArgumentException if prober not usable for the guest language. + */ + void addNodeProber(ASTNodeProber nodeProber); } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/RootCallTarget.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/RootCallTarget.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/RootCallTarget.java Wed Apr 23 15:48:38 2014 +0200 @@ -30,22 +30,7 @@ * Represents the target of a call to a {@link RootNode}, i.e., to another tree of nodes. Instances * of this class can be created using {@link TruffleRuntime#createCallTarget(RootNode)}. */ -public abstract class RootCallTarget extends CallTarget { - - private final RootNode rootNode; - - public RootCallTarget(RootNode function) { - this.rootNode = function; - this.rootNode.setCallTarget(this); - this.rootNode.adoptChildren(); - } +public interface RootCallTarget extends CallTarget { - @Override - public String toString() { - return rootNode.toString(); - } - - public final RootNode getRootNode() { - return rootNode; - } + RootNode getRootNode(); } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/TruffleRuntime.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/TruffleRuntime.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/TruffleRuntime.java Wed Apr 23 15:48:38 2014 +0200 @@ -50,7 +50,20 @@ */ RootCallTarget createCallTarget(RootNode rootNode); - CallNode createCallNode(CallTarget target); + /** + * Creates a new runtime specific version of {@link DirectCallNode}. + * + * @param target the direct {@link CallTarget} to call + * @return the new call node + */ + DirectCallNode createDirectCallNode(CallTarget target); + + /** + * Creates a new runtime specific version of {@link IndirectCallNode}. + * + * @return the new call node + */ + IndirectCallNode createIndirectCallNode(); /** * Creates a new assumption object that can be checked and invalidated. @@ -90,4 +103,19 @@ * @return the newly created materialized frame object */ MaterializedFrame createMaterializedFrame(Object[] arguments, FrameDescriptor frameDescriptor); + + /** + * Accesses the current stack, i.e., the contents of the {@link Frame}s and the associated + * {@link CallTarget}s. + * + * @return a lazy collection of {@link FrameInstance}. + */ + Iterable getStackTrace(); + + /** + * Accesses the current frame, i.e., the frame of the closest {@link CallTarget}. It is + * important to note that this {@link FrameInstance} supports only slow path access. + */ + FrameInstance getCurrentFrame(); + } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/ASTPrinter.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/ASTPrinter.java Wed Apr 23 15:22:20 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,65 +0,0 @@ -/* - * Copyright (c) 2013, 2014, 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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.truffle.api.debug; - -import java.io.*; - -import com.oracle.truffle.api.nodes.*; - -/** - * Language-agnostic access to AST-based debugging support. - *

    - * WARNING: this interface is under development and will change substantially. - */ -public interface ASTPrinter { - - /** - * Prints a textual AST display, one line per node, with nesting. - * - * @param p - * @param node the root node of the display. - * @param maxDepth the maximum number of levels to print below the root - * @param markNode a node to mark with a textual arrow prefix, if present. - */ - void printTree(PrintWriter p, Node node, int maxDepth, Node markNode); - - /** - * Creates a textual AST display, one line per node, with nesting. - * - * @param node the root node of the display. - * @param maxDepth the maximum number of levels to print below the root - * @param markNode a node to mark with a textual arrow prefix, if present. - */ - String printTreeToString(Node node, int maxDepth, Node markNode); - - /** - * Creates a textual AST display, one line per node, with nesting. - * - * @param node the root node of the display. - * @param maxDepth the maximum number of levels to print below the root - */ - String printTreeToString(Node node, int maxDepth); - -} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/DebugContext.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/DebugContext.java Wed Apr 23 15:22:20 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,72 +0,0 @@ -/* - * Copyright (c) 2014, 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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.truffle.api.debug; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.nodes.instrument.*; - -/** - * Access to the suite of facilities available when debugging is enabled. - */ -public interface DebugContext { - - /** - * Access to the Truffle execution context being debugged. - */ - ExecutionContext getContext(); - - /** - * Access to the appropriate implementation of AST node instrumentation. - */ - NodeInstrumenter getNodeInstrumenter(); - - /** - * Access to the management of breakpoints, notifications, etc. - */ - DebugManager getDebugManager(); - - /** - * Gets a printer for Truffle ASTs helpful for debugging guest language implementations. - */ - ASTPrinter getASTPrinter(); - - /** - * Converts a value in the guest language to a display string. - */ - String displayValue(Object value); - - /** - * Converts a slot identifier in the guest language to a display string. - */ - String displayIdentifier(FrameSlot slot); - - /** - * Invokes appropriate debugging action when Truffle execution halts. - */ - void executionHalted(Node node, MaterializedFrame frame); - -} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/DebugManager.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/DebugManager.java Wed Apr 23 15:22:20 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2013, 2014, 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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.truffle.api.debug; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.nodes.instrument.*; -import com.oracle.truffle.api.nodes.instrument.InstrumentationProbeNode.ProbeChain; - -/** - * Language-agnostic access to AST-based debugging support. - *

    - * Disclaimer: this interface is under development and will change. - */ -public interface DebugManager { - - /** - * Informs the {@link DebugManager} that the Guest Language runtime is starting to load a - * source. Care should be taken to ensure that under any circumstance there is always a - * following call to {@link #notifyFinishedLoading(Source)} with the same argument. - */ - void notifyStartLoading(Source source); - - /** - * Informs the {@link DebugManager} that the Guest Language runtime has finished loading a - * source. Care should be taken to ensure that under any circumstance there is always a prior - * call to {@link #notifyStartLoading(Source)} with the same argument. - */ - void notifyFinishedLoading(Source source); - - /** - * Return a reference to the (canonical) instrumentation site associated with a particular - * source code location; this site will have effect on any Truffle/AST implementation - * corresponding to the source location, even if the AST is copied multiple times. - */ - ProbeChain getProbeChain(SourceSection sourceSection); - - /** - * Informs the {@link DebugManager} that Truffle execution has halted; execution will resume - * when this method returns. - * - * @param astNode a guest language AST node that represents the current execution site, assumed - * not to be any kind of {@link InstrumentationNode}, - * @param frame execution frame at the site where execution suspended - */ - void haltedAt(Node astNode, MaterializedFrame frame); - -} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/DefaultDebugManager.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/DefaultDebugManager.java Wed Apr 23 15:22:20 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,111 +0,0 @@ -/* - * Copyright (c) 2014, 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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.truffle.api.debug; - -import java.util.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.nodes.instrument.InstrumentationProbeNode.ProbeChain; -import com.oracle.truffle.api.source.*; - -/** - * A minimal, language-agnostic implementation that tracks loaded sources, and keeps maps describing - * what locations in the source have instrumentation available. This implementation will do nothing - * unless there are calls to it during AST construction, notably {@link #notifyStartLoading(Source)} - * and {@link #notifyFinishedLoading(Source)} and there are at least some AST nodes being - * instrumented. - */ -public class DefaultDebugManager implements DebugManager { - - private final Set loadedSources = new HashSet<>(); - - private Source beingLoaded = null; - - /** - * Map: SourceSection ==> probe chain associated with that source section in an AST. - */ - private final Map srcToProbeChain = new HashMap<>(); - - /** - * Map: Source lines ==> probe chains associated with source sections starting on the line. - */ - private final Map> lineToProbeChains = new HashMap<>(); - - private final ExecutionContext context; - - public DefaultDebugManager(ExecutionContext context) { - this.context = context; - } - - /** - * Gets the {@linkplain ProbeChain probe} associated with a particular {@link SourceSection - * source location}, creating a new one if needed. There should only be one probe associated - * with each {@linkplain SourceSection source location}. - */ - public ProbeChain getProbeChain(SourceSection sourceSection) { - assert sourceSection != null; - assert sourceSection.getSource().equals(beingLoaded); - - ProbeChain probeChain = srcToProbeChain.get(sourceSection); - - if (probeChain != null) { - return probeChain; - } - probeChain = new ProbeChain(context, sourceSection, null); - - // Register new ProbeChain by unique SourceSection - srcToProbeChain.put(sourceSection, probeChain); - - // Register new ProbeChain by source line, there may be more than one - // Create line location for map key - final SourceLineLocation lineLocation = new SourceLineLocation(sourceSection.getSource(), sourceSection.getStartLine()); - - Set probeChains = lineToProbeChains.get(lineLocation); - if (probeChains == null) { - probeChains = new HashSet<>(); - lineToProbeChains.put(lineLocation, probeChains); - } - probeChains.add(probeChain); - - return probeChain; - } - - public void notifyStartLoading(Source source) { - assert beingLoaded == null; - beingLoaded = source; - } - - public void notifyFinishedLoading(Source source) { - assert source == beingLoaded; - loadedSources.add(source); - beingLoaded = null; - } - - public void haltedAt(Node astNode, MaterializedFrame frame) { - } - -} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/KillException.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/KillException.java Wed Apr 23 15:22:20 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2014, 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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.truffle.api.debug; - -import com.oracle.truffle.api.nodes.*; - -/** - * Controls breaking out of an execution context, such as a shell or eval. - */ -public final class KillException extends ControlFlowException { - - private static final long serialVersionUID = 3163641880088766957L; -} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/QuitException.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/QuitException.java Wed Apr 23 15:22:20 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2014, 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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.truffle.api.debug; - -import com.oracle.truffle.api.nodes.*; - -/** - * Controls breaking out of all executions and ending Truffle execution. - */ -public final class QuitException extends ControlFlowException { - - private static final long serialVersionUID = -4301115629772778413L; -} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameInstance.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameInstance.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2014, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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.truffle.api.frame; + +import com.oracle.truffle.api.*; +import com.oracle.truffle.api.nodes.*; + +public interface FrameInstance { + + public static enum FrameAccess { + NONE, + READ_ONLY, + READ_WRITE, + MATERIALIZE + } + + Frame getFrame(FrameAccess access, boolean slowPath); + + boolean isVirtualFrame(); + + DirectCallNode getCallNode(); + + CallTarget getCallTarget(); + + CallTarget getTargetCallTarget(); +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/AbstractExecutionContext.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/AbstractExecutionContext.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2014, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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.truffle.api.impl; + +import com.oracle.truffle.api.*; +import com.oracle.truffle.api.instrument.*; +import com.oracle.truffle.api.instrument.impl.*; +import com.oracle.truffle.api.source.*; + +public abstract class AbstractExecutionContext implements ExecutionContext { + + private final SourceManager sourceManager = new SourceManager(); + private final Instrumentation instrumentation; + private Visualizer visualizer = new DefaultVisualizer(); + protected ASTProber astProber = null; + + protected AbstractExecutionContext() { + this.instrumentation = InstrumentationFactory.create(this); + } + + public final SourceManager getSourceManager() { + return sourceManager; + } + + public final Instrumentation instrumentation() { + return instrumentation; + } + + public Visualizer visualizer() { + return visualizer; + } + + public void addNodeProber(ASTNodeProber nodeProber) { + if (astProber == null) { + throw new IllegalStateException("No ASTProber installed in context"); + } + astProber.addNodeProber(nodeProber); + } + + /** + * Assign guest language-specific visualization support for tools. This must be assigned outside + * the implementation context to avoid build circularities. + */ + public void setVisualizer(Visualizer visualizer) { + this.visualizer = visualizer; + } + + /** + * Assigns a guest language-specific manager for using {@link ASTNodeProber}s added by tools to + * instrument ASTs with {@link Probe}s at specified nodes. This must be assigned outside the + * implementation context to avoid build circularities. It must also be set before any + * instrumentation probe implementations are assigned. + */ + public void setASTProber(ASTProber astProber) { + this.astProber = astProber; + } + + /** + * Gets a guest language-specific {@link ASTNodeProber} that will apply all that have been + * added; {@code null} if no instrumentation in AST. + */ + public ASTNodeProber getCombinedNodeProber() { + return astProber == null ? null : astProber.getCombinedNodeProber(); + } + + public abstract void setInstrumentEventListener(InstrumentEventListener listener); + + public abstract InstrumentEventListener getInstrumentEventListener(); +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultCallNode.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultCallNode.java Wed Apr 23 15:22:20 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,74 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.truffle.api.impl; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.nodes.*; - -public class DefaultCallNode extends CallNode { - - public DefaultCallNode(CallTarget target) { - super(target); - } - - @Override - public Object call(Object[] arguments) { - return getCurrentCallTarget().call(arguments); - } - - @Override - public void inline() { - } - - @Override - public CallTarget getSplitCallTarget() { - return null; - } - - @Override - public boolean split() { - return false; - } - - @Override - public boolean isSplittable() { - return false; - } - - @Override - public boolean isInlined() { - return false; - } - - @Override - public boolean isInlinable() { - return false; - } - - @Override - public String toString() { - return (getParent() != null ? getParent().toString() : super.toString()) + " call " + getCurrentCallTarget().toString(); - } -} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultCallTarget.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultCallTarget.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultCallTarget.java Wed Apr 23 15:48:38 2014 +0200 @@ -32,14 +32,27 @@ * This is an implementation-specific class. Do not use or instantiate it. Instead, use * {@link TruffleRuntime#createCallTarget(RootNode)} to create a {@link RootCallTarget}. */ -public class DefaultCallTarget extends RootCallTarget { +public class DefaultCallTarget implements RootCallTarget { + + private final RootNode rootNode; - protected DefaultCallTarget(RootNode function) { - super(function); + public DefaultCallTarget(RootNode function) { + this.rootNode = function; + this.rootNode.adoptChildren(); + this.rootNode.setCallTarget(this); } @Override - public Object call(Object[] args) { + public String toString() { + return rootNode.toString(); + } + + public final RootNode getRootNode() { + return rootNode; + } + + @Override + public Object call(Object... args) { VirtualFrame frame = new DefaultVirtualFrame(getRootNode().getFrameDescriptor(), args); return getRootNode().execute(frame); } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultDirectCallNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultDirectCallNode.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,86 @@ +/* + * 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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.truffle.api.impl; + +import com.oracle.truffle.api.*; +import com.oracle.truffle.api.frame.*; +import com.oracle.truffle.api.nodes.*; + +/** + * This is runtime specific API. Do not use in a guest language. + */ +public final class DefaultDirectCallNode extends DirectCallNode { + + private boolean inliningForced; + + public DefaultDirectCallNode(CallTarget target) { + super(target); + } + + @Override + public Object call(VirtualFrame frame, Object[] arguments) { + return getCurrentCallTarget().call(arguments); + } + + @Override + public void forceInlining() { + inliningForced = true; + } + + @Override + public boolean isInliningForced() { + return inliningForced; + } + + @Override + public CallTarget getSplitCallTarget() { + return null; + } + + @Override + public boolean split() { + return false; + } + + @Override + public boolean isInlined() { + return false; + } + + @Override + public boolean isSplittable() { + return false; + } + + @Override + public boolean isInlinable() { + return false; + } + + @Override + public String toString() { + return (getParent() != null ? getParent().toString() : super.toString()) + " call " + getCurrentCallTarget().toString(); + } +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultIndirectCallNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultIndirectCallNode.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,41 @@ +/* + * 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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.truffle.api.impl; + +import com.oracle.truffle.api.*; +import com.oracle.truffle.api.frame.*; +import com.oracle.truffle.api.nodes.*; + +/** + * This is runtime specific API. Do not use in a guest language. + */ +final class DefaultIndirectCallNode extends IndirectCallNode { + + @Override + public Object call(VirtualFrame frame, CallTarget target, Object[] arguments) { + return target.call(arguments); + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultTruffleRuntime.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultTruffleRuntime.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultTruffleRuntime.java Wed Apr 23 15:48:38 2014 +0200 @@ -53,8 +53,12 @@ return new DefaultCallTarget(rootNode); } - public CallNode createCallNode(CallTarget target) { - return new DefaultCallNode(target); + public DirectCallNode createDirectCallNode(CallTarget target) { + return new DefaultDirectCallNode(target); + } + + public IndirectCallNode createIndirectCallNode() { + return new DefaultIndirectCallNode(); } @Override @@ -81,4 +85,14 @@ public Assumption createAssumption(String name) { return new DefaultAssumption(name); } + + public Iterable getStackTrace() { + // TODO(lstadler) implement this using ThreadLocal + return null; + } + + public FrameInstance getCurrentFrame() { + // TODO(lstadler) implement this using ThreadLocal + return null; + } } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/ASTNodeProber.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/ASTNodeProber.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2014, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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.truffle.api.instrument; + +import com.oracle.truffle.api.nodes.*; + +/** + * Implementation of a policy for instrumenting inserting a {@link Probe} at a Truffle AST + * node. + *

    + * Note that this interface is guest language agnostic, but current extensions are + * language-specific. This will be revisited. + *

    + * Disclaimer: experimental interface under development. Really! + */ +public interface ASTNodeProber { + + /** + * Optionally applies instrumentation at a Truffle AST node, depending on guest + * language characteristics and use-case policy. + *

      + *
    • if no instrumentation is to be applied, returns the AST node unmodified;
    • + *
    • if an AST node is to be instrumented, then returns a newly created {@link Wrapper} that + * decorates the AST node and notifies an associated {@link Probe} of all + * {@link ExecutionEvents} at the wrapped AST node.
    • + *
    • if the argument is itself a {@link Wrapper}, i.e. if the AST node at this site has + * already been wrapped, then the wrapper is returned (with the possible addition of a + * {@linkplain PhylumTag tag}).
    • + *
    + * + * @param astNode an AST node to which instrumentation might be applied + * @param tag an optional category directing how the node, if instrumented, should be perceived + * by tool users + * @param args additional arguments for instrumentation specific to a particular guest language + * @return if no instrumentation should be applied or if the node is a {@link Wrapper} then the + * unmodified node; otherwise a newly created {@link Wrapper} (whose child + * {@code astNode}) with an associated {@link Probe} . + */ + + Node probeAs(Node astNode, PhylumTag tag, Object... args); +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/ASTPrinter.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/ASTPrinter.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2013, 2014, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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.truffle.api.instrument; + +import java.io.*; + +import com.oracle.truffle.api.nodes.*; + +/** + * Language-agnostic access to AST-based debugging support. + *

    + * WARNING: this interface is under development and will change substantially. + */ +public interface ASTPrinter { + + /** + * Prints a textual AST display, one line per node, with nesting. + * + * @param p + * @param node the root node of the display. + * @param maxDepth the maximum number of levels to print below the root + * @param markNode a node to mark with a textual arrow prefix, if present. + */ + void printTree(PrintWriter p, Node node, int maxDepth, Node markNode); + + /** + * Creates a textual AST display, one line per node, with nesting. + * + * @param node the root node of the display. + * @param maxDepth the maximum number of levels to print below the root + * @param markNode a node to mark with a textual arrow prefix, if present. + */ + String printTreeToString(Node node, int maxDepth, Node markNode); + + /** + * Creates a textual AST display, one line per node, with nesting. + * + * @param node the root node of the display. + * @param maxDepth the maximum number of levels to print below the root + */ + String printTreeToString(Node node, int maxDepth); + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/ASTProber.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/ASTProber.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2013, 2014, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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.truffle.api.instrument; + +/** + * Implementation of a policy for instrumenting Truffle ASTs with {@link Probe}s at + * particular nodes by inserting node {@link Wrapper}s. + *

    + * Disclaimer: experimental interface under development. + */ +public interface ASTProber { + + // TODO (mlvdv) This is a provisional interface, more of a marker really + // TODO (mlvdv) AST probing should eventually be done with visitors. + + void addNodeProber(ASTNodeProber nodeProber); + + /** + * Gets a prober that applies all added {@link ASTNodeProber}s. + */ + ASTNodeProber getCombinedNodeProber(); +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/ExecutionEvents.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/ExecutionEvents.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,179 @@ +/* + * Copyright (c) 2013, 2014, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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.truffle.api.instrument; + +import com.oracle.truffle.api.frame.*; +import com.oracle.truffle.api.nodes.*; + +/** + * Normal events during program execution at Truffle AST nodes that are reported via a {@link Probe} + * associated with the node, and made available to the probe's attached {@link Instrument}s. + *

    + * Disclaimer: experimental interface under development. + */ +public interface ExecutionEvents { + + /** + * Notifies that an AST node's execute method has just been entered. Callers should assure that + * a matching call to {@link #leave(Node, VirtualFrame, Object)} always follows. + * + * @param astNode The AST node on which the execute method is being called + * @param frame The frame being passed to the execute method + */ + void enter(Node astNode, VirtualFrame frame); + + /** + * Notifies that an AST Node's void-valued execute method is about to exit. + *

    + * Callers should assure (via {@code try/finally}) that a matching call to this method always + * follows a call to {@link #enter(Node, VirtualFrame)}. + * + * @param astNode The AST node on which the execute method is being called + * @param frame The frame that was passed to the execute method + */ + void leave(Node astNode, VirtualFrame frame); + + /** + * Notifies that an AST Node's boolean-valued execute method is about to exit. + *

    + * Callers should assure (via {@code try/finally}) that a matching call to this method always + * follows a call to {@link #enter(Node, VirtualFrame)}. + * + * @param astNode The AST node on which the execute method is being called + * @param frame The frame that was passed to the execute method + * @param result The result of the call to the execute method. + */ + void leave(Node astNode, VirtualFrame frame, boolean result); + + /** + * Notifies that an AST Node's byte-valued execute method is about to exit. + *

    + * Callers should assure (via {@code try/finally}) that a matching call to this method always + * follows a call to {@link #enter(Node, VirtualFrame)}. + * + * @param astNode The AST node on which the execute method is being called + * @param frame The frame that was passed to the execute method + * @param result The result of the call to the execute method. + */ + void leave(Node astNode, VirtualFrame frame, byte result); + + /** + * Notifies that an AST Node's short-valued execute method is about to exit. + *

    + * Callers should assure (via {@code try/finally}) that a matching call to this method always + * follows a call to {@link #enter(Node, VirtualFrame)}. + * + * @param astNode The AST node on which the execute method is being called + * @param frame The frame that was passed to the execute method + * @param result The result of the call to the execute method. + */ + void leave(Node astNode, VirtualFrame frame, short result); + + /** + * Notifies that an AST Node's integer-valued execute method is about to exit. + *

    + * Callers should assure (via {@code try/finally}) that a matching call to this method always + * follows a call to {@link #enter(Node, VirtualFrame)}. + * + * @param astNode The AST node on which the execute method is being called + * @param frame The frame that was passed to the execute method + * @param result The result of the call to the execute method. + */ + void leave(Node astNode, VirtualFrame frame, int result); + + /** + * Notifies that an AST Node's long-valued execute method is about to exit. + *

    + * Callers should assure (via {@code try/finally}) that a matching call to this method always + * follows a call to {@link #enter(Node, VirtualFrame)}. + * + * @param astNode The AST node on which the execute method is being called + * @param frame The frame that was passed to the execute method + * @param result The result of the call to the execute method. + */ + void leave(Node astNode, VirtualFrame frame, long result); + + /** + * Notifies that an AST Node's float-valued execute method is about to exit. + *

    + * Callers should assure (via {@code try/finally}) that a matching call to this method always + * follows a call to {@link #enter(Node, VirtualFrame)}. + * + * @param astNode The AST node on which the execute method is being called + * @param frame The frame that was passed to the execute method + * @param result The result of the call to the execute method. + */ + void leave(Node astNode, VirtualFrame frame, float result); + + /** + * Notifies that an AST Node's double-valued execute method is about to exit. + *

    + * Callers should assure (via {@code try/finally}) that a matching call to this method always + * follows a call to {@link #enter(Node, VirtualFrame)}. + * + * @param astNode The AST node on which the execute method is being called + * @param frame The frame that was passed to the execute method + * @param result The result of the call to the execute method. + */ + void leave(Node astNode, VirtualFrame frame, double result); + + /** + * Notifies that an AST Node's char-valued execute method is about to exit. + *

    + * Callers should assure (via {@code try/finally}) that a matching call to this method always + * follows a call to {@link #enter(Node, VirtualFrame)}. + * + * @param astNode The AST node on which the execute method is being called + * @param frame The frame that was passed to the execute method + * @param result The result of the call to the execute method. + */ + void leave(Node astNode, VirtualFrame frame, char result); + + /** + * Notifies that an AST Node's object-valued execute method is about to exit. + *

    + * Callers should assure (via {@code try/finally}) that a matching call to this method always + * follows a call to {@link #enter(Node, VirtualFrame)}. + * + * @param astNode The AST node on which the execute method is being called + * @param frame The frame that was passed to the execute method + * @param result The result of the call to the execute method. + */ + void leave(Node astNode, VirtualFrame frame, Object result); + + /** + * Notifies that an AST Node's execute method is about to leave under exceptional conditions, + * returning no value. + *

    + * Callers should assure (via {@code try/finally}) that a matching call to this method always + * follows a call to {@link #enter(Node, VirtualFrame)}. + * + * @param astNode The AST node on which the execute method is being called + * @param frame The frame that was passed to the execute method + * @param e the exception associated with the unusual return + */ + void leaveExceptional(Node astNode, VirtualFrame frame, Exception e); + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Instrument.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Instrument.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2014, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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.truffle.api.instrument; + +/** + * A receiver of Truffle AST {@link ExecutionEvents}, propagated from a {@link Probe} to which the + * instrument is attached. + *

    + * Disclaimer: experimental interface under development. + */ +public interface Instrument extends ExecutionEvents { + + /** + * @return the {@link Probe} to which this instrument is attached. + */ + Probe getProbe(); + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/InstrumentEventListener.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/InstrumentEventListener.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2013, 2014, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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.truffle.api.instrument; + +import com.oracle.truffle.api.*; +import com.oracle.truffle.api.frame.*; +import com.oracle.truffle.api.nodes.*; + +/** + * A client of the instrumentation framework that requests event notifications from the language + * engine. + */ +public interface InstrumentEventListener { + + /** + * The guest language runtime is starting to load a source. Care should be taken to ensure that + * under any circumstance there is always a following call to {@link #loadEnding(Source)} with + * the same argument. + */ + void loadStarting(Source source); + + /** + * The guest language runtime has finished loading a source. Care should be taken to ensure that + * under any circumstance there is always a prior call to {@link #loadStarting(Source)} with the + * same argument. + */ + void loadEnding(Source source); + + /** + * A guest language call is about to be executed. + */ + void callEntering(Node astNode, String name); + + /** + * A guest language call has just completed. + */ + void callReturned(Node astNode, String name); + + /** + * An opportunity for instrumentation to interact with Truffle AST execution halted at some + * node. + */ + void haltedAt(Node astNode, MaterializedFrame frame); + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Instrumentation.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Instrumentation.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2014, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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.truffle.api.instrument; + +import java.util.*; + +import com.oracle.truffle.api.*; +import com.oracle.truffle.api.source.*; + +public interface Instrumentation { + + /** + * Adds a new specification for how to instrument ASTs. + */ + void addNodeProber(ASTNodeProber nodeProber); + + /** + * Registers a tool interested in being notified about the insertion of a newly created + * {@link Probe} into a Truffle AST. + */ + void addProbeListener(ProbeListener listener); + + /** + * Return the (possibly newly created) {@link Probe} uniquely associated with a particular + * source code location. A newly created probe carries no tags. + * + * @param eventListener an optional listener for certain instrumentation-related events + * @return a probe uniquely associated with an extent of guest language source code. + */ + Probe getProbe(SourceSection sourceSection, InstrumentEventListener eventListener); + + /** + * Returns all existing probes with specific tag, or all probes if {@code tag = null}; empty + * collection if no probes found. + */ + Collection findProbesTaggedAs(PhylumTag tag); + + /** + * Returns all existing probes with first character on a specified line; empty collection if no + * probes found. + */ + Collection findProbesByLine(SourceLineLocation lineLocation); + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/InstrumentationFactory.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/InstrumentationFactory.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2014, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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.truffle.api.instrument; + +import com.oracle.truffle.api.*; +import com.oracle.truffle.api.instrument.impl.*; + +public class InstrumentationFactory { + + public static Instrumentation create(ExecutionContext context) { + return new InstrumentationImpl(context); + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/KillException.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/KillException.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2014, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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.truffle.api.instrument; + +import com.oracle.truffle.api.nodes.*; + +/** + * Controls breaking out of an execution context, such as a shell or eval. + */ +public final class KillException extends ControlFlowException { + + private static final long serialVersionUID = 3163641880088766957L; +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/PhylumTag.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/PhylumTag.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2014, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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.truffle.api.instrument; + +/** + * Program element "tags" that define user-visible behavior for debugging and other simple tools. + * These categories (phyla) should correspond to program structures that are meaningful to + * a guest language programmer. + *

    + * An untagged Truffle node should be understood as an artifact of the guest language implementation + * and should not be visible to the user of a guest language programming tool. Nodes may also have + * more than one tag, for example a variable assignment that is also a statement. Finally, the + * assignment of tags to nodes could depending on the use-case of whatever tool is using them. + *

    + * This is a somewhat language-agnostic set of phyla, suitable for conventional imperative + * languages, and is being developed incrementally. + *

    + * The need for alternative sets of tags is likely to arise, perhaps for other families of languages + * (for example for mostly expression-oriented languages) or even for specific languages. + *

    + * These are listed alphabetically so that listing from some collection classes will come out in + * that order. + *

    + * Disclaimer: experimental interface under development. + */ +public enum PhylumTag { + + /** + * Marker for a variable assignment. + */ + ASSIGNMENT, + + /** + * Marker for a call site. + */ + CALL, + + /** + * Marker for a location where a guest language exception is about to be thrown. + */ + THROW, + + /** + * Marker for a location where ordinary "stepping" should halt. + */ + STATEMENT; + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/PhylumTagged.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/PhylumTagged.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2014, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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.truffle.api.instrument; + +import java.util.*; + +/** + * Information about a guest language program element that can be marked as belonging to 0 or more + * {@linkplain PhylumTag tags}. + *

    + * Disclaimer: experimental interface under development. + */ +public interface PhylumTagged { + + /** + * Is this node tagged as belonging to a particular category of language constructs? + */ + boolean isTaggedAs(PhylumTag tag); + + /** + * In which categories has this node been tagged (empty set if none). + */ + Set getPhylumTags(); + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Probe.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Probe.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2014, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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.truffle.api.instrument; + +import com.oracle.truffle.api.*; +import com.oracle.truffle.api.frame.*; +import com.oracle.truffle.api.nodes.*; + +/** + * A collector of {@link ExecutionEvents} at a specific site (node) in a Truffle AST (generated by a + * {@link Wrapper} inserted into the AST) for the purpose of instrumentation. For probes + * associated with programmer-facing tools, there should be no more than one probe associated with a + * particular piece of source code syntax (i.e. a {@link SourceSection}). + *

    + * Any {@linkplain PhylumTag tags} associated with a particular piece of source code syntax are + * managed by the probe. + *

    + * When ASTs are copied, it is presumed that the probe for a site is shared by all AST nodes + * representing that site. + *

    + * A probe holds zero or more {@link Instrument}s, which can be added and removed dynamically. + * Events reported to a probe are propagated to every attached instrument; the order is undefined. + *

    + * Probe methods must be amenable to Truffle/Graal inlining on the assumption that the collection of + * attached instruments seldom changes. The assumption is invalidated when instruments are added or + * removed, but some instruments may change their internal state in such a way that the assumption + * should also be invalidated. + *

    + * Disclaimer: experimental interface under development. + */ +public interface Probe extends PhylumTagged { + + /** + * The source location with which this probe is (presumably uniquely) associated. + */ + SourceSection getSourceLocation(); + + /** + * Mark this probe as being associated with an AST node in some category useful for debugging + * and other tools. + */ + void tagAs(PhylumTag tag); + + /** + * Adds an instrument to this probe. + */ + void addInstrument(Instrument newInstrument); + + /** + * Removes an instrument from this probe. + */ + void removeInstrument(Instrument oldInstrument); + + /** + * Change stepping mode, which is used in association with nodes tagged as + * {@linkplain PhylumTag#STATEMENT statements}. + */ + void setStepping(boolean stepping); + + /** + * Value of stepping mode, which is used in association with nodes tagged as + * {@linkplain PhylumTag#STATEMENT statements}. + */ + boolean isStepping(); + + /** + * @see ExecutionEvents#enter(Node, VirtualFrame) + */ + void notifyEnter(Node astNode, VirtualFrame frame); + + /** + * @see ExecutionEvents#leave(Node, VirtualFrame) + */ + void notifyLeave(Node astNode, VirtualFrame frame); + + /** + * @see ExecutionEvents#leave(Node, VirtualFrame, boolean) + */ + void notifyLeave(Node astNode, VirtualFrame frame, boolean result); + + /** + * @see ExecutionEvents#leave(Node, VirtualFrame, byte) + */ + void notifyLeave(Node astNode, VirtualFrame frame, byte result); + + /** + * @see ExecutionEvents#leave(Node, VirtualFrame, short) + */ + void notifyLeave(Node astNode, VirtualFrame frame, short result); + + /** + * @see ExecutionEvents#leave(Node, VirtualFrame, int) + */ + void notifyLeave(Node astNode, VirtualFrame frame, int result); + + /** + * @see ExecutionEvents#leave(Node, VirtualFrame, long) + */ + void notifyLeave(Node astNode, VirtualFrame frame, long result); + + /** + * @see ExecutionEvents#leave(Node, VirtualFrame, char) + */ + void notifyLeave(Node astNode, VirtualFrame frame, char result); + + /** + * @see ExecutionEvents#leave(Node, VirtualFrame, float) + */ + void notifyLeave(Node astNode, VirtualFrame frame, float result); + + /** + * @see ExecutionEvents#leave(Node, VirtualFrame, double) + */ + void notifyLeave(Node astNode, VirtualFrame frame, double result); + + /** + * @see ExecutionEvents#leave(Node, VirtualFrame, Object) + */ + void notifyLeave(Node astNode, VirtualFrame frame, Object result); + + /** + * @see ExecutionEvents#leaveExceptional(Node, VirtualFrame, Exception) + */ + void notifyLeaveExceptional(Node astNode, VirtualFrame frame, Exception e); + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/ProbeListener.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/ProbeListener.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2014, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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.truffle.api.instrument; + +import com.oracle.truffle.api.*; + +/** + * Client for receiving events relate to {@link Probe} management. Does not report AST copying. + */ +public interface ProbeListener { + + /** + * Notifies that a newly created (untagged) {@link Probe} has been inserted into a Truffle AST. + * There will be no notification when an existing {@link Probe} is shared by an AST copy. + */ + void newProbeInserted(SourceSection location, Probe probe); + + /** + * Notifies that a (fully constructed) {@link Probe} has been tagged. A subsequent marking with + * the same tag is idempotent and generates no notification. + */ + void probeTaggedAs(Probe probe, PhylumTag tag); + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/QuitException.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/QuitException.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2014, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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.truffle.api.instrument; + +import com.oracle.truffle.api.nodes.*; + +/** + * Controls breaking out of all executions and ending Truffle execution. + */ +public final class QuitException extends ControlFlowException { + + private static final long serialVersionUID = -4301115629772778413L; +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Visualizer.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Visualizer.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2014, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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.truffle.api.instrument; + +import com.oracle.truffle.api.frame.*; + +/** + * Visualization services for guest language and Truffle information. + */ +public interface Visualizer { + + /** + * Gets a printer for Truffle ASTs, possibly specialized to be helpful for a specific guest + * language implementation. + */ + ASTPrinter getASTPrinter(); + + /** + * Converts a value in the guest language to a display string. + */ + String displayValue(Object value); + + /** + * Converts a slot identifier in the guest language to a display string. + */ + String displayIdentifier(FrameSlot slot); + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Wrapper.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Wrapper.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2013, 2014, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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.truffle.api.instrument; + +import com.oracle.truffle.api.nodes.*; + +/** + * A node that can be inserted into a Truffle AST in order to attach instrumentation at a + * particular node. + *

    + * A wrapper decorates an AST node (its child) by acting as a transparent + * proxy for the child with respect to Truffle execution semantics. + *

    + * A wrapper is also expected to notify its associated {@link Probe} when certain + * {@link ExecutionEvents} occur at the wrapper during program execution. + *

    + * The wrapper's {@link Probe} is shared by every copy of the wrapper made when the AST is copied. + *

    + * Wrappers methods must be amenable to Truffle/Graal inlining. + *

    + * Disclaimer: experimental interface under development. + */ +public interface Wrapper extends PhylumTagged { + + /** + * Gets the AST node being instrumented, which should never be an instance of {@link Wrapper}. + */ + Node getChild(); + + /** + * Gets the {@link Probe} to which events occurring at this wrapper's child are propagated. + */ + Probe getProbe(); + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/impl/DefaultASTPrinter.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/impl/DefaultASTPrinter.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,168 @@ +/* + * Copyright (c) 2014, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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.truffle.api.instrument.impl; + +import java.io.*; +import java.util.*; + +import com.oracle.truffle.api.*; +import com.oracle.truffle.api.instrument.*; +import com.oracle.truffle.api.nodes.*; +import com.oracle.truffle.api.nodes.NodeUtil.NodeClass; +import com.oracle.truffle.api.nodes.NodeUtil.NodeField; +import com.oracle.truffle.api.nodes.NodeUtil.NodeFieldKind; + +/** + * A language-agnostic for printing out various pieces of a Truffle AST. + */ +public class DefaultASTPrinter implements ASTPrinter { + + public DefaultASTPrinter() { + } + + public void printTree(PrintWriter p, Node node, int maxDepth, Node markNode) { + printTree(p, node, maxDepth, markNode, 1); + p.println(); + p.flush(); + } + + public String printTreeToString(Node node, int maxDepth, Node markNode) { + StringWriter out = new StringWriter(); + printTree(new PrintWriter(out), node, maxDepth, markNode); + return out.toString(); + } + + public String printTreeToString(Node node, int maxDepth) { + return printTreeToString(node, maxDepth, null); + } + + private static void printTree(PrintWriter p, Node node, int maxDepth, Node markNode, int level) { + if (node == null) { + p.print("null"); + return; + } + + p.print(nodeName(node)); + + String sep = ""; + p.print("("); + + final SourceSection src = node.getSourceSection(); + if (src != null) { + if (!(src instanceof NullSourceSection)) { + p.print(src.getSource().getName() + ":" + src.getStartLine()); + } + } + if (node instanceof PhylumTagged) { + final PhylumTagged taggedNode = (PhylumTagged) node; + String prefix = ""; + for (PhylumTag tag : taggedNode.getPhylumTags()) { + p.print(prefix); + prefix = ","; + p.print(tag.toString()); + } + + } + + ArrayList childFields = new ArrayList<>(); + + for (NodeField field : NodeClass.get(node.getClass()).getFields()) { + if (field.getKind() == NodeFieldKind.CHILD || field.getKind() == NodeFieldKind.CHILDREN) { + childFields.add(field); + } else if (field.getKind() == NodeFieldKind.DATA) { + // p.print(sep); + // sep = ", "; + // + // final String fieldName = field.getName(); + // switch (fieldName) { + // + // } + // p.print(fieldName); + // p.print(" = "); + // p.print(field.loadValue(node)); + } + } + p.print(")"); + + if (level <= maxDepth) { + + if (childFields.size() != 0) { + p.print(" {"); + for (NodeField field : childFields) { + + Object value = field.loadValue(node); + if (value == null) { + printNewLine(p, level); + p.print(field.getName()); + p.print(" = null "); + } else if (field.getKind() == NodeFieldKind.CHILD) { + final Node valueNode = (Node) value; + printNewLine(p, level, valueNode == markNode); + p.print(field.getName()); + p.print(" = "); + printTree(p, valueNode, maxDepth, markNode, level + 1); + } else if (field.getKind() == NodeFieldKind.CHILDREN) { + printNewLine(p, level); + p.print(field.getName()); + Node[] children = (Node[]) value; + p.print(" = ["); + sep = ""; + for (Node child : children) { + p.print(sep); + sep = ", "; + printTree(p, child, maxDepth, markNode, level + 1); + } + p.print("]"); + } else { + printNewLine(p, level); + p.print(field.getName()); + } + } + printNewLine(p, level - 1); + p.print("}"); + } + } + } + + private static void printNewLine(PrintWriter p, int level, boolean mark) { + p.println(); + for (int i = 0; i < level; i++) { + if (mark && i == 0) { + p.print(" -->"); + } else { + p.print(" "); + } + } + } + + private static void printNewLine(PrintWriter p, int level) { + printNewLine(p, level, false); + } + + private static String nodeName(Node node) { + return node.getClass().getSimpleName(); + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/impl/DefaultInstrument.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/impl/DefaultInstrument.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2013, 2014, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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.truffle.api.instrument.impl; + +import com.oracle.truffle.api.frame.*; +import com.oracle.truffle.api.instrument.*; +import com.oracle.truffle.api.nodes.*; + +/** + * An {@link Instrument} that implements all {@link ExecutionEvents} notifications with empty + * methods. + */ +public class DefaultInstrument extends InstrumentationNodeImpl implements Instrument { + + protected DefaultInstrument() { + } + + public void enter(Node astNode, VirtualFrame frame) { + } + + public void leave(Node astNode, VirtualFrame frame) { + } + + public void leave(Node astNode, VirtualFrame frame, boolean result) { + leave(astNode, frame, (Object) result); + } + + public void leave(Node astNode, VirtualFrame frame, byte result) { + leave(astNode, frame, (Object) result); + } + + public void leave(Node astNode, VirtualFrame frame, short result) { + leave(astNode, frame, (Object) result); + } + + public void leave(Node astNode, VirtualFrame frame, int result) { + leave(astNode, frame, (Object) result); + } + + public void leave(Node astNode, VirtualFrame frame, long result) { + leave(astNode, frame, (Object) result); + } + + public void leave(Node astNode, VirtualFrame frame, char result) { + leave(astNode, frame, (Object) result); + } + + public void leave(Node astNode, VirtualFrame frame, float result) { + leave(astNode, frame, (Object) result); + } + + public void leave(Node astNode, VirtualFrame frame, double result) { + leave(astNode, frame, (Object) result); + } + + public void leave(Node astNode, VirtualFrame frame, Object result) { + } + + public void leaveExceptional(Node astNode, VirtualFrame frame, Exception e) { + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/impl/DefaultVisualizer.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/impl/DefaultVisualizer.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2014, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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.truffle.api.instrument.impl; + +import com.oracle.truffle.api.frame.*; +import com.oracle.truffle.api.instrument.*; + +public class DefaultVisualizer implements Visualizer { + + private final ASTPrinter astPrinter; + + public DefaultVisualizer() { + this.astPrinter = new DefaultASTPrinter(); + } + + public ASTPrinter getASTPrinter() { + return astPrinter; + } + + public String displayValue(Object value) { + return value.toString(); + } + + public String displayIdentifier(FrameSlot slot) { + return slot.getIdentifier().toString(); + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/impl/InstrumentationImpl.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/impl/InstrumentationImpl.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2013, 2014, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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.truffle.api.instrument.impl; + +import java.util.*; + +import com.oracle.truffle.api.*; +import com.oracle.truffle.api.instrument.*; +import com.oracle.truffle.api.source.*; + +/** + * @author mlvdv + * + */ +public final class InstrumentationImpl implements Instrumentation { + + private final ExecutionContext context; + + // TODO (mlvdv) maps should really use weak references. + + /** + * Map: SourceSection ==> probe associated with that source section in an AST. + */ + private final Map srcToProbe = new HashMap<>(); + + /** + * Map: Source line ==> probes associated with source sections starting on the line. + */ + private final Map> lineToProbes = new HashMap<>(); + + private final List probeListeners = new ArrayList<>(); + + public InstrumentationImpl(ExecutionContext context) { + this.context = context; + } + + public void addNodeProber(ASTNodeProber nodeProber) { + context.addNodeProber(nodeProber); + } + + public void addProbeListener(ProbeListener listener) { + assert listener != null; + probeListeners.add(listener); + } + + /** + * Return the (possibly newly created) {@link Probe} uniquely associated with a particular + * source code location. A newly created probe carries no tags. + * + * @param eventListener an optional listener for certain instrumentation-related events + * @return a probe uniquely associated with an extent of guest language source code. + */ + public Probe getProbe(SourceSection sourceSection, InstrumentEventListener eventListener) { + assert sourceSection != null; + + Probe probe = srcToProbe.get(sourceSection); + + if (probe != null) { + return probe; + } + probe = InstrumentationNodeImpl.createProbe(this, sourceSection, eventListener); + + // Register new probe by unique SourceSection + srcToProbe.put(sourceSection, probe); + + // Register new probe by source line, there may be more than one + // Create line location for map key + final SourceLineLocation lineLocation = new SourceLineLocation(sourceSection.getSource(), sourceSection.getStartLine()); + + Collection probes = lineToProbes.get(lineLocation); + if (probes == null) { + probes = new ArrayList<>(2); + lineToProbes.put(lineLocation, probes); + } + probes.add(probe); + + for (ProbeListener listener : probeListeners) { + listener.newProbeInserted(sourceSection, probe); + } + + return probe; + } + + /** + * Returns all existing probes with specific tag, or all probes if {@code tag = null}; empty + * collection if no probes found. + */ + public Collection findProbesTaggedAs(PhylumTag tag) { + if (tag == null) { + return new ArrayList<>(srcToProbe.values()); + } + final List probes = new ArrayList<>(); + for (Probe probe : srcToProbe.values()) { + if (probe.isTaggedAs(tag)) { + probes.add(probe); + } + } + return probes; + } + + /** + * Returns all existing probes with first character on a specified line; empty collection if no + * probes found. + */ + public Collection findProbesByLine(SourceLineLocation lineLocation) { + final Collection probes = lineToProbes.get(lineLocation); + if (probes == null) { + return Collections.emptyList(); + } + return new ArrayList<>(probes); + } + + /** + * Receives (from the {@link Probe} implementation) and distributes notification that a + * {@link Probe} has acquired a new {@linkplain PhylumTag tag}. + */ + void newTagAdded(Probe probe, PhylumTag tag) { + for (ProbeListener listener : probeListeners) { + listener.probeTaggedAs(probe, tag); + } + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/impl/InstrumentationNodeImpl.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/impl/InstrumentationNodeImpl.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,448 @@ +/* + * Copyright (c) 2013, 2014, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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.truffle.api.instrument.impl; + +import java.util.*; + +import com.oracle.truffle.api.*; +import com.oracle.truffle.api.frame.*; +import com.oracle.truffle.api.instrument.*; +import com.oracle.truffle.api.nodes.*; + +/** + * Abstract implementation of Truffle {@link Node} to be used for AST probes and instruments. + *

    + * Coordinates propagation of Truffle AST {@link ExecutionEvents}. + */ +public abstract class InstrumentationNodeImpl extends Node implements ExecutionEvents { + + // TODO (mlvdv) This is a pretty awkward design. + + /** + * Creates a new {@link Probe}, presumed to be unique to a particular {@linkplain SourceSection} + * extent of guest language source code. + * + * @param eventListener an optional listener for certain instrumentation-related events. + * @return a new probe + */ + static Probe createProbe(InstrumentationImpl instrumentation, SourceSection sourceSection, InstrumentEventListener eventListener) { + return new ProbeImpl(instrumentation, sourceSection, eventListener); + } + + /** + * Next in chain. + */ + @Child protected InstrumentationNodeImpl next; + + protected InstrumentationNodeImpl() { + } + + /** + * @return the instance of {@link Probe} to which this instrument is attached. + */ + public Probe getProbe() { + final InstrumentationNodeImpl parent = (InstrumentationNodeImpl) getParent(); + return parent == null ? null : parent.getProbe(); + } + + /** + * Add a probe to the end of this probe chain. + */ + void internalAddInstrument(InstrumentationNodeImpl newInstrument) { + if (next == null) { + this.next = insert(newInstrument); + } else { + next.internalAddInstrument(newInstrument); + } + } + + void internalRemoveInstrument(InstrumentationNodeImpl oldInstrument) { + if (next == null) { + throw new RuntimeException("Couldn't find probe to remove: " + oldInstrument); + } else if (next == oldInstrument) { + if (oldInstrument.next == null) { + this.next = null; + } else { + this.next = insert(oldInstrument.next); + oldInstrument.next = null; + } + } else { + next.internalRemoveInstrument(oldInstrument); + } + } + + /** + * Reports to the instance of {@link Probe} holding this instrument that some essential state + * has changed that requires deoptimization. + */ + @CompilerDirectives.SlowPath + protected void notifyProbeChanged(InstrumentationNodeImpl instrument) { + final ProbeImpl probe = (ProbeImpl) getProbe(); + probe.notifyProbeChanged(instrument); + } + + private void internalEnter(Node astNode, VirtualFrame frame) { + enter(astNode, frame); + if (next != null) { + next.internalEnter(astNode, frame); + } + } + + private void internalLeave(Node astNode, VirtualFrame frame) { + leave(astNode, frame); + if (next != null) { + next.internalLeave(astNode, frame); + } + } + + private void internalLeave(Node astNode, VirtualFrame frame, boolean result) { + leave(astNode, frame, result); + if (next != null) { + next.internalLeave(astNode, frame, result); + } + } + + private void internalLeave(Node astNode, VirtualFrame frame, byte result) { + leave(astNode, frame, result); + if (next != null) { + next.internalLeave(astNode, frame, result); + } + } + + private void internalLeave(Node astNode, VirtualFrame frame, short result) { + leave(astNode, frame, result); + if (next != null) { + next.internalLeave(astNode, frame, result); + } + } + + private void internalLeave(Node astNode, VirtualFrame frame, int result) { + leave(astNode, frame, result); + if (next != null) { + next.internalLeave(astNode, frame, result); + } + } + + private void internalLeave(Node astNode, VirtualFrame frame, long result) { + leave(astNode, frame, result); + if (next != null) { + next.internalLeave(astNode, frame, result); + } + } + + private void internalLeave(Node astNode, VirtualFrame frame, char result) { + leave(astNode, frame, result); + if (next != null) { + next.internalLeave(astNode, frame, result); + } + } + + private void internalLeave(Node astNode, VirtualFrame frame, float result) { + leave(astNode, frame, result); + if (next != null) { + next.internalLeave(astNode, frame, result); + } + } + + private void internalLeave(Node astNode, VirtualFrame frame, double result) { + leave(astNode, frame, result); + if (next != null) { + next.internalLeave(astNode, frame, result); + } + } + + private void internalLeave(Node astNode, VirtualFrame frame, Object result) { + leave(astNode, frame, result); + if (next != null) { + next.internalLeave(astNode, frame, result); + } + } + + private void internalLeaveExceptional(Node astNode, VirtualFrame frame, Exception e) { + leaveExceptional(astNode, frame, null); + if (next != null) { + next.internalLeaveExceptional(astNode, frame, e); + } + } + + /** + * Holder of a chain of {@linkplain InstrumentationNodeImpl instruments}: manages the + * {@link Assumption} that none of the instruments have changed since last checked. + *

    + * An instance is intended to be shared by every clone of the AST node with which it is + * originally attached, so it holds no parent pointer. + *

    + * May be categorized by one or more {@linkplain PhylumTag tags}, signifying information useful + * for instrumentation about its AST location(s). + */ + private static final class ProbeImpl extends InstrumentationNodeImpl implements Probe { + + final InstrumentationImpl instrumentation; + + final InstrumentEventListener eventListener; + + @CompilerDirectives.CompilationFinal private Assumption probeUnchanged; + + /** + * When in stepping mode, ordinary line breakpoints are ignored, but every entry at a line + * will cause a halt. + */ + @CompilerDirectives.CompilationFinal private boolean stepping; + + /** + * Source information about the AST node to which this instrumentation is attached. + */ + private final SourceSection probedSourceSection; + + private final Set tags = EnumSet.noneOf(PhylumTag.class); + + private ProbeImpl(InstrumentationImpl instrumentation, SourceSection sourceSection, InstrumentEventListener eventListener) { + this.instrumentation = instrumentation; + this.probedSourceSection = sourceSection; + this.eventListener = eventListener == null ? NullInstrumentEventListener.INSTANCE : eventListener; + this.probeUnchanged = Truffle.getRuntime().createAssumption(); + this.next = null; + } + + @Override + public Probe getProbe() { + return this; + } + + @Override + protected void notifyProbeChanged(InstrumentationNodeImpl instrument) { + probeUnchanged.invalidate(); + probeUnchanged = Truffle.getRuntime().createAssumption(); + } + + public SourceSection getSourceLocation() { + return probedSourceSection; + } + + public void tagAs(PhylumTag tag) { + assert tag != null; + if (!tags.contains(tag)) { + tags.add(tag); + instrumentation.newTagAdded(this, tag); + } + } + + public boolean isTaggedAs(PhylumTag tag) { + assert tag != null; + return tags.contains(tag); + } + + public Set getPhylumTags() { + return tags; + } + + public void setStepping(boolean stepping) { + if (this.stepping != stepping) { + this.stepping = stepping; + probeUnchanged.invalidate(); + probeUnchanged = Truffle.getRuntime().createAssumption(); + } + } + + public boolean isStepping() { + return stepping; + } + + @CompilerDirectives.SlowPath + public void addInstrument(Instrument instrument) { + probeUnchanged.invalidate(); + final InstrumentationNodeImpl instrumentImpl = (InstrumentationNodeImpl) instrument; + super.internalAddInstrument(instrumentImpl); + probeUnchanged = Truffle.getRuntime().createAssumption(); + } + + @CompilerDirectives.SlowPath + public void removeInstrument(Instrument instrument) { + probeUnchanged.invalidate(); + final InstrumentationNodeImpl instrumentImpl = (InstrumentationNodeImpl) instrument; + super.internalRemoveInstrument(instrumentImpl); + probeUnchanged = Truffle.getRuntime().createAssumption(); + } + + public void notifyEnter(Node astNode, VirtualFrame frame) { + if (stepping || next != null) { + if (!probeUnchanged.isValid()) { + CompilerDirectives.transferToInterpreter(); + } + if (stepping) { + eventListener.haltedAt(astNode, frame.materialize()); + } + if (next != null) { + next.internalEnter(astNode, frame); + } + } + } + + public void notifyLeave(Node astNode, VirtualFrame frame) { + if (next != null) { + if (!probeUnchanged.isValid()) { + CompilerDirectives.transferToInterpreter(); + } + next.internalLeave(astNode, frame); + } + } + + public void notifyLeave(Node astNode, VirtualFrame frame, boolean result) { + if (next != null) { + if (!probeUnchanged.isValid()) { + CompilerDirectives.transferToInterpreter(); + } + next.internalLeave(astNode, frame, result); + } + } + + public void notifyLeave(Node astNode, VirtualFrame frame, byte result) { + if (next != null) { + if (!probeUnchanged.isValid()) { + CompilerDirectives.transferToInterpreter(); + } + next.internalLeave(astNode, frame, result); + } + } + + public void notifyLeave(Node astNode, VirtualFrame frame, short result) { + if (next != null) { + if (!probeUnchanged.isValid()) { + CompilerDirectives.transferToInterpreter(); + } + next.internalLeave(astNode, frame, result); + } + } + + public void notifyLeave(Node astNode, VirtualFrame frame, int result) { + if (next != null) { + if (!probeUnchanged.isValid()) { + CompilerDirectives.transferToInterpreter(); + } + next.internalLeave(astNode, frame, result); + } + } + + public void notifyLeave(Node astNode, VirtualFrame frame, long result) { + if (next != null) { + if (!probeUnchanged.isValid()) { + CompilerDirectives.transferToInterpreter(); + } + next.internalLeave(astNode, frame, result); + } + } + + public void notifyLeave(Node astNode, VirtualFrame frame, char result) { + if (next != null) { + if (!probeUnchanged.isValid()) { + CompilerDirectives.transferToInterpreter(); + } + next.internalLeave(astNode, frame, result); + } + } + + public void notifyLeave(Node astNode, VirtualFrame frame, float result) { + if (next != null) { + if (!probeUnchanged.isValid()) { + CompilerDirectives.transferToInterpreter(); + } + next.internalLeave(astNode, frame, result); + } + } + + public void notifyLeave(Node astNode, VirtualFrame frame, double result) { + if (next != null) { + if (!probeUnchanged.isValid()) { + CompilerDirectives.transferToInterpreter(); + } + next.internalLeave(astNode, frame, result); + } + } + + public void notifyLeave(Node astNode, VirtualFrame frame, Object result) { + if (next != null) { + if (!probeUnchanged.isValid()) { + CompilerDirectives.transferToInterpreter(); + } + next.internalLeave(astNode, frame, result); + } + } + + public void notifyLeaveExceptional(Node astNode, VirtualFrame frame, Exception e) { + if (next != null) { + if (!probeUnchanged.isValid()) { + CompilerDirectives.transferToInterpreter(); + } + next.internalLeaveExceptional(astNode, frame, e); + } + } + + public void enter(Node astNode, VirtualFrame frame) { + } + + public void leave(Node astNode, VirtualFrame frame) { + } + + public void leave(Node astNode, VirtualFrame frame, boolean result) { + leave(astNode, frame, (Object) result); + } + + public void leave(Node astNode, VirtualFrame frame, byte result) { + leave(astNode, frame, (Object) result); + } + + public void leave(Node astNode, VirtualFrame frame, short result) { + leave(astNode, frame, (Object) result); + } + + public void leave(Node astNode, VirtualFrame frame, int result) { + leave(astNode, frame, (Object) result); + } + + public void leave(Node astNode, VirtualFrame frame, long result) { + leave(astNode, frame, (Object) result); + } + + public void leave(Node astNode, VirtualFrame frame, char result) { + leave(astNode, frame, (Object) result); + } + + public void leave(Node astNode, VirtualFrame frame, float result) { + leave(astNode, frame, (Object) result); + } + + public void leave(Node astNode, VirtualFrame frame, double result) { + leave(astNode, frame, (Object) result); + } + + public void leave(Node astNode, VirtualFrame frame, Object result) { + } + + public void leaveExceptional(Node astNode, VirtualFrame frame, Exception e) { + } + + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/impl/NullInstrumentEventListener.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/impl/NullInstrumentEventListener.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2013, 2014, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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.truffle.api.instrument.impl; + +import com.oracle.truffle.api.*; +import com.oracle.truffle.api.frame.*; +import com.oracle.truffle.api.instrument.*; +import com.oracle.truffle.api.nodes.*; + +/** + * Minimal, mostly no-op implementation of instrumentation services. + */ +public final class NullInstrumentEventListener implements InstrumentEventListener { + + public static final InstrumentEventListener INSTANCE = new NullInstrumentEventListener(); + + private NullInstrumentEventListener() { + } + + public void callEntering(Node astNode, String name) { + } + + public void callReturned(Node astNode, String name) { + } + + public void haltedAt(Node astNode, MaterializedFrame frame) { + } + + public void loadStarting(Source source) { + } + + public void loadEnding(Source source) { + } + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/CallNode.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/CallNode.java Wed Apr 23 15:22:20 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,156 +0,0 @@ -/* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.truffle.api.nodes; - -import com.oracle.truffle.api.*; - -/** - * Represents a call to a {@link CallTarget} in the Truffle AST. Addtionally to calling the - * {@link CallTarget} this {@link Node} enables the runtime system to implement further - * optimizations. Optimizations that can possibly applied to a {@link CallNode} are inlining and - * splitting. Inlining inlines this call site into the call graph of the parent {@link CallTarget}. - * Splitting duplicates the {@link CallTarget} using {@link RootNode#split()} to collect call site - * sensitive profiling information. - * - * Please note: This class is not intended to be subclassed by guest language implementations. - * - * @see TruffleRuntime#createCallNode(CallTarget) - * @see #inline() - * @see #split() - */ -public abstract class CallNode extends Node { - - protected final CallTarget callTarget; - - protected CallNode(CallTarget callTarget) { - this.callTarget = callTarget; - } - - /** - * Calls the inner {@link CallTarget} returned by {@link #getCurrentCallTarget()}. - * - * @param arguments the arguments that should be passed to the callee - * @return the return result of the call - */ - public abstract Object call(Object[] arguments); - - /** - * Returns the originally supplied {@link CallTarget} when this call node was created. Please - * note that the returned {@link CallTarget} is not necessarily the {@link CallTarget} that is - * called. For that use {@link #getCurrentCallTarget()} instead. - * - * @return the {@link CallTarget} provided. - */ - public CallTarget getCallTarget() { - return callTarget; - } - - /** - * Returns true if the underlying runtime system supports inlining for the - * {@link CallTarget} in this {@link CallNode}. - * - * @return true if inlining is supported. - */ - public abstract boolean isInlinable(); - - /** - * Returns true if the {@link CallTarget} in this {@link CallNode} is inlined. A - * {@link CallNode} can either be inlined manually by invoking {@link #inline()} or by the - * runtime system which may at any point decide to inline. - * - * @return true if this method was inlined else false. - */ - public abstract boolean isInlined(); - - /** - * Enforces the runtime system to inline the {@link CallTarget} at this call site. If the - * runtime system does not support inlining or it is already inlined this method has no effect. - */ - public abstract void inline(); - - /** - * Returns true if this {@link CallNode} can be split. A {@link CallNode} can only - * be split if the runtime system supports splitting and if the {@link RootNode} contained the - * {@link CallTarget} returns true for {@link RootNode#isSplittable()}. - * - * @return true if the target can be split - */ - public abstract boolean isSplittable(); - - /** - * Enforces the runtime system to split the {@link CallTarget}. If the {@link CallNode} is not - * splittable this methods has no effect. - */ - public abstract boolean split(); - - /** - * Returns true if the target of the {@link CallNode} was split. - * - * @return if the target was split - */ - public final boolean isSplit() { - return getSplitCallTarget() != null; - } - - /** - * Returns the splitted {@link CallTarget} if this method is split. - * - * @return the split {@link CallTarget} - */ - public abstract CallTarget getSplitCallTarget(); - - /** - * Returns the used call target when {@link #call(Object[])} is invoked. If the - * {@link CallTarget} was split this method returns the {@link CallTarget} returned by - * {@link #getSplitCallTarget()}. - * - * @return the used {@link CallTarget} when node is called - */ - public CallTarget getCurrentCallTarget() { - CallTarget split = getSplitCallTarget(); - if (split != null) { - return split; - } else { - return getCallTarget(); - } - } - - /** - * Returns the {@link RootNode} associated with {@link CallTarget} returned by - * {@link #getCurrentCallTarget()}. If the stored {@link CallTarget} does not contain a - * {@link RootNode} this method returns null. - * - * @see #getCurrentCallTarget() - * @return the root node of the used call target - */ - public final RootNode getCurrentRootNode() { - CallTarget target = getCurrentCallTarget(); - if (target instanceof RootCallTarget) { - return ((RootCallTarget) target).getRootNode(); - } - return null; - } - -} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/DirectCallNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/DirectCallNode.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,170 @@ +/* + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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.truffle.api.nodes; + +import com.oracle.truffle.api.*; +import com.oracle.truffle.api.frame.*; + +/** + * Represents a direct call to a {@link CallTarget}. Direct calls are calls for which the + * {@link CallTarget} remains the same for each consecutive call. This part of the Truffle API + * enables the runtime system to perform additional optimizations on direct calls. + * + * Optimizations that can be applied to a {@link DirectCallNode} are inlining and splitting. + * Inlining inlines this call site into the call graph of the parent {@link CallTarget}. Splitting + * duplicates the {@link CallTarget} using {@link RootNode#split()} to collect call site sensitive + * profiling information. + * + * Please note: This class is not intended to be subclassed by guest language implementations. + * + * @see IndirectCallNode for calls with a non-constant target + * @see TruffleRuntime#createDirectCallNode(CallTarget) + * @see #forceInlining() + * @see #split() + */ +public abstract class DirectCallNode extends Node { + + protected final CallTarget callTarget; + + protected DirectCallNode(CallTarget callTarget) { + this.callTarget = callTarget; + } + + /** + * Calls the inner {@link CallTarget} returned by {@link #getCurrentCallTarget()}. + * + * @param arguments the arguments that should be passed to the callee + * @return the return result of the call + */ + public abstract Object call(VirtualFrame frame, Object[] arguments); + + /** + * Returns the originally supplied {@link CallTarget} when this call node was created. Please + * note that the returned {@link CallTarget} is not necessarily the {@link CallTarget} that is + * called. For that use {@link #getCurrentCallTarget()} instead. + * + * @return the {@link CallTarget} provided. + */ + public CallTarget getCallTarget() { + return callTarget; + } + + /** + * Returns true if the underlying runtime system supports inlining for the + * {@link CallTarget} in this {@link DirectCallNode}. + * + * @return true if inlining is supported. + */ + public abstract boolean isInlinable(); + + /** + * Returns true if the {@link CallTarget} is forced to be inlined. A + * {@link DirectCallNode} can either be inlined manually by invoking {@link #forceInlining()} or + * by the runtime system which may at any point decide to inline. + * + * @return true if this method was inlined else false. + */ + public abstract boolean isInliningForced(); + + /** + * Enforces the runtime system to inline the {@link CallTarget} at this call site. If the + * runtime system does not support inlining or it is already inlined this method has no effect. + * The runtime system may decide to not inline calls which were forced to inline. + */ + public abstract void forceInlining(); + + /** + * Returns true if the runtime system has decided to inline this call-site. If the + * {@link DirectCallNode} was forced to inline then this does not necessarily mean that the + * {@link DirectCallNode} is really going to be inlined. This depends on whether or not the + * runtime system supports inlining. The runtime system may also decide to not inline calls + * which were forced to inline. + */ + public abstract boolean isInlined(); + + /** + * Returns true if this {@link DirectCallNode} can be split. A + * {@link DirectCallNode} can only be split if the runtime system supports splitting and if the + * {@link RootNode} contained the {@link CallTarget} returns true for + * {@link RootNode#isSplittable()}. + * + * @return true if the target can be split + */ + public abstract boolean isSplittable(); + + /** + * Enforces the runtime system to split the {@link CallTarget}. If the {@link DirectCallNode} is + * not splittable this methods has no effect. + */ + public abstract boolean split(); + + /** + * Returns true if the target of the {@link DirectCallNode} was split. + * + * @return if the target was split + */ + public final boolean isSplit() { + return getSplitCallTarget() != null; + } + + /** + * Returns the split {@link CallTarget} if this method is split. + * + * @return the split {@link CallTarget} + */ + public abstract CallTarget getSplitCallTarget(); + + /** + * Returns the used call target when {@link #call(VirtualFrame, Object[])} is invoked. If the + * {@link CallTarget} was split this method returns the {@link CallTarget} returned by + * {@link #getSplitCallTarget()}. + * + * @return the used {@link CallTarget} when node is called + */ + public CallTarget getCurrentCallTarget() { + CallTarget split = getSplitCallTarget(); + if (split != null) { + return split; + } else { + return getCallTarget(); + } + } + + /** + * Returns the {@link RootNode} associated with {@link CallTarget} returned by + * {@link #getCurrentCallTarget()}. If the stored {@link CallTarget} does not contain a + * {@link RootNode} this method returns null. + * + * @see #getCurrentCallTarget() + * @return the root node of the used call target + */ + public final RootNode getCurrentRootNode() { + CallTarget target = getCurrentCallTarget(); + if (target instanceof RootCallTarget) { + return ((RootCallTarget) target).getRootNode(); + } + return null; + } +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/IndirectCallNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/IndirectCallNode.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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.truffle.api.nodes; + +import com.oracle.truffle.api.*; +import com.oracle.truffle.api.frame.*; + +/** + * Represents an indirect call to a {@link CallTarget}. Indirect calls are calls for which the + * {@link CallTarget} may change dynamically for each consecutive call. This part of the Truffle API + * enables the runtime system to perform additional optimizations on indirect calls. + * + * Please note: This class is not intended to be sub classed by guest language implementations. + * + * @see DirectCallNode for faster calls with a constantly known {@link CallTarget}. + */ +public abstract class IndirectCallNode extends Node { + + /** + * Performs an indirect call to the given {@link CallTarget} target with the provided arguments. + * + * @param frame the caller frame + * @param target the {@link CallTarget} to call + * @param arguments the arguments to provide + * @return the return value of the call + */ + public abstract Object call(VirtualFrame frame, CallTarget target, Object[] arguments); + +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java Wed Apr 23 15:48:38 2014 +0200 @@ -636,8 +636,8 @@ nodeCount++; } - if (visitInlinedCallNodes && node instanceof CallNode) { - CallNode call = (CallNode) node; + if (visitInlinedCallNodes && node instanceof DirectCallNode) { + DirectCallNode call = (DirectCallNode) node; if (call.isInlined()) { Node target = ((RootCallTarget) call.getCurrentCallTarget()).getRootNode(); if (target != null) { @@ -763,7 +763,7 @@ /** * Prints a human readable form of a {@link Node} AST to the given {@link PrintStream}. This * print method does not check for cycles in the node structure. - * + * * @param out the stream to print to. * @param node the root node to write */ diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/RootNode.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/RootNode.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/RootNode.java Wed Apr 23 15:48:38 2014 +0200 @@ -58,7 +58,7 @@ * Creates a split {@link RootNode} based on the current {@link RootNode}. This method should * return an AST that was never executed and must not be shared with other {@link RootNode} or * {@link CallTarget} instances. This method is intended to be overridden by a subclass. - * + * * @return the split {@link RootNode} */ public RootNode split() { @@ -67,10 +67,10 @@ /** * Returns true if this {@link RootNode} can be split. A {@link RootNode} can be - * split inside of a {@link CallTarget} that is invoked using a {@link CallNode}. If this method - * returns true a proper implementation of {@link #split()} must also be provided. - * This method is intended to be overridden by a subclass. - * + * split inside of a {@link CallTarget} that is invoked using a {@link DirectCallNode}. If this + * method returns true a proper implementation of {@link #split()} must also be + * provided. This method is intended to be overridden by a subclass. + * * @return true if splittable else false. */ public boolean isSplittable() { @@ -89,7 +89,7 @@ /** * Executes this function using the specified frame and returns the result value. - * + * * @param frame the frame of the currently executing guest language method * @return the value of the execution */ diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/instrument/DefaultNodeInstrumenter.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/instrument/DefaultNodeInstrumenter.java Wed Apr 23 15:22:20 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2014, 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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.truffle.api.nodes.instrument; - -import com.oracle.truffle.api.nodes.*; - -/** - * A no-op node instrumenter; always returns the node unproxied and unmodified. - */ -public class DefaultNodeInstrumenter implements NodeInstrumenter { - - public Node instrumentAs(Node node, NodePhylum phylum, Object... args) { - return node; - } - -} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/instrument/InstrumentationNode.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/instrument/InstrumentationNode.java Wed Apr 23 15:22:20 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.truffle.api.nodes.instrument; - -/** - * Marker interface for all Truffle instrumentation nodes: nodes that are do not - * appear in Truffle ASTs as part of a language's execution semantics. - *

    - * In documentation related to instrumentation nodes, these are distinguished by referring to all - * other nodes (i.e. ones that do implement language semantics) as AST nodes. - */ -public interface InstrumentationNode { - -} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/instrument/InstrumentationProbeEvents.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/instrument/InstrumentationProbeEvents.java Wed Apr 23 15:22:20 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,190 +0,0 @@ -/* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.truffle.api.nodes.instrument; - -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; - -/** - * Marker interface for all Truffle instrumentation nodes: nodes that are do not - * appear in Truffle ASTs as part of a language's execution semantics. - *

    - * In documentation related to instrumentation nodes, these are distinguished by referring to all - * other nodes (i.e. ones that do implement language semantics) as AST nodes. - */ -public interface InstrumentationProbeEvents { - - /** - * Notifies a probe that receiver that an AST node's execute method has just been entered. - * Callers should assure that a matching call to {@link #leave(Node, VirtualFrame, Object)} - * always follows. - * - * @param astNode The AST node on which the execute method is being called - * @param frame The frame being passed to the execute method - */ - void enter(Node astNode, VirtualFrame frame); - - /** - * Notifies a probe that an AST Node's void-valued execute method is about to exit. - *

    - * Callers should assure (via {@code try/finally}) that a matching call to this method always - * follows a call to {@link #enter(Node, VirtualFrame)}. - * - * @param astNode The AST node on which the execute method is being called - * @param frame The frame that was passed to the execute method - */ - void leave(Node astNode, VirtualFrame frame); - - /** - * Notifies a probe that an AST Node's boolean-valued execute method is about to exit. - *

    - * Callers should assure (via {@code try/finally}) that a matching call to this method always - * follows a call to {@link #enter(Node, VirtualFrame)}. - * - * @param astNode The AST node on which the execute method is being called - * @param frame The frame that was passed to the execute method - * @param result The result of the call to the execute method. - */ - void leave(Node astNode, VirtualFrame frame, boolean result); - - /** - * Notifies a probe that an AST Node's byte-valued execute method is about to exit. - *

    - * Callers should assure (via {@code try/finally}) that a matching call to this method always - * follows a call to {@link #enter(Node, VirtualFrame)}. - * - * @param astNode The AST node on which the execute method is being called - * @param frame The frame that was passed to the execute method - * @param result The result of the call to the execute method. - */ - void leave(Node astNode, VirtualFrame frame, byte result); - - /** - * Notifies a probe that an AST Node's short-valued execute method is about to exit. - *

    - * Callers should assure (via {@code try/finally}) that a matching call to this method always - * follows a call to {@link #enter(Node, VirtualFrame)}. - * - * @param astNode The AST node on which the execute method is being called - * @param frame The frame that was passed to the execute method - * @param result The result of the call to the execute method. - */ - void leave(Node astNode, VirtualFrame frame, short result); - - /** - * Notifies a probe that an AST Node's integer-valued execute method is about to exit. - *

    - * Callers should assure (via {@code try/finally}) that a matching call to this method always - * follows a call to {@link #enter(Node, VirtualFrame)}. - * - * @param astNode The AST node on which the execute method is being called - * @param frame The frame that was passed to the execute method - * @param result The result of the call to the execute method. - */ - void leave(Node astNode, VirtualFrame frame, int result); - - /** - * Notifies a probe that an AST Node's long-valued execute method is about to exit. - *

    - * Callers should assure (via {@code try/finally}) that a matching call to this method always - * follows a call to {@link #enter(Node, VirtualFrame)}. - * - * @param astNode The AST node on which the execute method is being called - * @param frame The frame that was passed to the execute method - * @param result The result of the call to the execute method. - */ - void leave(Node astNode, VirtualFrame frame, long result); - - /** - * Notifies a probe that an AST Node's float-valued execute method is about to exit. - *

    - * Callers should assure (via {@code try/finally}) that a matching call to this method always - * follows a call to {@link #enter(Node, VirtualFrame)}. - * - * @param astNode The AST node on which the execute method is being called - * @param frame The frame that was passed to the execute method - * @param result The result of the call to the execute method. - */ - void leave(Node astNode, VirtualFrame frame, float result); - - /** - * Notifies a probe that an AST Node's double-valued execute method is about to exit. - *

    - * Callers should assure (via {@code try/finally}) that a matching call to this method always - * follows a call to {@link #enter(Node, VirtualFrame)}. - * - * @param astNode The AST node on which the execute method is being called - * @param frame The frame that was passed to the execute method - * @param result The result of the call to the execute method. - */ - void leave(Node astNode, VirtualFrame frame, double result); - - /** - * Notifies a probe that an AST Node's char-valued execute method is about to exit. - *

    - * Callers should assure (via {@code try/finally}) that a matching call to this method always - * follows a call to {@link #enter(Node, VirtualFrame)}. - * - * @param astNode The AST node on which the execute method is being called - * @param frame The frame that was passed to the execute method - * @param result The result of the call to the execute method. - */ - void leave(Node astNode, VirtualFrame frame, char result); - - /** - * Notifies a probe that an AST Node's object-valued execute method is about to exit. - *

    - * Callers should assure (via {@code try/finally}) that a matching call to this method always - * follows a call to {@link #enter(Node, VirtualFrame)}. - * - * @param astNode The AST node on which the execute method is being called - * @param frame The frame that was passed to the execute method - * @param result The result of the call to the execute method. - */ - void leave(Node astNode, VirtualFrame frame, Object result); - - /** - * Notifies a probe that an AST Node's execute method is about to leave under exceptional - * conditions, returning no value. - *

    - * Callers should assure (via {@code try/finally}) that a matching call to this method always - * follows a call to {@link #enter(Node, VirtualFrame)}. - * - * @param astNode The AST node on which the execute method is being called - * @param frame The frame that was passed to the execute method - * @param e the exception associated with the unusual return - */ - void leaveExceptional(Node astNode, VirtualFrame frame, Exception e); - - /** - * Notifies a probe that an AST node is about to be replaced with another. - * - * @param oldAstNode the AST node currently in the tree - * @param newAstNode the AST replacement node - * @param reason explanation for the replacement - */ - void replace(Node oldAstNode, Node newAstNode, String reason); - -} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/instrument/InstrumentationProbeNode.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/instrument/InstrumentationProbeNode.java Wed Apr 23 15:22:20 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,500 +0,0 @@ -/* - * Copyright (c) 2013, 2014, 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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.truffle.api.nodes.instrument; - -import java.util.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; - -/** - * A probe: a Truffle instrumentation node that holds code to perform some action - * when notified (via a {@linkplain InstrumentationProxyNode proxy node} in the AST) of a - * {@linkplain InstrumentationProbeEvents probe event} taking place at the AST node. - *

    - * Probes are only active when attached to a {@linkplain ProbeChain "probe chain"} that is referred - * to by one or more {@linkplain InstrumentationProxyNode proxy nodes} in an AST. - */ -public abstract class InstrumentationProbeNode extends Node implements InstrumentationNode, InstrumentationProbeEvents { - - /** - * Next in chain. - */ - @Child protected InstrumentationProbeNode next; - - protected InstrumentationProbeNode() { - } - - protected int countProbes() { - return next == null ? 0 : next.countProbes() + 1; - } - - protected boolean isStepping() { - final InstrumentationProbeNode parent = (InstrumentationProbeNode) getParent(); - return parent.isStepping(); - } - - /** - * Add a probe to the end of this probe chain. - */ - protected void internalAppendProbe(InstrumentationProbeNode newProbeNode) { - if (next == null) { - this.next = insert(newProbeNode); - } else { - next.internalAppendProbe(newProbeNode); - } - } - - protected void internalRemoveProbe(InstrumentationProbeNode oldProbeNode) { - if (next == null) { - throw new RuntimeException("Couldn't find probe to remove: " + oldProbeNode); - } else if (next == oldProbeNode) { - if (oldProbeNode.next == null) { - this.next = null; - } else { - this.next = insert(oldProbeNode.next); - oldProbeNode.next = null; - } - } else { - next.internalRemoveProbe(oldProbeNode); - } - } - - /** - * Passes up the chain notification that a probe has changed its execution state in a way that - * invalidates fast path code. Assumes that there is an instance of {@link ProbeChain} at the - * head of the chain. - */ - @CompilerDirectives.SlowPath - protected void notifyProbeChanged(InstrumentationProbeNode probeNode) { - final InstrumentationProbeNode parent = (InstrumentationProbeNode) getParent(); - parent.notifyProbeChanged(probeNode); - } - - // TODO (mlvdv) making the internal*() methods public is a workaround for a bug/limitation in - // the Truffle compiler; they are intended to be private. - - public void internalEnter(Node astNode, VirtualFrame frame) { - enter(astNode, frame); - if (next != null) { - next.internalEnter(astNode, frame); - } - } - - public void internalLeave(Node astNode, VirtualFrame frame) { - leave(astNode, frame); - if (next != null) { - next.internalLeave(astNode, frame); - } - } - - public void internalLeave(Node astNode, VirtualFrame frame, boolean result) { - leave(astNode, frame, result); - if (next != null) { - next.internalLeave(astNode, frame, result); - } - } - - public void internalLeave(Node astNode, VirtualFrame frame, byte result) { - leave(astNode, frame, result); - if (next != null) { - next.internalLeave(astNode, frame, result); - } - } - - public void internalLeave(Node astNode, VirtualFrame frame, short result) { - leave(astNode, frame, result); - if (next != null) { - next.internalLeave(astNode, frame, result); - } - } - - public void internalLeave(Node astNode, VirtualFrame frame, int result) { - leave(astNode, frame, result); - if (next != null) { - next.internalLeave(astNode, frame, result); - } - } - - public void internalLeave(Node astNode, VirtualFrame frame, long result) { - leave(astNode, frame, result); - if (next != null) { - next.internalLeave(astNode, frame, result); - } - } - - public void internalLeave(Node astNode, VirtualFrame frame, char result) { - leave(astNode, frame, result); - if (next != null) { - next.internalLeave(astNode, frame, result); - } - } - - public void internalLeave(Node astNode, VirtualFrame frame, float result) { - leave(astNode, frame, result); - if (next != null) { - next.internalLeave(astNode, frame, result); - } - } - - public void internalLeave(Node astNode, VirtualFrame frame, double result) { - leave(astNode, frame, result); - if (next != null) { - next.internalLeave(astNode, frame, result); - } - } - - public void internalLeave(Node astNode, VirtualFrame frame, Object result) { - leave(astNode, frame, result); - if (next != null) { - next.internalLeave(astNode, frame, result); - } - } - - public void internalLeaveExceptional(Node astNode, VirtualFrame frame, Exception e) { - leaveExceptional(astNode, frame, null); - if (next != null) { - next.internalLeaveExceptional(astNode, frame, e); - } - } - - public void internalReplace(Node oldAstNode, Node newAstNode, String reason) { - replace(oldAstNode, newAstNode, reason); - if (next != null) { - next.internalReplace(oldAstNode, newAstNode, reason); - } - } - - /** - * A probe implementation that implements all of {@link InstrumentationProbeEvents} with empty - * methods; concrete subclasses can override only the methods for which something is to be done. - */ - public static class DefaultProbeNode extends InstrumentationProbeNode { - - private final ExecutionContext executionContext; - - protected DefaultProbeNode(ExecutionContext context) { - this.executionContext = context; - } - - public ExecutionContext getContext() { - return executionContext; - } - - public void enter(Node astNode, VirtualFrame frame) { - } - - public void leave(Node astNode, VirtualFrame frame) { - } - - public void leave(Node astNode, VirtualFrame frame, boolean result) { - leave(astNode, frame, (Object) result); - } - - public void leave(Node astNode, VirtualFrame frame, byte result) { - leave(astNode, frame, (Object) result); - } - - public void leave(Node astNode, VirtualFrame frame, short result) { - leave(astNode, frame, (Object) result); - } - - public void leave(Node astNode, VirtualFrame frame, int result) { - leave(astNode, frame, (Object) result); - } - - public void leave(Node astNode, VirtualFrame frame, long result) { - leave(astNode, frame, (Object) result); - } - - public void leave(Node astNode, VirtualFrame frame, char result) { - leave(astNode, frame, (Object) result); - } - - public void leave(Node astNode, VirtualFrame frame, float result) { - leave(astNode, frame, (Object) result); - } - - public void leave(Node astNode, VirtualFrame frame, double result) { - leave(astNode, frame, (Object) result); - } - - public void leave(Node astNode, VirtualFrame frame, Object result) { - } - - public void leaveExceptional(Node astNode, VirtualFrame frame, Exception e) { - } - - public void replace(Node oldAstNode, Node newAstNode, String reason) { - } - - } - - /** - * Holder of a chain of {@linkplain InstrumentationProbeNode probes}: manages the - * {@link Assumption} that the chain has not changed since checked checked. - *

    - * May be categorized by one or more {@linkplain NodePhylum node phyla}, signifying information - * useful for instrumentation about its AST location(s). - */ - public static final class ProbeChain extends DefaultProbeNode implements PhylumMarked { - - @CompilerDirectives.CompilationFinal private Assumption probeUnchanged; - - /** - * When in stepping mode, ordinary line breakpoints are ignored, but every entry at a line - * will cause a halt. - */ - @CompilerDirectives.CompilationFinal private boolean stepping; - - /** - * Source information about the node to which this probe chain is attached; it isn't - * otherwise available. A probe chain is shared by every copy made during runtime, so there - * is no parent pointer. - */ - private final SourceSection probedSourceSection; - - private final Set phyla = EnumSet.noneOf(NodePhylum.class); - - private final String description; // for debugging - - /** - * Creates a new, empty chain of {@linkplain InstrumentationProbeNode probes}, to which - * probes can be added/removed, and all of which will be notified of - * {@linkplain InstrumentationProbeEvents events} when the chain is notified. - */ - public ProbeChain(ExecutionContext context, SourceSection sourceSection, String description) { - super(context); - this.probeUnchanged = Truffle.getRuntime().createAssumption(); - this.probedSourceSection = sourceSection; - this.description = description; - this.next = null; - } - - public int probeCount() { - return countProbes(); - } - - public String getDescription() { - return description; - } - - public SourceSection getProbedSourceSection() { - return probedSourceSection; - } - - /** - * Mark this probe chain as being associated with an AST node in some category useful for - * debugging and other tools. - */ - public void markAs(NodePhylum phylum) { - assert phylum != null; - phyla.add(phylum); - } - - /** - * Is this probe chain as being associated with an AST node in some category useful for - * debugging and other tools. - */ - public boolean isMarkedAs(NodePhylum phylum) { - assert phylum != null; - return phyla.contains(phylum); - } - - /** - * In which categories is the AST (with which this probe is associated) marked? - */ - public Set getPhylumMarks() { - return phyla; - } - - /** - * Change stepping mode for statements. - */ - public void setStepping(boolean stepping) { - if (this.stepping != stepping) { - this.stepping = stepping; - probeUnchanged.invalidate(); - probeUnchanged = Truffle.getRuntime().createAssumption(); - } - } - - @Override - protected boolean isStepping() { - return stepping; - } - - @Override - protected int countProbes() { - // The head of the chain does not itself hold a probe - return next == null ? 0 : next.countProbes(); - } - - @Override - protected void notifyProbeChanged(InstrumentationProbeNode probeNode) { - probeUnchanged.invalidate(); - probeUnchanged = Truffle.getRuntime().createAssumption(); - } - - @CompilerDirectives.SlowPath - public void appendProbe(InstrumentationProbeNode newProbeNode) { - probeUnchanged.invalidate(); - super.internalAppendProbe(newProbeNode); - probeUnchanged = Truffle.getRuntime().createAssumption(); - } - - @CompilerDirectives.SlowPath - public void removeProbe(InstrumentationProbeNode oldProbeNode) { - probeUnchanged.invalidate(); - super.internalRemoveProbe(oldProbeNode); - probeUnchanged = Truffle.getRuntime().createAssumption(); - } - - public void notifyEnter(Node astNode, VirtualFrame frame) { - if (stepping || next != null) { - if (!probeUnchanged.isValid()) { - CompilerDirectives.transferToInterpreter(); - } - if (stepping) { - getContext().getDebugContext().getDebugManager().haltedAt(astNode, frame.materialize()); - } - if (next != null) { - next.internalEnter(astNode, frame); - } - } - } - - public void notifyLeave(Node astNode, VirtualFrame frame) { - if (next != null) { - if (!probeUnchanged.isValid()) { - CompilerDirectives.transferToInterpreter(); - } - next.internalLeave(astNode, frame); - } - } - - public void notifyLeave(Node astNode, VirtualFrame frame, boolean result) { - if (next != null) { - if (!probeUnchanged.isValid()) { - CompilerDirectives.transferToInterpreter(); - } - next.internalLeave(astNode, frame, result); - } - } - - public void notifyLeave(Node astNode, VirtualFrame frame, byte result) { - if (next != null) { - if (!probeUnchanged.isValid()) { - CompilerDirectives.transferToInterpreter(); - } - next.internalLeave(astNode, frame, result); - } - } - - public void notifyLeave(Node astNode, VirtualFrame frame, short result) { - if (next != null) { - if (!probeUnchanged.isValid()) { - CompilerDirectives.transferToInterpreter(); - } - next.internalLeave(astNode, frame, result); - } - } - - public void notifyLeave(Node astNode, VirtualFrame frame, int result) { - if (next != null) { - if (!probeUnchanged.isValid()) { - CompilerDirectives.transferToInterpreter(); - } - next.internalLeave(astNode, frame, result); - } - } - - public void notifyLeave(Node astNode, VirtualFrame frame, long result) { - if (next != null) { - if (!probeUnchanged.isValid()) { - CompilerDirectives.transferToInterpreter(); - } - next.internalLeave(astNode, frame, result); - } - } - - public void notifyLeave(Node astNode, VirtualFrame frame, char result) { - if (next != null) { - if (!probeUnchanged.isValid()) { - CompilerDirectives.transferToInterpreter(); - } - next.internalLeave(astNode, frame, result); - } - } - - public void notifyLeave(Node astNode, VirtualFrame frame, float result) { - if (next != null) { - if (!probeUnchanged.isValid()) { - CompilerDirectives.transferToInterpreter(); - } - next.internalLeave(astNode, frame, result); - } - } - - public void notifyLeave(Node astNode, VirtualFrame frame, double result) { - if (next != null) { - if (!probeUnchanged.isValid()) { - CompilerDirectives.transferToInterpreter(); - } - next.internalLeave(astNode, frame, result); - } - } - - public void notifyLeave(Node astNode, VirtualFrame frame, Object result) { - if (next != null) { - if (!probeUnchanged.isValid()) { - CompilerDirectives.transferToInterpreter(); - } - next.internalLeave(astNode, frame, result); - } - } - - public void notifyLeaveExceptional(Node astNode, VirtualFrame frame, Exception e) { - if (next != null) { - if (!probeUnchanged.isValid()) { - CompilerDirectives.transferToInterpreter(); - } - next.internalLeaveExceptional(astNode, frame, e); - } - } - - public void notifyReplace(Node oldAstNode, Node newAstNode, String reason) { - if (next != null) { - if (!probeUnchanged.isValid()) { - CompilerDirectives.transferToInterpreter(); - } - next.internalReplace(oldAstNode, newAstNode, reason); - } - } - - } - -} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/instrument/InstrumentationProxyNode.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/instrument/InstrumentationProxyNode.java Wed Apr 23 15:22:20 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2013, 2014, 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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.truffle.api.nodes.instrument; - -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.nodes.instrument.InstrumentationProbeNode.ProbeChain; - -/** - * Interface implemented by language-specific Truffle proxy nodes: nodes that do - * not participate in the language's execution semantics, but which are inserted into an AST so that - * tools (e.g. tracers, analyzers, debuggers) can be notified of AST interpretation events and - * possibly intervene. - *

    - * Language-specific proxy nodes call notification methods on an attached {@linkplain ProbeChain - * probe chain} which passes along {@linkplain InstrumentationProbeEvents events} to any - * {@linkplain InstrumentationProbeNode probes} that might have been attached. - */ -public interface InstrumentationProxyNode extends InstrumentationNode, PhylumMarked { - - /** - * Gets the non-instrumentation node being proxied. - */ - Node getChild(); - - /** - * Gets the chain of probes to which events at this node are delegated. Note that a chain of - * probes may be used by more than one proxy. - */ - ProbeChain getProbeChain(); - -} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/instrument/NodeInstrumenter.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/instrument/NodeInstrumenter.java Wed Apr 23 15:22:20 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2014, 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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.truffle.api.nodes.instrument; - -import com.oracle.truffle.api.nodes.*; - -/** - * Implements the instrumentation of a Truffle AST node and returning either: - *

      - *
    • the node itself, or
    • - *
    • a newly created {@linkplain InstrumentationProxyNode proxy node} that holds the instrumented - * node as its {@linkplain com.oracle.truffle.api.nodes.Node.Child child}.
    • - *
    - */ -public interface NodeInstrumenter { - - /** - * Wraps a {@linkplain InstrumentationProxyNode proxy node} around a node (if not already - * wrapped), marks the location with a {@linkplain NodePhylum phylum (category)} for user - * interaction, and passes along any characteristics of the particular node that are important - * for instrumentation (e.g. the function/method name at a call). - */ - Node instrumentAs(Node node, NodePhylum phylum, Object... args); -} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/instrument/NodePhylum.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/instrument/NodePhylum.java Wed Apr 23 15:22:20 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,65 +0,0 @@ -/* - * Copyright (c) 2014, 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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.truffle.api.nodes.instrument; - -/** - * Categories of {@link InstrumentationProxyNode}s to be used for defining user-visible debugging - * and other simple tool behavior. These categories (phyla) should correspond to program - * structures that are meaningful to a programmer using the guest language. A Truffle node without a - * proxy carrying some phylum should be treated as an artifact of the guest language implementation - * and should never be visible to the user of a guest language programming tool. - *

    - * Note that phyla are not intended to represent a partition of user-visible node categories, as the - * relative categorization of nodes can change with the particular programming tasks at hand. - *

    - * This is a somewhat language-agnostic set of phyla, suitable for conventional imperative - * languages, and is being developed incrementally. - *

    - * The need for alternative sets of phyla is likely to arise, perhaps for other families of - * languages (for example for mostly expression-oriented languages) or even for specific languages. - *

    - * These are listed alphabetically so that listing from some collection classes will come out in - * that order. - *

    - * Disclaimer: this interface is under development and will change. - */ -public enum NodePhylum { - - /** - * Marker for a proxy at a variable assignment. - */ - ASSIGNMENT, - - /** - * Marker for a proxy at a call site. - */ - CALL, - - /** - * Marker for a proxy at which ordinary "stepping" should halt. - */ - STATEMENT; - -} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/instrument/PhylumMarked.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/instrument/PhylumMarked.java Wed Apr 23 15:22:20 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2014, 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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.truffle.api.nodes.instrument; - -import java.util.*; - -import com.oracle.truffle.api.nodes.*; - -/** - * A kind of {@link Node} that can be marked as belong to 0 or more {@linkplain NodePhylum phyla}. - */ -public interface PhylumMarked { - - /** - * Is this proxy tagged as belonging to a particular category of language constructs? - */ - boolean isMarkedAs(NodePhylum phylum); - - /** - * In which categories is this node tagged (empty set if none). - */ - Set getPhylumMarks(); - -} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/source/SourceLineLocation.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/source/SourceLineLocation.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/source/SourceLineLocation.java Wed Apr 23 15:48:38 2014 +0200 @@ -31,7 +31,7 @@ * instance of {@link Source}, suitable for hash table keys with equality defined in terms of * content. */ -public class SourceLineLocation implements Comparable { +public class SourceLineLocation implements Comparable { private final Source source; private final int line; diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/TruffleProcessor.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/TruffleProcessor.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/TruffleProcessor.java Wed Apr 23 15:48:38 2014 +0200 @@ -60,7 +60,7 @@ // TODO run verifications that other annotations are not processed out of scope of the // operation or typelattice. try { - for (AnnotationProcessor generator : getGenerators()) { + for (AnnotationProcessor generator : getGenerators()) { AbstractParser parser = generator.getParser(); if (parser.getAnnotationType() != null) { for (Element e : env.getElementsAnnotatedWith(parser.getAnnotationType())) { @@ -86,7 +86,7 @@ } } - private static void processElement(RoundEnvironment env, AnnotationProcessor generator, Element e, boolean callback) { + private static void processElement(RoundEnvironment env, AnnotationProcessor generator, Element e, boolean callback) { try { generator.process(env, e, callback); } catch (Throwable e1) { @@ -94,16 +94,15 @@ } } - private static void handleThrowable(AnnotationProcessor generator, Throwable t, Element e) { + private static void handleThrowable(AnnotationProcessor generator, Throwable t, Element e) { String message = "Uncaught error in " + generator.getClass().getSimpleName() + " while processing " + e; generator.getContext().getEnvironment().getMessager().printMessage(Kind.ERROR, message + ": " + Utils.printException(t), e); } - @SuppressWarnings("unchecked") @Override public void callback(TypeElement template) { - for (AnnotationProcessor generator : generators) { - Class annotationType = generator.getParser().getAnnotationType(); + for (AnnotationProcessor generator : generators) { + Class annotationType = generator.getParser().getAnnotationType(); if (annotationType != null) { Annotation annotation = template.getAnnotation(annotationType); if (annotation != null) { diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/TruffleTypes.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/TruffleTypes.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/TruffleTypes.java Wed Apr 23 15:48:38 2014 +0200 @@ -112,7 +112,7 @@ return nodeCost; } - private DeclaredType getRequired(ProcessorContext context, Class clazz) { + private DeclaredType getRequired(ProcessorContext context, Class clazz) { TypeMirror type = context.getType(clazz); if (type == null) { errors.add(String.format("Could not find required type: %s", clazz.getSimpleName())); diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/compiler/AbstractCompiler.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/compiler/AbstractCompiler.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/compiler/AbstractCompiler.java Wed Apr 23 15:48:38 2014 +0200 @@ -32,7 +32,7 @@ return method.invoke(o); } - protected static Object method(Object o, String methodName, Class[] paramTypes, Object... values) throws Exception { + protected static Object method(Object o, String methodName, Class[] paramTypes, Object... values) throws Exception { Method method = o.getClass().getMethod(methodName, paramTypes); method.setAccessible(true); return method.invoke(o, values); diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/compiler/JavaCCompiler.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/compiler/JavaCCompiler.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/compiler/JavaCCompiler.java Wed Apr 23 15:48:38 2014 +0200 @@ -44,8 +44,8 @@ return type.getEnclosedElements(); } - private static final Class[] getTreeAndTopLevelSignature = new Class[]{Element.class, AnnotationMirror.class, AnnotationValue.class}; - private static final Class[] getCharContentSignature = new Class[]{boolean.class}; + private static final Class[] getTreeAndTopLevelSignature = new Class[]{Element.class, AnnotationMirror.class, AnnotationValue.class}; + private static final Class[] getCharContentSignature = new Class[]{boolean.class}; @Override public String getMethodBody(ProcessingEnvironment env, ExecutableElement method) { diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/CodeElementFactory.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/CodeElementFactory.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/CodeElementFactory.java Wed Apr 23 15:48:38 2014 +0200 @@ -44,7 +44,7 @@ protected void createChildren(M m) { } - @SuppressWarnings("unchecked") + @SuppressWarnings({"unchecked", "rawtypes"}) public CodeElement process(CodeElement parent, M m) { model = m; element = (CodeElement) create(model); @@ -57,6 +57,7 @@ return element; } + @SuppressWarnings("rawtypes") public CodeElement getElement() { return element; } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/CompilationUnitFactory.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/CompilationUnitFactory.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/CompilationUnitFactory.java Wed Apr 23 15:48:38 2014 +0200 @@ -36,6 +36,7 @@ return new CodeCompilationUnit(); } + @SuppressWarnings("rawtypes") @Override public CodeCompilationUnit process(CodeElement parent, M m) { return (CodeCompilationUnit) super.process(parent, m); diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.truffle.sl.test/tests/HelloEqualsWorld.output --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.sl.test/tests/HelloEqualsWorld.output Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,90 @@ +Initial stack trace: +Frame: root doIt, a=0, hello=null +Frame: root main, i=0 +After 123 assignment: +Frame: root doIt, a=0, hello=123 +Frame: root main, i=0 +After hello assignment: +Frame: root doIt, a=0, hello=world +Frame: root main, i=0 +Initial stack trace: +Frame: root doIt, a=1, hello=null +Frame: root main, i=1 +After 123 assignment: +Frame: root doIt, a=1, hello=123 +Frame: root main, i=1 +After hello assignment: +Frame: root doIt, a=1, hello=world +Frame: root main, i=1 +Initial stack trace: +Frame: root doIt, a=2, hello=null +Frame: root main, i=2 +After 123 assignment: +Frame: root doIt, a=2, hello=123 +Frame: root main, i=2 +After hello assignment: +Frame: root doIt, a=2, hello=world +Frame: root main, i=2 +Initial stack trace: +Frame: root doIt, a=3, hello=null +Frame: root main, i=3 +After 123 assignment: +Frame: root doIt, a=3, hello=123 +Frame: root main, i=3 +After hello assignment: +Frame: root doIt, a=3, hello=world +Frame: root main, i=3 +Initial stack trace: +Frame: root doIt, a=4, hello=null +Frame: root main, i=4 +After 123 assignment: +Frame: root doIt, a=4, hello=123 +Frame: root main, i=4 +After hello assignment: +Frame: root doIt, a=4, hello=world +Frame: root main, i=4 +Initial stack trace: +Frame: root doIt, a=5, hello=null +Frame: root main, i=5 +After 123 assignment: +Frame: root doIt, a=5, hello=123 +Frame: root main, i=5 +After hello assignment: +Frame: root doIt, a=5, hello=world +Frame: root main, i=5 +Initial stack trace: +Frame: root doIt, a=6, hello=null +Frame: root main, i=6 +After 123 assignment: +Frame: root doIt, a=6, hello=123 +Frame: root main, i=6 +After hello assignment: +Frame: root doIt, a=6, hello=world +Frame: root main, i=6 +Initial stack trace: +Frame: root doIt, a=7, hello=null +Frame: root main, i=7 +After 123 assignment: +Frame: root doIt, a=7, hello=123 +Frame: root main, i=7 +After hello assignment: +Frame: root doIt, a=7, hello=world +Frame: root main, i=7 +Initial stack trace: +Frame: root doIt, a=8, hello=null +Frame: root main, i=8 +After 123 assignment: +Frame: root doIt, a=8, hello=123 +Frame: root main, i=8 +After hello assignment: +Frame: root doIt, a=8, hello=world +Frame: root main, i=8 +Initial stack trace: +Frame: root doIt, a=9, hello=null +Frame: root main, i=9 +After 123 assignment: +Frame: root doIt, a=9, hello=123 +Frame: root main, i=9 +After hello assignment: +Frame: root doIt, a=9, hello=world +Frame: root main, i=9 \ No newline at end of file diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.truffle.sl.test/tests/HelloEqualsWorld.sl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.sl.test/tests/HelloEqualsWorld.sl Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,22 @@ +function doIt(a) { + println("Initial stack trace:"); + println(stacktrace()); + + hello = 123; + println("After 123 assignment:"); + println(stacktrace()); + + helloEqualsWorld(); + println("After hello assignment:"); + println(stacktrace()); + +// readln(); +} + +function main() { + i = 0; + while (i < 10) { + doIt(i); + i = i + 1; + } +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLHelloEqualsWorldBuiltin.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLHelloEqualsWorldBuiltin.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2012, 2014, 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.truffle.sl.builtins; + +import com.oracle.truffle.api.*; +import com.oracle.truffle.api.dsl.*; +import com.oracle.truffle.api.frame.*; +import com.oracle.truffle.api.frame.FrameInstance.FrameAccess; +import com.oracle.truffle.api.nodes.*; + +/** + * This builtin sets the variable named "hello" in the caller frame to the string "world". + */ +@NodeInfo(shortName = "helloEqualsWorld") +public abstract class SLHelloEqualsWorldBuiltin extends SLBuiltinNode { + + @Specialization + public String change() { + FrameInstance frameInstance = Truffle.getRuntime().getStackTrace().iterator().next(); + Frame frame = frameInstance.getFrame(FrameAccess.READ_WRITE, false); + FrameSlot slot = frame.getFrameDescriptor().findOrAddFrameSlot("hello"); + frame.setObject(slot, "world"); + return "world"; + } +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLStackTraceBuiltin.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLStackTraceBuiltin.java Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2012, 2014, 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.truffle.sl.builtins; + +import com.oracle.truffle.api.*; +import com.oracle.truffle.api.CompilerDirectives.SlowPath; +import com.oracle.truffle.api.dsl.*; +import com.oracle.truffle.api.frame.*; +import com.oracle.truffle.api.frame.FrameInstance.FrameAccess; +import com.oracle.truffle.api.nodes.*; + +/** + * Returns a string representation of the current stack. This includes the {@link CallTarget}s and + * the contents of the {@link Frame}. Note that this is implemented as a slow path by passing + * {@code true} to {@link FrameInstance#getFrame(FrameAccess, boolean)}. + */ +@NodeInfo(shortName = "stacktrace") +public abstract class SLStackTraceBuiltin extends SLBuiltinNode { + + @Specialization + public String trace() { + return createStackTrace(); + } + + @SlowPath + private static String createStackTrace() { + StringBuilder str = new StringBuilder(); + Iterable frames = Truffle.getRuntime().getStackTrace(); + + if (frames != null) { + for (FrameInstance frame : frames) { + dumpFrame(str, frame.getCallTarget(), frame.getFrame(FrameAccess.READ_ONLY, true), frame.isVirtualFrame()); + } + } + return str.toString(); + } + + private static void dumpFrame(StringBuilder str, CallTarget rootNode, Frame frame, boolean isVirtual) { + if (str.length() > 0) { + str.append("\n"); + } + str.append("Frame: ").append(rootNode).append(isVirtual ? " (virtual)" : ""); + FrameDescriptor frameDescriptor = frame.getFrameDescriptor(); + for (FrameSlot s : frameDescriptor.getSlots()) { + str.append(", ").append(s.getIdentifier()).append("=").append(frame.getValue(s)); + } + } +} diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/call/SLDirectDispatchNode.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/call/SLDirectDispatchNode.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/call/SLDirectDispatchNode.java Wed Apr 23 15:48:38 2014 +0200 @@ -36,11 +36,11 @@ private final SLFunction cachedFunction; /** - * {@link CallNode} is part of the Truffle API and handles all the steps necessary for method - * inlining: if the call is executed frequently and the callee is small, then the call is + * {@link DirectCallNode} is part of the Truffle API and handles all the steps necessary for + * method inlining: if the call is executed frequently and the callee is small, then the call is * inlined, i.e., the call node is replaced with a copy of the callee's AST. */ - @Child private CallNode callCachedTargetNode; + @Child private DirectCallNode callCachedTargetNode; /** Assumption that the {@link #callCachedTargetNode} is still valid. */ private final Assumption cachedTargetStable; @@ -53,7 +53,7 @@ protected SLDirectDispatchNode(SLAbstractDispatchNode next, SLFunction cachedFunction) { this.cachedFunction = cachedFunction; - this.callCachedTargetNode = Truffle.getRuntime().createCallNode(cachedFunction.getCallTarget()); + this.callCachedTargetNode = Truffle.getRuntime().createDirectCallNode(cachedFunction.getCallTarget()); this.cachedTargetStable = cachedFunction.getCallTargetStable(); this.nextNode = next; } @@ -92,7 +92,7 @@ * Now we are really ready to perform the call. We use a Truffle CallNode for that, * because it does all the work for method inlining. */ - return callCachedTargetNode.call(arguments); + return callCachedTargetNode.call(frame, arguments); } catch (InvalidAssumptionException ex) { /* diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/call/SLGenericDispatchNode.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/call/SLGenericDispatchNode.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/call/SLGenericDispatchNode.java Wed Apr 23 15:48:38 2014 +0200 @@ -22,7 +22,9 @@ */ package com.oracle.truffle.sl.nodes.call; +import com.oracle.truffle.api.*; import com.oracle.truffle.api.frame.*; +import com.oracle.truffle.api.nodes.*; import com.oracle.truffle.sl.runtime.*; /** @@ -31,12 +33,20 @@ */ final class SLGenericDispatchNode extends SLAbstractDispatchNode { + /** + * {@link IndirectCallNode} is part of the Truffle API and handles all the steps necessary for + * calling a megamorphic call-site. The Graal specific version of this node performs additional + * optimizations for the fast access of the SimpleLanguage stack trace. + */ + @Child private IndirectCallNode callNode = Truffle.getRuntime().createIndirectCallNode(); + @Override protected Object executeDispatch(VirtualFrame frame, SLFunction function, Object[] arguments) { /* * SL has a quite simple call lookup: just ask the function for the current call target, and * call it. */ - return function.getCallTarget().call(arguments); + return callNode.call(frame, function.getCallTarget(), arguments); } + } diff -r 518a7f487c4f -r 9363fffa8b07 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/runtime/SLContext.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/runtime/SLContext.java Wed Apr 23 15:22:20 2014 +0200 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/runtime/SLContext.java Wed Apr 23 15:48:38 2014 +0200 @@ -97,6 +97,8 @@ installBuiltin(SLPrintlnBuiltinFactory.getInstance()); installBuiltin(SLNanoTimeBuiltinFactory.getInstance()); installBuiltin(SLDefineFunctionBuiltinFactory.getInstance()); + installBuiltin(SLStackTraceBuiltinFactory.getInstance()); + installBuiltin(SLHelloEqualsWorldBuiltinFactory.getInstance()); } private void installBuiltin(NodeFactory factory) { diff -r 518a7f487c4f -r 9363fffa8b07 make/linux/makefiles/buildtree.make --- a/make/linux/makefiles/buildtree.make Wed Apr 23 15:22:20 2014 +0200 +++ b/make/linux/makefiles/buildtree.make Wed Apr 23 15:48:38 2014 +0200 @@ -258,6 +258,10 @@ echo "$(call gamma-path,altsrc,os/$(OS_FAMILY)/vm) \\"; \ echo "$(call gamma-path,commonsrc,os/$(OS_FAMILY)/vm) \\"; \ echo "$(call gamma-path,commonsrc,os/posix/vm) \\"; \ + echo "$(call gamma-path,altsrc,gpu/ptx/vm) \\"; \ + echo "$(call gamma-path,commonsrc,gpu/ptx/vm)" \\; \ + echo "$(call gamma-path,altsrc,gpu/hsail/vm) \\"; \ + echo "$(call gamma-path,commonsrc,gpu/hsail/vm) \\"; \ echo "$(call gamma-path,altsrc,gpu) \\"; \ echo "$(call gamma-path,commonsrc,gpu)"; \ [ -n "$(CFLAGS_BROWSE)" ] && \ diff -r 518a7f487c4f -r 9363fffa8b07 make/linux/makefiles/vm.make --- a/make/linux/makefiles/vm.make Wed Apr 23 15:22:20 2014 +0200 +++ b/make/linux/makefiles/vm.make Wed Apr 23 15:48:38 2014 +0200 @@ -185,8 +185,10 @@ GRAAL_PATHS += $(call altsrc,$(HS_COMMON_SRC)/share/vm/graal) GRAAL_PATHS += $(call altsrc,$(HS_COMMON_SRC)/gpu/ptx/vm) +GRAAL_PATHS += $(call altsrc,$(HS_COMMON_SRC)/gpu/hsail/vm) GRAAL_PATHS += $(HS_COMMON_SRC)/share/vm/graal GRAAL_PATHS += $(HS_COMMON_SRC)/gpu/ptx/vm +GRAAL_PATHS += $(HS_COMMON_SRC)/gpu/hsail/vm # Include dirs per type. Src_Dirs/CORE := $(CORE_PATHS) diff -r 518a7f487c4f -r 9363fffa8b07 make/solaris/makefiles/mapfile-vers --- a/make/solaris/makefiles/mapfile-vers Wed Apr 23 15:22:20 2014 +0200 +++ b/make/solaris/makefiles/mapfile-vers Wed Apr 23 15:48:38 2014 +0200 @@ -223,8 +223,6 @@ JVM_SetLength; JVM_SetNativeThreadName; JVM_SetPrimitiveArrayElement; - # Preserved so that Graal repo can link against a JDK7 libjava.so works - JVM_SetProtectionDomain; JVM_SetSockOpt; JVM_SetThreadPriority; JVM_Sleep; diff -r 518a7f487c4f -r 9363fffa8b07 mx/eclipse-settings/org.eclipse.jdt.core.prefs --- a/mx/eclipse-settings/org.eclipse.jdt.core.prefs Wed Apr 23 15:22:20 2014 +0200 +++ b/mx/eclipse-settings/org.eclipse.jdt.core.prefs Wed Apr 23 15:48:38 2014 +0200 @@ -87,7 +87,7 @@ org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=warning org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=ignore -org.eclipse.jdt.core.compiler.problem.rawTypeReference=ignore +org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=warning @@ -100,7 +100,6 @@ org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning -org.eclipse.jdt.core.compiler.problem.tasks=ignore org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning org.eclipse.jdt.core.compiler.problem.unclosedCloseable=ignore diff -r 518a7f487c4f -r 9363fffa8b07 mx/mx_graal.py --- a/mx/mx_graal.py Wed Apr 23 15:22:20 2014 +0200 +++ b/mx/mx_graal.py Wed Apr 23 15:48:38 2014 +0200 @@ -28,7 +28,7 @@ import os, sys, shutil, zipfile, tempfile, re, time, datetime, platform, subprocess, multiprocessing, StringIO from os.path import join, exists, dirname, basename, getmtime -from argparse import ArgumentParser, REMAINDER +from argparse import ArgumentParser, RawDescriptionHelpFormatter, REMAINDER from outputparser import OutputParser, ValuesMatcher import mx import xml.dom.minidom @@ -828,7 +828,7 @@ else: return [], args -def _run_tests(args, harness, annotations, testfile): +def _run_tests(args, harness, annotations, testfile, whitelist): vmArgs, tests = _extract_VM_args(args) @@ -860,6 +860,9 @@ mx.log('warning: no tests matched by substring "' + t) projectscp = mx.classpath(projs) + if whitelist: + classes = list(set(classes) & set(whitelist)) + if len(classes) != 0: f_testfile = open(testfile, 'w') for c in classes: @@ -867,7 +870,7 @@ f_testfile.close() harness(projectscp, vmArgs) -def _unittest(args, annotations, prefixcp=""): +def _unittest(args, annotations, prefixcp="", whitelist=None): mxdir = dirname(__file__) name = 'JUnitWrapper' javaSource = join(mxdir, name + '.java') @@ -894,12 +897,20 @@ vm(prefixArgs + vmArgs + ['-cp', prefixcp + projectscp + os.pathsep + mxdir, name] + [testfile]) try: - _run_tests(args, harness, annotations, testfile) + _run_tests(args, harness, annotations, testfile, whitelist) finally: if os.environ.get('MX_TESTFILE') is None: os.remove(testfile) _unittestHelpSuffix = """ + Unittest options: + + --short-only run short testcases only + --long-only run long testcases only + --baseline-whitelist run only testcases which are known to + work with the baseline compiler + + To avoid conflicts with VM options '--' can be used as delimiter. If filters are supplied, only tests whose fully qualified name includes a filter as a substring are run. @@ -928,17 +939,63 @@ def unittest(args): """run the JUnit tests (all testcases){0}""" - _unittest(args, ['@Test', '@LongTest', '@Parameters']) + parser = ArgumentParser(prog='mx unittest', + description='run the JUnit tests', + add_help=False, + formatter_class=RawDescriptionHelpFormatter, + epilog=_unittestHelpSuffix, + ) + group = parser.add_mutually_exclusive_group() + group.add_argument('--short-only', action='store_true', help='run short testcases only') + group.add_argument('--long-only', action='store_true', help='run long testcases only') + parser.add_argument('--baseline-whitelist', action='store_true', help='run baseline testcases only') + + ut_args = [] + delimiter = False + # check for delimiter + while len(args) > 0: + arg = args.pop(0) + if arg == '--': + delimiter = True + break + ut_args.append(arg) + + if delimiter: + # all arguments before '--' must be recognized + parsed_args = parser.parse_args(ut_args) + else: + # parse all know arguments + parsed_args, args = parser.parse_known_args(ut_args) + + whitelist = None + if parsed_args.baseline_whitelist: + baseline_whitelist_file = 'test/baseline_whitelist.txt' + try: + with open(join(_graal_home, baseline_whitelist_file)) as fp: + whitelist = [l.rstrip() for l in fp.readlines()] + except IOError: + mx.log('warning: could not read baseline whitelist: ' + baseline_whitelist_file) + + if parsed_args.long_only: + annotations = ['@LongTest', '@Parameters'] + elif parsed_args.short_only: + annotations = ['@Test'] + else: + annotations = ['@Test', '@LongTest', '@Parameters'] + + _unittest(args, annotations, whitelist=whitelist) def shortunittest(args): - """run the JUnit tests (short testcases only){0}""" + """alias for 'unittest --short-only'{0}""" - _unittest(args, ['@Test']) + args.insert(0, '--short-only') + unittest(args) def longunittest(args): - """run the JUnit tests (long testcases only){0}""" + """alias for 'unittest --long-only'{0}""" - _unittest(args, ['@LongTest', '@Parameters']) + args.insert(0, '--long-only') + unittest(args) def buildvms(args): """build one or more VMs in various configurations""" @@ -1248,10 +1305,10 @@ else: executable = join(libpath, 'c1visualizer', 'bin', 'c1visualizer') - archive = join(libpath, 'c1visualizer.zip') - if not exists(executable): + archive = join(libpath, 'c1visualizer_2014-04-22.zip') + if not exists(executable) or not exists(archive): if not exists(archive): - mx.download(archive, ['https://java.net/downloads/c1visualizer/c1visualizer.zip']) + mx.download(archive, ['https://java.net/downloads/c1visualizer/c1visualizer_2014-04-22.zip']) zf = zipfile.ZipFile(archive, 'r') zf.extractall(libpath) @@ -1345,33 +1402,154 @@ with open(resultFile, 'w') as f: f.write(json.dumps(results)) -def jmh(args): - """run the JMH_BENCHMARKS""" +def _get_jmh_path(): + path = mx.get_env('JMH_BENCHMARKS', None) + if not path: + probe = join(dirname(_graal_home), 'java-benchmarks') + if exists(probe): + path = probe + + if not path: + mx.abort("Please set the JMH_BENCHMARKS environment variable to point to the java-benchmarks workspace") + if not exists(path): + mx.abort("The directory denoted by the JMH_BENCHMARKS environment variable does not exist: " + path) + return path + +def makejmhdeps(args): + """creates and installs Maven dependencies required by the JMH benchmarks - # TODO: add option for `mvn clean package' - # TODO: add options to pass through arguments directly to JMH + The dependencies are specified by files named pom.mxdeps in the + JMH directory tree. Each such file contains a list of dependencies + defined in JSON format. For example: + + '[{"artifactId" : "compiler.test", "groupId" : "com.oracle.graal", "deps" : ["com.oracle.graal.compiler.test"]}]' + + will result in a dependency being installed in the local Maven repository + that can be referenced in a pom.xml file as follows: + + + com.oracle.graal + compiler.test + 1.0-SNAPSHOT + """ + + parser = ArgumentParser(prog='mx makejmhdeps') + parser.add_argument('-s', '--settings', help='alternative path for Maven user settings file', metavar='') + parser.add_argument('-p', '--permissive', action='store_true', help='issue note instead of error if a Maven dependency cannot be built due to missing projects/libraries') + args = parser.parse_args(args) - vmArgs, benchmarks = _extract_VM_args(args) - jmhPath = mx.get_env('JMH_BENCHMARKS', None) - if not jmhPath or not exists(jmhPath): - mx.abort("$JMH_BENCHMARKS not properly defined: " + str(jmhPath)) + def makejmhdep(artifactId, groupId, deps): + graalSuite = mx.suite("graal") + path = artifactId + '.jar' + if args.permissive: + for name in deps: + if not mx.project(name, fatalIfMissing=False): + if not mx.library(name, fatalIfMissing=False): + mx.log('Skipping ' + groupId + '.' + artifactId + '.jar as ' + name + ' cannot be resolved') + return + d = mx.Distribution(graalSuite, name=artifactId, path=path, sourcesPath=path, deps=deps, excludedLibs=[]) + d.make_archive() + cmd = ['mvn', 'install:install-file', '-DgroupId=' + groupId, '-DartifactId=' + artifactId, + '-Dversion=1.0-SNAPSHOT', '-Dpackaging=jar', '-Dfile=' + d.path] + if not mx._opts.verbose: + cmd.append('-q') + if args.settings: + cmd = cmd + ['-s', args.settings] + mx.run(cmd) + os.unlink(d.path) - def _blackhole(x): - mx.logv(x[:-1]) + jmhPath = _get_jmh_path() + for root, _, filenames in os.walk(jmhPath): + for f in [join(root, n) for n in filenames if n == 'pom.mxdeps']: + mx.logv('[processing ' + f + ']') + try: + with open(f) as fp: + for d in json.load(fp): + artifactId = d['artifactId'] + groupId = d['groupId'] + deps = d['deps'] + makejmhdep(artifactId, groupId, deps) + except ValueError as e: + mx.abort('Error parsing {}:\n{}'.format(f, e)) + +def buildjmh(args): + """build the JMH benchmarks""" + parser = ArgumentParser(prog='mx buildjmh') + parser.add_argument('-s', '--settings', help='alternative path for Maven user settings file', metavar='') + parser.add_argument('-c', action='store_true', dest='clean', help='clean before building') + args = parser.parse_args(args) - # (Re)install graal.jar into the local m2 repository since the micros-graal - # benchmarks have it as a dependency - graalDist = mx.distribution('GRAAL') - cmd = ['mvn', 'install:install-file', '-q', - '-Dfile=' + graalDist.path, '-DgroupId=com.oracle.graal', '-DartifactId=graal', - '-Dversion=1.0-SNAPSHOT', '-Dpackaging=jar'] - if graalDist.sourcesPath: - cmd = cmd + ['-Dsources=' + graalDist.sourcesPath] - mx.run(cmd) + jmhPath = _get_jmh_path() + mx.log('JMH benchmarks: ' + jmhPath) + + # Ensure the mx injected dependencies are up to date + makejmhdeps(['-p'] + (['-s', args.settings] if args.settings else [])) + + timestamp = mx.TimeStampFile(join(_graal_home, 'mx', 'jmh', jmhPath.replace(os.sep, '_') + '.timestamp')) + mustBuild = args.clean + if not mustBuild: + try: + hgfiles = [join(jmhPath, f) for f in subprocess.check_output(['hg', '-R', jmhPath, 'locate']).split('\n')] + mustBuild = timestamp.isOlderThan(hgfiles) + except: + # not a Mercurial repository or hg commands are not available. + mustBuild = True - mx.log("Building benchmarks...") - mx.run(['mvn', 'package'], cwd=jmhPath, out=_blackhole) + if mustBuild: + buildOutput = [] + def _redirect(x): + if mx._opts.verbose: + mx.log(x[:-1]) + else: + buildOutput.append(x) + env = os.environ.copy() + env['JAVA_HOME'] = _jdk(vmToCheck='server') + env['MAVEN_OPTS'] = '-server' + mx.log("Building benchmarks...") + cmd = ['mvn'] + if args.settings: + cmd = cmd + ['-s', args.settings] + if args.clean: + cmd.append('clean') + cmd.append('package') + retcode = mx.run(cmd, cwd=jmhPath, out=_redirect, env=env, nonZeroIsFatal=False) + if retcode != 0: + mx.log(''.join(buildOutput)) + mx.abort(retcode) + timestamp.touch() + else: + mx.logv('[all Mercurial controlled files in ' + jmhPath + ' are older than ' + timestamp.path + ' - skipping build]') + +def jmh(args): + """run the JMH benchmarks + + This command respects the standard --vm and --vmbuild options + for choosing which VM to run the benchmarks with.""" + if '-h' in args: + mx.help_(['jmh']) + mx.abort(1) + + vmArgs, benchmarksAndJsons = _extract_VM_args(args) + + benchmarks = [b for b in benchmarksAndJsons if not b.startswith('{')] + jmhArgJsons = [b for b in benchmarksAndJsons if b.startswith('{')] + + jmhArgs = {'-rff' : join(_graal_home, 'mx', 'jmh', 'jmh.out'), '-v' : 'EXTRA' if mx._opts.verbose else 'NORMAL'} + + # e.g. '{"-wi" : 20}' + for j in jmhArgJsons: + try: + for n, v in json.loads(j).iteritems(): + if v is None: + del jmhArgs[n] + else: + jmhArgs[n] = v + except ValueError as e: + mx.abort('error parsing JSON input: {}\n{}'.format(j, e)) + + jmhPath = _get_jmh_path() + mx.log('Using benchmarks in ' + jmhPath) matchedSuites = set() numBench = [0] @@ -1385,8 +1563,7 @@ microJar = os.path.join(absoluteMicro, "target", "microbenchmarks.jar") if not exists(microJar): - mx.logv('JMH: ignored ' + absoluteMicro + " because it doesn't contain the expected jar file ('" + microJar + "')") - continue + mx.abort('Missing ' + microJar + ' - please run "mx buildjmh"') if benchmarks: def _addBenchmark(x): if x.startswith("Benchmark:"): @@ -1417,16 +1594,14 @@ (pfx, exe, vm, forkedVmArgs, _) = _parseVmArgs(vmArgs) if pfx: mx.warn("JMH ignores prefix: \"" + pfx + "\"") - mx.run_java( - ['-jar', os.path.join(absoluteMicro, "target", "microbenchmarks.jar"), - "-f", "1", - "-v", "EXTRA" if mx._opts.verbose else "NORMAL", - "-i", "10", "-wi", "10", - "--jvm", exe, - "--jvmArgs", " ".join(["-" + vm] + forkedVmArgs)] + regex, - addDefaultArgs=False, - cwd=jmhPath) - + javaArgs = ['-jar', os.path.join(absoluteMicro, "target", "microbenchmarks.jar"), + '--jvm', exe, + '--jvmArgs', ' '.join(["-" + vm] + forkedVmArgs)] + for k, v in jmhArgs.iteritems(): + javaArgs.append(k) + if len(str(v)): + javaArgs.append(str(v)) + mx.run_java(javaArgs + regex, addDefaultArgs=False, cwd=jmhPath) def specjvm2008(args): """run one or more SPECjvm2008 benchmarks""" @@ -1757,6 +1932,7 @@ def mx_init(suite): commands = { 'build': [build, ''], + 'buildjmh': [buildjmh, '[-options]'], 'buildvars': [buildvars, ''], 'buildvms': [buildvms, '[-options]'], 'c1visualizer' : [c1visualizer, ''], @@ -1768,7 +1944,7 @@ 'hcfdis': [hcfdis, ''], 'igv' : [igv, ''], 'jdkhome': [print_jdkhome, ''], - 'jmh': [jmh, '[VM options] [filters...]'], + 'jmh': [jmh, '[VM options] [filters|JMH-args-as-json...]'], 'dacapo': [dacapo, '[VM options] benchmarks...|"all" [DaCapo options]'], 'scaladacapo': [scaladacapo, '[VM options] benchmarks...|"all" [Scala DaCapo options]'], 'specjvm2008': [specjvm2008, '[VM options] benchmarks...|"all" [SPECjvm2008 options]'], @@ -1776,9 +1952,10 @@ 'specjbb2005': [specjbb2005, '[VM options] [-- [SPECjbb2005 options]]'], 'gate' : [gate, '[-options]'], 'bench' : [bench, '[-resultfile file] [all(default)|dacapo|specjvm2008|bootstrap]'], - 'unittest' : [unittest, '[VM options] [filters...]', _unittestHelpSuffix], - 'longunittest' : [longunittest, '[VM options] [filters...]', _unittestHelpSuffix], - 'shortunittest' : [shortunittest, '[VM options] [filters...]', _unittestHelpSuffix], + 'unittest' : [unittest, '[unittest options] [--] [VM options] [filters...]', _unittestHelpSuffix], + 'longunittest' : [longunittest, '[unittest options] [--] [VM options] [filters...]', _unittestHelpSuffix], + 'makejmhdeps' : [makejmhdeps, ''], + 'shortunittest' : [shortunittest, '[unittest options] [--] [VM options] [filters...]', _unittestHelpSuffix], 'jacocoreport' : [jacocoreport, '[output directory]'], 'site' : [site, '[-options]'], 'vm': [vm, '[-options] class [args...]'], diff -r 518a7f487c4f -r 9363fffa8b07 mx/projects --- a/mx/projects Wed Apr 23 15:22:20 2014 +0200 +++ b/mx/projects Wed Apr 23 15:48:38 2014 +0200 @@ -5,10 +5,21 @@ library@JDK_TOOLS@path=${JAVA_HOME}/lib/tools.jar library@JDK_TOOLS@optional=true -library@JUNIT@path=lib/junit-4.8.jar -library@JUNIT@urls=http://repo1.maven.org/maven2/junit/junit/4.8/junit-4.8.jar -library@JUNIT@sha1=4150c00c5706306ef0f8f1410e70c8ff12757922 +library@JUNIT@path=lib/junit-4.11.jar +library@JUNIT@urls=http://repo1.maven.org/maven2/junit/junit/4.11/junit-4.11.jar +library@JUNIT@sha1=4e031bb61df09069aeb2bffb4019e7a5034a4ee0 library@JUNIT@eclipse.container=org.eclipse.jdt.junit.JUNIT_CONTAINER/4 +library@JUNIT@sourcePath=lib/junit-4.11-sources.jar +library@JUNIT@sourceUrls=http://repo1.maven.org/maven2/junit/junit/4.11/junit-4.11-sources.jar +library@JUNIT@sourceSha1=28e0ad201304e4a4abf999ca0570b7cffc352c3c +library@JUNIT@dependencies=HAMCREST + +library@HAMCREST@path=lib/hamcrest-core-1.3.jar +library@HAMCREST@urls=http://repo1.maven.org/maven2/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3.jar +library@HAMCREST@sha1=42a25dc3219429f0e5d060061f71acb49bf010a0 +library@HAMCREST@sourcePath=lib/hamcrest-core-1.3-sources.jar +library@HAMCREST@sourceUrls=http://repo1.maven.org/maven2/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3-sources.jar +library@HAMCREST@sourceSha1=1dc37250fbc78e23a65a67fbbaf71d2e9cbc3c0b library@CHECKSTYLE@path=lib/checkstyle-5.5-all.jar library@CHECKSTYLE@urls=jar:http://sourceforge.net/projects/checkstyle/files/checkstyle/5.5/checkstyle-5.5-bin.zip/download!/checkstyle-5.5/checkstyle-5.5-all.jar @@ -45,6 +56,9 @@ library@JAVA_ALLOCATION_INSTRUMENTER@urls=http://lafo.ssw.uni-linz.ac.at/java-allocation-instrumenter/java-allocation-instrumenter-8f0db117e64e.jar library@JAVA_ALLOCATION_INSTRUMENTER@sha1=64c0a5329fbcb8284640e58d83252e0a3b08c23e +library@VECMATH@path=lib/vecmath-1.3.1.jar +library@VECMATH@urls=http://mirrors.ibiblio.org/pub/mirrors/maven/java3d/jars/vecmath-1.3.1.jar + distribution@GRAAL@path=graal.jar distribution@GRAAL@sourcesPath=graal.src.zip distribution@GRAAL@dependencies=\ @@ -239,7 +253,7 @@ # graal.graph project@com.oracle.graal.graph@subDir=graal project@com.oracle.graal.graph@sourceDirs=src -project@com.oracle.graal.graph@dependencies=com.oracle.graal.debug,com.oracle.graal.api.code,FINDBUGS +project@com.oracle.graal.graph@dependencies=com.oracle.graal.debug,com.oracle.graal.compiler.common,FINDBUGS project@com.oracle.graal.graph@javaCompliance=1.8 project@com.oracle.graal.graph@workingSets=Graal,Graph @@ -269,7 +283,7 @@ # graal.lir project@com.oracle.graal.lir@subDir=graal project@com.oracle.graal.lir@sourceDirs=src -project@com.oracle.graal.lir@dependencies=com.oracle.graal.asm,com.oracle.graal.nodes +project@com.oracle.graal.lir@dependencies=com.oracle.graal.debug,com.oracle.graal.compiler.common,com.oracle.graal.asm project@com.oracle.graal.lir@checkstyle=com.oracle.graal.graph project@com.oracle.graal.lir@javaCompliance=1.8 project@com.oracle.graal.lir@workingSets=Graal,LIR @@ -359,7 +373,7 @@ # graal.nodes project@com.oracle.graal.nodes@subDir=graal project@com.oracle.graal.nodes@sourceDirs=src -project@com.oracle.graal.nodes@dependencies=com.oracle.graal.graph,com.oracle.graal.api.replacements +project@com.oracle.graal.nodes@dependencies=com.oracle.graal.graph,com.oracle.graal.api.replacements,com.oracle.graal.lir project@com.oracle.graal.nodes@checkstyle=com.oracle.graal.graph project@com.oracle.graal.nodes@javaCompliance=1.8 project@com.oracle.graal.nodes@annotationProcessors=com.oracle.graal.replacements.verifier @@ -376,7 +390,7 @@ # graal.phases project@com.oracle.graal.phases@subDir=graal project@com.oracle.graal.phases@sourceDirs=src -project@com.oracle.graal.phases@dependencies=com.oracle.graal.nodes,com.oracle.graal.options +project@com.oracle.graal.phases@dependencies=com.oracle.graal.nodes project@com.oracle.graal.phases@checkstyle=com.oracle.graal.graph project@com.oracle.graal.phases@javaCompliance=1.8 project@com.oracle.graal.phases@workingSets=Graal,Phases @@ -408,7 +422,7 @@ # graal.compiler project@com.oracle.graal.compiler@subDir=graal project@com.oracle.graal.compiler@sourceDirs=src -project@com.oracle.graal.compiler@dependencies=com.oracle.graal.api.runtime,com.oracle.graal.virtual,com.oracle.graal.loop,com.oracle.graal.alloc,com.oracle.graal.lir +project@com.oracle.graal.compiler@dependencies=com.oracle.graal.api.runtime,com.oracle.graal.virtual,com.oracle.graal.loop,com.oracle.graal.alloc project@com.oracle.graal.compiler@checkstyle=com.oracle.graal.graph project@com.oracle.graal.compiler@javaCompliance=1.8 project@com.oracle.graal.compiler@annotationProcessors=com.oracle.graal.service.processor @@ -485,6 +499,14 @@ project@com.oracle.graal.java@javaCompliance=1.8 project@com.oracle.graal.java@workingSets=Graal,Java +# graal.compiler.common +project@com.oracle.graal.compiler.common@subDir=graal +project@com.oracle.graal.compiler.common@sourceDirs=src +project@com.oracle.graal.compiler.common@dependencies=com.oracle.graal.api.code,com.oracle.graal.options +project@com.oracle.graal.compiler.common@checkstyle=com.oracle.graal.graph +project@com.oracle.graal.compiler.common@javaCompliance=1.8 +project@com.oracle.graal.compiler.common@workingSets=Graal,Java + # graal.baseline project@com.oracle.graal.baseline@subDir=graal project@com.oracle.graal.baseline@sourceDirs=src @@ -611,14 +633,14 @@ # graal.compiler.hsail.test project@com.oracle.graal.compiler.hsail.test@subDir=graal project@com.oracle.graal.compiler.hsail.test@sourceDirs=src -project@com.oracle.graal.compiler.hsail.test@dependencies=com.oracle.graal.compiler.hsail.test.infra,com.oracle.graal.compiler.test +project@com.oracle.graal.compiler.hsail.test@dependencies=com.oracle.graal.compiler.hsail.test.infra,com.oracle.graal.compiler.test,VECMATH project@com.oracle.graal.compiler.hsail.test@checkstyle=com.oracle.graal.graph project@com.oracle.graal.compiler.hsail.test@javaCompliance=1.8 # graal.asm.hsail project@com.oracle.graal.asm.hsail@subDir=graal project@com.oracle.graal.asm.hsail@sourceDirs=src -project@com.oracle.graal.asm.hsail@dependencies=com.oracle.graal.hsail,OKRA,com.oracle.graal.asm,com.oracle.graal.graph +project@com.oracle.graal.asm.hsail@dependencies=com.oracle.graal.hsail,OKRA,com.oracle.graal.asm,com.oracle.graal.compiler.common project@com.oracle.graal.asm.hsail@checkstyle=com.oracle.graal.graph project@com.oracle.graal.asm.hsail@javaCompliance=1.8 @@ -723,7 +745,7 @@ # graal.truffle.hotspot.amd64 project@com.oracle.graal.truffle.hotspot.amd64@subDir=graal project@com.oracle.graal.truffle.hotspot.amd64@sourceDirs=src -project@com.oracle.graal.truffle.hotspot.amd64@dependencies=com.oracle.graal.truffle.hotspot,com.oracle.graal.hotspot.amd64 +project@com.oracle.graal.truffle.hotspot.amd64@dependencies=com.oracle.graal.truffle.hotspot,com.oracle.graal.asm.amd64 project@com.oracle.graal.truffle.hotspot.amd64@checkstyle=com.oracle.graal.graph project@com.oracle.graal.truffle.hotspot.amd64@javaCompliance=1.8 project@com.oracle.graal.truffle.hotspot.amd64@annotationProcessors=com.oracle.graal.service.processor diff -r 518a7f487c4f -r 9363fffa8b07 mxtool/mx.py --- a/mxtool/mx.py Wed Apr 23 15:22:20 2014 +0200 +++ b/mxtool/mx.py Wed Apr 23 15:48:38 2014 +0200 @@ -36,6 +36,7 @@ import sys, os, errno, time, subprocess, shlex, types, urllib2, contextlib, StringIO, zipfile, signal, xml.sax.saxutils, tempfile, fnmatch import textwrap import socket +import tarfile import hashlib import xml.parsers.expat import shutil, re, xml.dom.minidom @@ -84,6 +85,89 @@ def add_update_listener(self, listener): self.update_listeners.add(listener) + def make_archive(self): + # are sources combined into main archive? + unified = self.path == self.sourcesPath + + with Archiver(self.path) as arc, Archiver(None if unified else self.sourcesPath) as srcArcRaw: + srcArc = arc if unified else srcArcRaw + services = {} + def overwriteCheck(zf, arcname, source): + if not hasattr(zf, '_provenance'): + zf._provenance = {} + existingSource = zf._provenance.get(arcname, None) + if existingSource and existingSource != source and not arcname.endswith('/'): + log('warning: ' + self.path + ': overwriting ' + arcname + '\n new: ' + source + '\n old: ' + existingSource) + zf._provenance[arcname] = source + + for dep in self.sorted_deps(includeLibs=True): + if dep.isLibrary(): + l = dep + # merge library jar into distribution jar + logv('[' + self.path + ': adding library ' + l.name + ']') + lpath = l.get_path(resolve=True) + libSourcePath = l.get_source_path(resolve=True) + if lpath: + with zipfile.ZipFile(lpath, 'r') as lp: + for arcname in lp.namelist(): + if arcname.startswith('META-INF/services/') and not arcname == 'META-INF/services/': + service = arcname[len('META-INF/services/'):] + assert '/' not in service + services.setdefault(service, []).extend(lp.read(arcname).splitlines()) + else: + overwriteCheck(arc.zf, arcname, lpath + '!' + arcname) + arc.zf.writestr(arcname, lp.read(arcname)) + if srcArc.zf and libSourcePath: + with zipfile.ZipFile(libSourcePath, 'r') as lp: + for arcname in lp.namelist(): + overwriteCheck(srcArc.zf, arcname, lpath + '!' + arcname) + srcArc.zf.writestr(arcname, lp.read(arcname)) + else: + p = dep + # skip a Java project if its Java compliance level is "higher" than the configured JDK + jdk = java(p.javaCompliance) + if not jdk: + log('Excluding {0} from {2} (Java compliance level {1} required)'.format(p.name, p.javaCompliance, self.path)) + continue + + logv('[' + self.path + ': adding project ' + p.name + ']') + outputDir = p.output_dir() + for root, _, files in os.walk(outputDir): + relpath = root[len(outputDir) + 1:] + if relpath == join('META-INF', 'services'): + for service in files: + with open(join(root, service), 'r') as fp: + services.setdefault(service, []).extend([provider.strip() for provider in fp.readlines()]) + elif relpath == join('META-INF', 'providers'): + for provider in files: + with open(join(root, provider), 'r') as fp: + for service in fp: + services.setdefault(service.strip(), []).append(provider) + else: + for f in files: + arcname = join(relpath, f).replace(os.sep, '/') + overwriteCheck(arc.zf, arcname, join(root, f)) + arc.zf.write(join(root, f), arcname) + if srcArc.zf: + sourceDirs = p.source_dirs() + if p.source_gen_dir(): + sourceDirs.append(p.source_gen_dir()) + for srcDir in sourceDirs: + for root, _, files in os.walk(srcDir): + relpath = root[len(srcDir) + 1:] + for f in files: + if f.endswith('.java'): + arcname = join(relpath, f).replace(os.sep, '/') + overwriteCheck(srcArc.zf, arcname, join(root, f)) + srcArc.zf.write(join(root, f), arcname) + + for service, providers in services.iteritems(): + arcname = 'META-INF/services/' + service + arc.zf.writestr(arcname, '\n'.join(providers)) + + self.notify_updated() + + def notify_updated(self): for l in self.update_listeners: l(self) @@ -358,6 +442,18 @@ print >> fp, ap return outOfDate + def make_archive(self, path=None): + outputDir = self.output_dir() + if not path: + path = join(self.dir, self.name + '.jar') + with Archiver(path) as arc: + for root, _, files in os.walk(outputDir): + for f in files: + relpath = root[len(outputDir) + 1:] + arcname = join(relpath, f).replace(os.sep, '/') + arc.zf.write(join(root, f), arcname) + return path + def _make_absolute(path, prefix): """ Makes 'path' absolute if it isn't already by prefixing 'prefix' @@ -405,7 +501,7 @@ return path class Library(Dependency): - def __init__(self, suite, name, path, mustExist, urls, sha1, sourcePath, sourceUrls, sourceSha1): + def __init__(self, suite, name, path, mustExist, urls, sha1, sourcePath, sourceUrls, sourceSha1, deps): Dependency.__init__(self, suite, name) self.path = path.replace('/', os.sep) self.urls = urls @@ -414,6 +510,7 @@ self.sourcePath = sourcePath self.sourceUrls = sourceUrls self.sourceSha1 = sourceSha1 + self.deps = deps for url in urls: if url.endswith('/') != self.path.endswith(os.sep): abort('Path for dependency directory must have a URL ending with "/": path=' + self.path + ' url=' + url) @@ -447,9 +544,9 @@ def get_source_path(self, resolve): - if self.path is None: + if self.sourcePath is None: return None - path = _make_absolute(self.path, self.suite.dir) + path = _make_absolute(self.sourcePath, self.suite.dir) sha1path = path + '.sha1' return _download_file_with_sha1(self.name, path, self.sourceUrls, self.sourceSha1, sha1path, resolve, len(self.sourceUrls) != 0, sources=True) @@ -460,9 +557,21 @@ cp.append(path) def all_deps(self, deps, includeLibs, includeSelf=True, includeAnnotationProcessors=False): - if not includeLibs or not includeSelf: + """ + Add the transitive set of dependencies for this library to the 'deps' list. + """ + if not includeLibs: + return deps + childDeps = list(self.deps) + if self in deps: return deps - deps.append(self) + for name in childDeps: + assert name != self.name + dep = library(name) + if not dep in deps: + dep.all_deps(deps, includeLibs=includeLibs, includeAnnotationProcessors=includeAnnotationProcessors) + if not self in deps and includeSelf: + deps.append(self) return deps class HgConfig: @@ -619,7 +728,8 @@ sourcePath = attrs.pop('sourcePath', None) sourceUrls = pop_list(attrs, 'sourceUrls') sourceSha1 = attrs.pop('sourceSha1', None) - l = Library(self, name, path, mustExist, urls, sha1, sourcePath, sourceUrls, sourceSha1) + deps = pop_list(attrs, 'dependencies') + l = Library(self, name, path, mustExist, urls, sha1, sourcePath, sourceUrls, sourceSha1, deps) l.__dict__.update(attrs) self.libs.append(l) @@ -1693,6 +1803,7 @@ parser.add_argument('--force-javac', action='store_true', dest='javac', help='use javac despite ecj.jar is found or not') parser.add_argument('--jdt', help='path to ecj.jar, the Eclipse batch compiler (default: ' + defaultEcjPath + ')', default=defaultEcjPath, metavar='') parser.add_argument('--jdt-warning-as-error', action='store_true', help='convert all Eclipse batch compiler warnings to errors') + parser.add_argument('--jdt-show-task-tags', action='store_true', help='show task tags as Eclipse batch compiler warnings') parser.add_argument('--error-prone', dest='error_prone', help='path to error-prone.jar', metavar='') if suppliedParser: @@ -1918,11 +2029,15 @@ if not exists(jdtProperties): log('JDT properties file {0} not found'.format(jdtProperties)) else: - # convert all warnings to errors - if args.jdt_warning_as_error: + with open(jdtProperties) as fp: + origContent = fp.read() + content = origContent + if args.jdt_warning_as_error: + content = content.replace('=warning', '=error') + if not args.jdt_show_task_tags: + content = content + '\norg.eclipse.jdt.core.compiler.problem.tasks=ignore' + if origContent != content: jdtPropertiesTmp = jdtProperties + '.tmp' - with open(jdtProperties) as fp: - content = fp.read().replace('=warning', '=error') with open(jdtPropertiesTmp, 'w') as fp: fp.write(content) toBeDeleted.append(jdtPropertiesTmp) @@ -1943,6 +2058,39 @@ return args return None +def _chunk_files_for_command_line(files, limit=None, pathFunction=None): + """ + Returns a generator for splitting up a list of files into chunks such that the + size of the space separated file paths in a chunk is less than a given limit. + This is used to work around system command line length limits. + """ + chunkSize = 0 + chunkStart = 0 + if limit is None: + commandLinePrefixAllowance = 3000 + if get_os() == 'windows': + # The CreateProcess function on Windows limits the length of a command line to + # 32,768 characters (http://msdn.microsoft.com/en-us/library/ms682425%28VS.85%29.aspx) + limit = 32768 - commandLinePrefixAllowance + else: + # Using just SC_ARG_MAX without extra downwards adjustment + # results in "[Errno 7] Argument list too long" on MacOS. + syslimit = os.sysconf('SC_ARG_MAX') - 20000 + limit = syslimit - commandLinePrefixAllowance + for i in range(len(files)): + path = files[i] if pathFunction is None else pathFunction(files[i]) + size = len(path) + 1 + if chunkSize + size < limit: + chunkSize += size + else: + assert i > chunkStart + yield files[chunkStart:i] + chunkStart = i + chunkSize = 0 + if chunkStart == 0: + assert chunkSize < limit + yield files + def eclipseformat(args): """run the Eclipse Code Formatter on the Java sources @@ -2045,18 +2193,19 @@ if res is not batch: res.javafiles = res.javafiles + batch.javafiles - print "we have: " + str(len(batches)) + " batches" + log("we have: " + str(len(batches)) + " batches") for batch in batches.itervalues(): - run([args.eclipse_exe, - '-nosplash', - '-application', - 'org.eclipse.jdt.core.JavaCodeFormatter', - '-vm', java(batch.javaCompliance).java, - '-config', batch.path] - + [f.path for f in batch.javafiles]) - for fi in batch.javafiles: - if fi.update(batch.removeTrailingWhitespace): - modified.append(fi) + for chunk in _chunk_files_for_command_line(batch.javafiles, pathFunction=lambda f: f.path): + run([args.eclipse_exe, + '-nosplash', + '-application', + 'org.eclipse.jdt.core.JavaCodeFormatter', + '-vm', java(batch.javaCompliance).java, + '-config', batch.path] + + [f.path for f in chunk]) + for fi in chunk: + if fi.update(batch.removeTrailingWhitespace): + modified.append(fi) log('{0} files were modified'.format(len(modified))) @@ -2165,124 +2314,50 @@ log('Running pylint on ' + pyfile + '...') run(['pylint', '--reports=n', '--rcfile=' + rcfile, pyfile], env=env) +""" +Utility for creating and updating a zip file atomically. +""" +class Archiver: + def __init__(self, path): + self.path = path + + def __enter__(self): + if self.path: + fd, tmp = tempfile.mkstemp(suffix='', prefix=basename(self.path) + '.', dir=dirname(self.path)) + self.tmpFd = fd + self.tmpPath = tmp + self.zf = zipfile.ZipFile(tmp, 'w') + else: + self.tmpFd = None + self.tmpPath = None + self.zf = None + return self + + def __exit__(self, exc_type, exc_value, traceback): + if self.zf: + self.zf.close() + os.close(self.tmpFd) + # Correct the permissions on the temporary file which is created with restrictive permissions + os.chmod(self.tmpPath, 0o666 & ~currentUmask) + # Atomic on Unix + shutil.move(self.tmpPath, self.path) + def archive(args): """create jar files for projects and distributions""" parser = ArgumentParser(prog='mx archive') parser.add_argument('names', nargs=REMAINDER, metavar='[|@]...') args = parser.parse_args(args) - - class Archive: - def __init__(self, path): - self.path = path - - def __enter__(self): - if self.path: - fd, tmp = tempfile.mkstemp(suffix='', prefix=basename(self.path) + '.', dir=dirname(self.path)) - self.tmpFd = fd - self.tmpPath = tmp - self.zf = zipfile.ZipFile(tmp, 'w') - else: - self.tmpFd = None - self.tmpPath = None - self.zf = None - return self - - def __exit__(self, exc_type, exc_value, traceback): - if self.zf: - self.zf.close() - os.close(self.tmpFd) - # Correct the permissions on the temporary file which is created with restrictive permissions - os.chmod(self.tmpPath, 0o666 & ~currentUmask) - # Atomic on Unix - shutil.move(self.tmpPath, self.path) - archives = [] for name in args.names: if name.startswith('@'): dname = name[1:] d = distribution(dname) - with Archive(d.path) as arc, Archive(d.sourcesPath) as srcArc: - services = {} - def overwriteCheck(zf, arcname, source): - if arcname in zf.namelist(): - log('warning: ' + d.path + ': overwriting ' + arcname + ' [source: ' + source + ']') - - for dep in d.sorted_deps(includeLibs=True): - if dep.isLibrary(): - l = dep - # merge library jar into distribution jar - logv('[' + d.path + ': adding library ' + l.name + ']') - lpath = l.get_path(resolve=True) - libSourcePath = l.get_source_path(resolve=True) - if lpath: - with zipfile.ZipFile(lpath, 'r') as lp: - for arcname in lp.namelist(): - if arcname.startswith('META-INF/services/') and not arcname == 'META-INF/services/': - service = arcname[len('META-INF/services/'):] - assert '/' not in service - services.setdefault(service, []).extend(lp.read(arcname).splitlines()) - else: - overwriteCheck(arc.zf, arcname, lpath + '!' + arcname) - arc.zf.writestr(arcname, lp.read(arcname)) - if srcArc.zf and libSourcePath: - with zipfile.ZipFile(libSourcePath, 'r') as lp: - for arcname in lp.namelist(): - overwriteCheck(srcArc.zf, arcname, lpath + '!' + arcname) - srcArc.zf.writestr(arcname, lp.read(arcname)) - else: - p = dep - # skip a Java project if its Java compliance level is "higher" than the configured JDK - jdk = java(p.javaCompliance) - if not jdk: - log('Excluding {0} from {2} (Java compliance level {1} required)'.format(p.name, p.javaCompliance, d.path)) - continue - - logv('[' + d.path + ': adding project ' + p.name + ']') - outputDir = p.output_dir() - for root, _, files in os.walk(outputDir): - relpath = root[len(outputDir) + 1:] - if relpath == join('META-INF', 'services'): - for service in files: - with open(join(root, service), 'r') as fp: - services.setdefault(service, []).extend([provider.strip() for provider in fp.readlines()]) - elif relpath == join('META-INF', 'providers'): - for provider in files: - with open(join(root, provider), 'r') as fp: - for service in fp: - services.setdefault(service.strip(), []).append(provider) - else: - for f in files: - arcname = join(relpath, f).replace(os.sep, '/') - overwriteCheck(arc.zf, arcname, join(root, f)) - arc.zf.write(join(root, f), arcname) - if srcArc.zf: - for srcDir in p.source_dirs(): - for root, _, files in os.walk(srcDir): - relpath = root[len(srcDir) + 1:] - for f in files: - if f.endswith('.java'): - arcname = join(relpath, f).replace(os.sep, '/') - overwriteCheck(srcArc.zf, arcname, join(root, f)) - srcArc.zf.write(join(root, f), arcname) - - for service, providers in services.iteritems(): - arcname = 'META-INF/services/' + service - arc.zf.writestr(arcname, '\n'.join(providers)) - - d.notify_updated() + d.make_archive() archives.append(d.path) - else: p = project(name) - outputDir = p.output_dir() - with Archive(join(p.dir, p.name + '.jar')) as arc: - for root, _, files in os.walk(outputDir): - for f in files: - relpath = root[len(outputDir) + 1:] - arcname = join(relpath, f).replace(os.sep, '/') - arc.zf.write(join(root, f), arcname) - archives.append(arc.path) + archives.append(p.make_archive()) return archives @@ -2462,26 +2537,9 @@ log('Running Checkstyle on {0} using {1}...'.format(sourceDir, config)) try: - - # Checkstyle is unable to read the filenames to process from a file, and the - # CreateProcess function on Windows limits the length of a command line to - # 32,768 characters (http://msdn.microsoft.com/en-us/library/ms682425%28VS.85%29.aspx) - # so calling Checkstyle must be done in batches. - while len(javafilelist) != 0: - i = 0 - size = 0 - while i < len(javafilelist): - s = len(javafilelist[i]) + 1 - if size + s < 30000: - size += s - i += 1 - else: - break - - batch = javafilelist[:i] - javafilelist = javafilelist[i:] + for chunk in _chunk_files_for_command_line(javafilelist): try: - run_java(['-Xmx1g', '-jar', library('CHECKSTYLE').get_path(True), '-f', 'xml', '-c', config, '-o', auditfileName] + batch, nonZeroIsFatal=False) + run_java(['-Xmx1g', '-jar', library('CHECKSTYLE').get_path(True), '-f', 'xml', '-c', config, '-o', auditfileName] + chunk, nonZeroIsFatal=False) finally: if exists(auditfileName): errors = [] @@ -2853,35 +2911,47 @@ if exists(join(p.dir, 'plugin.xml')): # eclipse plugin project out.element('classpathentry', {'kind' : 'con', 'path' : 'org.eclipse.pde.core.requiredPlugins'}) + containerDeps = set() + libraryDeps = set() + projectDeps = set() + for dep in p.all_deps([], True): if dep == p: continue - if dep.isLibrary(): if hasattr(dep, 'eclipse.container'): - out.element('classpathentry', {'exported' : 'true', 'kind' : 'con', 'path' : getattr(dep, 'eclipse.container')}) - elif hasattr(dep, 'eclipse.project'): - out.element('classpathentry', {'combineaccessrules' : 'false', 'exported' : 'true', 'kind' : 'src', 'path' : '/' + getattr(dep, 'eclipse.project')}) + container = getattr(dep, 'eclipse.container') + containerDeps.add(container) + libraryDeps -= set(dep.all_deps([], True)) else: - path = dep.path - dep.get_path(resolve=True) - if not path or (not exists(path) and not dep.mustExist): - continue - - # Relative paths for "lib" class path entries have various semantics depending on the Eclipse - # version being used (e.g. see https://bugs.eclipse.org/bugs/show_bug.cgi?id=274737) so it's - # safest to simply use absolute paths. - path = _make_absolute(path, p.suite.dir) - - attributes = {'exported' : 'true', 'kind' : 'lib', 'path' : path} - - sourcePath = dep.get_source_path(resolve=True) - if sourcePath is not None: - attributes['sourcepath'] = sourcePath - out.element('classpathentry', attributes) - libFiles.append(path) + libraryDeps.add(dep) else: - out.element('classpathentry', {'combineaccessrules' : 'false', 'exported' : 'true', 'kind' : 'src', 'path' : '/' + dep.name}) + projectDeps.add(dep) + + for dep in containerDeps: + out.element('classpathentry', {'exported' : 'true', 'kind' : 'con', 'path' : dep}) + + for dep in libraryDeps: + path = dep.path + dep.get_path(resolve=True) + if not path or (not exists(path) and not dep.mustExist): + continue + + # Relative paths for "lib" class path entries have various semantics depending on the Eclipse + # version being used (e.g. see https://bugs.eclipse.org/bugs/show_bug.cgi?id=274737) so it's + # safest to simply use absolute paths. + path = _make_absolute(path, p.suite.dir) + + attributes = {'exported' : 'true', 'kind' : 'lib', 'path' : path} + + sourcePath = dep.get_source_path(resolve=True) + if sourcePath is not None: + attributes['sourcepath'] = sourcePath + out.element('classpathentry', attributes) + libFiles.append(path) + + for dep in projectDeps: + out.element('classpathentry', {'combineaccessrules' : 'false', 'exported' : 'true', 'kind' : 'src', 'path' : '/' + dep.name}) out.element('classpathentry', {'kind' : 'output', 'path' : getattr(p, 'eclipse.output', 'bin')}) out.close('classpath') @@ -3554,6 +3624,193 @@ _zip_files(files, suite.dir, configZip.path) _zip_files(libFiles, suite.dir, configLibsZip) +def intellijinit(args, refreshOnly=False): + """(re)generate Intellij project configurations""" + + for suite in suites(True): + _intellij_suite(args, suite, refreshOnly) + +def _intellij_suite(args, suite, refreshOnly=False): + + libraries = set() + + ideaProjectDirectory = join(suite.dir, '.idea') + + if not exists(ideaProjectDirectory): + os.mkdir(ideaProjectDirectory) + nameFile = join(ideaProjectDirectory, '.name') + update_file(nameFile, "Graal") + modulesXml = XMLDoc() + modulesXml.open('project', attributes={'version': '4'}) + modulesXml.open('component', attributes={'name': 'ProjectModuleManager'}) + modulesXml.open('modules') + + + def _intellij_exclude_if_exists(xml, p, name): + path = join(p.dir, name) + if exists(path): + xml.element('excludeFolder', attributes={'url':'file://$MODULE_DIR$/' + name}) + + annotationProcessorProfiles = {} + + def _complianceToIntellijLanguageLevel(compliance): + return 'JDK_1_' + str(compliance.value) + + # create the modules (1 module = 1 Intellij project) + for p in suite.projects: + if p.native: + continue + + if not java(p.javaCompliance): + log('Excluding {0} (JDK with compliance level {1} not available)'.format(p.name, p.javaCompliance)) + continue + + if not exists(p.dir): + os.makedirs(p.dir) + + annotationProcessorProfileKey = tuple(p.annotation_processors()) + + if not annotationProcessorProfileKey in annotationProcessorProfiles: + annotationProcessorProfiles[annotationProcessorProfileKey] = [p] + else: + annotationProcessorProfiles[annotationProcessorProfileKey].append(p) + + intellijLanguageLevel = _complianceToIntellijLanguageLevel(p.javaCompliance) + + moduleXml = XMLDoc() + moduleXml.open('module', attributes={'type': 'JAVA_MODULE', 'version': '4'}) + + moduleXml.open('component', attributes={'name': 'NewModuleRootManager', 'LANGUAGE_LEVEL': intellijLanguageLevel, 'inherit-compiler-output': 'false'}) + moduleXml.element('output', attributes={'url': 'file://$MODULE_DIR$/bin'}) + moduleXml.element('exclude-output') + + moduleXml.open('content', attributes={'url': 'file://$MODULE_DIR$'}) + for src in p.srcDirs: + srcDir = join(p.dir, src) + if not exists(srcDir): + os.mkdir(srcDir) + moduleXml.element('sourceFolder', attributes={'url':'file://$MODULE_DIR$/' + src, 'isTestSource': 'false'}) + + if len(p.annotation_processors()) > 0: + genDir = p.source_gen_dir() + if not exists(genDir): + os.mkdir(genDir) + moduleXml.element('sourceFolder', attributes={'url':'file://$MODULE_DIR$/' + os.path.relpath(genDir, p.dir), 'isTestSource': 'false'}) + + for name in ['.externalToolBuilders', '.settings', 'nbproject']: + _intellij_exclude_if_exists(moduleXml, p, name) + moduleXml.close('content') + + moduleXml.element('orderEntry', attributes={'type': 'jdk', 'jdkType': 'JavaSDK', 'jdkName': str(p.javaCompliance)}) + moduleXml.element('orderEntry', attributes={'type': 'sourceFolder', 'forTests': 'false'}) + + deps = p.all_deps([], True, includeAnnotationProcessors=True) + for dep in deps: + if dep == p: + continue + + if dep.isLibrary(): + if dep.mustExist: + libraries.add(dep) + moduleXml.element('orderEntry', attributes={'type': 'library', 'name': dep.name, 'level': 'project'}) + else: + moduleXml.element('orderEntry', attributes={'type': 'module', 'module-name': dep.name}) + + moduleXml.close('component') + moduleXml.close('module') + moduleFile = join(p.dir, p.name + '.iml') + update_file(moduleFile, moduleXml.xml(indent=' ', newl='\n')) + + moduleFilePath = "$PROJECT_DIR$/" + os.path.relpath(moduleFile, suite.dir) + modulesXml.element('module', attributes={'fileurl': 'file://' + moduleFilePath, 'filepath': moduleFilePath}) + + modulesXml.close('modules') + modulesXml.close('component') + modulesXml.close('project') + moduleXmlFile = join(ideaProjectDirectory, 'modules.xml') + update_file(moduleXmlFile, modulesXml.xml(indent=' ', newl='\n')) + + # TODO What about cross-suite dependencies? + + librariesDirectory = join(ideaProjectDirectory, 'libraries') + + if not exists(librariesDirectory): + os.mkdir(librariesDirectory) + + # Setup the libraries that were used above + # TODO: setup all the libraries from the suite regardless of usage? + for library in libraries: + libraryXml = XMLDoc() + + libraryXml.open('component', attributes={'name': 'libraryTable'}) + libraryXml.open('library', attributes={'name': library.name}) + libraryXml.open('CLASSES') + libraryXml.element('root', attributes={'url': 'jar://$PROJECT_DIR$/' + os.path.relpath(library.get_path(True), suite.dir) + '!/'}) + libraryXml.close('CLASSES') + libraryXml.element('JAVADOC') + if library.sourcePath: + libraryXml.open('SOURCES') + libraryXml.element('root', attributes={'url': 'jar://$PROJECT_DIR$/' + os.path.relpath(library.get_source_path(True), suite.dir) + '!/'}) + libraryXml.close('SOURCES') + else: + libraryXml.element('SOURCES') + libraryXml.close('library') + libraryXml.close('component') + + libraryFile = join(librariesDirectory, library.name + '.xml') + update_file(libraryFile, libraryXml.xml(indent=' ', newl='\n')) + + + + # Set annotation processor profiles up, and link them to modules in compiler.xml + compilerXml = XMLDoc() + compilerXml.open('project', attributes={'version': '4'}) + compilerXml.open('component', attributes={'name': 'CompilerConfiguration'}) + + compilerXml.element('option', attributes={'name': "DEFAULT_COMPILER", 'value': 'Javac'}) + compilerXml.element('resourceExtensions') + compilerXml.open('wildcardResourcePatterns') + compilerXml.element('entry', attributes={'name': '!?*.java'}) + compilerXml.close('wildcardResourcePatterns') + + if annotationProcessorProfiles: + compilerXml.open('annotationProcessing') + for processors, modules in annotationProcessorProfiles.items(): + compilerXml.open('profile', attributes={'default': 'false', 'name': '-'.join(processors), 'enabled': 'true'}) + compilerXml.element('sourceOutputDir', attributes={'name': 'src_gen'}) # TODO use p.source_gen_dir() ? + compilerXml.element('outputRelativeToContentRoot', attributes={'value': 'true'}) + compilerXml.open('processorPath', attributes={'useClasspath': 'false'}) + for apName in processors: + pDep = dependency(apName) + for entry in pDep.all_deps([], True): + if entry.isLibrary(): + compilerXml.element('entry', attributes={'name': '$PROJECT_DIR$/' + os.path.relpath(entry.path, suite.dir)}) + else: + assert entry.isProject() + compilerXml.element('entry', attributes={'name': '$PROJECT_DIR$/' + os.path.relpath(entry.output_dir(), suite.dir)}) + compilerXml.close('processorPath') + for module in modules: + compilerXml.element('module', attributes={'name': module.name}) + compilerXml.close('profile') + compilerXml.close('annotationProcessing') + + compilerXml.close('component') + compilerXml.close('project') + compilerFile = join(ideaProjectDirectory, 'compiler.xml') + update_file(compilerFile, compilerXml.xml(indent=' ', newl='\n')) + + # Wite misc.xml for global JDK config + miscXml = XMLDoc() + miscXml.open('project', attributes={'version': '4'}) + miscXml.element('component', attributes={'name': 'ProjectRootManager', 'version': '2', 'languageLevel': _complianceToIntellijLanguageLevel(java().javaCompliance), 'project-jdk-name': str(java().javaCompliance), 'project-jdk-type': 'JavaSDK'}) + miscXml.close('project') + miscFile = join(ideaProjectDirectory, 'misc.xml') + update_file(miscFile, miscXml.xml(indent=' ', newl='\n')) + + + # TODO look into copyright settings + # TODO should add vcs.xml support + def ideclean(args): """remove all Eclipse and NetBeans project configurations""" def rm(path): @@ -3563,6 +3820,7 @@ for s in suites(): rm(join(s.mxDir, 'eclipse-config.zip')) rm(join(s.mxDir, 'netbeans-config.zip')) + shutil.rmtree(join(s.dir, '.idea'), ignore_errors=True) for p in projects(): if p.native: @@ -3575,6 +3833,7 @@ rm(join(p.dir, '.checkstyle')) rm(join(p.dir, '.project')) rm(join(p.dir, '.factorypath')) + rm(join(p.dir, p.name + '.iml')) rm(join(p.dir, 'build.xml')) rm(join(p.dir, 'eclipse-build.xml')) try: @@ -3587,6 +3846,7 @@ """(re)generate Eclipse and NetBeans project configurations""" eclipseinit(args, refreshOnly=refreshOnly, buildProcessorJars=buildProcessorJars) netbeansinit(args, refreshOnly=refreshOnly, buildProcessorJars=buildProcessorJars) + intellijinit(args, refreshOnly=refreshOnly) if not refreshOnly: fsckprojects([]) @@ -4080,6 +4340,75 @@ return items[indexes[0]] return None +def exportlibs(args): + """export libraries to an archive file""" + + parser = ArgumentParser(prog='exportlibs') + parser.add_argument('-b', '--base', action='store', help='base name of archive (default: libs)', default='libs', metavar='') + parser.add_argument('--arc', action='store', choices=['tgz', 'tbz2', 'tar', 'zip'], default='tgz', help='the type of the archive to create') + parser.add_argument('--no-sha1', action='store_false', dest='sha1', help='do not create SHA1 signature of archive') + parser.add_argument('--no-md5', action='store_false', dest='md5', help='do not create MD5 signature of archive') + parser.add_argument('--include-system-libs', action='store_true', help='include system libraries (i.e., those not downloaded from URLs)') + parser.add_argument('extras', nargs=REMAINDER, help='extra files and directories to add to archive', metavar='files...') + args = parser.parse_args(args) + + def createArchive(addMethod): + entries = {} + def add(path, arcname): + apath = os.path.abspath(path) + if not entries.has_key(arcname): + entries[arcname] = apath + logv('[adding ' + path + ']') + addMethod(path, arcname=arcname) + elif entries[arcname] != apath: + logv('[warning: ' + apath + ' collides with ' + entries[arcname] + ' as ' + arcname + ']') + else: + logv('[already added ' + path + ']') + + for lib in _libs.itervalues(): + if len(lib.urls) != 0 or args.include_system_libs: + add(lib.get_path(resolve=True), lib.path) + if args.extras: + for e in args.extras: + if os.path.isdir(e): + for root, _, filenames in os.walk(e): + for name in filenames: + f = join(root, name) + add(f, f) + else: + add(e, e) + + if args.arc == 'zip': + path = args.base + '.zip' + with zipfile.ZipFile(path, 'w') as zf: + createArchive(zf.write) + else: + path = args.base + '.tar' + mode = 'w' + if args.arc != 'tar': + sfx = args.arc[1:] + mode = mode + ':' + sfx + path = path + '.' + sfx + with tarfile.open(path, mode) as tar: + createArchive(tar.add) + log('created ' + path) + + def digest(enabled, path, factory, suffix): + if enabled: + d = factory() + with open(path, 'rb') as f: + while True: + buf = f.read(4096) + if not buf: + break + d.update(buf) + with open(path + '.' + suffix, 'w') as fp: + print >> fp, d.hexdigest() + log('created ' + path + '.' + suffix) + + digest(args.sha1, path, hashlib.sha1, 'sha1') + digest(args.md5, path, hashlib.md5, 'md5') + def javap(args): """disassemble classes matching given pattern with javap""" @@ -4148,11 +4477,13 @@ 'clean': [clean, ''], 'eclipseinit': [eclipseinit, ''], 'eclipseformat': [eclipseformat, ''], + 'exportlibs': [exportlibs, ''], 'findclass': [findclass, ''], 'fsckprojects': [fsckprojects, ''], 'help': [help_, '[command]'], 'ideclean': [ideclean, ''], 'ideinit': [ideinit, ''], + 'intellijinit': [intellijinit, ''], 'archive': [archive, '[options]'], 'projectgraph': [projectgraph, ''], 'pylint': [pylint, ''], diff -r 518a7f487c4f -r 9363fffa8b07 src/cpu/sparc/vm/compiledIC_sparc.cpp --- a/src/cpu/sparc/vm/compiledIC_sparc.cpp Wed Apr 23 15:22:20 2014 +0200 +++ b/src/cpu/sparc/vm/compiledIC_sparc.cpp Wed Apr 23 15:48:38 2014 +0200 @@ -81,25 +81,26 @@ // ---------------------------------------------------------------------------- #define __ _masm. -void CompiledStaticCall::emit_to_interp_stub(CodeBuffer &cbuf) { -#ifdef COMPILER2 +void CompiledStaticCall::emit_to_interp_stub(CodeBuffer &cbuf, address mark) { // Stub is fixed up when the corresponding call is converted from calling // compiled code to calling interpreted code. // set (empty), G5 // jmp -1 - address mark = cbuf.insts_mark(); // Get mark within main instrs section. + if (mark == NULL) { + mark = cbuf.insts_mark(); // Get mark within main instrs section. + } MacroAssembler _masm(&cbuf); address base = - __ start_a_stub(to_interp_stub_size()*2); - if (base == NULL) return; // CodeBuffer::expand failed. + __ start_a_stub(to_interp_stub_size()); + guarantee(base != NULL, "out of space"); // Static stub relocation stores the instruction address of the call. __ relocate(static_stub_Relocation::spec(mark)); - __ set_metadata(NULL, as_Register(Matcher::inline_cache_reg_encode())); + __ set_metadata(NULL, G5); __ set_inst_mark(); AddressLiteral addrlit(-1); @@ -107,11 +108,10 @@ __ delayed()->nop(); + assert(__ pc() - base <= to_interp_stub_size(), "wrong stub size"); + // Update current stubs pointer and restore code_end. __ end_a_stub(); -#else - ShouldNotReachHere(); -#endif } #undef __ diff -r 518a7f487c4f -r 9363fffa8b07 src/cpu/sparc/vm/graalCodeInstaller_sparc.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cpu/sparc/vm/graalCodeInstaller_sparc.cpp Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +#include "graal/graalCodeInstaller.hpp" +#include "graal/graalCompiler.hpp" +#include "graal/graalCompilerToVM.hpp" +#include "graal/graalJavaAccess.hpp" + +jint CodeInstaller::pd_next_offset(NativeInstruction* inst, jint pc_offset, oop method) { + if (inst->is_call() || inst->is_jump()) { + return pc_offset + NativeCall::instruction_size; + } else if (inst->is_call_reg()) { + return pc_offset + NativeCallReg::instruction_size; + } else if (inst->is_sethi()) { + return pc_offset + NativeFarCall::instruction_size; + } else { + fatal("unsupported type of instruction for call site"); + return 0; + } +} + +void CodeInstaller::pd_patch_OopData(int pc_offset, oop data) { + address pc = _instructions->start() + pc_offset; + Handle obj = OopData::object(data); + jobject value = JNIHandles::make_local(obj()); + if (OopData::compressed(data)) { + fatal("unimplemented: narrow oop relocation"); + } else { + NativeMovConstReg* move = nativeMovConstReg_at(pc); + move->set_data((intptr_t) value); + + // We need two relocations: one on the sethi and one on the add. + int oop_index = _oop_recorder->find_index(value); + RelocationHolder rspec = oop_Relocation::spec(oop_index); + _instructions->relocate(pc + NativeMovConstReg::sethi_offset, rspec); + _instructions->relocate(pc + NativeMovConstReg::add_offset, rspec); + } +} + +void CodeInstaller::pd_patch_DataSectionReference(int pc_offset, oop data) { + address pc = _instructions->start() + pc_offset; + jint offset = DataSectionReference::offset(data); + + NativeMovRegMem* load = nativeMovRegMem_at(pc); + int disp = _constants_size + pc_offset - offset - BytesPerInstWord; + load->set_offset(-disp); +} + +void CodeInstaller::pd_relocate_CodeBlob(CodeBlob* cb, NativeInstruction* inst) { + fatal("CodeInstaller::pd_relocate_CodeBlob - sparc unimp"); +} + +void CodeInstaller::pd_relocate_ForeignCall(NativeInstruction* inst, jlong foreign_call_destination) { + address pc = (address) inst; + if (inst->is_call()) { + NativeCall* call = nativeCall_at(pc); + call->set_destination((address) foreign_call_destination); + _instructions->relocate(call->instruction_address(), runtime_call_Relocation::spec()); + } else if (inst->is_sethi()) { + NativeJump* jump = nativeJump_at(pc); + jump->set_jump_destination((address) foreign_call_destination); + _instructions->relocate(jump->instruction_address(), runtime_call_Relocation::spec()); + } else { + fatal(err_msg("unknown call or jump instruction at %p", pc)); + } + TRACE_graal_3("relocating (foreign call) at %p", inst); +} + +void CodeInstaller::pd_relocate_JavaMethod(oop hotspot_method, jint pc_offset) { +#ifdef ASSERT + Method* method = NULL; + // we need to check, this might also be an unresolved method + if (hotspot_method->is_a(HotSpotResolvedJavaMethod::klass())) { + method = getMethodFromHotSpotMethod(hotspot_method); + } +#endif + switch (_next_call_type) { + case INLINE_INVOKE: + break; + case INVOKEVIRTUAL: + case INVOKEINTERFACE: { + assert(method == NULL || !method->is_static(), "cannot call static method with invokeinterface"); + NativeCall* call = nativeCall_at(_instructions->start() + pc_offset); + call->set_destination(SharedRuntime::get_resolve_virtual_call_stub()); + _instructions->relocate(call->instruction_address(), virtual_call_Relocation::spec(_invoke_mark_pc)); + break; + } + case INVOKESTATIC: { + assert(method == NULL || method->is_static(), "cannot call non-static method with invokestatic"); + NativeCall* call = nativeCall_at(_instructions->start() + pc_offset); + call->set_destination(SharedRuntime::get_resolve_static_call_stub()); + _instructions->relocate(call->instruction_address(), relocInfo::static_call_type); + break; + } + case INVOKESPECIAL: { + assert(method == NULL || !method->is_static(), "cannot call static method with invokespecial"); + NativeCall* call = nativeCall_at(_instructions->start() + pc_offset); + call->set_destination(SharedRuntime::get_resolve_opt_virtual_call_stub()); + _instructions->relocate(call->instruction_address(), relocInfo::opt_virtual_call_type); + break; + } + default: + fatal("invalid _next_call_type value"); + break; + } +} + +void CodeInstaller::pd_relocate_poll(address pc, jint mark) { + switch (mark) { + case POLL_NEAR: + fatal("unimplemented"); + break; + case POLL_FAR: + _instructions->relocate(pc, relocInfo::poll_type); + break; + case POLL_RETURN_NEAR: + fatal("unimplemented"); + break; + case POLL_RETURN_FAR: + _instructions->relocate(pc, relocInfo::poll_return_type); + break; + default: + fatal("invalid mark value"); + break; + } +} diff -r 518a7f487c4f -r 9363fffa8b07 src/cpu/sparc/vm/graalCodeInstaller_sparc.hpp --- a/src/cpu/sparc/vm/graalCodeInstaller_sparc.hpp Wed Apr 23 15:22:20 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,151 +0,0 @@ -/* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -#ifndef CPU_SPARC_VM_CODEINSTALLER_SPARC_HPP -#define CPU_SPARC_VM_CODEINSTALLER_SPARC_HPP - -#include "graal/graalCompiler.hpp" -#include "graal/graalCompilerToVM.hpp" -#include "graal/graalJavaAccess.hpp" - -inline jint CodeInstaller::pd_next_offset(NativeInstruction* inst, jint pc_offset, oop method) { - if (inst->is_call() || inst->is_jump()) { - return pc_offset + NativeCall::instruction_size; - } else if (inst->is_call_reg()) { - return pc_offset + NativeCallReg::instruction_size; - } else if (inst->is_sethi()) { - return pc_offset + NativeFarCall::instruction_size; - } else { - fatal("unsupported type of instruction for call site"); - return 0; - } -} - -inline void CodeInstaller::pd_patch_OopData(int pc_offset, oop data) { - if (OopData::compressed(obj)) { - fatal("unimplemented: narrow oop relocation"); - } else { - address pc = _instructions->start() + pc_offset; - Handle obj = OopData::object(data); - jobject value = JNIHandles::make_local(obj()); - - NativeMovConstReg* move = nativeMovConstReg_at(pc); - move->set_data((intptr_t) value); - - // We need two relocations: one on the sethi and one on the add. - int oop_index = _oop_recorder->find_index(value); - RelocationHolder rspec = oop_Relocation::spec(oop_index); - _instructions->relocate(pc + NativeMovConstReg::sethi_offset, rspec); - _instructions->relocate(pc + NativeMovConstReg::add_offset, rspec); - } -} - -inline void CodeInstaller::pd_patch_DataSectionReference(int pc_offset, oop data) { - address pc = _instructions->start() + pc_offset; - jint offset = DataSectionReference::offset(data); - - NativeMovRegMem* load = nativeMovRegMem_at(pc); - int disp = _constants_size + pc_offset - offset - BytesPerInstWord; - load->set_offset(-disp); -} - -inline void CodeInstaller::pd_relocate_CodeBlob(CodeBlob* cb, NativeInstruction* inst) { - fatal("CodeInstaller::pd_relocate_CodeBlob - sparc unimp"); -} - -inline void CodeInstaller::pd_relocate_ForeignCall(NativeInstruction* inst, jlong foreign_call_destination) { - address pc = (address) inst; - if (inst->is_call()) { - NativeCall* call = nativeCall_at(pc); - call->set_destination((address) foreign_call_destination); - _instructions->relocate(call->instruction_address(), runtime_call_Relocation::spec()); - } else if (inst->is_sethi()) { - NativeJump* jump = nativeJump_at(pc); - jump->set_jump_destination((address) foreign_call_destination); - _instructions->relocate(jump->instruction_address(), runtime_call_Relocation::spec()); - } else { - fatal(err_msg("unknown call or jump instruction at %p", pc)); - } - TRACE_graal_3("relocating (foreign call) at %p", inst); -} - -inline void CodeInstaller::pd_relocate_JavaMethod(oop hotspot_method, jint pc_offset) { -#ifdef ASSERT - Method* method = NULL; - // we need to check, this might also be an unresolved method - if (hotspot_method->is_a(HotSpotResolvedJavaMethod::klass())) { - method = getMethodFromHotSpotMethod(hotspot_method); - } -#endif - switch (_next_call_type) { - case INLINE_INVOKE: - break; - case INVOKEVIRTUAL: - case INVOKEINTERFACE: { - assert(method == NULL || !method->is_static(), "cannot call static method with invokeinterface"); - NativeCall* call = nativeCall_at(_instructions->start() + pc_offset); - call->set_destination(SharedRuntime::get_resolve_virtual_call_stub()); - _instructions->relocate(call->instruction_address(), virtual_call_Relocation::spec(_invoke_mark_pc)); - break; - } - case INVOKESTATIC: { - assert(method == NULL || method->is_static(), "cannot call non-static method with invokestatic"); - NativeCall* call = nativeCall_at(_instructions->start() + pc_offset); - call->set_destination(SharedRuntime::get_resolve_static_call_stub()); - _instructions->relocate(call->instruction_address(), relocInfo::static_call_type); - break; - } - case INVOKESPECIAL: { - assert(method == NULL || !method->is_static(), "cannot call static method with invokespecial"); - NativeCall* call = nativeCall_at(_instructions->start() + pc_offset); - call->set_destination(SharedRuntime::get_resolve_opt_virtual_call_stub()); - _instructions->relocate(call->instruction_address(), relocInfo::opt_virtual_call_type); - break; - } - default: - fatal("invalid _next_call_type value"); - break; - } -} - -inline void CodeInstaller::pd_relocate_poll(address pc, jint mark) { - switch (mark) { - case POLL_NEAR: { - fatal("unimplemented"); - } - case POLL_FAR: - _instructions->relocate(pc, relocInfo::poll_type); - break; - case POLL_RETURN_NEAR: { - fatal("unimplemented"); - } - case POLL_RETURN_FAR: - _instructions->relocate(pc, relocInfo::poll_return_type); - break; - default: - fatal("invalid mark value"); - break; - } -} - -#endif // CPU_SPARC_VM_CODEINSTALLER_SPARC_HPP diff -r 518a7f487c4f -r 9363fffa8b07 src/cpu/x86/vm/compiledIC_x86.cpp --- a/src/cpu/x86/vm/compiledIC_x86.cpp Wed Apr 23 15:22:20 2014 +0200 +++ b/src/cpu/x86/vm/compiledIC_x86.cpp Wed Apr 23 15:48:38 2014 +0200 @@ -78,21 +78,24 @@ // ---------------------------------------------------------------------------- #define __ _masm. -void CompiledStaticCall::emit_to_interp_stub(CodeBuffer &cbuf) { +void CompiledStaticCall::emit_to_interp_stub(CodeBuffer &cbuf, address mark) { // Stub is fixed up when the corresponding call is converted from // calling compiled code to calling interpreted code. // movq rbx, 0 // jmp -5 # to self - address mark = cbuf.insts_mark(); // Get mark within main instrs section. + if (mark == NULL) { + mark = cbuf.insts_mark(); // Get mark within main instrs section. + } // Note that the code buffer's insts_mark is always relative to insts. // That's why we must use the macroassembler to generate a stub. MacroAssembler _masm(&cbuf); address base = - __ start_a_stub(to_interp_stub_size()*2); - if (base == NULL) return; // CodeBuffer::expand failed. + __ start_a_stub(to_interp_stub_size()); + guarantee(base != NULL, "out of space"); + // Static stub relocation stores the instruction address of the call. __ relocate(static_stub_Relocation::spec(mark), Assembler::imm_operand); // Static stub relocation also tags the Method* in the code-stream. @@ -100,6 +103,8 @@ // This is recognized as unresolved by relocs/nativeinst/ic code. __ jump(RuntimeAddress(__ pc())); + assert(__ pc() - base <= to_interp_stub_size(), "wrong stub size"); + // Update current stubs pointer and restore insts_end. __ end_a_stub(); } @@ -117,12 +122,6 @@ void CompiledStaticCall::set_to_interpreted(methodHandle callee, address entry) { address stub = find_stub(); -#ifdef GRAAL - if (stub == NULL) { - set_destination_mt_safe(entry); - return; - } -#endif guarantee(stub != NULL, "stub not found"); if (TraceICs) { @@ -172,14 +171,12 @@ verify_alignment(); } -#ifndef GRAAL // Verify stub. address stub = find_stub(); assert(stub != NULL, "no stub found for static call"); // Creation also verifies the object. NativeMovConstReg* method_holder = nativeMovConstReg_at(stub); NativeJump* jump = nativeJump_at(method_holder->next_instruction_address()); -#endif // Verify state. assert(is_clean() || is_call_to_compiled() || is_call_to_interpreted(), "sanity check"); diff -r 518a7f487c4f -r 9363fffa8b07 src/cpu/x86/vm/graalCodeInstaller_x86.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cpu/x86/vm/graalCodeInstaller_x86.cpp Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,212 @@ +/* + * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +#include "precompiled.hpp" +#include "compiler/disassembler.hpp" +#include "runtime/javaCalls.hpp" +#include "graal/graalEnv.hpp" +#include "graal/graalCompiler.hpp" +#include "graal/graalCodeInstaller.hpp" +#include "graal/graalJavaAccess.hpp" +#include "graal/graalCompilerToVM.hpp" +#include "graal/graalRuntime.hpp" +#include "asm/register.hpp" +#include "classfile/vmSymbols.hpp" +#include "code/vmreg.hpp" + +jint CodeInstaller::pd_next_offset(NativeInstruction* inst, jint pc_offset, oop method) { + if (inst->is_call() || inst->is_jump()) { + assert(NativeCall::instruction_size == (int)NativeJump::instruction_size, "unexpected size"); + return (pc_offset + NativeCall::instruction_size); + } else if (inst->is_mov_literal64()) { + // mov+call instruction pair + jint offset = pc_offset + NativeMovConstReg::instruction_size; + u_char* call = (u_char*) (_instructions->start() + offset); + assert((call[0] == 0x40 || call[0] == 0x41) && call[1] == 0xFF, "expected call with rex/rexb prefix byte"); + offset += 3; /* prefix byte + opcode byte + modrm byte */ + return (offset); + } else if (inst->is_call_reg()) { + // the inlined vtable stub contains a "call register" instruction + assert(method != NULL, "only valid for virtual calls"); + return (pc_offset + ((NativeCallReg *) inst)->next_instruction_offset()); + } else if (inst->is_cond_jump()) { + address pc = (address) (inst); + return pc_offset + (jint) (Assembler::locate_next_instruction(pc) - pc); + } else { + fatal("unsupported type of instruction for call site"); + return 0; + } +} + +void CodeInstaller::pd_patch_OopData(int pc_offset, oop data) { + address pc = _instructions->start() + pc_offset; + Handle obj = OopData::object(data); + jobject value = JNIHandles::make_local(obj()); + if (OopData::compressed(data)) { + address operand = Assembler::locate_operand(pc, Assembler::narrow_oop_operand); + int oop_index = _oop_recorder->find_index(value); + _instructions->relocate(pc, oop_Relocation::spec(oop_index), Assembler::narrow_oop_operand); + TRACE_graal_3("relocating (narrow oop constant) at %p/%p", pc, operand); + } else { + address operand = Assembler::locate_operand(pc, Assembler::imm_operand); + *((jobject*) operand) = value; + _instructions->relocate(pc, oop_Relocation::spec_for_immediate(), Assembler::imm_operand); + TRACE_graal_3("relocating (oop constant) at %p/%p", pc, operand); + } +} + +void CodeInstaller::pd_patch_DataSectionReference(int pc_offset, oop data) { + address pc = _instructions->start() + pc_offset; + jint offset = DataSectionReference::offset(data); + + address operand = Assembler::locate_operand(pc, Assembler::disp32_operand); + address next_instruction = Assembler::locate_next_instruction(pc); + address dest = _constants->start() + offset; + + long disp = dest - next_instruction; + assert(disp == (jint) disp, "disp doesn't fit in 32 bits"); + *((jint*) operand) = (jint) disp; + + _instructions->relocate(pc, section_word_Relocation::spec((address) dest, CodeBuffer::SECT_CONSTS), Assembler::disp32_operand); + TRACE_graal_3("relocating at %p/%p with destination at %p (%d)", pc, operand, dest, offset); +} + +void CodeInstaller::pd_relocate_CodeBlob(CodeBlob* cb, NativeInstruction* inst) { + if (cb->is_nmethod()) { + nmethod* nm = (nmethod*) cb; + nativeJump_at((address)inst)->set_jump_destination(nm->verified_entry_point()); + } else { + nativeJump_at((address)inst)->set_jump_destination(cb->code_begin()); + } + _instructions->relocate((address)inst, runtime_call_Relocation::spec(), Assembler::call32_operand); +} + +void CodeInstaller::pd_relocate_ForeignCall(NativeInstruction* inst, jlong foreign_call_destination) { + address pc = (address) inst; + if (inst->is_call()) { + // NOTE: for call without a mov, the offset must fit a 32-bit immediate + // see also CompilerToVM.getMaxCallTargetOffset() + NativeCall* call = nativeCall_at(pc); + call->set_destination((address) foreign_call_destination); + _instructions->relocate(call->instruction_address(), runtime_call_Relocation::spec(), Assembler::call32_operand); + } else if (inst->is_mov_literal64()) { + NativeMovConstReg* mov = nativeMovConstReg_at(pc); + mov->set_data((intptr_t) foreign_call_destination); + _instructions->relocate(mov->instruction_address(), runtime_call_Relocation::spec(), Assembler::imm_operand); + } else if (inst->is_jump()) { + NativeJump* jump = nativeJump_at(pc); + jump->set_jump_destination((address) foreign_call_destination); + _instructions->relocate(jump->instruction_address(), runtime_call_Relocation::spec(), Assembler::call32_operand); + } else if (inst->is_cond_jump()) { + address old_dest = nativeGeneralJump_at(pc)->jump_destination(); + address disp = Assembler::locate_operand(pc, Assembler::call32_operand); + *(jint*) disp += ((address) foreign_call_destination) - old_dest; + _instructions->relocate(pc, runtime_call_Relocation::spec(), Assembler::call32_operand); + } else { + fatal("unsupported relocation for foreign call"); + } + + TRACE_graal_3("relocating (foreign call) at %p", inst); +} + +void CodeInstaller::pd_relocate_JavaMethod(oop hotspot_method, jint pc_offset) { +#ifdef ASSERT + Method* method = NULL; + // we need to check, this might also be an unresolved method + if (hotspot_method->is_a(HotSpotResolvedJavaMethod::klass())) { + method = getMethodFromHotSpotMethod(hotspot_method); + } +#endif + switch (_next_call_type) { + case INLINE_INVOKE: + break; + case INVOKEVIRTUAL: + case INVOKEINTERFACE: { + assert(method == NULL || !method->is_static(), "cannot call static method with invokeinterface"); + + NativeCall* call = nativeCall_at(_instructions->start() + pc_offset); + call->set_destination(SharedRuntime::get_resolve_virtual_call_stub()); + _instructions->relocate(call->instruction_address(), + virtual_call_Relocation::spec(_invoke_mark_pc), + Assembler::call32_operand); + break; + } + case INVOKESTATIC: { + assert(method == NULL || method->is_static(), "cannot call non-static method with invokestatic"); + + NativeCall* call = nativeCall_at(_instructions->start() + pc_offset); + call->set_destination(SharedRuntime::get_resolve_static_call_stub()); + _instructions->relocate(call->instruction_address(), + relocInfo::static_call_type, Assembler::call32_operand); + break; + } + case INVOKESPECIAL: { + assert(method == NULL || !method->is_static(), "cannot call static method with invokespecial"); + NativeCall* call = nativeCall_at(_instructions->start() + pc_offset); + call->set_destination(SharedRuntime::get_resolve_opt_virtual_call_stub()); + _instructions->relocate(call->instruction_address(), + relocInfo::opt_virtual_call_type, Assembler::call32_operand); + break; + } + default: + break; + } +} + +static void relocate_poll_near(address pc) { + NativeInstruction* ni = nativeInstruction_at(pc); + int32_t* disp = (int32_t*) Assembler::locate_operand(pc, Assembler::disp32_operand); + int32_t offset = *disp; // The Java code installed the polling page offset into the disp32 operand + intptr_t new_disp = (intptr_t) (os::get_polling_page() + offset) - (intptr_t) ni; + *disp = (int32_t)new_disp; +} + + +void CodeInstaller::pd_relocate_poll(address pc, jint mark) { + switch (mark) { + case POLL_NEAR: { + relocate_poll_near(pc); + _instructions->relocate(pc, relocInfo::poll_type, Assembler::disp32_operand); + break; + } + case POLL_FAR: + // This is a load from a register so there is no relocatable operand. + // We just have to ensure that the format is not disp32_operand + // so that poll_Relocation::fix_relocation_after_move does the right + // thing (i.e. ignores this relocation record) + _instructions->relocate(pc, relocInfo::poll_type, Assembler::imm_operand); + break; + case POLL_RETURN_NEAR: { + relocate_poll_near(pc); + _instructions->relocate(pc, relocInfo::poll_return_type, Assembler::disp32_operand); + break; + } + case POLL_RETURN_FAR: + // see comment above for POLL_FAR + _instructions->relocate(pc, relocInfo::poll_return_type, Assembler::imm_operand); + break; + default: + fatal("invalid mark value"); + break; + } +} diff -r 518a7f487c4f -r 9363fffa8b07 src/cpu/x86/vm/graalCodeInstaller_x86.hpp --- a/src/cpu/x86/vm/graalCodeInstaller_x86.hpp Wed Apr 23 15:22:20 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,228 +0,0 @@ -/* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -#ifndef CPU_X86_VM_CODEINSTALLER_X86_HPP -#define CPU_X86_VM_CODEINSTALLER_X86_HPP - -#include "compiler/disassembler.hpp" -#include "runtime/javaCalls.hpp" -#include "graal/graalEnv.hpp" -#include "graal/graalCompiler.hpp" -#include "graal/graalCodeInstaller.hpp" -#include "graal/graalJavaAccess.hpp" -#include "graal/graalCompilerToVM.hpp" -#include "graal/graalRuntime.hpp" -#include "asm/register.hpp" -#include "classfile/vmSymbols.hpp" -#include "code/vmreg.hpp" - -inline jint CodeInstaller::pd_next_offset(NativeInstruction* inst, jint pc_offset, oop method) { - if (inst->is_call() || inst->is_jump()) { - assert(NativeCall::instruction_size == (int)NativeJump::instruction_size, "unexpected size"); - return (pc_offset + NativeCall::instruction_size); - } else if (inst->is_mov_literal64()) { - // mov+call instruction pair - jint offset = pc_offset + NativeMovConstReg::instruction_size; - u_char* call = (u_char*) (_instructions->start() + offset); - assert((call[0] == 0x40 || call[0] == 0x41) && call[1] == 0xFF, "expected call with rex/rexb prefix byte"); - offset += 3; /* prefix byte + opcode byte + modrm byte */ - return (offset); - } else if (inst->is_call_reg()) { - // the inlined vtable stub contains a "call register" instruction - assert(method != NULL, "only valid for virtual calls"); - return (pc_offset + ((NativeCallReg *) inst)->next_instruction_offset()); - } else if (inst->is_cond_jump()) { - address pc = (address) (inst); - return pc_offset + (jint) (Assembler::locate_next_instruction(pc) - pc); - } else { - fatal("unsupported type of instruction for call site"); - return 0; - } -} - -inline bool check_metaspace_data(address pc, oop data) { - jlong value = MetaspaceData::value(data); - address operand = Assembler::locate_operand(pc, Assembler::imm_operand); - if (MetaspaceData::compressed(data)) { - assert(*((jint*) operand) == value, err_msg("wrong compressed metaspace pointer: %p != %p", *((jint*) operand), value)); - } else { - assert(*((jlong*) operand) == value, err_msg("wrong metaspace pointer: %p != %p", *((jlong*) operand), value)); - } - return true; -} - -inline void CodeInstaller::pd_patch_OopData(int pc_offset, oop data) { - address pc = _instructions->start() + pc_offset; - - Handle obj = OopData::object(data); - jobject value = JNIHandles::make_local(obj()); - if (OopData::compressed(data)) { - address operand = Assembler::locate_operand(pc, Assembler::narrow_oop_operand); - int oop_index = _oop_recorder->find_index(value); - _instructions->relocate(pc, oop_Relocation::spec(oop_index), Assembler::narrow_oop_operand); - TRACE_graal_3("relocating (narrow oop constant) at %p/%p", pc, operand); - } else { - address operand = Assembler::locate_operand(pc, Assembler::imm_operand); - *((jobject*) operand) = value; - _instructions->relocate(pc, oop_Relocation::spec_for_immediate(), Assembler::imm_operand); - TRACE_graal_3("relocating (oop constant) at %p/%p", pc, operand); - } -} - -inline void CodeInstaller::pd_patch_DataSectionReference(int pc_offset, oop data) { - address pc = _instructions->start() + pc_offset; - jint offset = DataSectionReference::offset(data); - - address operand = Assembler::locate_operand(pc, Assembler::disp32_operand); - address next_instruction = Assembler::locate_next_instruction(pc); - address dest = _constants->start() + offset; - - long disp = dest - next_instruction; - assert(disp == (jint) disp, "disp doesn't fit in 32 bits"); - *((jint*) operand) = (jint) disp; - - _instructions->relocate(pc, section_word_Relocation::spec((address) dest, CodeBuffer::SECT_CONSTS), Assembler::disp32_operand); - TRACE_graal_3("relocating at %p/%p with destination at %p (%d)", pc, operand, dest, offset); -} - -inline void CodeInstaller::pd_relocate_CodeBlob(CodeBlob* cb, NativeInstruction* inst) { - if (cb->is_nmethod()) { - nmethod* nm = (nmethod*) cb; - nativeJump_at((address)inst)->set_jump_destination(nm->verified_entry_point()); - } else { - nativeJump_at((address)inst)->set_jump_destination(cb->code_begin()); - } - _instructions->relocate((address)inst, runtime_call_Relocation::spec(), Assembler::call32_operand); -} - -inline void CodeInstaller::pd_relocate_ForeignCall(NativeInstruction* inst, jlong foreign_call_destination) { - address pc = (address) inst; - if (inst->is_call()) { - // NOTE: for call without a mov, the offset must fit a 32-bit immediate - // see also CompilerToVM.getMaxCallTargetOffset() - NativeCall* call = nativeCall_at(pc); - call->set_destination((address) foreign_call_destination); - _instructions->relocate(call->instruction_address(), runtime_call_Relocation::spec(), Assembler::call32_operand); - } else if (inst->is_mov_literal64()) { - NativeMovConstReg* mov = nativeMovConstReg_at(pc); - mov->set_data((intptr_t) foreign_call_destination); - _instructions->relocate(mov->instruction_address(), runtime_call_Relocation::spec(), Assembler::imm_operand); - } else if (inst->is_jump()) { - NativeJump* jump = nativeJump_at(pc); - jump->set_jump_destination((address) foreign_call_destination); - _instructions->relocate(jump->instruction_address(), runtime_call_Relocation::spec(), Assembler::call32_operand); - } else if (inst->is_cond_jump()) { - address old_dest = nativeGeneralJump_at(pc)->jump_destination(); - address disp = Assembler::locate_operand(pc, Assembler::call32_operand); - *(jint*) disp += ((address) foreign_call_destination) - old_dest; - _instructions->relocate(pc, runtime_call_Relocation::spec(), Assembler::call32_operand); - } else { - fatal("unsupported relocation for foreign call"); - } - - TRACE_graal_3("relocating (foreign call) at %p", inst); -} - -inline void CodeInstaller::pd_relocate_JavaMethod(oop hotspot_method, jint pc_offset) { -#ifdef ASSERT - Method* method = NULL; - // we need to check, this might also be an unresolved method - if (hotspot_method->is_a(HotSpotResolvedJavaMethod::klass())) { - method = getMethodFromHotSpotMethod(hotspot_method); - } -#endif - switch (_next_call_type) { - case INLINE_INVOKE: - break; - case INVOKEVIRTUAL: - case INVOKEINTERFACE: { - assert(method == NULL || !method->is_static(), "cannot call static method with invokeinterface"); - - NativeCall* call = nativeCall_at(_instructions->start() + pc_offset); - call->set_destination(SharedRuntime::get_resolve_virtual_call_stub()); - _instructions->relocate(call->instruction_address(), - virtual_call_Relocation::spec(_invoke_mark_pc), - Assembler::call32_operand); - break; - } - case INVOKESTATIC: { - assert(method == NULL || method->is_static(), "cannot call non-static method with invokestatic"); - - NativeCall* call = nativeCall_at(_instructions->start() + pc_offset); - call->set_destination(SharedRuntime::get_resolve_static_call_stub()); - _instructions->relocate(call->instruction_address(), - relocInfo::static_call_type, Assembler::call32_operand); - break; - } - case INVOKESPECIAL: { - assert(method == NULL || !method->is_static(), "cannot call static method with invokespecial"); - NativeCall* call = nativeCall_at(_instructions->start() + pc_offset); - call->set_destination(SharedRuntime::get_resolve_opt_virtual_call_stub()); - _instructions->relocate(call->instruction_address(), - relocInfo::opt_virtual_call_type, Assembler::call32_operand); - break; - } - default: - break; - } -} - -static void relocate_poll_near(address pc) { - NativeInstruction* ni = nativeInstruction_at(pc); - int32_t* disp = (int32_t*) Assembler::locate_operand(pc, Assembler::disp32_operand); - int32_t offset = *disp; // The Java code installed the polling page offset into the disp32 operand - intptr_t new_disp = (intptr_t) (os::get_polling_page() + offset) - (intptr_t) ni; - *disp = (int32_t)new_disp; -} - - -inline void CodeInstaller::pd_relocate_poll(address pc, jint mark) { - switch (mark) { - case POLL_NEAR: { - relocate_poll_near(pc); - _instructions->relocate(pc, relocInfo::poll_type, Assembler::disp32_operand); - break; - } - case POLL_FAR: - // This is a load from a register so there is no relocatable operand. - // We just have to ensure that the format is not disp32_operand - // so that poll_Relocation::fix_relocation_after_move does the right - // thing (i.e. ignores this relocation record) - _instructions->relocate(pc, relocInfo::poll_type, Assembler::imm_operand); - break; - case POLL_RETURN_NEAR: { - relocate_poll_near(pc); - _instructions->relocate(pc, relocInfo::poll_return_type, Assembler::disp32_operand); - break; - } - case POLL_RETURN_FAR: - // see comment above for MARK_POLL_FAR - _instructions->relocate(pc, relocInfo::poll_return_type, Assembler::imm_operand); - break; - default: - fatal("invalid mark value"); - break; - } -} - -#endif // CPU_X86_VM_CODEINSTALLER_X86_HPP - diff -r 518a7f487c4f -r 9363fffa8b07 src/cpu/x86/vm/sharedRuntime_x86_64.cpp --- a/src/cpu/x86/vm/sharedRuntime_x86_64.cpp Wed Apr 23 15:22:20 2014 +0200 +++ b/src/cpu/x86/vm/sharedRuntime_x86_64.cpp Wed Apr 23 15:48:38 2014 +0200 @@ -3360,10 +3360,9 @@ #ifdef GRAAL int implicit_exception_uncommon_trap_offset = __ pc() - start; + __ pushptr(Address(r15_thread, in_bytes(JavaThread::graal_implicit_exception_pc_offset()))); - int uncommon_trap_offset = __ pc() - start; - // Save everything in sight. RegisterSaver::save_live_registers(masm, 0, &frame_size_in_words); // fetch_unroll_info needs to call last_java_frame() @@ -3643,7 +3642,6 @@ _deopt_blob = DeoptimizationBlob::create(&buffer, oop_maps, 0, exception_offset, reexecute_offset, frame_size_in_words); _deopt_blob->set_unpack_with_exception_in_tls_offset(exception_in_tls_offset); #ifdef GRAAL - _deopt_blob->set_uncommon_trap_offset(uncommon_trap_offset); _deopt_blob->set_implicit_exception_uncommon_trap_offset(implicit_exception_uncommon_trap_offset); #endif } diff -r 518a7f487c4f -r 9363fffa8b07 src/cpu/x86/vm/vmStructs_x86.hpp --- a/src/cpu/x86/vm/vmStructs_x86.hpp Wed Apr 23 15:22:20 2014 +0200 +++ b/src/cpu/x86/vm/vmStructs_x86.hpp Wed Apr 23 15:48:38 2014 +0200 @@ -47,6 +47,8 @@ #define VM_INT_CONSTANTS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant) \ declare_constant(frame::arg_reg_save_area_bytes) \ + declare_constant(frame::interpreter_frame_sender_sp_offset) \ + declare_constant(frame::interpreter_frame_last_sp_offset) \ declare_constant(VM_Version::CPU_CX8) \ declare_constant(VM_Version::CPU_CMOV) \ declare_constant(VM_Version::CPU_FXSR) \ diff -r 518a7f487c4f -r 9363fffa8b07 src/gpu/hsail/vm/gpu_hsail.cpp --- a/src/gpu/hsail/vm/gpu_hsail.cpp Wed Apr 23 15:22:20 2014 +0200 +++ b/src/gpu/hsail/vm/gpu_hsail.cpp Wed Apr 23 15:48:38 2014 +0200 @@ -59,19 +59,19 @@ #define OBJECT "Ljava/lang/Object;" #define STRING "Ljava/lang/String;" +#define JLTHREAD "Ljava/lang/Thread;" #define HS_INSTALLED_CODE "Lcom/oracle/graal/hotspot/meta/HotSpotInstalledCode;" #define HS_COMPILED_NMETHOD "Lcom/oracle/graal/hotspot/HotSpotCompiledNmethod;" #define HS_NMETHOD "Lcom/oracle/graal/hotspot/meta/HotSpotNmethod;" -// public native void executeKernel(HotSpotNmethod kernel, int jobSize, int i, int j, Object[] args) throws InvalidInstalledCodeException; - JNINativeMethod Hsail::HSAIL_methods[] = { {CC"initialize", CC"()Z", FN_PTR(Hsail::initialize)}, {CC"generateKernel", CC"([B" STRING ")J", FN_PTR(Hsail::generate_kernel)}, - {CC"executeKernel0", CC"("HS_INSTALLED_CODE"I["OBJECT"["OBJECT")Z", FN_PTR(Hsail::execute_kernel_void_1d)}, + {CC"executeKernel0", CC"("HS_INSTALLED_CODE"I["OBJECT"["OBJECT"["JLTHREAD"I)Z", FN_PTR(Hsail::execute_kernel_void_1d)}, }; void * Hsail::_device_context = NULL; +jint Hsail::_notice_safepoints = false; Hsail::okra_create_context_func_t Hsail::_okra_create_context; Hsail::okra_create_kernel_func_t Hsail::_okra_create_kernel; @@ -86,6 +86,55 @@ Hsail::okra_clearargs_func_t Hsail::_okra_clearargs; Hsail::okra_register_heap_func_t Hsail::_okra_register_heap; +struct Stats { + int _dispatches; + int _deopts; + int _overflows; + bool _changeSeen; + +public: + Stats() { + _dispatches = _deopts = _overflows = 0; + _changeSeen = false; + } + + void incDeopts() { + _deopts++; + _changeSeen = true; + } + void incOverflows() { + _overflows++; + _changeSeen = true; + } + + void finishDispatch() { + _dispatches++; + if (_changeSeen) { + // print(); + _changeSeen = false; + } + } + + void print() { + tty->print_cr("Disp=%d, Deopts=%d, Ovflows=%d", _dispatches, _deopts, _overflows); + } + +}; + +static Stats kernelStats; + +//static jint in_kernel = 0; + +void Hsail::notice_safepoints() { + _notice_safepoints = true; +// if (TraceGPUInteraction) { +// tty->print_cr("[HSAIL] Notice safepoint in_kernel=%d", in_kernel); +// } +} + +void Hsail::ignore_safepoints() { + _notice_safepoints = false; +} void Hsail::register_heap() { // After the okra functions are set up and the heap is initialized, register the java heap with HSA @@ -97,10 +146,11 @@ _okra_register_heap(Universe::heap()->base(), Universe::heap()->capacity()); } -GPU_VMENTRY(jboolean, Hsail::execute_kernel_void_1d, (JNIEnv* env, jclass, jobject kernel_handle, jint dimX, jobject args_handle, jobject oops_save_handle)) +GPU_VMENTRY(jboolean, Hsail::execute_kernel_void_1d, (JNIEnv* env, jclass, jobject kernel_handle, jint dimX, jobject args, jobject oops_save, + jobject donor_threads, jint allocBytesPerWorkitem)) ResourceMark rm; - jlong nmethodValue = HotSpotInstalledCode::codeBlob(kernel_handle); + jlong nmethodValue = InstalledCode::address(kernel_handle); if (nmethodValue == 0) { SharedRuntime::throw_and_post_jvmti_exception(JavaThread::current(), vmSymbols::com_oracle_graal_api_code_InvalidInstalledCodeException(), NULL); } @@ -113,7 +163,7 @@ SharedRuntime::throw_and_post_jvmti_exception(JavaThread::current(), vmSymbols::com_oracle_graal_api_code_InvalidInstalledCodeException(), NULL); } - return execute_kernel_void_1d_internal((address) kernel, dimX, args_handle, mh, nm, oops_save_handle, CHECK_0); + return execute_kernel_void_1d_internal((address) kernel, dimX, args, mh, nm, oops_save, donor_threads, allocBytesPerWorkitem, CHECK_0); GPU_END static void showRanges(jboolean *a, int len) { @@ -133,10 +183,79 @@ } } -jboolean Hsail::execute_kernel_void_1d_internal(address kernel, int dimX, jobject args_handle, methodHandle& mh, nmethod *nm, jobject oops_save_handle, TRAPS) { +// fill and retire old tlab and get a new one +// if we can't get one, no problem someone will eventually do a gc +void Hsail::getNewTlabForDonorThread(ThreadLocalAllocBuffer* tlab, size_t tlabMinHsail) { + tlab->clear_before_allocation(); // fill and retire old tlab (will also check for null) + + // get a size for a new tlab that is at least tlabMinHsail. + size_t new_tlab_size = tlab->compute_size(tlabMinHsail); + if (new_tlab_size == 0) return; + + HeapWord* tlab_start = Universe::heap()->allocate_new_tlab(new_tlab_size); + if (tlab_start == NULL) return; + + // ..and clear it if required + if (ZeroTLAB) { + Copy::zero_to_words(tlab_start, new_tlab_size); + } + // and init the tlab pointers + tlab->fill(tlab_start, tlab_start, new_tlab_size); +} + +static void printTlabInfo (ThreadLocalAllocBuffer* tlab) { + HeapWord *start = tlab->start(); + HeapWord *top = tlab->top(); + HeapWord *end = tlab->end(); + // sizes are in bytes + size_t tlabFree = tlab->free() * HeapWordSize; + size_t tlabUsed = tlab->used() * HeapWordSize; + size_t tlabSize = tlabFree + tlabUsed; + double freePct = 100.0 * (double) tlabFree/(double) tlabSize; + tty->print_cr("(%p, %p, %p), siz=%ld, free=%ld (%f%%)", start, top, end, tlabSize, tlabFree, freePct); +} + +jboolean Hsail::execute_kernel_void_1d_internal(address kernel, int dimX, jobject args, methodHandle& mh, nmethod *nm, jobject oops_save, + jobject donor_threads, int allocBytesPerWorkitem, TRAPS) { ResourceMark rm(THREAD); - objArrayOop argsArray = (objArrayOop) JNIHandles::resolve(args_handle); + objArrayOop argsArray = (objArrayOop) JNIHandles::resolve(args); + + // TODO: avoid donor thread logic if kernel does not allocate + objArrayOop donorThreadObjects = (objArrayOop) JNIHandles::resolve(donor_threads); + int numDonorThreads = donorThreadObjects->length(); + guarantee(numDonorThreads > 0, "need at least one donor thread"); + JavaThread** donorThreads = NEW_RESOURCE_ARRAY(JavaThread*, numDonorThreads); + for (int i = 0; i < numDonorThreads; i++) { + donorThreads[i] = java_lang_Thread::thread(donorThreadObjects->obj_at(i)); + } + + + // compute tlabMinHsail based on number of workitems, number of donor + // threads, allocBytesPerWorkitem rounded up + size_t tlabMinHsail = (allocBytesPerWorkitem * dimX + (numDonorThreads - 1)) / numDonorThreads; + if (TraceGPUInteraction) { + tty->print_cr("computed tlabMinHsail = %d", tlabMinHsail); + } + + for (int i = 0; i < numDonorThreads; i++) { + JavaThread* donorThread = donorThreads[i]; + ThreadLocalAllocBuffer* tlab = &donorThread->tlab(); + if (TraceGPUInteraction) { + tty->print("donorThread %d, is %p, tlab at %p -> ", i, donorThread, tlab); + printTlabInfo(tlab); + } + + // note: this used vs. free limit checking should be based on some + // heuristic where we see how much this kernel tends to allocate + if ((tlab->end() == NULL) || (tlab->free() * HeapWordSize < tlabMinHsail)) { + getNewTlabForDonorThread(tlab, tlabMinHsail); + if (TraceGPUInteraction) { + tty->print("donorThread %d, refilled tlab, -> ", i); + printTlabInfo(tlab); + } + } + } // Reset the kernel arguments _okra_clearargs(kernel); @@ -146,10 +265,14 @@ e = new (ResourceObj::C_HEAP, mtInternal) HSAILDeoptimizationInfo(); e->set_never_ran_array(NEW_C_HEAP_ARRAY(jboolean, dimX, mtInternal)); memset(e->never_ran_array(), 0, dimX * sizeof(jboolean)); + e->set_donor_threads(donorThreads); } // This object sets up the kernel arguments HSAILKernelArguments hka((address) kernel, mh->signature(), argsArray, mh->is_static(), e); + if (TraceGPUInteraction) { + tty->print_cr("[HSAIL] range=%d", dimX); + } // if any object passed was null, throw an exception here // doing this means the kernel code can avoid null checks on the object parameters. @@ -165,25 +288,53 @@ // Run the kernel bool success = false; { - TraceTime t1("execute kernel", TraceGPUInteraction); + TraceTime t("execute kernel", TraceGPUInteraction); + + //in_kernel = 1; + // Run the kernel success = _okra_execute_with_range(kernel, dimX); + //in_kernel = 0; + } + + // fix up any tlab tops that overflowed + bool anyOverflows = false; + for (int i = 0; i < numDonorThreads; i++) { + JavaThread * donorThread = donorThreads[i]; + ThreadLocalAllocBuffer* tlab = &donorThread->tlab(); + if (tlab->top() > tlab->end()) { + anyOverflows = true; + long overflowAmount = (long) tlab->top() - (long) tlab->pf_top(); + // tlab->set_top is private this ugly hack gets around that + *(long *)((char *)tlab + in_bytes(tlab->top_offset())) = (long) tlab->pf_top(); + if (TraceGPUInteraction) { + tty->print_cr("donorThread %d at %p overflowed by %ld bytes, setting last good top to %p", i, donorThread, overflowAmount, tlab->top()); + } + } + } + if (anyOverflows) { + kernelStats.incOverflows(); } if (UseHSAILDeoptimization) { + kernelStats.incDeopts(); // check if any workitem requested a deopt // currently we only support at most one such workitem int deoptcode = e->deopt_occurred(); - if (deoptcode != 0) { - if (deoptcode != 1) { + if (deoptcode != 1) { + if (deoptcode == 0) { + if (TraceGPUInteraction && _notice_safepoints != 0) { + tty->print_cr("[HSAIL] observed safepoint during kernel"); + } + } else { // error condition detected in deopt code char msg[200]; sprintf(msg, "deopt error detected, slot for workitem %d was not empty", -1 * (deoptcode + 1)); guarantee(deoptcode == 1, msg); } + } else { { TraceTime t3("handle deoptimizing workitems", TraceGPUInteraction); - if (TraceGPUInteraction) { tty->print_cr("deopt happened."); HSAILKernelDeoptimization * pdeopt = &e->_deopt_save_states[0]; @@ -194,7 +345,7 @@ // the hsail frames in oops_save so they get adjusted by any // GC. Need to do this before leaving thread_in_vm mode. // resolve handle only needed once here (not exiting vm mode) - objArrayOop oopsSaveArray = (objArrayOop) JNIHandles::resolve(oops_save_handle); + objArrayOop oopsSaveArray = (objArrayOop) JNIHandles::resolve(oops_save); // since slots are allocated from the beginning, we know how far to look assert(e->num_deopts() < MAX_DEOPT_SAVE_STATES_SIZE, "deopt save state overflow"); @@ -228,7 +379,7 @@ // update the hsailFrame from the oopsSaveArray // re-resolve the handle - oopsSaveArray = (objArrayOop) JNIHandles::resolve(oops_save_handle); + oopsSaveArray = (objArrayOop) JNIHandles::resolve(oops_save); int dregOopMap = hsailFrame->dreg_oops_map(); for (int bit = 0; bit < 16; bit++) { @@ -276,51 +427,51 @@ tty->print_cr("[HSAIL] Deoptimizing to host completed for %d workitems", count_deoptimized); } } - - { - TraceTime t3("handle never-rans", TraceGPUInteraction); + } - // Handle any never_ran workitems if there were any - int count_never_ran = 0; - bool handleNeverRansHere = true; - // turn off verbose trace stuff for javacall arg setup - bool savedTraceGPUInteraction = TraceGPUInteraction; - TraceGPUInteraction = false; - jboolean *never_ran_array = e->never_ran_array(); - if (handleNeverRansHere) { - for (int k = 0; k < dimX; k++) { - if (never_ran_array[k]) { - // run it as a javaCall - KlassHandle methKlass = mh->method_holder(); - Thread* THREAD = Thread::current(); - JavaValue result(T_VOID); - JavaCallArguments javaArgs; - // re-resolve the args_handle here - objArrayOop resolvedArgsArray = (objArrayOop) JNIHandles::resolve(args_handle); - // This object sets up the javaCall arguments - // the way argsArray is set up, this should work for instance methods as well - // (the receiver will be the first oop pushed) - HSAILJavaCallArguments hjca(&javaArgs, k, mh->signature(), resolvedArgsArray, mh->is_static()); - if (mh->is_static()) { - JavaCalls::call_static(&result, methKlass, mh->name(), mh->signature(), &javaArgs, THREAD); - } else { - JavaCalls::call_virtual(&result, methKlass, mh->name(), mh->signature(), &javaArgs, THREAD); - } - count_never_ran++; + // Handle any never_ran workitems if there were any + { + TraceTime t("handle never-rans ", TraceGPUInteraction); + int count_never_ran = 0; + bool handleNeverRansHere = true; + // turn off verbose trace stuff for javacall arg setup + bool savedTraceGPUInteraction = TraceGPUInteraction; + TraceGPUInteraction = false; + jboolean *never_ran_array = e->never_ran_array(); + if (handleNeverRansHere) { + for (int k = 0; k < dimX; k++) { + if (never_ran_array[k]) { + // run it as a javaCall + KlassHandle methKlass = mh->method_holder(); + Thread* THREAD = Thread::current(); + JavaValue result(T_VOID); + JavaCallArguments javaArgs; + // re-resolve the args_handle here + objArrayOop resolvedArgsArray = (objArrayOop) JNIHandles::resolve(args); + // This object sets up the javaCall arguments + // the way argsArray is set up, this should work for instance methods as well + // (the receiver will be the first oop pushed) + HSAILJavaCallArguments hjca(&javaArgs, k, mh->signature(), resolvedArgsArray, mh->is_static()); + if (mh->is_static()) { + JavaCalls::call_static(&result, methKlass, mh->name(), mh->signature(), &javaArgs, THREAD); + } else { + JavaCalls::call_virtual(&result, methKlass, mh->name(), mh->signature(), &javaArgs, THREAD); } + count_never_ran++; } - TraceGPUInteraction = savedTraceGPUInteraction; - if (TraceGPUInteraction) { - tty->print_cr("%d workitems never ran, have been run via JavaCall", count_never_ran); - showRanges(never_ran_array, dimX); - } - } // end of never-ran handling - } + } + TraceGPUInteraction = savedTraceGPUInteraction; + if (TraceGPUInteraction) { + tty->print_cr("%d workitems never ran, have been run via JavaCall", count_never_ran); + showRanges(never_ran_array, dimX); + } + } // end of never-ran handling } FREE_C_HEAP_ARRAY(jboolean, e->never_ran_array(), mtInternal); delete e; } + kernelStats.finishDispatch(); return success; } @@ -361,7 +512,7 @@ #define LOOKUP_OKRA_FUNCTION(name, alias) \ _##alias = \ - CAST_TO_FN_PTR(alias##_func_t, os::dll_lookup(handle, STRINGIFY(name))); \ + CAST_TO_FN_PTR(alias##_func_t, os::dll_lookup(okra_lib_handle, STRINGIFY(name))); \ if (_##alias == NULL) { \ tty->print_cr("[HSAIL] ***** Error: Failed to lookup %s in %s, wrong version of OKRA?", STRINGIFY(name), okra_library_name); \ return false; \ @@ -377,22 +528,25 @@ // here we know we have a valid okra_library_name to try to load char ebuf[O_BUFLEN]; + char *okra_lib_name_from_env_var = getenv("_OKRA_SIM_LIB_PATH_"); + if (okra_lib_name_from_env_var != NULL) { + okra_library_name = okra_lib_name_from_env_var; + } if (TraceGPUInteraction) { - tty->print_cr("[HSAIL] library is %s", okra_library_name); + tty->print_cr("[HSAIL] library is %s", okra_library_name); } - - void *handle = os::dll_load(okra_library_name, ebuf, O_BUFLEN); - // try alternate location if env variable set - char *okra_lib_name_from_env_var = getenv("_OKRA_SIM_LIB_PATH_"); - if ((handle == NULL) && (okra_lib_name_from_env_var != NULL)) { - handle = os::dll_load(okra_lib_name_from_env_var, ebuf, O_BUFLEN); - if ((handle != NULL) && TraceGPUInteraction) { - tty->print_cr("[HSAIL] using _OKRA_SIM_LIB_PATH_=%s", getenv("_OKRA_SIM_LIB_PATH_")); - } - } - - if (handle == NULL) { - // Unable to dlopen okra + void *okra_lib_handle = NULL; +#if defined(LINUX) + // Check first if the Okra library is already loaded. + // TODO: Figure out how to do this on other OSes. + okra_lib_handle = ::dlopen(okra_library_name, RTLD_LAZY | RTLD_NOLOAD); +#endif + // If Okra library is not already loaded, load it here + if (okra_lib_handle == NULL) { + okra_lib_handle = os::dll_load(okra_library_name, ebuf, O_BUFLEN); + } + if (okra_lib_handle == NULL) { + // Unable to open Okra library if (TraceGPUInteraction) { tty->print_cr("[HSAIL] library load failed."); } @@ -401,7 +555,8 @@ guarantee(_okra_create_context == NULL, "cannot repeat GPU initialization"); - // at this point we know handle is valid and we can lookup the functions + // at this point we know okra_lib_handle is valid whether we loaded + // here or earlier. In either case, we can lookup the functions LOOKUP_OKRA_FUNCTION(okra_create_context, okra_create_context); LOOKUP_OKRA_FUNCTION(okra_create_kernel, okra_create_kernel); LOOKUP_OKRA_FUNCTION(okra_push_object, okra_push_object); @@ -416,7 +571,7 @@ LOOKUP_OKRA_FUNCTION(okra_register_heap, okra_register_heap); // if we made it this far, real success - gpu::initialized_gpu("Okra"); + Gpu::initialized_gpu(new Hsail()); return true; GPU_END diff -r 518a7f487c4f -r 9363fffa8b07 src/gpu/hsail/vm/gpu_hsail.hpp --- a/src/gpu/hsail/vm/gpu_hsail.hpp Wed Apr 23 15:22:20 2014 +0200 +++ b/src/gpu/hsail/vm/gpu_hsail.hpp Wed Apr 23 15:48:38 2014 +0200 @@ -27,11 +27,9 @@ #include "utilities/exceptions.hpp" #include "graal/graalEnv.hpp" -// #include "graal/graalCodeInstaller.hpp" #include "gpu_hsail_Frame.hpp" -class Hsail { - friend class gpu; +class Hsail : public Gpu { public: class HSAILKernelDeoptimization { @@ -58,25 +56,28 @@ class HSAILDeoptimizationInfo : public ResourceObj { friend class VMStructs; private: + jint* _notice_safepoints; jint _deopt_occurred; jint _deopt_next_index; + JavaThread** _donor_threads; jboolean * _never_ran_array; public: HSAILKernelDeoptimization _deopt_save_states[MAX_DEOPT_SAVE_STATES_SIZE]; inline HSAILDeoptimizationInfo() { + _notice_safepoints = &Hsail::_notice_safepoints; _deopt_occurred = 0; _deopt_next_index = 0; } inline jint deopt_occurred() { - // Check that hsail did not write in the wrong place return _deopt_occurred; } inline jint num_deopts() { return _deopt_next_index; } inline jboolean *never_ran_array() { return _never_ran_array; } inline void set_never_ran_array(jboolean *p) { _never_ran_array = p; } + inline void set_donor_threads(JavaThread **threads) { _donor_threads = threads; } }; @@ -91,14 +92,17 @@ JNIEXPORT static jlong generate_kernel(JNIEnv *env, jclass, jbyteArray code_handle, jstring name_handle); // static native boolean executeKernel0(HotSpotInstalledCode kernel, int jobSize, Object[] args); - JNIEXPORT static jboolean execute_kernel_void_1d(JNIEnv *env, jclass, jobject hotspotInstalledCode, jint dimX, jobject args, jobject oopsSave); + JNIEXPORT static jboolean execute_kernel_void_1d(JNIEnv *env, jclass, jobject hotspotInstalledCode, jint dimX, jobject args, jobject oopsSave, + jobject donorThreads, int allocBytesPerWorkitem); + + // static native void getThreadPointers(Object[] donorThreads, long[] threadPointersOut); + JNIEXPORT static void get_thread_pointers(JNIEnv *env, jclass, jobject donor_threads_handle, jobject thread_ptrs_handle); - // static native void setSimulatorSingleThreaded0(); - JNIEXPORT static void setSimulatorSingleThreaded0(JNIEnv *env, jclass); + static void getNewTlabForDonorThread(ThreadLocalAllocBuffer* tlab, size_t tlabMinHsail); - - static jboolean execute_kernel_void_1d_internal(address kernel, int dimX, jobject args, methodHandle& mh, nmethod *nm, jobject oopsSave, TRAPS); - + static jboolean execute_kernel_void_1d_internal(address kernel, int dimX, jobject args, methodHandle& mh, nmethod *nm, jobject oopsSave, + jobject donor_threads, int allocBytesPerWorkitem, TRAPS); + static void register_heap(); static GraalEnv::CodeInstallResult install_code(Handle& compiled_code, CodeBlob*& cb, Handle installed_code, Handle triggered_deoptimizations); @@ -108,6 +112,11 @@ // Registers the implementations for the native methods in HSAILHotSpotBackend static bool register_natives(JNIEnv* env); + virtual const char* name() { return "HSAIL"; } + + virtual void notice_safepoints(); + virtual void ignore_safepoints(); + #if defined(__x86_64) || defined(AMD64) || defined(_M_AMD64) typedef unsigned long long CUdeviceptr; #else @@ -144,5 +153,8 @@ protected: static void* _device_context; + + // true if safepoints are activated + static jint _notice_safepoints; }; #endif // GPU_HSAIL_HPP diff -r 518a7f487c4f -r 9363fffa8b07 src/gpu/hsail/vm/vmStructs_hsail.hpp --- a/src/gpu/hsail/vm/vmStructs_hsail.hpp Wed Apr 23 15:22:20 2014 +0200 +++ b/src/gpu/hsail/vm/vmStructs_hsail.hpp Wed Apr 23 15:48:38 2014 +0200 @@ -32,17 +32,19 @@ // constants required by the Serviceability Agent. This file is // referenced by vmStructs.cpp. -#define VM_STRUCTS_GPU_HSAIL(nonstatic_field) \ +#define VM_STRUCTS_GPU_HSAIL(nonstatic_field) \ nonstatic_field(HSAILFrame, _pc_offset, jint) \ nonstatic_field(HSAILFrame, _num_s_regs, jbyte) \ nonstatic_field(HSAILFrame, _save_area[0], jlong) \ - \ + \ nonstatic_field(Hsail::HSAILKernelDeoptimization, _workitemid, jint) \ nonstatic_field(Hsail::HSAILKernelDeoptimization, _actionAndReason, jint) \ - nonstatic_field(Hsail::HSAILKernelDeoptimization, _first_frame, HSAILFrame) \ - \ + nonstatic_field(Hsail::HSAILKernelDeoptimization, _first_frame, HSAILFrame) \ + \ + nonstatic_field(Hsail::HSAILDeoptimizationInfo, _notice_safepoints, jint*) \ nonstatic_field(Hsail::HSAILDeoptimizationInfo, _deopt_occurred, jint) \ nonstatic_field(Hsail::HSAILDeoptimizationInfo, _deopt_next_index, jint) \ + nonstatic_field(Hsail::HSAILDeoptimizationInfo, _donor_threads, JavaThread**) \ nonstatic_field(Hsail::HSAILDeoptimizationInfo, _never_ran_array, jboolean *) \ nonstatic_field(Hsail::HSAILDeoptimizationInfo, _deopt_save_states[0], Hsail::HSAILKernelDeoptimization) \ nonstatic_field(Hsail::HSAILDeoptimizationInfo, _deopt_save_states[1], Hsail::HSAILKernelDeoptimization) diff -r 518a7f487c4f -r 9363fffa8b07 src/gpu/ptx/vm/gpu_ptx.cpp --- a/src/gpu/ptx/vm/gpu_ptx.cpp Wed Apr 23 15:22:20 2014 +0200 +++ b/src/gpu/ptx/vm/gpu_ptx.cpp Wed Apr 23 15:48:38 2014 +0200 @@ -271,7 +271,7 @@ tty->print_cr("[CUDA] Success: Created context for device: %d", _cu_device); } - gpu::initialized_gpu(device_name); + Gpu::initialized_gpu(new Ptx()); return true; GPU_END diff -r 518a7f487c4f -r 9363fffa8b07 src/gpu/ptx/vm/gpu_ptx.hpp --- a/src/gpu/ptx/vm/gpu_ptx.hpp Wed Apr 23 15:22:20 2014 +0200 +++ b/src/gpu/ptx/vm/gpu_ptx.hpp Wed Apr 23 15:48:38 2014 +0200 @@ -93,7 +93,7 @@ #define GRAAL_SUPPORTED_COMPUTE_CAPABILITY_VERSION 3.0 -class Ptx { +class Ptx : public Gpu { friend class PtxCall; private: @@ -120,6 +120,9 @@ static int ncores(int major, int minor); public: + + virtual const char* name() { return "PTX"; } + // Registers the implementations for the native methods in PTXHotSpotBackend static bool register_natives(JNIEnv* env); diff -r 518a7f487c4f -r 9363fffa8b07 src/os/bsd/vm/gpu_bsd.cpp --- a/src/os/bsd/vm/gpu_bsd.cpp Wed Apr 23 15:22:20 2014 +0200 +++ b/src/os/bsd/vm/gpu_bsd.cpp Wed Apr 23 15:48:38 2014 +0200 @@ -27,7 +27,7 @@ #include "hsail/vm/gpu_hsail.hpp" #include "utilities/ostream.hpp" -jobject gpu::probe_gpus(JNIEnv* env) { +jobject Gpu::probe_gpus(JNIEnv* env) { #ifdef __APPLE__ /* * Let the CUDA driver initialization be the gate to GPU for now, pending diff -r 518a7f487c4f -r 9363fffa8b07 src/os/linux/vm/gpu_linux.cpp --- a/src/os/linux/vm/gpu_linux.cpp Wed Apr 23 15:22:20 2014 +0200 +++ b/src/os/linux/vm/gpu_linux.cpp Wed Apr 23 15:48:38 2014 +0200 @@ -38,7 +38,7 @@ #define PCI_DRIVER_NAME_START_POS 255 -jobject gpu::probe_gpus(JNIEnv* env) { +jobject Gpu::probe_gpus(JNIEnv* env) { bool hsail = false; bool ptx = false; diff -r 518a7f487c4f -r 9363fffa8b07 src/os/windows/vm/gpu_windows.cpp --- a/src/os/windows/vm/gpu_windows.cpp Wed Apr 23 15:22:20 2014 +0200 +++ b/src/os/windows/vm/gpu_windows.cpp Wed Apr 23 15:48:38 2014 +0200 @@ -27,7 +27,7 @@ #include "hsail/vm/gpu_hsail.hpp" #include "utilities/ostream.hpp" -jobject gpu::probe_gpus(JNIEnv* env) { +jobject Gpu::probe_gpus(JNIEnv* env) { // TODO: add detection of PTX/NVidia if (Hsail::register_natives(env)) { return env->NewStringUTF("HSAIL"); diff -r 518a7f487c4f -r 9363fffa8b07 src/share/vm/classfile/systemDictionary.hpp --- a/src/share/vm/classfile/systemDictionary.hpp Wed Apr 23 15:22:20 2014 +0200 +++ b/src/share/vm/classfile/systemDictionary.hpp Wed Apr 23 15:48:38 2014 +0200 @@ -186,6 +186,9 @@ /* Support for Graal */ \ do_klass(CompilerThread_klass, com_oracle_graal_compiler_CompilerThread, Opt) \ do_klass(BitSet_klass, java_util_BitSet, Opt) \ + /* graal.graph */ \ + do_klass(Node_klass, com_oracle_graal_graph_Node, Opt) \ + do_klass(NodeClass_klass, com_oracle_graal_graph_NodeClass, Opt) \ /* graal.hotspot */ \ do_klass(HotSpotCompiledCode_klass, com_oracle_graal_hotspot_HotSpotCompiledCode, Opt) \ do_klass(HotSpotCompiledCode_Comment_klass, com_oracle_graal_hotspot_HotSpotCompiledCode_Comment, Opt) \ @@ -204,6 +207,9 @@ do_klass(HotSpotResolvedJavaMethod_klass, com_oracle_graal_hotspot_meta_HotSpotResolvedJavaMethod, Opt) \ do_klass(HotSpotResolvedObjectType_klass, com_oracle_graal_hotspot_meta_HotSpotResolvedObjectType, Opt) \ do_klass(HotSpotMonitorValue_klass, com_oracle_graal_hotspot_meta_HotSpotMonitorValue, Opt) \ + do_klass(HotSpotObjectConstant_klass, com_oracle_graal_hotspot_meta_HotSpotObjectConstant, Opt) \ + do_klass(HotSpotMetaspaceConstant_klass, com_oracle_graal_hotspot_meta_HotSpotMetaspaceConstant, Opt) \ + do_klass(HotSpotStackFrameReference_klass, com_oracle_graal_hotspot_HotSpotStackFrameReference, Opt) \ /* graal.api.code */ \ do_klass(Assumptions_klass, com_oracle_graal_api_code_Assumptions, Opt) \ do_klass(Assumptions_ConcreteMethod_klass, com_oracle_graal_api_code_Assumptions_ConcreteMethod, Opt) \ @@ -224,6 +230,7 @@ do_klass(CompilationResult_Site_klass, com_oracle_graal_api_code_CompilationResult_Site, Opt) \ do_klass(ExternalCompilationResult_klass, com_oracle_graal_gpu_ExternalCompilationResult, Opt) \ do_klass(InfopointReason_klass, com_oracle_graal_api_code_InfopointReason, Opt) \ + do_klass(InstalledCode_klass, com_oracle_graal_api_code_InstalledCode, Opt) \ do_klass(code_Register_klass, com_oracle_graal_api_code_Register, Opt) \ do_klass(RegisterValue_klass, com_oracle_graal_api_code_RegisterValue, Opt) \ do_klass(StackSlot_klass, com_oracle_graal_api_code_StackSlot, Opt) \ @@ -231,6 +238,8 @@ do_klass(SpeculationLog_klass, com_oracle_graal_api_code_SpeculationLog, Opt) \ /* graal.api.meta */ \ do_klass(Constant_klass, com_oracle_graal_api_meta_Constant, Opt) \ + do_klass(PrimitiveConstant_klass, com_oracle_graal_api_meta_PrimitiveConstant, Opt) \ + do_klass(NullConstant_klass, com_oracle_graal_api_meta_NullConstant, Opt) \ do_klass(ExceptionHandler_klass, com_oracle_graal_api_meta_ExceptionHandler, Opt) \ do_klass(Kind_klass, com_oracle_graal_api_meta_Kind, Opt) \ do_klass(JavaMethod_klass, com_oracle_graal_api_meta_JavaMethod, Opt) \ diff -r 518a7f487c4f -r 9363fffa8b07 src/share/vm/classfile/vmSymbols.hpp --- a/src/share/vm/classfile/vmSymbols.hpp Wed Apr 23 15:22:20 2014 +0200 +++ b/src/share/vm/classfile/vmSymbols.hpp Wed Apr 23 15:48:38 2014 +0200 @@ -292,6 +292,9 @@ /* Support for Graal */ \ template(com_oracle_graal_compiler_CompilerThread, "com/oracle/graal/compiler/CompilerThread") \ template(java_util_BitSet, "java/util/BitSet") \ + /* graal.graph */ \ + template(com_oracle_graal_graph_Node, "com/oracle/graal/graph/Node") \ + template(com_oracle_graal_graph_NodeClass, "com/oracle/graal/graph/NodeClass") \ /* graal.hotspot */ \ template(com_oracle_graal_hotspot_HotSpotGraalRuntime, "com/oracle/graal/hotspot/HotSpotGraalRuntime") \ template(com_oracle_graal_hotspot_HotSpotKlassOop, "com/oracle/graal/hotspot/HotSpotKlassOop") \ @@ -315,8 +318,13 @@ template(com_oracle_graal_hotspot_meta_HotSpotResolvedJavaMethod, "com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod") \ template(com_oracle_graal_hotspot_meta_HotSpotResolvedObjectType, "com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType") \ template(com_oracle_graal_hotspot_meta_HotSpotMonitorValue, "com/oracle/graal/hotspot/meta/HotSpotMonitorValue") \ + template(com_oracle_graal_hotspot_meta_HotSpotObjectConstant, "com/oracle/graal/hotspot/meta/HotSpotObjectConstant") \ + template(com_oracle_graal_hotspot_meta_HotSpotMetaspaceConstant, "com/oracle/graal/hotspot/meta/HotSpotMetaspaceConstant") \ + template(com_oracle_graal_hotspot_HotSpotStackFrameReference, "com/oracle/graal/hotspot/HotSpotStackFrameReference") \ /* graal.api.meta */ \ template(com_oracle_graal_api_meta_Constant, "com/oracle/graal/api/meta/Constant") \ + template(com_oracle_graal_api_meta_PrimitiveConstant, "com/oracle/graal/api/meta/PrimitiveConstant") \ + template(com_oracle_graal_api_meta_NullConstant, "com/oracle/graal/api/meta/NullConstant") \ template(com_oracle_graal_api_meta_ConstantPool, "com/oracle/graal/api/meta/ConstantPool") \ template(com_oracle_graal_api_meta_ExceptionHandler, "com/oracle/graal/api/meta/ExceptionHandler") \ template(com_oracle_graal_api_meta_JavaMethod, "com/oracle/graal/api/meta/JavaMethod") \ @@ -339,6 +347,7 @@ template(com_oracle_graal_api_code_CompilationResult_Infopoint, "com/oracle/graal/api/code/CompilationResult$Infopoint") \ template(com_oracle_graal_api_code_CompilationResult_Site, "com/oracle/graal/api/code/CompilationResult$Site") \ template(com_oracle_graal_api_code_InfopointReason, "com/oracle/graal/api/code/InfopointReason") \ + template(com_oracle_graal_api_code_InstalledCode, "com/oracle/graal/api/code/InstalledCode") \ template(com_oracle_graal_api_code_BytecodeFrame, "com/oracle/graal/api/code/BytecodeFrame") \ template(com_oracle_graal_api_code_BytecodePosition, "com/oracle/graal/api/code/BytecodePosition") \ template(com_oracle_graal_api_code_DebugInfo, "com/oracle/graal/api/code/DebugInfo") \ @@ -352,7 +361,7 @@ /* graal.gpu */ \ template(com_oracle_graal_gpu_ExternalCompilationResult, "com/oracle/graal/gpu/ExternalCompilationResult") \ /* graal.truffle */ \ - template(com_oracle_graal_truffle_GraalTruffleRuntime, "com/oracle/graal/truffle/GraalTruffleRuntime") \ + template(com_oracle_graal_truffle_hotspot_HotSpotTruffleRuntime, "com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime") \ template(startCompiler_name, "startCompiler") \ template(bootstrap_name, "bootstrap") \ template(compileTheWorld_name, "compileTheWorld") \ @@ -367,7 +376,7 @@ template(runtime_name, "runtime") \ template(runtime_signature, "()Lcom/oracle/graal/hotspot/HotSpotGraalRuntime;") \ template(makeInstance_name, "makeInstance") \ - template(makeInstance_signature, "()Lcom/oracle/graal/truffle/GraalTruffleRuntime;") \ + template(makeInstance_signature, "()Lcom/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime;") \ template(initialize_name, "initialize") \ template(forObject_name, "forObject") \ template(callbackInternal_name, "callbackInternal") \ diff -r 518a7f487c4f -r 9363fffa8b07 src/share/vm/code/codeBlob.hpp --- a/src/share/vm/code/codeBlob.hpp Wed Apr 23 15:22:20 2014 +0200 +++ b/src/share/vm/code/codeBlob.hpp Wed Apr 23 15:48:38 2014 +0200 @@ -358,8 +358,6 @@ int _unpack_with_exception_in_tls; #ifdef GRAAL - // (thomaswue) Offset when Graal calls uncommon_trap. - int _uncommon_trap_offset; int _implicit_exception_uncommon_trap_offset; #endif @@ -417,12 +415,6 @@ address unpack_with_exception_in_tls() const { return code_begin() + _unpack_with_exception_in_tls; } #ifdef GRAAL - // (thomaswue) Offset when Graal calls uncommon_trap. - void set_uncommon_trap_offset(int offset) { - _uncommon_trap_offset = offset; - assert(contains(code_begin() + _uncommon_trap_offset), "must be PC inside codeblob"); - } - address uncommon_trap() const { return code_begin() + _uncommon_trap_offset; } void set_implicit_exception_uncommon_trap_offset(int offset) { _implicit_exception_uncommon_trap_offset = offset; assert(contains(code_begin() + _implicit_exception_uncommon_trap_offset), "must be PC inside codeblob"); diff -r 518a7f487c4f -r 9363fffa8b07 src/share/vm/code/compiledIC.cpp --- a/src/share/vm/code/compiledIC.cpp Wed Apr 23 15:22:20 2014 +0200 +++ b/src/share/vm/code/compiledIC.cpp Wed Apr 23 15:48:38 2014 +0200 @@ -76,7 +76,7 @@ // Don't use ic_destination for this test since that forwards // through ICBuffer instead of returning the actual current state of // the CompiledIC. - if (is_icholder_entry(_ic_call->destination()) GRAAL_ONLY(&& _value != NULL)) { + if (is_icholder_entry(_ic_call->destination())) { // When patching for the ICStub case the cached value isn't // overwritten until the ICStub copied into the CompiledIC during // the next safepoint. Make sure that the CompiledICHolder* is @@ -107,13 +107,6 @@ _ic_call->set_destination_mt_safe(entry_point); } -#ifdef GRAAL - if (_value == NULL) { - // Can happen when Graal converted a virtual call into an invoke special based on static analysis. - return; - } -#endif - if (is_optimized() || is_icstub) { // Optimized call sites don't have a cache value and ICStub call // sites only change the entry point. Changing the value in that @@ -235,7 +228,9 @@ bool is_monomorphic = (cb != NULL && cb->is_nmethod()); // Check that the cached_value is a klass for non-optimized monomorphic calls // This assertion is invalid for compiler1: a call that does not look optimized (no static stub) can be used - // for calling directly to vep without using the inline cache (i.e., cached_value == NULL) + // for calling directly to vep without using the inline cache (i.e., cached_value == NULL). + // For Graal this occurs because CHA is only used to improve inlining so call sites which could be optimized + // virtuals because there are no currently loaded subclasses of a type are left as virtual call sites. #ifdef ASSERT CodeBlob* caller = CodeCache::find_blob_unsafe(instruction_address()); bool is_c1_or_graal_method = caller->is_compiled_by_c1() || caller->is_compiled_by_graal(); @@ -264,14 +259,12 @@ // Check if we are calling into our own codeblob (i.e., to a stub) CodeBlob* cb = CodeCache::find_blob(_ic_call->instruction_address()); address dest = ic_destination(); -#ifndef GRAAL #ifdef ASSERT { CodeBlob* db = CodeCache::find_blob_unsafe(dest); assert(!db->is_adapter_blob(), "must use stub!"); } #endif /* ASSERT */ -#endif is_call_to_interpreted = cb->contains(dest); } return is_call_to_interpreted; diff -r 518a7f487c4f -r 9363fffa8b07 src/share/vm/code/compiledIC.hpp --- a/src/share/vm/code/compiledIC.hpp Wed Apr 23 15:22:20 2014 +0200 +++ b/src/share/vm/code/compiledIC.hpp Wed Apr 23 15:48:38 2014 +0200 @@ -308,7 +308,7 @@ friend CompiledStaticCall* compiledStaticCall_at(Relocation* call_site); // Code - static void emit_to_interp_stub(CodeBuffer &cbuf); + static void emit_to_interp_stub(CodeBuffer &cbuf, address mark = NULL); static int to_interp_stub_size(); static int reloc_to_interp_stub(); diff -r 518a7f487c4f -r 9363fffa8b07 src/share/vm/code/debugInfoRec.cpp --- a/src/share/vm/code/debugInfoRec.cpp Wed Apr 23 15:22:20 2014 +0200 +++ b/src/share/vm/code/debugInfoRec.cpp Wed Apr 23 15:48:38 2014 +0200 @@ -235,10 +235,16 @@ int DebugInformationRecorder::find_sharable_decode_offset(int stream_offset) { + // It's always a space win to share and Graal generates quite a bit + // of scopes data so always enable the sharing logic with Graal. + // Presumably this is disabled in regular HotSpot because it makes + // recording more expensive? +#ifndef GRAAL // Only pull this trick if non-safepoint recording // is enabled, for now. if (!recording_non_safepoints()) return serialized_null; +#endif NOT_PRODUCT(++dir_stats.chunks_queried); int stream_length = stream()->position() - stream_offset; diff -r 518a7f487c4f -r 9363fffa8b07 src/share/vm/code/nmethod.cpp --- a/src/share/vm/code/nmethod.cpp Wed Apr 23 15:22:20 2014 +0200 +++ b/src/share/vm/code/nmethod.cpp Wed Apr 23 15:48:38 2014 +0200 @@ -1330,7 +1330,7 @@ // Java wrapper is no longer alive. Here we need to clear out this weak // reference to the dead object. if (_graal_installed_code != NULL) { - HotSpotInstalledCode::set_codeBlob(_graal_installed_code, 0); + InstalledCode::set_address(_graal_installed_code, 0); _graal_installed_code = NULL; } #endif @@ -1510,8 +1510,8 @@ } #ifdef GRAAL if (_graal_installed_code != NULL) { - // Break the link between nmethod and HotSpotInstalledCode such that the nmethod can subsequently be flushed safely. - HotSpotInstalledCode::set_codeBlob(_graal_installed_code, 0); + // Break the link between nmethod and InstalledCode such that the nmethod can subsequently be flushed safely. + InstalledCode::set_address(_graal_installed_code, 0); } #endif @@ -1738,7 +1738,7 @@ #ifdef GRAAL // Follow Graal method if (_graal_installed_code != NULL) { - if (HotSpotNmethod::isDefault(_graal_installed_code)) { + if (_graal_installed_code->is_a(HotSpotNmethod::klass()) && HotSpotNmethod::isDefault(_graal_installed_code)) { if (!is_alive->do_object_b(_graal_installed_code)) { _graal_installed_code = NULL; } diff -r 518a7f487c4f -r 9363fffa8b07 src/share/vm/compiler/disassembler.cpp --- a/src/share/vm/compiler/disassembler.cpp Wed Apr 23 15:22:20 2014 +0200 +++ b/src/share/vm/compiler/disassembler.cpp Wed Apr 23 15:48:38 2014 +0200 @@ -522,7 +522,7 @@ nm->method()->method_holder()->name()->print_symbol_on(env.output()); env.output()->print("."); nm->method()->name()->print_symbol_on(env.output()); - env.output()->print_cr(" [" PTR_FORMAT ", " PTR_FORMAT "] %d bytes", p, end, ((jlong)(end - p)) * sizeof(unsigned char*)); + env.output()->print_cr(" [" PTR_FORMAT ", " PTR_FORMAT "] %d bytes", p, end, ((jlong)(end - p))); // If there has been profiling, print the buckets. if (FlatProfiler::bucket_start_for(p) != NULL) { diff -r 518a7f487c4f -r 9363fffa8b07 src/share/vm/gc_interface/collectedHeap.hpp --- a/src/share/vm/gc_interface/collectedHeap.hpp Wed Apr 23 15:22:20 2014 +0200 +++ b/src/share/vm/gc_interface/collectedHeap.hpp Wed Apr 23 15:48:38 2014 +0200 @@ -84,6 +84,7 @@ class CollectedHeap : public CHeapObj { friend class VMStructs; friend class IsGCActiveMark; // Block structured external access to _is_gc_active + friend class Hsail; // access to allocate_new_tlab #ifdef ASSERT static int _fire_out_of_memory_count; diff -r 518a7f487c4f -r 9363fffa8b07 src/share/vm/graal/graalCodeInstaller.cpp --- a/src/share/vm/graal/graalCodeInstaller.cpp Wed Apr 23 15:22:20 2014 +0200 +++ b/src/share/vm/graal/graalCodeInstaller.cpp Wed Apr 23 15:48:38 2014 +0200 @@ -22,6 +22,7 @@ */ #include "precompiled.hpp" +#include "code/compiledIC.hpp" #include "compiler/compileBroker.hpp" #include "compiler/disassembler.hpp" #include "runtime/javaCalls.hpp" @@ -180,14 +181,14 @@ // Records any Metadata values embedded in a Constant (e.g., the value returned by HotSpotResolvedObjectType.klass()). static void record_metadata_in_constant(oop constant, OopRecorder* oop_recorder) { - char kind = Kind::typeChar(Constant::kind(constant)); - char wordKind = 'j'; - if (kind == wordKind) { - oop obj = Constant::object(constant); - jlong prim = Constant::primitive(constant); - if (obj != NULL) { - record_metadata_reference(obj, prim, false, oop_recorder); - } + if (constant->is_a(HotSpotMetaspaceConstant::klass())) { + oop obj = HotSpotMetaspaceConstant::metaspaceObject(constant); + jlong prim = HotSpotMetaspaceConstant::primitive(constant); + assert(Kind::typeChar(Constant::kind(constant)) == 'j', "must have word kind"); + assert(obj != NULL, "must have an object"); + assert(prim != 0, "must have a primitive value"); + + record_metadata_reference(obj, prim, false, oop_recorder); } } @@ -263,17 +264,19 @@ return value; } else if (value->is_a(Constant::klass())){ record_metadata_in_constant(value, oop_recorder); - jlong prim = Constant::primitive(value); if (type == T_INT || type == T_FLOAT || type == T_SHORT || type == T_CHAR || type == T_BOOLEAN || type == T_BYTE) { + jlong prim = PrimitiveConstant::primitive(value); return new ConstantIntValue(*(jint*)&prim); } else if (type == T_LONG || type == T_DOUBLE) { + jlong prim = PrimitiveConstant::primitive(value); second = new ConstantIntValue(0); return new ConstantLongValue(prim); } else if (type == T_OBJECT) { - oop obj = Constant::object(value); - if (obj == NULL) { + if (value->is_a(NullConstant::klass())) { return new ConstantOopWriteValue(NULL); } else { + oop obj = HotSpotObjectConstant::object(value); + assert(obj != NULL, "null value must be in NullConstant"); return new ConstantOopWriteValue(JNIHandles::make_local(obj)); } } else if (type == T_ADDRESS) { @@ -452,8 +455,7 @@ _code = (arrayOop) CompilationResult::targetCode(comp_result); _code_size = CompilationResult::targetCodeSize(comp_result); - // The frame size we get from the target method does not include the return address, so add one word for it here. - _total_frame_size = CompilationResult::frameSize(comp_result) + HeapWordSize; // FIXME this is an x86-ism + _total_frame_size = CompilationResult::totalFrameSize(comp_result); _custom_stack_area_offset = CompilationResult::customStackAreaOffset(comp_result); // Pre-calculate the constants section size. This is required for PC-relative addressing. @@ -472,12 +474,35 @@ _next_call_type = INVOKE_INVALID; } +int CodeInstaller::estimate_stub_entries() { + // Estimate the number of static call stubs that might be emitted. + int static_call_stubs = 0; + for (int i = 0; i < _sites->length(); i++) { + oop site = ((objArrayOop) (_sites))->obj_at(i); + if (site->is_a(CompilationResult_Mark::klass())) { + oop id_obj = CompilationResult_Mark::id(site); + if (id_obj != NULL) { + assert(java_lang_boxing_object::is_instance(id_obj, T_INT), "Integer id expected"); + jint id = id_obj->int_field(java_lang_boxing_object::value_offset_in_bytes(T_INT)); + if (id == INVOKESTATIC || id == INVOKESPECIAL) { + static_call_stubs++; + } + } + } + } + return static_call_stubs; +} + // perform data and call relocation on the CodeBuffer bool CodeInstaller::initialize_buffer(CodeBuffer& buffer) { int locs_buffer_size = _sites->length() * (relocInfo::length_limit + sizeof(relocInfo)); char* locs_buffer = NEW_RESOURCE_ARRAY(char, locs_buffer_size); buffer.insts()->initialize_shared_locs((relocInfo*)locs_buffer, locs_buffer_size / sizeof(relocInfo)); - buffer.initialize_stubs_size(256); + // Allocate enough space in the stub section for the static call + // stubs. Stubs have extra relocs but they are managed by the stub + // section itself so they don't need to be accounted for in the + // locs_buffer above. + buffer.initialize_stubs_size(estimate_stub_entries() * CompiledStaticCall::to_interp_stub_size()); buffer.initialize_consts_size(_constants_size); _debug_recorder = new DebugInformationRecorder(_oop_recorder); @@ -651,8 +676,11 @@ oop hotspot_method = BytecodePosition::method(frame); Method* method = getMethodFromHotSpotMethod(hotspot_method); jint bci = BytecodePosition::bci(frame); + if (bci == BytecodeFrame::BEFORE_BCI()) { + bci = SynchronizationEntryBCI; + } bool reexecute; - if (bci == -1 || bci == -2){ + if (bci == SynchronizationEntryBCI){ reexecute = false; } else { Bytecodes::Code code = Bytecodes::java_code_at(method, method->bcp_from(bci)); @@ -776,6 +804,10 @@ TRACE_graal_3("method call"); CodeInstaller::pd_relocate_JavaMethod(hotspot_method, pc_offset); + if (_next_call_type == INVOKESTATIC || _next_call_type == INVOKESPECIAL) { + // Need a static call stub for transitions from compiled to interpreted. + CompiledStaticCall::emit_to_interp_stub(buffer, _instructions->start() + pc_offset); + } } _next_call_type = INVOKE_INVALID; diff -r 518a7f487c4f -r 9363fffa8b07 src/share/vm/graal/graalCodeInstaller.hpp --- a/src/share/vm/graal/graalCodeInstaller.hpp Wed Apr 23 15:22:20 2014 +0200 +++ b/src/share/vm/graal/graalCodeInstaller.hpp Wed Apr 23 15:48:38 2014 +0200 @@ -102,7 +102,9 @@ // extract the fields of the CompilationResult void initialize_fields(oop target_method); void initialize_assumptions(oop target_method); - + + int estimate_stub_entries(); + // perform data and call relocation on the CodeBuffer bool initialize_buffer(CodeBuffer& buffer); @@ -120,7 +122,7 @@ void record_scope(jint pc_offset, oop code_pos, GrowableArray* objects); void process_exception_handlers(); - + int estimateStubSpace(int static_call_stubs); }; /** @@ -128,20 +130,4 @@ */ Method* getMethodFromHotSpotMethod(oop hotspot_method); -#ifdef TARGET_ARCH_x86 -# include "graalCodeInstaller_x86.hpp" -#endif -#ifdef TARGET_ARCH_sparc -# include "graalCodeInstaller_sparc.hpp" -#endif -#ifdef TARGET_ARCH_zero -# error -#endif -#ifdef TARGET_ARCH_arm -# error -#endif -#ifdef TARGET_ARCH_ppc -# error -#endif - #endif // SHARE_VM_GRAAL_GRAAL_CODE_INSTALLER_HPP diff -r 518a7f487c4f -r 9363fffa8b07 src/share/vm/graal/graalCompiler.cpp diff -r 518a7f487c4f -r 9363fffa8b07 src/share/vm/graal/graalCompilerToVM.cpp --- a/src/share/vm/graal/graalCompilerToVM.cpp Wed Apr 23 15:22:20 2014 +0200 +++ b/src/share/vm/graal/graalCompilerToVM.cpp Wed Apr 23 15:48:38 2014 +0200 @@ -22,6 +22,7 @@ */ #include "precompiled.hpp" +#include "code/scopeDesc.hpp" #include "memory/oopFactory.hpp" #include "oops/generateOopMap.hpp" #include "oops/fieldStreams.hpp" @@ -39,6 +40,9 @@ #include "graal/graalVMToCompiler.hpp" #include "gc_implementation/g1/heapRegion.hpp" #include "runtime/javaCalls.hpp" +#include "runtime/deoptimization.hpp" +#include "runtime/vframe.hpp" +#include "runtime/vframe_hp.hpp" #include "runtime/vmStructs.hpp" #include "runtime/gpu.hpp" @@ -153,7 +157,6 @@ //------------------------------------------------------------------------------------------------ set_address("handleDeoptStub", SharedRuntime::deopt_blob()->unpack()); - set_address("uncommonTrapStub", SharedRuntime::deopt_blob()->uncommon_trap()); set_address("registerFinalizerAddress", SharedRuntime::register_finalizer); set_address("exceptionHandlerForReturnAddressAddress", SharedRuntime::exception_handler_for_return_address); @@ -187,6 +190,10 @@ set_address("writeBarrierPostAddress", GraalRuntime::write_barrier_post); set_address("validateObject", GraalRuntime::validate_object); + set_address("deoptimizationFetchUnrollInfo", Deoptimization::fetch_unroll_info); + set_address("deoptimizationUncommonTrap", Deoptimization::uncommon_trap); + set_address("deoptimizationUnpackFrames", Deoptimization::unpack_frames); + //------------------------------------------------------------------------------------------------ set_int("graalCountersThreadOffset", in_bytes(JavaThread::graal_counters_offset())); @@ -203,6 +210,7 @@ #undef set_boolean #undef set_int #undef set_long +#undef set_address C2V_END @@ -523,15 +531,16 @@ assert(cb == NULL, "should be"); } else { if (!installed_code_handle.is_null()) { - assert(installed_code_handle->is_a(HotSpotInstalledCode::klass()), "wrong type"); - HotSpotInstalledCode::set_codeBlob(installed_code_handle, (jlong) cb); + assert(installed_code_handle->is_a(InstalledCode::klass()), "wrong type"); + InstalledCode::set_address(installed_code_handle, (jlong) cb); + InstalledCode::set_version(installed_code_handle, InstalledCode::version(installed_code_handle) + 1); oop comp_result = HotSpotCompiledCode::comp(compiled_code_handle); if (comp_result->is_a(ExternalCompilationResult::klass())) { if (TraceGPUInteraction) { tty->print_cr("installCode0: ExternalCompilationResult"); } HotSpotInstalledCode::set_codeStart(installed_code_handle, ExternalCompilationResult::entryPoint(comp_result)); - } else { + } else if (installed_code_handle->is_a(HotSpotInstalledCode::klass())) { HotSpotInstalledCode::set_size(installed_code_handle, cb->size()); HotSpotInstalledCode::set_codeStart(installed_code_handle, (jlong) cb->code_begin()); HotSpotInstalledCode::set_codeSize(installed_code_handle, cb->code_size()); @@ -553,8 +562,10 @@ stats->_standard.update(timer, processedBytecodes); } Handle installed_code_handle = JNIHandles::resolve(installed_code); - stats->_nmethods_size += HotSpotInstalledCode::size(installed_code_handle); - stats->_nmethods_code_size += HotSpotInstalledCode::codeSize(installed_code_handle); + if (installed_code_handle->is_a(HotSpotInstalledCode::klass())) { + stats->_nmethods_size += HotSpotInstalledCode::size(installed_code_handle); + stats->_nmethods_code_size += HotSpotInstalledCode::codeSize(installed_code_handle); + } if (CITimeEach) { methodHandle method = asMethod(HotSpotResolvedJavaMethod::metaspaceMethod(hotspot_method)); @@ -626,7 +637,7 @@ ResourceMark rm; HandleMark hm; - jlong nmethodValue = HotSpotInstalledCode::codeBlob(hotspotInstalledCode); + jlong nmethodValue = InstalledCode::address(hotspotInstalledCode); if (nmethodValue == 0L) { THROW_(vmSymbols::com_oracle_graal_api_code_InvalidInstalledCodeException(), NULL); } @@ -717,21 +728,19 @@ C2V_VMENTRY(void, invalidateInstalledCode, (JNIEnv *env, jobject, jobject hotspotInstalledCode)) - jlong nativeMethod = HotSpotInstalledCode::codeBlob(hotspotInstalledCode); + jlong nativeMethod = InstalledCode::address(hotspotInstalledCode); nmethod* m = (nmethod*)nativeMethod; if (m != NULL && !m->is_not_entrant()) { m->mark_for_deoptimization(); VM_Deoptimize op; VMThread::execute(&op); } - HotSpotInstalledCode::set_codeBlob(hotspotInstalledCode, 0); + InstalledCode::set_address(hotspotInstalledCode, 0); C2V_END - -C2V_VMENTRY(jobject, readUnsafeUncompressedPointer, (JNIEnv *env, jobject, jobject o, jlong offset)) - oop resolved_o = JNIHandles::resolve(o); - address addr = ((address)resolved_o) + offset; - return JNIHandles::make_local(*((oop*)addr)); +C2V_VMENTRY(jobject, getJavaMirror, (JNIEnv *env, jobject, jlong metaspace_klass)) + Klass* klass = asKlass(metaspace_klass); + return JNIHandles::make_local(klass->java_mirror()); C2V_END C2V_VMENTRY(jlong, readUnsafeKlassPointer, (JNIEnv *env, jobject, jobject o)) @@ -748,7 +757,7 @@ C2V_ENTRY(jobject, getGPUs, (JNIEnv *env, jobject)) #if defined(TARGET_OS_FAMILY_bsd) || defined(TARGET_OS_FAMILY_linux) || defined(TARGET_OS_FAMILY_windows) - return gpu::probe_gpus(env); + return Gpu::probe_gpus(env); #else return env->NewStringUTF(""); #endif @@ -772,6 +781,260 @@ return method->lookup_osr_nmethod_for(entry_bci, comp_level, true) != NULL; C2V_END +C2V_VMENTRY(jlong, getTimeStamp, (JNIEnv *env, jobject)) + // tty->time_stamp is the time since VM start which should be used + // for all HotSpot log output when a timestamp is required. + return tty->time_stamp().milliseconds(); +C2V_END + +bool matches(jlongArray methods, Method* method) { + typeArrayOop methods_oop = (typeArrayOop) JNIHandles::resolve(methods); + + for (int i = 0; i < methods_oop->length(); i++) { + if (methods_oop->long_at(i) == (jlong) method) { + return true; + } + } + return false; +} + +C2V_VMENTRY(jobject, getNextStackFrame, (JNIEnv *env, jobject compilerToVM, jobject hs_frame, jlongArray methods, jint initialSkip)) + ResourceMark rm; + + if (!thread->has_last_Java_frame()) return NULL; + Handle result = InstanceKlass::cast(HotSpotStackFrameReference::klass())->allocate_instance(thread); + HotSpotStackFrameReference::klass()->initialize(thread); + + StackFrameStream fst(thread); + if (hs_frame != NULL) { + // look for the correct stack frame if one is given + intptr_t* stack_pointer = (intptr_t*) HotSpotStackFrameReference::stackPointer(hs_frame); + while (fst.current()->sp() != stack_pointer && !fst.is_done()) { + fst.next(); + } + if (fst.current()->sp() != stack_pointer) { + THROW_MSG_NULL(vmSymbols::java_lang_IllegalStateException(), "stack frame not found") + } + } + + int frame_number = 0; + vframe* vf = vframe::new_vframe(fst.current(), fst.register_map(), thread); + if (hs_frame != NULL) { + // look for the correct vframe within the stack frame if one is given + int last_frame_number = HotSpotStackFrameReference::frameNumber(hs_frame); + while (frame_number < last_frame_number) { + if (vf->is_top()) { + THROW_MSG_NULL(vmSymbols::java_lang_IllegalStateException(), "invalid frame number") + } + vf = vf->sender(); + frame_number ++; + } + // move one frame forward + if (vf->is_top()) { + if (fst.is_done()) { + return NULL; + } + fst.next(); + vf = vframe::new_vframe(fst.current(), fst.register_map(), thread); + frame_number = 0; + } else { + vf = vf->sender(); + frame_number++; + } + } + + while (true) { + // look for the given method + while (true) { + StackValueCollection* locals = NULL; + if (vf->is_compiled_frame()) { + // compiled method frame + compiledVFrame* cvf = compiledVFrame::cast(vf); + if (methods == NULL || matches(methods, cvf->method())) { + if (initialSkip > 0) { + initialSkip --; + } else { + GrowableArray* objects = cvf->scope()->objects(); + bool reallocated = false; + if (objects != NULL) { + reallocated = Deoptimization::realloc_objects(thread, fst.current(), objects, THREAD); + if (reallocated) { + Deoptimization::reassign_fields(fst.current(), fst.register_map(), objects); + } + + GrowableArray* local_values = cvf->scope()->locals(); + typeArrayHandle array = oopFactory::new_boolArray(local_values->length(), thread); + for (int i = 0; i < local_values->length(); i++) { + ScopeValue* value = local_values->at(i); + if (value->is_object()) { + array->bool_at_put(i, true); + } + } + HotSpotStackFrameReference::set_localIsVirtual(result, array()); + } else { + HotSpotStackFrameReference::set_localIsVirtual(result, NULL); + } + + locals = cvf->locals(); + HotSpotStackFrameReference::set_bci(result, cvf->bci()); + HotSpotStackFrameReference::set_metaspaceMethod(result, (jlong) cvf->method()); + } + } + } else if (vf->is_interpreted_frame()) { + // interpreted method frame + interpretedVFrame* ivf = interpretedVFrame::cast(vf); + if (methods == NULL || matches(methods, ivf->method())) { + if (initialSkip > 0) { + initialSkip --; + } else { + locals = ivf->locals(); + HotSpotStackFrameReference::set_bci(result, ivf->bci()); + HotSpotStackFrameReference::set_metaspaceMethod(result, (jlong) ivf->method()); + HotSpotStackFrameReference::set_localIsVirtual(result, NULL); + } + } + } + + // locals != NULL means that we found a matching frame and result is already partially initialized + if (locals != NULL) { + HotSpotStackFrameReference::set_compilerToVM(result, JNIHandles::resolve(compilerToVM)); + HotSpotStackFrameReference::set_stackPointer(result, (jlong) fst.current()->sp()); + HotSpotStackFrameReference::set_frameNumber(result, frame_number); + + // initialize the locals array + objArrayHandle array = oopFactory::new_objectArray(locals->size(), thread); + for (int i = 0; i < locals->size(); i++) { + StackValue* var = locals->at(i); + if (var->type() == T_OBJECT) { + array->obj_at_put(i, locals->at(i)->get_obj()()); + } + } + HotSpotStackFrameReference::set_locals(result, array()); + + return JNIHandles::make_local(thread, result()); + } + + if (vf->is_top()) { + break; + } + frame_number++; + vf = vf->sender(); + } // end of vframe loop + + if (fst.is_done()) { + break; + } + fst.next(); + vf = vframe::new_vframe(fst.current(), fst.register_map(), thread); + frame_number = 0; + } // end of frame loop + + // the end was reached without finding a matching method + return NULL; +C2V_END + +C2V_VMENTRY(void, resolveInvokeDynamic, (JNIEnv *env, jobject, jlong metaspace_constant_pool, jint index)) + ConstantPool* cp = (ConstantPool*)metaspace_constant_pool; + CallInfo callInfo; + LinkResolver::resolve_invokedynamic(callInfo, cp, index, CHECK); + ConstantPoolCacheEntry* cp_cache_entry = cp->invokedynamic_cp_cache_entry_at(index); + cp_cache_entry->set_dynamic_call(cp, callInfo); +C2V_END + +// public native void materializeVirtualObjects(HotSpotStackFrameReference stackFrame, boolean invalidate); +C2V_VMENTRY(void, materializeVirtualObjects, (JNIEnv *env, jobject, jobject hs_frame, bool invalidate)) + ResourceMark rm; + + if (hs_frame == NULL) { + THROW_MSG(vmSymbols::java_lang_NullPointerException(), "stack frame is null") + } + + HotSpotStackFrameReference::klass()->initialize(thread); + + // look for the given stack frame + StackFrameStream fst(thread); + intptr_t* stack_pointer = (intptr_t*) HotSpotStackFrameReference::stackPointer(hs_frame); + while (fst.current()->sp() != stack_pointer && !fst.is_done()) { + fst.next(); + } + if (fst.current()->sp() != stack_pointer) { + THROW_MSG(vmSymbols::java_lang_IllegalStateException(), "stack frame not found") + } + + if (invalidate) { + assert(fst.current()->cb()->is_nmethod(), "nmethod expected"); + ((nmethod*) fst.current()->cb())->make_not_entrant(); + } + Deoptimization::deoptimize(thread, *fst.current(), fst.register_map(), Deoptimization::Reason_none); + + vframe* vf = vframe::new_vframe(fst.current(), fst.register_map(), thread); + if (!vf->is_compiled_frame()) { + THROW_MSG(vmSymbols::java_lang_IllegalStateException(), "compiled stack frame expected") + } + + GrowableArray* virtualFrames = new GrowableArray(10); + while (true) { + assert(vf->is_compiled_frame(), "Wrong frame type"); + virtualFrames->push(compiledVFrame::cast(vf)); + if (vf->is_top()) { + break; + } + vf = vf->sender(); + } + + int last_frame_number = HotSpotStackFrameReference::frameNumber(hs_frame); + if (last_frame_number >= virtualFrames->length()) { + THROW_MSG(vmSymbols::java_lang_IllegalStateException(), "invalid frame number") + } + + // Reallocate the non-escaping objects and restore their fields. + assert (virtualFrames->at(last_frame_number)->scope() != NULL,"invalid scope"); + GrowableArray* objects = virtualFrames->at(last_frame_number)->scope()->objects(); + + if (objects == NULL) { + // no objects to materialize + return; + } + + bool reallocated = Deoptimization::realloc_objects(thread, fst.current(), objects, THREAD); + if (reallocated) { + Deoptimization::reassign_fields(fst.current(), fst.register_map(), objects); + + for (int frame_index = 0; frame_index < virtualFrames->length(); frame_index++) { + compiledVFrame* cvf = virtualFrames->at(frame_index); + + GrowableArray* scopeLocals = cvf->scope()->locals(); + StackValueCollection* locals = cvf->locals(); + + if (locals != NULL) { + for (int i2 = 0; i2 < locals->size(); i2++) { + StackValue* var = locals->at(i2); + if (var->type() == T_OBJECT && scopeLocals->at(i2)->is_object()) { + jvalue val; + val.l = (jobject) locals->at(i2)->get_obj()(); + cvf->update_local(T_OBJECT, i2, val); + } + } + } + } + + // all locals are materialized by now + HotSpotStackFrameReference::set_localIsVirtual(hs_frame, NULL); + + // update the locals array + objArrayHandle array = (objArrayOop) HotSpotStackFrameReference::locals(hs_frame); + StackValueCollection* locals = virtualFrames->at(last_frame_number)->locals(); + for (int i = 0; i < locals->size(); i++) { + StackValue* var = locals->at(i); + if (var->type() == T_OBJECT) { + array->obj_at_put(i, locals->at(i)->get_obj()()); + } + } + } +C2V_END + + + #define CC (char*) /*cast a literal from (const char*)*/ #define FN_PTR(f) CAST_FROM_FN_PTR(void*, &(c2v_ ## f)) @@ -784,9 +1047,12 @@ #define CLASS "Ljava/lang/Class;" #define STACK_TRACE_ELEMENT "Ljava/lang/StackTraceElement;" #define HS_RESOLVED_METHOD "Lcom/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod;" +#define RESOLVED_METHOD "Lcom/oracle/graal/api/meta/ResolvedJavaMethod;" #define HS_COMPILED_CODE "Lcom/oracle/graal/hotspot/HotSpotCompiledCode;" #define HS_CONFIG "Lcom/oracle/graal/hotspot/HotSpotVMConfig;" -#define HS_INSTALLED_CODE "Lcom/oracle/graal/hotspot/meta/HotSpotInstalledCode;" +#define INSTALLED_CODE "Lcom/oracle/graal/api/code/InstalledCode;" +#define NODE_CLASS "Lcom/oracle/graal/graph/NodeClass;" +#define HS_STACK_FRAME_REF "Lcom/oracle/graal/hotspot/HotSpotStackFrameReference;" #define METASPACE_KLASS "J" #define METASPACE_METHOD "J" #define METASPACE_METHOD_DATA "J" @@ -818,30 +1084,34 @@ {CC"lookupMethodInPool", CC"("METASPACE_CONSTANT_POOL"IB)"METASPACE_METHOD, FN_PTR(lookupMethodInPool)}, {CC"constantPoolRemapInstructionOperandFromCache", CC"("METASPACE_CONSTANT_POOL"I)I", FN_PTR(constantPoolRemapInstructionOperandFromCache)}, {CC"resolveField", CC"("METASPACE_CONSTANT_POOL"IB[J)"METASPACE_KLASS, FN_PTR(resolveField)}, + {CC"resolveInvokeDynamic", CC"("METASPACE_CONSTANT_POOL"I)V", FN_PTR(resolveInvokeDynamic)}, {CC"resolveMethod", CC"("METASPACE_KLASS STRING STRING")"METASPACE_METHOD, FN_PTR(resolveMethod)}, {CC"getClassInitializer", CC"("METASPACE_KLASS")"METASPACE_METHOD, FN_PTR(getClassInitializer)}, {CC"hasFinalizableSubclass", CC"("METASPACE_KLASS")Z", FN_PTR(hasFinalizableSubclass)}, {CC"getMaxCallTargetOffset", CC"(J)J", FN_PTR(getMaxCallTargetOffset)}, {CC"getMetaspaceMethod", CC"("CLASS"I)"METASPACE_METHOD, FN_PTR(getMetaspaceMethod)}, {CC"initializeConfiguration", CC"("HS_CONFIG")V", FN_PTR(initializeConfiguration)}, - {CC"installCode0", CC"("HS_COMPILED_CODE HS_INSTALLED_CODE SPECULATION_LOG")I", FN_PTR(installCode0)}, - {CC"notifyCompilationStatistics", CC"(I"HS_RESOLVED_METHOD"ZIJJ"HS_INSTALLED_CODE")V", FN_PTR(notifyCompilationStatistics)}, + {CC"installCode0", CC"("HS_COMPILED_CODE INSTALLED_CODE SPECULATION_LOG")I", FN_PTR(installCode0)}, + {CC"notifyCompilationStatistics", CC"(I"HS_RESOLVED_METHOD"ZIJJ"INSTALLED_CODE")V", FN_PTR(notifyCompilationStatistics)}, {CC"printCompilationStatistics", CC"(ZZ)V", FN_PTR(printCompilationStatistics)}, {CC"resetCompilationStatistics", CC"()V", FN_PTR(resetCompilationStatistics)}, {CC"disassembleCodeBlob", CC"(J)"STRING, FN_PTR(disassembleCodeBlob)}, - {CC"executeCompiledMethodVarargs", CC"(["OBJECT HS_INSTALLED_CODE")"OBJECT, FN_PTR(executeCompiledMethodVarargs)}, + {CC"executeCompiledMethodVarargs", CC"(["OBJECT INSTALLED_CODE")"OBJECT, FN_PTR(executeCompiledMethodVarargs)}, {CC"getLineNumberTable", CC"("METASPACE_METHOD")[J", FN_PTR(getLineNumberTable)}, {CC"getLocalVariableTableStart", CC"("METASPACE_METHOD")J", FN_PTR(getLocalVariableTableStart)}, {CC"getLocalVariableTableLength", CC"("METASPACE_METHOD")I", FN_PTR(getLocalVariableTableLength)}, {CC"reprofile", CC"("METASPACE_METHOD")V", FN_PTR(reprofile)}, - {CC"invalidateInstalledCode", CC"("HS_INSTALLED_CODE")V", FN_PTR(invalidateInstalledCode)}, - {CC"readUnsafeUncompressedPointer", CC"("OBJECT"J)"OBJECT, FN_PTR(readUnsafeUncompressedPointer)}, + {CC"invalidateInstalledCode", CC"("INSTALLED_CODE")V", FN_PTR(invalidateInstalledCode)}, + {CC"getJavaMirror", CC"("METASPACE_KLASS")"CLASS, FN_PTR(getJavaMirror)}, {CC"readUnsafeKlassPointer", CC"("OBJECT")J", FN_PTR(readUnsafeKlassPointer)}, {CC"collectCounters", CC"()[J", FN_PTR(collectCounters)}, {CC"getGPUs", CC"()"STRING, FN_PTR(getGPUs)}, {CC"allocateCompileId", CC"("METASPACE_METHOD"I)I", FN_PTR(allocateCompileId)}, {CC"isMature", CC"("METASPACE_METHOD_DATA")Z", FN_PTR(isMature)}, {CC"hasCompiledCodeForOSR", CC"("METASPACE_METHOD"II)Z", FN_PTR(hasCompiledCodeForOSR)}, + {CC"getTimeStamp", CC"()J", FN_PTR(getTimeStamp)}, + {CC"getNextStackFrame", CC"("HS_STACK_FRAME_REF "[JI)"HS_STACK_FRAME_REF, FN_PTR(getNextStackFrame)}, + {CC"materializeVirtualObjects", CC"("HS_STACK_FRAME_REF"Z)V", FN_PTR(materializeVirtualObjects)}, }; int CompilerToVM_methods_count() { diff -r 518a7f487c4f -r 9363fffa8b07 src/share/vm/graal/graalEnv.cpp --- a/src/share/vm/graal/graalEnv.cpp Wed Apr 23 15:22:20 2014 +0200 +++ b/src/share/vm/graal/graalEnv.cpp Wed Apr 23 15:48:38 2014 +0200 @@ -515,7 +515,7 @@ // (Put nm into the task handle *before* publishing to the Java heap.) if (task != NULL) task->set_code(nm); - if (HotSpotNmethod::isDefault(installed_code())) { + if (installed_code->is_a(HotSpotNmethod::klass()) && HotSpotNmethod::isDefault(installed_code())) { if (entry_bci == InvocationEntryBci) { if (TieredCompilation) { // If there is an old version we're done with it diff -r 518a7f487c4f -r 9363fffa8b07 src/share/vm/graal/graalGlobals.hpp --- a/src/share/vm/graal/graalGlobals.hpp Wed Apr 23 15:22:20 2014 +0200 +++ b/src/share/vm/graal/graalGlobals.hpp Wed Apr 23 15:48:38 2014 +0200 @@ -88,6 +88,9 @@ product(bool, UseHSAILDeoptimization, true, \ "Code gen and runtime support for deoptimizing HSAIL kernels") \ \ + product(bool, UseHSAILSafepoints, true, \ + "Code gen and runtime support for safepoints in HSAIL kernels") \ + \ product(bool, GPUOffload, false, \ "Offload execution to GPU whenever possible") \ \ diff -r 518a7f487c4f -r 9363fffa8b07 src/share/vm/graal/graalJavaAccess.cpp --- a/src/share/vm/graal/graalJavaAccess.cpp Wed Apr 23 15:22:20 2014 +0200 +++ b/src/share/vm/graal/graalJavaAccess.cpp Wed Apr 23 15:48:38 2014 +0200 @@ -59,11 +59,12 @@ #define FLOAT_FIELD(klass, name) FIELD(klass, name, "F", false) #define OOP_FIELD(klass, name, signature) FIELD(klass, name, signature, false) #define STATIC_OOP_FIELD(klass, name, signature) FIELD(klass, name, signature, true) +#define STATIC_INT_FIELD(klass, name) FIELD(klass, name, "I", true) void graal_compute_offsets() { - COMPILER_CLASSES_DO(START_CLASS, END_CLASS, CHAR_FIELD, INT_FIELD, BOOLEAN_FIELD, LONG_FIELD, FLOAT_FIELD, OOP_FIELD, STATIC_OOP_FIELD) - guarantee(HotSpotInstalledCode::_codeBlob_offset == sizeof(oopDesc), "codeBlob must be first field!"); + COMPILER_CLASSES_DO(START_CLASS, END_CLASS, CHAR_FIELD, INT_FIELD, BOOLEAN_FIELD, LONG_FIELD, FLOAT_FIELD, OOP_FIELD, STATIC_OOP_FIELD, STATIC_INT_FIELD) + guarantee(InstalledCode::_address_offset == sizeof(oopDesc), "codeBlob must be first field!"); } #define EMPTY0 @@ -72,7 +73,7 @@ #define FIELD2(klass, name) int klass::_##name##_offset = 0; #define FIELD3(klass, name, sig) FIELD2(klass, name) -COMPILER_CLASSES_DO(EMPTY1, EMPTY0, FIELD2, FIELD2, FIELD2, FIELD2, FIELD2, FIELD3, FIELD3) +COMPILER_CLASSES_DO(EMPTY1, EMPTY0, FIELD2, FIELD2, FIELD2, FIELD2, FIELD2, FIELD3, FIELD3, FIELD2) diff -r 518a7f487c4f -r 9363fffa8b07 src/share/vm/graal/graalJavaAccess.hpp --- a/src/share/vm/graal/graalJavaAccess.hpp Wed Apr 23 15:22:20 2014 +0200 +++ b/src/share/vm/graal/graalJavaAccess.hpp Wed Apr 23 15:48:38 2014 +0200 @@ -47,9 +47,9 @@ * */ -#define COMPILER_CLASSES_DO(start_class, end_class, char_field, int_field, boolean_field, long_field, float_field, oop_field, static_oop_field) \ +#define COMPILER_CLASSES_DO(start_class, end_class, char_field, int_field, boolean_field, long_field, float_field, oop_field, static_oop_field, static_int_field) \ start_class(HotSpotResolvedObjectType) \ - oop_field(HotSpotResolvedObjectType, javaClass, "Ljava/lang/Class;") \ + oop_field(HotSpotResolvedObjectType, javaClass, "Ljava/lang/Class;") \ end_class \ start_class(HotSpotResolvedJavaMethod) \ oop_field(HotSpotResolvedJavaMethod, name, "Ljava/lang/String;") \ @@ -59,8 +59,11 @@ start_class(HotSpotJavaType) \ oop_field(HotSpotJavaType, name, "Ljava/lang/String;") \ end_class \ + start_class(InstalledCode) \ + long_field(InstalledCode, address) \ + long_field(InstalledCode, version) \ + end_class \ start_class(HotSpotInstalledCode) \ - long_field(HotSpotInstalledCode, codeBlob) \ int_field(HotSpotInstalledCode, size) \ long_field(HotSpotInstalledCode, codeStart) \ int_field(HotSpotInstalledCode, codeSize) \ @@ -113,7 +116,7 @@ long_field(ExternalCompilationResult, entryPoint) \ end_class \ start_class(CompilationResult) \ - int_field(CompilationResult, frameSize) \ + int_field(CompilationResult, totalFrameSize) \ int_field(CompilationResult, customStackAreaOffset) \ oop_field(CompilationResult, targetCode, "[B") \ oop_field(CompilationResult, assumptions, "Lcom/oracle/graal/api/code/Assumptions;") \ @@ -193,6 +196,7 @@ int_field(BytecodeFrame, numLocks) \ boolean_field(BytecodeFrame, rethrowException) \ boolean_field(BytecodeFrame, duringCall) \ + static_int_field(BytecodeFrame, BEFORE_BCI) \ end_class \ start_class(BytecodePosition) \ oop_field(BytecodePosition, caller, "Lcom/oracle/graal/api/code/BytecodePosition;") \ @@ -201,8 +205,18 @@ end_class \ start_class(Constant) \ oop_field(Constant, kind, "Lcom/oracle/graal/api/meta/Kind;") \ - oop_field(Constant, object, "Ljava/lang/Object;") \ - long_field(Constant, primitive) \ + end_class \ + start_class(PrimitiveConstant) \ + long_field(PrimitiveConstant, primitive) \ + end_class \ + start_class(NullConstant) \ + end_class \ + start_class(HotSpotObjectConstant) \ + oop_field(HotSpotObjectConstant, object, "Ljava/lang/Object;") \ + end_class \ + start_class(HotSpotMetaspaceConstant) \ + long_field(HotSpotMetaspaceConstant, primitive) \ + oop_field(HotSpotMetaspaceConstant, metaspaceObject, "Ljava/lang/Object;") \ end_class \ start_class(Kind) \ char_field(Kind, typeChar) \ @@ -239,7 +253,16 @@ end_class \ start_class(SpeculationLog) \ oop_field(SpeculationLog, lastFailed, "Ljava/lang/Object;") \ - end_class + end_class \ + start_class(HotSpotStackFrameReference) \ + oop_field(HotSpotStackFrameReference, compilerToVM, "Lcom/oracle/graal/hotspot/bridge/CompilerToVM;") \ + long_field(HotSpotStackFrameReference, stackPointer) \ + int_field(HotSpotStackFrameReference, frameNumber) \ + int_field(HotSpotStackFrameReference, bci) \ + long_field(HotSpotStackFrameReference, metaspaceMethod) \ + oop_field(HotSpotStackFrameReference, locals, "[Ljava/lang/Object;") \ + oop_field(HotSpotStackFrameReference, localIsVirtual, "[Z") \ + end_class \ /* end*/ #define START_CLASS(name) \ @@ -291,7 +314,19 @@ oop_store((oop*)addr, x); \ } \ } -COMPILER_CLASSES_DO(START_CLASS, END_CLASS, CHAR_FIELD, INT_FIELD, BOOLEAN_FIELD, LONG_FIELD, FLOAT_FIELD, OOP_FIELD, STATIC_OOP_FIELD) +#define STATIC_INT_FIELD(klassName, name) \ + static int _##name##_offset; \ + static int name() { \ + InstanceKlass* ik = InstanceKlass::cast(klassName::klass()); \ + address addr = ik->static_field_addr(_##name##_offset - InstanceMirrorKlass::offset_of_static_fields()); \ + return *((jint *)addr); \ + } \ + static void set_##name(int x) { \ + InstanceKlass* ik = InstanceKlass::cast(klassName::klass()); \ + address addr = ik->static_field_addr(_##name##_offset - InstanceMirrorKlass::offset_of_static_fields()); \ + *((jint *)addr) = x; \ + } +COMPILER_CLASSES_DO(START_CLASS, END_CLASS, CHAR_FIELD, INT_FIELD, BOOLEAN_FIELD, LONG_FIELD, FLOAT_FIELD, OOP_FIELD, STATIC_OOP_FIELD, STATIC_INT_FIELD) #undef START_CLASS #undef END_CLASS #undef FIELD @@ -302,6 +337,7 @@ #undef FLOAT_FIELD #undef OOP_FIELD #undef STATIC_OOP_FIELD +#undef STATIC_INT_FIELD void compute_offset(int &dest_offset, Klass* klass, const char* name, const char* signature, bool static_field); diff -r 518a7f487c4f -r 9363fffa8b07 src/share/vm/graal/graalVMToCompiler.cpp --- a/src/share/vm/graal/graalVMToCompiler.cpp Wed Apr 23 15:22:20 2014 +0200 +++ b/src/share/vm/graal/graalVMToCompiler.cpp Wed Apr 23 15:48:38 2014 +0200 @@ -49,12 +49,12 @@ } Handle VMToCompiler::truffleRuntime() { - Symbol* name = vmSymbols::com_oracle_graal_truffle_GraalTruffleRuntime(); + Symbol* name = vmSymbols::com_oracle_graal_truffle_hotspot_HotSpotTruffleRuntime(); KlassHandle klass = loadClass(name); JavaValue result(T_OBJECT); JavaCalls::call_static(&result, klass, vmSymbols::makeInstance_name(), vmSymbols::makeInstance_signature(), Thread::current()); - check_pending_exception("Couldn't initialize GraalTruffleRuntime"); + check_pending_exception("Couldn't initialize HotSpotTruffleRuntime"); return Handle((oop) result.get_jobject()); } diff -r 518a7f487c4f -r 9363fffa8b07 src/share/vm/graal/graalVMToCompiler.hpp diff -r 518a7f487c4f -r 9363fffa8b07 src/share/vm/graal/vmStructs_graal.hpp --- a/src/share/vm/graal/vmStructs_graal.hpp Wed Apr 23 15:22:20 2014 +0200 +++ b/src/share/vm/graal/vmStructs_graal.hpp Wed Apr 23 15:48:38 2014 +0200 @@ -31,9 +31,10 @@ #include "graal/graalEnv.hpp" #define VM_STRUCTS_GRAAL(nonstatic_field, static_field) \ - nonstatic_field(ThreadShadow, _pending_deoptimization, int) \ - nonstatic_field(ThreadShadow, _pending_failed_speculation, oop) \ - nonstatic_field(MethodData, _graal_node_count, int) \ + nonstatic_field(InstanceKlass, _graal_node_class, oop) \ + nonstatic_field(ThreadShadow, _pending_deoptimization, int) \ + nonstatic_field(ThreadShadow, _pending_failed_speculation, oop) \ + nonstatic_field(MethodData, _graal_node_count, int) \ #define VM_TYPES_GRAAL(declare_type, declare_toplevel_type) \ diff -r 518a7f487c4f -r 9363fffa8b07 src/share/vm/oops/instanceKlass.cpp --- a/src/share/vm/oops/instanceKlass.cpp Wed Apr 23 15:22:20 2014 +0200 +++ b/src/share/vm/oops/instanceKlass.cpp Wed Apr 23 15:48:38 2014 +0200 @@ -288,6 +288,9 @@ set_init_state(InstanceKlass::allocated); set_init_thread(NULL); set_reference_type(rt); +#ifdef GRAAL + set_graal_node_class(NULL); +#endif set_oop_map_cache(NULL); set_jni_ids(NULL); set_osr_nmethods_head(NULL); @@ -317,6 +320,12 @@ set_layout_helper(Klass::instance_layout_helper(0, true)); } +#ifdef GRAAL +void InstanceKlass::oops_do(OopClosure* cl) { + Klass::oops_do(cl); + cl->do_oop(adr_graal_node_class()); +} +#endif void InstanceKlass::deallocate_methods(ClassLoaderData* loader_data, Array* methods) { @@ -1192,6 +1201,21 @@ JavaValue result(T_VOID); JavaCalls::call(&result, h_method, &args, CHECK); // Static call (no args) } + +#ifdef GRAAL + if (this_oop->is_subtype_of(SystemDictionary::Node_klass())) { + if (this_oop() != SystemDictionary::Node_klass()) { + // Create the NodeClass for a Node subclass. + TempNewSymbol sig = SymbolTable::new_symbol("(Ljava/lang/Class;)Lcom/oracle/graal/graph/NodeClass;", CHECK); + JavaValue result(T_OBJECT); + JavaCalls::call_static(&result, SystemDictionary::NodeClass_klass(), vmSymbols::get_name(), sig, this_oop->java_mirror(), CHECK); + this_oop->set_graal_node_class((oop) result.get_jobject()); + } else { + // A NodeClass cannot be created for Node due to checks in + // NodeClass.FieldScanner.scanField() + } + } +#endif } @@ -2254,6 +2278,10 @@ } init_implementor(); +#ifdef GRAAL + set_graal_node_class(NULL); +#endif + constants()->remove_unshareable_info(); for (int i = 0; i < methods()->length(); i++) { diff -r 518a7f487c4f -r 9363fffa8b07 src/share/vm/oops/instanceKlass.hpp --- a/src/share/vm/oops/instanceKlass.hpp Wed Apr 23 15:22:20 2014 +0200 +++ b/src/share/vm/oops/instanceKlass.hpp Wed Apr 23 15:48:38 2014 +0200 @@ -241,6 +241,10 @@ Thread* _init_thread; // Pointer to current thread doing initialization (to handle recusive initialization) int _vtable_len; // length of Java vtable (in words) int _itable_len; // length of Java itable (in words) +#ifdef GRAAL + // com/oracle/graal/graph/NodeClass instance mirroring this class + oop _graal_node_class; +#endif OopMapCache* volatile _oop_map_cache; // OopMapCache for all methods in the klass (allocated lazily) MemberNameTable* _member_names; // Member names JNIid* _jni_ids; // First JNI identifier for static fields in this class @@ -745,6 +749,16 @@ void call_class_initializer(TRAPS); void set_initialization_state_and_notify(ClassState state, TRAPS); +#ifdef GRAAL + // Graal com.oracle.graal.graph.NodeClass mirror + oop graal_node_class() { return _graal_node_class; } + void set_graal_node_class(oop m) { klass_oop_store(&_graal_node_class, m); } + oop* adr_graal_node_class() { return (oop*)&this->_graal_node_class; } + + // GC support + virtual void oops_do(OopClosure* cl); +#endif + // OopMapCache support OopMapCache* oop_map_cache() { return _oop_map_cache; } void set_oop_map_cache(OopMapCache *cache) { _oop_map_cache = cache; } diff -r 518a7f487c4f -r 9363fffa8b07 src/share/vm/oops/klass.hpp --- a/src/share/vm/oops/klass.hpp Wed Apr 23 15:22:20 2014 +0200 +++ b/src/share/vm/oops/klass.hpp Wed Apr 23 15:48:38 2014 +0200 @@ -298,10 +298,6 @@ static ByteSize modifier_flags_offset() { return in_ByteSize(offset_of(Klass, _modifier_flags)); } static ByteSize layout_helper_offset() { return in_ByteSize(offset_of(Klass, _layout_helper)); } static ByteSize access_flags_offset() { return in_ByteSize(offset_of(Klass, _access_flags)); } -#ifdef GRAAL - static ByteSize next_sibling_offset() { return in_ByteSize(offset_of(Klass, _next_sibling)); } - static ByteSize subklass_offset() { return in_ByteSize(offset_of(Klass, _subklass)); } -#endif // Unpacking layout_helper: enum { diff -r 518a7f487c4f -r 9363fffa8b07 src/share/vm/oops/method.cpp --- a/src/share/vm/oops/method.cpp Wed Apr 23 15:22:20 2014 +0200 +++ b/src/share/vm/oops/method.cpp Wed Apr 23 15:48:38 2014 +0200 @@ -216,7 +216,7 @@ Thread* myThread = Thread::current(); methodHandle h_this(myThread, this); -#ifdef ASSERT +#if defined(ASSERT) && !defined(GRAAL) bool has_capability = myThread->is_VM_thread() || myThread->is_ConcurrentGC_thread() || myThread->is_GC_task_thread(); diff -r 518a7f487c4f -r 9363fffa8b07 src/share/vm/runtime/arguments.cpp --- a/src/share/vm/runtime/arguments.cpp Wed Apr 23 15:22:20 2014 +0200 +++ b/src/share/vm/runtime/arguments.cpp Wed Apr 23 15:48:38 2014 +0200 @@ -35,7 +35,6 @@ #include "prims/jvmtiExport.hpp" #include "runtime/arguments.hpp" #include "runtime/globals_extension.hpp" -#include "runtime/gpu.hpp" #include "runtime/java.hpp" #include "services/management.hpp" #include "services/memTracker.hpp" @@ -183,7 +182,11 @@ PropertyList_add(&_system_properties, new SystemProperty("java.vm.name", VM_Version::vm_name(), false)); PropertyList_add(&_system_properties, new SystemProperty("java.vm.info", VM_Version::vm_info_string(), true)); #ifdef GRAAL +#ifdef GRAAL_VERSION PropertyList_add(&_system_properties, new SystemProperty("graal.version", GRAAL_VERSION, true)); +#else + PropertyList_add(&_system_properties, new SystemProperty("graal.version", "unknown", true)); +#endif #endif // following are JVMTI agent writeable properties. diff -r 518a7f487c4f -r 9363fffa8b07 src/share/vm/runtime/arguments.hpp --- a/src/share/vm/runtime/arguments.hpp Wed Apr 23 15:22:20 2014 +0200 +++ b/src/share/vm/runtime/arguments.hpp Wed Apr 23 15:48:38 2014 +0200 @@ -264,9 +264,6 @@ static SystemProperty *_java_home; static SystemProperty *_java_class_path; static SystemProperty *_sun_boot_class_path; -#ifdef GRAAL - static SystemProperty *_graal_gpu_isalist; -#endif // Meta-index for knowing what packages are in the boot class path static char* _meta_index_path; diff -r 518a7f487c4f -r 9363fffa8b07 src/share/vm/runtime/deoptimization.cpp --- a/src/share/vm/runtime/deoptimization.cpp Wed Apr 23 15:22:20 2014 +0200 +++ b/src/share/vm/runtime/deoptimization.cpp Wed Apr 23 15:48:38 2014 +0200 @@ -357,7 +357,10 @@ unpack_sp = deoptee.unextended_sp(); #ifdef ASSERT - assert(cb->is_deoptimization_stub() || cb->is_uncommon_trap_stub(), "just checking"); + assert(cb->is_deoptimization_stub() || + cb->is_uncommon_trap_stub() || + strcmp("Stub", cb->name()) == 0, + err_msg("unexpected code blob: %s", cb->name())); #endif #else intptr_t* unpack_sp = stub_frame.sender(&dummy_map).unextended_sp(); @@ -1482,7 +1485,10 @@ #ifdef GRAAL oop installedCode = nm->graal_installed_code(); if (installedCode != NULL) { - oop installedCodeName = HotSpotNmethod::name(installedCode); + oop installedCodeName = NULL; + if (installedCode->is_a(HotSpotNmethod::klass())) { + installedCodeName = HotSpotNmethod::name(installedCode); + } if (installedCodeName != NULL) { tty->print(" (Graal: installedCodeName=%s) ", java_lang_String::as_utf8_string(installedCodeName)); } else { diff -r 518a7f487c4f -r 9363fffa8b07 src/share/vm/runtime/deoptimization.hpp --- a/src/share/vm/runtime/deoptimization.hpp Wed Apr 23 15:22:20 2014 +0200 +++ b/src/share/vm/runtime/deoptimization.hpp Wed Apr 23 15:48:38 2014 +0200 @@ -139,6 +139,8 @@ static void revoke_biases_of_monitors(CodeBlob* cb); #if defined(COMPILER2) || defined(GRAAL) +GRAAL_ONLY(public:) + // Support for restoring non-escaping objects static bool realloc_objects(JavaThread* thread, frame* fr, GrowableArray* objects, TRAPS); static void reassign_type_array_elements(frame* fr, RegisterMap* reg_map, ObjectValue* sv, typeArrayOop obj, BasicType type); diff -r 518a7f487c4f -r 9363fffa8b07 src/share/vm/runtime/gpu.cpp --- a/src/share/vm/runtime/gpu.cpp Wed Apr 23 15:22:20 2014 +0200 +++ b/src/share/vm/runtime/gpu.cpp Wed Apr 23 15:48:38 2014 +0200 @@ -26,11 +26,24 @@ #include "runtime/gpu.hpp" #include "runtime/handles.hpp" -int gpu::_initialized_gpus = 0; +int Gpu::_initialized_gpus_count = 0; +Gpu* Gpu::_initialized_gpus[MAX_GPUS]; -void gpu::initialized_gpu(const char* name) { - _initialized_gpus++; - if (TraceGPUInteraction) { - tty->print_cr("[GPU] registered initialization of %s (total initialized: %d)", name, _initialized_gpus); +void Gpu::initialized_gpu(Gpu* gpu) { + // GPUs are always initialized on the same thread so no need for locking + guarantee(_initialized_gpus_count < MAX_GPUS, "oob"); + _initialized_gpus[_initialized_gpus_count++] = gpu; + if (TraceGPUInteraction) { + tty->print_cr("[GPU] registered initialization of %s (total initialized: %d)", gpu->name(), _initialized_gpus_count); + } +} + +void Gpu::safepoint_event(SafepointEvent event) { + for (int i = 0; i < _initialized_gpus_count; i++) { + if (event == SafepointBegin) { + _initialized_gpus[i]->notice_safepoints(); + } else { + _initialized_gpus[i]->ignore_safepoints(); } + } } diff -r 518a7f487c4f -r 9363fffa8b07 src/share/vm/runtime/gpu.hpp --- a/src/share/vm/runtime/gpu.hpp Wed Apr 23 15:22:20 2014 +0200 +++ b/src/share/vm/runtime/gpu.hpp Wed Apr 23 15:48:38 2014 +0200 @@ -29,21 +29,41 @@ #include "oops/symbol.hpp" #include "utilities/array.hpp" +#define MAX_GPUS 2 + // Defines the interface to the graphics processor(s). -class gpu : AllStatic { +class Gpu : public CHeapObj { private: - static int _initialized_gpus; // number of initialize GPU devices + static int _initialized_gpus_count; + static Gpu* _initialized_gpus[MAX_GPUS]; public: // Notification of a GPU device that has been initialized. - static void initialized_gpu(const char* name); + static void initialized_gpu(Gpu* gpu); // Gets a comma separated list of supported GPU architecture names. static jobject probe_gpus(JNIEnv* env); // Gets the number of GPU devices that have been initialized. - static int initialized_gpus() { return _initialized_gpus; } + static int initialized_gpus() { return _initialized_gpus_count; } + + enum SafepointEvent { + SafepointBegin, + SafepointEnd + }; + + // Called when a safepoint has been activated. + static void safepoint_event(SafepointEvent event); + + // Name of this GPU + virtual const char* name() = 0; + + // Called when a safepoint has been activated. + virtual void notice_safepoints() {}; + + // Called when a safepoint has been deactivated. + virtual void ignore_safepoints() {}; }; #endif // SHARE_VM_RUNTIME_GPU_HPP diff -r 518a7f487c4f -r 9363fffa8b07 src/share/vm/runtime/javaCalls.cpp --- a/src/share/vm/runtime/javaCalls.cpp Wed Apr 23 15:22:20 2014 +0200 +++ b/src/share/vm/runtime/javaCalls.cpp Wed Apr 23 15:48:38 2014 +0200 @@ -412,7 +412,7 @@ if (nm->is_alive()) { ((JavaThread*) THREAD)->set_graal_alternate_call_target(nm->verified_entry_point()); oop graalInstalledCode = nm->graal_installed_code(); - if (graalInstalledCode != NULL && HotSpotNmethod::isExternal(graalInstalledCode)) { + if (graalInstalledCode != NULL && graalInstalledCode->is_a(HotSpotNmethod::klass()) && HotSpotNmethod::isExternal(graalInstalledCode)) { entry_point = GraalCompiler::instance()->get_external_deopt_i2c_entry(); } else { entry_point = method->adapter()->get_i2c_entry(); diff -r 518a7f487c4f -r 9363fffa8b07 src/share/vm/runtime/safepoint.cpp --- a/src/share/vm/runtime/safepoint.cpp Wed Apr 23 15:22:20 2014 +0200 +++ b/src/share/vm/runtime/safepoint.cpp Wed Apr 23 15:48:38 2014 +0200 @@ -39,6 +39,7 @@ #include "runtime/compilationPolicy.hpp" #include "runtime/deoptimization.hpp" #include "runtime/frame.inline.hpp" +#include "runtime/gpu.hpp" #include "runtime/interfaceSupport.hpp" #include "runtime/mutexLocker.hpp" #include "runtime/osThread.hpp" @@ -205,6 +206,12 @@ os::make_polling_page_unreadable(); } +#ifdef GRAAL + if (UseHSAILSafepoints) { + Gpu::safepoint_event(Gpu::SafepointBegin); + } +#endif + // Consider using active_processor_count() ... but that call is expensive. int ncpus = os::processor_count() ; @@ -438,6 +445,12 @@ // Remove safepoint check from interpreter Interpreter::ignore_safepoints(); +#ifdef GRAAL + if (UseHSAILSafepoints) { + Gpu::safepoint_event(Gpu::SafepointEnd); + } +#endif + { MutexLocker mu(Safepoint_lock); diff -r 518a7f487c4f -r 9363fffa8b07 src/share/vm/runtime/vmStructs.cpp --- a/src/share/vm/runtime/vmStructs.cpp Wed Apr 23 15:22:20 2014 +0200 +++ b/src/share/vm/runtime/vmStructs.cpp Wed Apr 23 15:48:38 2014 +0200 @@ -576,6 +576,7 @@ nonstatic_field(ThreadLocalAllocBuffer, _start, HeapWord*) \ nonstatic_field(ThreadLocalAllocBuffer, _top, HeapWord*) \ nonstatic_field(ThreadLocalAllocBuffer, _end, HeapWord*) \ + nonstatic_field(ThreadLocalAllocBuffer, _pf_top, HeapWord*) \ nonstatic_field(ThreadLocalAllocBuffer, _desired_size, size_t) \ nonstatic_field(ThreadLocalAllocBuffer, _refill_waste_limit, size_t) \ static_field(ThreadLocalAllocBuffer, _target_refills, unsigned) \ @@ -2422,6 +2423,7 @@ declare_constant(Method::_force_inline) \ declare_constant(Method::_dont_inline) \ declare_constant(Method::_hidden) \ + declare_constant(Method::nonvirtual_vtable_index) \ \ declare_constant(ConstMethod::_has_linenumber_table) \ declare_constant(ConstMethod::_has_checked_exceptions) \ diff -r 518a7f487c4f -r 9363fffa8b07 test/baseline_whitelist.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/baseline_whitelist.txt Wed Apr 23 15:48:38 2014 +0200 @@ -0,0 +1,19 @@ +com.oracle.graal.jtt.loop.Loop03 +com.oracle.graal.jtt.loop.Loop04 +com.oracle.graal.jtt.loop.Loop08 +com.oracle.graal.jtt.loop.Loop11 +com.oracle.graal.jtt.bytecode.BC_iadd +com.oracle.graal.jtt.bytecode.BC_iadd2 +com.oracle.graal.jtt.bytecode.BC_iadd3 +com.oracle.graal.jtt.bytecode.BC_ifeq_2 +com.oracle.graal.jtt.bytecode.BC_ifeq_3 +com.oracle.graal.jtt.bytecode.BC_ifeq +com.oracle.graal.jtt.bytecode.BC_aload_3 +com.oracle.graal.jtt.bytecode.BC_aload_2 +com.oracle.graal.jtt.bytecode.BC_aload_1 +com.oracle.graal.jtt.bytecode.BC_aload_0 +com.oracle.graal.jtt.bytecode.BC_areturn +com.oracle.graal.jtt.bytecode.BC_freturn +com.oracle.graal.jtt.bytecode.BC_iconst +com.oracle.graal.jtt.bytecode.BC_ireturn +com.oracle.graal.jtt.bytecode.BC_lreturn