changeset 14097:a124cc76cde9

Merge with 1b84e499127b0086271898a1298577d15e0b3101
author Michael Van De Vanter <michael.van.de.vanter@oracle.com>
date Wed, 05 Mar 2014 19:40:15 -0800
parents d0e82d536325 (current diff) 1b84e499127b (diff)
children e7f611868ffb
files GRAAL_AUTHORS README README_GRAAL.txt graal/com.oracle.graal.asm/src/com/oracle/graal/asm/AbstractAssembler.java graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/PTXPhase.java graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILCompilationResult.java graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotSuitesProvider.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotRuntimeInterpreterInterface.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToGPU.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToGPUImpl.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/GraphKit.java graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64CharArrayEqualsOp.java graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64ConvertNode.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/CharArrayEqualsNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleInlining.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleInliningImpl.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/DefaultCallTargetSubstitutions.java graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/FrameFactory.java graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/InlinableCallSite.java graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/InlinedCallSite.java graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/instrument/InstrumentationProbeNode.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/api/ExtensionProcessor.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/ast/CodeTreeVariable.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/SpecializationListenerData.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/JavaName.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/CoreSource.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/CoreSourceSection.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/DefinedNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/InlinableMethodImplementation.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/ReadNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/RubyNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/RubyRootNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/RubyTypes.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/WriteNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/call/BooleanDispatchNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/call/BoxedDispatchNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/call/BoxingDispatchNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/call/CachedBoxedDispatchNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/call/CachedUnboxedDispatchNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/call/CallNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/call/DispatchHeadNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/call/DispatchNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/call/GeneralBoxedDispatchNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/call/GeneralSuperCallNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/call/InlineHeuristic.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/call/InlinedBoxedDispatchNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/call/InlinedUnboxedDispatchNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/call/ProcOrNullNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/call/UnboxedDispatchNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/call/UninitializedBoxingDispatchNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/call/UninitializedDispatchNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/cast/BooleanCastNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/cast/LambdaNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/cast/ProcCastNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/cast/SplatCastNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/cast/StringToRegexpNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/cast/StringToSymbolNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/constants/CachedReadConstantNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/constants/ReadConstantNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/constants/UninitializedReadConstantNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/constants/WriteConstantNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/control/AndNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/control/BreakNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/control/ElidableResultNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/control/EnsureNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/control/FlipFlopNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/control/IfNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/control/NextNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/control/NotNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/control/OrNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/control/RedoNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/control/RescueAnyNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/control/RescueClassesNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/control/RescueNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/control/RescueSplatNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/control/RetryNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/control/ReturnNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/control/SequenceNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/control/TryNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/control/WhileNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/ArrayConcatNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/ArrayCoreMethodNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/ArrayIndexNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/ArrayNodes.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/ArrayPushNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/ArrayRestNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/BasicObjectNodes.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/BignumNodes.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/ClassNodes.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/ComparableNodes.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/ContinuationNodes.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/CoreClass.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/CoreMethod.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/CoreMethodNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/CoreMethodNodeManager.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/DirNodes.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/ExceptionNodes.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/FalseClassNodes.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/FiberNodes.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/FileNodes.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/FixnumNodes.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/FloatNodes.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/HashNodes.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/InterpolatedStringNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/KernelNodes.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/MainNodes.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/MatchDataNodes.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/MathNodes.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/ModuleNodes.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/NilClassNodes.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/ObjectNodes.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/ObjectSpaceNodes.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/ProcNodes.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/ProcessNodes.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/RangeNodes.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/RegexpNodes.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/SignalNodes.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/StringNodes.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/StructNodes.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/SymbolNodes.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/SystemNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/ThreadNodes.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/TimeNodes.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/TrueClassNodes.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/YieldingCoreMethodNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/instrument/MinimalRubyNodeInstrumenter.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/instrument/RubyNodeInstrumenter.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/instrument/RubyProxyNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/literal/BignumLiteralNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/literal/BooleanLiteralNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/literal/FixnumLiteralNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/literal/FloatLiteralNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/literal/HashLiteralNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/literal/NilNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/literal/ObjectLiteralNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/literal/RangeLiteralNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/literal/StringLiteralNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/literal/array/ArrayLiteralNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/literal/array/FixnumArrayLiteralNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/literal/array/ObjectArrayLiteralNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/literal/array/UninitialisedArrayLiteralNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/AddMethodNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/AliasNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/BlockDefinitionNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/CatchNextNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/CatchReturnAsErrorNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/CatchReturnNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/MethodDefinitionNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/ShellResultNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/arguments/BlockDestructureSwitchNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/arguments/CheckArityNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/arguments/ReadAllArgumentsNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/arguments/ReadBlockArgumentNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/arguments/ReadDestructureArgumentNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/arguments/ReadOptionalArgumentNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/arguments/ReadPostArgumentNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/arguments/ReadPreArgumentNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/arguments/ReadRestArgumentNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/locals/FlipFlopStateNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/locals/FrameSlotNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/locals/InitFlipFlopSlotNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/locals/LevelFlipFlopStateNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/locals/LocalFlipFlopStateNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/locals/ReadLevelVariableNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/locals/ReadLocalVariableNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/locals/WriteLevelVariableNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/locals/WriteLocalVariableNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/objects/ClassNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/objects/DefineOrGetClassNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/objects/DefineOrGetModuleNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/objects/OpenModuleNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/objects/ReadClassVariableNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/objects/SelfNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/objects/SingletonClassNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/objects/WriteClassVariableNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/objects/instancevariables/ReadFixnumInstanceVariableNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/objects/instancevariables/ReadFloatInstanceVariableNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/objects/instancevariables/ReadInstanceVariableNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/objects/instancevariables/ReadMissingInstanceVariableNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/objects/instancevariables/ReadObjectInstanceVariableNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/objects/instancevariables/ReadSpecializedInstanceVariableNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/objects/instancevariables/UninitializedReadInstanceVariableNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/objects/instancevariables/UninitializedWriteInstanceVariableNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/objects/instancevariables/WriteFixnumInstanceVariableNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/objects/instancevariables/WriteFloatInstanceVariableNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/objects/instancevariables/WriteInstanceVariableNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/objects/instancevariables/WriteObjectInstanceVariableNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/objects/instancevariables/WriteSpecializedInstanceVariableNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/yield/GeneralYieldDispatchNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/yield/InlinedYieldDispatchNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/yield/UninitializedYieldDispatchNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/yield/YieldDispatchNode.java graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/yield/YieldNode.java graal/com.oracle.truffle.ruby.parser/src/com/oracle/truffle/ruby/parser/DeadNode.java graal/com.oracle.truffle.ruby.parser/src/com/oracle/truffle/ruby/parser/JRubyParser.java graal/com.oracle.truffle.ruby.parser/src/com/oracle/truffle/ruby/parser/MethodTranslator.java graal/com.oracle.truffle.ruby.parser/src/com/oracle/truffle/ruby/parser/ModuleTranslator.java graal/com.oracle.truffle.ruby.parser/src/com/oracle/truffle/ruby/parser/RubyFrameTypeConversion.java graal/com.oracle.truffle.ruby.parser/src/com/oracle/truffle/ruby/parser/Translator.java graal/com.oracle.truffle.ruby.parser/src/com/oracle/truffle/ruby/parser/TranslatorEnvironment.java graal/com.oracle.truffle.ruby.runtime/.checkstyle_checks.xml graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/InputReader.java graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/NilPlaceholder.java graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/RubyArguments.java graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/RubyContext.java graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/RubyParser.java graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/RubyParserResult.java graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/ShellResult.java graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/UndefinedPlaceholder.java graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/configuration/Configuration.java graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/configuration/ConfigurationBuilder.java graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/control/BreakException.java graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/control/ContinuationReturnException.java graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/control/ExceptionTranslator.java graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/control/NextException.java graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/control/RaiseException.java graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/control/RedoException.java graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/control/RetryException.java graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/control/ReturnException.java graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/control/ThrowException.java graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/CoreLibrary.java graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/GeneralConversions.java graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/RubyBignum.java graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/RubyBinding.java graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/RubyClass.java graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/RubyContinuation.java graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/RubyException.java graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/RubyFalseClass.java graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/RubyFiber.java graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/RubyFile.java graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/RubyFixnum.java graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/RubyFloat.java graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/RubyHash.java graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/RubyMatchData.java graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/RubyModule.java graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/RubyNilClass.java graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/RubyObject.java graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/RubyProc.java graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/RubyRegexp.java graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/RubyString.java graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/RubySymbol.java graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/RubyThread.java graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/RubyTime.java graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/RubyTrueClass.java graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/StringFormatter.java graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/array/ArrayStore.java graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/array/ArrayUtilities.java graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/array/BaseArrayStore.java graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/array/EmptyArrayStore.java graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/array/FixnumArrayStore.java graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/array/FixnumImmutablePairArrayStore.java graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/array/GeneraliseArrayStoreException.java graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/array/ObjectArrayStore.java graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/array/ObjectImmutablePairArrayStore.java graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/array/RubyArray.java graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/range/FixnumRange.java graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/range/ObjectRange.java graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/range/RubyRange.java graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/debug/RubyProbe.java graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/debug/RubyTraceProbe.java graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/lookup/LookupFork.java graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/lookup/LookupNode.java graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/lookup/LookupTerminal.java graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/methods/Arity.java graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/methods/CallTargetMethodImplementation.java graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/methods/MethodImplementation.java graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/methods/RubyMethod.java graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/methods/UniqueMethodIdentifier.java graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/methods/Visibility.java graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/objects/FixnumStorageLocation.java graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/objects/FloatStorageLocation.java graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/objects/GeneralizeStorageLocationException.java graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/objects/ObjectLayout.java graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/objects/ObjectStorageLocation.java graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/objects/PrimitiveStorageLocation.java graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/objects/RubyBasicObject.java graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/objects/StorageLocation.java graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/objects/Unboxable.java graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/subsystems/AtExitManager.java graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/subsystems/FeatureManager.java graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/subsystems/FiberManager.java graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/subsystems/ObjectSpaceManager.java graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/subsystems/ThreadManager.java graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/subsystems/TraceManager.java graal/com.oracle.truffle.ruby.shell/src/com/oracle/truffle/ruby/shell/CommandLineOptions.java graal/com.oracle.truffle.ruby.shell/src/com/oracle/truffle/ruby/shell/CommandLineParser.java graal/com.oracle.truffle.ruby.shell/src/com/oracle/truffle/ruby/shell/Shell.java graal/com.oracle.truffle.ruby.test/specs/README graal/com.oracle.truffle.ruby.test/specs/rubytruffle graal/com.oracle.truffle.ruby.test/specs/rubytruffle.mspec graal/com.oracle.truffle.ruby.test/specs/tags/command_line/dash_a_tags.txt graal/com.oracle.truffle.ruby.test/specs/tags/command_line/dash_d_tags.txt graal/com.oracle.truffle.ruby.test/specs/tags/command_line/dash_e_tags.txt graal/com.oracle.truffle.ruby.test/specs/tags/command_line/dash_n_tags.txt graal/com.oracle.truffle.ruby.test/specs/tags/command_line/dash_p_tags.txt graal/com.oracle.truffle.ruby.test/specs/tags/command_line/dash_r_tags.txt graal/com.oracle.truffle.ruby.test/specs/tags/command_line/dash_s_tags.txt graal/com.oracle.truffle.ruby.test/specs/tags/command_line/dash_upper_e_tags.txt graal/com.oracle.truffle.ruby.test/specs/tags/command_line/dash_upper_f_tags.txt graal/com.oracle.truffle.ruby.test/specs/tags/command_line/dash_upper_i_tags.txt graal/com.oracle.truffle.ruby.test/specs/tags/command_line/dash_upper_u_tags.txt graal/com.oracle.truffle.ruby.test/specs/tags/command_line/dash_upper_w_tags.txt graal/com.oracle.truffle.ruby.test/specs/tags/command_line/dash_v_tags.txt graal/com.oracle.truffle.ruby.test/specs/tags/command_line/dash_w_tags.txt graal/com.oracle.truffle.ruby.test/specs/tags/command_line/dash_x_tags.txt graal/com.oracle.truffle.ruby.test/specs/tags/command_line/error_message_tags.txt graal/com.oracle.truffle.ruby.test/specs/tags/language/BEGIN_tags.txt graal/com.oracle.truffle.ruby.test/specs/tags/language/alias_tags.txt graal/com.oracle.truffle.ruby.test/specs/tags/language/array_tags.txt graal/com.oracle.truffle.ruby.test/specs/tags/language/block_tags.txt graal/com.oracle.truffle.ruby.test/specs/tags/language/break_tags.txt graal/com.oracle.truffle.ruby.test/specs/tags/language/case_tags.txt graal/com.oracle.truffle.ruby.test/specs/tags/language/class_tags.txt graal/com.oracle.truffle.ruby.test/specs/tags/language/class_variable_tags.txt graal/com.oracle.truffle.ruby.test/specs/tags/language/constants_tags.txt graal/com.oracle.truffle.ruby.test/specs/tags/language/def_tags.txt graal/com.oracle.truffle.ruby.test/specs/tags/language/defined_tags.txt graal/com.oracle.truffle.ruby.test/specs/tags/language/encoding_tags.txt graal/com.oracle.truffle.ruby.test/specs/tags/language/ensure_tags.txt graal/com.oracle.truffle.ruby.test/specs/tags/language/execution_tags.txt graal/com.oracle.truffle.ruby.test/specs/tags/language/file_tags.txt graal/com.oracle.truffle.ruby.test/specs/tags/language/for_tags.txt graal/com.oracle.truffle.ruby.test/specs/tags/language/hash_tags.txt graal/com.oracle.truffle.ruby.test/specs/tags/language/line_tags.txt graal/com.oracle.truffle.ruby.test/specs/tags/language/literal_lambda_tags.txt graal/com.oracle.truffle.ruby.test/specs/tags/language/magic_comment_tags.txt graal/com.oracle.truffle.ruby.test/specs/tags/language/match_tags.txt graal/com.oracle.truffle.ruby.test/specs/tags/language/metaclass_tags.txt graal/com.oracle.truffle.ruby.test/specs/tags/language/module_tags.txt graal/com.oracle.truffle.ruby.test/specs/tags/language/next_tags.txt graal/com.oracle.truffle.ruby.test/specs/tags/language/precedence_tags.txt graal/com.oracle.truffle.ruby.test/specs/tags/language/predefined/data_tags.txt graal/com.oracle.truffle.ruby.test/specs/tags/language/predefined_tags.txt graal/com.oracle.truffle.ruby.test/specs/tags/language/private_tags.txt graal/com.oracle.truffle.ruby.test/specs/tags/language/proc_tags.txt graal/com.oracle.truffle.ruby.test/specs/tags/language/redo_tags.txt graal/com.oracle.truffle.ruby.test/specs/tags/language/regexp/anchors_tags.txt graal/com.oracle.truffle.ruby.test/specs/tags/language/regexp/back-references_tags.txt graal/com.oracle.truffle.ruby.test/specs/tags/language/regexp/character_classes_tags.txt graal/com.oracle.truffle.ruby.test/specs/tags/language/regexp/encoding_tags.txt graal/com.oracle.truffle.ruby.test/specs/tags/language/regexp/escapes_tags.txt graal/com.oracle.truffle.ruby.test/specs/tags/language/regexp/grouping_tags.txt graal/com.oracle.truffle.ruby.test/specs/tags/language/regexp/interpolation_tags.txt graal/com.oracle.truffle.ruby.test/specs/tags/language/regexp/modifiers_tags.txt graal/com.oracle.truffle.ruby.test/specs/tags/language/regexp/repetition_tags.txt graal/com.oracle.truffle.ruby.test/specs/tags/language/regexp_tags.txt graal/com.oracle.truffle.ruby.test/specs/tags/language/rescue_tags.txt graal/com.oracle.truffle.ruby.test/specs/tags/language/retry_tags.txt graal/com.oracle.truffle.ruby.test/specs/tags/language/return_tags.txt graal/com.oracle.truffle.ruby.test/specs/tags/language/send_tags.txt graal/com.oracle.truffle.ruby.test/specs/tags/language/singleton_class_tags.txt graal/com.oracle.truffle.ruby.test/specs/tags/language/splat_tags.txt graal/com.oracle.truffle.ruby.test/specs/tags/language/string_tags.txt graal/com.oracle.truffle.ruby.test/specs/tags/language/super_tags.txt graal/com.oracle.truffle.ruby.test/specs/tags/language/symbol_tags.txt graal/com.oracle.truffle.ruby.test/specs/tags/language/throw_tags.txt graal/com.oracle.truffle.ruby.test/specs/tags/language/undef_tags.txt graal/com.oracle.truffle.ruby.test/specs/tags/language/until_tags.txt graal/com.oracle.truffle.ruby.test/specs/tags/language/variables_tags.txt graal/com.oracle.truffle.ruby.test/specs/tags/language/while_tags.txt graal/com.oracle.truffle.ruby.test/specs/tags/language/yield_tags.txt graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/RubyTests.java graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/core/ArrayTests.java graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/core/BignumTests.java graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/core/BoolTests.java graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/core/ContinuationTests.java graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/core/FiberTests.java graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/core/FixnumTests.java graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/core/FloatTests.java graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/core/HashTests.java graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/core/IntegerTests.java graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/core/KernelTests.java graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/core/MathTests.java graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/core/ModuleTests.java graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/core/ObjectSpaceTests.java graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/core/ObjectTests.java graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/core/ProcTests.java graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/core/RangeTests.java graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/core/RegexpTests.java graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/core/StringTests.java graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/core/SymbolTests.java graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/core/ThreadTests.java graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/language/AndTests.java graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/language/BlockTests.java graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/language/CaseTests.java graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/language/ClassLocalTests.java graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/language/ClassTests.java graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/language/ConstantTests.java graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/language/ForTests.java graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/language/GlobalVariableTests.java graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/language/IfTests.java graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/language/InterpolatedStringTests.java graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/language/LocalTests.java graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/language/MethodTests.java graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/language/ModuleTests.java graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/language/MultipleAssignmentTests.java graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/language/OrTests.java graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/language/PolymorphismTests.java graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/language/RaiseRescueTests.java graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/language/RedefinitionTests.java graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/language/ShortcutTests.java graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/language/SpecialVariableTests.java graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/language/UntilTests.java graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/language/WhileTests.java graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/runtime/ObjectLayoutTests.java graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/AbstractTest.java graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/AddTest.java graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/BuiltinsTest.java graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/CallTest.java graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/ComparisonTest.java graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/DivTest.java graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/FibonacciTest.java graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/LoopPrintTest.java graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/LoopTest.java graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/MulTest.java graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/SplitOutputStream.java graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/SubTest.java graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/SumTest.java graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/TernaryTest.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/SLNode.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/SLNodeFactory.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/SLScript.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/SLTypes.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/SimpleLanguage.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/BuiltinNode.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/DefaultBuiltins.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/PrintBuiltin.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/TimeBuiltin.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/ArgumentsNode.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/ArithmeticNode.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/BigIntegerLiteralNode.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/BinaryNode.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/BlockNode.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/BreakException.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/BreakNode.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/CallNode.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/ConditionNode.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/ContinueException.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/ContinueNode.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/FrameSlotNode.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/FunctionBodyNode.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/FunctionRootNode.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/IfNode.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/IntegerLiteralNode.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/LessThanNode.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/LogicalAndNode.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/NullLiteralNode.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/ReadArgumentNode.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/ReadFunctionNode.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/ReadLocalNode.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/ReadUninitializedNode.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/ReturnException.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/ReturnNode.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/StatementNode.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/StringLiteralNode.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/TernaryNode.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/TypedNode.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/WhileNode.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/WriteLocalNode.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/ParserUtils.java src/gpu/ptx/vm/ptxKernelArguments.cpp src/gpu/ptx/vm/ptxKernelArguments.hpp src/os_gpu/bsd_ptx/vm/gpu_bsd.cpp src/os_gpu/bsd_ptx/vm/gpu_bsd.hpp src/os_gpu/linux_ptx/vm/gpu_linux.cpp src/os_gpu/linux_ptx/vm/gpu_linux.hpp src/os_gpu/windows_hsail/vm/gpu_windows.cpp src/os_gpu/windows_hsail/vm/gpu_windows.hpp src/share/vm/graal/graalCompilerToGPU.cpp src/share/vm/graal/graalCompilerToGPU.hpp
diffstat 1033 files changed, 21388 insertions(+), 45199 deletions(-) [+]
line wrap: on
line diff
--- a/.hgignore	Sun Feb 23 17:00:35 2014 -0800
+++ b/.hgignore	Wed Mar 05 19:40:15 2014 -0800
@@ -85,5 +85,3 @@
 agent/build/*
 agent/make/filelist
 agent/make/sa17.tar.gz
-graal/com.oracle.truffle.ruby.test/specs/mspec
-graal/com.oracle.truffle.ruby.test/specs/rubyspec
--- a/.hgtags	Sun Feb 23 17:00:35 2014 -0800
+++ b/.hgtags	Wed Mar 05 19:40:15 2014 -0800
@@ -403,3 +403,4 @@
 05fedd51e40da22c9460bf17c7185889e435db3d hs25-b62
 fca262db9c4309f99d2f5542ab0780e45c2f1578 jdk8-b120
 41f4cad94c581034d4c427d2aaabcc20f26342d0 hs25-b63
+b124e22eb772806c13d942cc110de38da0108147 graal-0.1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/AUTHORS.md	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,25 @@
+# Graal Authors
+
+The GraalVM is based on the source code of HotSpot. The following authors have contributed to the Graal-specific part of the source base:
+
+* Tom Deneau (tdeneau)
+* Gilles Duboscq (gdub)
+* Matthias Grimmer (mgrimmer)
+* Peter Hofer
+* Christian Haeubl (chaeubl)
+* Michael Haupt (mhaupt)
+* Christian Humer (chumer)
+* Morris Meyer (morris)
+* Roland Schatz
+* Doug Simon (dnsimon)
+* Lukas Stadler (lstadler)
+* Roland Schatz (rschatz)
+* Alexander Stipsits
+* Katrin Strassl
+* Christian Thalinger (twisti)
+* Vasanth Venkatachalam (vvenkat)
+* Christian Wimmer (cwimmer)
+* Christian Wirth (cwirth)
+* Andreas Woess (aw)
+* Thomas Wuerthinger (thomaswue)
+* Bharadwaj Yadavalli (bharadwaj)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/CHANGELOG.md	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,25 @@
+# GraalVM Changelog
+
+## `tip`
+### Graal
+* New methods for querying memory usage of individual objects and object graphs in Graal API (MetaAccessProvider#getMemorySize, MetaUtil#getMemorySizeRecursive).
+* ...
+
+### Truffle
+* ...
+
+## Version 0.1
+5-Feb-2014, [Repository Revision](http://hg.openjdk.java.net/graal/graal/rev/b124e22eb772)
+
+### Graal
+
+* Initial version of a dynamic Java compiler written in Java.
+* Support for multiple co-existing GPU backends ([GRAAL-1](https://bugs.openjdk.java.net/browse/GRAAL-1)).
+* Fixed a compiler bug when running RuneScape ([GRAAL-7](https://bugs.openjdk.java.net/browse/GRAAL-7)).
+* Bug fixes ([GRAAL-4](https://bugs.openjdk.java.net/browse/GRAAL-4), [GRAAL-5](https://bugs.openjdk.java.net/browse/GRAAL-5)).
+
+### Truffle
+
+* Initial version of a multi-language framework on top of Graal.
+* Update of the [Truffle Inlining API](http://mail.openjdk.java.net/pipermail/graal-dev/2014-January/001516.html).
+
--- a/GRAAL_AUTHORS	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,12 +0,0 @@
-Gilles Duboscq (gdub)
-Peter Hofer
-Christian Haeubl (chaeubl)
-Christian Humer (chumer)
-Roland Schatz
-Doug Simon (dnsimon)
-Lukas Stadler (lstadler)
-Alexander Stipsits
-Katrin Strassl
-Christian Wimmer (cwimmer)
-Andreas Woess (aw)
-Thomas Wuerthinger (thomaswue)
--- a/README	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,14 +0,0 @@
-README:
-  This file should be located at the top of the hotspot Mercurial repository.
-
-  See http://openjdk.java.net/ for more information about the OpenJDK.
-
-  See ../README-builds.html for complete details on build machine requirements.
-
-Simple Build Instructions:
-
-    cd make && gnumake
-     
-  The files that will be imported into the jdk build will be in the "build"
-  directory.
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/README.md	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,82 @@
+## Building Graal
+
+There is a Python script in mxtool/mx.py that simplifies working with the code
+base. It requires Python 2.7. While you can run this script by using an absolute path,
+it's more convenient to add graal/mxtool to your PATH environment variable so that the
+'mx' helper script can be used. The following instructions in this file assume this
+setup.
+
+Building both the Java and C++ source code comprising the Graal VM
+can be done with the following simple command.
+
+```
+% mx build
+```
+
+There are a number of VM configurations supported by mx which can
+be explicitly specified using the --vm option. However, you'll typically
+want one of these VM configurations:
+
+1. The 'server' configuration is a standard HotSpot VM that includes the
+   runtime support for Graal but uses the existing compilers for normal
+   compilation (e.g., when the interpreter threshold is hit for a method).
+   Compilation with Graal is only done by explicit requests to the
+   Graal API. This is how Truffle uses Graal.
+   
+2. The 'graal' configuration is a VM where all compilation is performed
+   by Graal and no other compilers are built into the VM binary. This
+   VM will bootstrap Graal itself at startup unless the -XX:-BootstrapGraal
+   VM option is given.   
+
+Unless you use the --vm option with the build command, you will be presented
+with a dialogue to choose one of the above VM configurations for the build
+as well as have the option to make it your default for subsequent commands
+that need a VM specified.
+
+To build the debug or fastdebug builds:
+
+```
+% mx --vmbuild debug build
+% mx --vmbuild fastdebug build
+```
+
+## Running Graal
+
+To run the VM, use 'mx vm' in place of the standard 'java' command:
+
+```
+% mx vm ...
+```
+
+To select the fastdebug or debug builds of the VM:
+
+```
+% mx --vmbuild fastdebug vm ...
+% mx --vmbuild debug vm ...
+```
+
+## Other VM Configurations
+
+In addition to the VM configurations described above, there are
+VM configurations that omit all VM support for Graal:
+
+```
+% mx --vm server-nograal build
+% mx --vm server-nograal vm -version
+java version "1.7.0_25"
+Java(TM) SE Runtime Environment (build 1.7.0_25-b15)
+OpenJDK 64-Bit Server VM (build 25.0-b43-internal, mixed mode)
+```
+
+```
+% mx --vm client-nograal build
+% mx --vm client-nograal vm -version
+java version "1.7.0_25"
+Java(TM) SE Runtime Environment (build 1.7.0_25-b15)
+OpenJDK 64-Bit Client VM (build 25.0-b43-internal, mixed mode)
+```
+
+These configurations aim to match as closely as possible the
+VM(s) included in the OpenJDK binaries one can download.
+ No newline at end of file
+
--- a/README_GRAAL.txt	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,70 +0,0 @@
-Building Graal
---------------
-There is a Python script in mxtool/mx.py that simplifies working with the code
-base. It requires Python 2.7. While you can run this script by using an absolute path,
-it's more convenient to add graal/mxtool to your PATH environment variable so that the
-'mx' helper script can be used. The following instructions in this file assume this
-setup.
-
-Building both the Java and C++ source code comprising the Graal VM
-can be done with the following simple command.
-
-% mx build
-
-There are a number of VM configurations supported by mx which can
-be explicitly specified using the --vm option. However, you'll typically
-want one of these VM configurations:
-
-1. The 'server' configuration is a standard HotSpot VM that includes the
-   runtime support for Graal but uses the existing compilers for normal
-   compilation (e.g., when the interpreter threshold is hit for a method).
-   Compilation with Graal is only done by explicit requests to the
-   Graal API. This is how Truffle uses Graal.
-   
-2. The 'graal' configuration is a VM where all compilation is performed
-   by Graal and no other compilers are built into the VM binary. This
-   VM will bootstrap Graal itself at startup unless the -XX:-BootstrapGraal
-   VM option is given.   
-
-Unless you use the --vm option with the build command, you will be presented
-with a dialogue to choose one of the above VM configurations for the build
-as well as have the option to make it your default for subsequent commands
-that need a VM specified.
-
-To build the debug or fastdebug builds:
-
-% mx --vmbuild debug build
-% mx --vmbuild fastdebug build
-
-Running Graal
--------------
-
-To run the VM, use 'mx vm' in place of the standard 'java' command:
-
-% mx vm ...
-
-To select the fastdebug or debug builds of the VM:
-
-% mx --vmbuild fastdebug vm ...
-% mx --vmbuild debug vm ...
-
-Other VM Configurations
------------------------
-
-In addition to the VM configurations described above, there are
-VM configurations that omit all VM support for Graal:
-
-% mx --vm server-nograal build
-% mx --vm server-nograal vm -version
-java version "1.7.0_25"
-Java(TM) SE Runtime Environment (build 1.7.0_25-b15)
-OpenJDK 64-Bit Server VM (build 25.0-b43-internal, mixed mode)
-
-% mx --vm client-nograal build
-% mx --vm client-nograal vm -version
-java version "1.7.0_25"
-Java(TM) SE Runtime Environment (build 1.7.0_25-b15)
-OpenJDK 64-Bit Cleint VM (build 25.0-b43-internal, mixed mode)
-
-These configurations aim to match as closely as possible the
-VM(s) included in the OpenJDK binaries one can download.
\ No newline at end of file
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/Architecture.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/Architecture.java	Wed Mar 05 19:40:15 2014 -0800
@@ -172,31 +172,6 @@
     }
 
     /**
-     * Determine the maximum vector length supported for vector operations on values of a given
-     * {@link Kind}.
-     * 
-     * @param kind the kind of the individual vector elements
-     * @return the maximum supported vector size
-     */
-    public int getMaxVectorLength(Kind kind) {
-        return 1;
-    }
-
-    /**
-     * Get a natively supported vector length for breaking down some vector operation on a constant
-     * length vector.
-     * 
-     * @param kind the kind of the individual vector elements
-     * @param maxLength the maximum length that should be returned
-     * @param arithmetic the arithmetic operation for which the vector size should be determined, or
-     *            null if no arithmetic needs to be performed on the vector
-     * @return a supported vector size, but at most {@code maxLength}
-     */
-    public int getSupportedVectorLength(Kind kind, int maxLength, Class<? extends ArithmeticOperation> arithmetic) {
-        return 1;
-    }
-
-    /**
      * Gets the size in bytes of the specified kind for this target.
      * 
      * @param kind the kind for which to get the size
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/BytecodeFrame.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/BytecodeFrame.java	Wed Mar 05 19:40:15 2014 -0800
@@ -119,6 +119,24 @@
     }
 
     /**
+     * Ensure that the frame state is formatted as expected by the JVM, with null or Illegal in the
+     * slot following a double word item. This should really be checked in FrameState itself but
+     * because of Word type rewriting and alternative backends that can't be done.
+     */
+    public boolean validateFormat() {
+        for (int i = 0; i < numLocals + numStack; i++) {
+            if (values[i] != null) {
+                Kind kind = values[i].getKind();
+                if (kind == Kind.Long || kind == Kind.Double) {
+                    assert values.length > i + 1 : String.format("missing second word %s", this);
+                    assert values[i + 1] == null || values[i + 1].getKind() == Kind.Illegal;
+                }
+            }
+        }
+        return true;
+    }
+
+    /**
      * Gets the value representing the specified local variable.
      * 
      * @param i the local variable index
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CompilationResult.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CompilationResult.java	Wed Mar 05 19:40:15 2014 -0800
@@ -288,6 +288,14 @@
             }
         }
 
+        public int getAlignment() {
+            if (externalData instanceof ConstantData) {
+                return ((ConstantData) externalData).getAlignment();
+            } else {
+                return 0;
+            }
+        }
+
         public String getDataString() {
             if (inlineData != null) {
                 return inlineData.toString();
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/ExternalCompilationResult.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/ExternalCompilationResult.java	Wed Mar 05 19:40:15 2014 -0800
@@ -60,4 +60,11 @@
     public long getEntryPoint() {
         return entryPoint;
     }
+
+    /**
+     * Gets the {@linkplain #getTargetCode() code} in this compilation result as a string.
+     */
+    public String getCodeString() {
+        return new String(getTargetCode(), 0, getTargetCodeSize());
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/NativeFunctionHandle.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.api.code;
+
+/**
+ * A handle that can be used to {@linkplain #call(Object[]) call} a native function.
+ */
+public interface NativeFunctionHandle {
+
+    /**
+     * Calls the native function.
+     * <p>
+     * The caller is responsible for ensuring {@code args} comply with the platform ABI (e.g. <a
+     * href="http://www.uclibc.org/docs/psABI-x86_64.pdf"> Unix AMD64 ABI</a>). If the library
+     * function has struct parameters, the fields of the struct must be passed as individual
+     * arguments.
+     * 
+     * @param args the arguments that will be passed to the native function
+     * @return boxed return value of the function call
+     */
+    Object call(Object... args);
+
+    /**
+     * Returns the installed code of the call stub for the native function call.
+     * 
+     * @return the installed code of the native call stub
+     */
+    InstalledCode getCallStub();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/NativeFunctionInterface.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.api.code;
+
+/**
+ * Interface to get a {@linkplain NativeFunctionHandle handle} or {@linkplain NativeFunctionPointer
+ * pointer} to a native function or a {@linkplain NativeLibraryHandle handle} to an open native
+ * library.
+ */
+public interface NativeFunctionInterface {
+
+    /**
+     * 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
+     */
+    NativeLibraryHandle getLibraryHandle(String libPath);
+
+    /**
+     * Determines if the underlying platform/runtime supports the notion of a default library search
+     * path. For example, on *nix systems, this is typically defined by the {@code LD_LIBRARY_PATH}
+     * environment variable.
+     */
+    boolean isDefaultLibrarySearchSupported();
+
+    /**
+     * 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
+     * @throws UnsatisfiedLinkError if the function could not be resolved
+     */
+    NativeFunctionPointer getFunctionPointer(NativeLibraryHandle[] libraries, String name);
+
+    /**
+     * 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
+     * @param argumentTypes the types of the arguments
+     * @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);
+
+    /**
+     * 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);
+
+    /**
+     * 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
+     * @param argumentTypes the types of the arguments
+     * @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);
+
+    /**
+     * 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
+     * @return the function handle of the native function
+     * @throws UnsatisfiedLinkError if default library searching is not
+     *             {@linkplain #isDefaultLibrarySearchSupported() supported} or if the function
+     *             could not be resolved
+     */
+    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}
+     */
+    NativeFunctionPointer getNativeFunctionPointerFromRawValue(long rawValue);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/NativeFunctionPointer.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.api.code;
+
+/**
+ * An opaque representation of a native function pointer.
+ * <p>
+ * Use {@code NativeFunctionInterface#getFunctionHandle(NativeFunctionPointer, Class, Class...)} to
+ * get a handle enabling the native function to be {@linkplain NativeFunctionHandle#call(Object...)
+ * called}.
+ */
+public interface NativeFunctionPointer {
+
+    /**
+     * Returns the name of the function.
+     * 
+     * @return name of the function
+     */
+    String getName();
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/NativeLibraryHandle.java	Wed Mar 05 19:40:15 2014 -0800
@@ -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.api.code;
+
+/**
+ * An opaque representation of a native library handle. A handle is obtained via
+ * {@link NativeFunctionInterface#getLibraryHandle(String)}. A handle is used to resolve a string to
+ * a {@linkplain NativeFunctionInterface#getFunctionHandle(String, Class, Class...) handle} or
+ * {@linkplain NativeFunctionInterface#getFunctionPointer(NativeLibraryHandle[], String) pointer}.
+ */
+public interface NativeLibraryHandle {
+    /**
+     * Gets a name for this library. This may be the path for the file from which the library was
+     * loaded.
+     */
+    String getName();
+}
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/ReferenceMap.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/ReferenceMap.java	Wed Mar 05 19:40:15 2014 -0800
@@ -86,6 +86,29 @@
         return frameRefMap != null && frameRefMap.size() > 0;
     }
 
+    public interface Iterator {
+        void register(int idx, boolean narrow);
+
+        void stackSlot(int idx, boolean narrow1, boolean narrow2);
+    }
+
+    public void iterate(Iterator iterator) {
+        if (hasRegisterRefMap()) {
+            for (int i = 0; i < registerRefMap.size() / 2; i++) {
+                if (registerRefMap.get(2 * i)) {
+                    iterator.register(i, registerRefMap.get(2 * i + 1));
+                }
+            }
+        }
+        if (hasFrameRefMap()) {
+            for (int i = 0; i < frameRefMap.size() / 3; i++) {
+                if (frameRefMap.get(3 * i)) {
+                    iterator.stackSlot(i, frameRefMap.get(3 * i + 1), frameRefMap.get(3 * i + 2));
+                }
+            }
+        }
+    }
+
     private static class NumberedRefMapFormatter implements RefMapFormatter {
 
         public String formatStackSlot(int frameRefMapIndex) {
--- /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/FieldUniverse.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.api.meta.test;
+
+import java.lang.reflect.*;
+import java.util.*;
+
+import com.oracle.graal.api.meta.*;
+
+/**
+ * Context for field related api.meta tests.
+ */
+public class FieldUniverse extends TypeUniverse {
+
+    public final Map<Field, ResolvedJavaField> fields = new HashMap<>();
+
+    public FieldUniverse() {
+        for (Class c : classes) {
+            for (Field f : c.getDeclaredFields()) {
+                ResolvedJavaField field = metaAccess.lookupJavaField(f);
+                fields.put(f, field);
+            }
+        }
+    }
+}
--- /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/TestJavaField.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,76 @@
+/*
+ * 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 java.util.*;
+
+import org.junit.*;
+
+import com.oracle.graal.api.meta.*;
+
+/**
+ * Tests for {@link JavaField}.
+ */
+public class TestJavaField extends FieldUniverse {
+
+    @Test
+    public void getNameTest() {
+        for (Map.Entry<Field, ResolvedJavaField> e : fields.entrySet()) {
+            String expected = e.getKey().getName();
+            String actual = e.getValue().getName();
+            assertEquals(expected, actual);
+        }
+    }
+
+    @Test
+    public void getTypeTest() {
+        for (Map.Entry<Field, ResolvedJavaField> e : fields.entrySet()) {
+            // Must resolve types first as a resolved types != unresolved types
+            ResolvedJavaField rf = e.getValue();
+            JavaType expected = metaAccess.lookupJavaType(e.getKey().getType()).resolve(rf.getDeclaringClass());
+            JavaType actual = rf.getType().resolve(rf.getDeclaringClass());
+            assertEquals(expected, actual);
+        }
+    }
+
+    @Test
+    public void getKindTest() {
+        for (Map.Entry<Field, ResolvedJavaField> e : fields.entrySet()) {
+            Kind expected = metaAccess.lookupJavaType(e.getKey().getType()).getKind();
+            Kind actual = e.getValue().getKind();
+            assertEquals(expected, actual);
+        }
+    }
+
+    @Test
+    public void getDeclaringClassTest() {
+        for (Map.Entry<Field, ResolvedJavaField> e : fields.entrySet()) {
+            Class expected = e.getKey().getDeclaringClass();
+            ResolvedJavaType actual = e.getValue().getDeclaringClass();
+            assertTrue(actual.equals(metaAccess.lookupJavaType(expected)));
+        }
+    }
+}
--- a/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestMetaAccessProvider.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestMetaAccessProvider.java	Wed Mar 05 19:40:15 2014 -0800
@@ -69,7 +69,7 @@
             for (Field reflect : c.getDeclaredFields()) {
                 ResolvedJavaField field = metaAccess.lookupJavaField(reflect);
                 assertNotNull(field);
-                int expected = reflect.getModifiers() & Modifier.fieldModifiers();
+                int expected = reflect.getModifiers();
                 int actual = field.getModifiers();
                 assertEquals(String.format("%s: 0x%x != 0x%x", reflect, expected, actual), expected, actual);
                 assertTrue(field.getDeclaringClass().equals(metaAccess.lookupJavaType(reflect.getDeclaringClass())));
--- /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/TestResolvedJavaField.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,174 @@
+/*
+ * 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 java.lang.reflect.Modifier.*;
+import static org.junit.Assert.*;
+
+import java.lang.annotation.*;
+import java.lang.reflect.*;
+import java.util.*;
+
+import org.junit.*;
+
+import com.oracle.graal.api.meta.*;
+
+/**
+ * Tests for {@link ResolvedJavaField}.
+ */
+public class TestResolvedJavaField extends FieldUniverse {
+
+    public TestResolvedJavaField() {
+    }
+
+    @Test
+    public void getModifiersTest() {
+        for (Map.Entry<Field, ResolvedJavaField> e : fields.entrySet()) {
+            int expected = e.getKey().getModifiers();
+            int actual = e.getValue().getModifiers();
+            assertEquals(expected, actual);
+        }
+    }
+
+    @Test
+    public void isSyntheticTest() {
+        for (Map.Entry<Field, ResolvedJavaField> e : fields.entrySet()) {
+            boolean expected = e.getKey().isSynthetic();
+            boolean actual = e.getValue().isSynthetic();
+            assertEquals(expected, actual);
+        }
+    }
+
+    @Test
+    public void getAnnotationTest() {
+        for (Map.Entry<Field, ResolvedJavaField> e : fields.entrySet()) {
+            for (Annotation expected : e.getKey().getAnnotations()) {
+                if (expected != null) {
+                    Annotation actual = e.getValue().getAnnotation(expected.annotationType());
+                    assertEquals(expected, actual);
+                }
+            }
+        }
+    }
+
+    @Test
+    public void readConstantValueTest() throws NoSuchFieldException {
+        for (Map.Entry<Field, ResolvedJavaField> e : fields.entrySet()) {
+            Field field = e.getKey();
+            if (isStatic(field.getModifiers())) {
+                try {
+                    Object expected = field.get(null);
+                    Object actual = e.getValue().readConstantValue(null).asBoxedValue();
+                    assertEquals(expected, actual);
+                } catch (IllegalArgumentException | IllegalAccessException e1) {
+                }
+            } else {
+                try {
+                    Object receiver = field.getDeclaringClass().newInstance();
+                    Object expected = field.get(receiver);
+                    Object actual = e.getValue().readConstantValue(Constant.forObject(receiver)).asBoxedValue();
+                    assertEquals(expected, actual);
+                } catch (InstantiationException | IllegalArgumentException | IllegalAccessException e1) {
+                }
+            }
+        }
+
+        ResolvedJavaField field = metaAccess.lookupJavaField(getClass().getDeclaredField("stringField"));
+        for (Object receiver : new Object[]{this, null, new String()}) {
+            Constant value = field.readConstantValue(Constant.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));
+            if (value != null) {
+                Object expected = "constantField";
+                assertTrue(value.asObject() == expected);
+            }
+        }
+    }
+
+    @Test
+    public void readValueTest() throws IllegalArgumentException, IllegalAccessException {
+        for (Map.Entry<Field, ResolvedJavaField> e : fields.entrySet()) {
+            Field field = e.getKey();
+            field.setAccessible(true);
+            if (isStatic(field.getModifiers())) {
+                try {
+                    Object expected = field.get(null);
+                    Object actual = e.getValue().readValue(null).asBoxedValue();
+                    assertEquals(expected, actual);
+                } catch (IllegalArgumentException | IllegalAccessException e1) {
+                }
+            }
+        }
+
+        String testString = "a test string";
+        testString.hashCode(); // create hash
+        for (Field f : String.class.getDeclaredFields()) {
+            f.setAccessible(true);
+            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();
+            assertEquals(expected, actual);
+        }
+    }
+
+    String stringField = "field";
+    final String constantStringField = "constantField";
+
+    private Method findTestMethod(Method apiMethod) {
+        String testName = apiMethod.getName() + "Test";
+        for (Method m : getClass().getDeclaredMethods()) {
+            if (m.getName().equals(testName) && m.getAnnotation(Test.class) != null) {
+                return m;
+            }
+        }
+        return null;
+    }
+
+    // @formatter:off
+    private static final String[] untestedApiMethods = {
+        "getDeclaringClass",
+        "isInternal"
+    };
+    // @formatter:on
+
+    /**
+     * Ensures that any new methods added to {@link ResolvedJavaMethod} either have a test written
+     * for them or are added to {@link #untestedApiMethods}.
+     */
+    @Test
+    public void testCoverage() {
+        Set<String> known = new HashSet<>(Arrays.asList(untestedApiMethods));
+        for (Method m : ResolvedJavaField.class.getDeclaredMethods()) {
+            if (findTestMethod(m) == null) {
+                assertTrue("test missing for " + m, known.contains(m.getName()));
+            } else {
+                assertFalse("test should be removed from untestedApiMethods" + m, known.contains(m.getName()));
+            }
+        }
+    }
+}
--- a/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaMethod.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaMethod.java	Wed Mar 05 19:40:15 2014 -0800
@@ -290,6 +290,7 @@
         "reprofile",
         "getCompilerStorage",
         "canBeInlined",
+        "shouldBeInlined",
         "getLineNumberTable",
         "getLocalVariableTable",
         "isInVirtualMethodTable",
--- a/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaType.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaType.java	Wed Mar 05 19:40:15 2014 -0800
@@ -40,6 +40,7 @@
 /**
  * Tests for {@link ResolvedJavaType}.
  */
+@SuppressWarnings("unused")
 public class TestResolvedJavaType extends TypeUniverse {
 
     public TestResolvedJavaType() {
@@ -503,7 +504,6 @@
     public ResolvedJavaField lookupField(ResolvedJavaField[] fields, Field key) {
         for (ResolvedJavaField rf : fields) {
             if (fieldsEqual(key, rf)) {
-                assert (fieldModifiers() & key.getModifiers()) == rf.getModifiers() : key + ": " + toHexString(key.getModifiers()) + " != " + toHexString(rf.getModifiers());
                 return rf;
             }
         }
@@ -513,7 +513,6 @@
     public Field lookupField(Set<Field> fields, ResolvedJavaField key) {
         for (Field f : fields) {
             if (fieldsEqual(f, key)) {
-                assert key.getModifiers() == (fieldModifiers() & f.getModifiers()) : key + ": " + toHexString(key.getModifiers()) + " != " + toHexString(f.getModifiers());
                 return f;
             }
         }
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Constant.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Constant.java	Wed Mar 05 19:40:15 2014 -0800
@@ -424,6 +424,18 @@
     }
 
     /**
+     * Creates a {@link Constant} from a primitive integer of a certain width.
+     */
+    public static Constant forPrimitiveInt(int bits, long i) {
+        assert bits <= 64;
+        if (bits > 32) {
+            return new Constant(Kind.Long, null, i);
+        } else {
+            return new Constant(Kind.Int, null, (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.
      * 
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/DefaultProfilingInfo.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/DefaultProfilingInfo.java	Wed Mar 05 19:40:15 2014 -0800
@@ -95,4 +95,8 @@
     public String toString() {
         return "BaseProfilingInfo<" + MetaUtil.profileToString(this, null, "; ") + ">";
     }
+
+    public void setMature() {
+        // Do nothing
+    }
 }
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Kind.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Kind.java	Wed Mar 05 19:40:15 2014 -0800
@@ -72,12 +72,12 @@
     private final Class primitiveJavaClass;
     private final Class boxedJavaClass;
 
-    private Kind(char typeChar, String javaName, boolean isStackInt, Class primitiveJavaClass, Class boxedJavasClass) {
+    private Kind(char typeChar, String javaName, boolean isStackInt, Class primitiveJavaClass, Class boxedJavaClass) {
         this.typeChar = typeChar;
         this.javaName = javaName;
         this.isStackInt = isStackInt;
         this.primitiveJavaClass = primitiveJavaClass;
-        this.boxedJavaClass = boxedJavasClass;
+        this.boxedJavaClass = boxedJavaClass;
         assert primitiveJavaClass == null || javaName.equals(primitiveJavaClass.getName());
     }
 
@@ -129,6 +129,15 @@
     }
 
     /**
+     * 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() {
+        return this == Kind.Boolean || this == Kind.Char;
+    }
+
+    /**
      * 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}.
@@ -138,6 +147,15 @@
     }
 
     /**
+     * Checks whether this represent an Object of some sort.
+     * 
+     * @return {@code true} if this is {@link #Object} or {@link #NarrowOop}.
+     */
+    public boolean isObject() {
+        return this == Kind.Object || this == Kind.NarrowOop;
+    }
+
+    /**
      * Returns the kind corresponding to the Java type string.
      * 
      * @param typeString the Java type string
@@ -255,19 +273,30 @@
 
     /**
      * Marker interface for types that should be {@linkplain Kind#format(Object) formatted} with
-     * their {@link Object#toString()} value.
+     * their {@link Object#toString()} value. Calling {@link Object#toString()} on other objects
+     * poses a security risk because it can potentially call user code.
      */
     public interface FormatWithToString {
     }
 
     /**
+     * Classes for which invoking {@link Object#toString()} does not run user code.
+     */
+    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
      */
     public String format(Object value) {
-        if (this == Kind.Object) {
+        if (isPrimitive()) {
+            assert isToStringSafe(value.getClass());
+            return value.toString();
+        } else {
             if (value == null) {
                 return "null";
             } else {
@@ -280,18 +309,20 @@
                     }
                 } else if (value instanceof JavaType) {
                     return "JavaType:" + MetaUtil.toJavaName((JavaType) value);
-                } else if (value instanceof Enum || value instanceof FormatWithToString || value instanceof Number) {
+                } else if (value instanceof Enum) {
+                    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<?>) {
                     return "Class:" + ((Class<?>) value).getName();
+                } else if (isToStringSafe(value.getClass())) {
+                    return value.toString();
                 } else if (value.getClass().isArray()) {
                     return formatArray(value);
                 } else {
                     return MetaUtil.getSimpleName(value.getClass(), true) + "@" + System.identityHashCode(value);
                 }
             }
-        } else {
-            return value.toString();
         }
     }
 
@@ -370,6 +401,19 @@
     }
 
     /**
+     * Number of bytes that are necessary to represent a value of this kind.
+     * 
+     * @return the number of bytes
+     */
+    public int getByteCount() {
+        if (this == Boolean) {
+            return 1;
+        } else {
+            return getBitCount() >> 3;
+        }
+    }
+
+    /**
      * Number of bits that are necessary to represent a value of this kind.
      * 
      * @return the number of bits
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/LocationIdentity.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/LocationIdentity.java	Wed Mar 05 19:40:15 2014 -0800
@@ -41,4 +41,8 @@
      */
     LocationIdentity FINAL_LOCATION = new NamedLocationIdentity("FINAL_LOCATION");
 
+    /**
+     * Denotes the location of the length field of a Java array.
+     */
+    LocationIdentity ARRAY_LENGTH_LOCATION = new NamedLocationIdentity("[].length");
 }
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/MetaAccessProvider.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/MetaAccessProvider.java	Wed Mar 05 19:40:15 2014 -0800
@@ -60,6 +60,14 @@
     ResolvedJavaType lookupJavaType(Constant constant);
 
     /**
+     * Returns the number of bytes occupied by this constant value or constant object.
+     * 
+     * @param constant the constant whose bytes should be measured
+     * @return the number of bytes occupied by this constant
+     */
+    long getMemorySize(Constant constant);
+
+    /**
      * Parses a <a
      * href="http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.3.3">method
      * descriptor</a> into a {@link Signature}. The behavior of this method is undefined if the
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/MetaUtil.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/MetaUtil.java	Wed Mar 05 19:40:15 2014 -0800
@@ -24,6 +24,7 @@
 
 import static java.lang.reflect.Modifier.*;
 
+import java.io.*;
 import java.lang.annotation.*;
 import java.lang.reflect.*;
 import java.util.*;
@@ -36,6 +37,104 @@
  */
 public class MetaUtil {
 
+    private static class ClassInfo {
+        public long totalSize;
+        public long instanceCount;
+
+        @Override
+        public String toString() {
+            return "totalSize=" + totalSize + ", instanceCount=" + instanceCount;
+        }
+    }
+
+    /**
+     * 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<Object, Boolean> marked = new IdentityHashMap<>();
+        Stack<Constant> stack = new Stack<>();
+        if (constant.getKind() == Kind.Object && constant.isNonNull()) {
+            marked.put(constant.asObject(), Boolean.TRUE);
+        }
+        final HashMap<Class, ClassInfo> histogram = new HashMap<>();
+        stack.push(constant);
+        long sum = 0;
+        while (!stack.isEmpty()) {
+            Constant c = stack.pop();
+            long memorySize = access.getMemorySize(constant);
+            sum += memorySize;
+            if (c.getKind() == Kind.Object && c.isNonNull()) {
+                Class<?> clazz = c.asObject().getClass();
+                if (!histogram.containsKey(clazz)) {
+                    histogram.put(clazz, new ClassInfo());
+                }
+                ClassInfo info = histogram.get(clazz);
+                info.instanceCount++;
+                info.totalSize += memorySize;
+                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);
+                        }
+                    }
+                } else {
+                    ResolvedJavaField[] instanceFields = type.getInstanceFields(true);
+                    for (ResolvedJavaField f : instanceFields) {
+                        if (f.getKind() == Kind.Object) {
+                            Constant value = f.readValue(c);
+                            pushConstant(marked, stack, value);
+                        }
+                    }
+                }
+            }
+        }
+        ArrayList<Class> clazzes = new ArrayList<>();
+        clazzes.addAll(histogram.keySet());
+        Collections.sort(clazzes, new Comparator<Class>() {
+
+            @Override
+            public int compare(Class o1, Class o2) {
+                long l1 = histogram.get(o1).totalSize;
+                long l2 = histogram.get(o2).totalSize;
+                if (l1 > l2) {
+                    return -1;
+                } else if (l1 == l2) {
+                    return 0;
+                } else {
+                    return 1;
+                }
+            }
+        });
+
+        int z = 0;
+        for (Class c : clazzes) {
+            if (z > printTopN) {
+                break;
+            }
+            out.println("Class " + c + ", " + histogram.get(c));
+            ++z;
+        }
+
+        return sum;
+    }
+
+    private static void pushConstant(IdentityHashMap<Object, Boolean> marked, Stack<Constant> stack, Constant value) {
+        if (value.isNonNull()) {
+            if (!marked.containsKey(value.asObject())) {
+                marked.put(value.asObject(), Boolean.TRUE);
+                stack.push(value);
+            }
+        }
+    }
+
     /**
      * Returns true if the specified typed is exactly the type {@link java.lang.Object}.
      */
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ProfilingInfo.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ProfilingInfo.java	Wed Mar 05 19:40:15 2014 -0800
@@ -121,4 +121,9 @@
      */
     boolean isMature();
 
+    /**
+     * Force data to be treated as mature if possible.
+     */
+
+    void setMature();
 }
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaField.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaField.java	Wed Mar 05 19:40:15 2014 -0800
@@ -64,7 +64,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 {@link #readConstantValue(Constant)} by the runtime.
+     * 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.
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaMethod.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaMethod.java	Wed Mar 05 19:40:15 2014 -0800
@@ -185,6 +185,8 @@
      */
     boolean canBeInlined();
 
+    boolean shouldBeInlined();
+
     /**
      * Returns the LineNumberTable of this method or null if this method does not have a line
      * numbers table.
--- a/graal/com.oracle.graal.api.replacements/src/com/oracle/graal/api/replacements/ClassSubstitution.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.api.replacements/src/com/oracle/graal/api/replacements/ClassSubstitution.java	Wed Mar 05 19:40:15 2014 -0800
@@ -61,6 +61,5 @@
      * Determines if the substitutions in a class are globally enabled. Individual
      * MethodSubstitutions can also have guards and those override this guard.
      */
-
     Class<? extends SubstitutionGuard> defaultGuard() default SubstitutionGuard.class;
 }
--- a/graal/com.oracle.graal.asm.amd64.test/src/com/oracle/graal/asm/amd64/test/SimpleAssemblerTest.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.asm.amd64.test/src/com/oracle/graal/asm/amd64/test/SimpleAssemblerTest.java	Wed Mar 05 19:40:15 2014 -0800
@@ -30,7 +30,6 @@
 import com.oracle.graal.api.code.CompilationResult.ConstantData;
 import com.oracle.graal.api.code.CompilationResult.RawData;
 import com.oracle.graal.api.meta.*;
-import com.oracle.graal.asm.Buffer;
 import com.oracle.graal.asm.amd64.*;
 import com.oracle.graal.asm.test.*;
 
@@ -41,12 +40,12 @@
         CodeGenTest test = new CodeGenTest() {
 
             @Override
-            public Buffer generateCode(CompilationResult compResult, TargetDescription target, RegisterConfig registerConfig, CallingConvention cc) {
+            public byte[] generateCode(CompilationResult compResult, TargetDescription target, RegisterConfig registerConfig, CallingConvention cc) {
                 AMD64Assembler asm = new AMD64Assembler(target, registerConfig);
                 Register ret = registerConfig.getReturnRegister(Kind.Int);
                 asm.movl(ret, 8472);
                 asm.ret(0);
-                return asm.codeBuffer;
+                return asm.close(true);
             }
         };
         assertReturn("intStub", test, 8472);
@@ -57,13 +56,13 @@
         CodeGenTest test = new CodeGenTest() {
 
             @Override
-            public Buffer generateCode(CompilationResult compResult, TargetDescription target, RegisterConfig registerConfig, CallingConvention cc) {
+            public byte[] generateCode(CompilationResult compResult, TargetDescription target, RegisterConfig registerConfig, CallingConvention cc) {
                 AMD64MacroAssembler asm = new AMD64MacroAssembler(target, registerConfig);
                 Register ret = registerConfig.getReturnRegister(Kind.Double);
-                compResult.recordDataReference(asm.codeBuffer.position(), new ConstantData(Constant.forDouble(84.72), 8));
+                compResult.recordDataReference(asm.position(), new ConstantData(Constant.forDouble(84.72), 8));
                 asm.movdbl(ret, asm.getPlaceholder());
                 asm.ret(0);
-                return asm.codeBuffer;
+                return asm.close(true);
             }
         };
         assertReturn("doubleStub", test, 84.72);
@@ -74,16 +73,16 @@
         CodeGenTest test = new CodeGenTest() {
 
             @Override
-            public Buffer generateCode(CompilationResult compResult, TargetDescription target, RegisterConfig registerConfig, CallingConvention cc) {
+            public byte[] generateCode(CompilationResult compResult, TargetDescription target, RegisterConfig registerConfig, CallingConvention cc) {
                 AMD64MacroAssembler asm = new AMD64MacroAssembler(target, registerConfig);
                 Register ret = registerConfig.getReturnRegister(Kind.Double);
 
                 byte[] rawBytes = new byte[8];
                 ByteBuffer.wrap(rawBytes).order(ByteOrder.nativeOrder()).putDouble(84.72);
-                compResult.recordDataReference(asm.codeBuffer.position(), new RawData(rawBytes, 8));
+                compResult.recordDataReference(asm.position(), new RawData(rawBytes, 8));
                 asm.movdbl(ret, asm.getPlaceholder());
                 asm.ret(0);
-                return asm.codeBuffer;
+                return asm.close(true);
             }
         };
         assertReturn("doubleStub", test, 84.72);
--- a/graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Assembler.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Assembler.java	Wed Mar 05 19:40:15 2014 -0800
@@ -34,7 +34,7 @@
 /**
  * This class implements an assembler that can encode most X86 instructions.
  */
-public class AMD64Assembler extends AbstractAssembler {
+public class AMD64Assembler extends Assembler {
 
     private static final int MinEncodingNeedsRex = 8;
 
@@ -746,7 +746,7 @@
     public void jcc(ConditionFlag cc, int jumpTarget, boolean forceDisp32) {
         int shortSize = 2;
         int longSize = 6;
-        long disp = jumpTarget - codeBuffer.position();
+        long disp = jumpTarget - position();
         if (!forceDisp32 && isByte(disp - shortSize)) {
             // 0111 tttn #8-bit disp
             emitByte(0x70 | cc.getValue());
@@ -769,7 +769,7 @@
             // is the same however, seems to be rather unlikely case.
             // Note: use jccb() if label to be bound is very close to get
             // an 8-bit displacement
-            l.addPatchAt(codeBuffer.position());
+            l.addPatchAt(position());
             emitByte(0x0F);
             emitByte(0x80 | cc.getValue());
             emitInt(0);
@@ -781,13 +781,13 @@
         if (l.isBound()) {
             int shortSize = 2;
             int entry = l.position();
-            assert isByte(entry - (codeBuffer.position() + shortSize)) : "Dispacement too large for a short jmp";
-            long disp = entry - codeBuffer.position();
+            assert isByte(entry - (position() + shortSize)) : "Dispacement too large for a short jmp";
+            long disp = entry - position();
             // 0111 tttn #8-bit disp
             emitByte(0x70 | cc.getValue());
             emitByte((int) ((disp - shortSize) & 0xFF));
         } else {
-            l.addPatchAt(codeBuffer.position());
+            l.addPatchAt(position());
             emitByte(0x70 | cc.getValue());
             emitByte(0);
         }
@@ -796,7 +796,7 @@
     public final void jmp(int jumpTarget, boolean forceDisp32) {
         int shortSize = 2;
         int longSize = 5;
-        long disp = jumpTarget - codeBuffer.position();
+        long disp = jumpTarget - position();
         if (!forceDisp32 && isByte(disp - shortSize)) {
             emitByte(0xEB);
             emitByte((int) ((disp - shortSize) & 0xFF));
@@ -816,7 +816,7 @@
             // the forward jump will not run beyond 256 bytes, use jmpb to
             // force an 8-bit displacement.
 
-            l.addPatchAt(codeBuffer.position());
+            l.addPatchAt(position());
             emitByte(0xE9);
             emitInt(0);
         }
@@ -832,13 +832,13 @@
         if (l.isBound()) {
             int shortSize = 2;
             int entry = l.position();
-            assert isByte((entry - codeBuffer.position()) + shortSize) : "Dispacement too large for a short jmp";
-            long offs = entry - codeBuffer.position();
+            assert isByte((entry - position()) + shortSize) : "Dispacement too large for a short jmp";
+            long offs = entry - position();
             emitByte(0xEB);
             emitByte((int) ((offs - shortSize) & 0xFF));
         } else {
 
-            l.addPatchAt(codeBuffer.position());
+            l.addPatchAt(position());
             emitByte(0xEB);
             emitByte(0);
         }
@@ -1034,6 +1034,20 @@
         emitByte(0xC0 | encode);
     }
 
+    public final void movsbq(Register dst, AMD64Address src) {
+        prefixq(src, dst);
+        emitByte(0x0F);
+        emitByte(0xBE);
+        emitOperandHelper(dst, src);
+    }
+
+    public final void movsbq(Register dst, Register src) {
+        int encode = prefixqAndEncode(dst.encoding, src.encoding);
+        emitByte(0x0F);
+        emitByte(0xBE);
+        emitByte(0xC0 | encode);
+    }
+
     public final void movsd(Register dst, Register src) {
         assert dst.getRegisterCategory() == AMD64.XMM;
         assert src.getRegisterCategory() == AMD64.XMM;
@@ -1104,6 +1118,20 @@
         emitByte(0xC0 | encode);
     }
 
+    public final void movswq(Register dst, AMD64Address src) {
+        prefixq(src, dst);
+        emitByte(0x0F);
+        emitByte(0xBF);
+        emitOperandHelper(dst, src);
+    }
+
+    public final void movswq(Register dst, Register src) {
+        int encode = prefixqAndEncode(dst.encoding, src.encoding);
+        emitByte(0x0F);
+        emitByte(0xBF);
+        emitByte(0xC0 | encode);
+    }
+
     public final void movw(AMD64Address dst, int imm16) {
         emitByte(0x66); // switch to 16-bit mode
         prefix(dst);
@@ -2418,21 +2446,21 @@
 
     @Override
     protected final void patchJumpTarget(int branch, int branchTarget) {
-        int op = codeBuffer.getByte(branch);
+        int op = getByte(branch);
         assert op == 0xE8 // call
                         ||
                         op == 0x00 // jump table entry
                         || op == 0xE9 // jmp
                         || op == 0xEB // short jmp
                         || (op & 0xF0) == 0x70 // short jcc
-                        || op == 0x0F && (codeBuffer.getByte(branch + 1) & 0xF0) == 0x80 // jcc
+                        || op == 0x0F && (getByte(branch + 1) & 0xF0) == 0x80 // jcc
         : "Invalid opcode at patch point branch=" + branch + ", branchTarget=" + branchTarget + ", op=" + op;
 
         if (op == 0x00) {
-            int offsetToJumpTableBase = codeBuffer.getShort(branch + 1);
+            int offsetToJumpTableBase = getShort(branch + 1);
             int jumpTableBase = branch - offsetToJumpTableBase;
             int imm32 = branchTarget - jumpTableBase;
-            codeBuffer.emitInt(imm32, branch);
+            emitInt(imm32, branch);
         } else if (op == 0xEB || (op & 0xF0) == 0x70) {
 
             // short offset operators (jmp and jcc)
@@ -2444,7 +2472,7 @@
             if (!NumUtil.isByte(imm8)) {
                 throw new InternalError("branch displacement out of range: " + imm8);
             }
-            codeBuffer.emitByte(imm8, branch + 1);
+            emitByte(imm8, branch + 1);
 
         } else {
 
@@ -2454,7 +2482,7 @@
             }
 
             int imm32 = branchTarget - (branch + 4 + off);
-            codeBuffer.emitInt(imm32, branch + off);
+            emitInt(imm32, branch + off);
         }
     }
 
@@ -2464,8 +2492,8 @@
 
     @Override
     public void align(int modulus) {
-        if (codeBuffer.position() % modulus != 0) {
-            nop(modulus - (codeBuffer.position() % modulus));
+        if (position() % modulus != 0) {
+            nop(modulus - (position() % modulus));
         }
     }
 
--- a/graal/com.oracle.graal.asm.hsail/src/com/oracle/graal/asm/hsail/AbstractHSAILAssembler.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.asm.hsail/src/com/oracle/graal/asm/hsail/AbstractHSAILAssembler.java	Wed Mar 05 19:40:15 2014 -0800
@@ -28,7 +28,7 @@
 /**
  * The platform-dependent base class for the HSAIL assembler.
  */
-public abstract class AbstractHSAILAssembler extends AbstractAssembler {
+public abstract class AbstractHSAILAssembler extends Assembler {
 
     public AbstractHSAILAssembler(TargetDescription target) {
         super(target);
--- a/graal/com.oracle.graal.asm.hsail/src/com/oracle/graal/asm/hsail/HSAILAssembler.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.asm.hsail/src/com/oracle/graal/asm/hsail/HSAILAssembler.java	Wed Mar 05 19:40:15 2014 -0800
@@ -120,7 +120,13 @@
     }
 
     private void emitAddrOp(String instr, Value reg, HSAILAddress addr) {
-        emitString(instr + " " + HSAIL.mapRegister(reg) + ", " + mapAddress(addr) + ";");
+        String storeValue = null;
+        if (reg instanceof RegisterValue) {
+            storeValue = HSAIL.mapRegister(reg);
+        } else if (reg instanceof Constant) {
+            storeValue = ((Constant) reg).asBoxedValue().toString();
+        }
+        emitString(instr + " " + storeValue + ", " + mapAddress(addr) + ";");
     }
 
     /**
@@ -160,10 +166,31 @@
         emitAddrOp("st_global_" + argTypeStr, dest, addr);
     }
 
+    private void storeImmediateImpl(String storeType, String value, HSAILAddress addr) {
+        emitString("st_global_" + storeType + " " + value + ", " + mapAddress(addr) + ";");
+    }
+
+    public final void emitStoreImmediate(Kind kind, long src, HSAILAddress addr) {
+        assert (kind != Kind.Float && kind != Kind.Double);
+        storeImmediateImpl(getArgTypeFromKind(kind), Long.toString(src), addr);
+    }
+
+    public final void emitStoreImmediate(float src, HSAILAddress addr) {
+        storeImmediateImpl("f32", Float.toString(src), addr);
+    }
+
+    public final void emitStoreImmediate(double src, HSAILAddress addr) {
+        storeImmediateImpl("f64", Double.toString(src), addr);
+    }
+
     public final void emitSpillLoad(Value dest, Value src) {
         emitString("ld_spill_" + getArgType(dest) + " " + HSAIL.mapRegister(dest) + ", " + mapStackSlot(src, getArgSize(dest)) + ";");
     }
 
+    public final void emitStore(Value src, HSAILAddress addr) {
+        emitString("st_global_" + getArgType(src) + " " + HSAIL.mapRegister(src) + ", " + mapAddress(addr) + ";");
+    }
+
     public final void emitSpillStore(Value src, Value dest) {
         int sizestored = getArgSize(src);
         if (maxDataTypeSize < sizestored) {
@@ -206,7 +233,7 @@
         }
     }
 
-    public static final String getArgType(Value src) {
+    private static String getArgType(Value src) {
         return getArgTypeFromKind(src.getKind());
     }
 
@@ -237,6 +264,9 @@
             case Byte:
                 prefix = "s8";
                 break;
+            case NarrowOop:
+                prefix = "u32";
+                break;
             default:
                 throw GraalInternalError.shouldNotReachHere();
         }
@@ -282,9 +312,7 @@
         emitString(prefix + " $c0, " + mapRegOrConstToString(src0) + ", " + mapRegOrConstToString(src1) + ";" + comment);
     }
 
-    public void emitConvert(Value dest, Value src, Kind destKind, Kind srcKind) {
-        String destType = getArgTypeFromKind(destKind);
-        String srcType = getArgTypeFromKind(srcKind);
+    public void emitConvert(Value dest, Value src, String destType, String srcType) {
         String prefix = (destType.equals("f32") && srcType.equals("f64")) ? "cvt_near_" : "cvt_";
         emitString(prefix + destType + "_" + srcType + " " + HSAIL.mapRegister(dest) + ", " + HSAIL.mapRegister(src) + ";");
     }
@@ -506,4 +534,8 @@
     public void emitComment(String comment) {
         emitString(comment);
     }
+
+    public void emitStoreRelease(Value src, HSAILAddress address) {
+        emitAddrOp("st_global_rel_u" + getArgSize(src), src, address);
+    }
 }
--- a/graal/com.oracle.graal.asm.ptx/src/com/oracle/graal/asm/ptx/AbstractPTXAssembler.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.asm.ptx/src/com/oracle/graal/asm/ptx/AbstractPTXAssembler.java	Wed Mar 05 19:40:15 2014 -0800
@@ -28,7 +28,7 @@
 /**
  * The platform-dependent base class for the PTX assembler.
  */
-public abstract class AbstractPTXAssembler extends AbstractAssembler {
+public abstract class AbstractPTXAssembler extends Assembler {
 
     public AbstractPTXAssembler(TargetDescription target) {
         super(target);
--- a/graal/com.oracle.graal.asm.ptx/src/com/oracle/graal/asm/ptx/PTXAssembler.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.asm.ptx/src/com/oracle/graal/asm/ptx/PTXAssembler.java	Wed Mar 05 19:40:15 2014 -0800
@@ -397,13 +397,17 @@
     }
 
     // Checkstyle: stop method name check
-    public final void bra(String tgt, int pred) {
+    /*
+     * Emit conditional branch to target 'tgt' guarded by predicate register 'pred' whose state is
+     * tested to be 'predCheck'.
+     */
+    public final void bra(String tgt, int pred, boolean predCheck) {
         assert pred >= 0;
 
         if (tgt.equals("?")) {
             Thread.dumpStack();
         }
-        emitString("@%p" + pred + " " + "bra" + " " + tgt + ";");
+        emitString("@" + (predCheck ? "%p" : "!%p") + pred + " " + "bra" + " " + tgt + ";");
     }
 
     public final void bra(String src) {
--- a/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAssembler.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAssembler.java	Wed Mar 05 19:40:15 2014 -0800
@@ -33,7 +33,7 @@
 /**
  * This class implements an assembler that can encode most SPARC instructions.
  */
-public abstract class SPARCAssembler extends AbstractAssembler {
+public abstract class SPARCAssembler extends Assembler {
 
     /**
      * Constructs an assembler for the SPARC architecture.
@@ -89,7 +89,7 @@
         }
 
         public static Fmt00a read(SPARCAssembler masm, int pos) {
-            final int inst = masm.codeBuffer.getInt(pos);
+            final int inst = masm.getInt(pos);
 
             // Make sure it's the right instruction:
             final int op = (inst & OP_MASK) >> OP_SHIFT;
@@ -105,7 +105,7 @@
 
         public void write(SPARCAssembler masm, int pos) {
             verify();
-            masm.codeBuffer.emitInt(getInstructionBits(), pos);
+            masm.emitInt(getInstructionBits(), pos);
         }
 
         public void emit(SPARCAssembler masm) {
@@ -253,7 +253,7 @@
         }
 
         public static Fmt00c read(SPARCAssembler masm, int pos) {
-            final int inst = masm.codeBuffer.getInt(pos);
+            final int inst = masm.getInt(pos);
 
             // Make sure it's the right instruction:
             final int op = (inst & OP_MASK) >> OP_SHIFT;
@@ -274,13 +274,13 @@
 
         public void write(SPARCAssembler masm, int pos) {
             verify();
-            masm.codeBuffer.emitInt(getInstructionBits(), pos);
+            masm.emitInt(getInstructionBits(), pos);
         }
 
         public void emit(SPARCAssembler masm) {
             if (label != null) {
                 final int pos = label.isBound() ? label.position() : patchUnbound(masm, label);
-                final int disp = pos - masm.codeBuffer.position();
+                final int disp = pos - masm.position();
                 setDisp19(disp);
             }
             verify();
@@ -288,7 +288,7 @@
         }
 
         private static int patchUnbound(SPARCAssembler masm, Label label) {
-            label.addPatchAt(masm.codeBuffer.position());
+            label.addPatchAt(masm.position());
             return 0;
         }
 
@@ -370,7 +370,7 @@
         }
 
         public static Fmt01 read(SPARCAssembler masm, int pos) {
-            final int inst = masm.codeBuffer.getInt(pos);
+            final int inst = masm.getInt(pos);
 
             // Make sure it's the right instruction:
             final int op = (inst & OP_MASK) >> OP_SHIFT;
@@ -386,7 +386,7 @@
 
         public void write(SPARCAssembler masm, int pos) {
             verify();
-            masm.codeBuffer.emitInt(getInstructionBits(), pos);
+            masm.emitInt(getInstructionBits(), pos);
         }
 
         public void emit(SPARCAssembler masm) {
@@ -550,7 +550,7 @@
         }
 
         public static Fmt10 read(SPARCAssembler masm, int pos) {
-            final int inst = masm.codeBuffer.getInt(pos);
+            final int inst = masm.getInt(pos);
 
             // Make sure it's the right instruction:
             final int op = (inst & OP_MASK) >> OP_SHIFT;
@@ -571,7 +571,7 @@
 
         public void write(SPARCAssembler masm, int pos) {
             verify();
-            masm.codeBuffer.emitInt(getInstructionBits(), pos);
+            masm.emitInt(getInstructionBits(), pos);
         }
 
         public void emit(SPARCAssembler masm) {
@@ -654,7 +654,7 @@
         }
 
         /**
-         * Special constructor for Casa and Casxa.
+         * Special constructor for {@link Casa} and {@link Casxa}.
          */
         public Fmt11(Op3s op3, Register rs1, Register rs2, Register rd, Asi asi) {
             this(rd.encoding(), op3.getValue(), rs1.encoding(), asi.isValid() ? 0 : 1, asi.isValid() ? asi.getValue() : 0, rs2.encoding(), 0);
@@ -666,6 +666,18 @@
          */
         public Fmt11(Op3s op3, SPARCAddress addr, Register rd) {
             this(rd.encoding(), op3.getValue(), addr.getBase().encoding(), 0, 0, 0, 0);
+            decodeAddress(addr);
+        }
+
+        /**
+         * Special constructor for {@link Prefetch} and Prefetcha.
+         */
+        public Fmt11(Op3s op3, SPARCAddress addr, Prefetch.Fcn fcn) {
+            this(fcn.getValue(), op3.getValue(), addr.getBase().encoding(), 0, 0, 0, 0);
+            decodeAddress(addr);
+        }
+
+        private void decodeAddress(SPARCAddress addr) {
             if (!addr.getIndex().equals(Register.None)) {
                 this.rs2 = addr.getIndex().encoding();
             } else {
@@ -684,7 +696,7 @@
         }
 
         public static Fmt11 read(SPARCAssembler masm, int pos) {
-            final int inst = masm.codeBuffer.getInt(pos);
+            final int inst = masm.getInt(pos);
 
             // Make sure it's the right instruction:
             final int op = (inst & OP_MASK) >> OP_SHIFT;
@@ -704,7 +716,7 @@
 
         public void write(SPARCAssembler masm, int pos) {
             verify();
-            masm.codeBuffer.emitInt(getInstructionBits(), pos);
+            masm.emitInt(getInstructionBits(), pos);
         }
 
         public void emit(SPARCAssembler masm) {
@@ -820,7 +832,7 @@
         }
 
         public static Fmt10c read(SPARCAssembler masm, int pos) {
-            final int inst = masm.codeBuffer.getInt(pos);
+            final int inst = masm.getInt(pos);
 
             // Make sure it's the right instruction:
             final int op = (inst & OP_MASK) >> OP_SHIFT;
@@ -840,7 +852,7 @@
 
         public void write(SPARCAssembler masm, int pos) {
             verify();
-            masm.codeBuffer.emitInt(getInstructionBits(), pos);
+            masm.emitInt(getInstructionBits(), pos);
         }
 
         public void emit(SPARCAssembler masm) {
@@ -1009,6 +1021,8 @@
         Retry(0x3e, "retry"),
         Casa(0b111100, "casa"),
         Casxa(0b111110, "casxa"),
+        Prefetch(0b101101, "prefetch"),
+        Prefetcha(0b111101, "prefetcha"),
 
         Lduw(0b00000, "lduw"),
         Ldub(0b00001, "ldub"),
@@ -2921,6 +2935,27 @@
         }
     }
 
+    public static class Prefetch extends Fmt11 {
+
+        public enum Fcn {
+            SeveralReads(0), OneRead(1), SeveralWritesAndPossiblyReads(2), OneWrite(3), Page(4);
+
+            private final int value;
+
+            private Fcn(int value) {
+                this.value = value;
+            }
+
+            public int getValue() {
+                return value;
+            }
+        }
+
+        public Prefetch(SPARCAddress addr, Prefetch.Fcn fcn) {
+            super(Op3s.Prefetch, addr, fcn);
+        }
+    }
+
     // A.44 Read State Register
 
     @Deprecated
--- a/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCMacroAssembler.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCMacroAssembler.java	Wed Mar 05 19:40:15 2014 -0800
@@ -42,8 +42,8 @@
 
     @Override
     public void align(int modulus) {
-        if (codeBuffer.position() % modulus != 0) {
-            final int count = modulus - (codeBuffer.position() % modulus);
+        if (position() % modulus != 0) {
+            final int count = modulus - (position() % modulus);
             for (int i = 0; i < count; i++) {
                 new Nop().emit(this);
             }
@@ -364,7 +364,7 @@
             int lo = (int) (value & ~0);
 
             // This is the same logic as MacroAssembler::internal_set.
-            final int startPc = masm.codeBuffer.position();
+            final int startPc = masm.position();
 
             if (hi == 0 && lo >= 0) {
                 new Sethi(hi22(lo), dst).emit(masm);
@@ -399,7 +399,7 @@
             }
             // Pad out the instruction sequence so it can be patched later.
             if (forceRelocatable) {
-                while (masm.codeBuffer.position() < (startPc + (INSTRUCTION_SIZE * 4))) {
+                while (masm.position() < (startPc + (INSTRUCTION_SIZE * 4))) {
                     new Nop().emit(masm);
                 }
             }
--- a/graal/com.oracle.graal.asm.test/src/com/oracle/graal/asm/test/AssemblerTest.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.asm.test/src/com/oracle/graal/asm/test/AssemblerTest.java	Wed Mar 05 19:40:15 2014 -0800
@@ -29,7 +29,6 @@
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.api.runtime.*;
-import com.oracle.graal.asm.*;
 import com.oracle.graal.phases.util.*;
 import com.oracle.graal.runtime.*;
 import com.oracle.graal.test.*;
@@ -40,8 +39,7 @@
     protected final CodeCacheProvider codeCache;
 
     public interface CodeGenTest {
-
-        Buffer generateCode(CompilationResult compResult, TargetDescription target, RegisterConfig registerConfig, CallingConvention cc);
+        byte[] generateCode(CompilationResult compResult, TargetDescription target, RegisterConfig registerConfig, CallingConvention cc);
     }
 
     public AssemblerTest() {
@@ -60,8 +58,8 @@
         CallingConvention cc = CodeUtil.getCallingConvention(codeCache, CallingConvention.Type.JavaCallee, method, false);
 
         CompilationResult compResult = new CompilationResult();
-        Buffer codeBuffer = test.generateCode(compResult, codeCache.getTarget(), registerConfig, cc);
-        compResult.setTargetCode(codeBuffer.close(true), codeBuffer.position());
+        byte[] targetCode = test.generateCode(compResult, codeCache.getTarget(), registerConfig, cc);
+        compResult.setTargetCode(targetCode, targetCode.length);
 
         InstalledCode code = codeCache.addMethod(method, compResult, null);
 
--- a/graal/com.oracle.graal.asm/src/com/oracle/graal/asm/AbstractAssembler.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,127 +0,0 @@
-/*
- * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.asm;
-
-import java.nio.*;
-import java.util.*;
-
-import com.oracle.graal.api.code.*;
-
-/**
- * The platform-independent base class for the assembler.
- */
-public abstract class AbstractAssembler {
-
-    public final TargetDescription target;
-    public final Buffer codeBuffer;
-
-    public AbstractAssembler(TargetDescription target) {
-        this.target = target;
-
-        if (target.arch.getByteOrder() == ByteOrder.BIG_ENDIAN) {
-            this.codeBuffer = new Buffer.BigEndian();
-        } else {
-            this.codeBuffer = new Buffer.LittleEndian();
-        }
-    }
-
-    public void bind(Label l) {
-        assert !l.isBound() : "can bind label only once";
-        l.bind(codeBuffer.position());
-        l.patchInstructions(this);
-    }
-
-    public abstract void align(int modulus);
-
-    public abstract void jmp(Label l);
-
-    protected abstract void patchJumpTarget(int branch, int jumpTarget);
-
-    private Map<Label, String> nameMap;
-
-    /**
-     * Creates a name for a label.
-     * 
-     * @param l the label for which a name is being created
-     * @param id a label identifier that is unique with the scope of this assembler
-     * @return a label name in the form of "L123"
-     */
-    protected String createLabelName(Label l, int id) {
-        return "L" + id;
-    }
-
-    /**
-     * Gets a name for a label, creating it if it does not yet exist. By default, the returned name
-     * is only unique with the scope of this assembler.
-     */
-    public String nameOf(Label l) {
-        if (nameMap == null) {
-            nameMap = new HashMap<>();
-        }
-        String name = nameMap.get(l);
-        if (name == null) {
-            name = createLabelName(l, nameMap.size());
-            nameMap.put(l, name);
-        }
-        return name;
-    }
-
-    protected final void emitByte(int x) {
-        codeBuffer.emitByte(x);
-    }
-
-    protected final void emitShort(int x) {
-        codeBuffer.emitShort(x);
-    }
-
-    protected final void emitInt(int x) {
-        codeBuffer.emitInt(x);
-    }
-
-    protected final void emitLong(long x) {
-        codeBuffer.emitLong(x);
-    }
-
-    /**
-     * Some GPU architectures have a text based encoding.
-     */
-    protected final void emitString(String x) {
-        codeBuffer.emitString(x);
-    }
-
-    // XXX for pretty-printing
-    protected final void emitString0(String x) {
-        codeBuffer.emitString0(x);
-    }
-
-    /**
-     * This is used by the CompilationResultBuilder to convert a {@link StackSlot} to an
-     * {@link AbstractAddress}.
-     */
-    public abstract AbstractAddress makeAddress(Register base, int displacement);
-
-    /**
-     * Returns a target specific placeholder address that can be used for code patching.
-     */
-    public abstract AbstractAddress getPlaceholder();
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.asm/src/com/oracle/graal/asm/Assembler.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,186 @@
+/*
+ * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.asm;
+
+import java.nio.*;
+import java.util.*;
+
+import com.oracle.graal.api.code.*;
+
+/**
+ * The platform-independent base class for the assembler.
+ */
+public abstract class Assembler {
+
+    public final TargetDescription target;
+
+    /**
+     * Backing code buffer.
+     */
+    private final Buffer codeBuffer;
+
+    public Assembler(TargetDescription target) {
+        this.target = target;
+        if (target.arch.getByteOrder() == ByteOrder.BIG_ENDIAN) {
+            this.codeBuffer = new Buffer.BigEndian();
+        } else {
+            this.codeBuffer = new Buffer.LittleEndian();
+        }
+    }
+
+    /**
+     * Returns the current position of the underlying code buffer.
+     * 
+     * @return current position in code buffer
+     */
+    public int position() {
+        return codeBuffer.position();
+    }
+
+    public final void emitByte(int x) {
+        codeBuffer.emitByte(x);
+    }
+
+    public final void emitShort(int x) {
+        codeBuffer.emitShort(x);
+    }
+
+    public final void emitInt(int x) {
+        codeBuffer.emitInt(x);
+    }
+
+    public final void emitLong(long x) {
+        codeBuffer.emitLong(x);
+    }
+
+    public final void emitByte(int b, int pos) {
+        codeBuffer.emitByte(b, pos);
+    }
+
+    public final void emitShort(int b, int pos) {
+        codeBuffer.emitShort(b, pos);
+    }
+
+    public final void emitInt(int b, int pos) {
+        codeBuffer.emitInt(b, pos);
+    }
+
+    public final void emitLong(long b, int pos) {
+        codeBuffer.emitLong(b, pos);
+    }
+
+    public final int getByte(int pos) {
+        return codeBuffer.getByte(pos);
+    }
+
+    public final int getShort(int pos) {
+        return codeBuffer.getShort(pos);
+    }
+
+    public final int getInt(int pos) {
+        return codeBuffer.getInt(pos);
+    }
+
+    private static final String NEWLINE = System.getProperty("line.separator");
+
+    /**
+     * Some GPU architectures have a text based encoding.
+     */
+    public final void emitString(String x) {
+        emitString0("\t");  // XXX REMOVE ME pretty-printing
+        emitString0(x);
+        emitString0(NEWLINE);
+    }
+
+    // XXX for pretty-printing
+    public final void emitString0(String x) {
+        codeBuffer.emitBytes(x.getBytes(), 0, x.length());
+    }
+
+    public void emitString(String s, int pos) {
+        codeBuffer.emitBytes(s.getBytes(), pos);
+    }
+
+    /**
+     * Closes this assembler. No extra data can be written to this assembler after this call.
+     * 
+     * @param trimmedCopy if {@code true}, then a copy of the underlying byte array up to (but not
+     *            including) {@code position()} is returned
+     * @return the data in this buffer or a trimmed copy if {@code trimmedCopy} is {@code true}
+     */
+    public byte[] close(boolean trimmedCopy) {
+        return codeBuffer.close(trimmedCopy);
+    }
+
+    public void bind(Label l) {
+        assert !l.isBound() : "can bind label only once";
+        l.bind(position());
+        l.patchInstructions(this);
+    }
+
+    public abstract void align(int modulus);
+
+    public abstract void jmp(Label l);
+
+    protected abstract void patchJumpTarget(int branch, int jumpTarget);
+
+    private Map<Label, String> nameMap;
+
+    /**
+     * Creates a name for a label.
+     * 
+     * @param l the label for which a name is being created
+     * @param id a label identifier that is unique with the scope of this assembler
+     * @return a label name in the form of "L123"
+     */
+    protected String createLabelName(Label l, int id) {
+        return "L" + id;
+    }
+
+    /**
+     * Gets a name for a label, creating it if it does not yet exist. By default, the returned name
+     * is only unique with the scope of this assembler.
+     */
+    public String nameOf(Label l) {
+        if (nameMap == null) {
+            nameMap = new HashMap<>();
+        }
+        String name = nameMap.get(l);
+        if (name == null) {
+            name = createLabelName(l, nameMap.size());
+            nameMap.put(l, name);
+        }
+        return name;
+    }
+
+    /**
+     * This is used by the CompilationResultBuilder to convert a {@link StackSlot} to an
+     * {@link AbstractAddress}.
+     */
+    public abstract AbstractAddress makeAddress(Register base, int displacement);
+
+    /**
+     * Returns a target specific placeholder address that can be used for code patching.
+     */
+    public abstract AbstractAddress getPlaceholder();
+}
--- a/graal/com.oracle.graal.asm/src/com/oracle/graal/asm/Buffer.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.asm/src/com/oracle/graal/asm/Buffer.java	Wed Mar 05 19:40:15 2014 -0800
@@ -28,7 +28,7 @@
  * Code buffer management for the assembler. Support for little endian and big endian architectures
  * is implemented using subclasses.
  */
-public abstract class Buffer {
+abstract class Buffer {
 
     protected byte[] data;
     protected int position;
@@ -105,19 +105,6 @@
         position = emitLong(b, position);
     }
 
-    private static final String NEWLINE = System.getProperty("line.separator");
-
-    public void emitString(String s) {
-        position = emitString("\t", position);  // XXX REMOVE ME pretty-printing
-        position = emitString(s, position);
-        position = emitString(NEWLINE, position);
-    }
-
-    // XXX for pretty-printing
-    public void emitString0(String s) {
-        emitBytes(s.getBytes(), 0, s.length());
-    }
-
     public int emitBytes(byte[] arr, int pos) {
         final int len = arr.length;
         final int newPos = pos + len;
@@ -140,10 +127,6 @@
 
     public abstract int emitLong(long b, int pos);
 
-    public int emitString(String s, int pos) {
-        return emitBytes(s.getBytes(), pos);
-    }
-
     public int getByte(int pos) {
         return data[pos] & 0xff;
     }
--- a/graal/com.oracle.graal.asm/src/com/oracle/graal/asm/Label.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.asm/src/com/oracle/graal/asm/Label.java	Wed Mar 05 19:40:15 2014 -0800
@@ -34,8 +34,7 @@
 
     /**
      * References to instructions that jump to this unresolved label. These instructions need to be
-     * patched when the label is bound using the {@link #patchInstructions(AbstractAssembler)}
-     * method.
+     * patched when the label is bound using the {@link #patchInstructions(Assembler)} method.
      */
     private ArrayList<Integer> patchPositions = null;
 
@@ -82,7 +81,7 @@
         patchPositions.add(branchLocation);
     }
 
-    protected void patchInstructions(AbstractAssembler masm) {
+    protected void patchInstructions(Assembler masm) {
         assert isBound() : "Label should be bound";
         if (patchPositions != null) {
             int target = position;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.baseline/src/com/oracle/graal/baseline/BaslineCompiler.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,710 @@
+/*
+ * 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 static com.oracle.graal.api.code.TypeCheckHints.*;
+import static com.oracle.graal.api.meta.DeoptimizationAction.*;
+import static com.oracle.graal.api.meta.DeoptimizationReason.*;
+import static com.oracle.graal.bytecode.Bytecodes.*;
+import static com.oracle.graal.phases.GraalOptions.*;
+import static java.lang.reflect.Modifier.*;
+
+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.api.meta.ResolvedJavaType.Representation;
+import com.oracle.graal.bytecode.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.java.*;
+import com.oracle.graal.java.BciBlockMapping.Block;
+import com.oracle.graal.java.BciBlockMapping.ExceptionDispatchBlock;
+import com.oracle.graal.java.GraphBuilderPhase.*;
+import com.oracle.graal.lir.*;
+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;
+import com.oracle.graal.nodes.type.*;
+import com.oracle.graal.nodes.util.*;
+import com.oracle.graal.phases.*;
+import com.oracle.graal.phases.tiers.*;
+
+/**
+ * The {@code GraphBuilder} class parses the bytecode of a method and builds the IR graph.
+ */
+@SuppressWarnings("all")
+public class BaslineCompiler {
+
+    public BaslineCompiler(GraphBuilderConfiguration graphBuilderConfig, MetaAccessProvider metaAccess) {
+        this.graphBuilderConfig = graphBuilderConfig;
+        this.metaAccess = metaAccess;
+    }
+
+    private final MetaAccessProvider metaAccess;
+    private ConstantPool constantPool;
+    private ResolvedJavaMethod method;
+    private int entryBCI;
+    private ProfilingInfo profilingInfo;
+    private BytecodeStream stream;           // the bytecode stream
+
+    private Block currentBlock;
+
+    private ValueNode methodSynchronizedObject;
+    private ExceptionDispatchBlock unwindBlock;
+
+    private final GraphBuilderConfiguration graphBuilderConfig;
+    private Block[] loopHeaders;
+
+    /**
+     * Meters the number of actual bytecodes parsed.
+     */
+    public static final DebugMetric BytecodesParsed = Debug.metric("BytecodesParsed");
+
+    protected ResolvedJavaMethod getMethod() {
+        return method;
+    }
+
+    public LIR generate(ResolvedJavaMethod method, int entryBCI) {
+        this.method = method;
+        this.entryBCI = entryBCI;
+        profilingInfo = method.getProfilingInfo();
+        assert method.getCode() != null : "method must contain bytecodes: " + method;
+        this.stream = new BytecodeStream(method.getCode());
+        this.constantPool = method.getConstantPool();
+        unwindBlock = null;
+        methodSynchronizedObject = null;
+        TTY.Filter filter = new TTY.Filter(PrintFilter.getValue(), method);
+        try {
+            build();
+        } finally {
+            filter.remove();
+        }
+        return null;
+    }
+
+    protected void build() {
+        if (PrintProfilingInformation.getValue()) {
+            TTY.println("Profiling info for " + MetaUtil.format("%H.%n(%p)", method));
+            TTY.println(MetaUtil.indent(MetaUtil.profileToString(profilingInfo, method, CodeUtil.NEW_LINE), "  "));
+        }
+
+        Indent indent = Debug.logAndIndent("build graph for %s", method);
+
+        // compute the block map, setup exception handlers and get the entrypoint(s)
+        BciBlockMapping blockMap = BciBlockMapping.create(method);
+        loopHeaders = blockMap.loopHeaders;
+
+        if (isSynchronized(method.getModifiers())) {
+            throw GraalInternalError.unimplemented("Handle synchronized methods");
+        }
+
+        // TODO: clear non live locals
+
+        currentBlock = blockMap.startBlock;
+        if (blockMap.startBlock.isLoopHeader) {
+            throw GraalInternalError.unimplemented("Handle start block as loop header");
+        }
+
+        for (Block block : blockMap.blocks) {
+            processBlock(block);
+        }
+
+        indent.outdent();
+    }
+
+    public BytecodeStream stream() {
+        return stream;
+    }
+
+    public int bci() {
+        return stream.currentBCI();
+    }
+
+    private void loadLocal(int index, Kind kind) {
+        throw GraalInternalError.unimplemented();
+    }
+
+    private void storeLocal(Kind kind, int index) {
+        throw GraalInternalError.unimplemented();
+    }
+
+    /**
+     * @param type the unresolved type of the constant
+     */
+    protected void handleUnresolvedLoadConstant(JavaType type) {
+        throw GraalInternalError.unimplemented();
+    }
+
+    /**
+     * @param type the unresolved type of the type check
+     * @param object the object value whose type is being checked against {@code type}
+     */
+    protected void handleUnresolvedCheckCast(JavaType type, ValueNode object) {
+        throw GraalInternalError.unimplemented();
+    }
+
+    /**
+     * @param type the unresolved type of the type check
+     * @param object the object value whose type is being checked against {@code type}
+     */
+    protected void handleUnresolvedInstanceOf(JavaType type, ValueNode object) {
+        throw GraalInternalError.unimplemented();
+    }
+
+    /**
+     * @param type the type being instantiated
+     */
+    protected void handleUnresolvedNewInstance(JavaType type) {
+        throw GraalInternalError.unimplemented();
+    }
+
+    /**
+     * @param type the type of the array being instantiated
+     * @param length the length of the array
+     */
+    protected void handleUnresolvedNewObjectArray(JavaType type, ValueNode length) {
+        throw GraalInternalError.unimplemented();
+    }
+
+    /**
+     * @param type the type being instantiated
+     * @param dims the dimensions for the multi-array
+     */
+    protected void handleUnresolvedNewMultiArray(JavaType type, ValueNode[] dims) {
+        throw GraalInternalError.unimplemented();
+    }
+
+    /**
+     * @param field the unresolved field
+     * @param receiver the object containing the field or {@code null} if {@code field} is static
+     */
+    protected void handleUnresolvedLoadField(JavaField field, ValueNode receiver) {
+        throw GraalInternalError.unimplemented();
+    }
+
+    /**
+     * @param field the unresolved field
+     * @param value the value being stored to the field
+     * @param receiver the object containing the field or {@code null} if {@code field} is static
+     */
+    protected void handleUnresolvedStoreField(JavaField field, ValueNode value, ValueNode receiver) {
+        throw GraalInternalError.unimplemented();
+    }
+
+    /**
+     * @param representation
+     * @param type
+     */
+    protected void handleUnresolvedExceptionType(Representation representation, JavaType type) {
+        throw GraalInternalError.unimplemented();
+    }
+
+    protected void handleUnresolvedInvoke(JavaMethod javaMethod, InvokeKind invokeKind) {
+        throw GraalInternalError.unimplemented();
+    }
+
+    private DispatchBeginNode handleException(ValueNode exceptionObject, int bci) {
+        throw GraalInternalError.unimplemented();
+    }
+
+    private void genLoadConstant(int cpi, int opcode) {
+        throw GraalInternalError.unimplemented();
+    }
+
+    private void genLoadIndexed(Kind kind) {
+        throw GraalInternalError.unimplemented();
+    }
+
+    private void genStoreIndexed(Kind kind) {
+        throw GraalInternalError.unimplemented();
+    }
+
+    private void stackOp(int opcode) {
+        throw GraalInternalError.unimplemented();
+    }
+
+    private void genArithmeticOp(Kind result, int opcode) {
+        throw GraalInternalError.unimplemented();
+    }
+
+    private void genIntegerDivOp(Kind result, int opcode) {
+        throw GraalInternalError.unimplemented();
+    }
+
+    private void genNegateOp(Kind kind) {
+        throw GraalInternalError.unimplemented();
+    }
+
+    private void genShiftOp(Kind kind, int opcode) {
+        throw GraalInternalError.unimplemented();
+    }
+
+    private void genLogicOp(Kind kind, int opcode) {
+        throw GraalInternalError.unimplemented();
+    }
+
+    private void genCompareOp(Kind kind, boolean isUnorderedLess) {
+        throw GraalInternalError.unimplemented();
+    }
+
+    private void genFloatConvert(FloatConvert op, Kind from, Kind to) {
+        throw GraalInternalError.unimplemented();
+    }
+
+    private void genSignExtend(Kind from, Kind to) {
+        throw GraalInternalError.unimplemented();
+    }
+
+    private void genZeroExtend(Kind from, Kind to) {
+        throw GraalInternalError.unimplemented();
+    }
+
+    private void genNarrow(Kind from, Kind to) {
+        throw GraalInternalError.unimplemented();
+    }
+
+    private void genIncrement() {
+        throw GraalInternalError.unimplemented();
+    }
+
+    private void genGoto() {
+        throw GraalInternalError.unimplemented();
+    }
+
+    private void genIfZero(Condition cond) {
+        throw GraalInternalError.unimplemented();
+    }
+
+    private void genIfNull(Condition cond) {
+        throw GraalInternalError.unimplemented();
+    }
+
+    private void genIfSame(Kind kind, Condition cond) {
+        throw GraalInternalError.unimplemented();
+    }
+
+    private void genThrow() {
+        throw GraalInternalError.unimplemented();
+    }
+
+    private JavaType lookupType(int cpi, int bytecode) {
+        eagerResolvingForSnippets(cpi, bytecode);
+        JavaType result = constantPool.lookupType(cpi, bytecode);
+        assert !graphBuilderConfig.unresolvedIsError() || result instanceof ResolvedJavaType;
+        return result;
+    }
+
+    private JavaMethod lookupMethod(int cpi, int opcode) {
+        eagerResolvingForSnippets(cpi, opcode);
+        JavaMethod result = constantPool.lookupMethod(cpi, opcode);
+        /*
+         * assert !graphBuilderConfig.unresolvedIsError() || ((result instanceof ResolvedJavaMethod)
+         * && ((ResolvedJavaMethod) result).getDeclaringClass().isInitialized()) : result;
+         */
+        return result;
+    }
+
+    private JavaField lookupField(int cpi, int opcode) {
+        eagerResolvingForSnippets(cpi, opcode);
+        JavaField result = constantPool.lookupField(cpi, opcode);
+        assert !graphBuilderConfig.unresolvedIsError() || (result instanceof ResolvedJavaField && ((ResolvedJavaField) result).getDeclaringClass().isInitialized()) : result;
+        return result;
+    }
+
+    private Object lookupConstant(int cpi, int opcode) {
+        eagerResolvingForSnippets(cpi, opcode);
+        Object result = constantPool.lookupConstant(cpi);
+        assert !graphBuilderConfig.eagerResolving() || !(result instanceof JavaType) || (result instanceof ResolvedJavaType);
+        return result;
+    }
+
+    private void eagerResolvingForSnippets(int cpi, int bytecode) {
+        if (graphBuilderConfig.eagerResolving()) {
+            constantPool.loadReferencedType(cpi, bytecode);
+        }
+    }
+
+    private JavaTypeProfile getProfileForTypeCheck(ResolvedJavaType type) {
+        if (!canHaveSubtype(type)) {
+            return null;
+        } else {
+            return profilingInfo.getTypeProfile(bci());
+        }
+    }
+
+    private void genCheckCast() {
+        throw GraalInternalError.unimplemented();
+    }
+
+    private void genInstanceOf() {
+        throw GraalInternalError.unimplemented();
+    }
+
+    void genNewInstance(int cpi) {
+        throw GraalInternalError.unimplemented();
+    }
+
+    protected NewInstanceNode createNewInstance(ResolvedJavaType type, boolean fillContents) {
+        return new NewInstanceNode(type, fillContents);
+    }
+
+    private void genNewPrimitiveArray(int typeCode) {
+        throw GraalInternalError.unimplemented();
+    }
+
+    private void genNewObjectArray(int cpi) {
+        throw GraalInternalError.unimplemented();
+    }
+
+    private void genNewMultiArray(int cpi) {
+        throw GraalInternalError.unimplemented();
+    }
+
+    private void genGetField(JavaField field) {
+        throw GraalInternalError.unimplemented();
+    }
+
+    private void genPutField(JavaField field) {
+        throw GraalInternalError.unimplemented();
+    }
+
+    private void genGetStatic(JavaField field) {
+        throw GraalInternalError.unimplemented();
+    }
+
+    private void genPutStatic(JavaField field) {
+        throw GraalInternalError.unimplemented();
+    }
+
+    private void genInvokeStatic(JavaMethod target) {
+        throw GraalInternalError.unimplemented();
+    }
+
+    private void genInvokeInterface(JavaMethod target) {
+        throw GraalInternalError.unimplemented();
+    }
+
+    private void genInvokeDynamic(JavaMethod target) {
+        throw GraalInternalError.unimplemented();
+    }
+
+    private void genInvokeVirtual(JavaMethod target) {
+        throw GraalInternalError.unimplemented();
+    }
+
+    private void genInvokeSpecial(JavaMethod target) {
+        throw GraalInternalError.unimplemented();
+    }
+
+    private void genJsr(int dest) {
+        throw GraalInternalError.unimplemented();
+    }
+
+    private void genRet(int localIndex) {
+        throw GraalInternalError.unimplemented();
+    }
+
+    private void genSwitch(BytecodeSwitch bs) {
+        throw GraalInternalError.unimplemented();
+    }
+
+    private void processBlock(Block block) {
+        Indent indent = Debug.logAndIndent("Parsing block %s  firstInstruction: %s  loopHeader: %b", block, block.firstInstruction, block.isLoopHeader);
+        currentBlock = block;
+        iterateBytecodesForBlock(block);
+        indent.outdent();
+    }
+
+    private void createExceptionDispatch(ExceptionDispatchBlock block) {
+        throw GraalInternalError.unimplemented();
+    }
+
+    private void iterateBytecodesForBlock(Block block) {
+
+        int endBCI = stream.endBCI();
+
+        stream.setBCI(block.startBci);
+        int bci = block.startBci;
+        BytecodesParsed.add(block.endBci - bci);
+
+        while (bci < endBCI) {
+
+            // read the opcode
+            int opcode = stream.currentBC();
+            traceInstruction(bci, opcode, bci == block.startBci);
+            if (bci == entryBCI) {
+                throw GraalInternalError.unimplemented();
+            }
+            processBytecode(bci, opcode);
+
+            stream.next();
+            bci = stream.currentBCI();
+        }
+    }
+
+    private void processBytecode(int bci, int opcode) {
+        int cpi;
+
+        // Checkstyle: stop
+        // @formatter:off
+        switch (opcode) {
+            case NOP            : /* nothing to do */ break;
+//            case ACONST_NULL    : frameState.apush(appendConstant(Constant.NULL_OBJECT)); break;
+//            case ICONST_M1      : frameState.ipush(appendConstant(Constant.INT_MINUS_1)); break;
+//            case ICONST_0       : frameState.ipush(appendConstant(Constant.INT_0)); break;
+//            case ICONST_1       : frameState.ipush(appendConstant(Constant.INT_1)); break;
+//            case ICONST_2       : frameState.ipush(appendConstant(Constant.INT_2)); break;
+//            case ICONST_3       : frameState.ipush(appendConstant(Constant.INT_3)); break;
+//            case ICONST_4       : frameState.ipush(appendConstant(Constant.INT_4)); break;
+//            case ICONST_5       : frameState.ipush(appendConstant(Constant.INT_5)); break;
+//            case LCONST_0       : frameState.lpush(appendConstant(Constant.LONG_0)); break;
+//            case LCONST_1       : frameState.lpush(appendConstant(Constant.LONG_1)); break;
+//            case FCONST_0       : frameState.fpush(appendConstant(Constant.FLOAT_0)); break;
+//            case FCONST_1       : frameState.fpush(appendConstant(Constant.FLOAT_1)); break;
+//            case FCONST_2       : frameState.fpush(appendConstant(Constant.FLOAT_2)); break;
+//            case DCONST_0       : frameState.dpush(appendConstant(Constant.DOUBLE_0)); break;
+//            case DCONST_1       : frameState.dpush(appendConstant(Constant.DOUBLE_1)); break;
+//            case BIPUSH         : frameState.ipush(appendConstant(Constant.forInt(stream.readByte()))); break;
+//            case SIPUSH         : frameState.ipush(appendConstant(Constant.forInt(stream.readShort()))); break;
+            case LDC            : // fall through
+            case LDC_W          : // fall through
+            case LDC2_W         : genLoadConstant(stream.readCPI(), opcode); break;
+            case ILOAD          : loadLocal(stream.readLocalIndex(), Kind.Int); break;
+            case LLOAD          : loadLocal(stream.readLocalIndex(), Kind.Long); break;
+            case FLOAD          : loadLocal(stream.readLocalIndex(), Kind.Float); break;
+            case DLOAD          : loadLocal(stream.readLocalIndex(), Kind.Double); break;
+            case ALOAD          : loadLocal(stream.readLocalIndex(), Kind.Object); break;
+            case ILOAD_0        : // fall through
+            case ILOAD_1        : // fall through
+            case ILOAD_2        : // fall through
+            case ILOAD_3        : loadLocal(opcode - ILOAD_0, Kind.Int); break;
+            case LLOAD_0        : // fall through
+            case LLOAD_1        : // fall through
+            case LLOAD_2        : // fall through
+            case LLOAD_3        : loadLocal(opcode - LLOAD_0, Kind.Long); break;
+            case FLOAD_0        : // fall through
+            case FLOAD_1        : // fall through
+            case FLOAD_2        : // fall through
+            case FLOAD_3        : loadLocal(opcode - FLOAD_0, Kind.Float); break;
+            case DLOAD_0        : // fall through
+            case DLOAD_1        : // fall through
+            case DLOAD_2        : // fall through
+            case DLOAD_3        : loadLocal(opcode - DLOAD_0, Kind.Double); break;
+            case ALOAD_0        : // fall through
+            case ALOAD_1        : // fall through
+            case ALOAD_2        : // fall through
+            case ALOAD_3        : loadLocal(opcode - ALOAD_0, Kind.Object); break;
+            case IALOAD         : genLoadIndexed(Kind.Int   ); break;
+            case LALOAD         : genLoadIndexed(Kind.Long  ); break;
+            case FALOAD         : genLoadIndexed(Kind.Float ); break;
+            case DALOAD         : genLoadIndexed(Kind.Double); break;
+            case AALOAD         : genLoadIndexed(Kind.Object); break;
+            case BALOAD         : genLoadIndexed(Kind.Byte  ); break;
+            case CALOAD         : genLoadIndexed(Kind.Char  ); break;
+            case SALOAD         : genLoadIndexed(Kind.Short ); break;
+            case ISTORE         : storeLocal(Kind.Int, stream.readLocalIndex()); break;
+            case LSTORE         : storeLocal(Kind.Long, stream.readLocalIndex()); break;
+            case FSTORE         : storeLocal(Kind.Float, stream.readLocalIndex()); break;
+            case DSTORE         : storeLocal(Kind.Double, stream.readLocalIndex()); break;
+            case ASTORE         : storeLocal(Kind.Object, stream.readLocalIndex()); break;
+            case ISTORE_0       : // fall through
+            case ISTORE_1       : // fall through
+            case ISTORE_2       : // fall through
+            case ISTORE_3       : storeLocal(Kind.Int, opcode - ISTORE_0); break;
+            case LSTORE_0       : // fall through
+            case LSTORE_1       : // fall through
+            case LSTORE_2       : // fall through
+            case LSTORE_3       : storeLocal(Kind.Long, opcode - LSTORE_0); break;
+            case FSTORE_0       : // fall through
+            case FSTORE_1       : // fall through
+            case FSTORE_2       : // fall through
+            case FSTORE_3       : storeLocal(Kind.Float, opcode - FSTORE_0); break;
+            case DSTORE_0       : // fall through
+            case DSTORE_1       : // fall through
+            case DSTORE_2       : // fall through
+            case DSTORE_3       : storeLocal(Kind.Double, opcode - DSTORE_0); break;
+            case ASTORE_0       : // fall through
+            case ASTORE_1       : // fall through
+            case ASTORE_2       : // fall through
+            case ASTORE_3       : storeLocal(Kind.Object, opcode - ASTORE_0); break;
+            case IASTORE        : genStoreIndexed(Kind.Int   ); break;
+            case LASTORE        : genStoreIndexed(Kind.Long  ); break;
+            case FASTORE        : genStoreIndexed(Kind.Float ); break;
+            case DASTORE        : genStoreIndexed(Kind.Double); break;
+            case AASTORE        : genStoreIndexed(Kind.Object); break;
+            case BASTORE        : genStoreIndexed(Kind.Byte  ); break;
+            case CASTORE        : genStoreIndexed(Kind.Char  ); break;
+            case SASTORE        : genStoreIndexed(Kind.Short ); break;
+            case POP            : // fall through
+            case POP2           : // fall through
+            case DUP            : // fall through
+            case DUP_X1         : // fall through
+            case DUP_X2         : // fall through
+            case DUP2           : // fall through
+            case DUP2_X1        : // fall through
+            case DUP2_X2        : // fall through
+            case SWAP           : stackOp(opcode); break;
+            case IADD           : // fall through
+            case ISUB           : // fall through
+            case IMUL           : genArithmeticOp(Kind.Int, opcode); break;
+            case IDIV           : // fall through
+            case IREM           : genIntegerDivOp(Kind.Int, opcode); break;
+            case LADD           : // fall through
+            case LSUB           : // fall through
+            case LMUL           : genArithmeticOp(Kind.Long, opcode); break;
+            case LDIV           : // fall through
+            case LREM           : genIntegerDivOp(Kind.Long, opcode); break;
+            case FADD           : // fall through
+            case FSUB           : // fall through
+            case FMUL           : // fall through
+            case FDIV           : // fall through
+            case FREM           : genArithmeticOp(Kind.Float, opcode); break;
+            case DADD           : // fall through
+            case DSUB           : // fall through
+            case DMUL           : // fall through
+            case DDIV           : // fall through
+            case DREM           : genArithmeticOp(Kind.Double, opcode); break;
+            case INEG           : genNegateOp(Kind.Int); break;
+            case LNEG           : genNegateOp(Kind.Long); break;
+            case FNEG           : genNegateOp(Kind.Float); break;
+            case DNEG           : genNegateOp(Kind.Double); break;
+            case ISHL           : // fall through
+            case ISHR           : // fall through
+            case IUSHR          : genShiftOp(Kind.Int, opcode); break;
+            case IAND           : // fall through
+            case IOR            : // fall through
+            case IXOR           : genLogicOp(Kind.Int, opcode); break;
+            case LSHL           : // fall through
+            case LSHR           : // fall through
+            case LUSHR          : genShiftOp(Kind.Long, opcode); break;
+            case LAND           : // fall through
+            case LOR            : // fall through
+            case LXOR           : genLogicOp(Kind.Long, opcode); break;
+            case IINC           : genIncrement(); break;
+            case I2F            : genFloatConvert(FloatConvert.I2F, Kind.Int, Kind.Float); break;
+            case I2D            : genFloatConvert(FloatConvert.I2D, Kind.Int, Kind.Double); break;
+            case L2F            : genFloatConvert(FloatConvert.L2F, Kind.Long, Kind.Float); break;
+            case L2D            : genFloatConvert(FloatConvert.L2D, Kind.Long, Kind.Double); break;
+            case F2I            : genFloatConvert(FloatConvert.F2I, Kind.Float, Kind.Int); break;
+            case F2L            : genFloatConvert(FloatConvert.F2L, Kind.Float, Kind.Long); break;
+            case F2D            : genFloatConvert(FloatConvert.F2D, Kind.Float, Kind.Double); break;
+            case D2I            : genFloatConvert(FloatConvert.D2I, Kind.Double, Kind.Int); break;
+            case D2L            : genFloatConvert(FloatConvert.D2L, Kind.Double, Kind.Long); break;
+            case D2F            : genFloatConvert(FloatConvert.D2F, Kind.Double, Kind.Float); break;
+            case L2I            : genNarrow(Kind.Long, Kind.Int); break;
+            case I2L            : genSignExtend(Kind.Int, Kind.Long); break;
+            case I2B            : genSignExtend(Kind.Byte, Kind.Int); break;
+            case I2S            : genSignExtend(Kind.Short, Kind.Int); break;
+            case I2C            : genZeroExtend(Kind.Char, Kind.Int); break;
+            case LCMP           : genCompareOp(Kind.Long, false); break;
+            case FCMPL          : genCompareOp(Kind.Float, true); break;
+            case FCMPG          : genCompareOp(Kind.Float, false); break;
+            case DCMPL          : genCompareOp(Kind.Double, true); break;
+            case DCMPG          : genCompareOp(Kind.Double, false); break;
+            case IFEQ           : genIfZero(Condition.EQ); break;
+            case IFNE           : genIfZero(Condition.NE); break;
+            case IFLT           : genIfZero(Condition.LT); break;
+            case IFGE           : genIfZero(Condition.GE); break;
+            case IFGT           : genIfZero(Condition.GT); break;
+            case IFLE           : genIfZero(Condition.LE); break;
+            case IF_ICMPEQ      : genIfSame(Kind.Int, Condition.EQ); break;
+            case IF_ICMPNE      : genIfSame(Kind.Int, Condition.NE); break;
+            case IF_ICMPLT      : genIfSame(Kind.Int, Condition.LT); break;
+            case IF_ICMPGE      : genIfSame(Kind.Int, Condition.GE); break;
+            case IF_ICMPGT      : genIfSame(Kind.Int, Condition.GT); break;
+            case IF_ICMPLE      : genIfSame(Kind.Int, Condition.LE); break;
+            case IF_ACMPEQ      : genIfSame(Kind.Object, Condition.EQ); break;
+            case IF_ACMPNE      : genIfSame(Kind.Object, Condition.NE); break;
+            case GOTO           : genGoto(); break;
+            case JSR            : genJsr(stream.readBranchDest()); break;
+            case RET            : genRet(stream.readLocalIndex()); break;
+            case TABLESWITCH    : genSwitch(new BytecodeTableSwitch(stream(), bci())); break;
+            case LOOKUPSWITCH   : genSwitch(new BytecodeLookupSwitch(stream(), bci())); break;
+//            case IRETURN        : genReturn(frameState.ipop()); break;
+//            case LRETURN        : genReturn(frameState.lpop()); break;
+//            case FRETURN        : genReturn(frameState.fpop()); break;
+//            case DRETURN        : genReturn(frameState.dpop()); break;
+//            case ARETURN        : genReturn(frameState.apop()); break;
+//            case RETURN         : genReturn(null); break;
+            case GETSTATIC      : cpi = stream.readCPI(); genGetStatic(lookupField(cpi, opcode)); break;
+            case PUTSTATIC      : cpi = stream.readCPI(); genPutStatic(lookupField(cpi, opcode)); break;
+            case GETFIELD       : cpi = stream.readCPI(); genGetField(lookupField(cpi, opcode)); break;
+            case PUTFIELD       : cpi = stream.readCPI(); genPutField(lookupField(cpi, opcode)); break;
+            case INVOKEVIRTUAL  : cpi = stream.readCPI(); genInvokeVirtual(lookupMethod(cpi, opcode)); break;
+            case INVOKESPECIAL  : cpi = stream.readCPI(); genInvokeSpecial(lookupMethod(cpi, opcode)); break;
+            case INVOKESTATIC   : cpi = stream.readCPI(); genInvokeStatic(lookupMethod(cpi, opcode)); break;
+            case INVOKEINTERFACE: cpi = stream.readCPI(); genInvokeInterface(lookupMethod(cpi, opcode)); break;
+            case INVOKEDYNAMIC  : cpi = stream.readCPI4(); genInvokeDynamic(lookupMethod(cpi, opcode)); break;
+            case NEW            : genNewInstance(stream.readCPI()); break;
+            case NEWARRAY       : genNewPrimitiveArray(stream.readLocalIndex()); break;
+            case ANEWARRAY      : genNewObjectArray(stream.readCPI()); break;
+            case ARRAYLENGTH    : genArrayLength(); break;
+            case ATHROW         : genThrow(); break;
+            case CHECKCAST      : genCheckCast(); break;
+            case INSTANCEOF     : genInstanceOf(); break;
+//            case MONITORENTER   : genMonitorEnter(frameState.apop()); break;
+//            case MONITOREXIT    : genMonitorExit(frameState.apop(), null); break;
+            case MULTIANEWARRAY : genNewMultiArray(stream.readCPI()); break;
+            case IFNULL         : genIfNull(Condition.EQ); break;
+            case IFNONNULL      : genIfNull(Condition.NE); break;
+            case GOTO_W         : genGoto(); break;
+            case JSR_W          : genJsr(stream.readBranchDest()); break;
+            case BREAKPOINT:
+                throw new BailoutException("concurrent setting of breakpoint");
+            default:
+                throw new BailoutException("Unsupported opcode " + opcode + " (" + nameOf(opcode) + ") [bci=" + bci + "]");
+        }
+        // @formatter:on
+        // Checkstyle: resume
+    }
+
+    private void traceInstruction(int bci, int opcode, boolean blockStart) {
+        if (Debug.isLogEnabled()) {
+            StringBuilder sb = new StringBuilder(40);
+            sb.append(blockStart ? '+' : '|');
+            if (bci < 10) {
+                sb.append("  ");
+            } else if (bci < 100) {
+                sb.append(' ');
+            }
+            sb.append(bci).append(": ").append(Bytecodes.nameOf(opcode));
+            for (int i = bci + 1; i < stream.nextBCI(); ++i) {
+                sb.append(' ').append(stream.readUByte(i));
+            }
+            if (!currentBlock.jsrScope.isEmpty()) {
+                sb.append(' ').append(currentBlock.jsrScope);
+            }
+            Debug.log(sb.toString());
+        }
+    }
+
+    private void genArrayLength() {
+        throw GraalInternalError.unimplemented();
+    }
+}
--- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java	Wed Mar 05 19:40:15 2014 -0800
@@ -57,13 +57,12 @@
 import com.oracle.graal.lir.amd64.AMD64ControlFlow.ReturnOp;
 import com.oracle.graal.lir.amd64.AMD64ControlFlow.StrategySwitchOp;
 import com.oracle.graal.lir.amd64.AMD64ControlFlow.TableSwitchOp;
-import com.oracle.graal.lir.amd64.AMD64Move.LeaOp;
 import com.oracle.graal.lir.amd64.AMD64Move.MembarOp;
-import com.oracle.graal.lir.amd64.AMD64Move.MoveFromRegOp;
-import com.oracle.graal.lir.amd64.AMD64Move.MoveToRegOp;
 import com.oracle.graal.lir.amd64.AMD64Move.StackLeaOp;
 import com.oracle.graal.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.*;
 
 /**
@@ -77,17 +76,8 @@
     private static final RegisterValue RDX_L = AMD64.rdx.asValue(Kind.Long);
     private static final RegisterValue RCX_I = AMD64.rcx.asValue(Kind.Int);
 
-    private class AMD64SpillMoveFactory implements LIR.SpillMoveFactory {
-
-        @Override
-        public LIRInstruction createMove(AllocatableValue result, Value input) {
-            return AMD64LIRGenerator.this.createMove(result, input);
-        }
-    }
-
     public AMD64LIRGenerator(StructuredGraph graph, Providers providers, FrameMap frameMap, CallingConvention cc, LIR lir) {
         super(graph, providers, frameMap, cc, lir);
-        lir.spillMoveFactory = new AMD64SpillMoveFactory();
     }
 
     @Override
@@ -125,24 +115,20 @@
 
     @Override
     public Variable emitMove(Value input) {
-        Variable result = newVariable(input.getPlatformKind());
+        PlatformKind kind;
+        if (input instanceof Constant) {
+            kind = input.getKind().getStackKind();
+        } else {
+            kind = input.getPlatformKind();
+        }
+        Variable result = newVariable(kind);
         emitMove(result, input);
         return result;
     }
 
-    protected AMD64LIRInstruction createMove(AllocatableValue dst, Value src) {
-        if (src instanceof AMD64AddressValue) {
-            return new LeaOp(dst, (AMD64AddressValue) src);
-        } else if (isRegister(src) || isStackSlot(dst)) {
-            return new MoveFromRegOp(dst, src);
-        } else {
-            return new MoveToRegOp(dst, src);
-        }
-    }
-
     @Override
     public void emitMove(AllocatableValue dst, Value src) {
-        append(createMove(dst, src));
+        append(AMD64Move.createMove(dst, src));
     }
 
     @Override
@@ -172,7 +158,7 @@
 
             } else if (scaleEnum == null) {
                 /* Scale value that architecture cannot handle, so scale manually. */
-                Value longIndex = index.getKind().getStackKind() == Kind.Int ? emitConvert(Kind.Int, Kind.Long, index) : index;
+                Value longIndex = index.getKind() == Kind.Long ? index : emitSignExtend(index, 32, 64);
                 if (CodeUtil.isPowerOf2(scale)) {
                     indexRegister = emitShl(longIndex, Constant.forLong(CodeUtil.log2(scale)));
                 } else {
@@ -229,18 +215,18 @@
     }
 
     @Override
-    public void emitCompareBranch(Value left, Value right, Condition cond, boolean unorderedIsTrue, LabelRef trueLabel, LabelRef falseLabel) {
+    public void emitCompareBranch(Value left, Value right, Condition cond, boolean unorderedIsTrue, LabelRef trueLabel, LabelRef falseLabel, double trueLabelProbability) {
         boolean mirrored = emitCompare(left, right);
         Condition finalCondition = mirrored ? cond.mirror() : cond;
         switch (left.getKind().getStackKind()) {
             case Int:
             case Long:
             case Object:
-                append(new BranchOp(finalCondition, trueLabel, falseLabel));
+                append(new BranchOp(finalCondition, trueLabel, falseLabel, trueLabelProbability));
                 break;
             case Float:
             case Double:
-                append(new FloatBranchOp(finalCondition, unorderedIsTrue, trueLabel, falseLabel));
+                append(new FloatBranchOp(finalCondition, unorderedIsTrue, trueLabel, falseLabel, trueLabelProbability));
                 break;
             default:
                 throw GraalInternalError.shouldNotReachHere("" + left.getKind());
@@ -255,22 +241,14 @@
     }
 
     @Override
-    public void emitOverflowCheckBranch(LabelRef overflow, LabelRef noOverflow, boolean negated) {
-        if (negated) {
-            append(new BranchOp(ConditionFlag.NoOverflow, noOverflow, overflow));
-        } else {
-            append(new BranchOp(ConditionFlag.Overflow, overflow, noOverflow));
-        }
+    public void emitOverflowCheckBranch(LabelRef overflow, LabelRef noOverflow, double overflowProbability) {
+        append(new BranchOp(ConditionFlag.Overflow, overflow, noOverflow, overflowProbability));
     }
 
     @Override
-    public void emitIntegerTestBranch(Value left, Value right, boolean negated, LabelRef trueDestination, LabelRef falseDestination) {
+    public void emitIntegerTestBranch(Value left, Value right, LabelRef trueDestination, LabelRef falseDestination, double trueDestinationProbability) {
         emitIntegerTest(left, right);
-        if (negated) {
-            append(new BranchOp(Condition.NE, falseDestination, trueDestination));
-        } else {
-            append(new BranchOp(Condition.EQ, trueDestination, falseDestination));
-        }
+        append(new BranchOp(Condition.EQ, trueDestination, falseDestination, trueDestinationProbability));
     }
 
     @Override
@@ -361,7 +339,7 @@
 
     @Override
     public void emitNullCheck(ValueNode v, DeoptimizingNode deoping) {
-        assert v.kind() == Kind.Object;
+        assert v.stamp() instanceof ObjectStamp;
         append(new AMD64Move.NullCheckOp(load(operand(v)), state(deoping)));
     }
 
@@ -714,181 +692,153 @@
         }
     }
 
-    private AllocatableValue emitConvertMove(Kind kind, AllocatableValue input) {
-        Variable result = newVariable(kind);
-        emitMove(result, input);
-        return result;
-    }
-
-    private AllocatableValue emitConvert1Op(Kind kind, AMD64Arithmetic op, AllocatableValue input) {
+    private AllocatableValue emitConvert1Op(PlatformKind kind, AMD64Arithmetic op, AllocatableValue input) {
         Variable result = newVariable(kind);
         append(new Unary1Op(op, result, input));
         return result;
     }
 
-    private AllocatableValue emitConvert2Op(Kind kind, AMD64Arithmetic op, AllocatableValue input) {
+    private AllocatableValue emitConvert2Op(PlatformKind kind, AMD64Arithmetic op, AllocatableValue input) {
         Variable result = newVariable(kind);
         append(new Unary2Op(op, result, input));
         return result;
     }
 
     @Override
-    public AllocatableValue emitConvert(Kind from, Kind to, Value inputVal) {
-        assert inputVal.getKind() == from.getStackKind();
+    public Value emitReinterpret(PlatformKind to, Value inputVal) {
+        Kind from = inputVal.getKind();
+        if (to == from) {
+            return inputVal;
+        }
 
         AllocatableValue input = asAllocatable(inputVal);
-        if (from == to) {
-            return input;
-        }
-        switch (to) {
-            case Byte:
-                switch (from) {
-                    case Short:
-                    case Char:
-                    case Int:
-                    case Long:
-                        return emitConvert2Op(to, I2B, input);
-                    case Float:
-                    case Double:
-                        AllocatableValue intVal = emitConvert(from, Kind.Int, inputVal);
-                        return emitConvert(Kind.Int, to, intVal);
-                }
-                break;
-            case Char:
-                switch (from) {
-                    case Byte:
-                    case Short:
-                    case Int:
-                    case Long:
-                        return emitConvert1Op(to, I2C, input);
-                    case Float:
-                    case Double:
-                        AllocatableValue intVal = emitConvert(from, Kind.Int, inputVal);
-                        return emitConvert(Kind.Int, to, intVal);
-                }
-                break;
-            case Short:
-                switch (from) {
-                    case Byte:
-                    case Char:
-                    case Int:
-                    case Long:
-                        return emitConvert2Op(to, I2S, input);
-                    case Float:
-                    case Double:
-                        AllocatableValue intVal = emitConvert(from, Kind.Int, inputVal);
-                        return emitConvert(Kind.Int, to, intVal);
-                }
-                break;
+        /*
+         * Conversions between integer to floating point types require moves between CPU and FPU
+         * registers.
+         */
+        switch ((Kind) to) {
             case Int:
                 switch (from) {
-                    case Byte:
-                    case Short:
-                    case Char:
-                        return emitConvertMove(to, input);
-                    case Long:
-                        return emitConvert1Op(to, L2I, input);
                     case Float:
-                        return emitConvert2Op(to, F2I, input);
-                    case Double:
-                        return emitConvert2Op(to, D2I, input);
+                        return emitConvert2Op(to, MOV_F2I, input);
                 }
                 break;
             case Long:
                 switch (from) {
-                    case Byte:
-                    case Short:
-                    case Char:
-                    case Int:
-                        return emitConvert2Op(to, I2L, input);
-                    case Float:
-                        return emitConvert2Op(to, F2L, input);
                     case Double:
-                        return emitConvert2Op(to, D2L, input);
+                        return emitConvert2Op(to, MOV_D2L, input);
                 }
                 break;
             case Float:
                 switch (from) {
-                    case Byte:
-                    case Short:
-                    case Char:
                     case Int:
-                        return emitConvert2Op(to, I2F, input);
-                    case Long:
-                        return emitConvert2Op(to, L2F, input);
-                    case Double:
-                        return emitConvert2Op(to, D2F, input);
+                        return emitConvert2Op(to, MOV_I2F, input);
                 }
                 break;
             case Double:
                 switch (from) {
-                    case Byte:
-                    case Short:
-                    case Char:
-                    case Int:
-                        return emitConvert2Op(to, I2D, input);
                     case Long:
-                        return emitConvert2Op(to, L2D, input);
-                    case Float:
-                        return emitConvert2Op(to, F2D, input);
+                        return emitConvert2Op(to, MOV_L2D, input);
                 }
                 break;
         }
         throw GraalInternalError.shouldNotReachHere();
     }
 
-    public AllocatableValue emitReinterpret(Kind to, Value inputVal) {
-        Kind from = inputVal.getKind();
+    public Value emitFloatConvert(FloatConvert op, Value inputVal) {
         AllocatableValue input = asAllocatable(inputVal);
+        switch (op) {
+            case D2F:
+                return emitConvert2Op(Kind.Float, D2F, input);
+            case D2I:
+                return emitConvert2Op(Kind.Int, D2I, input);
+            case D2L:
+                return emitConvert2Op(Kind.Long, D2L, input);
+            case F2D:
+                return emitConvert2Op(Kind.Double, F2D, input);
+            case F2I:
+                return emitConvert2Op(Kind.Int, F2I, input);
+            case F2L:
+                return emitConvert2Op(Kind.Long, F2L, input);
+            case I2D:
+                return emitConvert2Op(Kind.Double, I2D, input);
+            case I2F:
+                return emitConvert2Op(Kind.Float, I2F, input);
+            case L2D:
+                return emitConvert2Op(Kind.Double, L2D, input);
+            case L2F:
+                return emitConvert2Op(Kind.Float, L2F, input);
+            default:
+                throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+
+    @Override
+    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));
+        } else {
+            return inputVal;
+        }
+    }
 
-        /*
-         * Conversions between integer to floating point types require moves between CPU and FPU
-         * registers.
-         */
-        switch (to) {
-            case Int:
-                switch (from) {
-                    case Float:
-                    case Double:
-                        return emitConvert2Op(to, MOV_F2I, input);
-                }
-                break;
-            case Long:
-                switch (from) {
-                    case Float:
-                    case Double:
-                        return emitConvert2Op(to, MOV_D2L, input);
-                    case Int:
-                        /*
-                         * Unsigned int-to-long conversion: In theory, instructions that move or
-                         * generate 32-bit register values also set the upper 32 bits of the
-                         * register to zero. However, we cannot rely that the value was really
-                         * generated by an instruction, it could come from an untrusted source such
-                         * as native code. Therefore, make sure the high bits are really cleared.
-                         */
-                        Variable temp = newVariable(Kind.Int);
-                        Variable result = newVariable(Kind.Long);
-                        append(new BinaryRegConst(AMD64Arithmetic.IAND, temp, input, Constant.forInt(0xFFFFFFFF)));
-                        emitMove(result, temp);
-                        return result;
-                }
-                break;
-            case Float:
-                switch (from) {
-                    case Int:
-                    case Long:
-                        return emitConvert2Op(to, MOV_I2F, input);
-                }
-                break;
-            case Double:
-                switch (from) {
-                    case Int:
-                    case Long:
-                        return emitConvert2Op(to, MOV_L2D, input);
-                }
-                break;
+    @Override
+    public Value emitSignExtend(Value inputVal, int fromBits, int toBits) {
+        assert fromBits <= toBits && toBits <= 64;
+        if (fromBits == toBits) {
+            return inputVal;
+        } else if (toBits > 32) {
+            // sign extend to 64 bits
+            switch (fromBits) {
+                case 8:
+                    return emitConvert2Op(Kind.Long, B2L, asAllocatable(inputVal));
+                case 16:
+                    return emitConvert2Op(Kind.Long, S2L, asAllocatable(inputVal));
+                case 32:
+                    return emitConvert2Op(Kind.Long, I2L, asAllocatable(inputVal));
+                default:
+                    throw GraalInternalError.unimplemented("unsupported sign extension (" + fromBits + " bit -> " + toBits + " bit)");
+            }
+        } else {
+            // sign extend to 32 bits (smaller values are internally represented as 32 bit values)
+            switch (fromBits) {
+                case 8:
+                    return emitConvert2Op(Kind.Int, B2I, asAllocatable(inputVal));
+                case 16:
+                    return emitConvert2Op(Kind.Int, S2I, asAllocatable(inputVal));
+                case 32:
+                    return inputVal;
+                default:
+                    throw GraalInternalError.unimplemented("unsupported sign extension (" + fromBits + " bit -> " + toBits + " bit)");
+            }
         }
-        throw GraalInternalError.shouldNotReachHere();
+    }
+
+    @Override
+    public Value emitZeroExtend(Value inputVal, int fromBits, int toBits) {
+        assert fromBits <= toBits && toBits <= 64;
+        if (fromBits == toBits) {
+            return inputVal;
+        } else if (fromBits > 32) {
+            assert inputVal.getKind() == Kind.Long;
+            Variable result = newVariable(Kind.Long);
+            long mask = IntegerStamp.defaultMask(fromBits);
+            append(new BinaryRegConst(AMD64Arithmetic.LAND, result, asAllocatable(inputVal), Constant.forLong(mask)));
+            return result;
+        } else {
+            assert inputVal.getKind() == Kind.Int;
+            Variable result = newVariable(Kind.Int);
+            int mask = (int) IntegerStamp.defaultMask(fromBits);
+            append(new BinaryRegConst(AMD64Arithmetic.IAND, result, asAllocatable(inputVal), Constant.forInt(mask)));
+            if (toBits > 32) {
+                Variable longResult = newVariable(Kind.Long);
+                emitMove(longResult, result);
+                return longResult;
+            } else {
+                return result;
+            }
+        }
     }
 
     @Override
@@ -899,6 +849,8 @@
         }
     }
 
+    public abstract void emitCCall(long address, CallingConvention nativeCallingConvention, Value[] args, int numberOfFloatingPointArguments);
+
     @Override
     protected void emitForeignCall(ForeignCallLinkage linkage, Value result, Value[] arguments, Value[] temps, LIRFrameState info) {
         long maxOffset = linkage.getMaxCallTargetOffset();
@@ -980,8 +932,8 @@
     }
 
     @Override
-    public void emitCharArrayEquals(Variable result, Value array1, Value array2, Value length) {
-        append(new AMD64CharArrayEqualsOp(this, result, array1, array2, asAllocatable(length)));
+    public void emitArrayEquals(Kind kind, Variable result, Value array1, Value array2, Value length) {
+        append(new AMD64ArrayEqualsOp(this, kind, result, array1, array2, asAllocatable(length)));
     }
 
     @Override
--- a/graal/com.oracle.graal.compiler.hsail.test.infra/src/com/oracle/graal/compiler/hsail/test/infra/GraalKernelTester.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.compiler.hsail.test.infra/src/com/oracle/graal/compiler/hsail/test/infra/GraalKernelTester.java	Wed Mar 05 19:40:15 2014 -0800
@@ -27,33 +27,50 @@
  * This class extends KernelTester and provides a base class
  * for which the HSAIL code comes from the Graal compiler.
  */
+import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
 import static com.oracle.graal.phases.GraalOptions.*;
 
 import java.io.*;
 import java.lang.reflect.*;
 
+import org.junit.*;
+
 import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.compiler.target.*;
 import com.oracle.graal.debug.*;
 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.phases.GraalOptions;
-import static com.oracle.graal.options.OptionValue.OverrideScope;
+import com.oracle.graal.options.OptionValue.OverrideScope;
+import com.oracle.graal.phases.*;
 
 public abstract class GraalKernelTester extends KernelTester {
 
-    HSAILCompilationResult hsailCompResult;
+    public GraalKernelTester() {
+        super(getHSAILBackend().isDeviceInitialized());
+    }
+
+    private static HSAILHotSpotBackend getHSAILBackend() {
+        Backend backend = runtime().getBackend(HSAIL.class);
+        Assume.assumeTrue(backend instanceof HSAILHotSpotBackend);
+        return (HSAILHotSpotBackend) backend;
+    }
+
+    ExternalCompilationResult hsailCode;
     private boolean showHsailSource = false;
     private boolean saveInFile = false;
 
     @Override
     public String getCompiledHSAILSource(Method method) {
-        if (hsailCompResult == null) {
-            hsailCompResult = HSAILCompilationResult.getHSAILCompilationResult(method);
+        if (hsailCode == null) {
+            HSAILHotSpotBackend backend = getHSAILBackend();
+            ResolvedJavaMethod javaMethod = backend.getProviders().getMetaAccess().lookupJavaMethod(method);
+            hsailCode = backend.compileKernel(javaMethod, false);
         }
-        String hsailSource = hsailCompResult.getHSAILCode();
+        String hsailSource = hsailCode.getCodeString();
         if (showHsailSource) {
             logger.severe(hsailSource);
         }
@@ -86,12 +103,11 @@
 
     @Override
     protected void dispatchKernelOkra(int range, Object... args) {
-        HSAILCompilationResult hcr = HSAILCompilationResult.getHSAILCompilationResult(testMethod);
-        HotSpotNmethod code = (HotSpotNmethod) hcr.getInstalledCode();
-
-        if (code != null) {
+        HSAILHotSpotBackend backend = getHSAILBackend();
+        if (backend.isDeviceInitialized()) {
             try {
-                code.executeParallel(range, 0, 0, args);
+                HotSpotNmethod code = backend.compileAndInstallKernel(testMethod);
+                backend.executeKernel(code, range, args);
             } catch (InvalidInstalledCodeException e) {
                 Debug.log("WARNING:Invalid installed code: " + e);
                 e.printStackTrace();
--- a/graal/com.oracle.graal.compiler.hsail.test.infra/src/com/oracle/graal/compiler/hsail/test/infra/KernelTester.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.compiler.hsail.test.infra/src/com/oracle/graal/compiler/hsail/test/infra/KernelTester.java	Wed Mar 05 19:40:15 2014 -0800
@@ -108,17 +108,17 @@
 
     private static boolean gaveNoOkraWarning = false;
     private boolean onSimulator;
-    private boolean okraLibExists;
+    private final boolean okraLibExists;
 
     public boolean runningOnSimulator() {
         return onSimulator;
     }
 
-    public KernelTester() {
-        okraLibExists = OkraUtil.okraLibExists();
+    public KernelTester(boolean okraLibExists) {
         dispatchMode = DispatchMode.SEQ;
         hsailMode = HsailMode.COMPILED;
         useLambdaMethod = false;
+        this.okraLibExists = okraLibExists;
     }
 
     public abstract void runTest();
--- /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/ArgsIntBase.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,43 @@
+/*
+ * 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.*;
+
+/**
+ * Tests codegen for an IJ signature {@code IntStream} instance function.
+ */
+public abstract class ArgsIntBase extends GraalKernelTester {
+
+    static final int NUM = 20;
+
+    @Result public double[] outArray = new double[NUM];
+
+    void setupArrays() {
+        for (int i = 0; i < NUM; i++) {
+            outArray[i] = -i;
+        }
+    }
+
+}
--- /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/ArgsIntInstIITest.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,48 @@
+/*
+ * 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.*;
+
+/**
+ * Tests codegen for an II signature {@code IntStream} instance function.
+ */
+public class ArgsIntInstIITest extends ArgsIntBase {
+
+    public void run(int arg1, int arg2, int gid) {
+        outArray[gid] = gid + arg1 + arg2;
+    }
+
+    @Override
+    public void runTest() {
+        setupArrays();
+        dispatchMethodKernel(NUM, 7, 6);
+    }
+
+    @Test
+    public void test() {
+        testGeneratedHsail();
+    }
+
+}
--- /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/ArgsIntInstIJTest.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,48 @@
+/*
+ * 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.*;
+
+/**
+ * Tests codegen for an IJ signature {@code IntStream} instance function.
+ */
+public class ArgsIntInstIJTest extends ArgsIntBase {
+
+    public void run(int arg1, long arg2, int gid) {
+        outArray[gid] = gid + arg1 + arg2;
+    }
+
+    @Override
+    public void runTest() {
+        setupArrays();
+        dispatchMethodKernel(NUM, 7, 6);
+    }
+
+    @Test
+    public void test() {
+        testGeneratedHsail();
+    }
+
+}
--- /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/ArgsIntStatAIITest.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,48 @@
+/*
+ * 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.*;
+
+/**
+ * Tests codegen for an AII signature {@code IntStream} static function.
+ */
+public class ArgsIntStatAIITest extends ArgsIntBase {
+
+    public static void run(double[] out, int arg1, int arg2, int gid) {
+        out[gid] = gid + arg1 + arg2;
+    }
+
+    @Override
+    public void runTest() {
+        setupArrays();
+        dispatchMethodKernel(NUM, outArray, 7, 6);
+    }
+
+    @Test
+    public void test() {
+        testGeneratedHsail();
+    }
+
+}
--- /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/ArgsIntStatAIJTest.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,48 @@
+/*
+ * 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.*;
+
+/**
+ * Tests codegen for an AIJ signature {@code IntStream} static function.
+ */
+public class ArgsIntStatAIJTest extends ArgsIntBase {
+
+    public static void run(double[] out, int arg1, long arg2, int gid) {
+        out[gid] = gid + arg1 + arg2;
+    }
+
+    @Override
+    public void runTest() {
+        setupArrays();
+        dispatchMethodKernel(NUM, outArray, 7, 6);
+    }
+
+    @Test
+    public void test() {
+        testGeneratedHsail();
+    }
+
+}
--- /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/ArgsObjBase.java	Wed Mar 05 19:40:15 2014 -0800
@@ -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;
+
+import com.oracle.graal.compiler.hsail.test.infra.*;
+
+/**
+ * Tests codegen for an IJ signature Object stream instance function.
+ */
+public abstract class ArgsObjBase extends GraalKernelTester {
+
+    static class MyObj {
+        public int id;
+        public double d;
+
+        public MyObj(int id) {
+            this.id = id;
+        }
+
+        @Override
+        public boolean equals(Object other) {
+            if (!(other instanceof MyObj)) {
+                return false;
+            }
+            MyObj oth = (MyObj) other;
+            return (oth.id == id && oth.d == d);
+        }
+
+        @Override
+        public String toString() {
+            return ("MyObj[" + id + ", " + d + "]");
+        }
+
+        @Override
+        public int hashCode() {
+            return id;
+        }
+
+    }
+
+    static final int NUM = 20;
+
+    @Result public MyObj[] outArray = new MyObj[NUM];
+
+    void setupArrays() {
+        for (int i = 0; i < NUM; i++) {
+            outArray[i] = new MyObj(i + 1);
+        }
+    }
+
+}
--- /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/ArgsObjInstIITest.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,48 @@
+/*
+ * 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.*;
+
+/**
+ * Tests codegen for an II signature Object stream instance function.
+ */
+public class ArgsObjInstIITest extends ArgsObjBase {
+
+    public void run(int arg1, int arg2, MyObj myobj) {
+        myobj.d = myobj.id + arg1 + arg2;
+    }
+
+    @Override
+    public void runTest() {
+        setupArrays();
+        dispatchMethodKernel(outArray, 7, 6);
+    }
+
+    @Test
+    public void test() {
+        testGeneratedHsail();
+    }
+
+}
--- /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/ArgsObjInstIJTest.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,48 @@
+/*
+ * 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.*;
+
+/**
+ * Tests codegen for an IJ signature Object stream instance function.
+ */
+public class ArgsObjInstIJTest extends ArgsObjBase {
+
+    public void run(int arg1, long arg2, MyObj myobj) {
+        myobj.d = myobj.id + arg1 + arg2;
+    }
+
+    @Override
+    public void runTest() {
+        setupArrays();
+        dispatchMethodKernel(outArray, 7, 6);
+    }
+
+    @Test
+    public void test() {
+        testGeneratedHsail();
+    }
+
+}
--- /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/ArgsObjStatIITest.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,48 @@
+/*
+ * 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.*;
+
+/**
+ * Tests codegen for an II signature Object stream static function.
+ */
+public class ArgsObjStatIITest extends ArgsObjBase {
+
+    public static void run(int arg1, int arg2, MyObj myobj) {
+        myobj.d = myobj.id + arg1 + arg2;
+    }
+
+    @Override
+    public void runTest() {
+        setupArrays();
+        dispatchMethodKernel(outArray, 7, 6);
+    }
+
+    @Test
+    public void test() {
+        testGeneratedHsail();
+    }
+
+}
--- /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/ArgsObjStatIJTest.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,48 @@
+/*
+ * 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.*;
+
+/**
+ * Tests codegen for an IJ signature Object stream static function.
+ */
+public class ArgsObjStatIJTest extends ArgsObjBase {
+
+    public static void run(int arg1, long arg2, MyObj myobj) {
+        myobj.d = myobj.id + arg1 + arg2;
+    }
+
+    @Override
+    public void runTest() {
+        setupArrays();
+        dispatchMethodKernel(outArray, 7, 6);
+    }
+
+    @Test
+    public void test() {
+        testGeneratedHsail();
+    }
+
+}
--- a/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/BasicHSAILTest.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/BasicHSAILTest.java	Wed Mar 05 19:40:15 2014 -0800
@@ -22,14 +22,17 @@
  */
 package com.oracle.graal.compiler.hsail.test;
 
+import java.lang.reflect.*;
+
 import org.junit.*;
 
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.compiler.target.*;
 import com.oracle.graal.compiler.test.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.debug.Debug.Scope;
 import com.oracle.graal.hotspot.hsail.*;
 import com.oracle.graal.hsail.*;
-import com.oracle.graal.nodes.*;
 
 /**
  * Test class for small Java methods compiled to HSAIL kernels.
@@ -332,11 +335,18 @@
         out[gid] = val;
     }
 
+    @Override
+    protected HSAILHotSpotBackend getBackend() {
+        Backend backend = super.getBackend();
+        Assume.assumeTrue(backend instanceof HSAILHotSpotBackend);
+        return (HSAILHotSpotBackend) backend;
+    }
+
     private void test(final String snippet) {
         try (Scope s = Debug.scope("HSAILCodeGen")) {
-            StructuredGraph graph = parse(snippet);
-            HSAILCompilationResult compResult = HSAILCompilationResult.getHSAILCompilationResult(graph);
-            Debug.log("HSAIL code generated for %s:%n%s", snippet, compResult.getHSAILCode());
+            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);
         }
--- a/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/StaticMethod16InArraysTest.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/StaticMethod16InArraysTest.java	Wed Mar 05 19:40:15 2014 -0800
@@ -62,6 +62,7 @@
      * there are registers.
      */
     @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) {
--- /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/StringEqualsTest.java	Wed Mar 05 19:40:15 2014 -0800
@@ -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;
+
+import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester;
+import org.junit.Test;
+
+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));
+        }
+    }
+
+    public void run(String base, int gid) {
+        outArray[gid] = inArray[gid].equals(base);
+    }
+
+    @Override
+    public void runTest() {
+        setupArrays();
+
+        dispatchMethodKernel(NUM, "ABCDEFGHIJ");
+    }
+
+    @Test
+    public void test() {
+        testGeneratedHsail();
+    }
+}
--- a/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILLIRGenerator.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILLIRGenerator.java	Wed Mar 05 19:40:15 2014 -0800
@@ -47,12 +47,13 @@
 import com.oracle.graal.lir.hsail.HSAILControlFlow.FloatCondMoveOp;
 import com.oracle.graal.lir.hsail.HSAILControlFlow.ReturnOp;
 import com.oracle.graal.lir.hsail.HSAILControlFlow.StrategySwitchOp;
-import com.oracle.graal.lir.hsail.HSAILMove.LeaOp;
 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.nodes.type.*;
 import com.oracle.graal.phases.util.*;
 
 /**
@@ -60,23 +61,8 @@
  */
 public abstract class HSAILLIRGenerator extends LIRGenerator {
 
-    public static class HSAILSpillMoveFactory implements LIR.SpillMoveFactory {
-
-        @Override
-        public LIRInstruction createMove(AllocatableValue dst, Value src) {
-            if (src instanceof HSAILAddressValue) {
-                return new LeaOp(dst, (HSAILAddressValue) src);
-            } else if (isRegister(src) || isStackSlot(dst)) {
-                return new MoveFromRegOp(dst, src);
-            } else {
-                return new MoveToRegOp(dst, src);
-            }
-        }
-    }
-
     public HSAILLIRGenerator(StructuredGraph graph, Providers providers, FrameMap frameMap, CallingConvention cc, LIR lir) {
         super(graph, providers, frameMap, cc, lir);
-        lir.spillMoveFactory = new HSAILSpillMoveFactory();
     }
 
     @Override
@@ -145,7 +131,7 @@
             } else {
                 Value indexRegister;
                 Value convertedIndex;
-                convertedIndex = this.emitConvert(Kind.Int, Kind.Long, index);
+                convertedIndex = this.emitSignExtend(index, 32, 64);
                 if (scale != 1) {
                     indexRegister = emitUMul(convertedIndex, Constant.forInt(scale));
                 } else {
@@ -189,7 +175,7 @@
     }
 
     @Override
-    public void emitCompareBranch(Value left, Value right, Condition cond, boolean unorderedIsTrue, LabelRef trueDestination, LabelRef falseDestination) {
+    public void emitCompareBranch(Value left, Value right, Condition cond, boolean unorderedIsTrue, LabelRef trueDestination, LabelRef falseDestination, double trueDestinationProbability) {
         // We don't have to worry about mirroring the condition on HSAIL.
         Condition finalCondition = cond;
         Variable result = newVariable(left.getKind());
@@ -210,12 +196,12 @@
     }
 
     @Override
-    public void emitOverflowCheckBranch(LabelRef overflow, LabelRef noOverflow, boolean negated) {
+    public void emitOverflowCheckBranch(LabelRef overflow, LabelRef noOverflow, double overflowProbability) {
         throw GraalInternalError.unimplemented();
     }
 
     @Override
-    public void emitIntegerTestBranch(Value left, Value right, boolean negated, LabelRef trueDestination, LabelRef falseDestination) {
+    public void emitIntegerTestBranch(Value left, Value right, LabelRef trueDestination, LabelRef falseDestination, double trueDestinationProbability) {
         throw GraalInternalError.unimplemented();
     }
 
@@ -592,15 +578,92 @@
     }
 
     @Override
-    public Variable emitConvert(Kind from, Kind to, Value inputVal) {
+    public Value emitFloatConvert(FloatConvert op, Value inputVal) {
         Variable input = load(inputVal);
-        Variable result = newVariable(to);
+
+        String from;
+        switch (op) {
+            case D2F:
+            case D2I:
+            case D2L:
+                from = "f64";
+                break;
+            case F2D:
+            case F2I:
+            case F2L:
+                from = "f32";
+                break;
+            case I2D:
+            case I2F:
+                from = "s32";
+                break;
+            case L2D:
+            case L2F:
+                from = "s64";
+                break;
+            default:
+                throw GraalInternalError.shouldNotReachHere();
+        }
+
+        Variable result;
+        String to;
+        switch (op) {
+            case D2I:
+            case F2I:
+                to = "s32";
+                result = newVariable(Kind.Int);
+                break;
+            case D2L:
+            case F2L:
+                to = "s64";
+                result = newVariable(Kind.Long);
+                break;
+            case F2D:
+            case I2D:
+            case L2D:
+                to = "f64";
+                result = newVariable(Kind.Double);
+                break;
+            case D2F:
+            case I2F:
+            case L2F:
+                to = "f32";
+                result = newVariable(Kind.Float);
+                break;
+            default:
+                throw GraalInternalError.shouldNotReachHere();
+        }
+
         append(new ConvertOp(result, input, to, from));
         return result;
     }
 
     @Override
-    public Value emitReinterpret(Kind to, Value inputVal) {
+    public Value emitNarrow(Value inputVal, int bits) {
+        Variable input = load(inputVal);
+        Variable result = newVariable(bits > 32 ? Kind.Long : Kind.Int);
+        append(new ConvertOp(result, input, "s" + bits, input.getKind() == Kind.Long ? "s64" : "s32"));
+        return result;
+    }
+
+    @Override
+    public Value emitSignExtend(Value inputVal, int fromBits, int toBits) {
+        Variable input = load(inputVal);
+        Variable result = newVariable(toBits > 32 ? Kind.Long : Kind.Int);
+        append(new ConvertOp(result, input, "s" + toBits, "s" + fromBits));
+        return result;
+    }
+
+    @Override
+    public Value emitZeroExtend(Value inputVal, int fromBits, int toBits) {
+        Variable input = load(inputVal);
+        Variable result = newVariable(toBits > 32 ? Kind.Long : Kind.Int);
+        append(new ConvertOp(result, input, "u" + toBits, "u" + fromBits));
+        return result;
+    }
+
+    @Override
+    public Value emitReinterpret(PlatformKind to, Value inputVal) {
         Variable result = newVariable(to);
         emitMove(result, inputVal);
         return result;
@@ -734,7 +797,7 @@
     }
 
     @Override
-    public void emitCharArrayEquals(Variable result, Value array1, Value array2, Value length) {
+    public void emitArrayEquals(Kind kind, Variable result, Value array1, Value array2, Value length) {
         // TODO Auto-generated method stub
         throw GraalInternalError.unimplemented();
     }
@@ -816,7 +879,7 @@
 
     @Override
     public void emitNullCheck(ValueNode v, DeoptimizingNode deopting) {
-        assert v.kind() == Kind.Object;
+        assert v.stamp() instanceof ObjectStamp;
         Variable obj = newVariable(Kind.Object);
         emitMove(obj, operand(v));
         append(new HSAILMove.NullCheckOp(obj, state(deopting)));
--- a/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/BasicPTXTest.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/BasicPTXTest.java	Wed Mar 05 19:40:15 2014 -0800
@@ -22,6 +22,8 @@
  */
 package com.oracle.graal.compiler.ptx.test;
 
+import static org.junit.Assert.*;
+
 import org.junit.*;
 
 /**
@@ -56,6 +58,11 @@
         return p1 + p0;
     }
 
+    @Test
+    public void testGetAvailableProcessors() {
+        assertTrue(getPTXBackend().getAvailableProcessors() >= 0);
+    }
+
     public static void main(String[] args) {
         compileAndPrintCode(new BasicPTXTest());
     }
--- a/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/ControlPTXTest.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/ControlPTXTest.java	Wed Mar 05 19:40:15 2014 -0800
@@ -27,16 +27,25 @@
 public class ControlPTXTest extends PTXTest {
 
     @Test
-    public void testControl() {
+    public void testControl1() {
         test("testLoop", 42);
         test("testSwitchDefault1I", 3);
         test("testSwitch1I", 2);
         test("testIfElse1I", 222);
         test("testIfElse2I", 19, 64);
+    }
 
-        test("testIntegerTestBranch2I", 0xff00, 0x00ff);
+    @Test
+    public void testControl2() {
         compileKernel("testStatic");
         compileKernel("testCall");
+    }
+
+    @Ignore("[CUDA] Check for malformed PTX kernel or incorrect PTX compilation options")
+    @Test
+    public void testControl3() {
+        // test("testIntegerTestBranch2I", 0xff00, 0x00ff);
+        compileKernel("testIntegerTestBranch2I");
         compileKernel("testLookupSwitch1I");
     }
 
--- a/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/FloatPTXTest.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/FloatPTXTest.java	Wed Mar 05 19:40:15 2014 -0800
@@ -63,7 +63,6 @@
         return 32.0 + a;
     }
 
-    @Ignore
     @Test
     public void testSub() {
         compileKernel("testSub2F");
@@ -98,7 +97,7 @@
         return 32.0 - a;
     }
 
-    @Ignore
+    @Ignore("[CUDA] *** Error (209) Failed to load module data with online compiler options for method testMul2F")
     @Test
     public void testMul() {
         compileKernel("testMul2F");
@@ -133,7 +132,7 @@
         return 32.0 * a;
     }
 
-    @Ignore
+    @Ignore("[CUDA] *** Error (209) Failed to load module data with online compiler options for method testDiv2F")
     @Test
     public void testDiv() {
         compileKernel("testDiv2F");
@@ -168,7 +167,6 @@
         return 32.0 / a;
     }
 
-    @Ignore
     @Test
     public void testNeg() {
         compileKernel("testNeg2F");
@@ -183,12 +181,11 @@
         return -a;
     }
 
-    @Ignore
+    @Ignore("need linkage to PTX remainder")
     @Test
     public void testRem() {
-        // need linkage to PTX remainder()
-        // compileKernel("testRem2F");
-        // compileKernel("testRem2D");
+        compileKernel("testRem2F");
+        compileKernel("testRem2D");
     }
 
     public static float testRem2F(float a, float b) {
@@ -199,7 +196,7 @@
         return a % b;
     }
 
-    @Ignore
+    @Ignore("[CUDA] *** Error (209) Failed to load module data with online compiler options for method testF2I")
     @Test
     public void testFloatConversion() {
         compileKernel("testF2I");
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/ObjectPTXTest.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,161 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.compiler.ptx.test;
+
+import java.util.*;
+
+import org.junit.*;
+
+public class ObjectPTXTest extends PTXTest {
+
+    static class A {
+        boolean z = true;
+        byte b = 17;
+        char c = 'D';
+        short s = 12345;
+        int i = 0x1234565;
+        long l;
+        Object o;
+        float f;
+        double d;
+    }
+
+    @Test
+    public void test0() {
+        for (long l : new long[]{Long.MIN_VALUE, -10, 0, 1, 2, 10, Long.MAX_VALUE}) {
+            A a = new A();
+            a.l = l;
+            test("testLong", l * 2, a);
+        }
+    }
+
+    public static long testLong(long l, A a) {
+        return a.l + l;
+    }
+
+    @Test
+    public void test1() {
+        for (int i : new int[]{Integer.MIN_VALUE, -10, 0, 1, 2, 10, Integer.MAX_VALUE}) {
+            A a = new A();
+            a.i = i;
+            test("testInt", i * 2, a);
+        }
+    }
+
+    public static int testInt(int i, A a) {
+        return a.i + i;
+    }
+
+    @Test
+    public void test2() {
+        A a = new A();
+        a.z = true;
+        test("testBoolean", a);
+        a.z = false;
+        test("testBoolean", a);
+    }
+
+    public static boolean testBoolean(A a) {
+        return a.z;
+    }
+
+    @Test
+    public void test3() {
+        for (byte b : new byte[]{Byte.MIN_VALUE, -10, 0, 1, 2, 10, Byte.MAX_VALUE}) {
+            A a = new A();
+            a.b = b;
+            test("testByte", b, a);
+        }
+    }
+
+    public static int testByte(byte b, A a) {
+        return a.b + b;
+    }
+
+    @Test
+    public void test4() {
+        for (short s : new short[]{Short.MIN_VALUE, -10, 0, 1, 2, 10, Short.MAX_VALUE}) {
+            A a = new A();
+            a.s = s;
+            test("testShort", s, a);
+        }
+    }
+
+    public static int testShort(short s, A a) {
+        return a.s + s;
+    }
+
+    @Ignore("java.lang.AssertionError: expected:<65531> but was:<809107451>")
+    @Test
+    public void test5() {
+        for (char c : new char[]{Character.MIN_VALUE, 1, 2, 10, Character.MAX_VALUE}) {
+            A a = new A();
+            a.c = c;
+            test("testChar", (char) (c - 5), a);
+        }
+    }
+
+    public static int testChar(char c, A a) {
+        return a.c + c;
+    }
+
+    @Test
+    public void test6() {
+        for (float f : new float[]{Float.MIN_VALUE, Float.MIN_NORMAL, Float.NEGATIVE_INFINITY, Float.POSITIVE_INFINITY, Float.NaN, -11.45F, -0.0F, 0.0F, 2, 10, Float.MAX_VALUE}) {
+            A a = new A();
+            a.f = f;
+            test("testFloat", f * 2, a);
+        }
+    }
+
+    public static float testFloat(float f, A a) {
+        return a.f + f;
+    }
+
+    @Test
+    public void test7() {
+        for (double d : new double[]{Double.MIN_VALUE, Double.MIN_NORMAL, Double.NaN, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, -11.45D, -0.0D, 0.0D, 2, 10, Double.MAX_VALUE}) {
+            A a = new A();
+            a.d = d;
+            test("testDouble", d * 2, a);
+        }
+    }
+
+    public static double testDouble(double d, A a) {
+        return a.d + d;
+    }
+
+    @Ignore("Object return values not yet supported")
+    @Test
+    public void test9() {
+        for (Object o : new Object[]{null, "object", new Object(), new HashMap()}) {
+            A a = new A();
+            a.o = o;
+            test("testObject", a);
+        }
+    }
+
+    public static Object testObject(A a) {
+        return a.o;
+    }
+}
--- a/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/PTXPhase.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,43 +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.compiler.ptx.test;
-
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.type.*;
-import com.oracle.graal.phases.*;
-
-public class PTXPhase extends Phase {
-
-    @Override
-    protected void run(StructuredGraph graph) {
-        /*
-         * Assume that null checks would be done on the CPU caller side prior to copying data onto
-         * the GPU.
-         */
-        for (ParameterNode param : graph.getNodes(ParameterNode.class)) {
-            if (param.stamp() instanceof ObjectStamp) {
-                param.setStamp(StampFactory.declaredNonNull(((ObjectStamp) param.stamp()).type()));
-            }
-        }
-    }
-}
--- a/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/PTXTest.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/PTXTest.java	Wed Mar 05 19:40:15 2014 -0800
@@ -43,7 +43,7 @@
  */
 public abstract class PTXTest extends GraalCompilerTest {
 
-    private static PTXHotSpotBackend getPTXBackend() {
+    public static PTXHotSpotBackend getPTXBackend() {
         Backend backend = runtime().getBackend(PTX.class);
         Assume.assumeTrue(backend instanceof PTXHotSpotBackend);
         return (PTXHotSpotBackend) backend;
@@ -69,7 +69,15 @@
         Assume.assumeTrue(ptxBackend.isDeviceInitialized());
         HotSpotNmethod installedPTXCode = installKernel(method, ptxCode);
         StructuredGraph wrapper = new PTXWrapperBuilder(method, installedPTXCode, (HotSpotProviders) getProviders()).getGraph();
-        return super.getCode(method, wrapper);
+
+        // The PTX C++ layer expects a 1:1 relationship between kernel compilation
+        // and kernel execution as it creates a cuContext in the former and
+        // destroys it in the latter. So, each kernel installed requires a unique
+        // wrapper.
+        // TODO: do cuContext management properly
+        boolean forceCompile = true;
+
+        return getCode(method, wrapper, forceCompile);
     }
 
     protected static void compileAndPrintCode(PTXTest test) {
--- a/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXLIRGenerator.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXLIRGenerator.java	Wed Mar 05 19:40:15 2014 -0800
@@ -62,8 +62,10 @@
 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.java.*;
+import com.oracle.graal.nodes.type.*;
 import com.oracle.graal.phases.util.*;
 
 /**
@@ -79,17 +81,8 @@
     public static final ForeignCallDescriptor ARITHMETIC_FREM = new ForeignCallDescriptor("arithmeticFrem", float.class, float.class, float.class);
     public static final ForeignCallDescriptor ARITHMETIC_DREM = new ForeignCallDescriptor("arithmeticDrem", double.class, double.class, double.class);
 
-    public static class PTXSpillMoveFactory implements LIR.SpillMoveFactory {
-
-        @Override
-        public LIRInstruction createMove(AllocatableValue result, Value input) {
-            throw GraalInternalError.unimplemented("PTXSpillMoveFactory.createMove()");
-        }
-    }
-
     public PTXLIRGenerator(StructuredGraph graph, Providers providers, FrameMap frameMap, CallingConvention cc, LIR lir) {
         super(graph, providers, frameMap, cc, lir);
-        lir.spillMoveFactory = new PTXSpillMoveFactory();
         int callVariables = cc.getArgumentCount() + (cc.getReturn().equals(Value.ILLEGAL) ? 0 : 1);
         lir.setFirstVariableNumber(callVariables);
         nextPredRegNum = 0;
@@ -162,9 +155,9 @@
             }
             Warp warpAnnotation = parameterIndex >= 0 ? MetaUtil.getParameterAnnotation(Warp.class, parameterIndex, graph.method()) : null;
             if (warpAnnotation != null) {
-                setResult(param, emitWarpParam(paramValue.getKind(), warpAnnotation));
+                setResult(param, emitWarpParam(paramValue.getKind().getStackKind(), warpAnnotation));
             } else {
-                setResult(param, emitLoadParam(paramValue.getKind(), paramValue, null));
+                setResult(param, emitLoadParam(paramValue.getKind().getStackKind(), paramValue, null));
             }
         }
     }
@@ -232,7 +225,7 @@
                 Value convertedIndex;
                 Value indexRegister;
 
-                convertedIndex = emitConvert(Kind.Int, Kind.Long, index);
+                convertedIndex = emitSignExtend(index, 32, 64);
                 if (scale != 1) {
                     if (CodeUtil.isPowerOf2(scale)) {
                         indexRegister = emitShl(convertedIndex, Constant.forInt(CodeUtil.log2(scale)));
@@ -299,7 +292,7 @@
     }
 
     @Override
-    public void emitCompareBranch(Value left, Value right, Condition cond, boolean unorderedIsTrue, LabelRef trueDestination, LabelRef falseDestination) {
+    public void emitCompareBranch(Value left, Value right, Condition cond, boolean unorderedIsTrue, LabelRef trueDestination, LabelRef falseDestination, double trueDestinationProbability) {
         switch (left.getKind().getStackKind()) {
             case Int:
                 append(new CompareOp(ICMP, cond, left, right, nextPredRegNum));
@@ -327,12 +320,12 @@
     }
 
     @Override
-    public void emitOverflowCheckBranch(LabelRef overflow, LabelRef noOverflow, boolean negated) {
+    public void emitOverflowCheckBranch(LabelRef overflow, LabelRef noOverflow, double overflowProbability) {
         throw GraalInternalError.unimplemented("PTXLIRGenerator.emitOverflowCheckBranch()");
     }
 
     @Override
-    public void emitIntegerTestBranch(Value left, Value right, boolean negated, LabelRef trueDestination, LabelRef falseDestination) {
+    public void emitIntegerTestBranch(Value left, Value right, LabelRef trueDestination, LabelRef falseDestination, double trueDestinationProbability) {
         // / emitIntegerTest(left, right);
         // append(new BranchOp(negated ? Condition.NE : Condition.EQ, label));
         throw GraalInternalError.unimplemented("emitIntegerTestBranch()");
@@ -681,15 +674,112 @@
         return result;
     }
 
-    @Override
-    public Variable emitConvert(Kind from, Kind to, Value inputVal) {
+    public Variable emitConvertOp(Kind from, Kind to, Value inputVal) {
         Variable input = load(inputVal);
         Variable result = newVariable(to);
         append(new ConvertOp(result, input, to, from));
         return result;
     }
 
-    public Value emitReinterpret(Kind to, Value inputVal) {
+    @Override
+    public Value emitFloatConvert(FloatConvert op, Value inputVal) {
+        switch (op) {
+            case D2F:
+                return emitConvertOp(Kind.Double, Kind.Float, inputVal);
+            case D2I:
+                return emitConvertOp(Kind.Double, Kind.Int, inputVal);
+            case D2L:
+                return emitConvertOp(Kind.Double, Kind.Long, inputVal);
+            case F2D:
+                return emitConvertOp(Kind.Float, Kind.Double, inputVal);
+            case F2I:
+                return emitConvertOp(Kind.Float, Kind.Int, inputVal);
+            case F2L:
+                return emitConvertOp(Kind.Float, Kind.Long, inputVal);
+            case I2D:
+                return emitConvertOp(Kind.Int, Kind.Double, inputVal);
+            case I2F:
+                return emitConvertOp(Kind.Int, Kind.Float, inputVal);
+            case L2D:
+                return emitConvertOp(Kind.Long, Kind.Double, inputVal);
+            case L2F:
+                return emitConvertOp(Kind.Long, Kind.Float, inputVal);
+            default:
+                throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+
+    @Override
+    public Value emitNarrow(Value inputVal, int bits) {
+        if (inputVal.getKind() == Kind.Long && bits <= 32) {
+            return emitConvertOp(Kind.Long, Kind.Int, inputVal);
+        } else {
+            return inputVal;
+        }
+    }
+
+    @Override
+    public Value emitSignExtend(Value inputVal, int fromBits, int toBits) {
+        assert fromBits <= toBits && toBits <= 64;
+        if (fromBits == toBits) {
+            return inputVal;
+        } else if (toBits > 32) {
+            // sign extend to 64 bits
+            switch (fromBits) {
+                case 8:
+                    return emitConvertOp(Kind.Byte, Kind.Long, inputVal);
+                case 16:
+                    return emitConvertOp(Kind.Short, Kind.Long, inputVal);
+                case 32:
+                    return emitConvertOp(Kind.Int, Kind.Long, inputVal);
+                case 64:
+                    return inputVal;
+                default:
+                    throw GraalInternalError.unimplemented("unsupported sign extension (" + fromBits + " bit -> " + toBits + " bit)");
+            }
+        } else {
+            // sign extend to 32 bits (smaller values are internally represented as 32 bit values)
+            switch (fromBits) {
+                case 8:
+                    return emitConvertOp(Kind.Byte, Kind.Int, inputVal);
+                case 16:
+                    return emitConvertOp(Kind.Short, Kind.Int, inputVal);
+                case 32:
+                    return inputVal;
+                default:
+                    throw GraalInternalError.unimplemented("unsupported sign extension (" + fromBits + " bit -> " + toBits + " bit)");
+            }
+        }
+    }
+
+    @Override
+    public Value emitZeroExtend(Value inputVal, int fromBits, int toBits) {
+        assert fromBits <= toBits && toBits <= 64;
+        if (fromBits == toBits) {
+            return inputVal;
+        } else if (fromBits > 32) {
+            assert inputVal.getKind() == Kind.Long;
+            Variable result = newVariable(Kind.Long);
+            long mask = IntegerStamp.defaultMask(fromBits);
+            append(new Op2Stack(LAND, result, inputVal, Constant.forLong(mask)));
+            return result;
+        } else {
+            assert inputVal.getKind() == Kind.Int;
+            Variable result = newVariable(Kind.Int);
+            int mask = (int) IntegerStamp.defaultMask(fromBits);
+            append(new Op2Stack(IAND, result, inputVal, Constant.forInt(mask)));
+            if (toBits > 32) {
+                Variable longResult = newVariable(Kind.Long);
+                emitMove(longResult, result);
+                return longResult;
+            } else {
+                return result;
+            }
+        }
+    }
+
+    @Override
+    public Value emitReinterpret(PlatformKind to, Value inputVal) {
         Variable result = newVariable(to);
         emitMove(result, inputVal);
         return result;
@@ -775,7 +865,7 @@
     }
 
     @Override
-    public void emitCharArrayEquals(Variable result, Value array1, Value array2, Value length) {
+    public void emitArrayEquals(Kind kind, Variable result, Value array1, Value array2, Value length) {
         // TODO Auto-generated method stub
         throw GraalInternalError.unimplemented();
     }
--- a/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java	Wed Mar 05 19:40:15 2014 -0800
@@ -52,15 +52,14 @@
 import com.oracle.graal.lir.sparc.SPARCControlFlow.ReturnOp;
 import com.oracle.graal.lir.sparc.SPARCControlFlow.StrategySwitchOp;
 import com.oracle.graal.lir.sparc.SPARCControlFlow.TableSwitchOp;
-import com.oracle.graal.lir.sparc.SPARCMove.LoadAddressOp;
 import com.oracle.graal.lir.sparc.SPARCMove.MembarOp;
-import com.oracle.graal.lir.sparc.SPARCMove.MoveFromRegOp;
-import com.oracle.graal.lir.sparc.SPARCMove.MoveToRegOp;
 import com.oracle.graal.lir.sparc.SPARCMove.NullCheckOp;
 import com.oracle.graal.lir.sparc.SPARCMove.StackLoadAddressOp;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
+import com.oracle.graal.nodes.calc.FloatConvertNode.FloatConvert;
 import com.oracle.graal.nodes.java.*;
+import com.oracle.graal.nodes.type.*;
 import com.oracle.graal.phases.util.*;
 
 /**
@@ -68,17 +67,8 @@
  */
 public abstract class SPARCLIRGenerator extends LIRGenerator {
 
-    private class SPARCSpillMoveFactory implements LIR.SpillMoveFactory {
-
-        @Override
-        public LIRInstruction createMove(AllocatableValue result, Value input) {
-            return SPARCLIRGenerator.this.createMove(result, input);
-        }
-    }
-
     public SPARCLIRGenerator(StructuredGraph graph, Providers providers, FrameMap frameMap, CallingConvention cc, LIR lir) {
         super(graph, providers, frameMap, cc, lir);
-        lir.spillMoveFactory = new SPARCSpillMoveFactory();
     }
 
     @Override
@@ -114,19 +104,9 @@
         return result;
     }
 
-    protected SPARCLIRInstruction createMove(AllocatableValue dst, Value src) {
-        if (src instanceof SPARCAddressValue) {
-            return new LoadAddressOp(dst, (SPARCAddressValue) src);
-        } else if (isRegister(src) || isStackSlot(dst)) {
-            return new MoveFromRegOp(dst, src);
-        } else {
-            return new MoveToRegOp(dst, src);
-        }
-    }
-
     @Override
     public void emitMove(AllocatableValue dst, Value src) {
-        append(createMove(dst, src));
+        append(SPARCMove.createMove(dst, src));
     }
 
     @Override
@@ -153,8 +133,7 @@
                 indexRegister = Value.ILLEGAL;
             } else {
                 if (scale != 1) {
-                    // Variable longIndex = newVariable(Kind.Long);
-                    AllocatableValue longIndex = emitConvert(Kind.Int, Kind.Long, index);
+                    Value longIndex = emitSignExtend(index, 32, 64);
                     if (CodeUtil.isPowerOf2(scale)) {
                         indexRegister = emitShl(longIndex, Constant.forLong(CodeUtil.log2(scale)));
                     } else {
@@ -230,7 +209,7 @@
     }
 
     @Override
-    public void emitCompareBranch(Value left, Value right, Condition cond, boolean unorderedIsTrue, LabelRef trueDestination, LabelRef falseDestination) {
+    public void emitCompareBranch(Value left, Value right, Condition cond, boolean unorderedIsTrue, LabelRef trueDestination, LabelRef falseDestination, double trueDestinationProbability) {
         boolean mirrored = emitCompare(left, right);
         Condition finalCondition = mirrored ? cond.mirror() : cond;
         Kind kind = left.getKind().getStackKind();
@@ -254,15 +233,15 @@
     }
 
     @Override
-    public void emitOverflowCheckBranch(LabelRef overflow, LabelRef noOverflow, boolean negated) {
+    public void emitOverflowCheckBranch(LabelRef overflow, LabelRef noOverflow, double overflowProbability) {
         // append(new BranchOp(negated ? ConditionFlag.NoOverflow : ConditionFlag.Overflow, label));
         throw GraalInternalError.unimplemented();
     }
 
     @Override
-    public void emitIntegerTestBranch(Value left, Value right, boolean negated, LabelRef trueDestination, LabelRef falseDestination) {
+    public void emitIntegerTestBranch(Value left, Value right, LabelRef trueDestination, LabelRef falseDestination, double trueDestinationProbability) {
         emitIntegerTest(left, right);
-        append(new BranchOp(negated ? Condition.NE : Condition.EQ, trueDestination, falseDestination, left.getKind().getStackKind()));
+        append(new BranchOp(Condition.EQ, trueDestination, falseDestination, left.getKind().getStackKind()));
     }
 
     private void emitIntegerTest(Value a, Value b) {
@@ -443,7 +422,7 @@
     }
 
     @Override
-    public void emitCharArrayEquals(Variable result, Value array1, Value array2, Value length) {
+    public void emitArrayEquals(Kind kind, Variable result, Value array1, Value array2, Value length) {
         // TODO Auto-generated method stub
         throw GraalInternalError.unimplemented();
     }
@@ -753,129 +732,120 @@
         }
     }
 
-    private AllocatableValue emitConvertMove(Kind kind, AllocatableValue input) {
+    private AllocatableValue emitConvertMove(PlatformKind kind, AllocatableValue input) {
         Variable result = newVariable(kind);
         emitMove(result, input);
         return result;
     }
 
-    private AllocatableValue emitConvert2Op(Kind kind, SPARCArithmetic op, AllocatableValue input) {
+    private AllocatableValue emitConvert2Op(PlatformKind kind, SPARCArithmetic op, AllocatableValue input) {
         Variable result = newVariable(kind);
         append(new Unary2Op(op, result, input));
         return result;
     }
 
     @Override
-    public AllocatableValue emitConvert(Kind from, Kind to, Value inputVal) {
-        assert inputVal.getKind() == from.getStackKind();
-
+    public Value emitFloatConvert(FloatConvert op, Value inputVal) {
         AllocatableValue input = asAllocatable(inputVal);
-        if (from == to) {
-            return input;
+        switch (op) {
+            case D2F:
+                return emitConvert2Op(Kind.Float, D2F, input);
+            case D2I:
+                return emitConvert2Op(Kind.Int, D2I, input);
+            case D2L:
+                return emitConvert2Op(Kind.Long, D2L, input);
+            case F2D:
+                return emitConvert2Op(Kind.Double, F2D, input);
+            case F2I:
+                return emitConvert2Op(Kind.Int, F2I, input);
+            case F2L:
+                return emitConvert2Op(Kind.Long, F2L, input);
+            case I2D:
+                return emitConvert2Op(Kind.Double, I2D, input);
+            case I2F:
+                return emitConvert2Op(Kind.Float, I2F, input);
+            case L2D:
+                return emitConvert2Op(Kind.Double, L2D, input);
+            case L2F:
+                return emitConvert2Op(Kind.Float, L2F, input);
+            default:
+                throw GraalInternalError.shouldNotReachHere();
         }
-        switch (to) {
-            case Byte:
-                switch (from) {
-                    case Short:
-                    case Char:
-                    case Int:
-                    case Long:
-                        return emitConvert2Op(to, I2B, input);
-                    case Float:
-                    case Double:
-                        AllocatableValue intVal = emitConvert(from, Kind.Int, inputVal);
-                        return emitConvert(Kind.Int, to, intVal);
-                }
-                break;
-            case Char:
-                switch (from) {
-                    case Byte:
-                    case Short:
-                    case Int:
-                    case Long:
-                        return emitConvert2Op(to, I2C, input);
-                    case Float:
-                    case Double:
-                        AllocatableValue intVal = emitConvert(from, Kind.Int, inputVal);
-                        return emitConvert(Kind.Int, to, intVal);
-                }
-                break;
-            case Short:
-                switch (from) {
-                    case Byte:
-                    case Char:
-                    case Int:
-                    case Long:
-                        return emitConvert2Op(to, I2S, input);
-                    case Float:
-                    case Double:
-                        AllocatableValue intVal = emitConvert(from, Kind.Int, inputVal);
-                        return emitConvert(Kind.Int, to, intVal);
-                }
-                break;
-            case Int:
-                switch (from) {
-                    case Byte:
-                    case Short:
-                    case Char:
-                        return emitConvertMove(to, input);
-                    case Long:
-                        return emitConvert2Op(to, L2I, input);
-                    case Float:
-                        return emitConvert2Op(to, F2I, input);
-                    case Double:
-                        return emitConvert2Op(to, D2I, input);
-                }
-                break;
-            case Long:
-                switch (from) {
-                    case Byte:
-                    case Short:
-                    case Char:
-                    case Int:
-                        return emitConvert2Op(to, I2L, input);
-                    case Float:
-                        return emitConvert2Op(to, F2L, input);
-                    case Double:
-                        return emitConvert2Op(to, D2L, input);
-                }
-                break;
-            case Float:
-                switch (from) {
-                    case Byte:
-                    case Short:
-                    case Char:
-                    case Int:
-                        return emitConvert2Op(to, I2F, input);
-                    case Long:
-                        return emitConvert2Op(to, L2F, input);
-                    case Double:
-                        return emitConvert2Op(to, D2F, input);
-                }
-                break;
-            case Double:
-                switch (from) {
-                    case Byte:
-                    case Short:
-                    case Char:
-                    case Int:
-                        return emitConvert2Op(to, I2D, input);
-                    case Long:
-                        return emitConvert2Op(to, L2D, input);
-                    case Float:
-                        return emitConvert2Op(to, F2D, input);
-                }
-                break;
+    }
+
+    @Override
+    public Value emitNarrow(Value inputVal, int bits) {
+        if (inputVal.getKind() == Kind.Long && bits <= 32) {
+            return emitConvert2Op(Kind.Int, L2I, asAllocatable(inputVal));
+        } else {
+            return inputVal;
         }
-        throw GraalInternalError.shouldNotReachHere();
     }
 
-    public AllocatableValue emitReinterpret(Kind to, Value inputVal) {
+    @Override
+    public Value emitSignExtend(Value inputVal, int fromBits, int toBits) {
+        assert fromBits <= toBits && toBits <= 64;
+        if (fromBits == toBits) {
+            return inputVal;
+        } else if (toBits > 32) {
+            // sign extend to 64 bits
+            if (fromBits == 32) {
+                return emitConvert2Op(Kind.Long, I2L, asAllocatable(inputVal));
+            } else if (fromBits < 32) {
+                // TODO implement direct x2L sign extension conversions
+                Value intVal = emitSignExtend(inputVal, fromBits, 32);
+                return emitSignExtend(intVal, 32, toBits);
+            } else {
+                throw GraalInternalError.unimplemented("unsupported sign extension (" + fromBits + " bit -> " + toBits + " bit)");
+            }
+        } else {
+            // sign extend to 32 bits (smaller values are internally represented as 32 bit values)
+            switch (fromBits) {
+                case 8:
+                    return emitConvert2Op(Kind.Int, I2B, asAllocatable(inputVal));
+                case 16:
+                    return emitConvert2Op(Kind.Int, I2S, asAllocatable(inputVal));
+                case 32:
+                    return inputVal;
+                default:
+                    throw GraalInternalError.unimplemented("unsupported sign extension (" + fromBits + " bit -> " + toBits + " bit)");
+            }
+        }
+    }
+
+    @Override
+    public Value emitZeroExtend(Value inputVal, int fromBits, int toBits) {
+        assert fromBits <= toBits && toBits <= 64;
+        if (fromBits == toBits) {
+            return inputVal;
+        } else if (fromBits > 32) {
+            assert inputVal.getKind() == Kind.Long;
+            Variable result = newVariable(Kind.Long);
+            long mask = IntegerStamp.defaultMask(fromBits);
+            append(new BinaryRegConst(SPARCArithmetic.LAND, result, asAllocatable(inputVal), Constant.forLong(mask)));
+            return result;
+        } else {
+            assert inputVal.getKind() == Kind.Int;
+            Variable result = newVariable(Kind.Int);
+            int mask = (int) IntegerStamp.defaultMask(fromBits);
+            append(new BinaryRegConst(SPARCArithmetic.IAND, result, asAllocatable(inputVal), Constant.forInt(mask)));
+            if (toBits > 32) {
+                Variable longResult = newVariable(Kind.Long);
+                emitMove(longResult, result);
+                return longResult;
+            } else {
+                return result;
+            }
+        }
+    }
+
+    @Override
+    public AllocatableValue emitReinterpret(PlatformKind to, Value inputVal) {
         Kind from = inputVal.getKind();
         AllocatableValue input = asAllocatable(inputVal);
 
         // These cases require a move between CPU and FPU registers:
-        switch (to) {
+        switch ((Kind) to) {
             case Int:
                 switch (from) {
                     case Float:
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java	Wed Mar 05 19:40:15 2014 -0800
@@ -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
@@ -39,6 +39,7 @@
 import com.oracle.graal.api.code.CallingConvention.Type;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.api.runtime.*;
+import com.oracle.graal.baseline.*;
 import com.oracle.graal.compiler.target.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.debug.Debug.Scope;
@@ -83,10 +84,20 @@
     private final Backend backend;
     private final Suites suites;
 
+    private static boolean substitutionsInstalled;
+
+    private void installSubstitutions() {
+        if (!substitutionsInstalled) {
+            this.providers.getReplacements().registerSubstitutions(InjectProfileDataSubstitutions.class);
+            substitutionsInstalled = true;
+        }
+    }
+
     public GraalCompilerTest() {
         this.backend = Graal.getRequiredCapability(RuntimeProvider.class).getHostBackend();
         this.providers = getBackend().getProviders();
         this.suites = backend.getSuites().createSuites();
+        installSubstitutions();
     }
 
     /**
@@ -106,6 +117,7 @@
         }
         this.providers = backend.getProviders();
         this.suites = backend.getSuites().createSuites();
+        installSubstitutions();
     }
 
     @BeforeClass
@@ -413,7 +425,12 @@
         ResolvedJavaMethod javaMethod = getMetaAccess().lookupJavaMethod(method);
         checkArgs(javaMethod, executeArgs);
 
-        InstalledCode compiledMethod = getCode(javaMethod, parse(method));
+        InstalledCode compiledMethod = null;
+        if (UseBaselineCompiler.getValue()) {
+            compiledMethod = getCodeBaseline(javaMethod, method);
+        } else {
+            compiledMethod = getCode(javaMethod, parse(method));
+        }
         try {
             return new Result(compiledMethod.executeVarargs(executeArgs), null);
         } catch (Throwable e) {
@@ -423,6 +440,73 @@
         }
     }
 
+    protected InstalledCode getCodeBaseline(ResolvedJavaMethod javaMethod, Method method) {
+        return getCodeBaseline(javaMethod, method, false);
+    }
+
+    protected InstalledCode getCodeBaseline(ResolvedJavaMethod javaMethod, Method method, boolean forceCompile) {
+        assert method.getAnnotation(Test.class) == null : "shouldn't parse method with @Test annotation: " + method;
+
+        try (Scope bds = Debug.scope("Baseline")) {
+            Debug.log("getCodeBaseline()");
+        } catch (Throwable e) {
+            throw Debug.handle(e);
+        }
+
+        if (!forceCompile) {
+            InstalledCode cached = cache.get(javaMethod);
+            if (cached != null) {
+                if (cached.isValid()) {
+                    return cached;
+                }
+            }
+        }
+
+        final int id = compilationId.incrementAndGet();
+
+        InstalledCode installedCode = null;
+        try (Scope ds = Debug.scope("Compiling", new DebugDumpScope(String.valueOf(id), true))) {
+            final boolean printCompilation = PrintCompilation.getValue() && !TTY.isSuppressed();
+
+            if (printCompilation) {
+                TTY.println(String.format("@%-6d Graal %-70s %-45s %-50s ...", id, javaMethod.getDeclaringClass().getName(), javaMethod.getName(), javaMethod.getSignature()));
+            }
+            long start = System.currentTimeMillis();
+
+            CompilationResult compResult = compileBaseline(javaMethod);
+
+            if (printCompilation) {
+                TTY.println(String.format("@%-6d Graal %-70s %-45s %-50s | %4dms %5dB", id, "", "", "", System.currentTimeMillis() - start, compResult.getTargetCodeSize()));
+            }
+
+            try (Scope s = Debug.scope("CodeInstall", getCodeCache(), javaMethod)) {
+                installedCode = addMethod(javaMethod, compResult);
+                if (installedCode == null) {
+                    throw new GraalInternalError("Could not install code for " + MetaUtil.format("%H.%n(%p)", javaMethod));
+                }
+            } catch (Throwable e) {
+                throw Debug.handle(e);
+            }
+        } catch (Throwable e) {
+            throw Debug.handle(e);
+        }
+
+        if (!forceCompile) {
+            cache.put(javaMethod, installedCode);
+        }
+        return installedCode;
+    }
+
+    private CompilationResult compileBaseline(ResolvedJavaMethod javaMethod) {
+        try (Scope bds = Debug.scope("compileBaseline")) {
+            BaslineCompiler baselineCompiler = new BaslineCompiler(GraphBuilderConfiguration.getDefault(), providers.getMetaAccess());
+            baselineCompiler.generate(javaMethod, -1);
+            return null;
+        } catch (Throwable e) {
+            throw Debug.handle(e);
+        }
+    }
+
     protected void checkArgs(ResolvedJavaMethod method, Object[] args) {
         JavaType[] sig = MetaUtil.signatureToTypes(method);
         Assert.assertEquals(sig.length, args.length);
@@ -578,7 +662,11 @@
     protected CompilationResult compile(ResolvedJavaMethod method, final StructuredGraph graph) {
         CallingConvention cc = getCallingConvention(getCodeCache(), Type.JavaCallee, graph.method(), false);
         return compileGraph(graph, cc, method, getProviders(), getBackend(), getCodeCache().getTarget(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL, getProfilingInfo(graph),
-                        new SpeculationLog(), getSuites(), true, new CompilationResult(), CompilationResultBuilderFactory.Default);
+                        getSpeculationLog(), getSuites(), true, new CompilationResult(), CompilationResultBuilderFactory.Default);
+    }
+
+    protected SpeculationLog getSpeculationLog() {
+        return null;
     }
 
     protected InstalledCode addMethod(final ResolvedJavaMethod method, final CompilationResult compResult) {
@@ -639,4 +727,27 @@
     protected Replacements getReplacements() {
         return getProviders().getReplacements();
     }
+
+    /**
+     * Inject a probability for a branch condition into the profiling information of this test case.
+     * 
+     * @param p the probability that cond is true
+     * @param cond the condition of the branch
+     * @return cond
+     */
+    protected static boolean branchProbability(double p, boolean cond) {
+        return cond;
+    }
+
+    /**
+     * Inject an iteration count for a loop condition into the profiling information of this test
+     * case.
+     * 
+     * @param i the iteration count of the loop
+     * @param cond the condition of the loop
+     * @return cond
+     */
+    protected static boolean iterationCount(double i, boolean cond) {
+        return cond;
+    }
 }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/InfopointReasonTest.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/InfopointReasonTest.java	Wed Mar 05 19:40:15 2014 -0800
@@ -63,7 +63,7 @@
         final StructuredGraph graph = parse(method);
         CallingConvention cc = getCallingConvention(getCodeCache(), Type.JavaCallee, graph.method(), false);
         final CompilationResult cr = compileGraph(graph, cc, graph.method(), getProviders(), getBackend(), getCodeCache().getTarget(), null, getDefaultGraphBuilderSuite(),
-                        OptimisticOptimizations.ALL, getProfilingInfo(graph), new SpeculationLog(), getSuites(), true, new CompilationResult(), CompilationResultBuilderFactory.Default);
+                        OptimisticOptimizations.ALL, getProfilingInfo(graph), null, getSuites(), true, new CompilationResult(), CompilationResultBuilderFactory.Default);
         for (Infopoint sp : cr.getInfopoints()) {
             assertNotNull(sp.reason);
             if (sp instanceof Call) {
@@ -86,7 +86,7 @@
         CallingConvention cc = getCallingConvention(getCodeCache(), Type.JavaCallee, graph.method(), false);
         PhaseSuite<HighTierContext> graphBuilderSuite = getCustomGraphBuilderSuite(GraphBuilderConfiguration.getEagerInfopointDefault());
         final CompilationResult cr = compileGraph(graph, cc, graph.method(), getProviders(), getBackend(), getCodeCache().getTarget(), null, graphBuilderSuite, OptimisticOptimizations.ALL,
-                        getProfilingInfo(graph), new SpeculationLog(), getSuites(), true, new CompilationResult(), CompilationResultBuilderFactory.Default);
+                        getProfilingInfo(graph), getSpeculationLog(), getSuites(), true, new CompilationResult(), CompilationResultBuilderFactory.Default);
         int lineSPs = 0;
         for (Infopoint sp : cr.getInfopoints()) {
             assertNotNull(sp.reason);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/InjectProfileDataSubstitutions.java	Wed Mar 05 19:40:15 2014 -0800
@@ -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.test;
+
+import com.oracle.graal.api.replacements.*;
+import com.oracle.graal.nodes.extended.*;
+
+@ClassSubstitution(GraalCompilerTest.class)
+class InjectProfileDataSubstitutions {
+
+    @MethodSubstitution
+    public static boolean branchProbability(double p, boolean cond) {
+        return BranchProbabilityNode.probability(p, cond);
+    }
+
+    @MethodSubstitution
+    public static boolean iterationCount(double i, boolean cond) {
+        return BranchProbabilityNode.probability(1. - 1. / i, cond);
+    }
+}
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ProfilingInfoTest.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ProfilingInfoTest.java	Wed Mar 05 19:40:15 2014 -0800
@@ -323,7 +323,10 @@
             }
         }
 
-        return javaMethod.getProfilingInfo();
+        ProfilingInfo info = javaMethod.getProfilingInfo();
+        // The execution counts are low so force maturity
+        info.setMature();
+        return info;
     }
 
     private void resetProfile(String methodName) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ShortCircuitNodeTest.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,65 @@
+/*
+ * 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.compiler.test.ea.EATestBase.TestClassInt;
+
+public class ShortCircuitNodeTest extends GraalCompilerTest {
+
+    @Test
+    public void test1() {
+        // only executeActual, to avoid creating profiling information
+        executeActual(getMethod("test1Snippet"), 1, 2);
+    }
+
+    public static final TestClassInt field = null;
+    public static TestClassInt field2 = null;
+
+    @SuppressWarnings("unused")
+    public static void test1Snippet(int a, int b) {
+        /*
+         * if a ShortCircuitOrNode is created for the check inside test2, then faulty handling of
+         * guards can create a cycle in the graph.
+         */
+        int v;
+        if (a == 1) {
+            if (b != 1) {
+                int i = field.x;
+            }
+            field2 = null;
+            v = 0;
+        } else {
+            v = 1;
+        }
+
+        if (test2(v, b)) {
+            int i = field.x;
+        }
+    }
+
+    public static boolean test2(int a, int b) {
+        return a != 0 || b != 1;
+    }
+}
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/deopt/SynchronizedMethodDeoptimizationTest.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/deopt/SynchronizedMethodDeoptimizationTest.java	Wed Mar 05 19:40:15 2014 -0800
@@ -22,52 +22,29 @@
  */
 package com.oracle.graal.compiler.test.deopt;
 
-import java.lang.reflect.*;
-
 import org.junit.*;
 
-import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.test.*;
-import com.oracle.graal.nodes.*;
+import com.oracle.graal.compiler.test.ea.EATestBase.TestClassObject;
 
 /**
  * In the following tests, we try to deoptimize out of synchronized methods.
  */
 public class SynchronizedMethodDeoptimizationTest extends GraalCompilerTest {
 
-    public static final int N = 15000;
+    public static final TestClassObject testObject = null;
 
     public static synchronized Object testMethodSynchronized(Object o) {
         if (o == null) {
-            return null;
+            // this branch will always deoptimize
+            return testObject.x;
         }
         return o;
     }
 
     @Test
     public void test1() {
-        Method method = getMethod("testMethodSynchronized");
-        String testString = "test";
-        for (int i = 0; i < N; ++i) {
-            Assert.assertEquals(testString, testMethodSynchronized(testString));
-        }
-        final StructuredGraph graph = parseProfiled(method);
-        final ResolvedJavaMethod javaMethod = getMetaAccess().lookupJavaMethod(method);
-        InstalledCode compiledMethod = getCode(javaMethod, graph);
-        try {
-            Object result = compiledMethod.executeVarargs(testString);
-            Assert.assertEquals(testString, result);
-        } catch (InvalidInstalledCodeException t) {
-            Assert.fail("method invalidated");
-        }
-
-        try {
-            Object result = compiledMethod.executeVarargs(new Object[]{null});
-            Assert.assertEquals(null, result);
-            Assert.assertFalse(compiledMethod.isValid());
-        } catch (InvalidInstalledCodeException t) {
-            Assert.fail("method invalidated");
-        }
+        test("testMethodSynchronized", "test");
+        test("testMethodSynchronized", (Object) null);
     }
 }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EscapeAnalysisTest.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EscapeAnalysisTest.java	Wed Mar 05 19:40:15 2014 -0800
@@ -28,6 +28,7 @@
 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.*;
@@ -158,6 +159,103 @@
     }
 
     @Test
+    public void testMergeAllocationsInt() {
+        testEscapeAnalysis("testMergeAllocationsIntSnippet", Constant.forInt(1), false);
+    }
+
+    public int testMergeAllocationsIntSnippet(int a) {
+        TestClassInt obj;
+        if (a < 0) {
+            obj = new TestClassInt(1, 2);
+            notInlineable();
+        } else {
+            obj = new TestClassInt(1, 2);
+            notInlineable();
+        }
+        return obj.x <= 3 ? 1 : 0;
+    }
+
+    @Test
+    public void testMergeAllocationsObj() {
+        testEscapeAnalysis("testMergeAllocationsObjSnippet", Constant.forInt(1), false);
+    }
+
+    public int testMergeAllocationsObjSnippet(int a) {
+        TestClassObject obj;
+        Integer one = 1;
+        Integer two = 2;
+        Integer three = 3;
+        if (a < 0) {
+            obj = new TestClassObject(one, two);
+            notInlineable();
+        } else {
+            obj = new TestClassObject(one, three);
+            notInlineable();
+        }
+        return ((Integer) obj.x).intValue() <= 3 ? 1 : 0;
+    }
+
+    @Test
+    public void testMergeAllocationsObjCirc() {
+        testEscapeAnalysis("testMergeAllocationsObjCircSnippet", Constant.forInt(1), false);
+    }
+
+    public int testMergeAllocationsObjCircSnippet(int a) {
+        TestClassObject obj;
+        Integer one = 1;
+        Integer two = 2;
+        Integer three = 3;
+        if (a < 0) {
+            obj = new TestClassObject(one);
+            obj.y = obj;
+            obj.y = two;
+            notInlineable();
+        } else {
+            obj = new TestClassObject(one);
+            obj.y = obj;
+            obj.y = three;
+            notInlineable();
+        }
+        return ((Integer) obj.x).intValue() <= 3 ? 1 : 0;
+    }
+
+    static class MyException extends RuntimeException {
+
+        private static final long serialVersionUID = 0L;
+
+        protected Integer value;
+
+        public MyException(Integer value) {
+            super((Throwable) null);
+            this.value = value;
+        }
+
+        @SuppressWarnings("sync-override")
+        @Override
+        public final Throwable fillInStackTrace() {
+            return null;
+        }
+    }
+
+    @Test
+    public void testMergeAllocationsException() {
+        testEscapeAnalysis("testMergeAllocationsExceptionSnippet", Constant.forInt(1), false);
+    }
+
+    public int testMergeAllocationsExceptionSnippet(int a) {
+        MyException obj;
+        Integer one = 1;
+        if (a < 0) {
+            obj = new MyException(one);
+            notInlineable();
+        } else {
+            obj = new MyException(one);
+            notInlineable();
+        }
+        return obj.value <= 3 ? 1 : 0;
+    }
+
+    @Test
     public void testCheckCast() {
         testEscapeAnalysis("testCheckCastSnippet", Constant.forObject(TestClassObject.class), false);
     }
@@ -181,7 +279,7 @@
 
     @SuppressWarnings("unused")
     public static void testNewNodeSnippet() {
-        new IntegerAddNode(Kind.Int, null, null);
+        new IntegerAddNode(new IntegerStamp(32, false, Integer.MIN_VALUE, Integer.MAX_VALUE, 0, 0xFFFFFFFF), null, null);
     }
 
     /**
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/nfi/NativeFunctionInterfaceTest.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,400 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.compiler.test.nfi;
+
+import static com.oracle.graal.graph.UnsafeAccess.*;
+import static java.io.File.*;
+import static java.lang.System.*;
+import static org.junit.Assert.*;
+import static org.junit.Assume.*;
+
+import java.io.*;
+import java.util.*;
+
+import org.junit.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.runtime.*;
+import com.oracle.graal.compiler.target.*;
+import com.oracle.graal.runtime.*;
+
+public class NativeFunctionInterfaceTest {
+
+    public final NativeFunctionInterface nfi;
+
+    public NativeFunctionInterfaceTest() {
+        RuntimeProvider runtimeProvider = Graal.getRequiredCapability(RuntimeProvider.class);
+        Assume.assumeTrue(runtimeProvider.getHostBackend() instanceof HostBackend);
+        nfi = ((HostBackend) runtimeProvider.getHostBackend()).getNativeFunctionInterface();
+    }
+
+    private List<Long> allocations = new ArrayList<>();
+
+    protected long malloc(int length) {
+        long buf = unsafe.allocateMemory(length);
+        allocations.add(buf);
+        return buf;
+    }
+
+    @After
+    public void cleanup() {
+        for (long buf : allocations) {
+            unsafe.freeMemory(buf);
+        }
+    }
+
+    private static void assertCStringEquals(long cString, String s) {
+        for (int i = 0; i < s.length(); i++) {
+            assertEquals(unsafe.getByte(cString + i) & 0xFF, (byte) s.charAt(i));
+        }
+        assertEquals(unsafe.getByte(cString + s.length()) & 0xFF, (byte) '\0');
+    }
+
+    @Test
+    public void test1() {
+        assumeTrue(nfi.isDefaultLibrarySearchSupported());
+        NativeFunctionHandle malloc = nfi.getFunctionHandle("malloc", long.class, int.class);
+        NativeFunctionHandle snprintf = nfi.getFunctionHandle("snprintf", int.class, long.class, int.class, long.class);
+        NativeFunctionHandle free = nfi.getFunctionHandle("free", void.class, long.class);
+
+        String string = "GRAAL";
+        int bufferLength = string.length() + 1;
+        long cString = (long) malloc.call(bufferLength);
+        writeCString(string, cString);
+
+        long cStringCopy = malloc(bufferLength);
+        int result = (int) snprintf.call(cStringCopy, bufferLength, cString);
+        Assert.assertEquals(string.length(), result);
+        assertCStringEquals(cString, string);
+        assertCStringEquals(cStringCopy, string);
+
+        free.call(cString);
+    }
+
+    @Test
+    public void test2() {
+        assumeTrue(nfi.isDefaultLibrarySearchSupported());
+        String formatString = "AB %f%f";
+        long formatCString = writeCString("AB %f%f", malloc(formatString.length() + 1));
+
+        String referenceString = "AB 1.0000001.000000";
+        int bufferLength = referenceString.length() + 1;
+        long buffer = malloc(bufferLength);
+
+        NativeFunctionHandle snprintf = nfi.getFunctionHandle("snprintf", int.class, long.class, int.class, long.class, double.class, double.class);
+        int result = (int) snprintf.call(buffer, bufferLength, formatCString, 1.0D, 1.0D);
+
+        assertCStringEquals(buffer, referenceString);
+        Assert.assertEquals(referenceString.length(), result);
+    }
+
+    @Test
+    public void test3() {
+        assumeTrue(nfi.isDefaultLibrarySearchSupported());
+        String format = "%i%i%i%i%i%i%i%i%i%i%i%i";
+        long formatCString = writeCString(format, malloc(format.length() + 1));
+        String referenceString = "01234567891011";
+
+        int bufferLength = referenceString.length() + 1;
+        long buffer = malloc(bufferLength);
+
+        NativeFunctionHandle snprintf = nfi.getFunctionHandle("snprintf", int.class, long.class, int.class, long.class, int.class, int.class, int.class, int.class, int.class, int.class, int.class,
+                        int.class, int.class, int.class, int.class, int.class);
+
+        int result = (int) snprintf.call(buffer, bufferLength, formatCString, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11);
+        assertCStringEquals(buffer, referenceString);
+        Assert.assertEquals(referenceString.length(), result);
+    }
+
+    @Test
+    public void test4() {
+        assumeTrue(nfi.isDefaultLibrarySearchSupported());
+        long str = malloc(49);
+        int[] val = new int[12];
+        for (int i = 0; i < 12; i++) {
+            unsafe.putByte(str + 2 * i, (byte) '%');
+            unsafe.putByte(str + 2 * i + 1, (byte) 'i');
+            val[i] = i;
+        }
+        double[] dval = new double[12];
+        for (int i = 12; i < 24; i++) {
+            unsafe.putByte(str + 2 * i, (byte) '%');
+            unsafe.putByte(str + 2 * i + 1, (byte) 'f');
+            dval[i - 12] = i + 0.5;
+        }
+        unsafe.putByte(str + 48, (byte) '\0');
+
+        String referenceString = "0123456789101112.50000013.50000014.50000015.50000016.50000017.50000018.50000019.50000020.500000" + "21.50000022.50000023.500000";
+        int bufferLength = referenceString.length() + 1;
+
+        long buffer = malloc(bufferLength);
+
+        NativeFunctionHandle snprintf = nfi.getFunctionHandle("snprintf", int.class, long.class, int.class, long.class, int.class, int.class, int.class, int.class, int.class, int.class, int.class,
+                        int.class, int.class, int.class, int.class, int.class, double.class, double.class, double.class, double.class, double.class, double.class, double.class, double.class,
+                        double.class, double.class, double.class, double.class);
+
+        int result = (int) snprintf.call(buffer, bufferLength, str, val[0], val[1], val[2], val[3], val[4], val[5], val[6], val[7], val[8], val[9], val[10], val[11], dval[0], dval[1], dval[2],
+                        dval[3], dval[4], dval[5], dval[6], dval[7], dval[8], dval[9], dval[10], dval[11]);
+        assertCStringEquals(buffer, referenceString);
+        Assert.assertEquals(referenceString.length(), result);
+    }
+
+    @Test
+    public void test5() {
+        assumeTrue(nfi.isDefaultLibrarySearchSupported());
+        long str = malloc(73);
+        int[] val = new int[12];
+        for (int i = 0; i < 12; i++) {
+            unsafe.putByte(str + 2 * i, (byte) '%');
+            unsafe.putByte(str + 2 * i + 1, (byte) 'i');
+            val[i] = i;
+        }
+        double[] dval = new double[12];
+        for (int i = 12; i < 24; i++) {
+            unsafe.putByte(str + 2 * i, (byte) '%');
+            unsafe.putByte(str + 2 * i + 1, (byte) 'f');
+            dval[i - 12] = i + 0.5;
+        }
+        char[] cval = new char[12];
+        for (int i = 24; i < 36; i++) {
+            unsafe.putByte(str + 2 * i, (byte) '%');
+            unsafe.putByte(str + 2 * i + 1, (byte) 'c');
+            cval[i - 24] = (char) ('a' + (i - 24));
+        }
+        unsafe.putByte(str + 72, (byte) '\0');
+
+        String referenceString = "0123456789101112.50000013.50000014.50000015.50000016.50000017.50000018.50000019.50000020.50000021.50000022.50000023.500000abcdefghijkl";
+        int bufferLength = referenceString.length() + 1;
+
+        long buffer = malloc(bufferLength);
+
+        NativeFunctionHandle snprintf = nfi.getFunctionHandle("snprintf", int.class, long.class, int.class, long.class, int.class, int.class, int.class, int.class, int.class, int.class, int.class,
+                        int.class, int.class, int.class, int.class, int.class, double.class, double.class, double.class, double.class, double.class, double.class, double.class, double.class,
+                        double.class, double.class, double.class, double.class, char.class, char.class, char.class, char.class, char.class, char.class, char.class, char.class, char.class, char.class,
+                        char.class, char.class);
+
+        int result = (int) snprintf.call(buffer, bufferLength, str, val[0], val[1], val[2], val[3], val[4], val[5], val[6], val[7], val[8], val[9], val[10], val[11], dval[0], dval[1], dval[2],
+                        dval[3], dval[4], dval[5], dval[6], dval[7], dval[8], dval[9], dval[10], dval[11], cval[0], cval[1], cval[2], cval[3], cval[4], cval[5], cval[6], cval[7], cval[8], cval[9],
+                        cval[10], cval[11]);
+        assertCStringEquals(buffer, referenceString);
+        Assert.assertEquals(referenceString.length(), result);
+    }
+
+    @Test
+    public void test6() {
+        assumeTrue(nfi.isDefaultLibrarySearchSupported());
+        NativeFunctionHandle handle = nfi.getFunctionHandle("pow", double.class, double.class, double.class);
+        double result = (double) handle.call(3D, 5.5D);
+        assertEquals(Math.pow(3D, 5.5D), result, 0);
+    }
+
+    @Test
+    public void test7() {
+        assumeTrue(nfi.isDefaultLibrarySearchSupported());
+        double result = 0;
+        NativeFunctionHandle handle = nfi.getFunctionHandle("pow", double.class, double.class, double.class);
+        for (int i = 0; i < 10; i++) {
+            result = (double) handle.call(3D, 5.5D);
+        }
+        assertEquals(Math.pow(3D, 5.5D), result, 0);
+    }
+
+    @Test
+    public void test8() {
+        assumeTrue(nfi.isDefaultLibrarySearchSupported());
+        String formatString = "AB %f%f";
+        long formatCString = writeCString("AB %f%f", malloc(formatString.length() + 1));
+
+        String expected = "AB 1.0000001.000000";
+        int bufferLength = expected.length() + 1;
+        byte[] buffer = new byte[bufferLength];
+
+        NativeFunctionHandle snprintf = nfi.getFunctionHandle("snprintf", int.class, byte[].class, int.class, long.class, double.class, double.class);
+        int result = (int) snprintf.call(buffer, bufferLength, formatCString, 1.0D, 1.0D);
+
+        // trim trailing '\0'
+        String actual = new String(buffer, 0, expected.length());
+
+        assertEquals(expected, actual);
+        Assert.assertEquals(expected.length(), result);
+    }
+
+    private static double[] someDoubles = {2454.346D, 98789.22D, Double.MAX_VALUE, Double.MIN_NORMAL, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY};
+
+    @Test
+    public void test9() {
+        assumeTrue(nfi.isDefaultLibrarySearchSupported());
+        double[] src = someDoubles.clone();
+        double[] dst = new double[src.length];
+
+        NativeFunctionHandle memcpy = nfi.getFunctionHandle("memcpy", void.class, double[].class, double[].class, int.class);
+        memcpy.call(dst, src, src.length * (Double.SIZE / Byte.SIZE));
+
+        assertArrayEquals(src, dst, 0.0D);
+    }
+
+    private static String getVMName() {
+        String vmName = System.getProperty("java.vm.name").toLowerCase();
+        String vm = null;
+        if (vmName.contains("server")) {
+            vm = "server";
+        } else if (vmName.contains("graal")) {
+            vm = "graal";
+        } else if (vmName.contains("client")) {
+            vm = "client";
+        }
+
+        Assume.assumeTrue(vm != null);
+        return vm;
+    }
+
+    private static String getVMLibPath() {
+        String vm = getVMName();
+
+        String path = String.format("%s%c%s%c%s", getProperty("sun.boot.library.path"), separatorChar, vm, separatorChar, mapLibraryName("jvm"));
+        // Only continue if the library file exists
+        Assume.assumeTrue(new File(path).exists());
+        return path;
+    }
+
+    @Test
+    public void test10() {
+        NativeLibraryHandle vmLib = nfi.getLibraryHandle(getVMLibPath());
+        NativeFunctionHandle currentTimeMillis = nfi.getFunctionHandle(vmLib, "JVM_CurrentTimeMillis", long.class);
+        long time1 = (long) currentTimeMillis.call();
+        long time2 = System.currentTimeMillis();
+        long delta = time2 - time1;
+
+        // The 2 calls to get the current time should not differ by more than
+        // 100 milliseconds at the very most
+        assertTrue(String.valueOf(delta), delta >= 0);
+        assertTrue(String.valueOf(delta), delta < 100);
+    }
+
+    private static String getJavaLibPath() {
+        String path = String.format("%s%c%s", getProperty("sun.boot.library.path"), separatorChar, mapLibraryName("java"));
+        Assume.assumeTrue(new File(path).exists());
+        return path;
+    }
+
+    private static void testD2L(NativeFunctionHandle d2l) {
+        for (double d : someDoubles) {
+            long expected = Double.doubleToRawLongBits(d);
+            long actual = (long) d2l.call(0L, 0L, d);
+            assertEquals(Double.toString(d), expected, actual);
+        }
+    }
+
+    @Test
+    public void test11() {
+        NativeLibraryHandle javaLib = nfi.getLibraryHandle(getJavaLibPath());
+        NativeFunctionHandle d2l = nfi.getFunctionHandle(javaLib, "Java_java_lang_Double_doubleToRawLongBits", long.class, long.class, long.class, double.class);
+        testD2L(d2l);
+    }
+
+    @Test
+    public void test12() {
+        NativeLibraryHandle[] libs = {nfi.getLibraryHandle(getVMLibPath()), nfi.getLibraryHandle(getJavaLibPath())};
+        NativeFunctionHandle d2l = nfi.getFunctionHandle(libs, "Java_java_lang_Double_doubleToRawLongBits", long.class, long.class, long.class, double.class);
+        testD2L(d2l);
+
+        NativeLibraryHandle[] libsReveresed = {libs[1], libs[0]};
+        d2l = nfi.getFunctionHandle(libsReveresed, "Java_java_lang_Double_doubleToRawLongBits", long.class, long.class, long.class, double.class);
+        testD2L(d2l);
+    }
+
+    @Test
+    public void test13() {
+        NativeLibraryHandle[] libs = {nfi.getLibraryHandle(getVMLibPath()), nfi.getLibraryHandle(getJavaLibPath())};
+        NativeFunctionPointer functionPointer = nfi.getFunctionPointer(libs, "Java_java_lang_Double_doubleToRawLongBits");
+        NativeFunctionHandle d2l = nfi.getFunctionHandle(functionPointer, long.class, long.class, long.class, double.class);
+        testD2L(d2l);
+
+        NativeLibraryHandle[] libsReveresed = {libs[1], libs[0]};
+        functionPointer = nfi.getFunctionPointer(libsReveresed, "Java_java_lang_Double_doubleToRawLongBits");
+        d2l = nfi.getFunctionHandle(functionPointer, long.class, long.class, long.class, double.class);
+        testD2L(d2l);
+    }
+
+    @Test
+    public void test14() {
+        if (!nfi.isDefaultLibrarySearchSupported()) {
+            try {
+                nfi.getFunctionHandle("snprintf", int.class);
+                fail();
+            } catch (UnsatisfiedLinkError e) {
+            }
+        }
+    }
+
+    @Test
+    public void test15() {
+        assumeTrue(nfi.isDefaultLibrarySearchSupported());
+        try {
+            nfi.getFunctionHandle("an invalid function name", int.class);
+            fail();
+        } catch (UnsatisfiedLinkError e) {
+        }
+    }
+
+    @Test
+    public void test16() {
+        NativeLibraryHandle javaLib = nfi.getLibraryHandle(getJavaLibPath());
+        try {
+
+            nfi.getFunctionHandle(javaLib, "an invalid function name", int.class);
+            fail();
+        } catch (UnsatisfiedLinkError e) {
+        }
+    }
+
+    @Test
+    public void test17() {
+        NativeLibraryHandle[] libs = {nfi.getLibraryHandle(getVMLibPath()), nfi.getLibraryHandle(getJavaLibPath())};
+        try {
+            nfi.getFunctionPointer(libs, "an invalid function name");
+            fail();
+        } catch (UnsatisfiedLinkError e) {
+        }
+    }
+
+    @Test
+    public void test18() {
+        NativeLibraryHandle[] libs = {nfi.getLibraryHandle(getVMLibPath()), nfi.getLibraryHandle(getJavaLibPath())};
+        try {
+            nfi.getFunctionHandle(libs, "an invalid function name", int.class);
+            fail();
+        } catch (UnsatisfiedLinkError e) {
+        }
+    }
+
+    @Test
+    public void test19() {
+        try {
+            nfi.getLibraryHandle("an invalid library name");
+            fail();
+        } catch (UnsatisfiedLinkError e) {
+        }
+    }
+
+}
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java	Wed Mar 05 19:40:15 2014 -0800
@@ -138,6 +138,7 @@
     public static <T extends CompilationResult> T compileGraph(StructuredGraph graph, CallingConvention cc, ResolvedJavaMethod installedCodeOwner, Providers providers, Backend backend,
                     TargetDescription target, GraphCache cache, PhaseSuite<HighTierContext> graphBuilderSuite, OptimisticOptimizations optimisticOpts, ProfilingInfo profilingInfo,
                     SpeculationLog speculationLog, Suites suites, boolean withScope, T compilationResult, CompilationResultBuilderFactory factory) {
+        assert !graph.isFrozen();
         try (Scope s0 = withScope ? Debug.scope("GraalCompiler", graph, providers.getCodeCache()) : null) {
             Assumptions assumptions = new Assumptions(OptAssumptions.getValue());
             LIR lir = null;
@@ -268,20 +269,33 @@
             throw Debug.handle(e);
         }
 
-        try (Scope s = Debug.scope("Allocator")) {
+        try (Scope s = Debug.scope("Allocator", lirGen)) {
             if (backend.shouldAllocateRegisters()) {
-                new LinearScan(target, lir, lirGen, frameMap).allocate();
+                new LinearScan(target, lir, frameMap).allocate();
             }
         } catch (Throwable e) {
             throw Debug.handle(e);
         }
+
+        try (Scope s = Debug.scope("ControlFlowOptimizations")) {
+            EdgeMoveOptimizer.optimize(lir);
+            ControlFlowOptimizer.optimize(lir);
+            if (lirGen.canEliminateRedundantMoves()) {
+                RedundantMoveElimination.optimize(lir, frameMap, lirGen.getGraph().method());
+            }
+            NullCheckOptimizer.optimize(lir, target.implicitNullCheckLimit);
+
+            Debug.dump(lir, "After control flow optimization");
+        } catch (Throwable e) {
+            throw Debug.handle(e);
+        }
         return lirGen;
     }
 
     public static void emitCode(Backend backend, long[] leafGraphIds, Assumptions assumptions, LIRGenerator lirGen, CompilationResult compilationResult, ResolvedJavaMethod installedCodeOwner,
                     CompilationResultBuilderFactory factory) {
         CompilationResultBuilder crb = backend.newCompilationResultBuilder(lirGen, compilationResult, factory);
-        backend.emitCode(crb, lirGen, installedCodeOwner);
+        backend.emitCode(crb, lirGen.lir, installedCodeOwner);
         crb.finish();
         if (!assumptions.isEmpty()) {
             compilationResult.setAssumptions(assumptions);
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java	Wed Mar 05 19:40:15 2014 -0800
@@ -45,6 +45,7 @@
 import com.oracle.graal.lir.LIRInstruction.StateProcedure;
 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.*;
 
@@ -58,7 +59,6 @@
 
     final TargetDescription target;
     final LIR ir;
-    final LIRGenerator gen;
     final FrameMap frameMap;
     final RegisterAttributes[] registerAttributes;
     final Register[] registers;
@@ -158,10 +158,9 @@
      */
     private final int firstVariableNumber;
 
-    public LinearScan(TargetDescription target, LIR ir, LIRGenerator gen, FrameMap frameMap) {
+    public LinearScan(TargetDescription target, LIR ir, FrameMap frameMap) {
         this.target = target;
         this.ir = ir;
-        this.gen = gen;
         this.frameMap = frameMap;
         this.sortedBlocks = ir.linearScanOrder();
         this.registerAttributes = frameMap.registerConfig.getAttributesMap();
@@ -563,7 +562,7 @@
                             assert isRegister(fromLocation) : "from operand must be a register but is: " + fromLocation + " toLocation=" + toLocation + " spillState=" + interval.spillState();
                             assert isStackSlot(toLocation) : "to operand must be a stack slot";
 
-                            insertionBuffer.append(j + 1, ir.spillMoveFactory.createMove(toLocation, fromLocation));
+                            insertionBuffer.append(j + 1, frameMap.createSpillMove(toLocation, fromLocation));
 
                             Debug.log("inserting move after definition of interval %d to stack slot %s at opId %d", interval.operandNumber, interval.spillSlot(), opId);
                         }
@@ -881,21 +880,54 @@
         indent.outdent();
     }
 
+    private static LIRGenerator getLIRGeneratorFromDebugContext() {
+        if (Debug.isEnabled()) {
+            LIRGenerator lirGen = Debug.contextLookup(LIRGenerator.class);
+            assert lirGen != null;
+            return lirGen;
+        }
+        return null;
+    }
+
+    private static ValueNode getValueForOperandFromDebugContext(Value value) {
+        LIRGenerator gen = getLIRGeneratorFromDebugContext();
+        if (gen != null) {
+            return gen.valueForOperand(value);
+        }
+        return null;
+    }
+
+    private static StructuredGraph getGraphFromDebugContext() {
+        LIRGenerator gen = getLIRGeneratorFromDebugContext();
+        if (gen != null) {
+            return gen.getGraph();
+        }
+        return null;
+    }
+
+    private static ResolvedJavaMethod getMethodFromDebugContext() {
+        StructuredGraph graph = getGraphFromDebugContext();
+        if (graph != null) {
+            return graph.method();
+        }
+        return null;
+    }
+
     private void reportFailure(int numBlocks) {
-        Indent indent = Debug.logAndIndent("report failure, graph: %s", gen.getGraph());
+        Indent indent = Debug.logAndIndent("report failure, graph: %s", getGraphFromDebugContext());
 
         BitSet startBlockLiveIn = blockData.get(ir.cfg.getStartBlock()).liveIn;
         try (Indent indent2 = Debug.logAndIndent("Error: liveIn set of first block must be empty (when this fails, variables are used before they are defined):")) {
             for (int operandNum = startBlockLiveIn.nextSetBit(0); operandNum >= 0; operandNum = startBlockLiveIn.nextSetBit(operandNum + 1)) {
                 Value operand = operandFor(operandNum);
-                Debug.log("var %d; operand=%s; node=%s", operandNum, operand, gen.valueForOperand(operand));
+                Debug.log("var %d; operand=%s; node=%s", operandNum, operand, getValueForOperandFromDebugContext(operand));
             }
         }
 
         // print some additional information to simplify debugging
         for (int operandNum = startBlockLiveIn.nextSetBit(0); operandNum >= 0; operandNum = startBlockLiveIn.nextSetBit(operandNum + 1)) {
             Value operand = operandFor(operandNum);
-            final Indent indent2 = Debug.logAndIndent("---- Detailed information for var %d; operand=%s; node=%s ----", operandNum, operand, gen.valueForOperand(operand));
+            final Indent indent2 = Debug.logAndIndent("---- Detailed information for var %d; operand=%s; node=%s ----", operandNum, operand, getValueForOperandFromDebugContext(operand));
 
             Deque<Block> definedIn = new ArrayDeque<>();
             HashSet<Block> usedIn = new HashSet<>();
@@ -1036,7 +1068,7 @@
             // detection of method-parameters and roundfp-results
             interval.setSpillState(SpillState.StartInMemory);
         }
-        interval.addMaterializationValue(gen.getMaterializedValue(op, operand, interval));
+        interval.addMaterializationValue(LinearScan.getMaterializedValue(op, operand, interval));
 
         Debug.log("add def: %s defPos %d (%s)", interval, defPos, registerPriority.name());
     }
@@ -1839,7 +1871,7 @@
         /*
          * This is the point to enable debug logging for the whole register allocation.
          */
-        Indent indent = Debug.logAndIndent("LinearScan allocate %s", gen.getGraph().method());
+        Indent indent = Debug.logAndIndent("LinearScan allocate %s", getMethodFromDebugContext());
 
         try (Scope s = Debug.scope("LifetimeAnalysis")) {
             numberInstructions();
@@ -1887,16 +1919,7 @@
             throw Debug.handle(e);
         }
 
-        try (Scope s = Debug.scope("ControlFlowOptimizations")) {
-            printLir("After register number assignment", true);
-            EdgeMoveOptimizer.optimize(ir);
-            ControlFlowOptimizer.optimize(ir);
-            RedundantMoveElimination.optimize(ir, frameMap, gen.getGraph().method());
-            NullCheckOptimizer.optimize(ir, target.implicitNullCheckLimit);
-            printLir("After control flow optimization", false);
-        } catch (Throwable e) {
-            throw Debug.handle(e);
-        }
+        printLir("After register number assignment", true);
 
         indent.outdent();
     }
@@ -2102,4 +2125,38 @@
             }
         }
     }
+
+    /**
+     * Returns a value for a interval definition, which can be used for re-materialization.
+     * 
+     * @param op An instruction which defines a value
+     * @param operand The destination operand of the instruction
+     * @param interval The interval for this defined value.
+     * @return Returns the value which is moved to the instruction and which can be reused at all
+     *         reload-locations in case the interval of this instruction is spilled. Currently this
+     *         can only be a {@link Constant}.
+     */
+    public static Constant getMaterializedValue(LIRInstruction op, Value operand, Interval interval) {
+        if (op instanceof MoveOp) {
+            MoveOp move = (MoveOp) op;
+            if (move.getInput() instanceof Constant) {
+                /*
+                 * Check if the interval has any uses which would accept an stack location (priority
+                 * == ShouldHaveRegister). Rematerialization of such intervals can result in a
+                 * degradation, because rematerialization always inserts a constant load, even if
+                 * the value is not needed in a register.
+                 */
+                Interval.UsePosList usePosList = interval.usePosList();
+                int numUsePos = usePosList.size();
+                for (int useIdx = 0; useIdx < numUsePos; useIdx++) {
+                    Interval.RegisterPriority priority = usePosList.registerPriority(useIdx);
+                    if (priority == Interval.RegisterPriority.ShouldHaveRegister) {
+                        return null;
+                    }
+                }
+                return (Constant) move.getInput();
+            }
+        }
+        return null;
+    }
 }
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/MoveResolver.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/MoveResolver.java	Wed Mar 05 19:40:15 2014 -0800
@@ -202,7 +202,7 @@
         AllocatableValue fromOpr = fromInterval.operand;
         AllocatableValue toOpr = toInterval.operand;
 
-        insertionBuffer.append(insertIdx, allocator.ir.spillMoveFactory.createMove(toOpr, fromOpr));
+        insertionBuffer.append(insertIdx, allocator.frameMap.createSpillMove(toOpr, fromOpr));
 
         Debug.log("insert move from %s to %s at %d", fromInterval, toInterval, insertIdx);
     }
@@ -212,7 +212,7 @@
         assert insertIdx != -1 : "must setup insert position first";
 
         AllocatableValue toOpr = toInterval.operand;
-        insertionBuffer.append(insertIdx, allocator.ir.spillMoveFactory.createMove(toOpr, fromOpr));
+        insertionBuffer.append(insertIdx, allocator.frameMap.createSpillMove(toOpr, fromOpr));
 
         Debug.log("insert move from value %s to %s at %d", fromOpr, toInterval, insertIdx);
     }
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/DebugInfoBuilder.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/DebugInfoBuilder.java	Wed Mar 05 19:40:15 2014 -0800
@@ -165,6 +165,11 @@
         return toValue(state.lockAt(i));
     }
 
+    private static final DebugMetric STATE_VIRTUAL_OBJECTS = Debug.metric("StateVirtualObjects");
+    private static final DebugMetric STATE_ILLEGALS = Debug.metric("StateIllegals");
+    private static final DebugMetric STATE_VARIABLES = Debug.metric("StateVariables");
+    private static final DebugMetric STATE_CONSTANTS = Debug.metric("StateConstants");
+
     protected Value toValue(ValueNode value) {
         if (value instanceof VirtualObjectNode) {
             VirtualObjectNode obj = (VirtualObjectNode) value;
@@ -182,22 +187,22 @@
                     vobject = VirtualObject.get(obj.type(), null, virtualObjects.size());
                     virtualObjects.put(obj, vobject);
                 }
-                Debug.metric("StateVirtualObjects").increment();
+                STATE_VIRTUAL_OBJECTS.increment();
                 return vobject;
             }
         } else if (value instanceof ConstantNode) {
-            Debug.metric("StateConstants").increment();
+            STATE_CONSTANTS.increment();
             return ((ConstantNode) value).getValue();
 
         } else if (value != null) {
-            Debug.metric("StateVariables").increment();
+            STATE_VARIABLES.increment();
             Value operand = nodeOperands.get(value);
             assert operand != null && (operand instanceof Variable || operand instanceof Constant) : operand + " for " + value;
             return operand;
 
         } else {
             // return a dummy value because real value not needed
-            Debug.metric("StateIllegals").increment();
+            STATE_ILLEGALS.increment();
             return Value.ILLEGAL;
         }
     }
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java	Wed Mar 05 19:40:15 2014 -0800
@@ -22,7 +22,6 @@
  */
 package com.oracle.graal.compiler.gen;
 
-import static com.oracle.graal.api.code.CallingConvention.Type.*;
 import static com.oracle.graal.api.code.ValueUtil.*;
 import static com.oracle.graal.api.meta.Value.*;
 import static com.oracle.graal.lir.LIR.*;
@@ -36,12 +35,14 @@
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.*;
-import com.oracle.graal.compiler.alloc.*;
 import com.oracle.graal.compiler.target.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.lir.*;
-import com.oracle.graal.lir.StandardOp.*;
+import com.oracle.graal.lir.StandardOp.BlockEndOp;
+import com.oracle.graal.lir.StandardOp.JumpOp;
+import com.oracle.graal.lir.StandardOp.LabelOp;
+import com.oracle.graal.lir.StandardOp.NoOp;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.PhiNode.PhiType;
 import com.oracle.graal.nodes.calc.*;
@@ -56,7 +57,7 @@
 /**
  * This class traverses the HIR instructions and generates LIR instructions from them.
  */
-public abstract class LIRGenerator implements LIRGeneratorTool {
+public abstract class LIRGenerator implements LIRGeneratorTool, LIRTypeTool {
 
     public static class Options {
         // @formatter:off
@@ -174,13 +175,7 @@
         this.graph = graph;
         this.providers = providers;
         this.frameMap = frameMap;
-        if (graph.getEntryBCI() == StructuredGraph.INVOCATION_ENTRY_BCI) {
-            this.cc = cc;
-        } else {
-            JavaType[] parameterTypes = new JavaType[]{getMetaAccess().lookupJavaType(long.class)};
-            CallingConvention tmp = frameMap.registerConfig.getCallingConvention(JavaCallee, getMetaAccess().lookupJavaType(void.class), parameterTypes, target(), false);
-            this.cc = new CallingConvention(cc.getStackSize(), cc.getReturn(), tmp.getArgument(0));
-        }
+        this.cc = cc;
         this.nodeOperands = graph.createNodeMap();
         this.lir = lir;
         this.debugInfoBuilder = createDebugInfoBuilder(nodeOperands);
@@ -189,37 +184,11 @@
     }
 
     /**
-     * Returns a value for a interval definition, which can be used for re-materialization.
-     * 
-     * @param op An instruction which defines a value
-     * @param operand The destination operand of the instruction
-     * @param interval The interval for this defined value.
-     * @return Returns the value which is moved to the instruction and which can be reused at all
-     *         reload-locations in case the interval of this instruction is spilled. Currently this
-     *         can only be a {@link Constant}.
+     * Returns true if the redundant move elimination optimization should be done after register
+     * allocation.
      */
-    public Constant getMaterializedValue(LIRInstruction op, Value operand, Interval interval) {
-        if (op instanceof MoveOp) {
-            MoveOp move = (MoveOp) op;
-            if (move.getInput() instanceof Constant) {
-                /*
-                 * Check if the interval has any uses which would accept an stack location (priority
-                 * == ShouldHaveRegister). Rematerialization of such intervals can result in a
-                 * degradation, because rematerialization always inserts a constant load, even if
-                 * the value is not needed in a register.
-                 */
-                Interval.UsePosList usePosList = interval.usePosList();
-                int numUsePos = usePosList.size();
-                for (int useIdx = 0; useIdx < numUsePos; useIdx++) {
-                    Interval.RegisterPriority priority = usePosList.registerPriority(useIdx);
-                    if (priority == Interval.RegisterPriority.ShouldHaveRegister) {
-                        return null;
-                    }
-                }
-                return (Constant) move.getInput();
-            }
-        }
-        return null;
+    public boolean canEliminateRedundantMoves() {
+        return true;
     }
 
     @SuppressWarnings("hiding")
@@ -333,13 +302,7 @@
      */
     @Override
     public Variable newVariable(PlatformKind platformKind) {
-        PlatformKind stackKind;
-        if (platformKind instanceof Kind) {
-            stackKind = ((Kind) platformKind).getStackKind();
-        } else {
-            stackKind = platformKind;
-        }
-        return new Variable(stackKind, lir.nextVariable());
+        return new Variable(platformKind, lir.nextVariable());
     }
 
     @Override
@@ -655,37 +618,33 @@
 
     @Override
     public void emitIf(IfNode x) {
-        emitBranch(x.condition(), getLIRBlock(x.trueSuccessor()), getLIRBlock(x.falseSuccessor()));
+        emitBranch(x.condition(), getLIRBlock(x.trueSuccessor()), getLIRBlock(x.falseSuccessor()), x.probability(x.trueSuccessor()));
     }
 
-    public void emitBranch(LogicNode node, LabelRef trueSuccessor, LabelRef falseSuccessor) {
+    public void emitBranch(LogicNode node, LabelRef trueSuccessor, LabelRef falseSuccessor, double trueSuccessorProbability) {
         if (node instanceof IsNullNode) {
-            emitNullCheckBranch((IsNullNode) node, trueSuccessor, falseSuccessor);
+            emitNullCheckBranch((IsNullNode) node, trueSuccessor, falseSuccessor, trueSuccessorProbability);
         } else if (node instanceof CompareNode) {
-            emitCompareBranch((CompareNode) node, trueSuccessor, falseSuccessor);
+            emitCompareBranch((CompareNode) node, trueSuccessor, falseSuccessor, trueSuccessorProbability);
         } else if (node instanceof LogicConstantNode) {
             emitConstantBranch(((LogicConstantNode) node).getValue(), trueSuccessor, falseSuccessor);
         } else if (node instanceof IntegerTestNode) {
-            emitIntegerTestBranch((IntegerTestNode) node, trueSuccessor, falseSuccessor);
+            emitIntegerTestBranch((IntegerTestNode) node, trueSuccessor, falseSuccessor, trueSuccessorProbability);
         } else {
             throw GraalInternalError.unimplemented(node.toString());
         }
     }
 
-    private void emitNullCheckBranch(IsNullNode node, LabelRef trueSuccessor, LabelRef falseSuccessor) {
-        emitCompareBranch(operand(node.object()), Constant.NULL_OBJECT, Condition.EQ, false, trueSuccessor, falseSuccessor);
+    private void emitNullCheckBranch(IsNullNode node, LabelRef trueSuccessor, LabelRef falseSuccessor, double trueSuccessorProbability) {
+        emitCompareBranch(operand(node.object()), Constant.NULL_OBJECT, Condition.EQ, false, trueSuccessor, falseSuccessor, trueSuccessorProbability);
     }
 
-    public void emitCompareBranch(CompareNode compare, LabelRef trueSuccessor, LabelRef falseSuccessor) {
-        emitCompareBranch(operand(compare.x()), operand(compare.y()), compare.condition(), compare.unorderedIsTrue(), trueSuccessor, falseSuccessor);
+    public void emitCompareBranch(CompareNode compare, LabelRef trueSuccessor, LabelRef falseSuccessor, double trueSuccessorProbability) {
+        emitCompareBranch(operand(compare.x()), operand(compare.y()), compare.condition(), compare.unorderedIsTrue(), trueSuccessor, falseSuccessor, trueSuccessorProbability);
     }
 
-    public void emitOverflowCheckBranch(LabelRef noOverflowBlock, LabelRef overflowBlock) {
-        emitOverflowCheckBranch(overflowBlock, noOverflowBlock, false);
-    }
-
-    public void emitIntegerTestBranch(IntegerTestNode test, LabelRef trueSuccessor, LabelRef falseSuccessor) {
-        emitIntegerTestBranch(operand(test.x()), operand(test.y()), false, trueSuccessor, falseSuccessor);
+    public void emitIntegerTestBranch(IntegerTestNode test, LabelRef trueSuccessor, LabelRef falseSuccessor, double trueSuccessorProbability) {
+        emitIntegerTestBranch(operand(test.x()), operand(test.y()), trueSuccessor, falseSuccessor, trueSuccessorProbability);
     }
 
     public void emitConstantBranch(boolean value, LabelRef trueSuccessorBlock, LabelRef falseSuccessorBlock) {
@@ -719,11 +678,11 @@
 
     public abstract void emitJump(LabelRef label);
 
-    public abstract void emitCompareBranch(Value left, Value right, Condition cond, boolean unorderedIsTrue, LabelRef trueDestination, LabelRef falseDestination);
+    public abstract void emitCompareBranch(Value left, Value right, Condition cond, boolean unorderedIsTrue, LabelRef trueDestination, LabelRef falseDestination, double trueDestinationProbability);
 
-    public abstract void emitOverflowCheckBranch(LabelRef overflow, LabelRef noOverflow, boolean negated);
+    public abstract void emitOverflowCheckBranch(LabelRef overflow, LabelRef noOverflow, double overflowProbability);
 
-    public abstract void emitIntegerTestBranch(Value left, Value right, boolean negated, LabelRef trueDestination, LabelRef falseDestination);
+    public abstract void emitIntegerTestBranch(Value left, Value right, LabelRef trueDestination, LabelRef falseDestination, double trueSuccessorProbability);
 
     public abstract Variable emitConditionalMove(Value leftVal, Value right, Condition cond, boolean unorderedIsTrue, Value trueValue, Value falseValue);
 
@@ -851,7 +810,8 @@
             Variable value = load(operand(x.value()));
             if (keyCount == 1) {
                 assert defaultTarget != null;
-                emitCompareBranch(load(operand(x.value())), x.keyAt(0), Condition.EQ, false, getLIRBlock(x.keySuccessor(0)), defaultTarget);
+                double probability = x.probability(x.keySuccessor(0));
+                emitCompareBranch(load(operand(x.value())), x.keyAt(0), Condition.EQ, false, getLIRBlock(x.keySuccessor(0)), defaultTarget, probability);
             } else {
                 LabelRef[] keyTargets = new LabelRef[keyCount];
                 Constant[] keyConstants = new Constant[keyCount];
@@ -1016,6 +976,36 @@
         }
     }
 
+    /**
+     * 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 > 32) {
+            return Kind.Long;
+        } else {
+            return Kind.Int;
+        }
+    }
+
+    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);
@@ -1024,5 +1014,5 @@
 
     public abstract void emitByteSwap(Variable result, Value operand);
 
-    public abstract void emitCharArrayEquals(Variable result, Value array1, Value array2, Value length);
+    public abstract void emitArrayEquals(Kind kind, Variable result, Value array1, Value array2, Value length);
 }
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/Backend.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/Backend.java	Wed Mar 05 19:40:15 2014 -0800
@@ -70,7 +70,7 @@
     /**
      * Creates the assembler used to emit the machine code.
      */
-    protected abstract AbstractAssembler createAssembler(FrameMap frameMap);
+    protected abstract Assembler createAssembler(FrameMap frameMap);
 
     /**
      * Creates the object used to fill in the details of a given compilation result.
@@ -86,5 +86,5 @@
      *            {@linkplain InstalledCode#getMethod() associated} with once installed. This
      *            argument can be null.
      */
-    public abstract void emitCode(CompilationResultBuilder crb, LIRGenerator lirGen, ResolvedJavaMethod installedCodeOwner);
+    public abstract void emitCode(CompilationResultBuilder crb, LIR lir, ResolvedJavaMethod installedCodeOwner);
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/HostBackend.java	Wed Mar 05 19:40:15 2014 -0800
@@ -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.compiler.target;
+
+import com.oracle.graal.api.code.*;
+
+/**
+ * Common functionality of host backends.
+ */
+public interface HostBackend {
+    NativeFunctionInterface getNativeFunctionInterface();
+}
--- a/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/DebugScope.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/DebugScope.java	Wed Mar 05 19:40:15 2014 -0800
@@ -87,10 +87,10 @@
         }
     }
 
-    private static ThreadLocal<DebugScope> instanceTL = new ThreadLocal<>();
-    private static ThreadLocal<DebugScope> lastClosedTL = new ThreadLocal<>();
-    private static ThreadLocal<DebugConfig> configTL = new ThreadLocal<>();
-    private static ThreadLocal<Throwable> lastExceptionThrownTL = new ThreadLocal<>();
+    private static final ThreadLocal<DebugScope> instanceTL = new ThreadLocal<>();
+    private static final ThreadLocal<DebugScope> lastClosedTL = new ThreadLocal<>();
+    private static final ThreadLocal<DebugConfig> configTL = new ThreadLocal<>();
+    private static final ThreadLocal<Throwable> lastExceptionThrownTL = new ThreadLocal<>();
 
     private final DebugScope parent;
     private final DebugConfig parentConfig;
--- a/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/TimerImpl.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/TimerImpl.java	Wed Mar 05 19:40:15 2014 -0800
@@ -41,7 +41,7 @@
     /**
      * Records the most recent active timer.
      */
-    private static ThreadLocal<AbstractTimer> currentTimer = new ThreadLocal<>();
+    private static final ThreadLocal<AbstractTimer> currentTimer = new ThreadLocal<>();
 
     private final DebugValue flat;
 
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Graph.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Graph.java	Wed Mar 05 19:40:15 2014 -0800
@@ -75,6 +75,12 @@
     NodeChangedListener usagesDroppedToZeroListener;
     private final HashMap<CacheEntry, Node> cachedNodes = new HashMap<>();
 
+    /*
+     * Indicates that the graph should no longer be modified. Frozen graphs can be used my multiple
+     * threads so it's only safe to read them.
+     */
+    private boolean isFrozen = false;
+
     private static final class CacheEntry {
 
         private final Node node;
@@ -761,6 +767,7 @@
     }
 
     void register(Node node) {
+        assert !isFrozen();
         assert node.id() == Node.INITIAL_ID;
         if (nodes.length == nodesSize) {
             nodes = Arrays.copyOf(nodes, (nodesSize * 2) + 1);
@@ -812,6 +819,7 @@
     }
 
     void unregister(Node node) {
+        assert !isFrozen();
         assert !node.isDeleted() : "cannot delete a node twice! node=" + node;
         logNodeDeleted(node);
         nodes[node.id] = null;
@@ -896,4 +904,12 @@
     public Map<Node, Node> addDuplicates(Iterable<Node> newNodes, final Graph oldGraph, int estimatedNodeCount, DuplicationReplacement replacements) {
         return NodeClass.addGraphDuplicate(this, oldGraph, estimatedNodeCount, newNodes, replacements);
     }
+
+    public boolean isFrozen() {
+        return isFrozen;
+    }
+
+    public void freeze() {
+        this.isFrozen = true;
+    }
 }
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Node.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Node.java	Wed Mar 05 19:40:15 2014 -0800
@@ -467,17 +467,11 @@
             }
             if (newInput != null) {
                 if (newInput.recordsUsages()) {
-                    NodeChangedListener listener = graph.inputChangedListener;
-                    if (listener != null) {
-                        listener.nodeChanged(this);
-                    }
+                    maybeNotifyChanged(this);
                     newInput.addUsage(this);
                 }
             } else if (oldInput != null && oldInput.recordsUsages() && oldInput.usages().isEmpty()) {
-                NodeChangedListener listener = graph.usagesDroppedToZeroListener;
-                if (listener != null) {
-                    listener.nodeChanged(oldInput);
-                }
+                maybeNotifyZeroInputs(oldInput);
             }
         }
     }
@@ -488,6 +482,7 @@
      * this node to newSuccessor's predecessors.
      */
     protected void updatePredecessor(Node oldSuccessor, Node newSuccessor) {
+        assert graph == null || !graph.isFrozen();
         if (oldSuccessor != newSuccessor) {
             if (oldSuccessor != null) {
                 assert assertTrue(oldSuccessor.predecessor == this, "wrong predecessor in old successor (%s): %s", oldSuccessor, oldSuccessor.predecessor);
@@ -517,6 +512,7 @@
     }
 
     private boolean checkReplaceWith(Node other) {
+        assert assertTrue(graph == null || !graph.isFrozen(), "cannot modify frozen graph");
         assert assertFalse(other == this, "cannot replace a node with itself");
         assert assertFalse(isDeleted(), "cannot replace deleted node");
         assert assertTrue(other == null || !other.isDeleted(), "cannot replace with deleted node %s", other);
@@ -529,10 +525,7 @@
             boolean result = usage.getNodeClass().replaceFirstInput(usage, this, other);
             assert assertTrue(result, "not found in inputs, usage: %s", usage);
             if (other != null) {
-                NodeChangedListener listener = graph.inputChangedListener;
-                if (listener != null) {
-                    listener.nodeChanged(usage);
-                }
+                maybeNotifyChanged(usage);
                 if (other.recordsUsages()) {
                     other.addUsage(usage);
                 }
@@ -541,6 +534,22 @@
         clearUsages();
     }
 
+    private void maybeNotifyChanged(Node usage) {
+        assert graph == null || !graph.isFrozen();
+        NodeChangedListener listener = graph.inputChangedListener;
+        if (listener != null) {
+            listener.nodeChanged(usage);
+        }
+    }
+
+    private void maybeNotifyZeroInputs(Node oldInput) {
+        assert graph == null || !graph.isFrozen();
+        NodeChangedListener listener = graph.usagesDroppedToZeroListener;
+        if (listener != null) {
+            listener.nodeChanged(oldInput);
+        }
+    }
+
     public void replaceAtPredecessor(Node other) {
         assert checkReplaceWith(other);
         if (predecessor != null) {
@@ -579,10 +588,7 @@
             if (input.recordsUsages()) {
                 removeThisFromUsages(input);
                 if (input.usages().isEmpty()) {
-                    NodeChangedListener listener = graph.usagesDroppedToZeroListener;
-                    if (listener != null) {
-                        listener.nodeChanged(input);
-                    }
+                    maybeNotifyZeroInputs(input);
                 }
             }
         }
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeMap.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeMap.java	Wed Mar 05 19:40:15 2014 -0800
@@ -101,7 +101,7 @@
         if (autogrow && isNew(node)) {
             grow();
         }
-        assert node.graph() == graph : "this node is not part of the graph";
+        assert node.graph() == graph : String.format("%s is not part of the graph", node);
         assert !isNew(node) : "this node was added to the graph after creating the node map : " + node;
     }
 
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/UnsafeAccess.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/UnsafeAccess.java	Wed Mar 05 19:40:15 2014 -0800
@@ -49,4 +49,54 @@
             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;
+    }
 }
--- a/graal/com.oracle.graal.hotspot.amd64.test/src/com/oracle/graal/hotspot/amd64/test/AMD64HotSpotFrameOmissionTest.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.hotspot.amd64.test/src/com/oracle/graal/hotspot/amd64/test/AMD64HotSpotFrameOmissionTest.java	Wed Mar 05 19:40:15 2014 -0800
@@ -48,6 +48,7 @@
         return;
     }
 
+    @Ignore
     @Test
     public void test1() {
         testHelper("test1snippet", new CodeGenerator() {
@@ -64,6 +65,7 @@
         return x + 5;
     }
 
+    @Ignore
     @Test
     public void test2() {
         testHelper("test2snippet", new CodeGenerator() {
@@ -83,6 +85,7 @@
         return 1 + x;
     }
 
+    @Ignore
     @Test
     public void test3() {
         testHelper("test3snippet", new CodeGenerator() {
@@ -108,7 +111,7 @@
         AMD64Assembler asm = new AMD64Assembler(target, registerConfig);
 
         gen.generateCode(asm);
-        byte[] expectedCode = asm.codeBuffer.close(true);
+        byte[] expectedCode = asm.close(true);
 
         // Only compare up to expectedCode.length bytes to ignore
         // padding instructions adding during code installation
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java	Wed Mar 05 19:40:15 2014 -0800
@@ -43,6 +43,7 @@
 import com.oracle.graal.hotspot.*;
 import com.oracle.graal.hotspot.bridge.*;
 import com.oracle.graal.hotspot.meta.*;
+import com.oracle.graal.hotspot.nfi.*;
 import com.oracle.graal.hotspot.stubs.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.amd64.*;
@@ -97,9 +98,9 @@
                         disp -= frameSize;
                     }
                     crb.blockComment("[stack overflow check]");
-                    int pos = asm.codeBuffer.position();
+                    int pos = asm.position();
                     asm.movq(new AMD64Address(rsp, -disp), AMD64.rax);
-                    assert i > 0 || !isVerifiedEntryPoint || asm.codeBuffer.position() - pos >= PATCHED_VERIFIED_ENTRY_POINT_INSTRUCTION_SIZE;
+                    assert i > 0 || !isVerifiedEntryPoint || asm.position() - pos >= PATCHED_VERIFIED_ENTRY_POINT_INSTRUCTION_SIZE;
                 }
             }
         }
@@ -140,14 +141,14 @@
                     asm.nop(PATCHED_VERIFIED_ENTRY_POINT_INSTRUCTION_SIZE);
                 }
             } else {
-                int verifiedEntryPointOffset = asm.codeBuffer.position();
+                int verifiedEntryPointOffset = asm.position();
                 if (!isStub && pagesToBang > 0) {
                     emitStackOverflowCheck(crb, pagesToBang, false, true);
-                    assert asm.codeBuffer.position() - verifiedEntryPointOffset >= PATCHED_VERIFIED_ENTRY_POINT_INSTRUCTION_SIZE;
+                    assert asm.position() - verifiedEntryPointOffset >= PATCHED_VERIFIED_ENTRY_POINT_INSTRUCTION_SIZE;
                 }
-                if (!isStub && asm.codeBuffer.position() == verifiedEntryPointOffset) {
+                if (!isStub && asm.position() == verifiedEntryPointOffset) {
                     asm.subqWide(rsp, frameSize);
-                    assert asm.codeBuffer.position() - verifiedEntryPointOffset >= PATCHED_VERIFIED_ENTRY_POINT_INSTRUCTION_SIZE;
+                    assert asm.position() - verifiedEntryPointOffset >= PATCHED_VERIFIED_ENTRY_POINT_INSTRUCTION_SIZE;
                 } else {
                     asm.decrementq(rsp, frameSize);
                 }
@@ -173,7 +174,7 @@
                 CalleeSaveLayout csl = crb.frameMap.registerConfig.getCalleeSaveLayout();
 
                 if (csl != null && csl.size != 0) {
-                    crb.compilationResult.setRegisterRestoreEpilogueOffset(asm.codeBuffer.position());
+                    crb.compilationResult.setRegisterRestoreEpilogueOffset(asm.position());
                     // saved all registers, restore all registers
                     int frameToCSA = crb.frameMap.offsetToCalleeSaveArea();
                     asm.restore(csl, frameToCSA);
@@ -186,7 +187,7 @@
     }
 
     @Override
-    protected AbstractAssembler createAssembler(FrameMap frameMap) {
+    protected Assembler createAssembler(FrameMap frameMap) {
         return new AMD64MacroAssembler(getTarget(), frameMap.registerConfig);
     }
 
@@ -205,7 +206,7 @@
         boolean omitFrame = CanOmitFrame.getValue() && !frameMap.frameNeedsAllocating() && !lir.hasArgInCallerFrame() && !gen.hasForeignCall();
 
         Stub stub = gen.getStub();
-        AbstractAssembler masm = createAssembler(frameMap);
+        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());
@@ -223,7 +224,7 @@
     }
 
     @Override
-    public void emitCode(CompilationResultBuilder crb, LIRGenerator lirGen, ResolvedJavaMethod installedCodeOwner) {
+    public void emitCode(CompilationResultBuilder crb, LIR lir, ResolvedJavaMethod installedCodeOwner) {
         AMD64MacroAssembler asm = (AMD64MacroAssembler) crb.asm;
         FrameMap frameMap = crb.frameMap;
         RegisterConfig regConfig = frameMap.registerConfig;
@@ -234,10 +235,10 @@
         emitCodePrefix(installedCodeOwner, crb, asm, regConfig, config, verifiedEntry);
 
         // Emit code for the LIR
-        emitCodeBody(installedCodeOwner, crb, lirGen);
+        emitCodeBody(installedCodeOwner, crb, lir);
 
         // Emit the suffix
-        emitCodeSuffix(installedCodeOwner, crb, lirGen, asm, frameMap);
+        emitCodeSuffix(installedCodeOwner, crb, asm, frameMap);
     }
 
     /**
@@ -280,14 +281,14 @@
      * 
      * @param installedCodeOwner see {@link Backend#emitCode}
      */
-    public void emitCodeBody(ResolvedJavaMethod installedCodeOwner, CompilationResultBuilder crb, LIRGenerator lirGen) {
-        crb.emit(lirGen.lir);
+    public void emitCodeBody(ResolvedJavaMethod installedCodeOwner, CompilationResultBuilder crb, LIR lir) {
+        crb.emit(lir);
     }
 
     /**
      * @param installedCodeOwner see {@link Backend#emitCode}
      */
-    public void emitCodeSuffix(ResolvedJavaMethod installedCodeOwner, CompilationResultBuilder crb, LIRGenerator lirGen, AMD64MacroAssembler asm, FrameMap frameMap) {
+    public void emitCodeSuffix(ResolvedJavaMethod installedCodeOwner, CompilationResultBuilder crb, AMD64MacroAssembler asm, FrameMap frameMap) {
         HotSpotProviders providers = getProviders();
         HotSpotFrameContext frameContext = (HotSpotFrameContext) crb.frameContext;
         if (!frameContext.isStub) {
@@ -299,7 +300,22 @@
         } else {
             // No need to emit the stubs for entries back into the method since
             // it has no calls that can cause such "return" entries
-            assert !frameMap.accessesCallerFrame() : lirGen.getGraph();
+
+            if (frameContext.omitFrame) {
+                // Cannot access slots in caller's frame if my frame is omitted
+                assert !frameMap.accessesCallerFrame();
+            }
         }
     }
+
+    @Override
+    public NativeFunctionInterface getNativeFunctionInterface() {
+        HotSpotVMConfig config = getRuntime().getConfig();
+        RawNativeCallNodeFactory factory = new RawNativeCallNodeFactory() {
+            public FixedWithNextNode createRawCallNode(Kind returnType, Constant functionPointer, ValueNode... args) {
+                return new AMD64RawNativeCallNode(returnType, functionPointer, args);
+            }
+        };
+        return new HotSpotNativeFunctionInterface(getProviders(), factory, this, config.dllLoad, config.dllLookup, config.rtldDefault);
+    }
 }
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotForeignCallsProvider.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotForeignCallsProvider.java	Wed Mar 05 19:40:15 2014 -0800
@@ -67,8 +67,8 @@
         // replace a non-existing method anyway.
         try {
             // These stubs do callee saving
-            registerForeignCall(ENCRYPT_BLOCK, config.aescryptEncryptBlockStub, NativeCall, PRESERVES_REGISTERS, LEAF_NOFP, NOT_REEXECUTABLE, ANY_LOCATION);
-            registerForeignCall(DECRYPT_BLOCK, config.aescryptDecryptBlockStub, NativeCall, PRESERVES_REGISTERS, LEAF_NOFP, NOT_REEXECUTABLE, ANY_LOCATION);
+            registerForeignCall(ENCRYPT_BLOCK, config.aescryptEncryptBlockStub, NativeCall, PRESERVES_REGISTERS, LEAF_NOFP, NOT_REEXECUTABLE, NamedLocationIdentity.getArrayLocation(Kind.Byte));
+            registerForeignCall(DECRYPT_BLOCK, config.aescryptDecryptBlockStub, NativeCall, PRESERVES_REGISTERS, LEAF_NOFP, NOT_REEXECUTABLE, NamedLocationIdentity.getArrayLocation(Kind.Byte));
         } catch (GraalInternalError e) {
             if (!(e.getCause() instanceof ClassNotFoundException)) {
                 throw e;
@@ -76,8 +76,8 @@
         }
         try {
             // These stubs do callee saving
-            registerForeignCall(ENCRYPT, config.cipherBlockChainingEncryptAESCryptStub, NativeCall, PRESERVES_REGISTERS, LEAF_NOFP, NOT_REEXECUTABLE, ANY_LOCATION);
-            registerForeignCall(DECRYPT, config.cipherBlockChainingDecryptAESCryptStub, NativeCall, PRESERVES_REGISTERS, LEAF_NOFP, NOT_REEXECUTABLE, ANY_LOCATION);
+            registerForeignCall(ENCRYPT, config.cipherBlockChainingEncryptAESCryptStub, NativeCall, PRESERVES_REGISTERS, LEAF_NOFP, NOT_REEXECUTABLE, NamedLocationIdentity.getArrayLocation(Kind.Byte));
+            registerForeignCall(DECRYPT, config.cipherBlockChainingDecryptAESCryptStub, NativeCall, PRESERVES_REGISTERS, LEAF_NOFP, NOT_REEXECUTABLE, NamedLocationIdentity.getArrayLocation(Kind.Byte));
         } catch (GraalInternalError e) {
             if (!(e.getCause() instanceof ClassNotFoundException)) {
                 throw e;
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java	Wed Mar 05 19:40:15 2014 -0800
@@ -158,7 +158,6 @@
 
         CallingConvention incomingArguments = cc;
 
-        RegisterValue rbpParam = rbp.asValue(Kind.Long);
         Value[] params = new Value[incomingArguments.getArgumentCount() + 1];
         for (int i = 0; i < params.length - 1; i++) {
             params[i] = toStackKind(incomingArguments.getArgument(i));
@@ -169,7 +168,7 @@
                 }
             }
         }
-        params[params.length - 1] = rbpParam;
+        params[params.length - 1] = rbp.asValue(Kind.Long);
 
         emitIncomingValues(params);
 
@@ -350,6 +349,24 @@
     }
 
     @Override
+    public void emitCCall(long address, CallingConvention nativeCallingConvention, Value[] args, int numberOfFloatingPointArguments) {
+        Value[] argLocations = new Value[args.length];
+        frameMap.callsMethod(nativeCallingConvention);
+        // TODO(mg): in case a native function uses floating point varargs, the ABI requires that
+        // RAX contains the length of the varargs
+        AllocatableValue numberOfFloatingPointArgumentsRegister = AMD64.rax.asValue();
+        emitMove(numberOfFloatingPointArgumentsRegister, Constant.forInt(numberOfFloatingPointArguments));
+        for (int i = 0; i < args.length; i++) {
+            Value arg = args[i];
+            AllocatableValue loc = nativeCallingConvention.getArgument(i);
+            emitMove(loc, arg);
+            argLocations[i] = loc;
+        }
+        Value ptr = emitMove(Constant.forLong(address));
+        append(new AMD64CCall(nativeCallingConvention.getReturn(), ptr, numberOfFloatingPointArgumentsRegister, argLocations));
+    }
+
+    @Override
     protected void emitDirectCall(DirectCallTargetNode callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState callState) {
         InvokeKind invokeKind = ((HotSpotDirectCallTargetNode) callTarget).invokeKind();
         if (invokeKind == InvokeKind.Interface || invokeKind == InvokeKind.Virtual) {
@@ -467,7 +484,7 @@
     @Override
     public Variable emitLoad(Kind kind, Value address, Access access) {
         AMD64AddressValue loadAddress = asAddressValue(address);
-        Variable result = newVariable(kind);
+        Variable result = newVariable(kind.getStackKind());
         LIRFrameState state = null;
         if (access instanceof DeoptimizingNode) {
             state = state((DeoptimizingNode) access);
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLoweringProvider.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLoweringProvider.java	Wed Mar 05 19:40:15 2014 -0800
@@ -47,8 +47,8 @@
 
     @Override
     public void lower(Node n, LoweringTool tool) {
-        if (n instanceof ConvertNode) {
-            convertSnippets.lower((ConvertNode) n, tool);
+        if (n instanceof FloatConvertNode) {
+            convertSnippets.lower((FloatConvertNode) n, tool);
         } else {
             super.lower(n, tool);
         }
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotMove.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotMove.java	Wed Mar 05 19:40:15 2014 -0800
@@ -133,12 +133,12 @@
                     encodeKlassPointer(masm, asRegister(scratch), heapBaseReg, encoding);
                 }
                 if (state != null) {
-                    crb.recordImplicitException(masm.codeBuffer.position(), state);
+                    crb.recordImplicitException(masm.position(), state);
                 }
                 masm.movl(address.toAddress(), asRegister(scratch));
             }
             if (state != null) {
-                crb.recordImplicitException(masm.codeBuffer.position(), state);
+                crb.recordImplicitException(masm.position(), state);
             }
             masm.movl(address.toAddress(), asRegister(scratch));
         }
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRegisterConfig.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRegisterConfig.java	Wed Mar 05 19:40:15 2014 -0800
@@ -216,7 +216,7 @@
         }
 
         Kind returnKind = returnType == null ? Kind.Void : returnType.getKind();
-        AllocatableValue returnLocation = returnKind == Kind.Void ? Value.ILLEGAL : getReturnRegister(returnKind).asValue(returnKind);
+        AllocatableValue returnLocation = returnKind == Kind.Void ? Value.ILLEGAL : getReturnRegister(returnKind).asValue(returnKind.getStackKind());
         return new CallingConvention(currentStackOffset, returnLocation, locations);
     }
 
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotReturnOp.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotReturnOp.java	Wed Mar 05 19:40:15 2014 -0800
@@ -24,7 +24,6 @@
 
 import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
 import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
-import static com.oracle.graal.phases.GraalOptions.*;
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
@@ -51,7 +50,8 @@
     @Override
     public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
         leaveFrameAndRestoreRbp(crb, masm);
-        if (!isStub && (crb.frameContext.hasFrame() || !OptEliminateSafepoints.getValue())) {
+        if (!isStub) {
+            // Every non-stub compile method must have a poll before the return.
             AMD64HotSpotSafepointOp.emitCode(crb, masm, runtime().getConfig(), true, null, scratchForSafepointOnReturn);
         }
         masm.ret(0);
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotSafepointOp.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotSafepointOp.java	Wed Mar 05 19:40:15 2014 -0800
@@ -73,6 +73,7 @@
     }
 
     public static void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler asm, HotSpotVMConfig config, boolean atReturn, LIRFrameState state, Register scratch) {
+        assert !atReturn || state == null : "state is unneeded at return";
         if (ImmutableCode.getValue()) {
             Kind hostWordKind = HotSpotGraalRuntime.getHostWordKind();
             int alignment = hostWordKind.getBitCount() / Byte.SIZE;
@@ -80,7 +81,7 @@
             // 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));
-            final int pos = asm.codeBuffer.position();
+            final int pos = asm.position();
             crb.recordMark(atReturn ? MARK_POLL_RETURN_FAR : MARK_POLL_FAR);
             if (state != null) {
                 crb.recordInfopoint(pos, state, InfopointReason.SAFEPOINT);
@@ -89,14 +90,14 @@
         } else if (isPollingPageFar(config)) {
             asm.movq(scratch, config.safepointPollingAddress);
             crb.recordMark(atReturn ? MARK_POLL_RETURN_FAR : MARK_POLL_FAR);
-            final int pos = asm.codeBuffer.position();
+            final int pos = asm.position();
             if (state != null) {
                 crb.recordInfopoint(pos, state, InfopointReason.SAFEPOINT);
             }
             asm.testl(rax, new AMD64Address(scratch));
         } else {
             crb.recordMark(atReturn ? MARK_POLL_RETURN_NEAR : MARK_POLL_NEAR);
-            final int pos = asm.codeBuffer.position();
+            final int pos = asm.position();
             if (state != null) {
                 crb.recordInfopoint(pos, state, InfopointReason.SAFEPOINT);
             }
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64PrefetchOp.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64PrefetchOp.java	Wed Mar 05 19:40:15 2014 -0800
@@ -32,7 +32,7 @@
 
 public class AMD64PrefetchOp extends AMD64LIRInstruction {
 
-    private final int instr;  // AllocatePrefecthInstr
+    private final int instr;  // AllocatePrefetchInstr
     @Alive({COMPOSITE}) protected AMD64AddressValue address;
 
     public AMD64PrefetchOp(AMD64AddressValue address, int instr) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64RawNativeCallNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,76 @@
+/*
+ * 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 com.oracle.graal.api.code.*;
+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.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 {
+
+    private final Constant functionPointer;
+    @Input private final NodeInputList<ValueNode> args;
+
+    public AMD64RawNativeCallNode(Kind returnType, Constant functionPointer, ValueNode[] args) {
+        super(StampFactory.forKind(returnType));
+        this.functionPointer = functionPointer;
+        this.args = new NodeInputList<>(this, args);
+    }
+
+    @Override
+    public void generate(LIRGenerator generator) {
+        AMD64LIRGenerator gen = (AMD64LIRGenerator) generator;
+        Value[] parameter = new Value[args.count()];
+        JavaType[] parameterTypes = new JavaType[args.count()];
+        for (int i = 0; i < args.count(); i++) {
+            parameter[i] = generator.operand(args.get(i));
+            parameterTypes[i] = args.get(i).stamp().javaType(gen.getMetaAccess());
+        }
+        ResolvedJavaType returnType = stamp().javaType(gen.getMetaAccess());
+        CallingConvention cc = generator.getCodeCache().getRegisterConfig().getCallingConvention(Type.NativeCall, returnType, parameterTypes, generator.target(), false);
+        gen.emitCCall(functionPointer.asLong(), cc, parameter, countFloatingTypeArguments(args));
+        if (this.kind() != Kind.Void) {
+            generator.setResult(this, gen.emitMove(cc.getReturn()));
+        }
+    }
+
+    private static int countFloatingTypeArguments(NodeInputList<ValueNode> args) {
+        int count = 0;
+        for (ValueNode n : args) {
+            if (n.kind() == Kind.Double || n.kind() == Kind.Float) {
+                count++;
+            }
+        }
+        if (count > 8) {
+            return 8;
+        }
+        return count;
+    }
+
+}
--- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/ForEachToGraal.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/ForEachToGraal.java	Wed Mar 05 19:40:15 2014 -0800
@@ -23,10 +23,25 @@
 
 package com.oracle.graal.hotspot.hsail;
 
+import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
+
+import java.lang.reflect.*;
+
 import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.hsail.*;
+import com.oracle.graal.compiler.target.*;
 import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.internal.*;
+import com.oracle.graal.graph.iterators.*;
 import com.oracle.graal.hotspot.meta.*;
+import com.oracle.graal.hsail.*;
+import com.oracle.graal.java.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.java.*;
+import com.oracle.graal.phases.*;
+import com.oracle.graal.phases.util.*;
+import com.oracle.graal.printer.*;
 
 /**
  * Implements compile and dispatch of Java code containing lambda constructs. Currently only used by
@@ -34,18 +49,58 @@
  */
 public class ForEachToGraal implements CompileAndDispatch {
 
-    private static HSAILCompilationResult getCompiledLambda(Class consumerClass) {
-        return HSAILCompilationResult.getCompiledLambda(consumerClass);
+    private static HSAILHotSpotBackend getHSAILBackend() {
+        Backend backend = runtime().getBackend(HSAIL.class);
+        return (HSAILHotSpotBackend) backend;
     }
 
-    // Implementations of the CompileAndDispatch interface.
+    /**
+     * Gets a compiled and installed kernel for the lambda called by the {@code accept(int value)}
+     * method in a class implementing {@code java.util.function.IntConsumer}.
+     * 
+     * @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) {
+        Method acceptMethod = null;
+        for (Method m : intConsumerClass.getMethods()) {
+            if (m.getName().equals("accept")) {
+                assert acceptMethod == null : "found more than one implementation of accept(int) in " + intConsumerClass;
+                acceptMethod = m;
+            }
+        }
+
+        // Ensure a debug configuration for this thread is initialized
+        if (DebugScope.getConfig() == null) {
+            DebugEnvironment.initialize(System.out);
+        }
+
+        HSAILHotSpotBackend backend = getHSAILBackend();
+        Providers providers = backend.getProviders();
+        StructuredGraph graph = new StructuredGraph(((HotSpotMetaAccessProvider) providers.getMetaAccess()).lookupJavaMethod(acceptMethod));
+        new GraphBuilderPhase.Instance(providers.getMetaAccess(), GraphBuilderConfiguration.getDefault(), OptimisticOptimizations.ALL).apply(graph);
+        NodeIterable<MethodCallTargetNode> calls = graph.getNodes(MethodCallTargetNode.class);
+        assert calls.count() == 1;
+        ResolvedJavaMethod lambdaMethod = calls.first().targetMethod();
+        assert lambdaMethod.getName().startsWith("lambda$");
+        Debug.log("target ... " + lambdaMethod);
+
+        if (lambdaMethod == null) {
+            Debug.log("Did not find call in accept()");
+            return null;
+        }
+
+        ExternalCompilationResult hsailCode = backend.compileKernel(lambdaMethod, true);
+        return backend.installKernel(lambdaMethod, hsailCode);
+    }
+
     @Override
     public Object createKernel(Class<?> consumerClass) {
         try {
             return getCompiledLambda(consumerClass);
         } catch (Throwable e) {
-            // Note: Graal throws Errors. We want to revert to regular Java in these cases.
-            Debug.log("WARNING:Graal compilation failed.");
+            // If Graal compilation throws an exception, we want to revert to regular Java
+            Debug.log("WARNING: Graal compilation failed");
             e.printStackTrace();
             return null;
         }
@@ -53,16 +108,14 @@
 
     @Override
     public boolean dispatchKernel(Object kernel, int jobSize, Object[] args) {
-        // kernel is an HSAILCompilationResult
-        HotSpotNmethod code = (HotSpotNmethod) ((HSAILCompilationResult) kernel).getInstalledCode();
-
+        HotSpotNmethod code = (HotSpotNmethod) kernel;
         if (code != null) {
             try {
                 // No return value from HSAIL kernels
-                code.executeParallel(jobSize, 0, 0, args);
+                getHSAILBackend().executeKernel(code, jobSize, args);
                 return true;
             } catch (InvalidInstalledCodeException iice) {
-                Debug.log("WARNING:Invalid installed code at exec time." + iice);
+                Debug.log("WARNING: Invalid installed code at exec time." + iice);
                 iice.printStackTrace();
                 return false;
             }
--- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILCompilationResult.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,222 +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.hotspot.hsail;
-
-import static com.oracle.graal.compiler.GraalCompiler.*;
-import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
-
-import java.lang.reflect.*;
-
-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.debug.*;
-import com.oracle.graal.graph.*;
-import com.oracle.graal.graph.iterators.*;
-import com.oracle.graal.hotspot.*;
-import com.oracle.graal.hotspot.bridge.*;
-import com.oracle.graal.hotspot.meta.*;
-import com.oracle.graal.hsail.*;
-import com.oracle.graal.java.*;
-import com.oracle.graal.lir.asm.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.java.*;
-import com.oracle.graal.nodes.type.*;
-import com.oracle.graal.phases.*;
-import com.oracle.graal.phases.tiers.*;
-import com.oracle.graal.phases.util.*;
-import com.oracle.graal.runtime.*;
-
-/**
- * Class that represents a HSAIL compilation result. Includes the compiled HSAIL code.
- */
-public class HSAILCompilationResult extends ExternalCompilationResult {
-
-    private static final long serialVersionUID = -4178700465275724625L;
-
-    private static CompilerToGPU toGPU = HotSpotGraalRuntime.runtime().getCompilerToGPU();
-    private static boolean validDevice = toGPU.deviceInit();
-
-    // The installedCode is the executable representation of the kernel in the code cache
-    private InstalledCode installedCode;
-
-    public void setInstalledCode(InstalledCode newCode) {
-        installedCode = newCode;
-    }
-
-    public InstalledCode getInstalledCode() {
-        return installedCode;
-    }
-
-    static final HSAILHotSpotBackend backend;
-    static {
-        // Look for installed HSAIL backend
-        RuntimeProvider runtime = Graal.getRequiredCapability(RuntimeProvider.class);
-        HSAILHotSpotBackend b = (HSAILHotSpotBackend) runtime.getBackend(HSAIL.class);
-        if (b == null) {
-            // Fall back to a new instance
-            b = new HSAILHotSpotBackendFactory().createBackend(runtime(), runtime().getHostBackend());
-            b.completeInitialization();
-        }
-        backend = b;
-    }
-
-    public static HSAILCompilationResult getHSAILCompilationResult(Method meth) {
-        HotSpotMetaAccessProvider metaAccess = backend.getProviders().getMetaAccess();
-        ResolvedJavaMethod javaMethod = metaAccess.lookupJavaMethod(meth);
-        return getHSAILCompilationResult(javaMethod);
-    }
-
-    public static HSAILCompilationResult getHSAILCompilationResult(ResolvedJavaMethod javaMethod) {
-        HotSpotMetaAccessProvider metaAccess = backend.getProviders().getMetaAccess();
-        StructuredGraph graph = new StructuredGraph(javaMethod);
-        new GraphBuilderPhase.Instance(metaAccess, GraphBuilderConfiguration.getEagerDefault(), OptimisticOptimizations.ALL).apply(graph);
-        return getHSAILCompilationResult(graph);
-    }
-
-    /**
-     * HSAIL doesn't have a calling convention as such. Function arguments are actually passed in
-     * memory but then loaded into registers in the function body. This routine makes sure that
-     * arguments to a kernel or function are loaded (by the kernel or function body) into registers
-     * of the appropriate sizes. For example, int and float parameters should appear in S registers,
-     * whereas double and long parameters should appear in d registers.
-     */
-    public static CallingConvention getHSAILCallingConvention(CallingConvention.Type type, TargetDescription target, ResolvedJavaMethod method, boolean stackOnly) {
-        Signature sig = method.getSignature();
-        JavaType retType = sig.getReturnType(null);
-        int sigCount = sig.getParameterCount(false);
-        JavaType[] argTypes;
-        int argIndex = 0;
-        if (!Modifier.isStatic(method.getModifiers())) {
-            argTypes = new JavaType[sigCount + 1];
-            argTypes[argIndex++] = method.getDeclaringClass();
-        } else {
-            argTypes = new JavaType[sigCount];
-        }
-        for (int i = 0; i < sigCount; i++) {
-            argTypes[argIndex++] = sig.getParameterType(i, null);
-        }
-
-        RegisterConfig registerConfig = backend.getProviders().getCodeCache().getRegisterConfig();
-        return registerConfig.getCallingConvention(type, retType, argTypes, target, stackOnly);
-    }
-
-    public static HSAILCompilationResult getCompiledLambda(Class consumerClass) {
-        /**
-         * Find the accept() method in the IntConsumer, then use Graal API to find the target lambda
-         * that accept will call.
-         */
-        Method[] icMethods = consumerClass.getMethods();
-        Method acceptMethod = null;
-        for (Method m : icMethods) {
-            if (m.getName().equals("accept") && acceptMethod == null) {
-                acceptMethod = m;
-                break;
-            }
-        }
-
-        Providers providers = backend.getProviders();
-        HotSpotMetaAccessProvider metaAccess = (HotSpotMetaAccessProvider) providers.getMetaAccess();
-        ResolvedJavaMethod rm = metaAccess.lookupJavaMethod(acceptMethod);
-        StructuredGraph graph = new StructuredGraph(rm);
-        new GraphBuilderPhase.Instance(providers.getMetaAccess(), GraphBuilderConfiguration.getDefault(), OptimisticOptimizations.ALL).apply(graph);
-        NodeIterable<Node> nin = graph.getNodes();
-        ResolvedJavaMethod lambdaMethod = null;
-        for (Node n : nin) {
-            if (n instanceof MethodCallTargetNode) {
-                lambdaMethod = ((MethodCallTargetNode) n).targetMethod();
-                Debug.log("target ... " + lambdaMethod);
-                break;
-            }
-        }
-        if (lambdaMethod == null) {
-            // Did not find call in Consumer.accept.
-            Debug.log("Should not Reach here, did not find call in accept()");
-            return null;
-        }
-        // Now that we have the target lambda, compile it.
-        HSAILCompilationResult hsailCompResult = HSAILCompilationResult.getHSAILCompilationResult(lambdaMethod);
-        return hsailCompResult;
-    }
-
-    public static HSAILCompilationResult getHSAILCompilationResult(StructuredGraph graph) {
-        Debug.dump(graph, "Graph");
-        Providers providers = backend.getProviders();
-        TargetDescription target = providers.getCodeCache().getTarget();
-        PhaseSuite<HighTierContext> graphBuilderSuite = backend.getSuites().getDefaultGraphBuilderSuite().copy();
-        graphBuilderSuite.appendPhase(new HSAILPhase());
-        new HSAILPhase().apply(graph);
-        CallingConvention cc = getHSAILCallingConvention(Type.JavaCallee, target, graph.method(), false);
-        SuitesProvider suitesProvider = backend.getSuites();
-        try {
-            HSAILCompilationResult compResult = compileGraph(graph, cc, graph.method(), providers, backend, target, null, graphBuilderSuite, OptimisticOptimizations.NONE, getProfilingInfo(graph),
-                            new SpeculationLog(), suitesProvider.getDefaultSuites(), true, new HSAILCompilationResult(), CompilationResultBuilderFactory.Default);
-            if ((validDevice) && (compResult.getTargetCode() != null)) {
-                long kernel = toGPU.generateKernel(compResult.getTargetCode(), graph.method().getName());
-
-                if (kernel == 0) {
-                    throw new GraalInternalError("Failed to compile kernel.");
-                }
-
-                ((ExternalCompilationResult) compResult).setEntryPoint(kernel);
-                HotSpotResolvedJavaMethod compiledMethod = (HotSpotResolvedJavaMethod) graph.method();
-                InstalledCode installedCode = ((HotSpotCodeCacheProvider) providers.getCodeCache()).addExternalMethod(compiledMethod, compResult);
-                compResult.setInstalledCode(installedCode);
-            }
-            return compResult;
-        } catch (InvalidInstalledCodeException e) {
-            e.printStackTrace();
-            return null;
-        } catch (GraalInternalError e) {
-            String partialCode = backend.getPartialCodeString();
-            if (partialCode != null && !partialCode.equals("")) {
-                Debug.log("-------------------\nPartial Code Generation:\n--------------------");
-                Debug.log(partialCode);
-                Debug.log("-------------------\nEnd of Partial Code Generation\n--------------------");
-            }
-            throw e;
-        }
-    }
-
-    private static class HSAILPhase extends Phase {
-
-        @Override
-        protected void run(StructuredGraph graph) {
-            for (ParameterNode param : graph.getNodes(ParameterNode.class)) {
-                if (param.stamp() instanceof ObjectStamp) {
-                    param.setStamp(StampFactory.declaredNonNull(((ObjectStamp) param.stamp()).type()));
-                }
-            }
-        }
-    }
-
-    protected HSAILCompilationResult() {
-    }
-
-    public String getHSAILCode() {
-        return new String(getTargetCode(), 0, getTargetCodeSize());
-    }
-
-}
--- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackend.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackend.java	Wed Mar 05 19:40:15 2014 -0800
@@ -23,26 +23,34 @@
 package com.oracle.graal.hotspot.hsail;
 
 import static com.oracle.graal.api.code.CallingConvention.Type.*;
+import static com.oracle.graal.api.code.CodeUtil.*;
 import static com.oracle.graal.api.code.ValueUtil.*;
+import static com.oracle.graal.compiler.GraalCompiler.*;
 
 import java.lang.reflect.*;
 import java.util.*;
 
+import com.amd.okra.*;
 import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.code.CallingConvention.Type;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.*;
 import com.oracle.graal.asm.hsail.*;
 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.hotspot.*;
 import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.hsail.*;
+import com.oracle.graal.java.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.asm.*;
 import com.oracle.graal.lir.hsail.*;
 import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.spi.Replacements;
-import com.oracle.graal.replacements.hsail.*;
+import com.oracle.graal.phases.*;
+import com.oracle.graal.phases.common.*;
+import com.oracle.graal.phases.tiers.*;
 
 /**
  * HSAIL specific backend.
@@ -50,7 +58,7 @@
 public class HSAILHotSpotBackend extends HotSpotBackend {
 
     private Map<String, String> paramTypeMap = new HashMap<>();
-    private Buffer codeBuffer;
+    private final boolean deviceInitialized;
 
     public HSAILHotSpotBackend(HotSpotGraalRuntime runtime, HotSpotProviders providers) {
         super(runtime, providers);
@@ -58,6 +66,10 @@
         paramTypeMap.put("HotSpotResolvedPrimitiveType<float>", "f32");
         paramTypeMap.put("HotSpotResolvedPrimitiveType<double>", "f64");
         paramTypeMap.put("HotSpotResolvedPrimitiveType<long>", "s64");
+
+        // The order of the conjunction below is important: the OkraUtil
+        // call may provision the native library required by the initialize() call
+        deviceInitialized = OkraUtil.okraLibExists() && initialize();
     }
 
     @Override
@@ -66,6 +78,20 @@
     }
 
     /**
+     * Initializes the GPU device.
+     * 
+     * @return whether or not initialization was successful
+     */
+    private static native boolean initialize();
+
+    /**
+     * Determines if the GPU device (or simulator) is available and initialized.
+     */
+    public boolean isDeviceInitialized() {
+        return deviceInitialized;
+    }
+
+    /**
      * Completes the initialization of the HSAIL backend. This includes initializing the providers
      * and registering any method substitutions specified by the HSAIL backend.
      */
@@ -78,13 +104,82 @@
         lowerer.initialize(providers, config);
 
         // Register the replacements used by the HSAIL backend.
-        Replacements replacements = providers.getReplacements();
+        HSAILHotSpotReplacementsImpl replacements = (HSAILHotSpotReplacementsImpl) providers.getReplacements();
+        replacements.completeInitialization();
+    }
+
+    /**
+     * Compiles and installs a given method to a GPU binary.
+     */
+    public HotSpotNmethod compileAndInstallKernel(Method method) {
+        ResolvedJavaMethod javaMethod = getProviders().getMetaAccess().lookupJavaMethod(method);
+        return installKernel(javaMethod, compileKernel(javaMethod, true));
+    }
+
+    /**
+     * Compiles a given method to HSAIL code.
+     * 
+     * @param makeBinary specifies whether a GPU binary should also be generated for the HSAIL code.
+     *            If true, the returned value is guaranteed to have a non-zero
+     *            {@linkplain ExternalCompilationResult#getEntryPoint() entry point}.
+     * @return the HSAIL code compiled from {@code method}'s bytecode
+     */
+    public ExternalCompilationResult compileKernel(ResolvedJavaMethod method, boolean makeBinary) {
+        StructuredGraph graph = new StructuredGraph(method);
+        HotSpotProviders providers = getProviders();
+        new GraphBuilderPhase.Instance(providers.getMetaAccess(), GraphBuilderConfiguration.getEagerDefault(), OptimisticOptimizations.ALL).apply(graph);
+        PhaseSuite<HighTierContext> graphBuilderSuite = providers.getSuites().getDefaultGraphBuilderSuite();
+        graphBuilderSuite.appendPhase(new NonNullParametersPhase());
+        CallingConvention cc = getCallingConvention(providers.getCodeCache(), Type.JavaCallee, graph.method(), false);
+        Suites suites = providers.getSuites().getDefaultSuites();
+        ExternalCompilationResult hsailCode = compileGraph(graph, cc, method, providers, this, this.getTarget(), null, graphBuilderSuite, OptimisticOptimizations.NONE, getProfilingInfo(graph), null,
+                        suites, true, new ExternalCompilationResult(), CompilationResultBuilderFactory.Default);
 
-        // Register the substitutions for java.lang.Math routines.
-        replacements.registerSubstitutions(HSAILMathSubstitutions.class);
+        if (makeBinary) {
+            if (!deviceInitialized) {
+                throw new GraalInternalError("Cannot generate GPU kernel if device is not initialized");
+            }
+            try (Scope ds = Debug.scope("GeneratingKernelBinary")) {
+                long kernel = generateKernel(hsailCode.getTargetCode(), method.getName());
+                if (kernel == 0) {
+                    throw new GraalInternalError("Failed to compile HSAIL kernel");
+                }
+                hsailCode.setEntryPoint(kernel);
+            } catch (Throwable e) {
+                throw Debug.handle(e);
+            }
+        }
+        return hsailCode;
     }
 
     /**
+     * Generates a GPU binary from HSAIL code.
+     */
+    private static native long generateKernel(byte[] hsailCode, String name);
+
+    /**
+     * Installs the {@linkplain ExternalCompilationResult#getEntryPoint() GPU binary} associated
+     * with some given HSAIL code in the code cache and returns a {@link HotSpotNmethod} handle to
+     * the installed code.
+     * 
+     * @param hsailCode HSAIL compilation result for which a GPU binary has been generated
+     * @return a handle to the binary as installed in the HotSpot code cache
+     */
+    public final HotSpotNmethod installKernel(ResolvedJavaMethod method, ExternalCompilationResult hsailCode) {
+        assert hsailCode.getEntryPoint() != 0L;
+        return getProviders().getCodeCache().addExternalMethod(method, hsailCode);
+    }
+
+    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");
+        }
+        return executeKernel0(kernel, jobSize, args);
+    }
+
+    private static native boolean executeKernel0(HotSpotInstalledCode kernel, int jobSize, Object[] args) throws InvalidInstalledCodeException;
+
+    /**
      * Use the HSAIL register set when the compilation target is HSAIL.
      */
     @Override
@@ -97,14 +192,6 @@
         return new HSAILHotSpotLIRGenerator(graph, getProviders(), getRuntime().getConfig(), frameMap, cc, lir);
     }
 
-    public String getPartialCodeString() {
-        if (codeBuffer == null) {
-            return "";
-        }
-        byte[] data = codeBuffer.copyData(0, codeBuffer.position());
-        return (data == null ? "" : new String(data));
-    }
-
     class HotSpotFrameContext implements FrameContext {
 
         public boolean hasFrame() {
@@ -123,14 +210,14 @@
     }
 
     @Override
-    protected AbstractAssembler createAssembler(FrameMap frameMap) {
+    protected Assembler createAssembler(FrameMap frameMap) {
         return new HSAILAssembler(getTarget());
     }
 
     @Override
     public CompilationResultBuilder newCompilationResultBuilder(LIRGenerator lirGen, CompilationResult compilationResult, CompilationResultBuilderFactory factory) {
         FrameMap frameMap = lirGen.frameMap;
-        AbstractAssembler masm = createAssembler(frameMap);
+        Assembler masm = createAssembler(frameMap);
         HotSpotFrameContext frameContext = new HotSpotFrameContext();
         CompilationResultBuilder crb = factory.createBuilder(getCodeCache(), getForeignCalls(), frameMap, masm, frameContext, compilationResult);
         crb.setFrameSize(frameMap.frameSize());
@@ -138,12 +225,12 @@
     }
 
     @Override
-    public void emitCode(CompilationResultBuilder crb, LIRGenerator lirGen, ResolvedJavaMethod method) {
-        assert method != null : lirGen.getGraph() + " is not associated with a method";
+    public void emitCode(CompilationResultBuilder crb, LIR lir, ResolvedJavaMethod method) {
+        assert method != null : lir + " is not associated with a method";
         // Emit the prologue.
-        codeBuffer = crb.asm.codeBuffer;
-        codeBuffer.emitString0("version 0:95: $full : $large;");
-        codeBuffer.emitString("");
+        Assembler asm = crb.asm;
+        asm.emitString0("version 0:95: $full : $large;");
+        asm.emitString("");
 
         Signature signature = method.getSignature();
         int sigParamCount = signature.getParameterCount(false);
@@ -188,10 +275,10 @@
             }
         }
 
-        codeBuffer.emitString0("// " + (isStatic ? "static" : "instance") + " method " + method);
-        codeBuffer.emitString("");
-        codeBuffer.emitString0("kernel &run (");
-        codeBuffer.emitString("");
+        asm.emitString0("// " + (isStatic ? "static" : "instance") + " method " + method);
+        asm.emitString("");
+        asm.emitString0("kernel &run (");
+        asm.emitString("");
 
         FrameMap frameMap = crb.frameMap;
         RegisterConfig regConfig = frameMap.registerConfig;
@@ -221,14 +308,14 @@
         }
         // Emit the kernel function parameters.
         for (int i = 0; i < totalParamCount; i++) {
-            String str = "kernarg_" + paramHsailSizes[i] + " " + paramNames[i];
+            String str = "align 8 kernarg_" + paramHsailSizes[i] + " " + paramNames[i];
 
             if (i != totalParamCount - 1) {
                 str += ",";
             }
-            codeBuffer.emitString(str);
+            asm.emitString(str);
         }
-        codeBuffer.emitString(") {");
+        asm.emitString(") {");
 
         /*
          * End of parameters start of prolog code. Emit the load instructions for loading of the
@@ -236,7 +323,7 @@
          * loaded up front but will be loaded as needed.
          */
         for (int i = 0; i < nonConstantParamCount; i++) {
-            codeBuffer.emitString("ld_kernarg_" + paramHsailSizes[i] + "  " + HSAIL.mapRegister(cc.getArgument(i)) + ", [" + paramNames[i] + "];");
+            asm.emitString("ld_kernarg_" + paramHsailSizes[i] + "  " + HSAIL.mapRegister(cc.getArgument(i)) + ", [" + paramNames[i] + "];");
         }
 
         /*
@@ -244,16 +331,16 @@
          * the register as if it were the last of the nonConstant parameters.
          */
         String workItemReg = "$s" + Integer.toString(asRegister(cc.getArgument(nonConstantParamCount)).encoding());
-        codeBuffer.emitString("workitemabsid_u32 " + workItemReg + ", 0;");
+        asm.emitString("workitemabsid_u32 " + workItemReg + ", 0;");
 
         /*
          * Note the logic used for this spillseg size is to leave space and then go back and patch
          * in the correct size once we have generated all the instructions. This should probably be
          * done in a more robust way by implementing something like codeBuffer.insertString.
          */
-        int spillsegDeclarationPosition = codeBuffer.position() + 1;
+        int spillsegDeclarationPosition = asm.position() + 1;
         String spillsegTemplate = "align 4 spill_u8 %spillseg[123456];";
-        codeBuffer.emitString(spillsegTemplate);
+        asm.emitString(spillsegTemplate);
         // Emit object array load prologue here.
         if (isObjectLambda) {
             boolean useCompressedOops = getRuntime().getConfig().useCompressedOops;
@@ -263,41 +350,41 @@
             // so tempReg can be the next higher $d register
             String tmpReg = "$d" + (asRegister(cc.getArgument(nonConstantParamCount - 1)).encoding() + 1);
             // Convert gid to long.
-            codeBuffer.emitString("cvt_u64_s32 " + tmpReg + ", " + workItemReg + "; // Convert gid to long");
+            asm.emitString("cvt_u64_s32 " + tmpReg + ", " + workItemReg + "; // Convert gid to long");
             // Adjust index for sizeof ref. Where to pull this size from?
-            codeBuffer.emitString("mul_u64 " + tmpReg + ", " + tmpReg + ", " + (useCompressedOops ? 4 : 8) + "; // Adjust index for sizeof ref");
+            asm.emitString("mul_u64 " + tmpReg + ", " + tmpReg + ", " + (useCompressedOops ? 4 : 8) + "; // Adjust index for sizeof ref");
             // Adjust for actual data start.
-            codeBuffer.emitString("add_u64 " + tmpReg + ", " + tmpReg + ", " + arrayElementsOffset + "; // Adjust for actual elements data start");
+            asm.emitString("add_u64 " + tmpReg + ", " + tmpReg + ", " + arrayElementsOffset + "; // Adjust for actual elements data start");
             // Add to array ref ptr.
-            codeBuffer.emitString("add_u64 " + tmpReg + ", " + tmpReg + ", " + iterationObjArgReg + "; // Add to array ref ptr");
+            asm.emitString("add_u64 " + tmpReg + ", " + tmpReg + ", " + iterationObjArgReg + "; // Add to array ref ptr");
             // Load the object into the parameter reg.
             if (useCompressedOops) {
 
                 // Load u32 into the d 64 reg since it will become an object address
-                codeBuffer.emitString("ld_global_u32 " + tmpReg + ", " + "[" + tmpReg + "]" + "; // Load compressed ptr from array");
+                asm.emitString("ld_global_u32 " + tmpReg + ", " + "[" + tmpReg + "]" + "; // Load compressed ptr from array");
 
                 long narrowOopBase = getRuntime().getConfig().narrowOopBase;
                 long narrowOopShift = getRuntime().getConfig().narrowOopShift;
 
                 if (narrowOopBase == 0 && narrowOopShift == 0) {
                     // No more calculation to do, mov to target register
-                    codeBuffer.emitString("mov_b64 " + iterationObjArgReg + ", " + tmpReg + "; // no shift or base addition");
+                    asm.emitString("mov_b64 " + iterationObjArgReg + ", " + tmpReg + "; // no shift or base addition");
                 } else {
                     if (narrowOopBase == 0) {
-                        codeBuffer.emitString("shl_u64 " + iterationObjArgReg + ", " + tmpReg + ", " + narrowOopShift + "; // do narrowOopShift");
+                        asm.emitString("shl_u64 " + iterationObjArgReg + ", " + tmpReg + ", " + narrowOopShift + "; // do narrowOopShift");
                     } else if (narrowOopShift == 0) {
-                        codeBuffer.emitString("add_u64 " + iterationObjArgReg + ", " + tmpReg + ", " + narrowOopBase + "; // add narrowOopBase");
+                        asm.emitString("add_u64 " + iterationObjArgReg + ", " + tmpReg + ", " + narrowOopBase + "; // add narrowOopBase");
                     } else {
-                        codeBuffer.emitString("mad_u64 " + iterationObjArgReg + ", " + tmpReg + ", " + (1 << narrowOopShift) + ", " + narrowOopBase + "; // shift and add narrowOopBase");
+                        asm.emitString("mad_u64 " + iterationObjArgReg + ", " + tmpReg + ", " + (1 << narrowOopShift) + ", " + narrowOopBase + "; // shift and add narrowOopBase");
                     }
                 }
 
             } else {
-                codeBuffer.emitString("ld_global_u64 " + iterationObjArgReg + ", " + "[" + tmpReg + "]" + "; // Load from array element into parameter reg");
+                asm.emitString("ld_global_u64 " + iterationObjArgReg + ", " + "[" + tmpReg + "]" + "; // Load from array element into parameter reg");
             }
         }
         // Prologue done, Emit code for the LIR.
-        crb.emit(lirGen.lir);
+        crb.emit(lir);
         // Now that code is emitted go back and figure out what the upper Bound stack size was.
         long maxStackSize = ((HSAILAssembler) crb.asm).upperBoundStackSize();
         String spillsegStringFinal;
@@ -309,9 +396,10 @@
         } else {
             spillsegStringFinal = spillsegTemplate.replace("123456", String.format("%6d", maxStackSize));
         }
-        codeBuffer.emitString(spillsegStringFinal, spillsegDeclarationPosition);
+        asm.emitString(spillsegStringFinal, spillsegDeclarationPosition);
+
         // Emit the epilogue.
-        codeBuffer.emitString0("};");
-        codeBuffer.emitString("");
+        asm.emitString0("};");
+        asm.emitString("");
     }
 }
--- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackendFactory.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackendFactory.java	Wed Mar 05 19:40:15 2014 -0800
@@ -28,6 +28,7 @@
 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.*;
@@ -51,7 +52,7 @@
         Providers p = new Providers(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, null);
         Replacements replacements = new HSAILHotSpotReplacementsImpl(p, assumptions, codeCache.getTarget(), host.getReplacements());
         HotSpotDisassemblerProvider disassembler = host.getDisassembler();
-        SuitesProvider suites = host.getSuites();
+        SuitesProvider suites = new DefaultSuitesProvider();
         HotSpotProviders providers = new HotSpotProviders(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, replacements, disassembler, suites, registers);
 
         return new HSAILHotSpotBackend(runtime, providers);
--- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotLIRGenerator.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotLIRGenerator.java	Wed Mar 05 19:40:15 2014 -0800
@@ -26,6 +26,8 @@
 import sun.misc.*;
 
 import com.oracle.graal.api.code.*;
+import static com.oracle.graal.api.code.ValueUtil.asConstant;
+import static com.oracle.graal.api.code.ValueUtil.isConstant;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.hsail.*;
 import com.oracle.graal.hotspot.*;
@@ -33,11 +35,12 @@
 import com.oracle.graal.lir.hsail.*;
 import com.oracle.graal.lir.hsail.HSAILControlFlow.*;
 import com.oracle.graal.lir.hsail.HSAILMove.*;
+import com.oracle.graal.phases.util.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.java.*;
-import com.oracle.graal.phases.util.*;
+import com.oracle.graal.graph.*;
 
 /**
  * The HotSpot specific portion of the HSAIL LIR generator.
@@ -79,6 +82,11 @@
         return access != null && access.isCompressible();
     }
 
+    @Override
+    public boolean canStoreConstant(Constant c, boolean isCompressed) {
+        return true;
+    }
+
     /**
      * Appends either a {@link CompareAndSwapOp} or a {@link CompareAndSwapCompressedOp} depending
      * on whether the memory location of a given {@link LoweredCompareAndSwapNode} contains a
@@ -114,10 +122,17 @@
         setResult(node, nodeResult);
     }
 
+    /**
+     * Returns whether or not the input access should be (de)compressed.
+     */
+    private boolean isCompressedOperation(Kind kind, Access access) {
+        return access != null && access.isCompressible() && ((kind == Kind.Long && config.useCompressedClassPointers) || (kind == Kind.Object && config.useCompressedOops));
+    }
+
     @Override
     public Variable emitLoad(Kind kind, Value address, Access access) {
         HSAILAddressValue loadAddress = asAddressValue(address);
-        Variable result = newVariable(kind);
+        Variable result = newVariable(kind.getStackKind());
         LIRFrameState state = null;
         if (access instanceof DeoptimizingNode) {
             state = state((DeoptimizingNode) access);
@@ -141,6 +156,23 @@
         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.NarrowOop, storeAddress, c, state));
+                    } else {
+                        throw GraalInternalError.shouldNotReachHere("can't handle: " + access);
+                    }
+                    return;
+                } else {
+                    append(new StoreConstantOp(kind, storeAddress, c, state));
+                    return;
+                }
+            }
+        }
         Variable input = load(inputVal);
         if (isCompressCandidate(access) && config.useCompressedOops && kind == Kind.Object) {
             Variable scratch = newVariable(Kind.Long);
--- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotReplacementsImpl.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotReplacementsImpl.java	Wed Mar 05 19:40:15 2014 -0800
@@ -30,6 +30,8 @@
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.phases.util.*;
 import com.oracle.graal.replacements.*;
+import com.oracle.graal.replacements.hsail.*;
+import java.util.HashSet;
 
 /**
  * The substitutions and snippets supported by HSAIL.
@@ -37,12 +39,31 @@
 public class HSAILHotSpotReplacementsImpl extends ReplacementsImpl {
 
     private final Replacements host;
+    private HashSet<ResolvedJavaMethod> ignoredResolvedMethods = new HashSet<>();
 
     public HSAILHotSpotReplacementsImpl(Providers providers, Assumptions assumptions, TargetDescription target, Replacements host) {
         super(providers, assumptions, target);
         this.host = host;
     }
 
+    public void addIgnoredResolvedMethod(Class<?> cls, String methName, Class<?>... params) {
+        try {
+            Method m = cls.getMethod(methName, params);
+            ResolvedJavaMethod rjm = providers.getMetaAccess().lookupJavaMethod(m);
+            ignoredResolvedMethods.add(rjm);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    public void completeInitialization() {
+        // Register the substitutions for java.lang.Math routines.
+        registerSubstitutions(HSAILMathSubstitutions.class);
+
+        // Register the ignored substitutions
+        addIgnoredResolvedMethod(String.class, "equals", Object.class);
+    }
+
     @Override
     protected ResolvedJavaMethod registerMethodSubstitution(Member originalMethod, Method substituteMethod) {
         // TODO: decide if we want to override this in any way
@@ -70,9 +91,13 @@
     public StructuredGraph getMethodSubstitution(ResolvedJavaMethod original) {
         StructuredGraph m = super.getMethodSubstitution(original);
         if (m == null) {
-            // eventually we want to only defer certain substitutions to the host, but for now we
-            // will defer everything
-            return host.getMethodSubstitution(original);
+            // we check for a few special cases we do NOT want to defer here
+            // but basically we defer everything else to the host
+            if (ignoredResolvedMethods.contains(original)) {
+                return null;
+            } else {
+                return host.getMethodSubstitution(original);
+            }
         }
         return m;
     }
--- a/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotBackend.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotBackend.java	Wed Mar 05 19:40:15 2014 -0800
@@ -22,11 +22,9 @@
  */
 package com.oracle.graal.hotspot.ptx;
 
-import static com.oracle.graal.api.code.CallingConvention.Type.*;
 import static com.oracle.graal.api.code.CodeUtil.*;
 import static com.oracle.graal.api.meta.LocationIdentity.*;
 import static com.oracle.graal.compiler.GraalCompiler.*;
-import static com.oracle.graal.hotspot.HotSpotForeignCallLinkage.RegisterEffect.*;
 import static com.oracle.graal.hotspot.HotSpotForeignCallLinkage.Transition.*;
 import static com.oracle.graal.hotspot.meta.HotSpotForeignCallsProviderImpl.*;
 import static com.oracle.graal.lir.LIRValueUtil.*;
@@ -34,18 +32,16 @@
 import java.util.*;
 
 import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.code.CallingConvention.*;
+import com.oracle.graal.api.code.CallingConvention.Type;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.*;
 import com.oracle.graal.asm.ptx.*;
 import com.oracle.graal.compiler.gen.*;
-import com.oracle.graal.compiler.ptx.*;
 import com.oracle.graal.debug.*;
-import com.oracle.graal.debug.Debug.*;
+import com.oracle.graal.debug.Debug.Scope;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.hotspot.*;
 import com.oracle.graal.hotspot.HotSpotReplacementsImpl.GraphProducer;
-import com.oracle.graal.hotspot.bridge.*;
 import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.LIRInstruction.OperandFlag;
@@ -58,6 +54,7 @@
 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.*;
 import com.oracle.graal.word.*;
 
@@ -66,8 +63,10 @@
  */
 public class PTXHotSpotBackend extends HotSpotBackend {
 
+    private final boolean deviceInitialized;
+
     /**
-     * Descriptor for the PTX runtime method for launching a kernel. The C++ signature is:
+     * Descriptor for the PTX runtime method for calling a kernel. The C++ signature is:
      * 
      * <pre>
      *     jlong (JavaThread* thread,
@@ -77,11 +76,14 @@
      *            jint dimZ,
      *            jlong parametersAndReturnValueBuffer,
      *            jint parametersAndReturnValueBufferSize,
+     *            jint objectParametersCount,
+     *            jlong objectParametersOffsets,
+     *            jlong pinnedObjects,
      *            jint encodedReturnTypeSize)
      * </pre>
      */
     // @formatter:off
-    public static final ForeignCallDescriptor LAUNCH_KERNEL = new ForeignCallDescriptor("execute_kernel_from_vm", long.class,
+    public static final ForeignCallDescriptor CALL_KERNEL = new ForeignCallDescriptor("execute_kernel_from_vm", long.class,
                     Word.class, // thread
                     long.class, // kernel
                     int.class,  // dimX
@@ -89,43 +91,76 @@
                     int.class,  // dimZ
                     long.class, // parametersAndReturnValueBuffer
                     int.class,  // parametersAndReturnValueBufferSize
+                    int.class,  // objectParameterCount
+                    long.class, // objectParameterOffsets
+                    long.class, // pinnedObjects
                     int.class); // encodedReturnTypeSize
     // @formatter:on
 
     public PTXHotSpotBackend(HotSpotGraalRuntime runtime, HotSpotProviders providers) {
         super(runtime, providers);
-        CompilerToGPU compilerToGPU = getRuntime().getCompilerToGPU();
-        deviceInitialized = OmitDeviceInit || compilerToGPU.deviceInit();
+        if (OmitDeviceInit) {
+            deviceInitialized = true;
+        } else {
+            boolean init = false;
+            try {
+                init = initialize();
+            } catch (UnsatisfiedLinkError e) {
+            }
+            deviceInitialized = init;
+        }
     }
 
+    /**
+     * Initializes the GPU device.
+     * 
+     * @return whether or not initialization was successful
+     */
+    private static native boolean initialize();
+
     @Override
     public boolean shouldAllocateRegisters() {
         return false;
     }
 
     /**
-     * Used to omit {@linkplain CompilerToGPU#deviceInit() device initialization}.
+     * Used to omit {@linkplain #initialize() device initialization}.
      */
     private static final boolean OmitDeviceInit = Boolean.getBoolean("graal.ptx.omitDeviceInit");
 
     @Override
     public void completeInitialization() {
-        HotSpotHostForeignCallsProvider hostForeignCalls = (HotSpotHostForeignCallsProvider) getRuntime().getHostProviders().getForeignCalls();
-        CompilerToGPU compilerToGPU = getRuntime().getCompilerToGPU();
+        HotSpotProviders hostProviders = getRuntime().getHostProviders();
+        HotSpotHostForeignCallsProvider hostForeignCalls = (HotSpotHostForeignCallsProvider) hostProviders.getForeignCalls();
         if (deviceInitialized) {
-            long launchKernel = compilerToGPU.getLaunchKernelAddress();
-            hostForeignCalls.registerForeignCall(LAUNCH_KERNEL, launchKernel, NativeCall, DESTROYS_REGISTERS, NOT_LEAF, NOT_REEXECUTABLE, ANY_LOCATION);
+            long launchKernel = getLaunchKernelAddress();
+            hostForeignCalls.linkForeignCall(hostProviders, CALL_KERNEL, launchKernel, false, NOT_LEAF, NOT_REEXECUTABLE, ANY_LOCATION);
         }
+        /* Add a shutdown hook to destroy CUDA context(s) */
+        Runtime.getRuntime().addShutdownHook(new Thread("PTXShutdown") {
+            @Override
+            public void run() {
+                destroyContext();
+            }
+        });
         super.completeInitialization();
     }
 
-    private boolean deviceInitialized;
+    private static native void destroyContext();
+
+    /**
+     * Gets the address of {@code Ptx::execute_kernel_from_vm()}.
+     */
+    private static native long getLaunchKernelAddress();
 
     @Override
     public FrameMap newFrameMap() {
         return new PTXFrameMap(getCodeCache());
     }
 
+    /**
+     * Determines if the GPU device (or simulator) is available and initialized.
+     */
     public boolean isDeviceInitialized() {
         return deviceInitialized;
     }
@@ -148,7 +183,8 @@
             }
 
             private boolean canOffloadToGPU(ResolvedJavaMethod method) {
-                return method.getName().contains("lambda$") & method.isSynthetic();
+                HotSpotVMConfig config = getRuntime().getConfig();
+                return config.gpuOffload && method.getName().contains("lambda$") & method.isSynthetic();
             }
         };
     }
@@ -166,20 +202,26 @@
         HotSpotProviders providers = getProviders();
         CallingConvention cc = getCallingConvention(providers.getCodeCache(), Type.JavaCallee, method, false);
         PhaseSuite<HighTierContext> graphBuilderSuite = providers.getSuites().getDefaultGraphBuilderSuite();
+        graphBuilderSuite.appendPhase(new NonNullParametersPhase());
         Suites suites = providers.getSuites().getDefaultSuites();
-        ExternalCompilationResult ptxCode = compileGraph(graph, cc, method, providers, this, this.getTarget(), null, graphBuilderSuite, OptimisticOptimizations.NONE, getProfilingInfo(graph),
-                        new SpeculationLog(), suites, true, new ExternalCompilationResult(), CompilationResultBuilderFactory.Default);
+        ExternalCompilationResult ptxCode = compileGraph(graph, cc, method, providers, this, this.getTarget(), null, graphBuilderSuite, OptimisticOptimizations.NONE, getProfilingInfo(graph), null,
+                        suites, true, new ExternalCompilationResult(), CompilationResultBuilderFactory.Default);
         if (makeBinary) {
             try (Scope ds = Debug.scope("GeneratingKernelBinary")) {
-                long kernel = getRuntime().getCompilerToGPU().generateKernel(ptxCode.getTargetCode(), method.getName());
+                assert ptxCode.getTargetCode() != null;
+                long kernel = generateKernel(ptxCode.getTargetCode(), method.getName());
                 ptxCode.setEntryPoint(kernel);
             } catch (Throwable e) {
                 throw Debug.handle(e);
             }
         }
         return ptxCode;
+    }
 
-    }
+    /**
+     * Generates a GPU binary from PTX code.
+     */
+    private static native long generateKernel(byte[] targetCode, String name);
 
     /**
      * A list of the {@linkplain #installKernel(ResolvedJavaMethod, ExternalCompilationResult)
@@ -218,24 +260,24 @@
 
         LIRInstruction op;
 
-        void emitDeclarations(Buffer codeBuffer) {
+        void emitDeclarations(Assembler asm) {
             for (Integer i : unsigned8) {
-                codeBuffer.emitString(".reg .u8 %r" + i.intValue() + ";");
+                asm.emitString(".reg .u8 %r" + i.intValue() + ";");
             }
             for (Integer i : signed32) {
-                codeBuffer.emitString(".reg .s32 %r" + i.intValue() + ";");
+                asm.emitString(".reg .s32 %r" + i.intValue() + ";");
             }
             for (Integer i : signed64) {
-                codeBuffer.emitString(".reg .s64 %r" + i.intValue() + ";");
+                asm.emitString(".reg .s64 %r" + i.intValue() + ";");
             }
             for (Integer i : unsigned64) {
-                codeBuffer.emitString(".reg .u64 %r" + i.intValue() + ";");
+                asm.emitString(".reg .u64 %r" + i.intValue() + ";");
             }
             for (Integer i : float32) {
-                codeBuffer.emitString(".reg .f32 %r" + i.intValue() + ";");
+                asm.emitString(".reg .f32 %r" + i.intValue() + ";");
             }
             for (Integer i : float64) {
-                codeBuffer.emitString(".reg .f64 %r" + i.intValue() + ";");
+                asm.emitString(".reg .f64 %r" + i.intValue() + ";");
             }
         }
 
@@ -317,7 +359,7 @@
         // - has no incoming arguments passed on the stack
         // - has no instructions with debug info
         FrameMap frameMap = lirGen.frameMap;
-        AbstractAssembler masm = createAssembler(frameMap);
+        Assembler masm = createAssembler(frameMap);
         PTXFrameContext frameContext = new PTXFrameContext();
         CompilationResultBuilder crb = factory.createBuilder(getCodeCache(), getForeignCalls(), frameMap, masm, frameContext, compilationResult);
         crb.setFrameSize(0);
@@ -325,39 +367,39 @@
     }
 
     @Override
-    protected AbstractAssembler createAssembler(FrameMap frameMap) {
+    protected Assembler createAssembler(FrameMap frameMap) {
         return new PTXMacroAssembler(getTarget(), frameMap.registerConfig);
     }
 
     @Override
     public LIRGenerator newLIRGenerator(StructuredGraph graph, FrameMap frameMap, CallingConvention cc, LIR lir) {
-        return new PTXLIRGenerator(graph, getProviders(), frameMap, cc, lir);
+        return new PTXHotSpotLIRGenerator(graph, getProviders(), getRuntime().getConfig(), frameMap, cc, lir);
     }
 
-    private static void emitKernelEntry(CompilationResultBuilder crb, LIRGenerator lirGen, ResolvedJavaMethod codeCacheOwner) {
+    private static void emitKernelEntry(CompilationResultBuilder crb, LIR lir, ResolvedJavaMethod codeCacheOwner) {
         // Emit PTX kernel entry text based on PTXParameterOp
         // instructions in the start block. Remove the instructions
         // once kernel entry text and directives are emitted to
         // facilitate seemless PTX code generation subsequently.
-        assert codeCacheOwner != null : lirGen.getGraph() + " is not associated with a method";
+        assert codeCacheOwner != null : lir + " is not associated with a method";
         final String name = codeCacheOwner.getName();
-        Buffer codeBuffer = crb.asm.codeBuffer;
+        Assembler asm = crb.asm;
 
         // Emit initial boiler-plate directives.
-        codeBuffer.emitString(".version 3.0");
-        codeBuffer.emitString(".target sm_30");
-        codeBuffer.emitString0(".entry " + name + " (");
-        codeBuffer.emitString("");
+        asm.emitString(".version 3.0");
+        asm.emitString(".target sm_30");
+        asm.emitString0(".entry " + name + " (");
+        asm.emitString("");
 
         // Get the start block
-        Block startBlock = lirGen.lir.cfg.getStartBlock();
+        Block startBlock = lir.cfg.getStartBlock();
         // Keep a list of ParameterOp instructions to delete from the
         // list of instructions in the block.
         ArrayList<LIRInstruction> deleteOps = new ArrayList<>();
 
         // Emit .param arguments to kernel entry based on ParameterOp
         // instruction.
-        for (LIRInstruction op : lirGen.lir.lir(startBlock)) {
+        for (LIRInstruction op : lir.lir(startBlock)) {
             if (op instanceof PTXParameterOp) {
                 op.emitCode(crb);
                 deleteOps.add(op);
@@ -366,24 +408,23 @@
 
         // Delete ParameterOp instructions.
         for (LIRInstruction op : deleteOps) {
-            lirGen.lir.lir(startBlock).remove(op);
+            lir.lir(startBlock).remove(op);
         }
 
         // Start emiting body of the PTX kernel.
-        codeBuffer.emitString0(") {");
-        codeBuffer.emitString("");
+        asm.emitString0(") {");
+        asm.emitString("");
     }
 
     // Emit .reg space declarations
-    private static void emitRegisterDecl(CompilationResultBuilder crb, LIRGenerator lirGen, ResolvedJavaMethod codeCacheOwner) {
+    private static void emitRegisterDecl(CompilationResultBuilder crb, LIR lir, ResolvedJavaMethod codeCacheOwner) {
 
-        assert codeCacheOwner != null : lirGen.getGraph() + " is not associated with a method";
+        assert codeCacheOwner != null : lir + " is not associated with a method";
 
-        Buffer codeBuffer = crb.asm.codeBuffer;
         RegisterAnalysis registerAnalysis = new RegisterAnalysis();
 
-        for (Block b : lirGen.lir.codeEmittingOrder()) {
-            for (LIRInstruction op : lirGen.lir.lir(b)) {
+        for (Block b : lir.codeEmittingOrder()) {
+            for (LIRInstruction op : lir.lir(b)) {
                 if (op instanceof LabelOp) {
                     // Don't consider this as a definition
                 } else {
@@ -394,47 +435,60 @@
             }
         }
 
-        registerAnalysis.emitDeclarations(codeBuffer);
+        Assembler asm = crb.asm;
+        registerAnalysis.emitDeclarations(asm);
 
         // emit predicate register declaration
-        int maxPredRegNum = ((PTXLIRGenerator) lirGen).getNextPredRegNumber();
+        int maxPredRegNum = lir.numVariables();
         if (maxPredRegNum > 0) {
-            codeBuffer.emitString(".reg .pred %p<" + maxPredRegNum + ">;");
+            asm.emitString(".reg .pred %p<" + maxPredRegNum + ">;");
         }
     }
 
     @Override
-    public void emitCode(CompilationResultBuilder crb, LIRGenerator lirGen, ResolvedJavaMethod codeCacheOwner) {
-        assert codeCacheOwner != null : lirGen.getGraph() + " is not associated with a method";
-        Buffer codeBuffer = crb.asm.codeBuffer;
+    public void emitCode(CompilationResultBuilder crb, LIR lir, ResolvedJavaMethod codeCacheOwner) {
+        assert codeCacheOwner != null : lir + " is not associated with a method";
+        Assembler asm = crb.asm;
+
         // Emit the prologue
-        emitKernelEntry(crb, lirGen, codeCacheOwner);
+        emitKernelEntry(crb, lir, codeCacheOwner);
 
         // Emit register declarations
         try {
-            emitRegisterDecl(crb, lirGen, codeCacheOwner);
+            emitRegisterDecl(crb, lir, codeCacheOwner);
         } catch (GraalInternalError e) {
             e.printStackTrace();
             // TODO : Better error handling needs to be done once
             // all types of parameters are handled.
-            codeBuffer.setPosition(0);
-            codeBuffer.close(false);
+            asm.close(false);
             return;
         }
         // Emit code for the LIR
         try {
-            crb.emit(lirGen.lir);
+            crb.emit(lir);
         } catch (GraalInternalError e) {
             e.printStackTrace();
             // TODO : Better error handling needs to be done once
             // all types of parameters are handled.
-            codeBuffer.setPosition(0);
-            codeBuffer.close(false);
+            asm.close(false);
             return;
         }
 
         // Emit the epilogue
-        codeBuffer.emitString0("}");
-        codeBuffer.emitString("");
+        asm.emitString0("}");
+        asm.emitString("");
     }
+
+    /**
+     * Gets the total number of available CUDA cores.
+     */
+    public int getAvailableProcessors() {
+        if (!deviceInitialized) {
+            return 0;
+        }
+        return getAvailableProcessors0();
+    }
+
+    private static native int getAvailableProcessors0();
+
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotLIRGenerator.java	Wed Mar 05 19:40:15 2014 -0800
@@ -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.hotspot.ptx;
+
+import com.oracle.graal.api.code.CallingConvention;
+import com.oracle.graal.api.code.StackSlot;
+import com.oracle.graal.api.meta.DeoptimizationAction;
+import com.oracle.graal.api.meta.DeoptimizationReason;
+import com.oracle.graal.api.meta.Value;
+import com.oracle.graal.compiler.ptx.PTXLIRGenerator;
+import com.oracle.graal.graph.GraalInternalError;
+import com.oracle.graal.hotspot.HotSpotLIRGenerator;
+import com.oracle.graal.hotspot.HotSpotVMConfig;
+import com.oracle.graal.hotspot.meta.HotSpotProviders;
+import com.oracle.graal.hotspot.nodes.DirectCompareAndSwapNode;
+import com.oracle.graal.lir.FrameMap;
+import com.oracle.graal.lir.LIR;
+import com.oracle.graal.nodes.StructuredGraph;
+import com.oracle.graal.nodes.ValueNode;
+
+/**
+ * LIR generator specialized for PTX HotSpot.
+ */
+public class PTXHotSpotLIRGenerator extends PTXLIRGenerator implements HotSpotLIRGenerator {
+
+    protected PTXHotSpotLIRGenerator(StructuredGraph graph, HotSpotProviders providers, HotSpotVMConfig config, FrameMap frameMap, CallingConvention cc, LIR lir) {
+        super(graph, providers, frameMap, cc, lir);
+        assert config.basicLockSize == 8;
+    }
+
+    public void emitPrefetchAllocate(ValueNode address, ValueNode distance) {
+        // nop
+    }
+
+    public void emitTailcall(Value[] args, Value address) {
+        throw GraalInternalError.unimplemented();
+    }
+
+    public void emitDeoptimizeCaller(DeoptimizationAction action, DeoptimizationReason reason) {
+        throw GraalInternalError.unimplemented();
+    }
+
+    public void emitPatchReturnAddress(ValueNode address) {
+        throw GraalInternalError.unimplemented();
+    }
+
+    public void emitJumpToExceptionHandlerInCaller(ValueNode handlerInCallerPc, ValueNode exception, ValueNode exceptionPc) {
+        throw GraalInternalError.unimplemented();
+    }
+
+    public void visitDirectCompareAndSwap(DirectCompareAndSwapNode x) {
+        throw GraalInternalError.unimplemented();
+    }
+
+    public StackSlot getLockSlot(int lockDepth) {
+        throw GraalInternalError.unimplemented();
+    }
+
+    @Override
+    public HotSpotProviders getProviders() {
+        throw GraalInternalError.unimplemented();
+    }
+}
--- a/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotSuitesProvider.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,57 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.hotspot.ptx;
-
-import com.oracle.graal.java.*;
-import com.oracle.graal.phases.*;
-import com.oracle.graal.phases.tiers.*;
-
-public class PTXHotSpotSuitesProvider implements SuitesProvider {
-
-    private final Suites defaultSuites;
-    private final PhaseSuite<HighTierContext> defaultGraphBuilderSuite;
-
-    public PTXHotSpotSuitesProvider() {
-        this.defaultGraphBuilderSuite = createGraphBuilderSuite();
-        this.defaultSuites = createSuites();
-    }
-
-    public Suites getDefaultSuites() {
-        return defaultSuites;
-    }
-
-    public Suites createSuites() {
-        return Suites.createDefaultSuites();
-    }
-
-    public PhaseSuite<HighTierContext> getDefaultGraphBuilderSuite() {
-        return defaultGraphBuilderSuite;
-    }
-
-    protected PhaseSuite<HighTierContext> createGraphBuilderSuite() {
-        PhaseSuite<HighTierContext> suite = new PhaseSuite<>();
-        suite.appendPhase(new GraphBuilderPhase(GraphBuilderConfiguration.getDefault()));
-        return suite;
-    }
-
-}
--- a/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXWrapperBuilder.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXWrapperBuilder.java	Wed Mar 05 19:40:15 2014 -0800
@@ -40,7 +40,6 @@
 import com.oracle.graal.graph.*;
 import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.hotspot.nodes.*;
-import com.oracle.graal.hotspot.stubs.*;
 import com.oracle.graal.java.*;
 import com.oracle.graal.lir.ptx.*;
 import com.oracle.graal.nodes.*;
@@ -55,21 +54,62 @@
 
 /**
  * Utility for building a graph that "wraps" a compiled PTX kernel. Such a wrapper handles the
- * transition from the host CPU to the GPU and back. The graph created is something like the
- * following pseudo code with UPPER CASE denoting compile-time constants:
+ * transition from the host CPU to the GPU and back. The wrapper allocate 3 on-stack buffers:
+ * <ul>
+ * <li>PARAMS: a buffer for the kernel parameters and one word for the on-device address of the
+ * return value (if any).</li>
+ * <li>PINNED: a buffer into which the address of pinned objects is saved.</li>
+ * <li>OBJECT_OFFSETS: the offsets of the object values in PARAMS.</li>
+ * </ul>
+ * 
+ * 
+ * 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
+ * according to its data size. The wrapper copies the incoming arguments into the buffer as is. The
+ * native {@link PTXHotSpotBackend#CALL_KERNEL callKernel} function will pin the memory for each
+ * object parameter (using {@code cuMemHostRegister}) and then replace the object pointer in PARAMS
+ * with an on-device pointer to the object's memory (see {@code cuMemHostGetDevicePointer}). The
+ * function saves pinned object pointer into PINNED so that it can unpinned once the kernel returns.
+ * The object pointers in PARAMS are specified by OBJECT_OFFSETS.
+ * <p>
+ * As a concrete example, for a kernel whose Java method signature is:
  * 
  * <pre>
- *     T kernel(p0, p1, ..., pN) {
- *         jint bufSize = SIZE_OF_ALIGNED_PARAMS_AND_RETURN_VALUE_WITH_PADDING(p0, p1, ..., pN);
- *         jbyte buf[bufSize] = {p0, PAD(p1), p1, ..., PAD(pN), pN};
- *         jlong result = PTX_LAUNCH_KERNEL(THREAD_REGISTER, KERNEL_ENTRY_POINT, dimX, dimY, dimZ, buf, bufSize, encodedReturnTypeSize);
- *         return convert(result);
+ *     static int kernel(int p1, short p2, Object p3, long p4)
+ * </pre>
+ * 
+ * the graph created is shown below as psuedo-code:
+ * 
+ * <pre>
+ *     int kernel_wrapper(int p1, short p2, oop p3, long p4) {
+ *         address kernelAddr = kernel.start;
+ *         if (kernelAddr == 0) {
+ *             deopt(InvalidateRecompile, RuntimeConstraint);
+ *         }
+ *         byte PARAMS[32];
+ *         word PINNED[1]; // note: no refmap
+ *         int OBJECT_OFFSETS[1] = {8};
+ *         ((int*) PARAMS)[0] = p1;
+ *         ((short*) PARAMS)[2] = p2;
+ *         ((word*) PARAMS)[1] = p3;
+ *         ((long*) PARAMS)[2] = p4;
+ *         int result = CALL_KERNEL(THREAD_REGISTER, KERNEL_ENTRY_POINT, 1, 1, 1, PARAMS, 32, 1, OBJECT_OFFSETS, PINNED, 4);
+ *         if (clearPendingException(thread)) {
+ *             deopt(None, RuntimeConstraint);
+ *         }
+ *         return result;
  *     }
  * </pre>
  * <p>
  * The generated graph includes a reference to the {@link HotSpotNmethod} for the kernel. There must
  * be another reference to the same {@link HotSpotNmethod} object to ensure that the nmethod is not
- * unloaded by the next full GC.
+ * unloaded by the next full GC. Currently, these extra "keep-alive" references are maintained by
+ * {@link PTXHotSpotBackend}.
+ * <p>
+ * The PTX runtime code called by the wrapper blocks GC while the kernel is executing (cf
+ * GetPrimitiveArrayCritical/ReleasePrimitiveArrayCritical JNI functions). This ensures objects can
+ * be safely passed to kernels but should be replaced with a lighter weight mechanism at some point.
  */
 public class PTXWrapperBuilder extends GraphKit {
 
@@ -92,11 +132,23 @@
     int[] javaParameterOffsetsInKernelParametersBuffer;
 
     /**
-     * Constants denoting the arguments to {@link PTXHotSpotBackend#LAUNCH_KERNEL}.
+     * Constants denoting the arguments to {@link PTXHotSpotBackend#CALL_KERNEL}.
      */
+    // @formatter:off
     enum LaunchArg {
-        Thread, Kernel, DimX, DimY, DimZ, ParametersAndReturnValueBuffer, ParametersAndReturnValueBufferSize, EncodedReturnTypeSize
+        Thread,
+        Kernel,
+        DimX,
+        DimY,
+        DimZ,
+        ParametersAndReturnValueBuffer,
+        ParametersAndReturnValueBufferSize,
+        ObjectParametersCount,
+        ObjectParametersOffsets,
+        PinnedObjects,
+        EncodedReturnTypeSize
     }
+    // @formatter:on
 
     /**
      * Creates the graph implementing the CPU to GPU transition.
@@ -108,6 +160,7 @@
     public PTXWrapperBuilder(ResolvedJavaMethod method, HotSpotNmethod kernel, HotSpotProviders providers) {
         super(new StructuredGraph(method), providers);
         int wordSize = providers.getCodeCache().getTarget().wordSize;
+        int intSize = Integer.SIZE / Byte.SIZE;
         Kind wordKind = providers.getCodeCache().getTarget().wordKind;
         Signature sig = method.getSignature();
         boolean isStatic = isStatic(method.getModifiers());
@@ -117,17 +170,18 @@
         int javaParametersIndex = 0;
         Kind returnKind = sig.getReturnKind();
 
-        BitSet objects = new BitSet();
+        List<Integer> objectSlots = new ArrayList<>(javaParameters.length);
         if (!isStatic) {
-            allocateParameter(Kind.Object, javaParametersIndex++, objects, wordSize);
+            allocateParameter(Kind.Object, javaParametersIndex++, objectSlots, wordSize);
         }
         for (int sigIndex = 0; sigIndex < sigCount; sigIndex++) {
             Kind kind = sig.getParameterKind(sigIndex);
-            allocateParameter(kind, javaParametersIndex++, objects, wordSize);
+            allocateParameter(kind, javaParametersIndex++, objectSlots, wordSize);
         }
         bufSize = roundUp(bufSize, wordSize);
 
-        // Add slot for holding pointer to device memory storing return value
+        // Add slot for the device memory pointer. The kernel writes a
+        // pointer in this slot that points to the return value.
         int encodedReturnTypeSize = 0;
         if (returnKind != Kind.Void) {
             bufSize += wordSize;
@@ -140,7 +194,29 @@
 
         InvokeNode kernelStart = createInvoke(getClass(), "getKernelStart", ConstantNode.forObject(kernel, providers.getMetaAccess(), getGraph()));
 
-        AllocaNode buf = append(new AllocaNode(bufSize / wordSize, objects));
+        AllocaNode buf = append(new AllocaNode(bufSize / wordSize, new BitSet()));
+        ValueNode objectParametersOffsets;
+        ValueNode pinnedObjects;
+        ConstantNode nullWord = ConstantNode.forIntegerKind(wordKind, 0L, getGraph());
+        if (objectSlots.isEmpty()) {
+            objectParametersOffsets = ConstantNode.forLong(0, getGraph());
+            pinnedObjects = ConstantNode.forLong(0, getGraph());
+        } else {
+            int intsPerWord = wordSize / intSize;
+            int slots = roundUp(objectSlots.size(), intsPerWord);
+            objectParametersOffsets = append(new AllocaNode(slots, new BitSet()));
+            // No refmap for pinned objects list since kernel execution is (currently) GC unsafe
+            pinnedObjects = append(new AllocaNode(objectSlots.size(), new BitSet()));
+
+            // Initialize the object parameter offsets array
+            int index = 0;
+            for (int slot : objectSlots) {
+                int offset = slot * wordSize;
+                LocationNode location = ConstantLocationNode.create(FINAL_LOCATION, Kind.Int, index * intSize, getGraph());
+                append(new WriteNode(objectParametersOffsets, ConstantNode.forInt(offset, getGraph()), location, BarrierType.NONE, false, false));
+                index++;
+            }
+        }
 
         Map<LaunchArg, ValueNode> args = new EnumMap<>(LaunchArg.class);
         args.put(Thread, append(new ReadRegisterNode(providers.getRegisters().getThreadRegister(), true, false)));
@@ -150,6 +226,9 @@
         args.put(DimZ, forInt(1, getGraph()));
         args.put(ParametersAndReturnValueBuffer, buf);
         args.put(ParametersAndReturnValueBufferSize, forInt(bufSize, getGraph()));
+        args.put(ObjectParametersCount, forInt(objectSlots.size(), getGraph()));
+        args.put(ObjectParametersOffsets, objectParametersOffsets);
+        args.put(PinnedObjects, pinnedObjects);
         args.put(EncodedReturnTypeSize, forInt(encodedReturnTypeSize, getGraph()));
 
         int sigIndex = isStatic ? 0 : -1;
@@ -158,11 +237,11 @@
             int javaParameterOffset = javaParameterOffsetsInKernelParametersBuffer[javaParametersIndex];
             LocationNode location = ConstantLocationNode.create(FINAL_LOCATION, javaParameter.kind(), javaParameterOffset, getGraph());
             append(new WriteNode(buf, javaParameter, location, BarrierType.NONE, false, false));
-            updateDimArg(method, providers, sig, sigIndex++, args, javaParameter);
+            updateDimArg(method, sig, sigIndex++, args, javaParameter);
         }
         if (returnKind != Kind.Void) {
             LocationNode location = ConstantLocationNode.create(FINAL_LOCATION, wordKind, bufSize - wordSize, getGraph());
-            append(new WriteNode(buf, ConstantNode.forIntegerKind(wordKind, 0L, getGraph()), location, BarrierType.NONE, false, false));
+            append(new WriteNode(buf, nullWord, location, BarrierType.NONE, false, false));
         }
 
         FrameStateBuilder fsb = new FrameStateBuilder(method, getGraph(), true);
@@ -170,14 +249,10 @@
         getGraph().start().setStateAfter(fs);
 
         ValueNode[] launchArgsArray = args.values().toArray(new ValueNode[args.size()]);
-        ForeignCallNode result = append(new ForeignCallNode(providers.getForeignCalls(), LAUNCH_KERNEL, launchArgsArray));
+        ForeignCallNode result = append(new ForeignCallNode(providers.getForeignCalls(), CALL_KERNEL, launchArgsArray));
         result.setDeoptimizationState(fs);
 
-        ConstantNode isObjectResultArg = ConstantNode.forBoolean(returnKind == Kind.Object, getGraph());
-        InvokeNode handlePendingException = createInvoke(getClass(), "handlePendingException", args.get(Thread), isObjectResultArg);
-        handlePendingException.setStateAfter(fs);
         InvokeNode getObjectResult = null;
-
         ValueNode returnValue;
         switch (returnKind) {
             case Void:
@@ -188,14 +263,18 @@
             case Short:
             case Char:
             case Int:
-                returnValue = unique(new ConvertNode(Kind.Long, Kind.Int, result));
+                returnValue = unique(new NarrowNode(result, 32));
                 break;
             case Long:
                 returnValue = result;
                 break;
-            case Float:
+            case Float: {
+                ValueNode asInt = unique(new NarrowNode(result, 32));
+                returnValue = ReinterpretNode.reinterpret(Kind.Float, asInt);
+                break;
+            }
             case Double:
-                returnValue = unique(new ReinterpretNode(returnKind, result));
+                returnValue = ReinterpretNode.reinterpret(Kind.Double, result);
                 break;
             case Object:
                 getObjectResult = createInvoke(getClass(), "getObjectResult", args.get(Thread));
@@ -220,12 +299,12 @@
     }
 
     /**
-     * Allocates a slot in the kernel parameters' buffer for a Java parameter.
+     * 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
      */
-    private void allocateParameter(Kind kind, int javaParametersIndex, BitSet objects, int wordSize) {
+    private void allocateParameter(Kind kind, int javaParametersIndex, List<Integer> objectSlots, int wordSize) {
         int kindByteSize = kind == Kind.Object ? wordSize : kind.getBitCount() / Byte.SIZE;
         bufSize = roundUp(bufSize, kindByteSize);
         javaParameterOffsetsInKernelParametersBuffer[javaParametersIndex] = bufSize;
@@ -233,7 +312,7 @@
         if (kind == Kind.Object) {
             stamp = StampFactory.object();
             int slot = bufSize / wordSize;
-            objects.set(slot);
+            objectSlots.add(slot);
         } else {
             stamp = StampFactory.forKind(kind);
         }
@@ -245,7 +324,7 @@
      * Updates the {@code dimX}, {@code dimY} or {@code dimZ} argument passed to the kernel if
      * {@code javaParameter} is annotated with {@link ParallelOver}.
      */
-    private void updateDimArg(ResolvedJavaMethod method, HotSpotProviders providers, Signature sig, int sigIndex, Map<LaunchArg, ValueNode> launchArgs, ParameterNode javaParameter) {
+    private void updateDimArg(ResolvedJavaMethod method, Signature sig, int sigIndex, Map<LaunchArg, ValueNode> launchArgs, ParameterNode javaParameter) {
         if (sigIndex >= 0) {
             ParallelOver parallelOver = getParameterAnnotation(ParallelOver.class, sigIndex, method);
             if (parallelOver != null && sig.getParameterType(sigIndex, method.getDeclaringClass()).equals(providers.getMetaAccess().lookupJavaType(int[].class))) {
@@ -273,19 +352,6 @@
     }
 
     /**
-     * Snippet invoked upon return from the kernel to handle any pending exceptions.
-     */
-    @Snippet
-    private static void handlePendingException(Word thread, boolean isObjectResult) {
-        if (clearPendingException(thread)) {
-            if (isObjectResult) {
-                getAndClearObjectResult(thread);
-            }
-            DeoptimizeNode.deopt(DeoptimizationAction.None, RuntimeConstraint);
-        }
-    }
-
-    /**
      * Snippet invoked upon return from the kernel to retrieve an object return value from the
      * thread local used for communicating object return values from VM calls.
      */
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCDeoptimizeOp.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCDeoptimizeOp.java	Wed Mar 05 19:40:15 2014 -0800
@@ -26,11 +26,12 @@
 
 import com.oracle.graal.asm.sparc.*;
 import com.oracle.graal.lir.*;
+import com.oracle.graal.lir.StandardOp.*;
 import com.oracle.graal.lir.asm.*;
 import com.oracle.graal.lir.sparc.*;
 
 @Opcode("DEOPT")
-final class SPARCDeoptimizeOp extends SPARCLIRInstruction {
+final class SPARCDeoptimizeOp extends SPARCLIRInstruction implements BlockEndOp {
 
     @State private LIRFrameState info;
 
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java	Wed Mar 05 19:40:15 2014 -0800
@@ -32,6 +32,7 @@
 import com.oracle.graal.asm.sparc.*;
 import com.oracle.graal.asm.sparc.SPARCAssembler.*;
 import com.oracle.graal.compiler.gen.LIRGenerator;
+import com.oracle.graal.graph.*;
 import com.oracle.graal.hotspot.*;
 import com.oracle.graal.hotspot.bridge.*;
 import com.oracle.graal.hotspot.meta.*;
@@ -146,7 +147,7 @@
     }
 
     @Override
-    protected AbstractAssembler createAssembler(FrameMap frameMap) {
+    protected Assembler createAssembler(FrameMap frameMap) {
         return new SPARCMacroAssembler(getTarget(), frameMap.registerConfig);
     }
 
@@ -157,7 +158,7 @@
         assert gen.deoptimizationRescueSlot == null || frameMap.frameNeedsAllocating() : "method that can deoptimize must have a frame";
 
         Stub stub = gen.getStub();
-        AbstractAssembler masm = createAssembler(frameMap);
+        Assembler masm = createAssembler(frameMap);
         // 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);
@@ -178,7 +179,7 @@
     }
 
     @Override
-    public void emitCode(CompilationResultBuilder crb, LIRGenerator lirGen, ResolvedJavaMethod installedCodeOwner) {
+    public void emitCode(CompilationResultBuilder crb, LIR lir, ResolvedJavaMethod installedCodeOwner) {
         SPARCMacroAssembler masm = (SPARCMacroAssembler) crb.asm;
         FrameMap frameMap = crb.frameMap;
         RegisterConfig regConfig = frameMap.registerConfig;
@@ -207,7 +208,7 @@
         crb.recordMark(Marks.MARK_VERIFIED_ENTRY);
 
         // Emit code for the LIR
-        crb.emit(lirGen.lir);
+        crb.emit(lir);
 
         HotSpotFrameContext frameContext = (HotSpotFrameContext) crb.frameContext;
         HotSpotForeignCallsProvider foreignCalls = getProviders().getForeignCalls();
@@ -219,7 +220,6 @@
         } else {
             // No need to emit the stubs for entries back into the method since
             // it has no calls that can cause such "return" entries
-            assert !frameMap.accessesCallerFrame() : lirGen.getGraph();
         }
 
         if (unverifiedStub != null) {
@@ -228,4 +228,9 @@
             SPARCCall.indirectJmp(crb, masm, scratch, foreignCalls.lookupForeignCall(IC_MISS_HANDLER));
         }
     }
+
+    @Override
+    public NativeFunctionInterface getNativeFunctionInterface() {
+        throw GraalInternalError.unimplemented("No NativeFunctionInterface of SPARC");
+    }
 }
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackendFactory.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackendFactory.java	Wed Mar 05 19:40:15 2014 -0800
@@ -49,7 +49,7 @@
         assert host == null;
         TargetDescription target = createTarget();
 
-        HotSpotRegistersProvider registers = new HotSpotRegisters(Register.None, Register.None, Register.None); // FIXME
+        HotSpotRegistersProvider registers = createRegisters();
         HotSpotMetaAccessProvider metaAccess = new HotSpotMetaAccessProvider(runtime);
         HotSpotCodeCacheProvider codeCache = new SPARCHotSpotCodeCacheProvider(runtime, target);
         HotSpotConstantReflectionProvider constantReflection = new HotSpotConstantReflectionProvider(runtime);
@@ -68,6 +68,10 @@
         return new SPARCHotSpotBackend(runtime, providers);
     }
 
+    protected HotSpotRegistersProvider createRegisters() {
+        return new HotSpotRegisters(SPARC.g2, SPARC.g6, SPARC.sp);
+    }
+
     @SuppressWarnings("unused")
     private static Value[] createNativeABICallerSaveRegisters(HotSpotVMConfig config, RegisterConfig regConfig) {
         CalleeSaveLayout csl = regConfig.getCalleeSaveLayout();
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotEpilogueOp.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotEpilogueOp.java	Wed Mar 05 19:40:15 2014 -0800
@@ -23,12 +23,13 @@
 package com.oracle.graal.hotspot.sparc;
 
 import com.oracle.graal.lir.sparc.*;
+import com.oracle.graal.lir.StandardOp.*;
 import com.oracle.graal.lir.asm.*;
 
 /**
  * Superclass for operations that leave a method's frame.
  */
-abstract class SPARCHotSpotEpilogueOp extends SPARCLIRInstruction {
+abstract class SPARCHotSpotEpilogueOp extends SPARCLIRInstruction implements BlockEndOp {
 
     protected void leaveFrame(CompilationResultBuilder crb) {
         crb.frameContext.leave(crb);
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java	Wed Mar 05 19:40:15 2014 -0800
@@ -72,7 +72,6 @@
     @SuppressWarnings("hiding")
     @Override
     protected DebugInfoBuilder createDebugInfoBuilder(NodeMap<Value> nodeOperands) {
-        assert config.basicLockSize == 8;
         HotSpotLockStack lockStack = new HotSpotLockStack(frameMap, Kind.Long);
         return new HotSpotDebugInfoBuilder(nodeOperands, lockStack);
     }
@@ -97,10 +96,11 @@
 
     @Override
     public Variable emitForeignCall(ForeignCallLinkage linkage, DeoptimizingNode info, Value... args) {
+        Stub stub = getStub();
         Variable result;
 
         if (linkage.canDeoptimize()) {
-            assert info != null;
+            assert info != null || stub != null;
             HotSpotRegistersProvider registers = getProviders().getRegisters();
             Register thread = registers.getThreadRegister();
             Register stackPointer = registers.getStackPointerRegister();
@@ -243,7 +243,7 @@
     @Override
     public Variable emitLoad(Kind kind, Value address, Access access) {
         SPARCAddressValue loadAddress = asAddressValue(address);
-        Variable result = newVariable(kind);
+        Variable result = newVariable(kind.getStackKind());
         LIRFrameState state = null;
         if (access instanceof DeoptimizingNode) {
             state = state((DeoptimizingNode) access);
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotRegisterConfig.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotRegisterConfig.java	Wed Mar 05 19:40:15 2014 -0800
@@ -208,7 +208,7 @@
         }
 
         Kind returnKind = returnType == null ? Kind.Void : returnType.getKind();
-        AllocatableValue returnLocation = returnKind == Kind.Void ? Value.ILLEGAL : getReturnRegister(returnKind, type).asValue(returnKind);
+        AllocatableValue returnLocation = returnKind == Kind.Void ? Value.ILLEGAL : getReturnRegister(returnKind, type).asValue(returnKind.getStackKind());
         return new CallingConvention(currentStackOffset, returnLocation, locations);
     }
 
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotReturnOp.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotReturnOp.java	Wed Mar 05 19:40:15 2014 -0800
@@ -24,7 +24,6 @@
 
 import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
 import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
-import static com.oracle.graal.phases.GraalOptions.*;
 
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.sparc.*;
@@ -49,7 +48,8 @@
 
     @Override
     public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
-        if (!isStub && (crb.frameContext.hasFrame() || !OptEliminateSafepoints.getValue())) {
+        if (!isStub) {
+            // Every non-stub compile method must have a poll before the return.
             // Using the same scratch register as LIR_Assembler::return_op
             // in c1_LIRAssembler_sparc.cpp
             SPARCHotSpotSafepointOp.emitCode(crb, masm, runtime().getConfig(), true, null, SPARC.l0);
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotSafepointOp.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotSafepointOp.java	Wed Mar 05 19:40:15 2014 -0800
@@ -59,9 +59,9 @@
     }
 
     public static void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm, HotSpotVMConfig config, boolean atReturn, LIRFrameState state, Register scratch) {
-        final int pos = masm.codeBuffer.position();
+        final int pos = masm.position();
         new Setx(config.safepointPollingAddress, scratch).emit(masm);
-        crb.recordMark(atReturn ? MARK_POLL_RETURN_NEAR : MARK_POLL_NEAR);
+        crb.recordMark(atReturn ? MARK_POLL_RETURN_FAR : MARK_POLL_FAR);
         if (state != null) {
             crb.recordInfopoint(pos, state, InfopointReason.SAFEPOINT);
         }
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCPrefetchOp.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCPrefetchOp.java	Wed Mar 05 19:40:15 2014 -0800
@@ -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,16 +23,16 @@
 
 package com.oracle.graal.hotspot.sparc;
 
+import static com.oracle.graal.asm.sparc.SPARCMacroAssembler.*;
 import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
 
 import com.oracle.graal.asm.sparc.*;
-import com.oracle.graal.graph.*;
 import com.oracle.graal.lir.asm.*;
 import com.oracle.graal.lir.sparc.*;
 
 public class SPARCPrefetchOp extends SPARCLIRInstruction {
 
-    private final int instr;  // AllocatePrefecthInstr
+    private final int instr;  // AllocatePrefetchInstr
     @Alive({COMPOSITE}) protected SPARCAddressValue address;
 
     public SPARCPrefetchOp(SPARCAddressValue address, int instr) {
@@ -43,8 +43,6 @@
     @Override
     public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
         assert instr == 0 : "only supported value is 0";
-        // masm.prefetch(address.toAddress(), 2);
-        throw GraalInternalError.unimplemented("prefetch instruction");
+        new Prefetch(address.toAddress(), Prefetch.Fcn.SeveralWritesAndPossiblyReads).emit(masm);
     }
-
 }
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/AheadOfTimeCompilationTest.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/AheadOfTimeCompilationTest.java	Wed Mar 05 19:40:15 2014 -0800
@@ -172,6 +172,7 @@
         return Boolean.valueOf(true);
     }
 
+    @Ignore("ImmutableCode override may not work reliably in non-hosted mode")
     @Test
     public void testBoxedBooleanAOT() {
         StructuredGraph result = compile("getBoxedBoolean", true);
@@ -204,7 +205,7 @@
             // create suites everytime, as we modify options for the compiler
             final Suites suitesLocal = Graal.getRequiredCapability(RuntimeProvider.class).getHostBackend().getSuites().createSuites();
             final CompilationResult compResult = compileGraph(graph, cc, method, getProviders(), getBackend(), getCodeCache().getTarget(), null, getDefaultGraphBuilderSuite(),
-                            OptimisticOptimizations.ALL, getProfilingInfo(graph), new SpeculationLog(), suitesLocal, true, new CompilationResult(), CompilationResultBuilderFactory.Default);
+                            OptimisticOptimizations.ALL, getProfilingInfo(graph), getSpeculationLog(), suitesLocal, true, new CompilationResult(), CompilationResultBuilderFactory.Default);
             addMethod(method, compResult);
         }
 
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/CompressedOopTest.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/CompressedOopTest.java	Wed Mar 05 19:40:15 2014 -0800
@@ -198,6 +198,10 @@
         }
         int j = 0;
         while (j < objects.length) {
+            if (!installedBenchmarkCode.isValid()) {
+                // This can get invalidated due to lack of MDO update
+                installedBenchmarkCode = getInstalledCode("queueTest");
+            }
             installedBenchmarkCode.execute(q, objects[j], null);
             j++;
         }
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotCryptoSubstitutionTest.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotCryptoSubstitutionTest.java	Wed Mar 05 19:40:15 2014 -0800
@@ -115,6 +115,7 @@
                 ResolvedJavaMethod installedCodeOwner = getMetaAccess().lookupJavaMethod(method);
                 StructuredGraph graph = getReplacements().getMethodSubstitution(installedCodeOwner);
                 if (graph != null) {
+                    graph = graph.copy();
                     Assert.assertNotNull(getCode(installedCodeOwner, graph, true));
                     atLeastOneCompiled = true;
                 } else {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotResolvedJavaFieldTest.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot.test;
+
+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.*;
+
+import org.junit.*;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.hotspot.meta.*;
+
+/**
+ * Tests {@link HotSpotResolvedJavaField} functionality.
+ */
+public class HotSpotResolvedJavaFieldTest {
+
+    private static final Class[] classesWithInternalFields = {Class.class, ClassLoader.class};
+
+    /**
+     * Tests that {@link HotSpotResolvedJavaField#getModifiers()} only includes the modifiers
+     * returned by {@link Field#getModifiers()}. Namely, it must not include
+     * {@code HotSpotResolvedJavaField#FIELD_INTERNAL_FLAG}.
+     */
+    @Test
+    public void testModifiersForInternal() {
+        for (Class c : classesWithInternalFields) {
+            ResolvedJavaType type = HotSpotResolvedObjectType.fromClass(c);
+            for (ResolvedJavaField field : type.getInstanceFields(false)) {
+                if (field.isInternal()) {
+                    Assert.assertEquals(0, ~getReflectionFieldModifiers() & field.getModifiers());
+                }
+            }
+        }
+    }
+
+    /**
+     * Tests that {@link HotSpotResolvedObjectType#createField(String, JavaType, long, int)} always
+     * returns the same object for an internal field.
+     */
+    @Test
+    public void testCachingForInternalFields() {
+        for (Class c : classesWithInternalFields) {
+            HotSpotResolvedObjectType type = (HotSpotResolvedObjectType) HotSpotResolvedObjectType.fromClass(c);
+            for (ResolvedJavaField field : type.getInstanceFields(false)) {
+                if (field.isInternal()) {
+                    HotSpotResolvedJavaField expected = (HotSpotResolvedJavaField) field;
+                    ResolvedJavaField actual = type.createField(expected.getName(), expected.getType(), expected.offset(), expected.getModifiers());
+                    Assert.assertEquals(expected, actual);
+                }
+            }
+        }
+    }
+
+    @Test
+    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()));
+        }
+    }
+}
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotResolvedObjectTypeTest.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotResolvedObjectTypeTest.java	Wed Mar 05 19:40:15 2014 -0800
@@ -24,13 +24,12 @@
 
 import org.junit.*;
 
-import com.oracle.graal.compiler.test.*;
 import com.oracle.graal.hotspot.meta.*;
 
 /**
  * Tests {@link HotSpotResolvedObjectType} functionality.
  */
-public class HotSpotResolvedObjectTypeTest extends GraalCompilerTest {
+public class HotSpotResolvedObjectTypeTest {
 
     @Test
     public void testGetSourceFileName() throws Throwable {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java	Wed Mar 05 19:40:15 2014 -0800
@@ -22,6 +22,7 @@
  */
 package com.oracle.graal.hotspot;
 
+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.hotspot.bridge.VMToCompilerImpl.*;
@@ -29,6 +30,7 @@
 import static com.oracle.graal.phases.GraalOptions.*;
 import static com.oracle.graal.phases.common.InliningUtil.*;
 
+import java.io.*;
 import java.lang.reflect.*;
 import java.util.concurrent.*;
 import java.util.concurrent.atomic.*;
@@ -49,9 +51,16 @@
 import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.tiers.*;
 
-public class CompilationTask implements Runnable {
+public class CompilationTask implements Runnable, Comparable {
 
-    public static final ThreadLocal<Boolean> withinEnqueue = new ThreadLocal<Boolean>() {
+    // 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
+    // withinEnqueue is non-null we assume that CompilationTask is fully initialized.
+    private static final AtomicLong uniqueTaskIds = new AtomicLong();
+
+    private static final DebugMetric BAILOUTS = Debug.metric("Bailouts");
+
+    private static final ThreadLocal<Boolean> withinEnqueue = new ThreadLocal<Boolean>() {
 
         @Override
         protected Boolean initialValue() {
@@ -59,8 +68,24 @@
         }
     };
 
+    public static final boolean isWithinEnqueue() {
+        // It's possible this can be called before the <clinit> has completed so check for null
+        return withinEnqueue == null || withinEnqueue.get();
+    }
+
+    public static class BeginEnqueue implements Closeable {
+        public BeginEnqueue() {
+            assert !withinEnqueue.get();
+            withinEnqueue.set(Boolean.TRUE);
+        }
+
+        public void close() {
+            withinEnqueue.set(Boolean.FALSE);
+        }
+    }
+
     private enum CompilationStatus {
-        Queued, Running
+        Queued, Running, Finished
     }
 
     private final HotSpotBackend backend;
@@ -71,12 +96,20 @@
 
     private StructuredGraph graph;
 
-    public CompilationTask(HotSpotBackend backend, HotSpotResolvedJavaMethod method, int entryBCI, int id) {
-        assert id >= 0;
+    /**
+     * A long representing the sequence number of this task. Used for sorting the compile queue.
+     */
+    private long taskId;
+
+    private boolean blocking;
+
+    public CompilationTask(HotSpotBackend backend, HotSpotResolvedJavaMethod method, int entryBCI, boolean blocking) {
         this.backend = backend;
         this.method = method;
         this.entryBCI = entryBCI;
-        this.id = id;
+        this.id = backend.getRuntime().getCompilerToVM().allocateCompileId(method, entryBCI);
+        this.blocking = blocking;
+        this.taskId = uniqueTaskIds.incrementAndGet();
         this.status = new AtomicReference<>(CompilationStatus.Queued);
     }
 
@@ -101,10 +134,43 @@
                 method.setCurrentTask(null);
             }
             withinEnqueue.set(Boolean.TRUE);
+            status.set(CompilationStatus.Finished);
+            synchronized (this) {
+                notifyAll();
+            }
         }
     }
 
     /**
+     * Block waiting till the compilation completes.
+     */
+    public synchronized void block() {
+        while (status.get() != CompilationStatus.Finished) {
+            try {
+                wait();
+            } catch (InterruptedException e) {
+                // Ignore and retry
+            }
+        }
+    }
+
+    /**
+     * Sort blocking tasks before non-blocking ones and then by lowest taskId within the group.
+     */
+    public int compareTo(Object o) {
+        if (!(o instanceof CompilationTask)) {
+            return 1;
+        }
+        CompilationTask task2 = (CompilationTask) o;
+        if (this.blocking != task2.blocking) {
+            // Blocking CompilationTasks are always higher than CompilationTasks
+            return task2.blocking ? 1 : -1;
+        }
+        // Within the two groups sort by sequence id, so they are processed in insertion order.
+        return this.taskId > task2.taskId ? 1 : -1;
+    }
+
+    /**
      * Time spent in compilation.
      */
     public static final DebugTimer CompilationTime = Debug.timer("CompilationTime");
@@ -179,6 +245,13 @@
                 }
                 InlinedBytecodes.add(method.getCodeSize());
                 CallingConvention cc = getCallingConvention(providers.getCodeCache(), Type.JavaCallee, graph.method(), false);
+                if (graph.getEntryBCI() != StructuredGraph.INVOCATION_ENTRY_BCI) {
+                    // for OSR, only a pointer is passed to the method.
+                    JavaType[] parameterTypes = new JavaType[]{providers.getMetaAccess().lookupJavaType(long.class)};
+                    CallingConvention tmp = providers.getCodeCache().getRegisterConfig().getCallingConvention(JavaCallee, providers.getMetaAccess().lookupJavaType(void.class), parameterTypes,
+                                    backend.getTarget(), false);
+                    cc = new CallingConvention(cc.getStackSize(), cc.getReturn(), tmp.getArgument(0));
+                }
                 Suites suites = getSuites(providers);
                 ProfilingInfo profilingInfo = getProfilingInfo();
                 OptimisticOptimizations optimisticOpts = getOptimisticOpts(profilingInfo);
@@ -203,7 +276,7 @@
             }
             stats.finish(method);
         } catch (BailoutException bailout) {
-            Debug.metric("Bailouts").increment();
+            BAILOUTS.increment();
             if (ExitVMOnBailout.getValue()) {
                 TTY.cachedOut.println(MetaUtil.format("Bailout in %H.%n(%p)", method));
                 bailout.printStackTrace(TTY.cachedOut);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompileTheWorld.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompileTheWorld.java	Wed Mar 05 19:40:15 2014 -0800
@@ -39,9 +39,7 @@
 import com.oracle.graal.debug.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.hotspot.HotSpotOptions.OptionConsumer;
-import com.oracle.graal.hotspot.bridge.*;
 import com.oracle.graal.hotspot.meta.*;
-import com.oracle.graal.nodes.*;
 import com.oracle.graal.options.*;
 import com.oracle.graal.options.OptionValue.OverrideScope;
 import com.oracle.graal.phases.tiers.*;
@@ -147,7 +145,6 @@
 
     // Some runtime instances we need.
     private final HotSpotGraalRuntime runtime = runtime();
-    private final VMToCompilerImpl vmToCompiler = (VMToCompilerImpl) runtime.getVMToCompiler();
 
     /** List of Zip/Jar files to compile (see {@link #CompileTheWorldClasspath}. */
     private final String files;
@@ -320,8 +317,8 @@
 
     class CTWCompilationTask extends CompilationTask {
 
-        CTWCompilationTask(HotSpotBackend backend, HotSpotResolvedJavaMethod method, int id) {
-            super(backend, method, INVOCATION_ENTRY_BCI, id);
+        CTWCompilationTask(HotSpotBackend backend, HotSpotResolvedJavaMethod method) {
+            super(backend, method, INVOCATION_ENTRY_BCI, false);
         }
 
         /**
@@ -351,9 +348,8 @@
         try {
             long start = System.currentTimeMillis();
 
-            int id = vmToCompiler.allocateCompileTaskId(method, StructuredGraph.INVOCATION_ENTRY_BCI);
             HotSpotBackend backend = runtime.getHostBackend();
-            CompilationTask task = new CTWCompilationTask(backend, method, id);
+            CompilationTask task = new CTWCompilationTask(backend, method);
             task.runCompilation(false);
 
             compileTime += (System.currentTimeMillis() - start);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotCompiledCode.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotCompiledCode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -31,6 +31,7 @@
 import com.oracle.graal.api.code.CompilationResult.Data;
 import com.oracle.graal.api.code.CompilationResult.DataPatch;
 import com.oracle.graal.api.code.CompilationResult.ExceptionHandler;
+import com.oracle.graal.api.code.CompilationResult.Infopoint;
 import com.oracle.graal.api.code.CompilationResult.JumpTable;
 import com.oracle.graal.api.code.CompilationResult.Mark;
 import com.oracle.graal.api.code.CompilationResult.Site;
@@ -195,6 +196,24 @@
                 comments[i] = new Comment(annotation.position, text);
             }
         }
+        assert validateFrames();
+    }
+
+    /**
+     * Ensure that all the frames passed into HotSpot are properly formatted with an empty or
+     * illegal slot following double word slots.
+     */
+    private boolean validateFrames() {
+        for (Site site : sites) {
+            if (site instanceof Infopoint) {
+                Infopoint info = (Infopoint) site;
+                if (info.debugInfo != null) {
+                    BytecodeFrame frame = info.debugInfo.frame();
+                    assert frame == null || frame.validateFormat();
+                }
+            }
+        }
+        return true;
     }
 
     static class SiteComparator implements Comparator<Site> {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotDebugInfoBuilder.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotDebugInfoBuilder.java	Wed Mar 05 19:40:15 2014 -0800
@@ -56,6 +56,7 @@
         ValueNode lock = state.lockAt(lockIndex);
         Value object = toValue(lock);
         boolean eliminated = object instanceof VirtualObject && state.monitorIdAt(lockIndex) != null;
+        assert state.monitorIdAt(lockIndex) == null || state.monitorIdAt(lockIndex).getLockDepth() == lockDepth;
         return new HotSpotMonitorValue(object, slot, eliminated);
     }
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java	Wed Mar 05 19:40:15 2014 -0800
@@ -181,10 +181,8 @@
     }
 
     protected/* final */CompilerToVM compilerToVm;
-    protected/* final */CompilerToGPU compilerToGpu;
     protected/* final */VMToCompiler vmToCompiler;
 
-    private HotSpotRuntimeInterpreterInterface runtimeInterpreterInterface;
     private volatile HotSpotGraphCache cache;
 
     protected final HotSpotVMConfig config;
@@ -211,11 +209,9 @@
 
     private HotSpotGraalRuntime() {
         CompilerToVM toVM = new CompilerToVMImpl();
-        CompilerToGPU toGPU = new CompilerToGPUImpl();
         VMToCompiler toCompiler = new VMToCompilerImpl(this);
 
         compilerToVm = toVM;
-        compilerToGpu = toGPU;
         vmToCompiler = toCompiler;
         config = new HotSpotVMConfig(compilerToVm);
 
@@ -237,7 +233,7 @@
         String hostArchitecture = config.getHostArchitectureName();
         hostBackend = registerBackend(findFactory(hostArchitecture).createBackend(this, null));
 
-        String[] gpuArchitectures = getGPUArchitectureNames();
+        String[] gpuArchitectures = getGPUArchitectureNames(compilerToVm);
         for (String arch : gpuArchitectures) {
             HotSpotBackendFactory factory = findFactory(arch);
             if (factory == null) {
@@ -271,15 +267,12 @@
 
     /**
      * Gets the names of the supported GPU architectures for the purpose of finding the
-     * corresponding {@linkplain HotSpotBackendFactory backend} objects. This method first looks for
-     * a comma or {@link java.io.File#pathSeparatorChar} separated list of names in the
-     * {@value #GRAAL_GPU_ISALIST_PROPERTY_NAME} system property. If this property is not set, then
-     * the GPU native support code is queried.
+     * corresponding {@linkplain HotSpotBackendFactory backend} objects.
      */
-    private static String[] getGPUArchitectureNames() {
-        String gpuList = System.getProperty(GRAAL_GPU_ISALIST_PROPERTY_NAME);
-        if (gpuList != null && !gpuList.isEmpty()) {
-            String[] gpus = gpuList.split("[,:]");
+    private static String[] getGPUArchitectureNames(CompilerToVM c2vm) {
+        String gpuList = c2vm.getGPUs();
+        if (!gpuList.isEmpty()) {
+            String[] gpus = gpuList.split(",");
             return gpus;
         }
         return new String[0];
@@ -320,10 +313,6 @@
         return vmToCompiler;
     }
 
-    public CompilerToGPU getCompilerToGPU() {
-        return compilerToGpu;
-    }
-
     /**
      * Converts a name to a Java type.
      * 
@@ -351,18 +340,11 @@
         // Resolve the type in the VM.
         final long metaspaceKlass = compilerToVm.lookupType(name, accessingClass, eagerResolve);
         if (metaspaceKlass == 0) {
-            return vmToCompiler.createUnresolvedJavaType(name);
+            return HotSpotUnresolvedJavaType.create(name);
         }
         return HotSpotResolvedObjectType.fromMetaspaceKlass(metaspaceKlass);
     }
 
-    public HotSpotRuntimeInterpreterInterface getRuntimeInterpreterInterface() {
-        if (runtimeInterpreterInterface == null) {
-            runtimeInterpreterInterface = new HotSpotRuntimeInterpreterInterface(getHostProviders().getMetaAccess());
-        }
-        return runtimeInterpreterInterface;
-    }
-
     public HotSpotProviders getHostProviders() {
         return getHostBackend().getProviders();
     }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotHostBackend.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotHostBackend.java	Wed Mar 05 19:40:15 2014 -0800
@@ -28,6 +28,7 @@
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.compiler.target.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.debug.Debug.Scope;
 import com.oracle.graal.hotspot.HotSpotReplacementsImpl.*;
@@ -37,7 +38,7 @@
 /**
  * Common functionality of HotSpot host backends.
  */
-public abstract class HotSpotHostBackend extends HotSpotBackend {
+public abstract class HotSpotHostBackend extends HotSpotBackend implements HostBackend {
 
     /**
      * This will be 0 if stack banging is disabled.
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotReplacementsImpl.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotReplacementsImpl.java	Wed Mar 05 19:40:15 2014 -0800
@@ -58,6 +58,11 @@
                 if (!config.usePopCountInstruction) {
                     return null;
                 }
+            } else if (substituteMethod.getName().equals("numberOfLeadingZeros")) {
+                if (config.useCountLeadingZerosInstruction) {
+                    // bsr is lzcnt
+                    return null;
+                }
             }
         } else if (substituteClass == CRC32Substitutions.class) {
             if (!config.useCRC32Intrinsics) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotRuntimeInterpreterInterface.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,327 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.hotspot;
-
-import static com.oracle.graal.graph.FieldIntrospection.*;
-
-import java.lang.reflect.*;
-
-import sun.misc.*;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.hotspot.meta.*;
-
-public class HotSpotRuntimeInterpreterInterface {
-
-    private final MetaAccessProvider metaAccess;
-
-    public HotSpotRuntimeInterpreterInterface(MetaAccessProvider metaProvider) {
-        this.metaAccess = metaProvider;
-    }
-
-    public Class<?> getMirror(ResolvedJavaType type) {
-        return ((HotSpotResolvedJavaType) type).mirror();
-    }
-
-    public native Object invoke(ResolvedJavaMethod method, Object... args);
-
-    public void monitorEnter(Object value) {
-        nullCheck(value);
-        unsafe.monitorEnter(value);
-    }
-
-    public void monitorExit(Object value) {
-        nullCheck(value);
-        unsafe.monitorExit(value);
-    }
-
-    public Object newObject(ResolvedJavaType type) throws InstantiationException {
-        return unsafe.allocateInstance(getMirror(type));
-    }
-
-    public Object getFieldObject(Object base, ResolvedJavaField field) {
-        long offset = resolveOffset(field);
-        if (isVolatile(field)) {
-            return unsafe.getObjectVolatile(resolveBase(base, field), offset);
-        } else {
-            return unsafe.getObject(resolveBase(base, field), offset);
-        }
-    }
-
-    public boolean getFieldBoolean(Object base, ResolvedJavaField field) {
-        long offset = resolveOffset(field);
-        if (isVolatile(field)) {
-            return unsafe.getBooleanVolatile(resolveBase(base, field), offset);
-        } else {
-            return unsafe.getBoolean(resolveBase(base, field), offset);
-        }
-    }
-
-    public byte getFieldByte(Object base, ResolvedJavaField field) {
-        long offset = resolveOffset(field);
-        if (isVolatile(field)) {
-            return unsafe.getByteVolatile(resolveBase(base, field), offset);
-        } else {
-            return unsafe.getByte(resolveBase(base, field), offset);
-        }
-    }
-
-    public char getFieldChar(Object base, ResolvedJavaField field) {
-        long offset = resolveOffset(field);
-        if (isVolatile(field)) {
-            return unsafe.getCharVolatile(resolveBase(base, field), offset);
-        } else {
-            return unsafe.getChar(resolveBase(base, field), offset);
-        }
-    }
-
-    public short getFieldShort(Object base, ResolvedJavaField field) {
-        long offset = resolveOffset(field);
-        if (isVolatile(field)) {
-            return unsafe.getShortVolatile(resolveBase(base, field), offset);
-        } else {
-            return unsafe.getShort(resolveBase(base, field), offset);
-        }
-    }
-
-    public int getFieldInt(Object base, ResolvedJavaField field) {
-        long offset = resolveOffset(field);
-        if (isVolatile(field)) {
-            return unsafe.getIntVolatile(resolveBase(base, field), offset);
-        } else {
-            return unsafe.getInt(resolveBase(base, field), offset);
-        }
-    }
-
-    public long getFieldLong(Object base, ResolvedJavaField field) {
-        long offset = resolveOffset(field);
-        if (isVolatile(field)) {
-            return unsafe.getLongVolatile(resolveBase(base, field), offset);
-        } else {
-            return unsafe.getLong(resolveBase(base, field), offset);
-        }
-    }
-
-    public double getFieldDouble(Object base, ResolvedJavaField field) {
-        long offset = resolveOffset(field);
-        if (isVolatile(field)) {
-            return unsafe.getDoubleVolatile(resolveBase(base, field), offset);
-        } else {
-            return unsafe.getDouble(resolveBase(base, field), offset);
-        }
-    }
-
-    public float getFieldFloat(Object base, ResolvedJavaField field) {
-        long offset = resolveOffset(field);
-        if (isVolatile(field)) {
-            return unsafe.getFloatVolatile(resolveBase(base, field), offset);
-        } else {
-            return unsafe.getFloat(resolveBase(base, field), offset);
-        }
-    }
-
-    public void setFieldObject(Object value, Object base, ResolvedJavaField field) {
-        long offset = resolveOffset(field);
-        if (isVolatile(field)) {
-            unsafe.putObjectVolatile(resolveBase(base, field), offset, value);
-        } else {
-            unsafe.putObject(resolveBase(base, field), offset, value);
-        }
-    }
-
-    public void setFieldInt(int value, Object base, ResolvedJavaField field) {
-        long offset = resolveOffset(field);
-        if (isVolatile(field)) {
-            unsafe.putIntVolatile(resolveBase(base, field), offset, value);
-        } else {
-            unsafe.putInt(resolveBase(base, field), offset, value);
-        }
-    }
-
-    public void setFieldFloat(float value, Object base, ResolvedJavaField field) {
-        long offset = resolveOffset(field);
-        if (isVolatile(field)) {
-            unsafe.putFloatVolatile(resolveBase(base, field), offset, value);
-        } else {
-            unsafe.putFloat(resolveBase(base, field), offset, value);
-        }
-    }
-
-    public void setFieldDouble(double value, Object base, ResolvedJavaField field) {
-        long offset = resolveOffset(field);
-        if (isVolatile(field)) {
-            unsafe.putDoubleVolatile(resolveBase(base, field), offset, value);
-        } else {
-            unsafe.putDouble(resolveBase(base, field), offset, value);
-        }
-    }
-
-    public void setFieldLong(long value, Object base, ResolvedJavaField field) {
-        long offset = resolveOffset(field);
-        if (isVolatile(field)) {
-            unsafe.putDoubleVolatile(resolveBase(base, field), offset, value);
-        } else {
-            unsafe.putDouble(resolveBase(base, field), offset, value);
-        }
-    }
-
-    public byte getArrayByte(long index, Object array) {
-        checkArray(array, index);
-        return unsafe.getByte(array, Unsafe.ARRAY_BYTE_BASE_OFFSET + Unsafe.ARRAY_BYTE_INDEX_SCALE * index);
-    }
-
-    public char getArrayChar(long index, Object array) {
-        checkArray(array, index);
-        return unsafe.getChar(array, Unsafe.ARRAY_CHAR_BASE_OFFSET + Unsafe.ARRAY_CHAR_INDEX_SCALE * index);
-    }
-
-    public short getArrayShort(long index, Object array) {
-        checkArray(array, index);
-        return unsafe.getShort(array, Unsafe.ARRAY_SHORT_BASE_OFFSET + Unsafe.ARRAY_SHORT_INDEX_SCALE * index);
-    }
-
-    public int getArrayInt(long index, Object array) {
-        checkArray(array, index);
-        return unsafe.getInt(array, Unsafe.ARRAY_INT_BASE_OFFSET + Unsafe.ARRAY_INT_INDEX_SCALE * index);
-    }
-
-    public long getArrayLong(long index, Object array) {
-        checkArray(array, index);
-        return unsafe.getLong(array, Unsafe.ARRAY_LONG_BASE_OFFSET + Unsafe.ARRAY_LONG_INDEX_SCALE * index);
-    }
-
-    public double getArrayDouble(long index, Object array) {
-        checkArray(array, index);
-        return unsafe.getDouble(array, Unsafe.ARRAY_DOUBLE_BASE_OFFSET + Unsafe.ARRAY_DOUBLE_INDEX_SCALE * index);
-    }
-
-    public float getArrayFloat(long index, Object array) {
-        checkArray(array, index);
-        return unsafe.getFloat(array, Unsafe.ARRAY_FLOAT_BASE_OFFSET + Unsafe.ARRAY_FLOAT_INDEX_SCALE * index);
-    }
-
-    public Object getArrayObject(long index, Object array) {
-        checkArray(array, index);
-        return unsafe.getObject(array, Unsafe.ARRAY_OBJECT_BASE_OFFSET + Unsafe.ARRAY_OBJECT_INDEX_SCALE * index);
-    }
-
-    public void setArrayByte(byte value, long index, Object array) {
-        checkArray(array, index);
-        if (array instanceof boolean[]) {
-            checkArrayType(array, boolean.class);
-        } else {
-            checkArrayType(array, byte.class);
-        }
-        unsafe.putByte(array, Unsafe.ARRAY_BYTE_BASE_OFFSET + Unsafe.ARRAY_BYTE_INDEX_SCALE * index, value);
-    }
-
-    public void setArrayChar(char value, long index, Object array) {
-        checkArray(array, index);
-        checkArrayType(array, char.class);
-        unsafe.putChar(array, Unsafe.ARRAY_CHAR_BASE_OFFSET + Unsafe.ARRAY_CHAR_INDEX_SCALE * index, value);
-    }
-
-    public void setArrayShort(short value, long index, Object array) {
-        checkArray(array, index);
-        checkArrayType(array, short.class);
-        unsafe.putShort(array, Unsafe.ARRAY_SHORT_BASE_OFFSET + Unsafe.ARRAY_SHORT_INDEX_SCALE * index, value);
-    }
-
-    public void setArrayInt(int value, long index, Object array) {
-        checkArray(array, index);
-        checkArrayType(array, int.class);
-        unsafe.putInt(array, Unsafe.ARRAY_INT_BASE_OFFSET + Unsafe.ARRAY_INT_INDEX_SCALE * index, value);
-    }
-
-    public void setArrayLong(long value, long index, Object array) {
-        checkArray(array, index);
-        checkArrayType(array, long.class);
-        unsafe.putLong(array, Unsafe.ARRAY_LONG_BASE_OFFSET + Unsafe.ARRAY_LONG_INDEX_SCALE * index, value);
-    }
-
-    public void setArrayFloat(float value, long index, Object array) {
-        checkArray(array, index);
-        checkArrayType(array, float.class);
-        unsafe.putFloat(array, Unsafe.ARRAY_FLOAT_BASE_OFFSET + Unsafe.ARRAY_FLOAT_INDEX_SCALE * index, value);
-    }
-
-    public void setArrayDouble(double value, long index, Object array) {
-        checkArray(array, index);
-        checkArrayType(array, double.class);
-        unsafe.putDouble(array, Unsafe.ARRAY_DOUBLE_BASE_OFFSET + Unsafe.ARRAY_DOUBLE_INDEX_SCALE * index, value);
-    }
-
-    public void setArrayObject(Object value, long index, Object array) {
-        checkArray(array, index);
-        checkArrayType(array, value != null ? value.getClass() : null);
-        unsafe.putObject(array, Unsafe.ARRAY_OBJECT_BASE_OFFSET + Unsafe.ARRAY_OBJECT_INDEX_SCALE * index, value);
-    }
-
-    private static void nullCheck(Object value) {
-        if (value == null) {
-            throw new NullPointerException();
-        }
-    }
-
-    private void checkArrayType(Object array, Class<?> arrayType) {
-        if (arrayType == null) {
-            return;
-        }
-        ResolvedJavaType type = metaAccess.lookupJavaType(array.getClass()).getComponentType();
-        if (!getMirror(type).isAssignableFrom(arrayType)) {
-            throw new ArrayStoreException(arrayType.getName());
-        }
-    }
-
-    private void checkArray(Object array, long index) {
-        nullCheck(array);
-        ResolvedJavaType type = metaAccess.lookupJavaType(array.getClass());
-        if (!type.isArray()) {
-            throw new ArrayStoreException(array.getClass().getName());
-        }
-        if (index < 0 || index >= arrayLength(array)) {
-            throw new ArrayIndexOutOfBoundsException((int) index);
-        }
-    }
-
-    private static int arrayLength(Object array) {
-        assert array != null;
-        return Array.getLength(array);
-    }
-
-    private static boolean isVolatile(ResolvedJavaField field) {
-        return Modifier.isVolatile(field.getModifiers());
-    }
-
-    private static long resolveOffset(ResolvedJavaField field) {
-        return ((HotSpotResolvedJavaField) field).offset();
-    }
-
-    private Object resolveBase(Object base, ResolvedJavaField field) {
-        Object accessorBase = base;
-        if (accessorBase == null) {
-            accessorBase = getMirror(field.getDeclaringClass());
-        }
-        return accessorBase;
-    }
-}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java	Wed Mar 05 19:40:15 2014 -0800
@@ -29,6 +29,7 @@
 
 import com.oracle.graal.graph.*;
 import com.oracle.graal.hotspot.bridge.*;
+import com.oracle.graal.hotspot.meta.*;
 
 /**
  * Used to access native configuration details.
@@ -39,12 +40,19 @@
 
     private static final long serialVersionUID = -4744897993263044184L;
 
-    private static boolean containsString(String[] array, String item) {
-        if (array == null) {
-            return false;
+    /**
+     * Determines if the current architecture is included in a given architecture set specification.
+     * 
+     * @param currentArch
+     * @param archsSpecification specifies a set of architectures. A zero length value implies all
+     *            architectures.
+     */
+    private static boolean isRequired(String currentArch, String[] archsSpecification) {
+        if (archsSpecification.length == 0) {
+            return true;
         }
-        for (String arch : array) {
-            if (arch.equals(item)) {
+        for (String arch : archsSpecification) {
+            if (arch.equals(currentArch)) {
                 return true;
             }
         }
@@ -90,7 +98,7 @@
                 String type = annotation.type();
                 VMFields.Field entry = vmFields.get(name);
                 if (entry == null) {
-                    if (annotation.optional() || !containsString(annotation.archs(), currentArch)) {
+                    if (annotation.optional() || !isRequired(currentArch, annotation.archs())) {
                         continue;
                     }
                     throw new IllegalArgumentException("field not found: " + name);
@@ -135,11 +143,10 @@
                 String name = annotation.name();
                 AbstractConstant entry = vmConstants.get(name);
                 if (entry == null) {
-                    if (!containsString(annotation.archs(), currentArch)) {
+                    if (!isRequired(currentArch, annotation.archs())) {
                         continue;
-                    } else {
-                        throw new IllegalArgumentException("constant not found: " + name);
                     }
+                    throw new IllegalArgumentException("constant not found: " + name);
                 }
                 setField(f, entry.getValue());
             } else if (f.isAnnotationPresent(HotSpotVMFlag.class)) {
@@ -147,11 +154,11 @@
                 String name = annotation.name();
                 Flags.Flag entry = flags.get(name);
                 if (entry == null) {
-                    if (annotation.optional() || !containsString(annotation.archs(), currentArch)) {
+                    if (!isRequired(currentArch, annotation.archs())) {
                         continue;
-                    } else {
-                        throw new IllegalArgumentException("flag not found: " + name);
                     }
+                    throw new IllegalArgumentException("flag not found: " + name);
+
                 }
                 setField(f, entry.getValue());
             }
@@ -282,17 +289,17 @@
 
             public String getTypeName() {
                 long typeNameAddress = unsafe.getAddress(entryAddress + gHotSpotVMStructEntryTypeNameOffset);
-                return readCStringAsString(typeNameAddress);
+                return readCString(typeNameAddress);
             }
 
             public String getFieldName() {
                 long fieldNameAddress = unsafe.getAddress(entryAddress + gHotSpotVMStructEntryFieldNameOffset);
-                return readCStringAsString(fieldNameAddress);
+                return readCString(fieldNameAddress);
             }
 
             public String getTypeString() {
                 long typeStringAddress = unsafe.getAddress(entryAddress + gHotSpotVMStructEntryTypeStringOffset);
-                return readCStringAsString(typeStringAddress);
+                return readCString(typeStringAddress);
             }
 
             public boolean isStatic() {
@@ -398,12 +405,12 @@
 
             public String getTypeName() {
                 long typeNameAddress = unsafe.getAddress(entryAddress + gHotSpotVMTypeEntryTypeNameOffset);
-                return readCStringAsString(typeNameAddress);
+                return readCString(typeNameAddress);
             }
 
             public String getSuperclassName() {
                 long superclassNameAddress = unsafe.getAddress(entryAddress + gHotSpotVMTypeEntrySuperclassNameOffset);
-                return readCStringAsString(superclassNameAddress);
+                return readCString(superclassNameAddress);
             }
 
             public boolean isOopType() {
@@ -444,7 +451,7 @@
 
         public String getName() {
             long nameAddress = unsafe.getAddress(address + nameOffset);
-            return readCStringAsString(nameAddress);
+            return readCString(nameAddress);
         }
 
         public abstract long getValue();
@@ -639,12 +646,12 @@
 
             public String getType() {
                 long typeAddress = unsafe.getAddress(entryAddress + typeOffset);
-                return readCStringAsString(typeAddress);
+                return readCString(typeAddress);
             }
 
             public String getName() {
                 long nameAddress = unsafe.getAddress(entryAddress + nameOffset);
-                return readCStringAsString(nameAddress);
+                return readCString(nameAddress);
             }
 
             public long getAddr() {
@@ -663,7 +670,7 @@
                         return Double.valueOf(unsafe.getDouble(getAddr()));
                     case "ccstr":
                     case "ccstrlist":
-                        return readCStringAsString(getAddr());
+                        return readCString(getAddr());
                     default:
                         throw GraalInternalError.shouldNotReachHere(getType());
                 }
@@ -676,24 +683,6 @@
         }
     }
 
-    /**
-     * Read a null-terminated C string from memory and convert it to a Java String.
-     */
-    private static String readCStringAsString(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();
-    }
-
     // os information, register layout, code generation, ...
     @HotSpotVMConstant(name = "ASSERT") @Stable public boolean cAssertions;
     public final boolean windowsOs = System.getProperty("os.name", "").startsWith("Windows");
@@ -701,7 +690,7 @@
     @HotSpotVMFlag(name = "CodeEntryAlignment") @Stable public int codeEntryAlignment;
     @HotSpotVMFlag(name = "VerifyOops") @Stable public boolean verifyOops;
     @HotSpotVMFlag(name = "CITime") @Stable public boolean ciTime;
-    @HotSpotVMFlag(name = "CITimeEach", optional = true) @Stable public boolean ciTimeEach;
+    @HotSpotVMFlag(name = "CITimeEach") @Stable public boolean ciTimeEach;
     @HotSpotVMFlag(name = "CompileThreshold") @Stable public long compileThreshold;
     @HotSpotVMFlag(name = "CompileTheWorld") @Stable public boolean compileTheWorld;
     @HotSpotVMFlag(name = "CompileTheWorldStartAt") @Stable public int compileTheWorldStartAt;
@@ -712,11 +701,12 @@
     @HotSpotVMFlag(name = "PrintInlining") @Stable public boolean printInlining;
     @HotSpotVMFlag(name = "GraalUseFastLocking") @Stable public boolean useFastLocking;
     @HotSpotVMFlag(name = "ForceUnreachable") @Stable public boolean forceUnreachable;
+    @HotSpotVMFlag(name = "GPUOffload") @Stable public boolean gpuOffload;
 
     @HotSpotVMFlag(name = "UseTLAB") @Stable public boolean useTLAB;
     @HotSpotVMFlag(name = "UseBiasedLocking") @Stable public boolean useBiasedLocking;
     @HotSpotVMFlag(name = "UsePopCountInstruction") @Stable public boolean usePopCountInstruction;
-    @HotSpotVMFlag(name = "UseCountLeadingZerosInstruction", optional = true) @Stable public boolean useCountLeadingZerosInstruction;
+    @HotSpotVMFlag(name = "UseCountLeadingZerosInstruction", archs = {"amd64"}) @Stable public boolean useCountLeadingZerosInstruction;
     @HotSpotVMFlag(name = "UseAESIntrinsics") @Stable public boolean useAESIntrinsics;
     @HotSpotVMFlag(name = "UseCRC32Intrinsics") @Stable public boolean useCRC32Intrinsics;
     @HotSpotVMFlag(name = "UseG1GC") @Stable public boolean useG1GC;
@@ -798,6 +788,43 @@
     @HotSpotVMField(name = "Klass::_secondary_super_cache", type = "Klass*", get = HotSpotVMField.Type.OFFSET) @Stable public int secondarySuperCacheOffset;
     @HotSpotVMField(name = "Klass::_secondary_supers", type = "Array<Klass*>*", get = HotSpotVMField.Type.OFFSET) @Stable public int secondarySupersOffset;
 
+    /**
+     * The offset of the _java_mirror field (of type {@link Class}) in a Klass.
+     */
+    @HotSpotVMField(name = "Klass::_java_mirror", type = "oop", get = HotSpotVMField.Type.OFFSET) @Stable public int classMirrorOffset;
+
+    @HotSpotVMField(name = "Klass::_super", type = "Klass*", get = HotSpotVMField.Type.OFFSET) @Stable public int klassSuperKlassOffset;
+    @HotSpotVMField(name = "Klass::_modifier_flags", type = "jint", get = HotSpotVMField.Type.OFFSET) @Stable public int klassModifierFlagsOffset;
+    @HotSpotVMField(name = "Klass::_access_flags", type = "AccessFlags", get = HotSpotVMField.Type.OFFSET) @Stable public int klassAccessFlagsOffset;
+    @HotSpotVMField(name = "Klass::_layout_helper", type = "jint", get = HotSpotVMField.Type.OFFSET) @Stable public int klassLayoutHelperOffset;
+    @HotSpotVMField(name = "Klass::_layout_helper", type = "jint", get = HotSpotVMField.Type.OFFSET) @Stable public int klassInstanceSizeOffset;
+
+    @HotSpotVMConstant(name = "Klass::_lh_neutral_value") @Stable public int klassLayoutHelperNeutralValue;
+    @HotSpotVMConstant(name = "Klass::_lh_instance_slow_path_bit") @Stable public int klassLayoutHelperInstanceSlowPathBit;
+    @HotSpotVMConstant(name = "Klass::_lh_log2_element_size_shift") @Stable public int layoutHelperLog2ElementSizeShift;
+    @HotSpotVMConstant(name = "Klass::_lh_log2_element_size_mask") @Stable public int layoutHelperLog2ElementSizeMask;
+    @HotSpotVMConstant(name = "Klass::_lh_element_type_shift") @Stable public int layoutHelperElementTypeShift;
+    @HotSpotVMConstant(name = "Klass::_lh_element_type_mask") @Stable public int layoutHelperElementTypeMask;
+    @HotSpotVMConstant(name = "Klass::_lh_header_size_shift") @Stable public int layoutHelperHeaderSizeShift;
+    @HotSpotVMConstant(name = "Klass::_lh_header_size_mask") @Stable public int layoutHelperHeaderSizeMask;
+    @HotSpotVMConstant(name = "Klass::_lh_array_tag_shift") @Stable public int layoutHelperArrayTagShift;
+    @HotSpotVMConstant(name = "Klass::_lh_array_tag_type_value") @Stable public int layoutHelperArrayTagTypeValue;
+    @HotSpotVMConstant(name = "Klass::_lh_array_tag_obj_value") @Stable public int layoutHelperArrayTagObjectValue;
+
+    /**
+     * This filters out the bit that differentiates a type array from an object array.
+     */
+    public int layoutHelperElementTypePrimitiveInPlace() {
+        return (layoutHelperArrayTagTypeValue & ~layoutHelperArrayTagObjectValue) << layoutHelperArrayTagShift;
+    }
+
+    /**
+     * Bit pattern in the klass layout helper that can be used to identify arrays.
+     */
+    public final int arrayKlassLayoutHelperIdentifier = 0x80000000;
+
+    @HotSpotVMField(name = "ArrayKlass::_component_mirror", type = "oop", get = HotSpotVMField.Type.OFFSET) @Stable public int arrayKlassComponentMirrorOffset;
+
     @HotSpotVMType(name = "vtableEntry", get = HotSpotVMType.Type.SIZE) @Stable public int vtableEntrySize;
     @HotSpotVMField(name = "vtableEntry::_method", type = "Method*", get = HotSpotVMField.Type.OFFSET) @Stable public int vtableEntryMethodOffset;
     @Stable public int instanceKlassVtableStartOffset;
@@ -809,18 +836,34 @@
 
     @HotSpotVMField(name = "Array<int>::_length", type = "int", get = HotSpotVMField.Type.OFFSET) @Stable public int arrayU1LengthOffset;
     @HotSpotVMField(name = "Array<u1>::_data", type = "", get = HotSpotVMField.Type.OFFSET) @Stable public int arrayU1DataOffset;
+    @HotSpotVMField(name = "Array<u2>::_data", type = "", get = HotSpotVMField.Type.OFFSET) @Stable public int arrayU2DataOffset;
     @HotSpotVMField(name = "Array<Klass*>::_length", type = "int", get = HotSpotVMField.Type.OFFSET) @Stable public int metaspaceArrayLengthOffset;
     @HotSpotVMField(name = "Array<Klass*>::_data[0]", type = "Klass*", get = HotSpotVMField.Type.OFFSET) @Stable public int metaspaceArrayBaseOffset;
 
     @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;
+    @HotSpotVMField(name = "InstanceKlass::_fields", type = "Array<u2>*", get = HotSpotVMField.Type.OFFSET) @Stable public int instanceKlassFieldsOffset;
 
     @HotSpotVMConstant(name = "InstanceKlass::linked") @Stable public int klassStateLinked;
     @HotSpotVMConstant(name = "InstanceKlass::fully_initialized") @Stable public int klassStateFullyInitialized;
 
     @HotSpotVMField(name = "ObjArrayKlass::_element_klass", type = "Klass*", get = HotSpotVMField.Type.OFFSET) @Stable public int arrayClassElementOffset;
 
+    @HotSpotVMConstant(name = "FieldInfo::access_flags_offset") @Stable public int fieldInfoAccessFlagsOffset;
+    @HotSpotVMConstant(name = "FieldInfo::name_index_offset") @Stable public int fieldInfoNameIndexOffset;
+    @HotSpotVMConstant(name = "FieldInfo::signature_index_offset") @Stable public int fieldInfoSignatureIndexOffset;
+    @HotSpotVMConstant(name = "FieldInfo::initval_index_offset") @Stable public int fieldInfoInitvalIndexOffset;
+    @HotSpotVMConstant(name = "FieldInfo::low_packed_offset") @Stable public int fieldInfoLowPackedOffset;
+    @HotSpotVMConstant(name = "FieldInfo::high_packed_offset") @Stable public int fieldInfoHighPackedOffset;
+    @HotSpotVMConstant(name = "FieldInfo::field_slots") @Stable public int fieldInfoFieldSlots;
+
+    @HotSpotVMConstant(name = "FIELDINFO_TAG_SIZE") @Stable public int fieldInfoTagSize;
+
+    @HotSpotVMConstant(name = "JVM_ACC_FIELD_INTERNAL") @Stable public int jvmAccFieldInternal;
+    @HotSpotVMConstant(name = "JVM_ACC_FIELD_STABLE") @Stable public int jvmAccFieldStable;
+    @HotSpotVMConstant(name = "JVM_ACC_FIELD_HAS_GENERIC_SIGNATURE") @Stable public int jvmAccFieldHasGenericSignature;
+
     @HotSpotVMField(name = "Thread::_tlab", type = "ThreadLocalAllocBuffer", get = HotSpotVMField.Type.OFFSET) @Stable public int threadTlabOffset;
 
     @HotSpotVMField(name = "JavaThread::_anchor", type = "JavaFrameAnchor", get = HotSpotVMField.Type.OFFSET) @Stable public int javaThreadAnchorOffset;
@@ -832,7 +875,36 @@
     @HotSpotVMField(name = "JavaThread::_vm_result", type = "oop", get = HotSpotVMField.Type.OFFSET) @Stable public int threadObjectResultOffset;
     @HotSpotVMField(name = "JavaThread::_graal_counters[0]", type = "jlong", get = HotSpotVMField.Type.OFFSET, optional = true) @Stable public int graalCountersThreadOffset;
 
-    @HotSpotVMConstant(name = "GRAAL_COUNTERS_SIZE") @Stable public int graalCountersSize;
+    /**
+     * An invalid value for {@link #rtldDefault}.
+     */
+    public static final long INVALID_RTLD_DEFAULT_HANDLE = 0xDEADFACE;
+
+    /**
+     * Address of the library lookup routine. The C signature of this routine is:
+     * 
+     * <pre>
+     *     void* (const char *filename, char *ebuf, int ebuflen)
+     * </pre>
+     */
+    @Stable public long dllLoad;
+
+    /**
+     * Address of the library lookup routine. The C signature of this routine is:
+     * 
+     * <pre>
+     *     void* (void* handle, const char* name)
+     * </pre>
+     */
+    @Stable public long dllLookup;
+
+    /**
+     * A pseudo-handle which when used as the first argument to {@link #dllLookup} means lookup will
+     * return the first occurrence of the desired symbol using the default library search order. If
+     * this field is {@value #INVALID_RTLD_DEFAULT_HANDLE}, then this capability is not supported on
+     * the current platform.
+     */
+    @Stable public long rtldDefault = INVALID_RTLD_DEFAULT_HANDLE;
 
     /**
      * This field is used to pass exception objects into and out of the runtime system during
@@ -872,6 +944,8 @@
         return javaThreadAnchorOffset + javaFrameAnchorFlagsOffset;
     }
 
+    @HotSpotVMConstant(name = "frame::arg_reg_save_area_bytes", archs = {"amd64"}) @Stable public int runtimeCallStackSize;
+
     @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;
     @HotSpotVMField(name = "PtrQueue::_index", type = "size_t", get = HotSpotVMField.Type.OFFSET) @Stable public int ptrQueueIndexOffset;
@@ -971,6 +1045,8 @@
     @HotSpotVMField(name = "ConstantPool::_pool_holder", type = "InstanceKlass*", get = HotSpotVMField.Type.OFFSET) @Stable public int constantPoolHolderOffset;
     @HotSpotVMField(name = "ConstantPool::_length", type = "int", get = HotSpotVMField.Type.OFFSET) @Stable public int constantPoolLengthOffset;
 
+    @HotSpotVMConstant(name = "ConstantPool::CPCACHE_INDEX_TAG") @Stable public int constantPoolCpCacheIndexTag;
+
     @HotSpotVMConstant(name = "JVM_CONSTANT_Utf8") @Stable public int jvmConstantUtf8;
     @HotSpotVMConstant(name = "JVM_CONSTANT_Integer") @Stable public int jvmConstantInteger;
     @HotSpotVMConstant(name = "JVM_CONSTANT_Long") @Stable public int jvmConstantLong;
@@ -989,11 +1065,26 @@
     @HotSpotVMConstant(name = "JVM_CONSTANT_MethodType") @Stable public int jvmConstantMethodType;
     @HotSpotVMConstant(name = "JVM_CONSTANT_MethodTypeInError") @Stable public int jvmConstantMethodTypeInError;
 
+    @HotSpotVMConstant(name = "HeapWordSize") @Stable public int heapWordSize;
+
+    @HotSpotVMType(name = "Symbol*", get = HotSpotVMType.Type.SIZE) @Stable public int symbolPointerSize;
     @HotSpotVMField(name = "Symbol::_length", type = "unsigned short", get = HotSpotVMField.Type.OFFSET) @Stable public int symbolLengthOffset;
     @HotSpotVMField(name = "Symbol::_body[0]", type = "jbyte", get = HotSpotVMField.Type.OFFSET) @Stable public int symbolBodyOffset;
 
+    @HotSpotVMField(name = "vmSymbols::_symbols[0]", type = "Symbol*", get = HotSpotVMField.Type.ADDRESS) @Stable public long vmSymbolsSymbols;
+    @HotSpotVMConstant(name = "vmSymbols::FIRST_SID") @Stable public int vmSymbolsFirstSID;
+    @HotSpotVMConstant(name = "vmSymbols::SID_LIMIT") @Stable public int vmSymbolsSIDLimit;
+
     @HotSpotVMConstant(name = "JVM_ACC_HAS_FINALIZER") @Stable public int klassHasFinalizerFlag;
 
+    // Modifier.SYNTHETIC is not public so we get it via vmStructs.
+    @HotSpotVMConstant(name = "JVM_ACC_SYNTHETIC") @Stable public int syntheticFlag;
+
+    /**
+     * @see HotSpotResolvedObjectType#createField
+     */
+    @HotSpotVMConstant(name = "JVM_RECOGNIZED_FIELD_MODIFIERS") @Stable public int recognizedFieldModifiers;
+
     /**
      * Bit pattern that represents a non-oop. Neither the high bits nor the low bits of this value
      * are allowed to look like (respectively) the high or low bits of a real oop.
@@ -1071,40 +1162,6 @@
         return javaThreadSatbMarkQueueOffset + ptrQueueBufferOffset;
     }
 
-    /**
-     * The offset of the _java_mirror field (of type {@link Class}) in a Klass.
-     */
-    @HotSpotVMField(name = "Klass::_java_mirror", type = "oop", get = HotSpotVMField.Type.OFFSET) @Stable public int classMirrorOffset;
-
-    @HotSpotVMConstant(name = "frame::arg_reg_save_area_bytes", archs = {"amd64"}) @Stable public int runtimeCallStackSize;
-
-    @HotSpotVMField(name = "Klass::_super", type = "Klass*", get = HotSpotVMField.Type.OFFSET) @Stable public int klassSuperKlassOffset;
-    @HotSpotVMField(name = "Klass::_modifier_flags", type = "jint", get = HotSpotVMField.Type.OFFSET) @Stable public int klassModifierFlagsOffset;
-    @HotSpotVMField(name = "Klass::_access_flags", type = "AccessFlags", get = HotSpotVMField.Type.OFFSET) @Stable public int klassAccessFlagsOffset;
-    @HotSpotVMField(name = "Klass::_layout_helper", type = "jint", get = HotSpotVMField.Type.OFFSET) @Stable public int klassLayoutHelperOffset;
-    @HotSpotVMField(name = "Klass::_layout_helper", type = "jint", get = HotSpotVMField.Type.OFFSET) @Stable public int klassInstanceSizeOffset;
-
-    @HotSpotVMConstant(name = "Klass::_lh_neutral_value") @Stable public int klassLayoutHelperNeutralValue;
-    @HotSpotVMConstant(name = "Klass::_lh_instance_slow_path_bit") @Stable public int klassLayoutHelperInstanceSlowPathBit;
-    @HotSpotVMConstant(name = "Klass::_lh_log2_element_size_shift") @Stable public int layoutHelperLog2ElementSizeShift;
-    @HotSpotVMConstant(name = "Klass::_lh_log2_element_size_mask") @Stable public int layoutHelperLog2ElementSizeMask;
-    @HotSpotVMConstant(name = "Klass::_lh_element_type_shift") @Stable public int layoutHelperElementTypeShift;
-    @HotSpotVMConstant(name = "Klass::_lh_element_type_mask") @Stable public int layoutHelperElementTypeMask;
-    @HotSpotVMConstant(name = "Klass::_lh_header_size_shift") @Stable public int layoutHelperHeaderSizeShift;
-    @HotSpotVMConstant(name = "Klass::_lh_header_size_mask") @Stable public int layoutHelperHeaderSizeMask;
-    @HotSpotVMConstant(name = "Klass::_lh_array_tag_shift") @Stable public int layoutHelperArrayTagShift;
-    @HotSpotVMConstant(name = "Klass::_lh_array_tag_type_value") @Stable public int layoutHelperArrayTagTypeValue;
-    @HotSpotVMConstant(name = "Klass::_lh_array_tag_obj_value") @Stable public int layoutHelperArrayTagObjectValue;
-
-    /**
-     * This filters out the bit that differentiates a type array from an object array.
-     */
-    public int layoutHelperElementTypePrimitiveInPlace() {
-        return (layoutHelperArrayTagTypeValue & ~layoutHelperArrayTagObjectValue) << layoutHelperArrayTagShift;
-    }
-
-    @HotSpotVMField(name = "ArrayKlass::_component_mirror", type = "oop", get = HotSpotVMField.Type.OFFSET) @Stable public int arrayKlassComponentMirrorOffset;
-
     @HotSpotVMField(name = "java_lang_Class::_klass_offset", type = "int", get = HotSpotVMField.Type.VALUE) @Stable public int klassOffset;
     @HotSpotVMField(name = "java_lang_Class::_array_klass_offset", type = "int", get = HotSpotVMField.Type.VALUE) @Stable public int arrayKlassOffset;
 
@@ -1237,6 +1294,35 @@
     @HotSpotVMField(name = "StubRoutines::_updateBytesCRC32", type = "address", get = HotSpotVMField.Type.VALUE) @Stable public long updateBytesCRC32Stub;
     @HotSpotVMField(name = "StubRoutines::_crc_table_adr", type = "address", get = HotSpotVMField.Type.VALUE) @Stable public long crcTableAddress;
 
+    @HotSpotVMField(name = "StubRoutines::_jbyte_arraycopy", type = "address", get = HotSpotVMField.Type.VALUE) @Stable public long jbyteArraycopy;
+    @HotSpotVMField(name = "StubRoutines::_jshort_arraycopy", type = "address", get = HotSpotVMField.Type.VALUE) @Stable public long jshortArraycopy;
+    @HotSpotVMField(name = "StubRoutines::_jint_arraycopy", type = "address", get = HotSpotVMField.Type.VALUE) @Stable public long jintArraycopy;
+    @HotSpotVMField(name = "StubRoutines::_jlong_arraycopy", type = "address", get = HotSpotVMField.Type.VALUE) @Stable public long jlongArraycopy;
+    @HotSpotVMField(name = "StubRoutines::_oop_arraycopy", type = "address", get = HotSpotVMField.Type.VALUE) @Stable public long oopArraycopy;
+    @HotSpotVMField(name = "StubRoutines::_oop_arraycopy_uninit", type = "address", get = HotSpotVMField.Type.VALUE) @Stable public long oopArraycopyUninit;
+    @HotSpotVMField(name = "StubRoutines::_jbyte_disjoint_arraycopy", type = "address", get = HotSpotVMField.Type.VALUE) @Stable public long jbyteDisjointArraycopy;
+    @HotSpotVMField(name = "StubRoutines::_jshort_disjoint_arraycopy", type = "address", get = HotSpotVMField.Type.VALUE) @Stable public long jshortDisjointArraycopy;
+    @HotSpotVMField(name = "StubRoutines::_jint_disjoint_arraycopy", type = "address", get = HotSpotVMField.Type.VALUE) @Stable public long jintDisjointArraycopy;
+    @HotSpotVMField(name = "StubRoutines::_jlong_disjoint_arraycopy", type = "address", get = HotSpotVMField.Type.VALUE) @Stable public long jlongDisjointArraycopy;
+    @HotSpotVMField(name = "StubRoutines::_oop_disjoint_arraycopy", type = "address", get = HotSpotVMField.Type.VALUE) @Stable public long oopDisjointArraycopy;
+    @HotSpotVMField(name = "StubRoutines::_oop_disjoint_arraycopy_uninit", type = "address", get = HotSpotVMField.Type.VALUE) @Stable public long oopDisjointArraycopyUninit;
+    @HotSpotVMField(name = "StubRoutines::_arrayof_jbyte_arraycopy", type = "address", get = HotSpotVMField.Type.VALUE) @Stable public long jbyteAlignedArraycopy;
+    @HotSpotVMField(name = "StubRoutines::_arrayof_jshort_arraycopy", type = "address", get = HotSpotVMField.Type.VALUE) @Stable public long jshortAlignedArraycopy;
+    @HotSpotVMField(name = "StubRoutines::_arrayof_jint_arraycopy", type = "address", get = HotSpotVMField.Type.VALUE) @Stable public long jintAlignedArraycopy;
+    @HotSpotVMField(name = "StubRoutines::_arrayof_jlong_arraycopy", type = "address", get = HotSpotVMField.Type.VALUE) @Stable public long jlongAlignedArraycopy;
+    @HotSpotVMField(name = "StubRoutines::_arrayof_oop_arraycopy", type = "address", get = HotSpotVMField.Type.VALUE) @Stable public long alignedOopAlignedArraycopy;
+    @HotSpotVMField(name = "StubRoutines::_arrayof_oop_arraycopy_uninit", type = "address", get = HotSpotVMField.Type.VALUE) @Stable public long alignedOopArraycopyUninit;
+    @HotSpotVMField(name = "StubRoutines::_arrayof_jbyte_disjoint_arraycopy", type = "address", get = HotSpotVMField.Type.VALUE) @Stable public long jbyteAlignedDisjointArraycopy;
+    @HotSpotVMField(name = "StubRoutines::_arrayof_jshort_disjoint_arraycopy", type = "address", get = HotSpotVMField.Type.VALUE) @Stable public long jshortAlignedDisjointArraycopy;
+    @HotSpotVMField(name = "StubRoutines::_arrayof_jint_disjoint_arraycopy", type = "address", get = HotSpotVMField.Type.VALUE) @Stable public long jintAlignedDisjointArraycopy;
+    @HotSpotVMField(name = "StubRoutines::_arrayof_jlong_disjoint_arraycopy", type = "address", get = HotSpotVMField.Type.VALUE) @Stable public long jlongAlignedDisjointArraycopy;
+    @HotSpotVMField(name = "StubRoutines::_arrayof_oop_disjoint_arraycopy", type = "address", get = HotSpotVMField.Type.VALUE) @Stable public long alignedOopDisjointArraycopy;
+    @HotSpotVMField(name = "StubRoutines::_arrayof_oop_disjoint_arraycopy_uninit", type = "address", get = HotSpotVMField.Type.VALUE) @Stable public long alignedOopDisjointArraycopyUninit;
+    @HotSpotVMField(name = "StubRoutines::_checkcast_arraycopy", type = "address", get = HotSpotVMField.Type.VALUE) @Stable public long checkcastArraycopy;
+    @HotSpotVMField(name = "StubRoutines::_checkcast_arraycopy_uninit", type = "address", get = HotSpotVMField.Type.VALUE) @Stable public long checkcastArraycopyUninit;
+    @HotSpotVMField(name = "StubRoutines::_unsafe_arraycopy", type = "address", get = HotSpotVMField.Type.VALUE) @Stable public long unsafeArraycopy;
+    @HotSpotVMField(name = "StubRoutines::_generic_arraycopy", type = "address", get = HotSpotVMField.Type.VALUE) @Stable public long genericArraycopy;
+
     @Stable public long newInstanceAddress;
     @Stable public long newArrayAddress;
     @Stable public long newMultiArrayAddress;
@@ -1267,6 +1353,8 @@
     @Stable public long arithmeticTanAddress;
     @Stable public long loadAndClearExceptionAddress;
 
+    @Stable public int graalCountersSize;
+
     @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;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConstant.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConstant.java	Wed Mar 05 19:40:15 2014 -0800
@@ -32,7 +32,8 @@
 
     /**
      * List of architectures where this constant is required. Names are derived from
-     * {@link HotSpotVMConfig#getHostArchitectureName()}.
+     * {@link HotSpotVMConfig#getHostArchitectureName()}. An empty list implies that the constant is
+     * required on all architectures.
      */
     String[] archs() default {};
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMField.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMField.java	Wed Mar 05 19:40:15 2014 -0800
@@ -40,7 +40,8 @@
 
     /**
      * List of architectures where this constant is required. Names are derived from
-     * {@link HotSpotVMConfig#getHostArchitectureName()}.
+     * {@link HotSpotVMConfig#getHostArchitectureName()}. An empty list implies that the constant is
+     * required on all architectures.
      */
     String[] archs() default {};
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMFlag.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMFlag.java	Wed Mar 05 19:40:15 2014 -0800
@@ -32,9 +32,8 @@
 
     /**
      * List of architectures where this constant is required. Names are derived from
-     * {@link HotSpotVMConfig#getHostArchitectureName()}.
+     * {@link HotSpotVMConfig#getHostArchitectureName()}. An empty list implies that the constant is
+     * required on all architectures.
      */
     String[] archs() default {};
-
-    boolean optional() default false;
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVmSymbols.java	Wed Mar 05 19:40:15 2014 -0800
@@ -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.hotspot;
+
+import static com.oracle.graal.graph.UnsafeAccess.*;
+import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
+import sun.misc.*;
+
+/**
+ * Class to access the C++ {@code vmSymbols} table.
+ */
+public final class HotSpotVmSymbols {
+
+    /**
+     * Returns the {@link HotSpotSymbol} in the {@code vmSymbols} table at position {@code index} as
+     * {@link String}.
+     * 
+     * @param index position in the symbol table
+     * @return the symbol at position id
+     */
+    public static String symbolAt(int index) {
+        HotSpotVMConfig config = runtime().getConfig();
+        assert config.vmSymbolsFirstSID <= index && index < config.vmSymbolsSIDLimit : "index " + index + " is out of bounds";
+        assert config.symbolPointerSize == Unsafe.ADDRESS_SIZE : "the following address read is broken";
+        final long metaspaceSymbol = unsafe.getAddress(config.vmSymbolsSymbols + index * config.symbolPointerSize);
+        return new HotSpotSymbol(metaspaceSymbol).asString();
+    }
+}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToGPU.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,66 +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.api.code.InvalidInstalledCodeException;
-import com.oracle.graal.hotspot.meta.HotSpotInstalledCode;
-
-/**
- * Calls from Java into the GPU.
- */
-public interface CompilerToGPU {
-
-    /**
-     * Attempts to initialize and create a valid context with the GPU.
-     * 
-     * @return whether the GPU context has been initialized and is valid.
-     */
-    boolean deviceInit();
-
-    /**
-     * Attempts to detach from a valid GPU context.
-     * 
-     * @return whether the GPU context has been properly disposed.
-     */
-    boolean deviceDetach();
-
-    int availableProcessors();
-
-    /**
-     * Attempts to generate and return a bound function to the loaded method kernel on the GPU.
-     * 
-     * @param code the text or binary values for a method kernel
-     * @return the value of the bound kernel in GPU space.
-     */
-    long generateKernel(byte[] code, String name) throws InvalidInstalledCodeException;
-
-    Object executeExternalMethodVarargs(Object[] args, HotSpotInstalledCode hotspotInstalledCode) throws InvalidInstalledCodeException;
-
-    Object executeParallelMethodVarargs(int dimX, int dimY, int dimZ, Object[] args, HotSpotInstalledCode hotspotInstalledCode) throws InvalidInstalledCodeException;
-
-    /**
-     * Gets the address of the runtime function for launching a kernel function.
-     */
-    long getLaunchKernelAddress();
-}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToGPUImpl.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,47 +0,0 @@
-/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.oracle.graal.hotspot.bridge;
-
-import com.oracle.graal.api.code.InvalidInstalledCodeException;
-import com.oracle.graal.hotspot.meta.HotSpotInstalledCode;
-
-/**
- * Entries into the HotSpot GPU interface from Java code.
- */
-public class CompilerToGPUImpl implements CompilerToGPU {
-
-    public native boolean deviceInit();
-
-    public native long generateKernel(byte[] code, String name) throws InvalidInstalledCodeException;
-
-    public native boolean deviceDetach();
-
-    public native int availableProcessors();
-
-    public native Object executeExternalMethodVarargs(Object[] args, HotSpotInstalledCode hotspotInstalledCode) throws InvalidInstalledCodeException;
-
-    public native Object executeParallelMethodVarargs(int dimX, int dimY, int dimZ, Object[] args, HotSpotInstalledCode hotspotInstalledCode) throws InvalidInstalledCodeException;
-
-    public native long getLaunchKernelAddress();
-}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java	Wed Mar 05 19:40:15 2014 -0800
@@ -54,20 +54,30 @@
     boolean hasBalancedMonitors(long metaspaceMethod);
 
     /**
-     * Determines if a given metaspace Method object is compilable. A method may not be compilable
-     * for a number of reasons such as:
+     * Determines if a given metaspace Method can be inlined. A method may not be inlinable for a
+     * number of reasons such as:
      * <ul>
-     * <li>a CompileOracle directive may prevent compilation of methods</li>
+     * <li>a CompileOracle directive may prevent inlining or compilation of this methods</li>
      * <li>the method may have a bytecode breakpoint set</li>
      * <li>the method may have other bytecode features that require special handling by the VM</li>
      * </ul>
      * 
-     * A non-compilable method should not be inlined.
+     * @param metaspaceMethod the metaspace Method object to query
+     * @return true if the method can be inlined
+     */
+    boolean canInlineMethod(long metaspaceMethod);
+
+    /**
+     * Determines if a given metaspace Method should be inlined at any cost. This could be because:
+     * <ul>
+     * <li>a CompileOracle directive may forces inlining of this methods</li>
+     * <li>an annotation forces inlining of this method</li>
+     * </ul>
      * 
      * @param metaspaceMethod the metaspace Method object to query
-     * @return true if the method is compilable
+     * @return true if the method should be inlined
      */
-    boolean isMethodCompilable(long metaspaceMethod);
+    boolean shouldInlineMethod(long metaspaceMethod);
 
     /**
      * Used to implement {@link ResolvedJavaType#findUniqueConcreteMethod(ResolvedJavaMethod)}.
@@ -108,15 +118,58 @@
 
     Object lookupConstantInPool(long metaspaceConstantPool, int cpi);
 
-    JavaMethod lookupMethodInPool(long metaspaceConstantPool, int cpi, byte opcode);
-
-    JavaType lookupTypeInPool(long metaspaceConstantPool, int cpi);
+    /**
+     * Looks up a method entry in a constant pool. If the method is resolved, then
+     * {@code unresolvedInfo} is unmodified. Otherwise, it contains these values:
+     * 
+     * <pre>
+     *     [(Symbol*) name,
+     *      (Symbol*) signature,
+     *      (Symbol*) holderName, // only non-zero if holder == 0
+     *      (Klass*)  holder]
+     * </pre>
+     * 
+     * @param metaspaceConstantPool
+     * @param unresolvedInfo an array in which the details for an unresolved method are returned
+     * @return a metaspace Method for a resolved method entry otherwise 0 in which case the values
+     *         returned in {@code unresolvedInfo} should be consulted
+     */
+    long lookupMethodInPool(long metaspaceConstantPool, int cpi, byte opcode, long[] unresolvedInfo);
 
-    JavaField lookupFieldInPool(long metaspaceConstantPool, int cpi, byte opcode);
+    /**
+     * Looks up a class entry in a constant pool.
+     * 
+     * @param metaspaceConstantPool
+     * @param unresolvedTypeName a 1 element array in which the name of the class is returned if
+     *            this method returns 0
+     * @return a metaspace Klass for a resolved method entry otherwise 0 in which case the value
+     *         returned in {@code unresolvedTypeName} should be consulted
+     */
+    long lookupTypeInPool(long metaspaceConstantPool, int cpi, long[] unresolvedTypeName);
 
-    void lookupReferencedTypeInPool(long metaspaceConstantPool, int cpi, byte opcode);
+    /**
+     * Looks up a field entry in a constant pool and attempts to resolve it. The values returned in
+     * {@code info} are:
+     * 
+     * <pre>
+     *     [(Symbol*) name,
+     *      (Symbol*) typeName,   // only non-zero if type == 0
+     *      (Klass*)  type,
+     *      (Symbol*) holderName, // only non-zero if holder == 0
+     *      (Klass*)  holder,
+     *      (int)     flags,      // only valid if field is resolved
+     *      (int)     offset]     // only valid if field is resolved
+     * </pre>
+     * 
+     * @param metaspaceConstantPool
+     * @param info an array in which the details of the field are returned
+     * @return true if the field is resolved
+     */
+    boolean lookupFieldInPool(long metaspaceConstantPool, int cpi, byte opcode, long[] info);
 
-    Object lookupAppendixInPool(long metaspaceConstantPool, int cpi, byte opcode);
+    void loadReferencedTypeInPool(long metaspaceConstantPool, int cpi, byte opcode);
+
+    Object lookupAppendixInPool(long metaspaceConstantPool, int cpi);
 
     public enum CodeInstallResult {
         OK("ok"), DEPENDENCIES_FAILED("dependencies failed"), CACHE_FULL("code cache is full"), CODE_TOO_LARGE("code is too large");
@@ -194,8 +247,6 @@
 
     long resolveMethod(HotSpotResolvedObjectType klass, String name, String signature);
 
-    HotSpotResolvedJavaField[] getInstanceFields(HotSpotResolvedObjectType klass);
-
     long getClassInitializer(HotSpotResolvedObjectType klass);
 
     boolean hasFinalizableSubclass(HotSpotResolvedObjectType klass);
@@ -258,8 +309,17 @@
      */
     long[] collectCounters();
 
+    boolean isMature(long metaspaceMethodData);
+
     /**
      * Generate a unique id to identify the result of the compile.
      */
     int allocateCompileId(HotSpotResolvedJavaMethod method, int entryBCI);
+
+    /**
+     * Gets the names of the supported GPU architectures.
+     * 
+     * @return a comma separated list of names
+     */
+    String getGPUs();
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java	Wed Mar 05 19:40:15 2014 -0800
@@ -24,7 +24,6 @@
 package com.oracle.graal.hotspot.bridge;
 
 import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.meta.*;
 import com.oracle.graal.hotspot.*;
 import com.oracle.graal.hotspot.meta.*;
 
@@ -53,9 +52,6 @@
     public native boolean hasBalancedMonitors(long metaspaceMethod);
 
     @Override
-    public native boolean isMethodCompilable(long metaspaceMethod);
-
-    @Override
     public native long findUniqueConcreteMethod(long metaspaceMethod);
 
     @Override
@@ -68,19 +64,19 @@
     public native Object lookupConstantInPool(long metaspaceConstantPool, int cpi);
 
     @Override
-    public native JavaMethod lookupMethodInPool(long metaspaceConstantPool, int cpi, byte opcode);
+    public native long lookupMethodInPool(long metaspaceConstantPool, int cpi, byte opcode, long[] unresolvedInfo);
 
     @Override
-    public native JavaType lookupTypeInPool(long metaspaceConstantPool, int cpi);
+    public native long lookupTypeInPool(long metaspaceConstantPool, int cpi, long[] unresolvedTypeName);
 
     @Override
-    public native JavaField lookupFieldInPool(long metaspaceConstantPool, int cpi, byte opcode);
+    public native boolean lookupFieldInPool(long metaspaceConstantPool, int cpi, byte opcode, long[] info);
 
     @Override
-    public native void lookupReferencedTypeInPool(long metaspaceConstantPool, int cpi, byte opcode);
+    public native void loadReferencedTypeInPool(long metaspaceConstantPool, int cpi, byte opcode);
 
     @Override
-    public native Object lookupAppendixInPool(long metaspaceConstantPool, int cpi, byte opcode);
+    public native Object lookupAppendixInPool(long metaspaceConstantPool, int cpi);
 
     @Override
     public native void initializeConfiguration(HotSpotVMConfig config);
@@ -95,9 +91,6 @@
     public native void initializeMethod(long metaspaceMethod, HotSpotResolvedJavaMethod method);
 
     @Override
-    public native HotSpotResolvedJavaField[] getInstanceFields(HotSpotResolvedObjectType klass);
-
-    @Override
     public native long getClassInitializer(HotSpotResolvedObjectType klass);
 
     @Override
@@ -169,5 +162,13 @@
 
     public native long[] collectCounters();
 
+    public native boolean isMature(long method);
+
     public native int allocateCompileId(HotSpotResolvedJavaMethod method, int entryBCI);
+
+    public native String getGPUs();
+
+    public native boolean canInlineMethod(long metaspaceMethod);
+
+    public native boolean shouldInlineMethod(long metaspaceMethod);
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompiler.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompiler.java	Wed Mar 05 19:40:15 2014 -0800
@@ -25,8 +25,6 @@
 
 import java.io.*;
 
-import com.oracle.graal.api.meta.*;
-
 /**
  * Calls from HotSpot into Java.
  */
@@ -47,24 +45,4 @@
     void compileTheWorld() throws Throwable;
 
     PrintStream log();
-
-    JavaMethod createUnresolvedJavaMethod(String name, String signature, JavaType holder);
-
-    JavaField createJavaField(JavaType holder, String name, JavaType type, int offset, int flags, boolean internal);
-
-    ResolvedJavaMethod createResolvedJavaMethod(JavaType holder, long metaspaceMethod);
-
-    JavaType createPrimitiveJavaType(int basicType);
-
-    JavaType createUnresolvedJavaType(String name);
-
-    /**
-     * Creates a resolved Java type.
-     * 
-     * @param javaMirror the {@link Class} mirror
-     * @return the resolved type associated with {@code javaMirror} which may not be the type
-     *         instantiated by this call in the case of another thread racing to create the same
-     *         type
-     */
-    ResolvedJavaType createResolvedJavaType(Class javaMirror);
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java	Wed Mar 05 19:40:15 2014 -0800
@@ -33,6 +33,7 @@
 
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.*;
+import com.oracle.graal.compiler.CompilerThreadFactory.CompilerThread;
 import com.oracle.graal.compiler.CompilerThreadFactory.DebugConfigAccess;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.debug.internal.*;
@@ -83,7 +84,41 @@
 
     private final HotSpotGraalRuntime runtime;
 
-    private ThreadPoolExecutor compileQueue;
+    private Queue compileQueue;
+
+    /**
+     * Wrap access to the thread pool to ensure that {@link CompilationTask#isWithinEnqueue} state
+     * is in the proper state.
+     */
+    static class Queue {
+        private ThreadPoolExecutor executor;
+
+        Queue(CompilerThreadFactory factory) {
+            executor = new ThreadPoolExecutor(Threads.getValue(), Threads.getValue(), 0L, TimeUnit.MILLISECONDS, new PriorityBlockingQueue<Runnable>(), factory);
+        }
+
+        public long getCompletedTaskCount() {
+            try (CompilationTask.BeginEnqueue beginEnqueue = new CompilationTask.BeginEnqueue()) {
+                // Don't allow new enqueues while reading the state of queue.
+                return executor.getCompletedTaskCount();
+            }
+        }
+
+        public void execute(CompilationTask task) {
+            // The caller is expected to have set the within enqueue state.
+            assert CompilationTask.isWithinEnqueue();
+            executor.execute(task);
+        }
+
+        public void shutdown() throws InterruptedException {
+            assert CompilationTask.isWithinEnqueue();
+            executor.shutdown();
+            if (Debug.isEnabled() && Dump.getValue() != null) {
+                // Wait 2 seconds to flush out all graph dumps that may be of interest
+                executor.awaitTermination(2, TimeUnit.SECONDS);
+            }
+        }
+    }
 
     private volatile boolean bootstrapRunning;
 
@@ -95,10 +130,6 @@
         this.runtime = runtime;
     }
 
-    public int allocateCompileTaskId(HotSpotResolvedJavaMethod method, int entryBCI) {
-        return runtime.getCompilerToVM().allocateCompileId(method, entryBCI);
-    }
-
     public void startCompiler(boolean bootstrapEnabled) throws Throwable {
 
         FastNodeClassRegistry.initialize();
@@ -157,7 +188,7 @@
                 return Debug.isEnabled() ? DebugEnvironment.initialize(log) : null;
             }
         });
-        compileQueue = new ThreadPoolExecutor(Threads.getValue(), Threads.getValue(), 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(), factory);
+        compileQueue = new Queue(factory);
 
         // Create queue status printing thread.
         if (PrintQueue.getValue()) {
@@ -251,14 +282,8 @@
             // Compile until the queue is empty.
             int z = 0;
             while (true) {
-                try {
-                    assert !CompilationTask.withinEnqueue.get();
-                    CompilationTask.withinEnqueue.set(Boolean.TRUE);
-                    if (compileQueue.getCompletedTaskCount() >= Math.max(3, compileQueue.getTaskCount())) {
-                        break;
-                    }
-                } finally {
-                    CompilationTask.withinEnqueue.set(Boolean.FALSE);
+                if (compileQueue.getCompletedTaskCount() >= Math.max(3, compileQueue.getCompletedTaskCount())) {
+                    break;
                 }
 
                 Thread.sleep(100);
@@ -317,30 +342,18 @@
         compileMethod((HotSpotResolvedJavaMethod) javaMethod, StructuredGraph.INVOCATION_ENTRY_BCI, false);
     }
 
-    private static void shutdownCompileQueue(ThreadPoolExecutor queue) throws InterruptedException {
-        if (queue != null) {
-            queue.shutdown();
-            if (Debug.isEnabled() && Dump.getValue() != null) {
-                // Wait 2 seconds to flush out all graph dumps that may be of interest
-                queue.awaitTermination(2, TimeUnit.SECONDS);
-            }
-        }
-    }
-
     public void shutdownCompiler() throws Exception {
-        try {
-            assert !CompilationTask.withinEnqueue.get();
-            CompilationTask.withinEnqueue.set(Boolean.TRUE);
+        try (CompilationTask.BeginEnqueue beginEnqueue = new CompilationTask.BeginEnqueue()) {
             // We have to use a privileged action here because shutting down the compiler might be
             // called from user code which very likely contains unprivileged frames.
             AccessController.doPrivileged(new PrivilegedExceptionAction<Void>() {
                 public Void run() throws Exception {
-                    shutdownCompileQueue(compileQueue);
+                    if (compileQueue != null) {
+                        compileQueue.shutdown();
+                    }
                     return null;
                 }
             });
-        } finally {
-            CompilationTask.withinEnqueue.set(Boolean.FALSE);
         }
 
         printDebugValues(ResetDebugValuesAfterBootstrap.getValue() ? "application" : null, false);
@@ -540,7 +553,7 @@
             return;
         }
 
-        if (CompilationTask.withinEnqueue.get()) {
+        if (CompilationTask.isWithinEnqueue()) {
             // This is required to avoid deadlocking a compiler thread. The issue is that a
             // java.util.concurrent.BlockingQueue is used to implement the compilation worker
             // queues. If a compiler thread triggers a compilation, then it may be blocked trying
@@ -548,112 +561,29 @@
             return;
         }
 
-        CompilationTask.withinEnqueue.set(Boolean.TRUE);
-        try {
+        // Don't allow blocking compiles from CompilerThreads
+        boolean block = blocking && !(Thread.currentThread() instanceof CompilerThread);
+        try (CompilationTask.BeginEnqueue beginEnqueue = new CompilationTask.BeginEnqueue()) {
             if (method.tryToQueueForCompilation()) {
                 assert method.isQueuedForCompilation();
 
-                int id = allocateCompileTaskId(method, entryBCI);
                 HotSpotBackend backend = runtime.getHostBackend();
-                CompilationTask task = new CompilationTask(backend, method, entryBCI, id);
+                CompilationTask task = new CompilationTask(backend, method, entryBCI, block);
 
-                if (blocking) {
-                    task.runCompilation(true);
-                } else {
-                    try {
-                        method.setCurrentTask(task);
-                        compileQueue.execute(task);
-                    } catch (RejectedExecutionException e) {
-                        // The compile queue was already shut down.
+                try {
+                    method.setCurrentTask(task);
+                    compileQueue.execute(task);
+                    if (block) {
+                        task.block();
                     }
+                } catch (RejectedExecutionException e) {
+                    // The compile queue was already shut down.
                 }
             }
-        } finally {
-            CompilationTask.withinEnqueue.set(Boolean.FALSE);
         }
     }
 
     @Override
-    public JavaMethod createUnresolvedJavaMethod(String name, String signature, JavaType holder) {
-        return new HotSpotMethodUnresolved(name, signature, holder);
-    }
-
-    @Override
-    public JavaField createJavaField(JavaType holder, String name, JavaType type, int offset, int flags, boolean internal) {
-        if (offset != -1) {
-            HotSpotResolvedObjectType resolved = (HotSpotResolvedObjectType) holder;
-            return resolved.createField(name, type, offset, flags, internal);
-        }
-        return new HotSpotUnresolvedField(holder, name, type);
-    }
-
-    @Override
-    public ResolvedJavaMethod createResolvedJavaMethod(JavaType holder, long metaspaceMethod) {
-        HotSpotResolvedObjectType type = (HotSpotResolvedObjectType) holder;
-        return type.createMethod(metaspaceMethod);
-    }
-
-    @Override
-    public ResolvedJavaType createPrimitiveJavaType(int basicType) {
-        Class<?> javaClass;
-        switch (basicType) {
-            case 4:
-                javaClass = boolean.class;
-                break;
-            case 5:
-                javaClass = char.class;
-                break;
-            case 6:
-                javaClass = float.class;
-                break;
-            case 7:
-                javaClass = double.class;
-                break;
-            case 8:
-                javaClass = byte.class;
-                break;
-            case 9:
-                javaClass = short.class;
-                break;
-            case 10:
-                javaClass = int.class;
-                break;
-            case 11:
-                javaClass = long.class;
-                break;
-            case 14:
-                javaClass = void.class;
-                break;
-            default:
-                throw new IllegalArgumentException("Unknown basic type: " + basicType);
-        }
-        return HotSpotResolvedPrimitiveType.fromClass(javaClass);
-    }
-
-    @Override
-    public HotSpotUnresolvedJavaType createUnresolvedJavaType(String name) {
-        int dims = 0;
-        int startIndex = 0;
-        while (name.charAt(startIndex) == '[') {
-            startIndex++;
-            dims++;
-        }
-
-        // Decode name if necessary.
-        if (name.charAt(name.length() - 1) == ';') {
-            assert name.charAt(startIndex) == 'L';
-            return new HotSpotUnresolvedJavaType(name, name.substring(startIndex + 1, name.length() - 1), dims);
-        } else {
-            return new HotSpotUnresolvedJavaType(HotSpotUnresolvedJavaType.getFullName(name, dims), name, dims);
-        }
-    }
-
-    @Override
-    public ResolvedJavaType createResolvedJavaType(Class javaMirror) {
-        return HotSpotResolvedObjectType.fromClass(javaMirror);
-    }
-
-    @Override
     public PrintStream log() {
         return log;
     }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/debug/BenchmarkCounters.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/debug/BenchmarkCounters.java	Wed Mar 05 19:40:15 2014 -0800
@@ -107,7 +107,7 @@
 
     public static int getIndex(DynamicCounterNode counter) {
         if (!enabled) {
-            throw new GraalInternalError("counter nodes shouldn't exist when counters are not enabled");
+            throw new GraalInternalError("counter nodes shouldn't exist when counters are not enabled: " + counter.getGroup() + ", " + counter.getName());
         }
         String name = counter.getName();
         String group = counter.getGroup();
@@ -332,12 +332,15 @@
             if (index >= config.graalCountersSize) {
                 throw new GraalInternalError("too many counters, reduce number of counters or increase GRAAL_COUNTERS_SIZE (current value: " + config.graalCountersSize + ")");
             }
-            ConstantLocationNode location = ConstantLocationNode.create(LocationIdentity.ANY_LOCATION, Kind.Long, config.graalCountersThreadOffset + Unsafe.ARRAY_LONG_INDEX_SCALE * index, graph);
-            ReadNode read = graph.add(new ReadNode(thread, location, StampFactory.forKind(Kind.Long), BarrierType.NONE, false));
-            IntegerAddNode add = graph.unique(new IntegerAddNode(Kind.Long, read, counter.getIncrement()));
-            WriteNode write = graph.add(new WriteNode(thread, add, location, BarrierType.NONE, false));
+            ConstantLocationNode arrayLocation = ConstantLocationNode.create(LocationIdentity.ANY_LOCATION, Kind.Long, config.graalCountersThreadOffset, graph);
+            ReadNode readArray = graph.add(new ReadNode(thread, arrayLocation, StampFactory.forKind(wordKind), BarrierType.NONE, false));
+            ConstantLocationNode location = ConstantLocationNode.create(LocationIdentity.ANY_LOCATION, Kind.Long, Unsafe.ARRAY_LONG_INDEX_SCALE * index, graph);
+            ReadNode read = graph.add(new ReadNode(readArray, location, StampFactory.forKind(Kind.Long), BarrierType.NONE, false));
+            IntegerAddNode add = graph.unique(new IntegerAddNode(StampFactory.forKind(Kind.Long), read, counter.getIncrement()));
+            WriteNode write = graph.add(new WriteNode(readArray, add, location, BarrierType.NONE, false));
 
             graph.addBeforeFixed(counter, thread);
+            graph.addBeforeFixed(counter, readArray);
             graph.addBeforeFixed(counter, read);
             graph.addBeforeFixed(counter, write);
         }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotCodeCacheProvider.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotCodeCacheProvider.java	Wed Mar 05 19:40:15 2014 -0800
@@ -169,6 +169,9 @@
     }
 
     public HotSpotInstalledCode installMethod(HotSpotResolvedJavaMethod method, CompilationResult compResult) {
+        if (compResult.getId() == -1) {
+            compResult.setId(runtime.getCompilerToVM().allocateCompileId(method, compResult.getEntryBCI()));
+        }
         HotSpotInstalledCode installedCode = new HotSpotNmethod(method, compResult.getName(), true);
         runtime.getCompilerToVM().installCode(new HotSpotCompiledNmethod(target.arch, method, compResult), installedCode, method.getSpeculationLog());
         return logOrDump(installedCode, compResult);
@@ -177,6 +180,9 @@
     @Override
     public InstalledCode addMethod(ResolvedJavaMethod method, CompilationResult compResult, SpeculationLog log) {
         HotSpotResolvedJavaMethod hotspotMethod = (HotSpotResolvedJavaMethod) method;
+        if (compResult.getId() == -1) {
+            compResult.setId(runtime.getCompilerToVM().allocateCompileId(hotspotMethod, compResult.getEntryBCI()));
+        }
         HotSpotInstalledCode code = new HotSpotNmethod(hotspotMethod, compResult.getName(), false);
         CodeInstallResult result = runtime.getCompilerToVM().installCode(new HotSpotCompiledNmethod(target.arch, hotspotMethod, compResult), code, log);
         if (result != CodeInstallResult.OK) {
@@ -193,6 +199,9 @@
 
     public HotSpotNmethod addExternalMethod(ResolvedJavaMethod method, CompilationResult compResult) {
         HotSpotResolvedJavaMethod javaMethod = (HotSpotResolvedJavaMethod) method;
+        if (compResult.getId() == -1) {
+            compResult.setId(runtime.getCompilerToVM().allocateCompileId(javaMethod, compResult.getEntryBCI()));
+        }
         HotSpotNmethod code = new HotSpotNmethod(javaMethod, compResult.getName(), false, true);
         HotSpotCompiledNmethod compiled = new HotSpotCompiledNmethod(target.arch, javaMethod, compResult);
         CompilerToVM vm = runtime.getCompilerToVM();
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantPool.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantPool.java	Wed Mar 05 19:40:15 2014 -0800
@@ -47,6 +47,28 @@
     }
 
     /**
+     * Converts a raw index from the bytecodes to a constant pool index by adding a
+     * {@link HotSpotVMConfig#constantPoolCpCacheIndexTag constant}.
+     * 
+     * @param rawIndex index from the bytecode
+     * @param opcode bytecode to convert the index for
+     * @return constant pool index
+     */
+    private static int toConstantPoolIndex(int rawIndex, int opcode) {
+        int index;
+        if (opcode == Bytecodes.INVOKEDYNAMIC) {
+            index = rawIndex;
+            // See: ConstantPool::is_invokedynamic_index
+            assert index < 0 : "not an invokedynamic constant pool index " + index;
+        } else {
+            assert opcode == Bytecodes.GETFIELD || opcode == Bytecodes.PUTFIELD || opcode == Bytecodes.GETSTATIC || opcode == Bytecodes.PUTSTATIC || opcode == Bytecodes.INVOKEINTERFACE ||
+                            opcode == Bytecodes.INVOKEVIRTUAL || opcode == Bytecodes.INVOKESPECIAL || opcode == Bytecodes.INVOKESTATIC : "unexpected invoke opcode " + Bytecodes.nameOf(opcode);
+            index = rawIndex + runtime().getConfig().constantPoolCpCacheIndexTag;
+        }
+        return index;
+    }
+
+    /**
      * Returns the constant pool tag at index {@code index}.
      * 
      * @param index constant pool index
@@ -254,26 +276,82 @@
     @Override
     public Object lookupAppendix(int cpi, int opcode) {
         assert Bytecodes.isInvoke(opcode);
-        return runtime().getCompilerToVM().lookupAppendixInPool(metaspaceConstantPool, cpi, (byte) opcode);
+        final int index = toConstantPoolIndex(cpi, opcode);
+        return runtime().getCompilerToVM().lookupAppendixInPool(metaspaceConstantPool, index);
+    }
+
+    /**
+     * Gets a {@link JavaType} corresponding a given metaspace Klass or to a given name if the
+     * former is null.
+     * 
+     * @param metaspaceSymbol a type name
+     * @param metaspaceKlass a resolved type (if non-zero)
+     * @param mayBePrimitive specifies if the requested type may be primitive
+     */
+    private static JavaType getType(long metaspaceSymbol, long metaspaceKlass, boolean mayBePrimitive) {
+        if (metaspaceKlass == 0L) {
+            String name = new HotSpotSymbol(metaspaceSymbol).asString();
+            if (mayBePrimitive && name.length() == 1) {
+                Kind kind = Kind.fromPrimitiveOrVoidTypeChar(name.charAt(0));
+                return HotSpotResolvedPrimitiveType.fromClass(kind.toJavaClass());
+            }
+            return HotSpotUnresolvedJavaType.create(name);
+        } else {
+            return HotSpotResolvedObjectType.fromMetaspaceKlass(metaspaceKlass);
+        }
     }
 
     @Override
     public JavaMethod lookupMethod(int cpi, int opcode) {
-        return runtime().getCompilerToVM().lookupMethodInPool(metaspaceConstantPool, cpi, (byte) opcode);
+        final int index = toConstantPoolIndex(cpi, opcode);
+        // {name, signature, unresolved_holder_name, resolved_holder}
+        long[] unresolvedInfo = new long[4];
+        long metaspaceMethod = runtime().getCompilerToVM().lookupMethodInPool(metaspaceConstantPool, index, (byte) opcode, unresolvedInfo);
+        if (metaspaceMethod != 0L) {
+            return HotSpotResolvedJavaMethod.fromMetaspace(metaspaceMethod);
+        } else {
+            String name = new HotSpotSymbol(unresolvedInfo[0]).asString();
+            String signature = new HotSpotSymbol(unresolvedInfo[1]).asString();
+            JavaType holder = getType(unresolvedInfo[2], unresolvedInfo[3], false);
+            return new HotSpotMethodUnresolved(name, signature, holder);
+        }
     }
 
     @Override
     public JavaType lookupType(int cpi, int opcode) {
-        return runtime().getCompilerToVM().lookupTypeInPool(metaspaceConstantPool, cpi);
+        long[] unresolvedTypeName = {0};
+        long metaspaceKlass = runtime().getCompilerToVM().lookupTypeInPool(metaspaceConstantPool, cpi, unresolvedTypeName);
+        return getType(unresolvedTypeName[0], metaspaceKlass, false);
     }
 
     @Override
     public JavaField lookupField(int cpi, int opcode) {
-        return runtime().getCompilerToVM().lookupFieldInPool(metaspaceConstantPool, cpi, (byte) opcode);
+        final int index = toConstantPoolIndex(cpi, opcode);
+        long[] info = new long[7];
+        boolean resolved = runtime().getCompilerToVM().lookupFieldInPool(metaspaceConstantPool, index, (byte) opcode, info);
+        String name = new HotSpotSymbol(info[0]).asString();
+        JavaType type = getType(info[1], info[2], true);
+        JavaType holder = getType(info[3], info[4], false);
+        int flags = (int) info[5];
+        int offset = (int) info[6];
+        if (resolved) {
+            HotSpotResolvedObjectType resolvedHolder = (HotSpotResolvedObjectType) holder;
+            HotSpotResolvedJavaField f = resolvedHolder.createField(name, type, offset, flags);
+            return f;
+        } else {
+            return new HotSpotUnresolvedField(holder, name, type);
+        }
     }
 
     @Override
     public void loadReferencedType(int cpi, int opcode) {
-        runtime().getCompilerToVM().lookupReferencedTypeInPool(metaspaceConstantPool, cpi, (byte) opcode);
+        int index;
+        if (opcode != Bytecodes.CHECKCAST && opcode != Bytecodes.INSTANCEOF && opcode != Bytecodes.NEW && opcode != Bytecodes.ANEWARRAY && opcode != Bytecodes.MULTIANEWARRAY &&
+                        opcode != Bytecodes.LDC && opcode != Bytecodes.LDC_W && opcode != Bytecodes.LDC2_W) {
+            index = toConstantPoolIndex(cpi, opcode);
+        } else {
+            index = cpi;
+        }
+        runtime().getCompilerToVM().loadReferencedTypeInPool(metaspaceConstantPool, index, (byte) opcode);
     }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotHostForeignCallsProvider.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotHostForeignCallsProvider.java	Wed Mar 05 19:40:15 2014 -0800
@@ -48,10 +48,13 @@
 import static com.oracle.graal.replacements.Log.*;
 import static com.oracle.graal.replacements.MathSubstitutionsX86.*;
 
+import java.util.*;
+
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.hotspot.*;
 import com.oracle.graal.hotspot.stubs.*;
+import com.oracle.graal.word.*;
 
 /**
  * HotSpot implementation of {@link ForeignCallsProvider}.
@@ -66,6 +69,37 @@
         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);
+    }
+
+    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, ForeignCallDescriptor>(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);
+        arraycopyDescriptors[aligned ? 1 : 0][disjoint ? 1 : 0].put(kind, desc);
+        return desc;
+    }
+
+    private void registerArrayCopy(Kind kind, long routine, long alignedRoutine, long disjointRoutine, long alignedDisjointRoutine) {
+        LocationIdentity killed = NamedLocationIdentity.getArrayLocation(kind);
+        registerForeignCall(registerArraycopyDescriptor(kind, false, false), routine, NativeCall, DESTROYS_REGISTERS, LEAF_NOFP, NOT_REEXECUTABLE, killed);
+        registerForeignCall(registerArraycopyDescriptor(kind, true, false), alignedRoutine, NativeCall, DESTROYS_REGISTERS, LEAF_NOFP, NOT_REEXECUTABLE, killed);
+        registerForeignCall(registerArraycopyDescriptor(kind, false, true), disjointRoutine, NativeCall, DESTROYS_REGISTERS, LEAF_NOFP, NOT_REEXECUTABLE, killed);
+        registerForeignCall(registerArraycopyDescriptor(kind, true, true), alignedDisjointRoutine, NativeCall, DESTROYS_REGISTERS, LEAF_NOFP, NOT_REEXECUTABLE, killed);
+    }
+
     public void initialize(HotSpotProviders providers, HotSpotVMConfig c) {
         TargetDescription target = providers.getCodeCache().getTarget();
 
@@ -110,5 +144,15 @@
         linkForeignCall(providers, G1WBPRECALL, c.writeBarrierPreAddress, PREPEND_THREAD, LEAF_NOFP, REEXECUTABLE, NO_LOCATIONS);
         linkForeignCall(providers, G1WBPOSTCALL, c.writeBarrierPostAddress, PREPEND_THREAD, LEAF_NOFP, REEXECUTABLE, NO_LOCATIONS);
         linkForeignCall(providers, VALIDATE_OBJECT, c.validateObject, PREPEND_THREAD, LEAF_NOFP, REEXECUTABLE, NO_LOCATIONS);
+
+        registerArrayCopy(Kind.Byte, c.jbyteArraycopy, c.jbyteAlignedArraycopy, c.jbyteDisjointArraycopy, c.jbyteAlignedDisjointArraycopy);
+        registerArrayCopy(Kind.Boolean, c.jbyteArraycopy, c.jbyteAlignedArraycopy, c.jbyteDisjointArraycopy, c.jbyteAlignedDisjointArraycopy);
+        registerArrayCopy(Kind.Char, c.jshortArraycopy, c.jshortAlignedArraycopy, c.jshortDisjointArraycopy, c.jshortAlignedDisjointArraycopy);
+        registerArrayCopy(Kind.Short, c.jshortArraycopy, c.jshortAlignedArraycopy, c.jshortDisjointArraycopy, c.jshortAlignedDisjointArraycopy);
+        registerArrayCopy(Kind.Int, c.jintArraycopy, c.jintAlignedArraycopy, c.jintDisjointArraycopy, c.jintAlignedDisjointArraycopy);
+        registerArrayCopy(Kind.Float, c.jintArraycopy, c.jintAlignedArraycopy, c.jintDisjointArraycopy, c.jintAlignedDisjointArraycopy);
+        registerArrayCopy(Kind.Long, c.jlongArraycopy, c.jlongAlignedArraycopy, c.jlongDisjointArraycopy, c.jlongAlignedDisjointArraycopy);
+        registerArrayCopy(Kind.Double, c.jlongArraycopy, c.jlongAlignedArraycopy, c.jlongDisjointArraycopy, c.jlongAlignedDisjointArraycopy);
+        registerArrayCopy(Kind.Object, c.oopArraycopy, c.oopArraycopy, c.oopDisjointArraycopy, c.oopDisjointArraycopy);
     }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotLoweringProvider.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotLoweringProvider.java	Wed Mar 05 19:40:15 2014 -0800
@@ -27,7 +27,7 @@
 import static com.oracle.graal.api.meta.DeoptimizationReason.*;
 import static com.oracle.graal.api.meta.LocationIdentity.*;
 import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
-import static com.oracle.graal.hotspot.meta.HotSpotHostForeignCallsProvider.*;
+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.*;
@@ -97,325 +97,40 @@
 
     @Override
     public void lower(Node n, LoweringTool tool) {
-        HotSpotVMConfig config = runtime.getConfig();
         StructuredGraph graph = (StructuredGraph) n.graph();
 
-        Kind wordKind = runtime.getTarget().wordKind;
         if (n instanceof ArrayLengthNode) {
-            ArrayLengthNode arrayLengthNode = (ArrayLengthNode) n;
-            ValueNode array = arrayLengthNode.array();
-            ReadNode arrayLengthRead = graph.add(new ReadNode(array, ConstantLocationNode.create(FINAL_LOCATION, Kind.Int, config.arrayLengthOffset, graph), StampFactory.positiveInt(),
-                            BarrierType.NONE, false));
-            arrayLengthRead.setGuard(createNullCheck(array, arrayLengthNode, tool));
-            graph.replaceFixedWithFixed(arrayLengthNode, arrayLengthRead);
+            lowerArrayLengthNode((ArrayLengthNode) n, tool);
         } else if (n instanceof Invoke) {
-            Invoke invoke = (Invoke) n;
-            if (invoke.callTarget() instanceof MethodCallTargetNode) {
-
-                MethodCallTargetNode callTarget = (MethodCallTargetNode) invoke.callTarget();
-                NodeInputList<ValueNode> 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)) {
-                    receiverNullCheck = createNullCheck(receiver, invoke.asNode(), tool);
-                    invoke.setGuard(receiverNullCheck);
-                }
-                JavaType[] signature = MetaUtil.signatureToTypes(callTarget.targetMethod().getSignature(), callTarget.isStatic() ? null : callTarget.targetMethod().getDeclaringClass());
-
-                LoweredCallTargetNode loweredCallTarget = null;
-                if (callTarget.invokeKind() == InvokeKind.Virtual && InlineVTableStubs.getValue() && (AlwaysInlineVTableStubs.getValue() || invoke.isPolymorphic())) {
-
-                    HotSpotResolvedJavaMethod hsMethod = (HotSpotResolvedJavaMethod) callTarget.targetMethod();
-                    if (!hsMethod.getDeclaringClass().isInterface()) {
-                        if (hsMethod.isInVirtualMethodTable()) {
-                            int vtableEntryOffset = hsMethod.vtableEntryOffset();
-                            assert vtableEntryOffset > 0;
-                            FloatingReadNode hub = createReadHub(graph, wordKind, receiver, receiverNullCheck);
-
-                            ReadNode metaspaceMethod = createReadVirtualMethod(graph, wordKind, hub, hsMethod);
-                            // We use LocationNode.ANY_LOCATION for the reads that access the
-                            // compiled code entry as HotSpot does not guarantee they are final
-                            // values.
-                            ReadNode compiledEntry = graph.add(new ReadNode(metaspaceMethod, ConstantLocationNode.create(ANY_LOCATION, wordKind, config.methodCompiledEntryOffset, graph),
-                                            StampFactory.forKind(wordKind), BarrierType.NONE, false));
-
-                            loweredCallTarget = graph.add(new HotSpotIndirectCallTargetNode(metaspaceMethod, compiledEntry, parameters, invoke.asNode().stamp(), signature, callTarget.targetMethod(),
-                                            CallingConvention.Type.JavaCall));
-
-                            graph.addBeforeFixed(invoke.asNode(), metaspaceMethod);
-                            graph.addAfterFixed(metaspaceMethod, compiledEntry);
-                        }
-                    }
-                }
-
-                if (loweredCallTarget == null) {
-                    loweredCallTarget = graph.add(new HotSpotDirectCallTargetNode(parameters, invoke.asNode().stamp(), signature, callTarget.targetMethod(), CallingConvention.Type.JavaCall,
-                                    callTarget.invokeKind()));
-                }
-                callTarget.replaceAndDelete(loweredCallTarget);
-            }
+            lowerInvoke((Invoke) n, tool, graph);
         } else if (n instanceof LoadFieldNode) {
-            LoadFieldNode loadField = (LoadFieldNode) n;
-            HotSpotResolvedJavaField field = (HotSpotResolvedJavaField) loadField.field();
-            ValueNode object = loadField.isStatic() ? ConstantNode.forObject(field.getDeclaringClass().mirror(), metaAccess, graph) : loadField.object();
-            assert loadField.kind() != Kind.Illegal;
-            BarrierType barrierType = getFieldLoadBarrierType(field);
-            ReadNode memoryRead = graph.add(new ReadNode(object, createFieldLocation(graph, field, false), loadField.stamp(), barrierType, (loadField.kind() == Kind.Object)));
-            graph.replaceFixedWithFixed(loadField, memoryRead);
-            memoryRead.setGuard(createNullCheck(object, memoryRead, tool));
-
-            if (loadField.isVolatile()) {
-                MembarNode preMembar = graph.add(new MembarNode(JMM_PRE_VOLATILE_READ));
-                graph.addBeforeFixed(memoryRead, preMembar);
-                MembarNode postMembar = graph.add(new MembarNode(JMM_POST_VOLATILE_READ));
-                graph.addAfterFixed(memoryRead, postMembar);
-            }
+            lowerLoadFieldNode((LoadFieldNode) n, tool);
         } else if (n instanceof StoreFieldNode) {
-            StoreFieldNode storeField = (StoreFieldNode) n;
-            HotSpotResolvedJavaField field = (HotSpotResolvedJavaField) storeField.field();
-            ValueNode object = storeField.isStatic() ? ConstantNode.forObject(field.getDeclaringClass().mirror(), metaAccess, graph) : storeField.object();
-            BarrierType barrierType = getFieldStoreBarrierType(storeField);
-            WriteNode memoryWrite = graph.add(new WriteNode(object, storeField.value(), createFieldLocation(graph, field, false), barrierType, storeField.field().getKind() == Kind.Object));
-            memoryWrite.setStateAfter(storeField.stateAfter());
-            graph.replaceFixedWithFixed(storeField, memoryWrite);
-            memoryWrite.setGuard(createNullCheck(object, memoryWrite, tool));
-            FixedWithNextNode last = memoryWrite;
-            FixedWithNextNode first = memoryWrite;
-
-            if (storeField.isVolatile()) {
-                MembarNode preMembar = graph.add(new MembarNode(JMM_PRE_VOLATILE_WRITE));
-                graph.addBeforeFixed(first, preMembar);
-                MembarNode postMembar = graph.add(new MembarNode(JMM_POST_VOLATILE_WRITE));
-                graph.addAfterFixed(last, postMembar);
-            }
+            lowerStoreFieldNode((StoreFieldNode) n, tool);
         } else if (n instanceof CompareAndSwapNode) {
-            // Separate out GC barrier semantics
-            CompareAndSwapNode cas = (CompareAndSwapNode) n;
-            LocationNode location = IndexedLocationNode.create(cas.getLocationIdentity(), cas.expected().kind(), cas.displacement(), cas.offset(), graph, 1);
-            LoweredCompareAndSwapNode atomicNode = graph.add(new LoweredCompareAndSwapNode(cas.object(), location, cas.expected(), cas.newValue(), getCompareAndSwapBarrier(cas),
-                            cas.expected().kind() == Kind.Object));
-            atomicNode.setStateAfter(cas.stateAfter());
-            graph.replaceFixedWithFixed(cas, atomicNode);
+            lowerCompareAndSwapNode((CompareAndSwapNode) n);
         } else if (n instanceof LoadIndexedNode) {
-            LoadIndexedNode loadIndexed = (LoadIndexedNode) n;
-            Kind elementKind = loadIndexed.elementKind();
-            LocationNode arrayLocation = createArrayLocation(graph, elementKind, loadIndexed.index(), false);
-            ReadNode memoryRead = graph.add(new ReadNode(loadIndexed.array(), arrayLocation, loadIndexed.stamp(), BarrierType.NONE, elementKind == Kind.Object));
-            memoryRead.setGuard(createBoundsCheck(loadIndexed, tool));
-            graph.replaceFixedWithFixed(loadIndexed, memoryRead);
+            lowerLoadIndexedNode((LoadIndexedNode) n, tool);
         } else if (n instanceof StoreIndexedNode) {
-            StoreIndexedNode storeIndexed = (StoreIndexedNode) n;
-            GuardingNode boundsCheck = createBoundsCheck(storeIndexed, tool);
-            Kind elementKind = storeIndexed.elementKind();
-            LocationNode arrayLocation = createArrayLocation(graph, elementKind, storeIndexed.index(), false);
-            ValueNode value = storeIndexed.value();
-            ValueNode array = storeIndexed.array();
-
-            CheckCastNode checkcastNode = null;
-            CheckCastDynamicNode checkcastDynamicNode = null;
-            if (elementKind == Kind.Object && !ObjectStamp.isObjectAlwaysNull(value)) {
-                // Store check!
-                ResolvedJavaType arrayType = ObjectStamp.typeOrNull(array);
-                if (arrayType != null && ObjectStamp.isExactType(array)) {
-                    ResolvedJavaType elementType = arrayType.getComponentType();
-                    if (!MetaUtil.isJavaLangObject(elementType)) {
-                        checkcastNode = graph.add(new CheckCastNode(elementType, value, null, true));
-                        graph.addBeforeFixed(storeIndexed, checkcastNode);
-                        value = checkcastNode;
-                    }
-                } else {
-                    FloatingReadNode arrayClass = createReadHub(graph, wordKind, array, boundsCheck);
-                    LocationNode location = ConstantLocationNode.create(FINAL_LOCATION, wordKind, config.arrayClassElementOffset, graph);
-                    /*
-                     * Anchor the read of the element klass to the cfg, because it is only valid
-                     * when arrayClass is an object class, which might not be the case in other
-                     * parts of the compiled method.
-                     */
-                    FloatingReadNode arrayElementKlass = graph.unique(new FloatingReadNode(arrayClass, location, null, StampFactory.forKind(wordKind), BeginNode.prevBegin(storeIndexed)));
-                    checkcastDynamicNode = graph.add(new CheckCastDynamicNode(arrayElementKlass, value, true));
-                    graph.addBeforeFixed(storeIndexed, checkcastDynamicNode);
-                    value = checkcastDynamicNode;
-                }
-            }
-            BarrierType barrierType = getArrayStoreBarrierType(storeIndexed);
-            WriteNode memoryWrite = graph.add(new WriteNode(array, value, arrayLocation, barrierType, elementKind == Kind.Object));
-            memoryWrite.setGuard(boundsCheck);
-            memoryWrite.setStateAfter(storeIndexed.stateAfter());
-            graph.replaceFixedWithFixed(storeIndexed, memoryWrite);
-
-            // Lower the associated checkcast node.
-            if (checkcastNode != null) {
-                checkcastNode.lower(tool);
-            } else if (checkcastDynamicNode != null) {
-                checkcastDynamicSnippets.lower(checkcastDynamicNode, tool);
-            }
+            lowerStoreIndexedNode((StoreIndexedNode) n, tool);
         } else if (n instanceof UnsafeLoadNode) {
-            UnsafeLoadNode load = (UnsafeLoadNode) n;
-            if (load.getGuardingCondition() != null) {
-                boolean compressible = (!load.object().isNullConstant() && load.accessKind() == Kind.Object);
-                ConditionAnchorNode valueAnchorNode = graph.add(new ConditionAnchorNode(load.getGuardingCondition()));
-                LocationNode location = createLocation(load);
-                ReadNode memoryRead = graph.add(new ReadNode(load.object(), location, load.stamp(), valueAnchorNode, BarrierType.NONE, compressible));
-                load.replaceAtUsages(memoryRead);
-                graph.replaceFixedWithFixed(load, valueAnchorNode);
-                graph.addAfterFixed(valueAnchorNode, memoryRead);
-            } else if (graph.getGuardsStage().ordinal() > StructuredGraph.GuardsStage.FLOATING_GUARDS.ordinal()) {
-                assert load.kind() != Kind.Illegal;
-                boolean compressible = (!load.object().isNullConstant() && load.accessKind() == Kind.Object);
-                if (addReadBarrier(load)) {
-                    unsafeLoadSnippets.lower(load, tool);
-                } else {
-                    LocationNode location = createLocation(load);
-                    ReadNode memoryRead = graph.add(new ReadNode(load.object(), location, load.stamp(), BarrierType.NONE, compressible));
-                    // An unsafe read must not float outside its block otherwise
-                    // it may float above an explicit null check on its object.
-                    memoryRead.setGuard(AbstractBeginNode.prevBegin(load));
-                    graph.replaceFixedWithFixed(load, memoryRead);
-                }
-            }
+            lowerUnsafeLoadNode((UnsafeLoadNode) n, tool);
         } else if (n instanceof UnsafeStoreNode) {
-            UnsafeStoreNode store = (UnsafeStoreNode) n;
-            LocationNode location = createLocation(store);
-            ValueNode object = store.object();
-            BarrierType barrierType = getUnsafeStoreBarrierType(store);
-            WriteNode write = graph.add(new WriteNode(object, store.value(), location, barrierType, store.value().kind() == Kind.Object));
-            write.setStateAfter(store.stateAfter());
-            graph.replaceFixedWithFixed(store, write);
+            lowerUnsafeStoreNode((UnsafeStoreNode) n);
         } else if (n instanceof LoadHubNode) {
-            if (graph.getGuardsStage().ordinal() == StructuredGraph.GuardsStage.FIXED_DEOPTS.ordinal()) {
-                LoadHubNode loadHub = (LoadHubNode) n;
-                assert loadHub.kind() == wordKind;
-                ValueNode object = loadHub.object();
-                GuardingNode guard = loadHub.getGuard();
-                FloatingReadNode hub = createReadHub(graph, wordKind, object, guard);
-                graph.replaceFloating(loadHub, hub);
-            }
+            lowerLoadHubNode((LoadHubNode) n);
         } else if (n instanceof LoadMethodNode) {
-            LoadMethodNode loadMethodNode = (LoadMethodNode) n;
-            ResolvedJavaMethod method = loadMethodNode.getMethod();
-            ReadNode metaspaceMethod = createReadVirtualMethod(graph, wordKind, loadMethodNode.getHub(), method);
-            graph.replaceFixed(loadMethodNode, metaspaceMethod);
+            lowerLoadMethodNode((LoadMethodNode) n);
         } else if (n instanceof StoreHubNode) {
-            StoreHubNode storeHub = (StoreHubNode) n;
-            WriteNode hub = createWriteHub(graph, wordKind, storeHub.getObject(), storeHub.getValue());
-            graph.replaceFixed(storeHub, hub);
+            lowerStoreHubNode((StoreHubNode) n, graph);
         } else if (n instanceof CommitAllocationNode) {
-            if (graph.getGuardsStage() == StructuredGraph.GuardsStage.FIXED_DEOPTS) {
-                CommitAllocationNode commit = (CommitAllocationNode) n;
-                ValueNode[] allocations = new ValueNode[commit.getVirtualObjects().size()];
-                BitSet omittedValues = new BitSet();
-                int valuePos = 0;
-                for (int objIndex = 0; objIndex < commit.getVirtualObjects().size(); objIndex++) {
-                    VirtualObjectNode virtual = commit.getVirtualObjects().get(objIndex);
-                    int entryCount = virtual.entryCount();
-                    FixedWithNextNode newObject;
-                    if (virtual instanceof VirtualInstanceNode) {
-                        newObject = graph.add(new NewInstanceNode(virtual.type(), true));
-                    } else {
-                        newObject = graph.add(new NewArrayNode(((VirtualArrayNode) virtual).componentType(), ConstantNode.forInt(entryCount, graph), true));
-                    }
-                    graph.addBeforeFixed(commit, newObject);
-                    allocations[objIndex] = newObject;
-                    for (int i = 0; i < entryCount; i++) {
-                        ValueNode value = commit.getValues().get(valuePos);
-                        if (value instanceof VirtualObjectNode) {
-                            value = allocations[commit.getVirtualObjects().indexOf(value)];
-                        }
-                        if (value == null) {
-                            omittedValues.set(valuePos);
-                        } else if (!(value.isConstant() && value.asConstant().isDefaultForKind())) {
-                            // Constant.illegal is always the defaultForKind, so it is skipped
-                            Kind valueKind = value.kind();
-                            Kind entryKind = virtual.entryKind(i);
-
-                            // Truffle requires some leniency in terms of what can be put where:
-                            Kind accessKind = valueKind.getStackKind() == entryKind.getStackKind() ? entryKind : valueKind;
-                            assert valueKind.getStackKind() == entryKind.getStackKind() ||
-                                            (valueKind == Kind.Long || valueKind == Kind.Double || (valueKind == Kind.Int && virtual instanceof VirtualArrayNode));
-                            ConstantLocationNode location;
-                            BarrierType barrierType;
-                            if (virtual instanceof VirtualInstanceNode) {
-                                ResolvedJavaField field = ((VirtualInstanceNode) virtual).field(i);
-                                location = ConstantLocationNode.create(INIT_LOCATION, accessKind, ((HotSpotResolvedJavaField) field).offset(), graph);
-                                barrierType = (entryKind == Kind.Object && !useDeferredInitBarriers()) ? BarrierType.IMPRECISE : BarrierType.NONE;
-                            } else {
-                                location = ConstantLocationNode.create(INIT_LOCATION, accessKind, getArrayBaseOffset(entryKind) + i * getScalingFactor(entryKind), graph);
-                                barrierType = (entryKind == Kind.Object && !useDeferredInitBarriers()) ? BarrierType.PRECISE : BarrierType.NONE;
-                            }
-                            WriteNode write = new WriteNode(newObject, value, location, barrierType, entryKind == Kind.Object);
-                            graph.addAfterFixed(newObject, graph.add(write));
-                        }
-                        valuePos++;
-
-                    }
-                }
-                valuePos = 0;
-
-                for (int objIndex = 0; objIndex < commit.getVirtualObjects().size(); objIndex++) {
-                    VirtualObjectNode virtual = commit.getVirtualObjects().get(objIndex);
-                    int entryCount = virtual.entryCount();
-                    ValueNode newObject = allocations[objIndex];
-                    for (int i = 0; i < entryCount; i++) {
-                        if (omittedValues.get(valuePos)) {
-                            ValueNode value = commit.getValues().get(valuePos);
-                            assert value instanceof VirtualObjectNode;
-                            ValueNode allocValue = allocations[commit.getVirtualObjects().indexOf(value)];
-                            if (!(allocValue.isConstant() && allocValue.asConstant().isDefaultForKind())) {
-                                assert virtual.entryKind(i) == Kind.Object && allocValue.kind() == Kind.Object;
-                                WriteNode write;
-                                if (virtual instanceof VirtualInstanceNode) {
-                                    VirtualInstanceNode virtualInstance = (VirtualInstanceNode) virtual;
-                                    write = new WriteNode(newObject, allocValue, createFieldLocation(graph, (HotSpotResolvedJavaField) virtualInstance.field(i), true), BarrierType.IMPRECISE, true);
-                                } else {
-                                    write = new WriteNode(newObject, allocValue, createArrayLocation(graph, virtual.entryKind(i), ConstantNode.forInt(i, graph), true), BarrierType.PRECISE, true);
-                                }
-                                graph.addBeforeFixed(commit, graph.add(write));
-                            }
-                        }
-                        valuePos++;
-                    }
-                }
-
-                finishAllocatedObjects(tool, commit, allocations);
-                graph.removeFixed(commit);
-            }
+            lowerCommitAllocationNode((CommitAllocationNode) n, tool);
         } else if (n instanceof OSRStartNode) {
-            if (graph.getGuardsStage() == StructuredGraph.GuardsStage.FIXED_DEOPTS) {
-                OSRStartNode osrStart = (OSRStartNode) n;
-                StartNode newStart = graph.add(new StartNode());
-                ParameterNode buffer = graph.unique(new ParameterNode(0, StampFactory.forKind(wordKind)));
-                ForeignCallNode migrationEnd = graph.add(new ForeignCallNode(foreignCalls, OSR_MIGRATION_END, buffer));
-                migrationEnd.setStateAfter(osrStart.stateAfter());
-
-                newStart.setNext(migrationEnd);
-                FixedNode next = osrStart.next();
-                osrStart.setNext(null);
-                migrationEnd.setNext(next);
-                graph.setStart(newStart);
-
-                // mirroring the calculations in c1_GraphBuilder.cpp (setup_osr_entry_block)
-                int localsOffset = (graph.method().getMaxLocals() - 1) * 8;
-                for (OSRLocalNode osrLocal : graph.getNodes(OSRLocalNode.class)) {
-                    int size = FrameStateBuilder.stackSlots(osrLocal.kind());
-                    int offset = localsOffset - (osrLocal.index() + size - 1) * 8;
-                    IndexedLocationNode location = IndexedLocationNode.create(ANY_LOCATION, osrLocal.kind(), offset, ConstantNode.forLong(0, graph), graph, 1);
-                    ReadNode load = graph.add(new ReadNode(buffer, location, osrLocal.stamp(), BarrierType.NONE, false));
-                    osrLocal.replaceAndDelete(load);
-                    graph.addBeforeFixed(migrationEnd, load);
-                }
-                osrStart.replaceAtUsages(newStart);
-                osrStart.safeDelete();
-            }
+            lowerOSRStartNode((OSRStartNode) n);
         } else if (n instanceof DynamicCounterNode) {
-            if (graph.getGuardsStage() == StructuredGraph.GuardsStage.AFTER_FSA) {
-                BenchmarkCounters.lower((DynamicCounterNode) n, registers, runtime.getConfig(), wordKind);
-            }
+            lowerDynamicCounterNode((DynamicCounterNode) n);
         } else if (n instanceof DeferredForeignCallNode) {
-            if (graph.getGuardsStage() == StructuredGraph.GuardsStage.FLOATING_GUARDS) {
-                DeferredForeignCallNode deferred = (DeferredForeignCallNode) n;
-                ForeignCallNode foreignCallNode = graph.add(new ForeignCallNode(foreignCalls, deferred.getDescriptor(), deferred.getArguments()));
-                graph.replaceFixedWithFixed(deferred, foreignCallNode);
-            }
+            lowerDeferredForeignCallNode((DeferredForeignCallNode) n);
         } else if (n instanceof CheckCastDynamicNode) {
             checkcastDynamicSnippets.lower((CheckCastDynamicNode) n, tool);
         } else if (n instanceof InstanceOfNode) {
@@ -443,11 +158,11 @@
                 newObjectSnippets.lower((DynamicNewArrayNode) n, registers, tool);
             }
         } else if (n instanceof MonitorEnterNode) {
-            if (graph.getGuardsStage() == StructuredGraph.GuardsStage.FIXED_DEOPTS) {
+            if (graph.getGuardsStage() == StructuredGraph.GuardsStage.AFTER_FSA) {
                 monitorSnippets.lower((MonitorEnterNode) n, registers, tool);
             }
         } else if (n instanceof MonitorExitNode) {
-            if (graph.getGuardsStage() == StructuredGraph.GuardsStage.FIXED_DEOPTS) {
+            if (graph.getGuardsStage() == StructuredGraph.GuardsStage.AFTER_FSA) {
                 monitorSnippets.lower((MonitorExitNode) n, tool);
             }
         } else if (n instanceof G1PreWriteBarrier) {
@@ -480,8 +195,355 @@
         } else if (n instanceof DeoptimizeNode || n instanceof UnwindNode) {
             /* No lowering, we generate LIR directly for these nodes. */
         } else {
-            assert false : "Node implementing Lowerable not handled: " + n;
-            throw GraalInternalError.shouldNotReachHere();
+            throw GraalInternalError.shouldNotReachHere("Node implementing Lowerable not handled: " + n);
+        }
+    }
+
+    private void lowerArrayLengthNode(ArrayLengthNode arrayLengthNode, LoweringTool tool) {
+        StructuredGraph graph = arrayLengthNode.graph();
+        ValueNode array = arrayLengthNode.array();
+        ReadNode arrayLengthRead = graph.add(new ReadNode(array, ConstantLocationNode.create(ARRAY_LENGTH_LOCATION, Kind.Int, runtime.getConfig().arrayLengthOffset, graph),
+                        StampFactory.positiveInt(), BarrierType.NONE, false));
+        arrayLengthRead.setGuard(createNullCheck(array, arrayLengthNode, tool));
+        graph.replaceFixedWithFixed(arrayLengthNode, arrayLengthRead);
+    }
+
+    private void lowerInvoke(Invoke invoke, LoweringTool tool, StructuredGraph graph) {
+        if (invoke.callTarget() instanceof MethodCallTargetNode) {
+            MethodCallTargetNode callTarget = (MethodCallTargetNode) invoke.callTarget();
+            NodeInputList<ValueNode> 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)) {
+                receiverNullCheck = createNullCheck(receiver, invoke.asNode(), tool);
+                invoke.setGuard(receiverNullCheck);
+            }
+            JavaType[] signature = MetaUtil.signatureToTypes(callTarget.targetMethod().getSignature(), callTarget.isStatic() ? null : callTarget.targetMethod().getDeclaringClass());
+
+            LoweredCallTargetNode loweredCallTarget = null;
+            if (callTarget.invokeKind() == InvokeKind.Virtual && InlineVTableStubs.getValue() && (AlwaysInlineVTableStubs.getValue() || invoke.isPolymorphic())) {
+
+                HotSpotResolvedJavaMethod hsMethod = (HotSpotResolvedJavaMethod) callTarget.targetMethod();
+                if (!hsMethod.getDeclaringClass().isInterface()) {
+                    if (hsMethod.isInVirtualMethodTable()) {
+                        int vtableEntryOffset = hsMethod.vtableEntryOffset();
+                        assert vtableEntryOffset > 0;
+                        Kind wordKind = runtime.getTarget().wordKind;
+                        FloatingReadNode hub = createReadHub(graph, wordKind, receiver, receiverNullCheck);
+
+                        ReadNode metaspaceMethod = createReadVirtualMethod(graph, wordKind, hub, hsMethod);
+                        // We use LocationNode.ANY_LOCATION for the reads that access the
+                        // compiled code entry as HotSpot does not guarantee they are final
+                        // values.
+                        ReadNode compiledEntry = graph.add(new ReadNode(metaspaceMethod, ConstantLocationNode.create(ANY_LOCATION, wordKind, runtime.getConfig().methodCompiledEntryOffset, graph),
+                                        StampFactory.forKind(wordKind), BarrierType.NONE, false));
+
+                        loweredCallTarget = graph.add(new HotSpotIndirectCallTargetNode(metaspaceMethod, compiledEntry, parameters, invoke.asNode().stamp(), signature, callTarget.targetMethod(),
+                                        CallingConvention.Type.JavaCall));
+
+                        graph.addBeforeFixed(invoke.asNode(), metaspaceMethod);
+                        graph.addAfterFixed(metaspaceMethod, compiledEntry);
+                    }
+                }
+            }
+
+            if (loweredCallTarget == null) {
+                loweredCallTarget = graph.add(new HotSpotDirectCallTargetNode(parameters, invoke.asNode().stamp(), signature, callTarget.targetMethod(), CallingConvention.Type.JavaCall,
+                                callTarget.invokeKind()));
+            }
+            callTarget.replaceAndDelete(loweredCallTarget);
+        }
+    }
+
+    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();
+        assert loadField.kind() != Kind.Illegal;
+        BarrierType barrierType = getFieldLoadBarrierType(field);
+        ReadNode memoryRead = graph.add(new ReadNode(object, createFieldLocation(graph, field, false), loadField.stamp(), barrierType, (loadField.kind() == Kind.Object)));
+        graph.replaceFixedWithFixed(loadField, memoryRead);
+        memoryRead.setGuard(createNullCheck(object, memoryRead, tool));
+
+        if (loadField.isVolatile()) {
+            MembarNode preMembar = graph.add(new MembarNode(JMM_PRE_VOLATILE_READ));
+            graph.addBeforeFixed(memoryRead, preMembar);
+            MembarNode postMembar = graph.add(new MembarNode(JMM_POST_VOLATILE_READ));
+            graph.addAfterFixed(memoryRead, postMembar);
+        }
+    }
+
+    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();
+        BarrierType barrierType = getFieldStoreBarrierType(storeField);
+        WriteNode memoryWrite = graph.add(new WriteNode(object, storeField.value(), createFieldLocation(graph, field, false), barrierType, storeField.field().getKind() == Kind.Object));
+        memoryWrite.setStateAfter(storeField.stateAfter());
+        graph.replaceFixedWithFixed(storeField, memoryWrite);
+        memoryWrite.setGuard(createNullCheck(object, memoryWrite, tool));
+        FixedWithNextNode last = memoryWrite;
+        FixedWithNextNode first = memoryWrite;
+
+        if (storeField.isVolatile()) {
+            MembarNode preMembar = graph.add(new MembarNode(JMM_PRE_VOLATILE_WRITE));
+            graph.addBeforeFixed(first, preMembar);
+            MembarNode postMembar = graph.add(new MembarNode(JMM_POST_VOLATILE_WRITE));
+            graph.addAfterFixed(last, postMembar);
+        }
+    }
+
+    private static void lowerCompareAndSwapNode(CompareAndSwapNode cas) {
+        // Separate out GC barrier semantics
+        StructuredGraph graph = cas.graph();
+        LocationNode location = IndexedLocationNode.create(cas.getLocationIdentity(), cas.expected().kind(), cas.displacement(), cas.offset(), graph, 1);
+        LoweredCompareAndSwapNode atomicNode = graph.add(new LoweredCompareAndSwapNode(cas.object(), location, cas.expected(), cas.newValue(), getCompareAndSwapBarrier(cas),
+                        cas.expected().kind() == Kind.Object));
+        atomicNode.setStateAfter(cas.stateAfter());
+        graph.replaceFixedWithFixed(cas, atomicNode);
+    }
+
+    private void lowerLoadIndexedNode(LoadIndexedNode loadIndexed, LoweringTool tool) {
+        StructuredGraph graph = loadIndexed.graph();
+        Kind elementKind = loadIndexed.elementKind();
+        LocationNode arrayLocation = createArrayLocation(graph, elementKind, loadIndexed.index(), false);
+        ReadNode memoryRead = graph.add(new ReadNode(loadIndexed.array(), arrayLocation, loadIndexed.stamp(), BarrierType.NONE, elementKind == Kind.Object));
+        memoryRead.setGuard(createBoundsCheck(loadIndexed, tool));
+        graph.replaceFixedWithFixed(loadIndexed, memoryRead);
+    }
+
+    private void lowerStoreIndexedNode(StoreIndexedNode storeIndexed, LoweringTool tool) {
+        StructuredGraph graph = storeIndexed.graph();
+        GuardingNode boundsCheck = createBoundsCheck(storeIndexed, tool);
+        Kind elementKind = storeIndexed.elementKind();
+        LocationNode arrayLocation = createArrayLocation(graph, elementKind, storeIndexed.index(), false);
+        ValueNode value = storeIndexed.value();
+        ValueNode array = storeIndexed.array();
+
+        CheckCastNode checkcastNode = null;
+        CheckCastDynamicNode checkcastDynamicNode = null;
+        if (elementKind == Kind.Object && !ObjectStamp.isObjectAlwaysNull(value)) {
+            // Store check!
+            ResolvedJavaType arrayType = ObjectStamp.typeOrNull(array);
+            if (arrayType != null && ObjectStamp.isExactType(array)) {
+                ResolvedJavaType elementType = arrayType.getComponentType();
+                if (!MetaUtil.isJavaLangObject(elementType)) {
+                    checkcastNode = graph.add(new CheckCastNode(elementType, value, null, true));
+                    graph.addBeforeFixed(storeIndexed, checkcastNode);
+                    value = checkcastNode;
+                }
+            } else {
+                Kind wordKind = runtime.getTarget().wordKind;
+                FloatingReadNode 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
+                 * arrayClass is an object class, which might not be the case in other parts of the
+                 * compiled method.
+                 */
+                FloatingReadNode arrayElementKlass = graph.unique(new FloatingReadNode(arrayClass, location, null, StampFactory.forKind(wordKind), BeginNode.prevBegin(storeIndexed)));
+                checkcastDynamicNode = graph.add(new CheckCastDynamicNode(arrayElementKlass, value, true));
+                graph.addBeforeFixed(storeIndexed, checkcastDynamicNode);
+                value = checkcastDynamicNode;
+            }
+        }
+        BarrierType barrierType = getArrayStoreBarrierType(storeIndexed);
+        WriteNode memoryWrite = graph.add(new WriteNode(array, value, arrayLocation, barrierType, elementKind == Kind.Object));
+        memoryWrite.setGuard(boundsCheck);
+        memoryWrite.setStateAfter(storeIndexed.stateAfter());
+        graph.replaceFixedWithFixed(storeIndexed, memoryWrite);
+
+        // Lower the associated checkcast node.
+        if (checkcastNode != null) {
+            checkcastNode.lower(tool);
+        } else if (checkcastDynamicNode != null) {
+            checkcastDynamicSnippets.lower(checkcastDynamicNode, tool);
+        }
+    }
+
+    private void lowerUnsafeLoadNode(UnsafeLoadNode load, LoweringTool tool) {
+        StructuredGraph graph = load.graph();
+        if (load.getGuardingCondition() != null) {
+            boolean compressible = (!load.object().isNullConstant() && load.accessKind() == Kind.Object);
+            ConditionAnchorNode valueAnchorNode = graph.add(new ConditionAnchorNode(load.getGuardingCondition()));
+            LocationNode location = createLocation(load);
+            ReadNode memoryRead = graph.add(new ReadNode(load.object(), location, load.stamp(), valueAnchorNode, BarrierType.NONE, compressible));
+            load.replaceAtUsages(memoryRead);
+            graph.replaceFixedWithFixed(load, valueAnchorNode);
+            graph.addAfterFixed(valueAnchorNode, memoryRead);
+        } else if (graph.getGuardsStage().ordinal() > StructuredGraph.GuardsStage.FLOATING_GUARDS.ordinal()) {
+            assert load.kind() != Kind.Illegal;
+            boolean compressible = (!load.object().isNullConstant() && load.accessKind() == Kind.Object);
+            if (addReadBarrier(load)) {
+                unsafeLoadSnippets.lower(load, tool);
+            } else {
+                LocationNode location = createLocation(load);
+                ReadNode memoryRead = graph.add(new ReadNode(load.object(), location, load.stamp(), BarrierType.NONE, compressible));
+                // An unsafe read must not float outside its block otherwise
+                // it may float above an explicit null check on its object.
+                memoryRead.setGuard(AbstractBeginNode.prevBegin(load));
+                graph.replaceFixedWithFixed(load, memoryRead);
+            }
+        }
+    }
+
+    private static void lowerUnsafeStoreNode(UnsafeStoreNode store) {
+        StructuredGraph graph = store.graph();
+        LocationNode location = createLocation(store);
+        ValueNode object = store.object();
+        BarrierType barrierType = getUnsafeStoreBarrierType(store);
+        WriteNode write = graph.add(new WriteNode(object, store.value(), location, barrierType, store.value().kind() == Kind.Object));
+        write.setStateAfter(store.stateAfter());
+        graph.replaceFixedWithFixed(store, write);
+    }
+
+    private void lowerLoadHubNode(LoadHubNode loadHub) {
+        StructuredGraph graph = loadHub.graph();
+        if (graph.getGuardsStage().ordinal() >= StructuredGraph.GuardsStage.FIXED_DEOPTS.ordinal()) {
+            Kind wordKind = runtime.getTarget().wordKind;
+            assert loadHub.kind() == wordKind;
+            ValueNode object = loadHub.object();
+            GuardingNode guard = loadHub.getGuard();
+            FloatingReadNode hub = createReadHub(graph, wordKind, object, guard);
+            graph.replaceFloating(loadHub, hub);
+        }
+    }
+
+    private void lowerLoadMethodNode(LoadMethodNode loadMethodNode) {
+        StructuredGraph graph = loadMethodNode.graph();
+        ResolvedJavaMethod method = loadMethodNode.getMethod();
+        ReadNode metaspaceMethod = createReadVirtualMethod(graph, runtime.getTarget().wordKind, loadMethodNode.getHub(), method);
+        graph.replaceFixed(loadMethodNode, metaspaceMethod);
+    }
+
+    private void lowerStoreHubNode(StoreHubNode storeHub, StructuredGraph graph) {
+        WriteNode hub = createWriteHub(graph, runtime.getTarget().wordKind, storeHub.getObject(), storeHub.getValue());
+        graph.replaceFixed(storeHub, hub);
+    }
+
+    private void lowerCommitAllocationNode(CommitAllocationNode commit, LoweringTool tool) {
+        StructuredGraph graph = commit.graph();
+        if (graph.getGuardsStage() == StructuredGraph.GuardsStage.FIXED_DEOPTS) {
+            ValueNode[] allocations = new ValueNode[commit.getVirtualObjects().size()];
+            BitSet omittedValues = new BitSet();
+            int valuePos = 0;
+            for (int objIndex = 0; objIndex < commit.getVirtualObjects().size(); objIndex++) {
+                VirtualObjectNode virtual = commit.getVirtualObjects().get(objIndex);
+                int entryCount = virtual.entryCount();
+                FixedWithNextNode newObject;
+                if (virtual instanceof VirtualInstanceNode) {
+                    newObject = graph.add(new NewInstanceNode(virtual.type(), true));
+                } else {
+                    newObject = graph.add(new NewArrayNode(((VirtualArrayNode) virtual).componentType(), ConstantNode.forInt(entryCount, graph), true));
+                }
+                graph.addBeforeFixed(commit, newObject);
+                allocations[objIndex] = newObject;
+                for (int i = 0; i < entryCount; i++) {
+                    ValueNode value = commit.getValues().get(valuePos);
+                    if (value instanceof VirtualObjectNode) {
+                        value = allocations[commit.getVirtualObjects().indexOf(value)];
+                    }
+                    if (value == null) {
+                        omittedValues.set(valuePos);
+                    } else if (!(value.isConstant() && value.asConstant().isDefaultForKind())) {
+                        // Constant.illegal is always the defaultForKind, so it is skipped
+                        Kind valueKind = value.kind();
+                        Kind entryKind = virtual.entryKind(i);
+
+                        // Truffle requires some leniency in terms of what can be put where:
+                        Kind accessKind = valueKind.getStackKind() == entryKind.getStackKind() ? entryKind : valueKind;
+                        assert valueKind.getStackKind() == entryKind.getStackKind() ||
+                                        (valueKind == Kind.Long || valueKind == Kind.Double || (valueKind == Kind.Int && virtual instanceof VirtualArrayNode));
+                        ConstantLocationNode location;
+                        BarrierType barrierType;
+                        if (virtual instanceof VirtualInstanceNode) {
+                            ResolvedJavaField field = ((VirtualInstanceNode) virtual).field(i);
+                            location = ConstantLocationNode.create(INIT_LOCATION, accessKind, ((HotSpotResolvedJavaField) field).offset(), graph);
+                            barrierType = (entryKind == Kind.Object && !useDeferredInitBarriers()) ? BarrierType.IMPRECISE : BarrierType.NONE;
+                        } else {
+                            location = ConstantLocationNode.create(INIT_LOCATION, accessKind, getArrayBaseOffset(entryKind) + i * getScalingFactor(entryKind), graph);
+                            barrierType = (entryKind == Kind.Object && !useDeferredInitBarriers()) ? BarrierType.PRECISE : BarrierType.NONE;
+                        }
+                        WriteNode write = new WriteNode(newObject, value, location, barrierType, entryKind == Kind.Object);
+                        graph.addAfterFixed(newObject, graph.add(write));
+                    }
+                    valuePos++;
+
+                }
+            }
+            valuePos = 0;
+
+            for (int objIndex = 0; objIndex < commit.getVirtualObjects().size(); objIndex++) {
+                VirtualObjectNode virtual = commit.getVirtualObjects().get(objIndex);
+                int entryCount = virtual.entryCount();
+                ValueNode newObject = allocations[objIndex];
+                for (int i = 0; i < entryCount; i++) {
+                    if (omittedValues.get(valuePos)) {
+                        ValueNode value = commit.getValues().get(valuePos);
+                        assert value instanceof VirtualObjectNode;
+                        ValueNode allocValue = allocations[commit.getVirtualObjects().indexOf(value)];
+                        if (!(allocValue.isConstant() && allocValue.asConstant().isDefaultForKind())) {
+                            assert virtual.entryKind(i) == Kind.Object && allocValue.kind() == Kind.Object;
+                            WriteNode write;
+                            if (virtual instanceof VirtualInstanceNode) {
+                                VirtualInstanceNode virtualInstance = (VirtualInstanceNode) virtual;
+                                write = new WriteNode(newObject, allocValue, createFieldLocation(graph, (HotSpotResolvedJavaField) virtualInstance.field(i), true), BarrierType.IMPRECISE, true);
+                            } else {
+                                write = new WriteNode(newObject, allocValue, createArrayLocation(graph, virtual.entryKind(i), ConstantNode.forInt(i, graph), true), BarrierType.PRECISE, true);
+                            }
+                            graph.addBeforeFixed(commit, graph.add(write));
+                        }
+                    }
+                    valuePos++;
+                }
+            }
+
+            finishAllocatedObjects(tool, commit, allocations);
+            graph.removeFixed(commit);
+        }
+    }
+
+    private void lowerOSRStartNode(OSRStartNode osrStart) {
+        StructuredGraph graph = osrStart.graph();
+        if (graph.getGuardsStage() == StructuredGraph.GuardsStage.FIXED_DEOPTS) {
+            StartNode newStart = graph.add(new StartNode());
+            ParameterNode buffer = graph.unique(new ParameterNode(0, StampFactory.forKind(runtime.getTarget().wordKind)));
+            ForeignCallNode migrationEnd = graph.add(new ForeignCallNode(foreignCalls, OSR_MIGRATION_END, buffer));
+            migrationEnd.setStateAfter(osrStart.stateAfter());
+
+            newStart.setNext(migrationEnd);
+            FixedNode next = osrStart.next();
+            osrStart.setNext(null);
+            migrationEnd.setNext(next);
+            graph.setStart(newStart);
+
+            // mirroring the calculations in c1_GraphBuilder.cpp (setup_osr_entry_block)
+            int localsOffset = (graph.method().getMaxLocals() - 1) * 8;
+            for (OSRLocalNode osrLocal : graph.getNodes(OSRLocalNode.class)) {
+                int size = FrameStateBuilder.stackSlots(osrLocal.kind());
+                int offset = localsOffset - (osrLocal.index() + size - 1) * 8;
+                IndexedLocationNode location = IndexedLocationNode.create(ANY_LOCATION, osrLocal.kind(), offset, ConstantNode.forLong(0, graph), graph, 1);
+                ReadNode load = graph.add(new ReadNode(buffer, location, osrLocal.stamp(), BarrierType.NONE, false));
+                osrLocal.replaceAndDelete(load);
+                graph.addBeforeFixed(migrationEnd, load);
+            }
+            osrStart.replaceAtUsages(newStart);
+            osrStart.safeDelete();
+        }
+    }
+
+    private void lowerDynamicCounterNode(DynamicCounterNode n) {
+        StructuredGraph graph = n.graph();
+        if (graph.getGuardsStage() == StructuredGraph.GuardsStage.AFTER_FSA) {
+            BenchmarkCounters.lower(n, registers, runtime.getConfig(), runtime.getTarget().wordKind);
+        }
+    }
+
+    private void lowerDeferredForeignCallNode(DeferredForeignCallNode deferred) {
+        StructuredGraph graph = deferred.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);
         }
     }
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMetaAccessProvider.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMetaAccessProvider.java	Wed Mar 05 19:40:15 2014 -0800
@@ -26,9 +26,11 @@
 
 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.hotspot.*;
+import com.oracle.graal.hotspot.replacements.*;
 
 /**
  * HotSpot implementation of {@link MetaAccessProvider}.
@@ -110,14 +112,13 @@
         // are not used (yet).
         final int modifiers = reflectionField.getModifiers();
         final long offset = Modifier.isStatic(modifiers) ? unsafe.staticFieldOffset(reflectionField) : unsafe.objectFieldOffset(reflectionField);
-        final boolean internal = false;
 
         ResolvedJavaType holder = HotSpotResolvedObjectType.fromClass(fieldHolder);
         ResolvedJavaType type = HotSpotResolvedObjectType.fromClass(fieldType);
 
         if (offset != -1) {
             HotSpotResolvedObjectType resolved = (HotSpotResolvedObjectType) holder;
-            return resolved.createField(name, type, offset, modifiers, internal);
+            return resolved.createField(name, type, offset, modifiers);
         } else {
             // TODO this cast will not succeed
             return (ResolvedJavaField) new HotSpotUnresolvedField(holder, name, type);
@@ -284,4 +285,30 @@
         }
         throw GraalInternalError.shouldNotReachHere(Integer.toHexString(reason));
     }
+
+    @Override
+    public long getMemorySize(Constant constant) {
+        if (constant.getKind() == Kind.Object) {
+            HotSpotResolvedObjectType lookupJavaType = (HotSpotResolvedObjectType) this.lookupJavaType(constant);
+
+            if (lookupJavaType == null) {
+                return 0;
+            } else {
+                if (lookupJavaType.isArray()) {
+                    // TODO(tw): Add compressed pointer support.
+                    int length = Array.getLength(constant.asObject());
+                    ResolvedJavaType elementType = lookupJavaType.getComponentType();
+                    Kind elementKind = elementType.getKind();
+                    final int headerSize = HotSpotGraalRuntime.getArrayBaseOffset(elementKind);
+                    int sizeOfElement = HotSpotGraalRuntime.runtime().getTarget().arch.getSizeInBytes(elementKind);
+                    int alignment = HotSpotGraalRuntime.runtime().getTarget().wordSize;
+                    int log2ElementSize = CodeUtil.log2(sizeOfElement);
+                    return NewObjectSnippets.computeArrayAllocationSize(length, alignment, headerSize, log2ElementSize);
+                }
+                return lookupJavaType.instanceSize();
+            }
+        } else {
+            return constant.getKind().getByteCount();
+        }
+    }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodData.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodData.java	Wed Mar 05 19:40:15 2014 -0800
@@ -207,6 +207,14 @@
         return cells * config.dataLayoutCellSize;
     }
 
+    /**
+     * Returns whether profiling ran long enough that the profile information is mature. Other
+     * informational data will still be valid even if the profile isn't mature.
+     */
+    public boolean isProfileMature() {
+        return runtime().getCompilerToVM().isMature(metaspaceMethodData);
+    }
+
     @Override
     public String toString() {
         StringBuilder sb = new StringBuilder();
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotNmethod.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotNmethod.java	Wed Mar 05 19:40:15 2014 -0800
@@ -115,25 +115,11 @@
         return true;
     }
 
-    public Object executeParallel(int dimX, int dimY, int dimZ, Object... args) throws InvalidInstalledCodeException {
-
-        // For HSAIL, we do not pass the iteration variable, it comes from the workitemid
-        // assert checkArgs(args);
-
-        assert isExternal(); // for now
-
-        return runtime().getCompilerToGPU().executeParallelMethodVarargs(dimX, dimY, dimZ, args, this);
-
-    }
-
     @Override
     public Object executeVarargs(Object... args) throws InvalidInstalledCodeException {
         assert checkArgs(args);
-        if (isExternal()) {
-            return runtime().getCompilerToGPU().executeExternalMethodVarargs(args, this);
-        } else {
-            return runtime().getCompilerToVM().executeCompiledMethodVarargs(args, this);
-        }
+        assert !isExternal();
+        return runtime().getCompilerToVM().executeCompiledMethodVarargs(args, this);
     }
 
     @Override
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotProfilingInfo.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotProfilingInfo.java	Wed Mar 05 19:40:15 2014 -0800
@@ -34,6 +34,7 @@
     private final HotSpotMethodData methodData;
     private final HotSpotResolvedJavaMethod method;
 
+    private boolean isMature;
     private int position;
     private int hintPosition;
     private int hintBCI;
@@ -47,6 +48,7 @@
         this.method = method;
         this.includeNormal = includeNormal;
         this.includeOSR = includeOSR;
+        this.isMature = methodData.isProfileMature();
         hintPosition = 0;
         hintBCI = -1;
     }
@@ -58,24 +60,36 @@
 
     @Override
     public JavaTypeProfile getTypeProfile(int bci) {
+        if (!isMature) {
+            return null;
+        }
         findBCI(bci, false);
         return dataAccessor.getTypeProfile(methodData, position);
     }
 
     @Override
     public JavaMethodProfile getMethodProfile(int bci) {
+        if (!isMature) {
+            return null;
+        }
         findBCI(bci, false);
         return dataAccessor.getMethodProfile(methodData, position);
     }
 
     @Override
     public double getBranchTakenProbability(int bci) {
+        if (!isMature) {
+            return -1;
+        }
         findBCI(bci, false);
         return dataAccessor.getBranchTakenProbability(methodData, position);
     }
 
     @Override
     public double[] getSwitchProbabilities(int bci) {
+        if (!isMature) {
+            return null;
+        }
         findBCI(bci, false);
         return dataAccessor.getSwitchProbabilities(methodData, position);
     }
@@ -94,6 +108,9 @@
 
     @Override
     public int getExecutionCount(int bci) {
+        if (!isMature) {
+            return -1;
+        }
         findBCI(bci, false);
         return dataAccessor.getExecutionCount(methodData, position);
     }
@@ -172,11 +189,20 @@
 
     @Override
     public boolean isMature() {
-        return true;
+        return isMature;
+    }
+
+    public void ignoreMature() {
+        isMature = true;
     }
 
     @Override
     public String toString() {
         return "HotSpotProfilingInfo<" + MetaUtil.profileToString(this, null, "; ") + ">";
     }
+
+    @Override
+    public void setMature() {
+        isMature = true;
+    }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java	Wed Mar 05 19:40:15 2014 -0800
@@ -24,7 +24,9 @@
 
 import static com.oracle.graal.api.meta.MetaUtil.*;
 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.*;
@@ -44,41 +46,40 @@
  */
 public class HotSpotResolvedJavaField extends CompilerObject implements ResolvedJavaField {
 
-    // Must not conflict with any fields flags used by the VM - the assertion in the constructor
-    // checks this assumption
-    private static final int FIELD_INTERNAL_FLAG = 0x80000000;
-
     private static final long serialVersionUID = 7692985878836955683L;
     private final HotSpotResolvedObjectType holder;
     private final String name;
-    private final JavaType type;
+    private JavaType type;
     private final int offset;
-    private final int modifiers;
     private Constant constant;
 
-    public HotSpotResolvedJavaField(HotSpotResolvedObjectType holder, String name, JavaType type, long offset, int modifiers, boolean internal) {
-        assert (modifiers & FIELD_INTERNAL_FLAG) == 0;
+    /**
+     * The {@linkplain HotSpotResolvedObjectType#getReflectionFieldModifiers() reflection} modifiers
+     * for this field plus the {@link #FIELD_INTERNAL_FLAG} if it applies.
+     */
+    /**
+     * This value contains all flags as stored in the VM including internal ones.
+     */
+    private final int modifiers;
+
+    public HotSpotResolvedJavaField(HotSpotResolvedObjectType holder, String name, JavaType type, long offset, int modifiers) {
         this.holder = holder;
         this.name = name;
         this.type = type;
         assert offset != -1;
         assert offset == (int) offset : "offset larger than int";
         this.offset = (int) offset;
-        if (internal) {
-            this.modifiers = modifiers | FIELD_INTERNAL_FLAG;
-        } else {
-            this.modifiers = modifiers;
-        }
+        this.modifiers = modifiers;
     }
 
     @Override
     public int getModifiers() {
-        return modifiers & Modifier.fieldModifiers();
+        return modifiers & getReflectionFieldModifiers();
     }
 
     @Override
     public boolean isInternal() {
-        return (modifiers & FIELD_INTERNAL_FLAG) != 0;
+        return (modifiers & runtime().getConfig().jvmAccFieldInternal) != 0;
     }
 
     /**
@@ -118,42 +119,52 @@
         return false;
     }
 
-    private static final List<ResolvedJavaField> notEmbeddable = new ArrayList<>();
-
-    private static void addResolvedToSet(Field field) {
-        MetaAccessProvider metaAccess = runtime().getHostProviders().getMetaAccess();
-        notEmbeddable.add(metaAccess.lookupJavaField(field));
-    }
+    /**
+     * Separate out the static initialization to eliminate cycles between clinit and other locks
+     * that could lead to deadlock. Static code that doesn't call back into type or field machinery
+     * is probably ok but anything else should be made lazy.
+     */
+    static class Embeddable {
 
-    static {
-        try {
-            addResolvedToSet(Boolean.class.getDeclaredField("TRUE"));
-            addResolvedToSet(Boolean.class.getDeclaredField("FALSE"));
+        /**
+         * @return Return true if it's ok to embed the value of {@code field}.
+         */
+        public static boolean test(HotSpotResolvedJavaField field) {
+            return !ImmutableCode.getValue() || !fields.contains(field);
+        }
 
-            Class<?> characterCacheClass = Character.class.getDeclaredClasses()[0];
-            assert "java.lang.Character$CharacterCache".equals(characterCacheClass.getName());
-            addResolvedToSet(characterCacheClass.getDeclaredField("cache"));
+        private static final List<ResolvedJavaField> fields = new ArrayList<>();
+        static {
+            try {
+                MetaAccessProvider metaAccess = runtime().getHostProviders().getMetaAccess();
+                fields.add(metaAccess.lookupJavaField(Boolean.class.getDeclaredField("TRUE")));
+                fields.add(metaAccess.lookupJavaField(Boolean.class.getDeclaredField("FALSE")));
 
-            Class<?> byteCacheClass = Byte.class.getDeclaredClasses()[0];
-            assert "java.lang.Byte$ByteCache".equals(byteCacheClass.getName());
-            addResolvedToSet(byteCacheClass.getDeclaredField("cache"));
+                Class<?> characterCacheClass = Character.class.getDeclaredClasses()[0];
+                assert "java.lang.Character$CharacterCache".equals(characterCacheClass.getName());
+                fields.add(metaAccess.lookupJavaField(characterCacheClass.getDeclaredField("cache")));
 
-            Class<?> shortCacheClass = Short.class.getDeclaredClasses()[0];
-            assert "java.lang.Short$ShortCache".equals(shortCacheClass.getName());
-            addResolvedToSet(shortCacheClass.getDeclaredField("cache"));
+                Class<?> byteCacheClass = Byte.class.getDeclaredClasses()[0];
+                assert "java.lang.Byte$ByteCache".equals(byteCacheClass.getName());
+                fields.add(metaAccess.lookupJavaField(byteCacheClass.getDeclaredField("cache")));
+
+                Class<?> shortCacheClass = Short.class.getDeclaredClasses()[0];
+                assert "java.lang.Short$ShortCache".equals(shortCacheClass.getName());
+                fields.add(metaAccess.lookupJavaField(shortCacheClass.getDeclaredField("cache")));
 
-            Class<?> integerCacheClass = Integer.class.getDeclaredClasses()[0];
-            assert "java.lang.Integer$IntegerCache".equals(integerCacheClass.getName());
-            addResolvedToSet(integerCacheClass.getDeclaredField("cache"));
+                Class<?> integerCacheClass = Integer.class.getDeclaredClasses()[0];
+                assert "java.lang.Integer$IntegerCache".equals(integerCacheClass.getName());
+                fields.add(metaAccess.lookupJavaField(integerCacheClass.getDeclaredField("cache")));
 
-            Class<?> longCacheClass = Long.class.getDeclaredClasses()[0];
-            assert "java.lang.Long$LongCache".equals(longCacheClass.getName());
-            addResolvedToSet(longCacheClass.getDeclaredField("cache"));
+                Class<?> longCacheClass = Long.class.getDeclaredClasses()[0];
+                assert "java.lang.Long$LongCache".equals(longCacheClass.getName());
+                fields.add(metaAccess.lookupJavaField(longCacheClass.getDeclaredField("cache")));
 
-            addResolvedToSet(Throwable.class.getDeclaredField("UNASSIGNED_STACK"));
-            addResolvedToSet(Throwable.class.getDeclaredField("SUPPRESSED_SENTINEL"));
-        } catch (SecurityException | NoSuchFieldException e) {
-            throw new GraalInternalError(e);
+                fields.add(metaAccess.lookupJavaField(Throwable.class.getDeclaredField("UNASSIGNED_STACK")));
+                fields.add(metaAccess.lookupJavaField(Throwable.class.getDeclaredField("SUPPRESSED_SENTINEL")));
+            } catch (SecurityException | NoSuchFieldException e) {
+                throw new GraalInternalError(e);
+            }
         }
     }
 
@@ -161,10 +172,7 @@
      * in AOT mode, some fields should never be embedded even for snippets/replacements.
      */
     private boolean isEmbeddable() {
-        if (ImmutableCode.getValue() && notEmbeddable.contains(this)) {
-            return false;
-        }
-        return true;
+        return Embeddable.test(this);
     }
 
     private static final String SystemClassName = "Ljava/lang/System;";
@@ -180,7 +188,7 @@
         assert !ImmutableCode.getValue() || isCalledForSnippets() : receiver;
 
         if (receiver == null) {
-            assert Modifier.isStatic(modifiers);
+            assert isStatic(modifiers);
             if (constant == null) {
                 if (holder.isInitialized() && !holder.getName().equals(SystemClassName) && isEmbeddable()) {
                     if (Modifier.isFinal(getModifiers())) {
@@ -194,13 +202,13 @@
              * for non-static final fields, we must assume that they are only initialized if they
              * have a non-default value.
              */
-            assert !Modifier.isStatic(modifiers);
+            assert !isStatic(modifiers);
             Object object = receiver.asObject();
 
             // Canonicalization may attempt to process an unsafe read before
-            // processing a guard (e.g. a type check) for this read
-            // so we need to type check the object being read
-            if (isInObject(object)) {
+            // 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())) {
                     Constant value = readValue(receiver);
                     if (assumeNonStaticFinalFieldsAsFinal(object.getClass()) || !value.isDefaultForKind()) {
@@ -226,21 +234,27 @@
 
     /**
      * 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)) {
+            return false;
+        }
         return getDeclaringClass().isAssignableFrom(HotSpotResolvedObjectType.fromClass(object.getClass()));
     }
 
     @Override
     public Constant readValue(Constant receiver) {
         if (receiver == null) {
-            assert Modifier.isStatic(modifiers);
+            assert isStatic(modifiers);
             if (holder.isInitialized()) {
                 return runtime().getHostProviders().getConstantReflection().readUnsafeConstant(getKind(), holder.mirror(), offset, getKind() == Kind.Object);
             }
             return null;
         } else {
-            assert !Modifier.isStatic(modifiers);
+            assert !isStatic(modifiers);
             Object object = receiver.asObject();
             assert object != null && isInObject(object);
             return runtime().getHostProviders().getConstantReflection().readUnsafeConstant(getKind(), object, offset, getKind() == Kind.Object);
@@ -282,6 +296,13 @@
 
     @Override
     public JavaType getType() {
+        if (!(type instanceof ResolvedJavaType)) {
+            // Don't allow unresolved types to hang around forever
+            ResolvedJavaType resolved = type.resolve(holder);
+            if (resolved != null) {
+                type = resolved;
+            }
+        }
         return type;
     }
 
@@ -296,11 +317,7 @@
 
     @Override
     public boolean isSynthetic() {
-        Field javaField = toJava();
-        if (javaField != null) {
-            return javaField.isSynthetic();
-        }
-        return false;
+        return (runtime().getConfig().syntheticFlag & modifiers) != 0;
     }
 
     /**
@@ -323,6 +340,9 @@
     }
 
     private Field toJava() {
+        if (isInternal()) {
+            return null;
+        }
         try {
             return holder.mirror().getDeclaredField(name);
         } catch (NoSuchFieldException e) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java	Wed Mar 05 19:40:15 2014 -0800
@@ -157,10 +157,18 @@
         return getMetaspaceMethodConstant();
     }
 
+    /**
+     * Gets the complete set of modifiers for this method which includes the JVM specification
+     * modifiers as well as the HotSpot internal modifiers.
+     */
+    public int getAllModifiers() {
+        HotSpotVMConfig config = runtime().getConfig();
+        return unsafe.getInt(metaspaceMethod + config.methodAccessFlagsOffset);
+    }
+
     @Override
     public int getModifiers() {
-        HotSpotVMConfig config = runtime().getConfig();
-        return unsafe.getInt(metaspaceMethod + config.methodAccessFlagsOffset) & Modifier.methodModifiers();
+        return getAllModifiers() & Modifier.methodModifiers();
     }
 
     @Override
@@ -237,27 +245,9 @@
     }
 
     /**
-     * Returns true if this method has a ForceInline annotation.
-     * 
-     * @return true if ForceInline annotation present, false otherwise
-     */
-    public boolean isForceInline() {
-        return forceInline;
-    }
-
-    /**
-     * Returns true if this method has a DontInline annotation.
-     * 
-     * @return true if DontInline annotation present, false otherwise
-     */
-    public boolean isDontInline() {
-        return dontInline;
-    }
-
-    /**
      * Manually adds a DontInline annotation to this method.
      */
-    public void setDontInline() {
+    public void setNotInlineable() {
         dontInline = true;
         runtime().getCompilerToVM().doNotInlineOrCompile(metaspaceMethod);
     }
@@ -426,25 +416,8 @@
 
     @Override
     public boolean isSynthetic() {
-        if (isConstructor()) {
-            Constructor<?> javaConstructor = toJavaConstructor();
-            return javaConstructor == null ? false : javaConstructor.isSynthetic();
-        }
-
-        // Cannot use toJava() as it ignores the return type
-        HotSpotSignature sig = getSignature();
-        JavaType[] sigTypes = MetaUtil.signatureToTypes(sig, null);
-        MetaAccessProvider metaAccess = runtime().getHostProviders().getMetaAccess();
-        for (Method method : holder.mirror().getDeclaredMethods()) {
-            if (method.getName().equals(name)) {
-                if (metaAccess.lookupJavaType(method.getReturnType()).equals(sig.getReturnType(holder))) {
-                    if (matches(metaAccess, sigTypes, method.getParameterTypes())) {
-                        return method.isSynthetic();
-                    }
-                }
-            }
-        }
-        return false;
+        int modifiers = getAllModifiers();
+        return (runtime().getConfig().syntheticFlag & modifiers) != 0;
     }
 
     public boolean isDefault() {
@@ -476,18 +449,6 @@
         return result;
     }
 
-    private static boolean matches(MetaAccessProvider metaAccess, JavaType[] sigTypes, Class<?>[] parameterTypes) {
-        if (parameterTypes.length == sigTypes.length) {
-            for (int i = 0; i < parameterTypes.length; i++) {
-                if (!metaAccess.lookupJavaType(parameterTypes[i]).equals(sigTypes[i])) {
-                    return false;
-                }
-            }
-            return true;
-        }
-        return false;
-    }
-
     private Method toJava() {
         try {
             return holder.mirror().getDeclaredMethod(name, signatureToTypes());
@@ -509,7 +470,15 @@
         if (dontInline) {
             return false;
         }
-        return runtime().getCompilerToVM().isMethodCompilable(metaspaceMethod);
+        return runtime().getCompilerToVM().canInlineMethod(metaspaceMethod);
+    }
+
+    @Override
+    public boolean shouldBeInlined() {
+        if (forceInline) {
+            return true;
+        }
+        return runtime().getCompilerToVM().shouldInlineMethod(metaspaceMethod);
     }
 
     @Override
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java	Wed Mar 05 19:40:15 2014 -0800
@@ -53,7 +53,7 @@
      */
     private NodeClass nodeClass;
 
-    private HashMap<Long, ResolvedJavaField> fieldCache;
+    private HashMap<Long, HotSpotResolvedJavaField> fieldCache;
     private HashMap<Long, HotSpotResolvedJavaMethod> methodCache;
     private HotSpotResolvedJavaField[] instanceFields;
     private ResolvedJavaType[] interfaces;
@@ -418,16 +418,21 @@
         return method;
     }
 
-    public synchronized ResolvedJavaField createField(String fieldName, JavaType type, long offset, int rawFlags, boolean internal) {
-        ResolvedJavaField result = null;
+    /**
+     * Gets the mask used to filter out HotSpot internal flags for fields when a {@link Field}
+     * object is created. This is the value of {@code JVM_RECOGNIZED_FIELD_MODIFIERS} in
+     * {@code jvm.h}, <b>not</b> {@link Modifier#fieldModifiers()}.
+     */
+    public static int getReflectionFieldModifiers() {
+        return runtime().getConfig().recognizedFieldModifiers;
+    }
 
-        /*
-         * Filter out flags used internally by HotSpot, to get a canonical id value. When a field is
-         * created from a java.lang.reflect.Field, these flags would not be available anyway.
-         */
-        int flags = rawFlags & fieldModifiers();
+    public synchronized HotSpotResolvedJavaField createField(String fieldName, JavaType type, long offset, int rawFlags) {
+        HotSpotResolvedJavaField result = null;
 
-        long id = offset + ((long) flags << 32);
+        final int flags = rawFlags & getReflectionFieldModifiers();
+
+        final long id = offset + ((long) flags << 32);
 
         // (thomaswue) Must cache the fields, because the local load elimination only works if the
         // objects from two field lookups are identical.
@@ -438,10 +443,12 @@
         }
 
         if (result == null) {
-            result = new HotSpotResolvedJavaField(this, fieldName, type, offset, flags, internal);
+            result = new HotSpotResolvedJavaField(this, fieldName, type, offset, rawFlags);
             fieldCache.put(id, result);
         } else {
             assert result.getName().equals(fieldName);
+            // assert result.getType().equals(type);
+            assert result.offset() == offset;
             assert result.getModifiers() == flags;
         }
 
@@ -453,8 +460,134 @@
         return ((HotSpotResolvedJavaMethod) method).uniqueConcreteMethod();
     }
 
+    /**
+     * This class represents the field information for one field contained in the fields array of an
+     * {@code InstanceKlass}. The implementation is similar to the native {@code FieldInfo} class.
+     */
+    private class FieldInfo {
+        /**
+         * Native pointer into the array of Java shorts.
+         */
+        private final long metaspaceData;
+
+        /**
+         * Creates a field info for the field in the fields array at index {@code index}.
+         * 
+         * @param index index to the fields array
+         */
+        public FieldInfo(int index) {
+            HotSpotVMConfig config = runtime().getConfig();
+            // Get Klass::_fields
+            final long metaspaceFields = unsafe.getAddress(metaspaceKlass() + config.instanceKlassFieldsOffset);
+            assert config.fieldInfoFieldSlots == 6 : "revisit the field parsing code";
+            metaspaceData = metaspaceFields + config.arrayU2DataOffset + config.fieldInfoFieldSlots * 2 * index;  // TODO
+            // Short.BYTES
+        }
+
+        private int getAccessFlags() {
+            return readFieldSlot(runtime().getConfig().fieldInfoAccessFlagsOffset);
+        }
+
+        private int getNameIndex() {
+            return readFieldSlot(runtime().getConfig().fieldInfoNameIndexOffset);
+        }
+
+        private int getSignatureIndex() {
+            return readFieldSlot(runtime().getConfig().fieldInfoSignatureIndexOffset);
+        }
+
+        public int getOffset() {
+            HotSpotVMConfig config = runtime().getConfig();
+            final int lowPacked = readFieldSlot(config.fieldInfoLowPackedOffset);
+            final int highPacked = readFieldSlot(config.fieldInfoHighPackedOffset);
+            final int offset = ((highPacked << Short.SIZE) | lowPacked) >> config.fieldInfoTagSize;
+            return offset;
+        }
+
+        /**
+         * Helper method to read an entry (slot) from the field array. Currently field info is laid
+         * on top an array of Java shorts.
+         */
+        private int readFieldSlot(int index) {
+            return unsafe.getChar(metaspaceData + 2 * index);  // TODO Short.BYTES
+        }
+
+        /**
+         * Returns the name of this field as a {@link String}. If the field is an internal field the
+         * name index is pointing into the vmSymbols table.
+         */
+        public String getName() {
+            final int nameIndex = getNameIndex();
+            return isInternal() ? HotSpotVmSymbols.symbolAt(nameIndex) : constantPool().lookupUtf8(nameIndex);
+        }
+
+        /**
+         * Returns the signature of this field as {@link String}. If the field is an internal field
+         * the signature index is pointing into the vmSymbols table.
+         */
+        public String getSignature() {
+            final int signatureIndex = getSignatureIndex();
+            return isInternal() ? HotSpotVmSymbols.symbolAt(signatureIndex) : constantPool().lookupUtf8(signatureIndex);
+        }
+
+        public JavaType getType() {
+            String signature = getSignature();
+            Kind kind = Kind.fromTypeString(signature);
+
+            JavaType type;
+            if (kind.isPrimitive()) {
+                type = HotSpotResolvedPrimitiveType.fromKind(kind);
+            } else {
+                String signatureClass = getNameForClassForName(signature);
+                Class<?> c = null;
+                try {
+                    // This class is the accessing class so we use its classloader.
+                    c = Class.forName(signatureClass, false, mirror().getClassLoader());
+                } catch (ClassNotFoundException e) {
+                    throw new GraalInternalError(e);
+                }
+                if (c == null) {
+                    type = HotSpotUnresolvedJavaType.create(signature);
+                } else {
+                    type = HotSpotResolvedObjectType.fromClass(c);
+                }
+            }
+            return type;
+        }
+
+        /**
+         * Returns a name that is suitable to be passed to {@link Class#forName}.
+         */
+        private String getNameForClassForName(String name) {
+            // If this is an array type just return it.
+            if (name.charAt(0) == '[') {
+                return name.replace('/', '.');
+            }
+
+            // Decode name if necessary.
+            if (name.charAt(name.length() - 1) == ';') {
+                assert name.charAt(0) == 'L';
+                return name.substring(1, name.length() - 1).replace('/', '.');
+            }
+
+            // Primitive type name.
+            return name;
+        }
+
+        private boolean isInternal() {
+            return (getAccessFlags() & runtime().getConfig().jvmAccFieldInternal) != 0;
+        }
+
+        public boolean isStatic() {
+            return Modifier.isStatic(getAccessFlags());
+        }
+
+        public boolean hasGenericSignature() {
+            return (getAccessFlags() & runtime().getConfig().jvmAccFieldHasGenericSignature) != 0;
+        }
+    }
+
     private static class OffsetComparator implements Comparator<HotSpotResolvedJavaField> {
-
         @Override
         public int compare(HotSpotResolvedJavaField o1, HotSpotResolvedJavaField o2) {
             return o1.offset() - o2.offset();
@@ -467,8 +600,24 @@
             if (isArray() || isInterface()) {
                 instanceFields = new HotSpotResolvedJavaField[0];
             } else {
-                HotSpotResolvedJavaField[] myFields = runtime().getCompilerToVM().getInstanceFields(this);
-                Arrays.sort(myFields, new OffsetComparator());
+                final int fieldCount = getFieldCount();
+                ArrayList<HotSpotResolvedJavaField> fieldsArray = new ArrayList<>(fieldCount);
+
+                for (int i = 0; i < fieldCount; i++) {
+                    FieldInfo field = new FieldInfo(i);
+
+                    // We are only interested in instance fields.
+                    if (!field.isStatic()) {
+                        HotSpotResolvedJavaField resolvedJavaField = createField(field.getName(), field.getType(), field.getOffset(), field.getAccessFlags());
+                        fieldsArray.add(resolvedJavaField);
+                    }
+                }
+
+                // TODO use in 1.8: fieldsArray.sort(new OffsetComparator());
+                Collections.sort(fieldsArray, new OffsetComparator());
+
+                HotSpotResolvedJavaField[] myFields = fieldsArray.toArray(new HotSpotResolvedJavaField[0]);
+
                 if (javaClass != Object.class) {
                     HotSpotResolvedJavaField[] superFields = (HotSpotResolvedJavaField[]) getSuperclass().getInstanceFields(true);
                     HotSpotResolvedJavaField[] fields = Arrays.copyOf(superFields, superFields.length + myFields.length);
@@ -478,6 +627,7 @@
                     assert myFields.length == 0 : "java.lang.Object has fields!";
                     instanceFields = myFields;
                 }
+
             }
         }
         if (!includeSuperclasses) {
@@ -496,6 +646,29 @@
         return instanceFields;
     }
 
+    /**
+     * Returns the actual field count of this class's internal {@code InstanceKlass::_fields} array
+     * by walking the array and discounting the generic signature slots at the end of the array.
+     * 
+     * <p>
+     * See {@code FieldStreamBase::init_generic_signature_start_slot}
+     */
+    private int getFieldCount() {
+        HotSpotVMConfig config = runtime().getConfig();
+        final long metaspaceFields = unsafe.getAddress(metaspaceKlass() + config.instanceKlassFieldsOffset);
+        int metaspaceFieldsLength = unsafe.getInt(metaspaceFields + config.arrayU1LengthOffset);
+        int fieldCount = 0;
+
+        for (int i = 0, index = 0; i < metaspaceFieldsLength; i += config.fieldInfoFieldSlots, index++) {
+            FieldInfo field = new FieldInfo(index);
+            if (field.hasGenericSignature()) {
+                metaspaceFieldsLength--;
+            }
+            fieldCount++;
+        }
+        return fieldCount;
+    }
+
     @Override
     public Class<?> mirror() {
         return javaClass;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotUnresolvedJavaType.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotUnresolvedJavaType.java	Wed Mar 05 19:40:15 2014 -0800
@@ -42,6 +42,26 @@
         this.dimensions = dimensions;
     }
 
+    /**
+     * Creates an unresolved type for a valid {@link JavaType#getName() type name}.
+     */
+    public static HotSpotUnresolvedJavaType create(String name) {
+        int dims = 0;
+        int startIndex = 0;
+        while (name.charAt(startIndex) == '[') {
+            startIndex++;
+            dims++;
+        }
+
+        // Decode name if necessary.
+        if (name.charAt(name.length() - 1) == ';') {
+            assert name.charAt(startIndex) == 'L';
+            return new HotSpotUnresolvedJavaType(name, name.substring(startIndex + 1, name.length() - 1), dims);
+        } else {
+            return new HotSpotUnresolvedJavaType(HotSpotUnresolvedJavaType.getFullName(name, dims), name, dims);
+        }
+    }
+
     public static String getFullName(String name, int dimensions) {
         StringBuilder str = new StringBuilder(name.length() + dimensions + 2);
         for (int i = 0; i < dimensions; i++) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nfi/HotSpotNativeFunctionHandle.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,98 @@
+/*
+ * 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.nfi;
+
+import java.util.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+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;
+
+    public HotSpotNativeFunctionHandle(InstalledCode code, String name, Class... argumentTypes) {
+        this.argumentTypes = argumentTypes;
+        this.name = name;
+        this.code = code;
+    }
+
+    private void traceCall(Object... args) {
+        try (Scope s = Debug.scope("GNFI")) {
+            if (Debug.isLogEnabled()) {
+                Debug.log("[GNFI] %s%s", name, Arrays.toString(args));
+            }
+        }
+    }
+
+    private void traceResult(Object result) {
+        try (Scope s = Debug.scope("GNFI")) {
+            if (Debug.isLogEnabled()) {
+                Debug.log("[GNFI] %s --> %s", name, result);
+            }
+        }
+    }
+
+    @Override
+    public Object call(Object... args) {
+        assert checkArgs(args);
+        try {
+            traceCall(args);
+            Object res = code.execute(args, null, null);
+            traceResult(res);
+            return res;
+        } catch (InvalidInstalledCodeException e) {
+            throw GraalInternalError.shouldNotReachHere("Execution of GNFI Callstub failed: " + name);
+        }
+    }
+
+    private boolean checkArgs(Object... args) {
+        assert args.length == argumentTypes.length : this + " expected " + argumentTypes.length + " args, got " + args.length;
+        for (int i = 0; i < argumentTypes.length; i++) {
+            Object arg = args[i];
+            assert arg != null;
+            Class expectedType = argumentTypes[i];
+            if (expectedType.isPrimitive()) {
+                Kind kind = Kind.fromJavaClass(expectedType);
+                expectedType = kind.toBoxedJavaClass();
+            }
+            assert expectedType == arg.getClass() : this + " expected arg " + i + " to be " + expectedType.getName() + ", not " + arg.getClass().getName();
+
+        }
+        return true;
+    }
+
+    public InstalledCode getCallStub() {
+        return code;
+    }
+
+    @Override
+    public String toString() {
+        return name + Arrays.toString(argumentTypes);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nfi/HotSpotNativeFunctionInterface.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,192 @@
+/*
+ * 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.nfi;
+
+import static com.oracle.graal.api.code.CodeUtil.*;
+import static com.oracle.graal.graph.UnsafeAccess.*;
+import static com.oracle.graal.hotspot.nfi.NativeCallStubGraphBuilder.*;
+
+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.meta.ProfilingInfo.TriState;
+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.lir.asm.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.phases.*;
+import com.oracle.graal.phases.tiers.*;
+
+public class HotSpotNativeFunctionInterface implements NativeFunctionInterface {
+
+    private final HotSpotProviders providers;
+    private final Backend backend;
+    private final HotSpotNativeLibraryHandle rtldDefault;
+    private final HotSpotNativeFunctionPointer libraryLoadFunctionPointer;
+    private final HotSpotNativeFunctionPointer functionLookupFunctionPointer;
+    private final RawNativeCallNodeFactory factory;
+
+    private HotSpotNativeFunctionHandle libraryLookupFunctionHandle;
+    private HotSpotNativeFunctionHandle dllLookupFunctionHandle;
+
+    public HotSpotNativeFunctionInterface(HotSpotProviders providers, RawNativeCallNodeFactory factory, Backend backend, long dlopen, long dlsym, long rtldDefault) {
+        this.rtldDefault = rtldDefault == HotSpotVMConfig.INVALID_RTLD_DEFAULT_HANDLE ? null : new HotSpotNativeLibraryHandle("RTLD_DEFAULT", rtldDefault);
+        this.providers = providers;
+        this.backend = backend;
+        this.factory = factory;
+        this.libraryLoadFunctionPointer = new HotSpotNativeFunctionPointer(dlopen, "os::dll_load");
+        this.functionLookupFunctionPointer = new HotSpotNativeFunctionPointer(dlsym, "os::dll_lookup");
+    }
+
+    @Override
+    public HotSpotNativeLibraryHandle getLibraryHandle(String libPath) {
+        if (libraryLookupFunctionHandle == null) {
+            libraryLookupFunctionHandle = createHandle(libraryLoadFunctionPointer, long.class, long.class, long.class, int.class);
+        }
+
+        int ebufLen = 1024;
+        // Allocating a single chunk for both the error message buffer and the
+        // file name simplifies deallocation below.
+        long buffer = unsafe.allocateMemory(ebufLen + libPath.length() + 1);
+        long ebuf = buffer;
+        long libPathCString = writeCString(libPath, buffer + ebufLen);
+        try {
+            long handle = (long) libraryLookupFunctionHandle.call(libPathCString, ebuf, ebufLen);
+            if (handle == 0) {
+                throw new UnsatisfiedLinkError(libPath);
+            }
+            return new HotSpotNativeLibraryHandle(libPath, handle);
+        } finally {
+            unsafe.freeMemory(buffer);
+        }
+    }
+
+    @Override
+    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) {
+        HotSpotNativeFunctionPointer functionPointer = null;
+        for (NativeLibraryHandle libraryHandle : libraries) {
+            functionPointer = lookupFunctionPointer(name, libraryHandle, false);
+            if (functionPointer != null) {
+                return createHandle(functionPointer, returnType, argumentTypes);
+            }
+        }
+        // Fall back to default library path
+        return getFunctionHandle(name, returnType, argumentTypes);
+    }
+
+    @Override
+    public HotSpotNativeFunctionHandle getFunctionHandle(String name, Class returnType, Class... argumentTypes) {
+        if (rtldDefault == null) {
+            throw new UnsatisfiedLinkError(name);
+        }
+        return getFunctionHandle(rtldDefault, name, returnType, argumentTypes);
+    }
+
+    private HotSpotNativeFunctionPointer lookupFunctionPointer(String name, NativeLibraryHandle library, boolean linkageErrorIfMissing) {
+        if (name == null || library == null) {
+            throw new NullPointerException();
+        }
+
+        if (dllLookupFunctionHandle == null) {
+            dllLookupFunctionHandle = createHandle(functionLookupFunctionPointer, long.class, long.class, long.class);
+        }
+        long nameCString = createCString(name);
+        try {
+            long functionPointer = (long) dllLookupFunctionHandle.call(((HotSpotNativeLibraryHandle) library).value, nameCString);
+            if (functionPointer == 0L) {
+                if (!linkageErrorIfMissing) {
+                    return null;
+                }
+                throw new UnsatisfiedLinkError(name);
+            }
+            return new HotSpotNativeFunctionPointer(functionPointer, name);
+        } finally {
+            unsafe.freeMemory(nameCString);
+        }
+    }
+
+    @Override
+    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) {
+        HotSpotNativeFunctionPointer hs = (HotSpotNativeFunctionPointer) functionPointer;
+        InstalledCode code = installNativeFunctionStub(hs.value, returnType, argumentTypes);
+        return new HotSpotNativeFunctionHandle(code, hs.name, argumentTypes);
+    }
+
+    /**
+     * Creates and installs a stub for calling a native function.
+     */
+    private InstalledCode installNativeFunctionStub(long functionPointer, Class returnType, Class... argumentTypes) {
+        StructuredGraph g = getGraph(providers, factory, functionPointer, returnType, argumentTypes);
+        Suites suites = providers.getSuites().createSuites();
+        PhaseSuite<HighTierContext> phaseSuite = backend.getSuites().getDefaultGraphBuilderSuite().copy();
+        CallingConvention cc = getCallingConvention(providers.getCodeCache(), Type.JavaCallee, g.method(), false);
+        CompilationResult compResult = GraalCompiler.compileGraph(g, cc, g.method(), providers, backend, backend.getTarget(), null, phaseSuite, OptimisticOptimizations.ALL,
+                        DefaultProfilingInfo.get(TriState.UNKNOWN), null, suites, true, new CompilationResult(), CompilationResultBuilderFactory.Default);
+        InstalledCode installedCode;
+        try (Scope s = Debug.scope("CodeInstall", providers.getCodeCache(), g.method())) {
+            installedCode = providers.getCodeCache().addMethod(g.method(), compResult, null);
+        }
+        return installedCode;
+    }
+
+    @Override
+    public HotSpotNativeFunctionPointer getFunctionPointer(NativeLibraryHandle[] libraries, String name) {
+        for (NativeLibraryHandle libraryHandle : libraries) {
+            HotSpotNativeFunctionPointer functionPointer = lookupFunctionPointer(name, libraryHandle, false);
+            if (functionPointer != null) {
+                return functionPointer;
+            }
+        }
+        // Fall back to default library path
+        if (rtldDefault == null) {
+            throw new UnsatisfiedLinkError(name);
+        }
+        return lookupFunctionPointer(name, rtldDefault, true);
+    }
+
+    public boolean isDefaultLibrarySearchSupported() {
+        return rtldDefault != null;
+    }
+
+    @Override
+    public NativeFunctionPointer getNativeFunctionPointerFromRawValue(long rawValue) {
+        return new HotSpotNativeFunctionPointer(rawValue, null);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nfi/HotSpotNativeFunctionPointer.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,52 @@
+/*
+ * 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.nfi;
+
+import com.oracle.graal.api.code.*;
+
+public class HotSpotNativeFunctionPointer implements NativeFunctionPointer {
+
+    final long value;
+    final String name;
+
+    public HotSpotNativeFunctionPointer(long value, String name) {
+        if (value == 0) {
+            throw new UnsatisfiedLinkError(name);
+        }
+        this.value = value;
+        this.name = name;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public long getValue() {
+        return value;
+    }
+
+    @Override
+    public String toString() {
+        return name + "@0x" + Long.toHexString(value);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nfi/HotSpotNativeLibraryHandle.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,59 @@
+/*
+ * 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.nfi;
+
+import com.oracle.graal.api.code.*;
+
+public class HotSpotNativeLibraryHandle implements NativeLibraryHandle {
+
+    final long value;
+    final String name;
+
+    public HotSpotNativeLibraryHandle(String name, long handle) {
+        this.name = name;
+        this.value = handle;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj instanceof HotSpotNativeLibraryHandle) {
+            HotSpotNativeLibraryHandle that = (HotSpotNativeLibraryHandle) obj;
+            return that.value == value;
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        return (int) value;
+    }
+
+    @Override
+    public String toString() {
+        return name + "@" + value;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nfi/NativeCallStubGraphBuilder.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,180 @@
+/*
+ * 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.nfi;
+
+import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
+
+import java.util.*;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.hotspot.meta.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.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.*;
+
+/**
+ * Utility creating a graph for a stub used to call a native function.
+ */
+public class NativeCallStubGraphBuilder {
+
+    /**
+     * 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) {
+        try {
+            ResolvedJavaMethod method = providers.getMetaAccess().lookupJavaMethod(NativeCallStubGraphBuilder.class.getMethod("libCall", Object.class, Object.class, Object.class));
+            StructuredGraph g = new StructuredGraph(method);
+            ParameterNode arg0 = g.unique(new ParameterNode(0, StampFactory.forKind(Kind.Object)));
+            ParameterNode arg1 = g.unique(new ParameterNode(1, StampFactory.forKind(Kind.Object)));
+            ParameterNode arg2 = g.unique(new ParameterNode(2, StampFactory.forKind(Kind.Object)));
+            FrameState frameState = g.add(new FrameState(method, 0, Arrays.asList(new ValueNode[]{arg0, arg1, arg2}), 3, 0, false, false, new ArrayList<MonitorIdNode>(),
+                            new ArrayList<EscapeObjectState>()));
+            g.start().setStateAfter(frameState);
+            List<ValueNode> parameters = new ArrayList<>();
+            FixedWithNextNode fixedWithNext = getParameters(g, arg0, argumentTypes.length, argumentTypes, parameters, providers);
+            Constant functionPointerNode = Constant.forLong(functionPointer);
+
+            ValueNode[] arguments = new ValueNode[parameters.size()];
+
+            for (int i = 0; i < arguments.length; i++) {
+                arguments[i] = parameters.get(i);
+            }
+
+            FixedWithNextNode callNode = g.add(factory.createRawCallNode(getKind(returnType), functionPointerNode, arguments));
+
+            if (fixedWithNext == null) {
+                g.start().setNext(callNode);
+            } else {
+                fixedWithNext.setNext(callNode);
+            }
+
+            // box result
+            BoxNode boxedResult;
+            if (callNode.kind() != Kind.Void) {
+                if (callNode.kind() == Kind.Object) {
+                    throw new IllegalArgumentException("Return type not supported: " + returnType.getName());
+                }
+                ResolvedJavaType type = providers.getMetaAccess().lookupJavaType(callNode.kind().toBoxedJavaClass());
+                boxedResult = g.unique(new BoxNode(callNode, type, callNode.kind()));
+            } else {
+                boxedResult = g.unique(new BoxNode(ConstantNode.forLong(0, g), providers.getMetaAccess().lookupJavaType(Long.class), Kind.Long));
+            }
+
+            ReturnNode returnNode = g.add(new ReturnNode(boxedResult));
+            callNode.setNext(returnNode);
+            (new WordTypeRewriterPhase(providers.getMetaAccess(), 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<ValueNode> args, HotSpotProviders providers) {
+        assert numArgs == argumentTypes.length;
+        FixedWithNextNode last = null;
+        for (int i = 0; i < numArgs; i++) {
+            // load boxed array element:
+            LoadIndexedNode boxedElement = g.add(new LoadIndexedNode(argumentsArray, ConstantNode.forInt(i, g), Kind.Object));
+            if (i == 0) {
+                g.start().setNext(boxedElement);
+                last = boxedElement;
+            } else {
+                last.setNext(boxedElement);
+                last = boxedElement;
+            }
+            Class type = argumentTypes[i];
+            Kind kind = getKind(type);
+            if (kind == Kind.Object) {
+                // array value
+                Kind arrayElementKind = getElementKind(type);
+                LocationIdentity locationIdentity = NamedLocationIdentity.getArrayLocation(arrayElementKind);
+                int displacement = getArrayBaseOffset(arrayElementKind);
+                ConstantNode index = ConstantNode.forInt(0, g);
+                int indexScaling = getArrayIndexScale(arrayElementKind);
+                IndexedLocationNode locationNode = IndexedLocationNode.create(locationIdentity, arrayElementKind, displacement, index, g, indexScaling);
+                Stamp wordStamp = StampFactory.forKind(providers.getCodeCache().getTarget().wordKind);
+                ComputeAddressNode arrayAddress = g.unique(new ComputeAddressNode(boxedElement, locationNode, wordStamp));
+                args.add(arrayAddress);
+            } else {
+                // boxed primitive value
+                try {
+                    ResolvedJavaField field = providers.getMetaAccess().lookupJavaField(kind.toBoxedJavaClass().getDeclaredField("value"));
+                    LoadFieldNode loadFieldNode = g.add(new LoadFieldNode(boxedElement, field));
+                    last.setNext(loadFieldNode);
+                    last = loadFieldNode;
+                    args.add(loadFieldNode);
+                } catch (NoSuchFieldException e) {
+                    throw new GraalInternalError(e);
+                }
+            }
+        }
+        return last;
+    }
+
+    public static Kind getElementKind(Class clazz) {
+        Class componentType = clazz.getComponentType();
+        if (componentType == null) {
+            throw new IllegalArgumentException("Parameter type not supported: " + clazz);
+        }
+        if (componentType.isPrimitive()) {
+            return Kind.fromJavaClass(componentType);
+        }
+        throw new IllegalArgumentException("Parameter type not supported: " + 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) {
+            return Kind.Long;
+        } else if (clazz == char.class || clazz == Character.class) {
+            return Kind.Char;
+        } else if (clazz == byte.class || clazz == Byte.class) {
+            return Kind.Byte;
+        } else if (clazz == float.class || clazz == Float.class) {
+            return Kind.Float;
+        } else if (clazz == double.class || clazz == Double.class) {
+            return Kind.Double;
+        } else if (clazz == int[].class || clazz == long[].class || clazz == char[].class || clazz == byte[].class || clazz == float[].class || clazz == double[].class) {
+            return Kind.Object;
+        } else if (clazz == void.class) {
+            return Kind.Void;
+        } else {
+            throw new IllegalArgumentException("Type not supported: " + clazz);
+        }
+    }
+
+    @SuppressWarnings("unused")
+    public static Object libCall(Object argLoc, Object unused1, Object unused2) {
+        throw GraalInternalError.shouldNotReachHere("GNFI libCall method must not be called");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nfi/RawNativeCallNodeFactory.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,33 @@
+/*
+ * 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.nfi;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.nodes.*;
+
+/**
+ * Factory for creating a node that makes a direct call to a native function pointer.
+ */
+public interface RawNativeCallNodeFactory {
+    FixedWithNextNode createRawCallNode(Kind returnType, Constant functionPointer, ValueNode... args);
+}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassCastNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassCastNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -33,7 +33,7 @@
 /**
  * {@link MacroNode Macro node} for {@link Class#cast(Object)}.
  * 
- * @see ClassSubstitutions#isInstance(Class, Object)
+ * @see ClassSubstitutions#cast(Class, Object)
  */
 public class ClassCastNode extends MacroNode implements Canonicalizable {
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/LoadJavaMirrorWithKlassPhase.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/LoadJavaMirrorWithKlassPhase.java	Wed Mar 05 19:40:15 2014 -0800
@@ -63,7 +63,7 @@
             ConstantNode klassNode = ConstantNode.forConstant(klass, metaAccess, graph);
 
             Stamp stamp = StampFactory.exactNonNull(metaAccess.lookupJavaType(Class.class));
-            LocationNode location = graph.unique(ConstantLocationNode.create(FINAL_LOCATION, stamp.kind(), classMirrorOffset, graph));
+            LocationNode location = ConstantLocationNode.create(FINAL_LOCATION, Kind.Object, classMirrorOffset, graph);
             FloatingReadNode freadNode = graph.unique(new FloatingReadNode(klassNode, location, null, stamp));
             return freadNode;
         }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/OnStackReplacementPhase.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/OnStackReplacementPhase.java	Wed Mar 05 19:40:15 2014 -0800
@@ -78,10 +78,7 @@
                 ProxyNode proxy = (ProxyNode) usage;
                 proxy.replaceAndDelete(proxy.value());
             }
-            FixedNode next = osr.next();
-            osr.setNext(null);
-            ((FixedWithNextNode) osr.predecessor()).setNext(next);
-            GraphUtil.killWithUnusedFloatingInputs(osr);
+            GraphUtil.removeFixedWithUnusedInputs(osr);
             Debug.dump(graph, "OnStackReplacement loop peeling result");
         } while (true);
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/AESCryptSubstitutions.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/AESCryptSubstitutions.java	Wed Mar 05 19:40:15 2014 -0800
@@ -23,7 +23,6 @@
 package com.oracle.graal.hotspot.replacements;
 
 import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*;
-
 import sun.misc.*;
 
 import com.oracle.graal.api.meta.*;
@@ -32,8 +31,8 @@
 import com.oracle.graal.graph.Node.ConstantNodeParameter;
 import com.oracle.graal.graph.Node.NodeIntrinsic;
 import com.oracle.graal.hotspot.*;
-import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.hotspot.nodes.*;
+import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.word.*;
 
@@ -57,7 +56,6 @@
     }
 
     static final long kOffset;
-    static final LocationIdentity kLocationIdentity;
     static final Class<?> AESCryptClass;
 
     static {
@@ -67,7 +65,6 @@
             ClassLoader cl = Launcher.getLauncher().getClassLoader();
             AESCryptClass = Class.forName("com.sun.crypto.provider.AESCrypt", true, cl);
             kOffset = UnsafeAccess.unsafe.objectFieldOffset(AESCryptClass.getDeclaredField("K"));
-            kLocationIdentity = HotSpotResolvedObjectType.fromClass(AESCryptClass).findInstanceFieldWithOffset(kOffset);
         } catch (Exception ex) {
             throw new GraalInternalError(ex);
         }
@@ -84,7 +81,8 @@
     }
 
     private static void crypt(Object rcvr, byte[] in, int inOffset, byte[] out, int outOffset, boolean encrypt) {
-        Object kObject = UnsafeLoadNode.load(rcvr, kOffset, Kind.Object, kLocationIdentity);
+        Object realReceiver = PiNode.piCastNonNull(rcvr, AESCryptClass);
+        Object kObject = UnsafeLoadNode.load(realReceiver, kOffset, Kind.Object, LocationIdentity.ANY_LOCATION);
         Word kAddr = (Word) Word.fromObject(kObject).add(arrayBaseOffset(Kind.Byte));
         Word inAddr = Word.unsigned(GetObjectAddressNode.get(in) + arrayBaseOffset(Kind.Byte) + inOffset);
         Word outAddr = Word.unsigned(GetObjectAddressNode.get(out) + arrayBaseOffset(Kind.Byte) + outOffset);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/AbstractMethodHandleNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/AbstractMethodHandleNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -22,30 +22,18 @@
  */
 package com.oracle.graal.hotspot.replacements;
 
-import java.lang.reflect.Modifier;
-import java.util.Arrays;
+import java.lang.reflect.*;
+import java.util.*;
 
-import com.oracle.graal.api.meta.Constant;
-import com.oracle.graal.api.meta.JavaType;
-import com.oracle.graal.api.meta.ResolvedJavaField;
-import com.oracle.graal.api.meta.ResolvedJavaMethod;
-import com.oracle.graal.api.meta.ResolvedJavaType;
-import com.oracle.graal.graph.GraalInternalError;
-import com.oracle.graal.graph.NodeInputList;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.spi.*;
-import com.oracle.graal.hotspot.meta.HotSpotResolvedJavaMethod;
-import com.oracle.graal.hotspot.meta.HotSpotResolvedObjectType;
-import com.oracle.graal.hotspot.meta.HotSpotSignature;
-import com.oracle.graal.nodes.CallTargetNode;
-import com.oracle.graal.nodes.Invoke;
-import com.oracle.graal.nodes.InvokeNode;
-import com.oracle.graal.nodes.PiNode;
-import com.oracle.graal.nodes.ValueNode;
-import com.oracle.graal.nodes.java.MethodCallTargetNode;
+import com.oracle.graal.hotspot.meta.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.java.*;
 import com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind;
-import com.oracle.graal.nodes.java.SelfReplacingMethodCallTargetNode;
 import com.oracle.graal.nodes.type.*;
-import com.oracle.graal.replacements.nodes.MacroNode;
+import com.oracle.graal.replacements.nodes.*;
 
 /**
  * Common base class for method handle invoke nodes.
@@ -281,7 +269,7 @@
         // invoker's stamp would be wrong because it's a less concrete type
         // (usually java.lang.Object).
         InvokeNode invoke;
-        if (callTarget.returnStamp().kind() != stamp().kind()) {
+        if (stamp() == StampFactory.forVoid()) {
             invoke = new InvokeNode(callTarget, getBci(), stamp());
         } else {
             invoke = new InvokeNode(callTarget, getBci());
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopyCallNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,194 @@
+/*
+ * 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.replacements;
+
+import static com.oracle.graal.api.meta.LocationIdentity.*;
+import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.runtime.*;
+import com.oracle.graal.hotspot.meta.*;
+import com.oracle.graal.hotspot.nodes.*;
+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.phases.*;
+import com.oracle.graal.replacements.SnippetTemplate.Arguments;
+import com.oracle.graal.runtime.*;
+
+public final class ArrayCopyCallNode extends ArrayRangeWriteNode implements Lowerable, MemoryCheckpoint.Single {
+
+    @Input private ValueNode src;
+    @Input private ValueNode srcPos;
+    @Input private ValueNode dest;
+    @Input private ValueNode destPos;
+    @Input private ValueNode length;
+
+    private Kind elementKind;
+    private boolean aligned;
+    private boolean disjoint;
+
+    private ArrayCopyCallNode(ValueNode src, ValueNode srcPos, ValueNode dest, ValueNode destPos, ValueNode length, Kind elementKind, boolean aligned, boolean disjoint) {
+        super(StampFactory.forVoid());
+        assert elementKind != null;
+        this.src = src;
+        this.srcPos = srcPos;
+        this.dest = dest;
+        this.destPos = destPos;
+        this.length = length;
+        this.elementKind = elementKind;
+        this.aligned = aligned;
+        this.disjoint = disjoint;
+    }
+
+    private ArrayCopyCallNode(ValueNode src, ValueNode srcPos, ValueNode dest, ValueNode destPos, ValueNode length, Kind elementKind) {
+        this(src, srcPos, dest, destPos, length, elementKind, false, false);
+    }
+
+    public ValueNode getSource() {
+        return src;
+    }
+
+    public ValueNode getSourcePosition() {
+        return srcPos;
+    }
+
+    public ValueNode getDestination() {
+        return dest;
+    }
+
+    public ValueNode getDestinationPosition() {
+        return destPos;
+    }
+
+    @Override
+    public ValueNode getArray() {
+        return dest;
+    }
+
+    @Override
+    public ValueNode getIndex() {
+        return destPos;
+    }
+
+    @Override
+    public ValueNode getLength() {
+        return length;
+    }
+
+    @Override
+    public boolean isObjectArray() {
+        return elementKind == Kind.Object;
+    }
+
+    @Override
+    public boolean isInitialization() {
+        return false;
+    }
+
+    public void addSnippetArguments(Arguments args) {
+        args.add("src", src);
+        args.add("srcPos", srcPos);
+        args.add("dest", dest);
+        args.add("destPos", destPos);
+        args.add("length", length);
+    }
+
+    public Kind getElementKind() {
+        return elementKind;
+    }
+
+    private boolean shouldUnroll() {
+        return getLength().isConstant() && getLength().asConstant().asInt() <= GraalOptions.MaximumEscapeAnalysisArrayLength.getValue();
+    }
+
+    private ValueNode computeBase(ValueNode base, ValueNode pos) {
+        FixedWithNextNode basePtr = graph().add(new GetObjectAddressNode(base));
+        graph().addBeforeFixed(this, basePtr);
+        ValueNode loc = IndexedLocationNode.create(getLocationIdentity(), elementKind, arrayBaseOffset(elementKind), pos, graph(), arrayIndexScale(elementKind));
+        return graph().unique(new ComputeAddressNode(basePtr, loc, StampFactory.forKind(Kind.Long)));
+    }
+
+    @Override
+    public void lower(LoweringTool tool) {
+        if (graph().getGuardsStage() == StructuredGraph.GuardsStage.AFTER_FSA) {
+            updateAlignedDisjoint();
+            ForeignCallDescriptor desc = HotSpotHostForeignCallsProvider.lookupArraycopyDescriptor(elementKind, isAligned(), isDisjoint());
+            StructuredGraph graph = graph();
+            ValueNode srcAddr = computeBase(getSource(), getSourcePosition());
+            ValueNode destAddr = computeBase(getDestination(), getDestinationPosition());
+            ValueNode len = getLength();
+            if (len.stamp().getStackKind() != Kind.Long) {
+                len = IntegerConvertNode.convert(len, StampFactory.forKind(Kind.Long));
+            }
+            ForeignCallNode call = graph.add(new ForeignCallNode(Graal.getRequiredCapability(RuntimeProvider.class).getHostBackend().getForeignCalls(), desc, srcAddr, destAddr, len));
+            call.setStateAfter(stateAfter());
+            graph.replaceFixedWithFixed(this, call);
+
+        }
+    }
+
+    @Override
+    public LocationIdentity getLocationIdentity() {
+        if (elementKind != null) {
+            return NamedLocationIdentity.getArrayLocation(elementKind);
+        }
+        return ANY_LOCATION;
+    }
+
+    @NodeIntrinsic
+    public static native void arraycopy(Object src, int srcPos, Object dest, int destPos, int length, @ConstantNodeParameter Kind elementKind);
+
+    @NodeIntrinsic
+    public static native void arraycopy(Object src, int srcPos, Object dest, int destPos, int length, @ConstantNodeParameter Kind elementKind, @ConstantNodeParameter boolean aligned,
+                    @ConstantNodeParameter boolean disjoint);
+
+    public boolean isAligned() {
+        return aligned;
+    }
+
+    public boolean isDisjoint() {
+        return disjoint;
+    }
+
+    public void updateAlignedDisjoint() {
+        Kind componentKind = elementKind;
+        if (srcPos == destPos) {
+            // Can treat as disjoint
+            disjoint = true;
+        }
+        Constant constantSrc = srcPos.stamp().asConstant();
+        Constant constantDst = destPos.stamp().asConstant();
+        if (constantSrc != null && constantDst != null) {
+            if (!aligned) {
+                aligned = ArrayCopyNode.isHeapWordAligned(constantSrc, componentKind) && ArrayCopyNode.isHeapWordAligned(constantDst, componentKind);
+            }
+            if (constantSrc.asInt() >= constantDst.asInt()) {
+                // low to high copy so treat as disjoint
+                disjoint = true;
+            }
+        }
+    }
+}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopyNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopyNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -23,6 +23,7 @@
 package com.oracle.graal.hotspot.replacements;
 
 import static com.oracle.graal.compiler.GraalCompiler.*;
+import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*;
 
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.debug.*;
@@ -63,6 +64,10 @@
         return arguments.get(4);
     }
 
+    static boolean isHeapWordAligned(Constant value, Kind kind) {
+        return (arrayBaseOffset(kind) + (long) value.asInt() * arrayIndexScale(kind)) % heapWordSize() == 0;
+    }
+
     private StructuredGraph selectSnippet(LoweringTool tool, final Replacements replacements) {
         ResolvedJavaType srcType = ObjectStamp.typeOrNull(getSource().stamp());
         ResolvedJavaType destType = ObjectStamp.typeOrNull(getDestination().stamp());
@@ -70,11 +75,14 @@
         if (srcType == null || !srcType.isArray() || destType == null || !destType.isArray()) {
             return null;
         }
-        if (!destType.getComponentType().isAssignableFrom(srcType.getComponentType()) || !ObjectStamp.isExactType(getDestination().stamp())) {
+        if (!destType.getComponentType().isAssignableFrom(srcType.getComponentType())) {
+            return null;
+        }
+        if (!isExact()) {
             return null;
         }
         Kind componentKind = srcType.getComponentType().getKind();
-        final ResolvedJavaMethod snippetMethod = tool.getMetaAccess().lookupJavaMethod(ArrayCopySnippets.getSnippetForKind(componentKind));
+        final ResolvedJavaMethod snippetMethod = tool.getMetaAccess().lookupJavaMethod(ArrayCopySnippets.getSnippetForKind(componentKind, shouldUnroll(), isExact()));
         try (Scope s = Debug.scope("ArrayCopySnippet", snippetMethod)) {
             return replacements.getSnippet(snippetMethod);
         } catch (Throwable e) {
@@ -115,7 +123,7 @@
         } else {
             assert snippetGraph != null : "ArrayCopySnippets should be installed";
             snippetGraph = snippetGraph.copy();
-            if (getLength().isConstant() && getLength().asConstant().asInt() <= GraalOptions.MaximumEscapeAnalysisArrayLength.getValue()) {
+            if (shouldUnroll()) {
                 final StructuredGraph copy = snippetGraph;
                 try (Scope s = Debug.scope("ArrayCopySnippetSpecialization", snippetGraph.method())) {
                     unrollFixedLengthLoop(copy, getLength().asConstant().asInt(), tool);
@@ -127,6 +135,28 @@
         return lowerReplacement(snippetGraph, tool);
     }
 
+    private boolean shouldUnroll() {
+        return getLength().isConstant() && getLength().asConstant().asInt() <= GraalOptions.MaximumEscapeAnalysisArrayLength.getValue();
+    }
+
+    /*
+     * Returns true if this copy doesn't require store checks. Trivially true for primitive arrays.
+     */
+    private boolean isExact() {
+        ResolvedJavaType srcType = ObjectStamp.typeOrNull(getSource().stamp());
+        if (srcType.getComponentType().getKind().isPrimitive() || getSource() == getDestination()) {
+            return true;
+        }
+
+        ResolvedJavaType destType = ObjectStamp.typeOrNull(getDestination().stamp());
+        if (ObjectStamp.isExactType(getDestination().stamp())) {
+            if (destType != null && destType.isAssignableFrom(srcType)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
     private static boolean checkBounds(int position, int length, VirtualObjectNode virtualObject) {
         return position >= 0 && position + length <= virtualObject.entryCount();
     }
@@ -188,4 +218,5 @@
             }
         }
     }
+
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopySnippets.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopySnippets.java	Wed Mar 05 19:40:15 2014 -0800
@@ -22,39 +22,54 @@
  */
 package com.oracle.graal.hotspot.replacements;
 
-import static com.oracle.graal.api.meta.LocationIdentity.*;
 import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*;
 import static com.oracle.graal.nodes.GuardingPiNode.*;
-import static com.oracle.graal.nodes.calc.IsNullNode.*;
 import static com.oracle.graal.nodes.extended.BranchProbabilityNode.*;
 import static com.oracle.graal.phases.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.debug.*;
+import com.oracle.graal.debug.Debug.Scope;
 import com.oracle.graal.graph.*;
-import com.oracle.graal.hotspot.nodes.*;
+import com.oracle.graal.graph.Node.ConstantNodeParameter;
+import com.oracle.graal.graph.Node.NodeIntrinsic;
+import com.oracle.graal.loop.phases.*;
 import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.java.*;
-import com.oracle.graal.nodes.type.*;
-import com.oracle.graal.phases.*;
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.phases.common.*;
+import com.oracle.graal.phases.tiers.*;
+import com.oracle.graal.phases.util.*;
 import com.oracle.graal.replacements.*;
 import com.oracle.graal.replacements.Snippet.Fold;
-import com.oracle.graal.replacements.nodes.*;
+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.*;
 
 @SuppressWarnings("unused")
 public class ArrayCopySnippets implements Snippets {
 
     private static final EnumMap<Kind, Method> arraycopyMethods = new EnumMap<>(Kind.class);
+    private static final EnumMap<Kind, Method> arraycopyCalls = new EnumMap<>(Kind.class);
+
     public static final Method genericArraycopySnippet;
 
     private static void addArraycopySnippetMethod(Kind kind, Class<?> arrayClass) throws NoSuchMethodException {
         arraycopyMethods.put(kind, ArrayCopySnippets.class.getDeclaredMethod("arraycopy", arrayClass, int.class, arrayClass, int.class, int.class));
+        if (CallArrayCopy.getValue()) {
+            if (kind == Kind.Object) {
+                arraycopyCalls.put(kind, ArrayCopySnippets.class.getDeclaredMethod("objectArraycopyUnchecked", arrayClass, int.class, arrayClass, int.class, int.class));
+            } else {
+                arraycopyCalls.put(kind, ArrayCopySnippets.class.getDeclaredMethod(kind + "Arraycopy", arrayClass, int.class, arrayClass, int.class, int.class));
+            }
+        }
     }
 
     static {
@@ -74,7 +89,14 @@
         }
     }
 
-    public static Method getSnippetForKind(Kind kind) {
+    public static Method getSnippetForKind(Kind kind, boolean shouldUnroll, boolean exact) {
+        Method m = null;
+        if (!shouldUnroll && exact) {
+            m = arraycopyCalls.get(kind);
+            if (m != null) {
+                return m;
+            }
+        }
         return arraycopyMethods.get(kind);
     }
 
@@ -195,6 +217,62 @@
         }
     }
 
+    @NodeIntrinsic(ForeignCallNode.class)
+    public static native void callArraycopy(@ConstantNodeParameter ForeignCallDescriptor descriptor, Word src, Word dest, Word len);
+
+    private static void callArraycopyTemplate(SnippetCounter counter, Kind kind, boolean aligned, boolean disjoint, Object src, int srcPos, Object dest, int destPos, int length) {
+        counter.inc();
+        Object nonNullSrc = guardingNonNull(src);
+        Object nonNullDest = guardingNonNull(dest);
+        checkLimits(nonNullSrc, srcPos, nonNullDest, destPos, length);
+        ArrayCopyCallNode.arraycopy(nonNullSrc, srcPos, nonNullDest, destPos, length, kind, aligned, disjoint);
+    }
+
+    @Snippet
+    public static void objectArraycopyUnchecked(Object[] src, int srcPos, Object[] dest, int destPos, int length) {
+        callArraycopyTemplate(objectCallCounter, Kind.Object, false, false, src, srcPos, dest, destPos, length);
+    }
+
+    @Snippet
+    public static void byteArraycopy(byte[] src, int srcPos, byte[] dest, int destPos, int length) {
+        callArraycopyTemplate(byteCallCounter, Kind.Byte, false, false, src, srcPos, dest, destPos, length);
+    }
+
+    @Snippet
+    public static void booleanArraycopy(boolean[] src, int srcPos, boolean[] dest, int destPos, int length) {
+        callArraycopyTemplate(booleanCallCounter, Kind.Boolean, false, false, src, srcPos, dest, destPos, length);
+    }
+
+    @Snippet
+    public static void charArraycopy(char[] src, int srcPos, char[] dest, int destPos, int length) {
+        callArraycopyTemplate(charCallCounter, Kind.Char, false, false, src, srcPos, dest, destPos, length);
+    }
+
+    @Snippet
+    public static void shortArraycopy(short[] src, int srcPos, short[] dest, int destPos, int length) {
+        callArraycopyTemplate(shortCallCounter, Kind.Short, false, false, src, srcPos, dest, destPos, length);
+    }
+
+    @Snippet
+    public static void intArraycopy(int[] src, int srcPos, int[] dest, int destPos, int length) {
+        callArraycopyTemplate(intCallCounter, Kind.Int, false, false, src, srcPos, dest, destPos, length);
+    }
+
+    @Snippet
+    public static void floatArraycopy(float[] src, int srcPos, float[] dest, int destPos, int length) {
+        callArraycopyTemplate(floatCallCounter, Kind.Float, false, false, src, srcPos, dest, destPos, length);
+    }
+
+    @Snippet
+    public static void longArraycopy(long[] src, int srcPos, long[] dest, int destPos, int length) {
+        callArraycopyTemplate(longCallCounter, Kind.Long, false, false, src, srcPos, dest, destPos, length);
+    }
+
+    @Snippet
+    public static void doubleArraycopy(double[] src, int srcPos, double[] dest, int destPos, int length) {
+        callArraycopyTemplate(doubleCallCounter, Kind.Double, false, false, src, srcPos, dest, destPos, length);
+    }
+
     private static final SnippetCounter.Group checkCounters = SnippetCounters.getValue() ? new SnippetCounter.Group("System.arraycopy checkInputs") : null;
     private static final SnippetCounter checkSuccessCounter = new SnippetCounter(checkCounters, "checkSuccess", "checkSuccess");
     private static final SnippetCounter checkNPECounter = new SnippetCounter(checkCounters, "checkNPE", "checkNPE");
@@ -210,8 +288,19 @@
     private static final SnippetCounter objectCounter = new SnippetCounter(counters, "Object[]", "arraycopy for Object[] arrays");
     private static final SnippetCounter floatCounter = new SnippetCounter(counters, "float[]", "arraycopy for float[] arrays");
     private static final SnippetCounter doubleCounter = new SnippetCounter(counters, "double[]", "arraycopy for double[] arrays");
+
+    private static final SnippetCounter objectCallCounter = new SnippetCounter(counters, "Object[]", "arraycopy call for Object[] arrays");
+
+    private static final SnippetCounter booleanCallCounter = new SnippetCounter(counters, "boolean[]", "arraycopy call for boolean[] arrays");
+    private static final SnippetCounter byteCallCounter = new SnippetCounter(counters, "byte[]", "arraycopy call for byte[] arrays");
+    private static final SnippetCounter charCallCounter = new SnippetCounter(counters, "char[]", "arraycopy call for char[] arrays");
+    private static final SnippetCounter doubleCallCounter = new SnippetCounter(counters, "double[]", "arraycopy call for double[] arrays");
+    private static final SnippetCounter floatCallCounter = new SnippetCounter(counters, "float[]", "arraycopy call for float[] arrays");
+    private static final SnippetCounter intCallCounter = new SnippetCounter(counters, "int[]", "arraycopy call for int[] arrays");
+    private static final SnippetCounter longCallCounter = new SnippetCounter(counters, "long[]", "arraycopy call for long[] arrays");
+    private static final SnippetCounter shortCallCounter = new SnippetCounter(counters, "short[]", "arraycopy call for short[] arrays");
+
     private static final SnippetCounter genericPrimitiveCallCounter = new SnippetCounter(counters, "genericPrimitive", "generic arraycopy snippet for primitive arrays");
     private static final SnippetCounter genericObjectExactCallCounter = new SnippetCounter(counters, "genericObjectExact", "generic arraycopy snippet for special object arrays");
     private static final SnippetCounter genericObjectCallCounter = new SnippetCounter(counters, "genericObject", "call to the generic, native arraycopy method");
-
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CipherBlockChainingSubstitutions.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CipherBlockChainingSubstitutions.java	Wed Mar 05 19:40:15 2014 -0800
@@ -30,8 +30,8 @@
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.Node.ConstantNodeParameter;
 import com.oracle.graal.graph.Node.NodeIntrinsic;
-import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.hotspot.nodes.*;
+import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.replacements.Snippet.Fold;
 import com.oracle.graal.word.*;
@@ -43,22 +43,20 @@
 public class CipherBlockChainingSubstitutions {
 
     private static final long embeddedCipherOffset;
-    private static final LocationIdentity embeddedCipherLocationIdentity;
     private static final long rOffset;
-    private static final LocationIdentity rLocationIdentity;
+    private static final Class<?> cipherBlockChainingClass;
+    private static final Class<?> feedbackCipherClass;
     static {
         try {
             // Need to use launcher class path as com.sun.crypto.provider.AESCrypt
             // is normally not on the boot class path
             ClassLoader cl = Launcher.getLauncher().getClassLoader();
 
-            Class<?> feedbackCipherClass = Class.forName("com.sun.crypto.provider.FeedbackCipher", true, cl);
+            feedbackCipherClass = Class.forName("com.sun.crypto.provider.FeedbackCipher", true, cl);
             embeddedCipherOffset = UnsafeAccess.unsafe.objectFieldOffset(feedbackCipherClass.getDeclaredField("embeddedCipher"));
-            embeddedCipherLocationIdentity = HotSpotResolvedObjectType.fromClass(feedbackCipherClass).findInstanceFieldWithOffset(embeddedCipherOffset);
 
-            Class<?> cipherBlockChainingClass = Class.forName("com.sun.crypto.provider.CipherBlockChaining", true, cl);
+            cipherBlockChainingClass = Class.forName("com.sun.crypto.provider.CipherBlockChaining", true, cl);
             rOffset = UnsafeAccess.unsafe.objectFieldOffset(cipherBlockChainingClass.getDeclaredField("r"));
-            rLocationIdentity = HotSpotResolvedObjectType.fromClass(cipherBlockChainingClass).findInstanceFieldWithOffset(rOffset);
         } catch (Exception ex) {
             throw new GraalInternalError(ex);
         }
@@ -71,9 +69,10 @@
 
     @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, embeddedCipherLocationIdentity);
+        Object embeddedCipher = UnsafeLoadNode.load(rcvr, embeddedCipherOffset, Kind.Object, LocationIdentity.ANY_LOCATION);
         if (getAESCryptClass().isInstance(embeddedCipher)) {
-            crypt(rcvr, in, inOffset, inLength, out, outOffset, embeddedCipher, true);
+            Object aesCipher = PiNode.piCastNonNull(embeddedCipher, AESCryptSubstitutions.AESCryptClass);
+            crypt(rcvr, in, inOffset, inLength, out, outOffset, aesCipher, true);
         } else {
             encrypt(rcvr, in, inOffset, inLength, out, outOffset);
         }
@@ -81,39 +80,46 @@
 
     @MethodSubstitution(isStatic = false, optional = true)
     static void decrypt(Object rcvr, byte[] in, int inOffset, int inLength, byte[] out, int outOffset) {
-        Object embeddedCipher = UnsafeLoadNode.load(rcvr, embeddedCipherOffset, Kind.Object, embeddedCipherLocationIdentity);
+        Object realReceiver = PiNode.piCastNonNull(rcvr, cipherBlockChainingClass);
+        Object embeddedCipher = UnsafeLoadNode.load(realReceiver, embeddedCipherOffset, Kind.Object, LocationIdentity.ANY_LOCATION);
         if (in != out && getAESCryptClass().isInstance(embeddedCipher)) {
-            crypt(rcvr, in, inOffset, inLength, out, outOffset, embeddedCipher, false);
+            Object aesCipher = PiNode.piCastNonNull(embeddedCipher, AESCryptSubstitutions.AESCryptClass);
+            crypt(realReceiver, in, inOffset, inLength, out, outOffset, aesCipher, false);
         } else {
-            decrypt(rcvr, in, inOffset, inLength, out, outOffset);
+            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) {
-        Object embeddedCipher = UnsafeLoadNode.load(rcvr, embeddedCipherOffset, Kind.Object, embeddedCipherLocationIdentity);
+        Object realReceiver = PiNode.piCastNonNull(rcvr, cipherBlockChainingClass);
+        Object embeddedCipher = UnsafeLoadNode.load(realReceiver, embeddedCipherOffset, Kind.Object, LocationIdentity.ANY_LOCATION);
         if (getAESCryptClass().isInstance(embeddedCipher)) {
-            crypt(rcvr, in, inOffset, inLength, out, outOffset, embeddedCipher, true);
+            Object aesCipher = PiNode.piCastNonNull(embeddedCipher, AESCryptSubstitutions.AESCryptClass);
+            crypt(realReceiver, in, inOffset, inLength, out, outOffset, aesCipher, true);
             return inLength;
         } else {
-            return encryptInt(rcvr, in, inOffset, inLength, out, outOffset);
+            return encryptInt(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) {
-        Object embeddedCipher = UnsafeLoadNode.load(rcvr, embeddedCipherOffset, Kind.Object, embeddedCipherLocationIdentity);
+        Object realReceiver = PiNode.piCastNonNull(rcvr, cipherBlockChainingClass);
+        Object embeddedCipher = UnsafeLoadNode.load(realReceiver, embeddedCipherOffset, Kind.Object, LocationIdentity.ANY_LOCATION);
         if (in != out && getAESCryptClass().isInstance(embeddedCipher)) {
-            crypt(rcvr, in, inOffset, inLength, out, outOffset, embeddedCipher, false);
+            Object aesCipher = PiNode.piCastNonNull(embeddedCipher, AESCryptSubstitutions.AESCryptClass);
+            crypt(realReceiver, in, inOffset, inLength, out, outOffset, aesCipher, false);
             return inLength;
         } else {
-            return decryptInt(rcvr, in, inOffset, inLength, out, outOffset);
+            return decryptInt(realReceiver, in, inOffset, inLength, out, outOffset);
         }
     }
 
     private static void crypt(Object rcvr, byte[] in, int inOffset, int inLength, byte[] out, int outOffset, Object embeddedCipher, boolean encrypt) {
-        Object kObject = UnsafeLoadNode.load(embeddedCipher, AESCryptSubstitutions.kOffset, Kind.Object, AESCryptSubstitutions.kLocationIdentity);
-        Object rObject = UnsafeLoadNode.load(rcvr, rOffset, Kind.Object, rLocationIdentity);
+        Object realReceiver = PiNode.piCastNonNull(rcvr, cipherBlockChainingClass);
+        Object kObject = UnsafeLoadNode.load(embeddedCipher, AESCryptSubstitutions.kOffset, Kind.Object, LocationIdentity.ANY_LOCATION);
+        Object rObject = UnsafeLoadNode.load(realReceiver, rOffset, Kind.Object, LocationIdentity.ANY_LOCATION);
         Word kAddr = (Word) Word.fromObject(kObject).add(arrayBaseOffset(Kind.Byte));
         Word rAddr = (Word) Word.fromObject(rObject).add(arrayBaseOffset(Kind.Byte));
         Word inAddr = Word.unsigned(GetObjectAddressNode.get(in) + arrayBaseOffset(Kind.Byte) + inOffset);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ClassSubstitutions.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ClassSubstitutions.java	Wed Mar 05 19:40:15 2014 -0800
@@ -96,7 +96,7 @@
                     if (superKlass.equal(0)) {
                         return null;
                     } else {
-                        return piCast(superKlass.readObject(classMirrorOffset(), LocationIdentity.FINAL_LOCATION), Class.class, true, true);
+                        return piCastExactNonNull(superKlass.readObject(classMirrorOffset(), LocationIdentity.FINAL_LOCATION), Class.class);
                     }
                 }
             }
@@ -110,7 +110,7 @@
         Word klass = loadWordFromObject(thisObj, klassOffset());
         if (klass.notEqual(0)) {
             if (klassIsArray(klass)) {
-                return piCast(klass.readObject(arrayKlassComponentMirrorOffset(), LocationIdentity.FINAL_LOCATION), Class.class, true, true);
+                return piCastExactNonNull(klass.readObject(arrayKlassComponentMirrorOffset(), LocationIdentity.FINAL_LOCATION), Class.class);
             }
         }
         return null;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotReplacementsUtil.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotReplacementsUtil.java	Wed Mar 05 19:40:15 2014 -0800
@@ -211,6 +211,11 @@
         return Unsafe.getUnsafe().pageSize();
     }
 
+    @Fold
+    public static int heapWordSize() {
+        return config().heapWordSize;
+    }
+
     public static final LocationIdentity PROTOTYPE_MARK_WORD_LOCATION = new NamedLocationIdentity("PrototypeMarkWord");
 
     @Fold
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/InstanceOfSnippets.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/InstanceOfSnippets.java	Wed Mar 05 19:40:15 2014 -0800
@@ -230,7 +230,7 @@
                 Arguments args;
 
                 StructuredGraph graph = instanceOf.graph();
-                if (hintInfo.hintHitProbability >= hintHitProbabilityThresholdForDeoptimizingSnippet()) {
+                if (hintInfo.hintHitProbability >= hintHitProbabilityThresholdForDeoptimizingSnippet() && hintInfo.exact == null) {
                     Hints hints = createHints(hintInfo, providers.getMetaAccess(), false, graph);
                     args = new Arguments(instanceofWithProfile, graph.getGuardsStage(), tool.getLoweringStage());
                     args.add("object", object);
@@ -256,7 +256,7 @@
                 }
                 args.add("trueValue", replacer.trueValue);
                 args.add("falseValue", replacer.falseValue);
-                if (hintInfo.hintHitProbability >= hintHitProbabilityThresholdForDeoptimizingSnippet()) {
+                if (hintInfo.hintHitProbability >= hintHitProbabilityThresholdForDeoptimizingSnippet() && hintInfo.exact == null) {
                     args.addConst("nullSeen", hintInfo.profile.getNullSeen() != TriState.FALSE);
                 }
                 return args;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/LoadExceptionObjectSnippets.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/LoadExceptionObjectSnippets.java	Wed Mar 05 19:40:15 2014 -0800
@@ -53,7 +53,7 @@
     private static final boolean USE_C_RUNTIME = Boolean.getBoolean("graal.loadExceptionObject.useCRuntime");
 
     @Snippet
-    public static Object loadException(@ConstantParameter Register threadRegister) {
+    public static Throwable loadException(@ConstantParameter Register threadRegister) {
         Word thread = registerAsWord(threadRegister);
         Object exception = readExceptionOop(thread);
         writeExceptionOop(thread, null);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MonitorSnippets.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MonitorSnippets.java	Wed Mar 05 19:40:15 2014 -0800
@@ -34,7 +34,6 @@
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
-import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.Node.ConstantNodeParameter;
 import com.oracle.graal.graph.Node.NodeIntrinsic;
 import com.oracle.graal.graph.iterators.*;
@@ -425,7 +424,6 @@
         public void lower(MonitorEnterNode monitorenterNode, HotSpotRegistersProvider registers, LoweringTool tool) {
             StructuredGraph graph = monitorenterNode.graph();
             checkBalancedMonitors(graph, tool);
-            FrameState stateAfter = monitorenterNode.stateAfter();
 
             Arguments args;
             if (useFastLocking) {
@@ -435,24 +433,15 @@
             }
             args.add("object", monitorenterNode.object());
             args.addConst("lockDepth", monitorenterNode.getMonitorId().getLockDepth());
-            boolean tracingEnabledForMethod = stateAfter != null && (isTracingEnabledForMethod(stateAfter.method()) || isTracingEnabledForMethod(graph.method()));
             args.addConst("threadRegister", registers.getThreadRegister());
             args.addConst("stackPointerRegister", registers.getStackPointerRegister());
-            args.addConst("trace", isTracingEnabledForType(monitorenterNode.object()) || tracingEnabledForMethod);
-
-            Map<Node, Node> nodes = template(args).instantiate(providers.getMetaAccess(), monitorenterNode, DEFAULT_REPLACER, args);
+            args.addConst("trace", isTracingEnabledForType(monitorenterNode.object()) || isTracingEnabledForMethod(graph.method()));
 
-            for (Node n : nodes.values()) {
-                if (n instanceof BeginLockScopeNode) {
-                    BeginLockScopeNode begin = (BeginLockScopeNode) n;
-                    begin.setStateAfter(stateAfter);
-                }
-            }
+            template(args).instantiate(providers.getMetaAccess(), monitorenterNode, DEFAULT_REPLACER, args);
         }
 
         public void lower(MonitorExitNode monitorexitNode, LoweringTool tool) {
             StructuredGraph graph = monitorexitNode.graph();
-            FrameState stateAfter = monitorexitNode.stateAfter();
 
             Arguments args;
             if (useFastLocking) {
@@ -462,16 +451,9 @@
             }
             args.add("object", monitorexitNode.object());
             args.addConst("lockDepth", monitorexitNode.getMonitorId().getLockDepth());
-            args.addConst("trace", isTracingEnabledForType(monitorexitNode.object()) || isTracingEnabledForMethod(stateAfter.method()) || isTracingEnabledForMethod(graph.method()));
-
-            Map<Node, Node> nodes = template(args).instantiate(providers.getMetaAccess(), monitorexitNode, DEFAULT_REPLACER, args);
+            args.addConst("trace", isTracingEnabledForType(monitorexitNode.object()) || isTracingEnabledForMethod(graph.method()));
 
-            for (Node n : nodes.values()) {
-                if (n instanceof EndLockScopeNode) {
-                    EndLockScopeNode end = (EndLockScopeNode) n;
-                    end.setStateAfter(stateAfter);
-                }
-            }
+            template(args).instantiate(providers.getMetaAccess(), monitorexitNode, DEFAULT_REPLACER, args);
         }
 
         static boolean isTracingEnabledForType(ValueNode object) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectSubstitutions.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectSubstitutions.java	Wed Mar 05 19:40:15 2014 -0800
@@ -41,7 +41,7 @@
     @MethodSubstitution(isStatic = false, forced = true)
     public static Class<?> getClass(final Object thisObj) {
         Word hub = loadHub(thisObj);
-        return piCast(hub.readObject(Word.signed(classMirrorOffset()), LocationIdentity.FINAL_LOCATION), Class.class, true, true);
+        return piCastExactNonNull(hub.readObject(Word.signed(classMirrorOffset()), LocationIdentity.FINAL_LOCATION), Class.class);
     }
 
     @MethodSubstitution(isStatic = false)
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ThreadSubstitutions.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ThreadSubstitutions.java	Wed Mar 05 19:40:15 2014 -0800
@@ -33,6 +33,7 @@
 import com.oracle.graal.graph.Node.ConstantNodeParameter;
 import com.oracle.graal.graph.Node.NodeIntrinsic;
 import com.oracle.graal.hotspot.nodes.*;
+import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.word.*;
 
@@ -44,7 +45,7 @@
 
     @MethodSubstitution
     public static Thread currentThread() {
-        return (Thread) CurrentJavaThreadNode.get().readObject(threadObjectOffset(), LocationIdentity.FINAL_LOCATION);
+        return PiNode.piCastExactNonNull(CurrentJavaThreadNode.get().readObject(threadObjectOffset(), LocationIdentity.FINAL_LOCATION), Thread.class);
     }
 
     @MethodSubstitution(isStatic = false)
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ForeignCallStub.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ForeignCallStub.java	Wed Mar 05 19:40:15 2014 -0800
@@ -35,6 +35,7 @@
 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.*;
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/GraphKit.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,165 +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.hotspot.stubs;
-
-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.java.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.calc.*;
-import com.oracle.graal.nodes.java.*;
-import com.oracle.graal.nodes.java.MethodCallTargetNode.*;
-import com.oracle.graal.phases.common.*;
-import com.oracle.graal.phases.util.*;
-import com.oracle.graal.replacements.*;
-import com.oracle.graal.replacements.ReplacementsImpl.*;
-import com.oracle.graal.word.phases.*;
-
-/**
- * A utility for manually creating a graph. This will be expanded as necessary to support all
- * subsystems that employ manual graph creation (as opposed to {@linkplain GraphBuilderPhase
- * bytecode parsing} based graph creation).
- */
-public class GraphKit {
-
-    private final Providers providers;
-    private final StructuredGraph graph;
-    private FixedWithNextNode lastFixedNode;
-
-    public GraphKit(StructuredGraph graph, Providers providers) {
-        this.providers = providers;
-        this.graph = graph;
-        this.lastFixedNode = graph.start();
-    }
-
-    public StructuredGraph getGraph() {
-        return graph;
-    }
-
-    /**
-     * Ensures a floating node is added to or already present in the graph via {@link Graph#unique}.
-     * 
-     * @return a node similar to {@code node} if one exists, otherwise {@code node}
-     */
-    protected <T extends FloatingNode> T unique(T node) {
-        return graph.unique(node);
-    }
-
-    /**
-     * Appends a fixed node to the graph.
-     */
-    protected <T extends FixedNode> T append(T node) {
-        T result = graph.add(node);
-        assert lastFixedNode != null;
-        assert result.predecessor() == null;
-        graph.addAfterFixed(lastFixedNode, result);
-        if (result instanceof FixedWithNextNode) {
-            lastFixedNode = (FixedWithNextNode) result;
-        } else {
-            lastFixedNode = null;
-        }
-        return result;
-    }
-
-    /**
-     * Creates and appends an {@link InvokeNode} for a call to a given method with a given set of
-     * arguments.
-     * 
-     * @param declaringClass the class declaring the invoked method
-     * @param name the name of the invoked method
-     * @param args the arguments to the invocation
-     */
-    public InvokeNode createInvoke(Class<?> declaringClass, String name, ValueNode... args) {
-        ResolvedJavaMethod method = null;
-        for (Method m : declaringClass.getDeclaredMethods()) {
-            if (Modifier.isStatic(m.getModifiers()) && m.getName().equals(name)) {
-                assert method == null : "found more than one method in " + declaringClass + " named " + name;
-                method = providers.getMetaAccess().lookupJavaMethod(m);
-            }
-        }
-        assert method != null : "did not find method in " + declaringClass + " named " + name;
-        Signature signature = method.getSignature();
-        JavaType returnType = signature.getReturnType(null);
-        assert checkArgs(method, args);
-        MethodCallTargetNode callTarget = graph.add(new MethodCallTargetNode(InvokeKind.Static, method, args, returnType));
-        InvokeNode invoke = append(new InvokeNode(callTarget, FrameState.UNKNOWN_BCI));
-        return invoke;
-    }
-
-    /**
-     * Determines if a given set of arguments is compatible with the signature of a given method.
-     * 
-     * @return true if {@code args} are compatible with the signature if {@code method}
-     * @throws AssertionError if {@code args} are not compatible with the signature if
-     *             {@code method}
-     */
-    public boolean checkArgs(ResolvedJavaMethod method, ValueNode... args) {
-        Signature signature = method.getSignature();
-        if (signature.getParameterCount(false) != args.length) {
-            throw new AssertionError(graph + ": wrong number of arguments to " + method);
-        }
-        for (int i = 0; i != args.length; i++) {
-            Kind expected = signature.getParameterKind(i).getStackKind();
-            Kind actual = args[i].stamp().kind();
-            if (expected != actual) {
-                throw new AssertionError(graph + ": wrong kind of value for argument " + i + " of calls to " + method + " [" + actual + " != " + expected + "]");
-            }
-        }
-        return true;
-    }
-
-    /**
-     * Rewrite all word types in the graph.
-     */
-    public void rewriteWordTypes() {
-        new WordTypeRewriterPhase(providers.getMetaAccess(), providers.getCodeCache().getTarget().wordKind).apply(graph);
-    }
-
-    /**
-     * {@linkplain #inline(InvokeNode) Inlines} all invocations currently in the graph.
-     */
-    public void inlineInvokes() {
-        for (InvokeNode invoke : graph.getNodes().filter(InvokeNode.class).snapshot()) {
-            inline(invoke);
-        }
-
-        // Clean up all code that is now dead after inlining.
-        new DeadCodeEliminationPhase().apply(graph);
-        assert graph.getNodes().filter(InvokeNode.class).isEmpty();
-    }
-
-    /**
-     * Inlines a given invocation to a method. The graph of the inlined method is
-     * {@linkplain ReplacementsImpl#makeGraph processed} in the same manner as for snippets and
-     * method substitutions.
-     */
-    public void inline(InvokeNode invoke) {
-        ResolvedJavaMethod method = ((MethodCallTargetNode) invoke.callTarget()).targetMethod();
-        ReplacementsImpl repl = new ReplacementsImpl(providers, new Assumptions(false), providers.getCodeCache().getTarget());
-        StructuredGraph calleeGraph = repl.makeGraph(method, null, method, null, FrameStateProcessing.CollapseFrameForSingleSideEffect);
-        InliningUtil.inline(invoke, calleeGraph, false);
-    }
-}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java	Wed Mar 05 19:40:15 2014 -0800
@@ -146,8 +146,8 @@
                 // The stub itself needs the incoming calling convention.
                 CallingConvention incomingCc = linkage.getIncomingCallingConvention();
                 final CompilationResult compResult = compileGraph(graph, incomingCc, getInstalledCodeOwner(), providers, backend, codeCache.getTarget(), null,
-                                providers.getSuites().getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL, getProfilingInfo(graph), new SpeculationLog(),
-                                providers.getSuites().getDefaultSuites(), true, new CompilationResult(), CompilationResultBuilderFactory.Default);
+                                providers.getSuites().getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL, getProfilingInfo(graph), null, providers.getSuites().getDefaultSuites(), true,
+                                new CompilationResult(), CompilationResultBuilderFactory.Default);
 
                 assert destroyedRegisters != null;
                 try (Scope s = Debug.scope("CodeInstall")) {
--- a/graal/com.oracle.graal.java.decompiler.test/src/com/oracle/graal/java/decompiler/test/TestUtil.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.java.decompiler.test/src/com/oracle/graal/java/decompiler/test/TestUtil.java	Wed Mar 05 19:40:15 2014 -0800
@@ -49,7 +49,7 @@
         new GraphBuilderPhase.Instance(metaAccess, GraphBuilderConfiguration.getEagerDefault(), OptimisticOptimizations.ALL).apply(graph);
         PhaseSuite<HighTierContext> graphBuilderSuite = suitesProvider.getDefaultGraphBuilderSuite();
         CallingConvention cc = getCallingConvention(providers.getCodeCache(), Type.JavaCallee, graph.method(), false);
-        compileGraph(graph, cc, method, providers, backend, providers.getCodeCache().getTarget(), null, graphBuilderSuite, OptimisticOptimizations.ALL, getProfilingInfo(graph), new SpeculationLog(),
-                        suites, true, new CompilationResult(), CompilationResultBuilderFactory.Default);
+        compileGraph(graph, cc, method, providers, backend, providers.getCodeCache().getTarget(), null, graphBuilderSuite, OptimisticOptimizations.ALL, getProfilingInfo(graph), null, suites, true,
+                        new CompilationResult(), CompilationResultBuilderFactory.Default);
     }
 }
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/BciBlockMapping.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/BciBlockMapping.java	Wed Mar 05 19:40:15 2014 -0800
@@ -172,7 +172,7 @@
      * 
      * @param method the compiler interface method containing the code
      */
-    public BciBlockMapping(ResolvedJavaMethod method) {
+    private BciBlockMapping(ResolvedJavaMethod method) {
         this.method = method;
         exceptionHandlers = method.getExceptionHandlers();
         stream = new BytecodeStream(method.getCode());
@@ -879,6 +879,16 @@
         }
     }
 
+    public static BciBlockMapping create(ResolvedJavaMethod method) {
+        BciBlockMapping map = new BciBlockMapping(method);
+        map.build();
+        if (Debug.isDumpEnabled()) {
+            Debug.dump(map, MetaUtil.format("After block building %f %R %H.%n(%P)", method));
+        }
+
+        return map;
+    }
+
     private static void loadTwo(Block block, int local) {
         loadOne(block, local);
         loadOne(block, local + 1);
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/FrameStateBuilder.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/FrameStateBuilder.java	Wed Mar 05 19:40:15 2014 -0800
@@ -90,7 +90,7 @@
             if (kind == Kind.Object && type instanceof ResolvedJavaType) {
                 stamp = StampFactory.declared((ResolvedJavaType) type);
             } else {
-                stamp = StampFactory.forKind(type.getKind());
+                stamp = StampFactory.forKind(kind);
             }
             ParameterNode param = graph.unique(new ParameterNode(index, stamp));
             storeLocal(javaIndex, param);
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Wed Mar 05 19:40:15 2014 -0800
@@ -44,6 +44,7 @@
 import com.oracle.graal.java.BciBlockMapping.ExceptionDispatchBlock;
 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;
@@ -67,8 +68,8 @@
 
     public static final class RuntimeCalls {
 
-        public static final ForeignCallDescriptor CREATE_NULL_POINTER_EXCEPTION = new ForeignCallDescriptor("createNullPointerException", Object.class);
-        public static final ForeignCallDescriptor CREATE_OUT_OF_BOUNDS_EXCEPTION = new ForeignCallDescriptor("createOutOfBoundsException", Object.class, int.class);
+        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", IndexOutOfBoundsException.class, int.class);
     }
 
     /**
@@ -213,16 +214,6 @@
             return getName() + " " + MetaUtil.format("%H.%n(%p):%r", method);
         }
 
-        private BciBlockMapping createBlockMap() {
-            BciBlockMapping map = new BciBlockMapping(method);
-            map.build();
-            if (Debug.isDumpEnabled()) {
-                Debug.dump(map, MetaUtil.format("After block building %f %R %H.%n(%P)", method));
-            }
-
-            return map;
-        }
-
         protected void build() {
             if (PrintProfilingInformation.getValue()) {
                 TTY.println("Profiling info for " + MetaUtil.format("%H.%n(%p)", method));
@@ -232,7 +223,7 @@
             Indent indent = Debug.logAndIndent("build graph for %s", method);
 
             // compute the block map, setup exception handlers and get the entrypoint(s)
-            BciBlockMapping blockMap = createBlockMap();
+            BciBlockMapping blockMap = BciBlockMapping.create(method);
             loopHeaders = blockMap.loopHeaders;
 
             lastInstr = currentGraph.start();
@@ -302,11 +293,11 @@
             return unwindBlock;
         }
 
-        public BytecodeStream stream() {
+        protected BytecodeStream stream() {
             return stream;
         }
 
-        public int bci() {
+        protected int bci() {
             return stream.currentBCI();
         }
 
@@ -326,14 +317,6 @@
             frameState.storeLocal(index, value);
         }
 
-        public static boolean covers(ExceptionHandler handler, int bci) {
-            return handler.getStartBCI() <= bci && bci < handler.getEndBCI();
-        }
-
-        public static boolean isCatchAll(ExceptionHandler handler) {
-            return handler.catchTypeCPI() == 0;
-        }
-
         /**
          * @param type the unresolved type of the constant
          */
@@ -597,35 +580,35 @@
             switch (opcode) {
                 case IADD:
                 case LADD:
-                    v = new IntegerAddNode(result, x, y);
+                    v = new IntegerAddNode(StampFactory.forKind(result), x, y);
                     break;
                 case FADD:
                 case DADD:
-                    v = new FloatAddNode(result, x, y, isStrictFP);
+                    v = new FloatAddNode(StampFactory.forKind(result), x, y, isStrictFP);
                     break;
                 case ISUB:
                 case LSUB:
-                    v = new IntegerSubNode(result, x, y);
+                    v = new IntegerSubNode(StampFactory.forKind(result), x, y);
                     break;
                 case FSUB:
                 case DSUB:
-                    v = new FloatSubNode(result, x, y, isStrictFP);
+                    v = new FloatSubNode(StampFactory.forKind(result), x, y, isStrictFP);
                     break;
                 case IMUL:
                 case LMUL:
-                    v = new IntegerMulNode(result, x, y);
+                    v = new IntegerMulNode(StampFactory.forKind(result), x, y);
                     break;
                 case FMUL:
                 case DMUL:
-                    v = new FloatMulNode(result, x, y, isStrictFP);
+                    v = new FloatMulNode(StampFactory.forKind(result), x, y, isStrictFP);
                     break;
                 case FDIV:
                 case DDIV:
-                    v = new FloatDivNode(result, x, y, isStrictFP);
+                    v = new FloatDivNode(StampFactory.forKind(result), x, y, isStrictFP);
                     break;
                 case FREM:
                 case DREM:
-                    v = new FloatRemNode(result, x, y, isStrictFP);
+                    v = new FloatRemNode(StampFactory.forKind(result), x, y, isStrictFP);
                     break;
                 default:
                     throw new GraalInternalError("should not reach");
@@ -640,11 +623,11 @@
             switch (opcode) {
                 case IDIV:
                 case LDIV:
-                    v = new IntegerDivNode(result, x, y);
+                    v = new IntegerDivNode(StampFactory.forKind(result), x, y);
                     break;
                 case IREM:
                 case LREM:
-                    v = new IntegerRemNode(result, x, y);
+                    v = new IntegerRemNode(StampFactory.forKind(result), x, y);
                     break;
                 default:
                     throw new GraalInternalError("should not reach");
@@ -663,15 +646,15 @@
             switch (opcode) {
                 case ISHL:
                 case LSHL:
-                    v = new LeftShiftNode(kind, x, s);
+                    v = new LeftShiftNode(StampFactory.forKind(kind), x, s);
                     break;
                 case ISHR:
                 case LSHR:
-                    v = new RightShiftNode(kind, x, s);
+                    v = new RightShiftNode(StampFactory.forKind(kind), x, s);
                     break;
                 case IUSHR:
                 case LUSHR:
-                    v = new UnsignedRightShiftNode(kind, x, s);
+                    v = new UnsignedRightShiftNode(StampFactory.forKind(kind), x, s);
                     break;
                 default:
                     throw new GraalInternalError("should not reach");
@@ -682,19 +665,20 @@
         private void genLogicOp(Kind kind, int opcode) {
             ValueNode y = frameState.pop(kind);
             ValueNode x = frameState.pop(kind);
+            Stamp stamp = StampFactory.forKind(kind);
             BitLogicNode v;
             switch (opcode) {
                 case IAND:
                 case LAND:
-                    v = new AndNode(kind, x, y);
+                    v = new AndNode(stamp, x, y);
                     break;
                 case IOR:
                 case LOR:
-                    v = new OrNode(kind, x, y);
+                    v = new OrNode(stamp, x, y);
                     break;
                 case IXOR:
                 case LXOR:
-                    v = new XorNode(kind, x, y);
+                    v = new XorNode(stamp, x, y);
                     break;
                 default:
                     throw new GraalInternalError("should not reach");
@@ -708,9 +692,30 @@
             frameState.ipush(append(new NormalizeCompareNode(x, y, isUnorderedLess)));
         }
 
-        private void genConvert(Kind from, Kind to) {
+        private void genFloatConvert(FloatConvert op, Kind from, Kind to) {
+            ValueNode input = frameState.pop(from.getStackKind());
+            frameState.push(to.getStackKind(), append(new FloatConvertNode(op, input)));
+        }
+
+        private void genSignExtend(Kind from, Kind to) {
             ValueNode input = frameState.pop(from.getStackKind());
-            frameState.push(to.getStackKind(), append(new ConvertNode(from, to, input)));
+            if (from != from.getStackKind()) {
+                input = append(new NarrowNode(input, from.getBitCount()));
+            }
+            frameState.push(to.getStackKind(), append(new SignExtendNode(input, to.getBitCount())));
+        }
+
+        private void genZeroExtend(Kind from, Kind to) {
+            ValueNode input = frameState.pop(from.getStackKind());
+            if (from != from.getStackKind()) {
+                input = append(new NarrowNode(input, from.getBitCount()));
+            }
+            frameState.push(to.getStackKind(), append(new ZeroExtendNode(input, to.getBitCount())));
+        }
+
+        private void genNarrow(Kind from, Kind to) {
+            ValueNode input = frameState.pop(from.getStackKind());
+            frameState.push(to.getStackKind(), append(new NarrowNode(input, to.getBitCount())));
         }
 
         private void genIncrement() {
@@ -718,7 +723,7 @@
             int delta = stream().readIncrement();
             ValueNode x = frameState.loadLocal(index);
             ValueNode y = appendConstant(Constant.forInt(delta));
-            frameState.storeLocal(index, append(new IntegerAddNode(Kind.Int, x, y)));
+            frameState.storeLocal(index, append(new IntegerAddNode(StampFactory.forKind(Kind.Int), x, y)));
         }
 
         private void genGoto() {
@@ -815,10 +820,12 @@
             eagerResolvingForSnippets(cpi, opcode);
             JavaMethod result = constantPool.lookupMethod(cpi, opcode);
             /*
-             * assert !graphBuilderConfig.unresolvedIsError() || ((result instanceof
-             * ResolvedJavaMethod) && ((ResolvedJavaMethod)
-             * result).getDeclaringClass().isInitialized()) : result;
+             * In general, one cannot assume that the declaring class being initialized is useful,
+             * since the actual concrete receiver may be a different class (except for static
+             * calls). Also, interfaces are initialized only under special circumstances, so that
+             * this assertion would often fail for interface calls.
              */
+            assert !graphBuilderConfig.unresolvedIsError() || (result instanceof ResolvedJavaMethod && (opcode != INVOKESTATIC || ((ResolvedJavaMethod) result).getDeclaringClass().isInitialized()));
             return result;
         }
 
@@ -950,12 +957,16 @@
                 dims[i] = frameState.ipop();
             }
             if (type instanceof ResolvedJavaType) {
-                frameState.apush(append(new NewMultiArrayNode((ResolvedJavaType) type, dims)));
+                frameState.apush(append(createNewMultiArray((ResolvedJavaType) type, dims)));
             } else {
                 handleUnresolvedNewMultiArray(type, dims);
             }
         }
 
+        protected NewMultiArrayNode createNewMultiArray(ResolvedJavaType type, ValueNode[] dimensions) {
+            return new NewMultiArrayNode(type, dimensions);
+        }
+
         private void genGetField(JavaField field) {
             emitExplicitExceptions(frameState.peek(0), null);
 
@@ -993,6 +1004,7 @@
                 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()));
@@ -1017,12 +1029,15 @@
                 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()));
             }
         }
 
+        private static final DebugMetric EXPLICIT_EXCEPTIONS = Debug.metric("ExplicitExceptions");
+
         protected void emitExplicitExceptions(ValueNode receiver, ValueNode outOfBoundsIndex) {
             assert receiver != null;
             if (graphBuilderConfig.omitAllExceptionEdges() || (optimisticOpts.useExceptionProbabilityForOperations() && profilingInfo.getExceptionSeen(bci()) == TriState.FALSE)) {
@@ -1034,7 +1049,7 @@
                 ValueNode length = append(new ArrayLengthNode(receiver));
                 emitBoundsCheck(outOfBoundsIndex, length);
             }
-            Debug.metric("ExplicitExceptions").increment();
+            EXPLICIT_EXCEPTIONS.increment();
         }
 
         private void genPutField(JavaField field) {
@@ -1067,15 +1082,6 @@
             }
         }
 
-        private ConstantNode genTypeOrDeopt(Representation representation, JavaType type, boolean initialized) {
-            if (initialized) {
-                return appendConstant(((ResolvedJavaType) type).getEncoding(representation));
-            } else {
-                handleUnresolvedExceptionType(representation, type);
-                return null;
-            }
-        }
-
         private void appendOptimizedStoreField(StoreFieldNode store) {
             append(store);
         }
@@ -1711,14 +1717,17 @@
                 ResolvedJavaType resolvedCatchType = (ResolvedJavaType) catchType;
                 for (ResolvedJavaType skippedType : graphBuilderConfig.getSkippedExceptionTypes()) {
                     if (skippedType.isAssignableFrom(resolvedCatchType)) {
-                        append(new DeoptimizeNode(InvalidateReprofile, UnreachedCode));
+                        Block nextBlock = block.successors.size() == 1 ? unwindBlock(block.deoptBci) : block.successors.get(1);
+                        ValueNode exception = frameState.stackAt(0);
+                        FixedNode trueSuccessor = currentGraph.add(new DeoptimizeNode(InvalidateReprofile, UnreachedCode));
+                        FixedNode nextDispatch = createTarget(nextBlock, frameState);
+                        append(new IfNode(currentGraph.unique(new InstanceOfNode((ResolvedJavaType) catchType, exception, null)), trueSuccessor, nextDispatch, 0));
                         return;
                     }
                 }
             }
 
-            ConstantNode typeInstruction = genTypeOrDeopt(Representation.ObjectHub, catchType, initialized);
-            if (typeInstruction != null) {
+            if (initialized) {
                 Block nextBlock = block.successors.size() == 1 ? unwindBlock(block.deoptBci) : block.successors.get(1);
                 ValueNode exception = frameState.stackAt(0);
                 CheckCastNode checkCast = currentGraph.add(new CheckCastNode((ResolvedJavaType) catchType, exception, null, false));
@@ -1730,6 +1739,8 @@
                 FixedNode nextDispatch = createTarget(nextBlock, frameState);
                 checkCast.setNext(catchSuccessor);
                 append(new IfNode(currentGraph.unique(new InstanceOfNode((ResolvedJavaType) catchType, exception, null)), checkCast, nextDispatch, 0.5));
+            } else {
+                handleUnresolvedExceptionType(Representation.ObjectHub, catchType);
             }
         }
 
@@ -1991,21 +2002,21 @@
             case LOR            : // fall through
             case LXOR           : genLogicOp(Kind.Long, opcode); break;
             case IINC           : genIncrement(); break;
-            case I2L            : genConvert(Kind.Int, Kind.Long); break;
-            case I2F            : genConvert(Kind.Int, Kind.Float); break;
-            case I2D            : genConvert(Kind.Int, Kind.Double); break;
-            case L2I            : genConvert(Kind.Long, Kind.Int); break;
-            case L2F            : genConvert(Kind.Long, Kind.Float); break;
-            case L2D            : genConvert(Kind.Long, Kind.Double); break;
-            case F2I            : genConvert(Kind.Float, Kind.Int); break;
-            case F2L            : genConvert(Kind.Float, Kind.Long); break;
-            case F2D            : genConvert(Kind.Float, Kind.Double); break;
-            case D2I            : genConvert(Kind.Double, Kind.Int); break;
-            case D2L            : genConvert(Kind.Double, Kind.Long); break;
-            case D2F            : genConvert(Kind.Double, Kind.Float); break;
-            case I2B            : genConvert(Kind.Int, Kind.Byte); break;
-            case I2C            : genConvert(Kind.Int, Kind.Char); break;
-            case I2S            : genConvert(Kind.Int, Kind.Short); break;
+            case I2F            : genFloatConvert(FloatConvert.I2F, Kind.Int, Kind.Float); break;
+            case I2D            : genFloatConvert(FloatConvert.I2D, Kind.Int, Kind.Double); break;
+            case L2F            : genFloatConvert(FloatConvert.L2F, Kind.Long, Kind.Float); break;
+            case L2D            : genFloatConvert(FloatConvert.L2D, Kind.Long, Kind.Double); break;
+            case F2I            : genFloatConvert(FloatConvert.F2I, Kind.Float, Kind.Int); break;
+            case F2L            : genFloatConvert(FloatConvert.F2L, Kind.Float, Kind.Long); break;
+            case F2D            : genFloatConvert(FloatConvert.F2D, Kind.Float, Kind.Double); break;
+            case D2I            : genFloatConvert(FloatConvert.D2I, Kind.Double, Kind.Int); break;
+            case D2L            : genFloatConvert(FloatConvert.D2L, Kind.Double, Kind.Long); break;
+            case D2F            : genFloatConvert(FloatConvert.D2F, Kind.Double, Kind.Float); break;
+            case L2I            : genNarrow(Kind.Long, Kind.Int); break;
+            case I2L            : genSignExtend(Kind.Int, Kind.Long); break;
+            case I2B            : genSignExtend(Kind.Byte, Kind.Int); break;
+            case I2S            : genSignExtend(Kind.Short, Kind.Int); break;
+            case I2C            : genZeroExtend(Kind.Char, Kind.Int); break;
             case LCMP           : genCompareOp(Kind.Long, false); break;
             case FCMPL          : genCompareOp(Kind.Float, true); break;
             case FCMPG          : genCompareOp(Kind.Float, false); break;
--- a/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/bytecode/BC_i2b.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/bytecode/BC_i2b.java	Wed Mar 05 19:40:15 2014 -0800
@@ -53,4 +53,51 @@
         runTest("test", 128);
     }
 
+    public static int testInt(int a) {
+        return (byte) a;
+    }
+
+    @Test
+    public void runI0() throws Throwable {
+        runTest("testInt", -1);
+    }
+
+    @Test
+    public void runI1() throws Throwable {
+        runTest("testInt", 2);
+    }
+
+    @Test
+    public void runI2() throws Throwable {
+        runTest("testInt", 255);
+    }
+
+    @Test
+    public void runI3() throws Throwable {
+        runTest("testInt", 128);
+    }
+
+    public static long testLong(int a) {
+        return (byte) a;
+    }
+
+    @Test
+    public void runL0() throws Throwable {
+        runTest("testLong", -1);
+    }
+
+    @Test
+    public void runL1() throws Throwable {
+        runTest("testLong", 2);
+    }
+
+    @Test
+    public void runL2() throws Throwable {
+        runTest("testLong", 255);
+    }
+
+    @Test
+    public void runL3() throws Throwable {
+        runTest("testLong", 128);
+    }
 }
--- a/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/bytecode/BC_i2c.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/bytecode/BC_i2c.java	Wed Mar 05 19:40:15 2014 -0800
@@ -48,4 +48,41 @@
         runTest("test", 65535);
     }
 
+    public static int testInt(int a) {
+        return (char) a;
+    }
+
+    @Test
+    public void runI0() throws Throwable {
+        runTest("testInt", -1);
+    }
+
+    @Test
+    public void runI1() throws Throwable {
+        runTest("testInt", 645);
+    }
+
+    @Test
+    public void runI2() throws Throwable {
+        runTest("testInt", 65535);
+    }
+
+    public static long testLong(int a) {
+        return (char) a;
+    }
+
+    @Test
+    public void runL0() throws Throwable {
+        runTest("testLong", -1);
+    }
+
+    @Test
+    public void runL1() throws Throwable {
+        runTest("testLong", 645);
+    }
+
+    @Test
+    public void runL2() throws Throwable {
+        runTest("testLong", 65535);
+    }
 }
--- a/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/bytecode/BC_i2s.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/bytecode/BC_i2s.java	Wed Mar 05 19:40:15 2014 -0800
@@ -53,4 +53,51 @@
         runTest("test", 32768);
     }
 
+    public static int testInt(int a) {
+        return (short) a;
+    }
+
+    @Test
+    public void runI0() throws Throwable {
+        runTest("testInt", -1);
+    }
+
+    @Test
+    public void runI1() throws Throwable {
+        runTest("testInt", 34);
+    }
+
+    @Test
+    public void runI2() throws Throwable {
+        runTest("testInt", 65535);
+    }
+
+    @Test
+    public void runI3() throws Throwable {
+        runTest("testInt", 32768);
+    }
+
+    public static long testLong(int a) {
+        return (short) a;
+    }
+
+    @Test
+    public void runL0() throws Throwable {
+        runTest("testLong", -1);
+    }
+
+    @Test
+    public void runL1() throws Throwable {
+        runTest("testLong", 34);
+    }
+
+    @Test
+    public void runL2() throws Throwable {
+        runTest("testLong", 65535);
+    }
+
+    @Test
+    public void runL3() throws Throwable {
+        runTest("testLong", 32768);
+    }
 }
--- a/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/optimize/ConvertCompare.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/optimize/ConvertCompare.java	Wed Mar 05 19:40:15 2014 -0800
@@ -34,4 +34,32 @@
     public void run0() throws Throwable {
         runTest("test", 0, 2.87f);
     }
+
+    public static boolean testChar42(int x) {
+        return ((char) x) == 42;
+    }
+
+    @Test
+    public void run1() {
+        runTest("testChar42", 42);
+    }
+
+    @Test
+    public void run2() {
+        runTest("testChar42", (int) Character.MAX_VALUE);
+    }
+
+    public static boolean testCharMax(int x) {
+        return ((char) x) == Character.MAX_VALUE;
+    }
+
+    @Test
+    public void run3() {
+        runTest("testCharMax", 42);
+    }
+
+    @Test
+    public void run4() {
+        runTest("testCharMax", (int) Character.MAX_VALUE);
+    }
 }
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Arithmetic.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Arithmetic.java	Wed Mar 05 19:40:15 2014 -0800
@@ -44,7 +44,7 @@
     DADD, DSUB, DMUL, DDIV, DREM, DAND, DOR, DXOR,
     INEG, LNEG, INOT, LNOT,
     SQRT,
-    I2L, L2I, I2B, I2C, I2S,
+    L2I, B2I, S2I, B2L, S2L, I2L,
     F2D, D2F,
     I2F, I2D,
     L2F, L2D,
@@ -373,9 +373,6 @@
             case L2I:
                 masm.andl(asIntReg(result), 0xFFFFFFFF);
                 break;
-            case I2C:
-                masm.andl(asIntReg(result), 0xFFFF);
-                break;
             default:
                 throw GraalInternalError.shouldNotReachHere();
         }
@@ -495,12 +492,18 @@
                     masm.sqrtsd(asDoubleReg(dst), asDoubleReg(src));
                     break;
 
-                case I2B:
+                case B2I:
                     masm.movsbl(asIntReg(dst), asIntReg(src));
                     break;
-                case I2S:
+                case S2I:
                     masm.movswl(asIntReg(dst), asIntReg(src));
                     break;
+                case B2L:
+                    masm.movsbq(asLongReg(dst), asIntReg(src));
+                    break;
+                case S2L:
+                    masm.movswq(asLongReg(dst), asIntReg(src));
+                    break;
                 case I2L:
                     masm.movslq(asLongReg(dst), asIntReg(src));
                     break;
@@ -551,7 +554,7 @@
                 case IDIV:
                 case IREM:
                     masm.cdql();
-                    exceptionOffset = masm.codeBuffer.position();
+                    exceptionOffset = masm.position();
                     masm.idivl(asRegister(src));
                     break;
 
@@ -559,7 +562,7 @@
                 case LDIV:
                 case LREM:
                     masm.cdqq();
-                    exceptionOffset = masm.codeBuffer.position();
+                    exceptionOffset = masm.position();
                     masm.idivq(asRegister(src));
                     break;
 
@@ -567,7 +570,7 @@
                 case IUREM:
                     // Must zero the high 64-bit word (in RDX) of the dividend
                     masm.xorq(AMD64.rdx, AMD64.rdx);
-                    exceptionOffset = masm.codeBuffer.position();
+                    exceptionOffset = masm.position();
                     masm.divl(asRegister(src));
                     break;
 
@@ -575,7 +578,7 @@
                 case LUREM:
                     // Must zero the high 64-bit word (in RDX) of the dividend
                     masm.xorq(AMD64.rdx, AMD64.rdx);
-                    exceptionOffset = masm.codeBuffer.position();
+                    exceptionOffset = masm.position();
                     masm.divq(asRegister(src));
                     break;
                 default:
@@ -755,12 +758,18 @@
                     masm.sqrtsd(asDoubleReg(dst), (AMD64Address) crb.asDoubleAddr(src));
                     break;
 
-                case I2B:
+                case B2I:
                     masm.movsbl(asIntReg(dst), (AMD64Address) crb.asIntAddr(src));
                     break;
-                case I2S:
+                case S2I:
                     masm.movswl(asIntReg(dst), (AMD64Address) crb.asIntAddr(src));
                     break;
+                case B2L:
+                    masm.movsbq(asLongReg(dst), (AMD64Address) crb.asIntAddr(src));
+                    break;
+                case S2L:
+                    masm.movswq(asLongReg(dst), (AMD64Address) crb.asIntAddr(src));
+                    break;
                 case I2L:
                     masm.movslq(asLongReg(dst), (AMD64Address) crb.asIntAddr(src));
                     break;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64ArrayEqualsOp.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,295 @@
+/*
+ * 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.lir.amd64;
+
+import static com.oracle.graal.api.code.ValueUtil.*;
+import static com.oracle.graal.graph.UnsafeAccess.*;
+import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
+
+import java.lang.reflect.*;
+
+import com.oracle.graal.amd64.*;
+import com.oracle.graal.amd64.AMD64.*;
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.asm.*;
+import com.oracle.graal.asm.amd64.*;
+import com.oracle.graal.asm.amd64.AMD64Address.Scale;
+import com.oracle.graal.asm.amd64.AMD64Assembler.*;
+import com.oracle.graal.lir.*;
+import com.oracle.graal.lir.asm.*;
+import com.oracle.graal.nodes.spi.*;
+
+/**
+ * Emits code which compares two arrays of the same length. If the CPU supports any vector
+ * instructions specialized code is emitted to leverage these instructions.
+ */
+@Opcode("ARRAY_EQUALS")
+public class AMD64ArrayEqualsOp extends AMD64LIRInstruction {
+
+    private final Kind kind;
+    private final int arrayBaseOffset;
+    private final int arrayIndexScale;
+
+    @Def({REG}) protected Value resultValue;
+    @Alive({REG}) protected Value array1Value;
+    @Alive({REG}) protected Value array2Value;
+    @Alive({REG}) protected Value lengthValue;
+    @Temp({REG}) protected Value temp1;
+    @Temp({REG}) protected Value temp2;
+    @Temp({REG}) protected Value temp3;
+    @Temp({REG}) protected Value temp4;
+    @Temp({REG}) protected Value vectorTemp1;
+    @Temp({REG}) protected Value vectorTemp2;
+
+    public AMD64ArrayEqualsOp(LIRGeneratorTool tool, Kind kind, Value result, Value array1, Value array2, Value length) {
+        this.kind = kind;
+
+        Class<?> arrayClass = Array.newInstance(kind.toJavaClass(), 0).getClass();
+        this.arrayBaseOffset = unsafe.arrayBaseOffset(arrayClass);
+        this.arrayIndexScale = unsafe.arrayIndexScale(arrayClass);
+
+        this.resultValue = result;
+        this.array1Value = array1;
+        this.array2Value = array2;
+        this.lengthValue = length;
+
+        // Allocate some temporaries.
+        this.temp1 = tool.newVariable(tool.target().wordKind);
+        this.temp2 = tool.newVariable(tool.target().wordKind);
+        this.temp3 = tool.newVariable(tool.target().wordKind);
+        this.temp4 = tool.newVariable(tool.target().wordKind);
+
+        // We only need the vector temporaries if we generate SSE code.
+        if (supportsSSE41(tool.target())) {
+            this.vectorTemp1 = tool.newVariable(Kind.Double);
+            this.vectorTemp2 = tool.newVariable(Kind.Double);
+        }
+    }
+
+    @Override
+    public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
+        Register result = asRegister(resultValue);
+        Register array1 = asRegister(temp1);
+        Register array2 = asRegister(temp2);
+        Register length = asRegister(temp3);
+
+        Label trueLabel = new Label();
+        Label falseLabel = new Label();
+        Label done = new Label();
+
+        // Load array base addresses.
+        masm.leaq(array1, new AMD64Address(asRegister(array1Value), arrayBaseOffset));
+        masm.leaq(array2, new AMD64Address(asRegister(array2Value), arrayBaseOffset));
+
+        // Get array length in bytes.
+        masm.imull(length, asRegister(lengthValue), arrayIndexScale);
+        masm.movl(result, length); // copy
+
+        if (supportsSSE41(crb.target)) {
+            emitSSE41Compare(crb, masm, result, array1, array2, length, trueLabel, falseLabel);
+        }
+
+        emit8ByteCompare(crb, masm, result, array1, array2, length, trueLabel, falseLabel);
+        emitTailCompares(masm, result, array1, array2, length, trueLabel, falseLabel);
+
+        // Return true
+        masm.bind(trueLabel);
+        masm.movl(result, 1);
+        masm.jmpb(done);
+
+        // Return false
+        masm.bind(falseLabel);
+        masm.xorl(result, result);
+
+        // That's it
+        masm.bind(done);
+    }
+
+    /**
+     * Returns if the underlying AMD64 architecture supports SSE 4.1 instructions.
+     * 
+     * @param target target description of the underlying architecture
+     * @return true if the underlying architecture supports SSE 4.1
+     */
+    private static boolean supportsSSE41(TargetDescription target) {
+        AMD64 arch = (AMD64) target.arch;
+        return arch.getFeatures().contains(CPUFeature.SSE4_1);
+    }
+
+    /**
+     * Vector size used in {@link #emitSSE41Compare}.
+     */
+    private static final int SSE4_1_VECTOR_SIZE = 16;
+
+    /**
+     * Emits code that uses SSE4.1 128-bit (16-byte) vector compares.
+     */
+    private void emitSSE41Compare(CompilationResultBuilder crb, AMD64MacroAssembler masm, Register result, Register array1, Register array2, Register length, Label trueLabel, Label falseLabel) {
+        assert supportsSSE41(crb.target);
+
+        Register vector1 = asDoubleReg(vectorTemp1);
+        Register vector2 = asDoubleReg(vectorTemp2);
+
+        Label loop = new Label();
+        Label compareTail = new Label();
+
+        // Compare 16-byte vectors
+        masm.andl(result, SSE4_1_VECTOR_SIZE - 1); // tail count (in bytes)
+        masm.andl(length, ~(SSE4_1_VECTOR_SIZE - 1)); // vector count (in bytes)
+        masm.jccb(ConditionFlag.Zero, compareTail);
+
+        masm.leaq(array1, new AMD64Address(array1, length, Scale.Times1, 0));
+        masm.leaq(array2, new AMD64Address(array2, length, Scale.Times1, 0));
+        masm.negq(length);
+
+        // Align the main loop
+        masm.align(crb.target.wordSize * 2);
+        masm.bind(loop);
+        masm.movdqu(vector1, new AMD64Address(array1, length, Scale.Times1, 0));
+        masm.movdqu(vector2, new AMD64Address(array2, length, Scale.Times1, 0));
+        masm.pxor(vector1, vector2);
+        masm.ptest(vector1, vector1);
+        masm.jcc(ConditionFlag.NotZero, falseLabel);
+        masm.addq(length, SSE4_1_VECTOR_SIZE);
+        masm.jcc(ConditionFlag.NotZero, loop);
+
+        masm.testl(result, result);
+        masm.jcc(ConditionFlag.Zero, trueLabel);
+
+        /*
+         * Compare the remaining bytes with an unaligned memory load aligned to the end of the
+         * array.
+         */
+        masm.movdqu(vector1, new AMD64Address(array1, result, Scale.Times1, -SSE4_1_VECTOR_SIZE));
+        masm.movdqu(vector2, new AMD64Address(array2, result, Scale.Times1, -SSE4_1_VECTOR_SIZE));
+        masm.pxor(vector1, vector2);
+        masm.ptest(vector1, vector1);
+        masm.jcc(ConditionFlag.NotZero, falseLabel);
+        masm.jmp(trueLabel);
+
+        masm.bind(compareTail);
+        masm.movl(length, result);
+    }
+
+    /**
+     * Vector size used in {@link #emit8ByteCompare}.
+     */
+    private static final int VECTOR_SIZE = 8;
+
+    /**
+     * Emits code that uses 8-byte vector compares.
+     */
+    private void emit8ByteCompare(CompilationResultBuilder crb, AMD64MacroAssembler masm, Register result, Register array1, Register array2, Register length, Label trueLabel, Label falseLabel) {
+        Label loop = new Label();
+        Label compareTail = new Label();
+
+        Register temp = asRegister(temp4);
+
+        masm.andl(result, VECTOR_SIZE - 1); // tail count (in bytes)
+        masm.andl(length, ~(VECTOR_SIZE - 1));  // vector count (in bytes)
+        masm.jccb(ConditionFlag.Zero, compareTail);
+
+        masm.leaq(array1, new AMD64Address(array1, length, Scale.Times1, 0));
+        masm.leaq(array2, new AMD64Address(array2, length, Scale.Times1, 0));
+        masm.negq(length);
+
+        // Align the main loop
+        masm.align(crb.target.wordSize * 2);
+        masm.bind(loop);
+        masm.movq(temp, new AMD64Address(array1, length, Scale.Times1, 0));
+        masm.cmpq(temp, new AMD64Address(array2, length, Scale.Times1, 0));
+        masm.jccb(ConditionFlag.NotEqual, falseLabel);
+        masm.addq(length, VECTOR_SIZE);
+        masm.jccb(ConditionFlag.NotZero, loop);
+
+        masm.testl(result, result);
+        masm.jccb(ConditionFlag.Zero, trueLabel);
+
+        /*
+         * Compare the remaining bytes with an unaligned memory load aligned to the end of the
+         * array.
+         */
+        masm.movq(temp, new AMD64Address(array1, result, Scale.Times1, -VECTOR_SIZE));
+        masm.cmpq(temp, new AMD64Address(array2, result, Scale.Times1, -VECTOR_SIZE));
+        masm.jccb(ConditionFlag.NotEqual, falseLabel);
+        masm.jmpb(trueLabel);
+
+        masm.bind(compareTail);
+        masm.movl(length, result);
+    }
+
+    /**
+     * Emits code to compare the remaining 1 to 4 bytes.
+     */
+    private void emitTailCompares(AMD64MacroAssembler masm, Register result, Register array1, Register array2, Register length, Label trueLabel, Label falseLabel) {
+        Label compare2Bytes = new Label();
+        Label compare1Byte = new Label();
+
+        Register temp = asRegister(temp4);
+
+        if (kind.getByteCount() <= 4) {
+            // Compare trailing 4 bytes, if any.
+            masm.testl(result, 4);
+            masm.jccb(ConditionFlag.Zero, compare2Bytes);
+            masm.movl(temp, new AMD64Address(array1, 0));
+            masm.cmpl(temp, new AMD64Address(array2, 0));
+            masm.jccb(ConditionFlag.NotEqual, falseLabel);
+
+            if (kind.getByteCount() <= 2) {
+                // Move array pointers forward.
+                masm.leaq(array1, new AMD64Address(array1, 4));
+                masm.leaq(array2, new AMD64Address(array2, 4));
+
+                // Compare trailing 2 bytes, if any.
+                masm.bind(compare2Bytes);
+                masm.testl(result, 2);
+                masm.jccb(ConditionFlag.Zero, compare1Byte);
+                masm.movzwl(temp, new AMD64Address(array1, 0));
+                masm.movzwl(length, new AMD64Address(array2, 0));
+                masm.cmpl(temp, length);
+                masm.jccb(ConditionFlag.NotEqual, falseLabel);
+
+                // The one-byte tail compare is only required for boolean and byte arrays.
+                if (kind.getByteCount() <= 1) {
+                    // Move array pointers forward before we compare the last trailing byte.
+                    masm.leaq(array1, new AMD64Address(array1, 2));
+                    masm.leaq(array2, new AMD64Address(array2, 2));
+
+                    // Compare trailing byte, if any.
+                    masm.bind(compare1Byte);
+                    masm.testl(result, 1);
+                    masm.jccb(ConditionFlag.Zero, trueLabel);
+                    masm.movzbl(temp, new AMD64Address(array1, 0));
+                    masm.movzbl(length, new AMD64Address(array2, 0));
+                    masm.cmpl(temp, length);
+                    masm.jccb(ConditionFlag.NotEqual, falseLabel);
+                } else {
+                    masm.bind(compare1Byte);
+                }
+            } else {
+                masm.bind(compare2Bytes);
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64CCall.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,62 @@
+/*
+ * 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.amd64;
+
+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.lir.asm.*;
+
+public class AMD64CCall extends AMD64LIRInstruction {
+
+    @Def({REG, ILLEGAL}) protected Value result;
+    @Use({REG, STACK}) protected Value[] parameters;
+    @Use({REG}) protected Value functionPtr;
+    @Use({REG}) protected Value numberOfFloatingPointArguments;
+
+    public AMD64CCall(Value result, Value functionPtr, Value numberOfFloatingPointArguments, Value[] parameters) {
+        this.result = result;
+        this.functionPtr = functionPtr;
+        this.parameters = parameters;
+        this.numberOfFloatingPointArguments = numberOfFloatingPointArguments;
+    }
+
+    @Override
+    public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
+        directCall(masm);
+    }
+
+    private void directCall(AMD64MacroAssembler masm) {
+        Register reg = ValueUtil.asRegister(functionPtr);
+        masm.call(reg);
+        masm.ensureUniquePC();
+    }
+
+    @Override
+    public boolean destroysCallerSavedRegisters() {
+        return true;
+    }
+
+}
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Call.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Call.java	Wed Mar 05 19:40:15 2014 -0800
@@ -155,7 +155,7 @@
         if (align) {
             emitAlignmentForDirectCall(crb, masm);
         }
-        int before = masm.codeBuffer.position();
+        int before = masm.position();
         if (scratch != null) {
             // offset might not fit a 32-bit immediate, generate an
             // indirect call with a 64-bit immediate
@@ -164,7 +164,7 @@
         } else {
             masm.call();
         }
-        int after = masm.codeBuffer.position();
+        int after = masm.position();
         crb.recordDirectCall(before, after, callTarget, info);
         crb.recordExceptionHandlers(after, info);
         masm.ensureUniquePC();
@@ -172,7 +172,7 @@
 
     protected static void emitAlignmentForDirectCall(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
         // make sure that the displacement word of the call ends up word aligned
-        int offset = masm.codeBuffer.position();
+        int offset = masm.position();
         offset += crb.target.arch.getMachineCodeCallDisplacementOffset();
         int modulus = crb.target.wordSize;
         if (offset % modulus != 0) {
@@ -181,25 +181,25 @@
     }
 
     public static void directJmp(CompilationResultBuilder crb, AMD64MacroAssembler masm, InvokeTarget target) {
-        int before = masm.codeBuffer.position();
+        int before = masm.position();
         masm.jmp(0, true);
-        int after = masm.codeBuffer.position();
+        int after = masm.position();
         crb.recordDirectCall(before, after, target, null);
         masm.ensureUniquePC();
     }
 
     public static void directConditionalJmp(CompilationResultBuilder crb, AMD64MacroAssembler masm, InvokeTarget target, ConditionFlag cond) {
-        int before = masm.codeBuffer.position();
+        int before = masm.position();
         masm.jcc(cond, 0, true);
-        int after = masm.codeBuffer.position();
+        int after = masm.position();
         crb.recordDirectCall(before, after, target, null);
         masm.ensureUniquePC();
     }
 
     public static void indirectCall(CompilationResultBuilder crb, AMD64MacroAssembler masm, Register dst, InvokeTarget callTarget, LIRFrameState info) {
-        int before = masm.codeBuffer.position();
+        int before = masm.position();
         masm.call(dst);
-        int after = masm.codeBuffer.position();
+        int after = masm.position();
         crb.recordIndirectCall(before, after, callTarget, info);
         crb.recordExceptionHandlers(after, info);
         masm.ensureUniquePC();
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64CharArrayEqualsOp.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,216 +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.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle 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.amd64;
-
-import static com.oracle.graal.api.code.ValueUtil.*;
-import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
-import sun.misc.*;
-
-import com.oracle.graal.amd64.*;
-import com.oracle.graal.amd64.AMD64.*;
-import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.asm.*;
-import com.oracle.graal.asm.amd64.*;
-import com.oracle.graal.asm.amd64.AMD64Address.Scale;
-import com.oracle.graal.asm.amd64.AMD64Assembler.*;
-import com.oracle.graal.lir.*;
-import com.oracle.graal.lir.asm.*;
-import com.oracle.graal.nodes.spi.*;
-
-/**
- * Emits code which compares two {@code char[]}. If the CPU supports any vector instructions
- * specialized code is emitted to leverage these instructions.
- */
-@Opcode("CHAR_ARRAY_EQUALS")
-public class AMD64CharArrayEqualsOp extends AMD64LIRInstruction {
-
-    @Def({REG}) protected Value resultValue;
-    @Alive({REG}) protected Value array1Value;
-    @Alive({REG}) protected Value array2Value;
-    @Alive({REG}) protected Value lengthValue;
-    @Temp({REG}) protected Value temp1;
-    @Temp({REG}) protected Value temp2;
-    @Temp({REG}) protected Value temp3;
-    @Temp({REG}) protected Value temp4;
-    @Temp({REG}) protected Value vectorTemp1;
-    @Temp({REG}) protected Value vectorTemp2;
-
-    public AMD64CharArrayEqualsOp(LIRGeneratorTool tool, Value result, Value array1, Value array2, Value length) {
-        this.resultValue = result;
-        this.array1Value = array1;
-        this.array2Value = array2;
-        this.lengthValue = length;
-
-        // Allocate some temporaries.
-        this.temp1 = tool.newVariable(tool.target().wordKind);
-        this.temp2 = tool.newVariable(tool.target().wordKind);
-        this.temp3 = tool.newVariable(tool.target().wordKind);
-        this.temp4 = tool.newVariable(tool.target().wordKind);
-
-        // We only need the vector temporaries if we generate SSE code.
-        if (supportsSSE41(tool.target())) {
-            this.vectorTemp1 = tool.newVariable(Kind.Double);
-            this.vectorTemp2 = tool.newVariable(Kind.Double);
-        }
-    }
-
-    /**
-     * Returns if the underlying AMD64 architecture supports SSE 4.1 instructions.
-     * 
-     * @param target target description of the underlying architecture
-     * @return true if the underlying architecture supports SSE 4.1
-     */
-    private static boolean supportsSSE41(TargetDescription target) {
-        AMD64 arch = (AMD64) target.arch;
-        return arch.getFeatures().contains(CPUFeature.SSE4_1);
-    }
-
-    @Override
-    public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
-        Register result = asRegister(resultValue);
-        Register array1 = asRegister(temp1);
-        Register array2 = asRegister(temp2);
-        Register length = asRegister(temp3);
-
-        Label trueLabel = new Label();
-        Label falseLabel = new Label();
-
-        // Load array base addresses.
-        masm.leaq(array1, new AMD64Address(asRegister(array1Value), Unsafe.ARRAY_CHAR_BASE_OFFSET));
-        masm.leaq(array2, new AMD64Address(asRegister(array2Value), Unsafe.ARRAY_CHAR_BASE_OFFSET));
-
-        masm.movq(length, asRegister(lengthValue));
-        masm.shll(length, 1); // get length in bytes
-        masm.movl(result, length); // copy
-
-        if (supportsSSE41(crb.target)) {
-            emitSSE41Compare(crb, masm, result, array1, array2, length, falseLabel, trueLabel);
-            // Fall-through to tail compare.
-        }
-        emit4ByteCompare(crb, masm, result, array1, array2, length, falseLabel, trueLabel);
-    }
-
-    /**
-     * Vector size used in {@link #emit4ByteCompare}.
-     */
-    private static final int VECTOR_SIZE = 4;
-
-    /**
-     * Emits code that uses 4-byte vector compares.
-     */
-    private void emit4ByteCompare(CompilationResultBuilder crb, AMD64MacroAssembler masm, Register result, Register array1, Register array2, Register length, Label falseLabel, Label trueLabel) {
-        Label compareVectors = new Label();
-        Label compareChar = new Label();
-        Label done = new Label();
-        Register temp = asRegister(temp4);
-
-        masm.andl(length, 0xfffffffc); // vector count (in bytes)
-        masm.jccb(ConditionFlag.Zero, compareChar);
-
-        masm.leaq(array1, new AMD64Address(array1, length, Scale.Times1, 0));
-        masm.leaq(array2, new AMD64Address(array2, length, Scale.Times1, 0));
-        masm.negq(length);
-
-        // Align the main loop
-        masm.align(crb.target.wordSize * 2);
-        masm.bind(compareVectors);
-        masm.movl(temp, new AMD64Address(array1, length, Scale.Times1, 0));
-        masm.cmpl(temp, new AMD64Address(array2, length, Scale.Times1, 0));
-        masm.jccb(ConditionFlag.NotEqual, falseLabel);
-        masm.addq(length, VECTOR_SIZE);
-        masm.jcc(ConditionFlag.NotZero, compareVectors);
-
-        // Compare trailing char (final 2 bytes), if any
-        masm.bind(compareChar);
-        masm.testl(result, 0x2); // tail char
-        masm.jccb(ConditionFlag.Zero, trueLabel);
-        masm.movzwl(temp, new AMD64Address(array1, 0));
-        masm.movzwl(length, new AMD64Address(array2, 0));
-        masm.cmpl(temp, length);
-        masm.jccb(ConditionFlag.NotEqual, falseLabel);
-
-        masm.bind(trueLabel);
-        masm.movl(result, 1); // return true
-        masm.jmpb(done);
-
-        masm.bind(falseLabel);
-        masm.xorl(result, result); // return false
-
-        // That's it
-        masm.bind(done);
-    }
-
-    /**
-     * Vector size used in {@link #emitSSE41Compare}.
-     */
-    private static final int SSE4_1_VECTOR_SIZE = 16;
-
-    /**
-     * Emits code that uses SSE4.1 128-bit (16-byte) vector compares.
-     */
-    private void emitSSE41Compare(CompilationResultBuilder crb, AMD64MacroAssembler masm, Register result, Register array1, Register array2, Register length, Label falseLabel, Label trueLabel) {
-        assert supportsSSE41(crb.target);
-
-        Register vector1 = asDoubleReg(vectorTemp1);
-        Register vector2 = asDoubleReg(vectorTemp2);
-
-        Label compareWideVectors = new Label();
-        Label compareTail = new Label();
-
-        // Compare 16-byte vectors
-        masm.andl(result, 0x0000000e); // tail count (in bytes)
-        masm.andl(length, 0xfffffff0); // vector count (in bytes)
-        masm.jccb(ConditionFlag.Zero, compareTail);
-
-        masm.leaq(array1, new AMD64Address(array1, length, Scale.Times1, 0));
-        masm.leaq(array2, new AMD64Address(array2, length, Scale.Times1, 0));
-        masm.negq(length);
-
-        // Align the main loop
-        masm.align(crb.target.wordSize * 2);
-        masm.bind(compareWideVectors);
-        masm.movdqu(vector1, new AMD64Address(array1, length, Scale.Times1, 0));
-        masm.movdqu(vector2, new AMD64Address(array2, length, Scale.Times1, 0));
-        masm.pxor(vector1, vector2);
-
-        masm.ptest(vector1, vector1);
-        masm.jccb(ConditionFlag.NotZero, falseLabel);
-        masm.addq(length, SSE4_1_VECTOR_SIZE);
-        masm.jcc(ConditionFlag.NotZero, compareWideVectors);
-
-        masm.testl(result, result);
-        masm.jccb(ConditionFlag.Zero, trueLabel);
-
-        masm.movdqu(vector1, new AMD64Address(array1, result, Scale.Times1, -SSE4_1_VECTOR_SIZE));
-        masm.movdqu(vector2, new AMD64Address(array2, result, Scale.Times1, -SSE4_1_VECTOR_SIZE));
-        masm.pxor(vector1, vector2);
-
-        masm.ptest(vector1, vector1);
-        masm.jccb(ConditionFlag.NotZero, falseLabel);
-        masm.jmpb(trueLabel);
-
-        masm.bind(compareTail); // length is zero
-        masm.movl(length, result);
-    }
-}
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Compare.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Compare.java	Wed Mar 05 19:40:15 2014 -0800
@@ -73,12 +73,23 @@
                 default:   throw GraalInternalError.shouldNotReachHere();
             }
         } else if (isConstant(y)) {
+            boolean isZero = ((Constant) y).isDefaultForKind();
             switch (opcode) {
-                case ICMP: masm.cmpl(asIntReg(x), crb.asIntConst(y)); break;
-                case LCMP: masm.cmpq(asLongReg(x), crb.asIntConst(y)); break;
+                case ICMP: if (isZero) {
+                    masm.testl(asIntReg(x), asIntReg(x));
+                } else {
+                    masm.cmpl(asIntReg(x), crb.asIntConst(y));
+                }
+                break;
+                case LCMP: if (isZero) {
+                    masm.testq(asLongReg(x), asLongReg(x));
+                } else {
+                    masm.cmpq(asLongReg(x), crb.asIntConst(y));
+                }
+                break;
                 case ACMP:
-                    if (((Constant) y).isNull()) {
-                        masm.cmpq(asObjectReg(x), 0); break;
+                    if (isZero) {
+                        masm.testq(asObjectReg(x), asObjectReg(x)); break;
                     } else {
                         throw GraalInternalError.shouldNotReachHere("Only null object constants are allowed in comparisons");
                     }
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64ControlFlow.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64ControlFlow.java	Wed Mar 05 19:40:15 2014 -0800
@@ -61,25 +61,39 @@
         protected final LabelRef trueDestination;
         protected final LabelRef falseDestination;
 
-        public BranchOp(Condition condition, LabelRef trueDestination, LabelRef falseDestination) {
-            this(intCond(condition), trueDestination, falseDestination);
+        private final double trueDestinationProbability;
+
+        public BranchOp(Condition condition, LabelRef trueDestination, LabelRef falseDestination, double trueDestinationProbability) {
+            this(intCond(condition), trueDestination, falseDestination, trueDestinationProbability);
         }
 
-        public BranchOp(ConditionFlag condition, LabelRef trueDestination, LabelRef falseDestination) {
+        public BranchOp(ConditionFlag condition, LabelRef trueDestination, LabelRef falseDestination, double trueDestinationProbability) {
             this.condition = condition;
             this.trueDestination = trueDestination;
             this.falseDestination = falseDestination;
+            this.trueDestinationProbability = trueDestinationProbability;
         }
 
         @Override
         public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
+            /*
+             * The strategy for emitting jumps is: If either trueDestination or falseDestination is
+             * the successor block, assume the block scheduler did the correct thing and jcc to the
+             * other. Otherwise, we need a jcc followed by a jmp. Use the branch probability to make
+             * sure it is more likely to branch on the jcc (= less likely to execute both the jcc
+             * and the jmp instead of just the jcc). In the case of loops, that means the jcc is the
+             * back-edge.
+             */
             if (crb.isSuccessorEdge(trueDestination)) {
                 jcc(masm, true, falseDestination);
+            } else if (crb.isSuccessorEdge(falseDestination)) {
+                jcc(masm, false, trueDestination);
+            } else if (trueDestinationProbability < 0.5) {
+                jcc(masm, true, falseDestination);
+                masm.jmp(trueDestination.label());
             } else {
                 jcc(masm, false, trueDestination);
-                if (!crb.isSuccessorEdge(falseDestination)) {
-                    masm.jmp(falseDestination.label());
-                }
+                masm.jmp(falseDestination.label());
             }
         }
 
@@ -91,8 +105,8 @@
     public static class FloatBranchOp extends BranchOp {
         protected boolean unorderedIsTrue;
 
-        public FloatBranchOp(Condition condition, boolean unorderedIsTrue, LabelRef trueDestination, LabelRef falseDestination) {
-            super(floatCond(condition), trueDestination, falseDestination);
+        public FloatBranchOp(Condition condition, boolean unorderedIsTrue, LabelRef trueDestination, LabelRef falseDestination, double trueDestinationProbability) {
+            super(floatCond(condition), trueDestination, falseDestination, trueDestinationProbability);
             this.unorderedIsTrue = unorderedIsTrue;
         }
 
@@ -184,7 +198,6 @@
                 masm.movl(idxScratchReg, indexReg);
             }
 
-            Buffer buf = masm.codeBuffer;
             // Compare index against jump table bounds
             int highKey = lowKey + targets.length - 1;
             if (lowKey != 0) {
@@ -201,9 +214,8 @@
             }
 
             // Set scratch to address of jump table
-            int leaPos = buf.position();
             masm.leaq(scratchReg, new AMD64Address(AMD64.rip, 0));
-            int afterLea = buf.position();
+            final int afterLea = masm.position();
 
             // Load jump table entry into scratch and jump to it
             masm.movslq(idxScratchReg, new AMD64Address(scratchReg, idxScratchReg, Scale.Times4, 0));
@@ -211,29 +223,29 @@
             masm.jmp(scratchReg);
 
             // Inserting padding so that jump table address is 4-byte aligned
-            if ((buf.position() & 0x3) != 0) {
-                masm.nop(4 - (buf.position() & 0x3));
+            if ((masm.position() & 0x3) != 0) {
+                masm.nop(4 - (masm.position() & 0x3));
             }
 
             // Patch LEA instruction above now that we know the position of the jump table
-            int jumpTablePos = buf.position();
-            buf.setPosition(leaPos);
-            masm.leaq(scratchReg, new AMD64Address(AMD64.rip, jumpTablePos - afterLea));
-            buf.setPosition(jumpTablePos);
+            // TODO this is ugly and should be done differently
+            final int jumpTablePos = masm.position();
+            final int leaDisplacementPosition = afterLea - 4;
+            masm.emitInt(jumpTablePos - afterLea, leaDisplacementPosition);
 
             // Emit jump table entries
             for (LabelRef target : targets) {
                 Label label = target.label();
-                int offsetToJumpTableBase = buf.position() - jumpTablePos;
+                int offsetToJumpTableBase = masm.position() - jumpTablePos;
                 if (label.isBound()) {
                     int imm32 = label.position() - jumpTablePos;
-                    buf.emitInt(imm32);
+                    masm.emitInt(imm32);
                 } else {
-                    label.addPatchAt(buf.position());
+                    label.addPatchAt(masm.position());
 
-                    buf.emitByte(0); // pseudo-opcode for jump table entry
-                    buf.emitShort(offsetToJumpTableBase);
-                    buf.emitByte(0); // padding to make jump table entry 4 bytes wide
+                    masm.emitByte(0); // pseudo-opcode for jump table entry
+                    masm.emitShort(offsetToJumpTableBase);
+                    masm.emitByte(0); // padding to make jump table entry 4 bytes wide
                 }
             }
 
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64FrameMap.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64FrameMap.java	Wed Mar 05 19:40:15 2014 -0800
@@ -101,4 +101,9 @@
     protected StackSlot allocateNewSpillSlot(PlatformKind kind, int additionalOffset) {
         return StackSlot.get(kind, -spillSize + additionalOffset, true);
     }
+
+    @Override
+    public LIRInstruction createSpillMove(AllocatableValue result, Value input) {
+        return AMD64Move.createMove(result, input);
+    }
 }
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Move.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Move.java	Wed Mar 05 19:40:15 2014 -0800
@@ -41,6 +41,16 @@
 
 public class AMD64Move {
 
+    public static AMD64LIRInstruction createMove(AllocatableValue dst, Value src) {
+        if (src instanceof AMD64AddressValue) {
+            return new LeaOp(dst, (AMD64AddressValue) src);
+        } else if (isRegister(src) || isStackSlot(dst)) {
+            return new MoveFromRegOp(dst, src);
+        } else {
+            return new MoveToRegOp(dst, src);
+        }
+    }
+
     @Opcode("MOVE")
     public static class MoveToRegOp extends AMD64LIRInstruction implements MoveOp {
 
@@ -112,7 +122,7 @@
         @Override
         public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
             if (state != null) {
-                crb.recordImplicitException(masm.codeBuffer.position(), state);
+                crb.recordImplicitException(masm.position(), state);
             }
             emitMemAccess(crb, masm);
         }
@@ -139,6 +149,8 @@
         public void emitMemAccess(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
             switch (kind) {
                 case Boolean:
+                    masm.movzbl(asRegister(result), address.toAddress());
+                    break;
                 case Byte:
                     masm.movsbl(asRegister(result), address.toAddress());
                     break;
@@ -317,7 +329,7 @@
 
         @Override
         public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
-            crb.recordImplicitException(masm.codeBuffer.position(), state);
+            crb.recordImplicitException(masm.position(), state);
             masm.nullCheck(asRegister(input));
         }
 
--- a/graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILArithmetic.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILArithmetic.java	Wed Mar 05 19:40:15 2014 -0800
@@ -105,12 +105,12 @@
     UNDEF;
 
     public static class ConvertOp extends HSAILLIRInstruction {
-        private final Kind from;
-        private final Kind to;
+        private final String from;
+        private final String to;
         @Def({REG}) protected AllocatableValue result;
         @Use({REG, STACK}) protected AllocatableValue x;
 
-        public ConvertOp(AllocatableValue result, AllocatableValue x, Kind to, Kind from) {
+        public ConvertOp(AllocatableValue result, AllocatableValue x, String to, String from) {
             this.from = from;
             this.to = to;
             this.result = result;
--- a/graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILFrameMap.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILFrameMap.java	Wed Mar 05 19:40:15 2014 -0800
@@ -22,9 +22,12 @@
  */
 package com.oracle.graal.lir.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.lir.*;
+import com.oracle.graal.lir.hsail.HSAILMove.*;
 
 /**
  * HSAIL specific frame map.
@@ -69,4 +72,15 @@
     protected StackSlot allocateNewSpillSlot(PlatformKind kind, int additionalOffset) {
         return StackSlot.get(kind, -spillSize + additionalOffset, true);
     }
+
+    @Override
+    public LIRInstruction createSpillMove(AllocatableValue dst, Value src) {
+        if (src instanceof HSAILAddressValue) {
+            return new LeaOp(dst, (HSAILAddressValue) src);
+        } else if (isRegister(src) || isStackSlot(dst)) {
+            return new MoveFromRegOp(dst, src);
+        } else {
+            return new MoveToRegOp(dst, src);
+        }
+    }
 }
--- a/graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILMove.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILMove.java	Wed Mar 05 19:40:15 2014 -0800
@@ -146,7 +146,7 @@
         @Override
         public void emitCode(CompilationResultBuilder crb, HSAILAssembler masm) {
             if (state != null) {
-                // crb.recordImplicitException(masm.codeBuffer.position(), state);
+                // crb.recordImplicitException(masm.position(), state);
                 throw new InternalError("NYI");
             }
             emitMemAccess(masm);
@@ -200,6 +200,56 @@
         }
     }
 
+    public static class StoreConstantOp extends MemOp {
+
+        protected final Constant input;
+
+        public StoreConstantOp(Kind kind, HSAILAddressValue address, Constant input, LIRFrameState state) {
+            super(kind, address, state);
+            this.input = input;
+        }
+
+        @Override
+        public void emitMemAccess(HSAILAssembler masm) {
+            switch (kind) {
+                case Boolean:
+                case Byte:
+                    masm.emitStoreImmediate(kind, input.asLong() & 0xFF, address.toAddress());
+                    break;
+                case Char:
+                case Short:
+                    masm.emitStoreImmediate(kind, input.asLong() & 0xFFFF, address.toAddress());
+                    break;
+                case Int:
+                case Long:
+                    masm.emitStoreImmediate(kind, input.asLong(), address.toAddress());
+                    break;
+                case Float:
+                    masm.emitStoreImmediate(input.asFloat(), address.toAddress());
+                    break;
+                case Double:
+                    masm.emitStoreImmediate(input.asDouble(), address.toAddress());
+                    break;
+                case Object:
+                    if (input.isNull()) {
+                        masm.emitStoreImmediate(kind, 0L, address.toAddress());
+                    } else {
+                        throw GraalInternalError.shouldNotReachHere("Cannot store 64-bit constants to object ref");
+                    }
+                    break;
+                case NarrowOop:
+                    if (input.isNull()) {
+                        masm.emitStoreImmediate(kind, 0L, address.toAddress());
+                    } else {
+                        throw GraalInternalError.shouldNotReachHere("Cannot store 64-bit constants to object ref");
+                    }
+                    break;
+                default:
+                    throw GraalInternalError.shouldNotReachHere();
+            }
+        }
+    }
+
     public static class LoadCompressedPointer extends LoadOp {
 
         private final long base;
@@ -255,7 +305,7 @@
             encodePointer(masm, scratch, base, shift, alignment, testForNull);
             if (state != null) {
                 throw new InternalError("NYI");
-                // crb.recordImplicitException(masm.codeBuffer.position(), state);
+                // crb.recordImplicitException(masm.position(), state);
             }
             masm.emitStore(scratch, address.toAddress(), "u32");
         }
--- a/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXControlFlow.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXControlFlow.java	Wed Mar 05 19:40:15 2014 -0800
@@ -86,9 +86,9 @@
         @Override
         public void emitCode(CompilationResultBuilder crb, PTXMacroAssembler masm) {
             if (crb.isSuccessorEdge(trueDestination)) {
-                masm.bra(masm.nameOf(falseDestination.label()), predRegNum);
+                masm.bra(masm.nameOf(falseDestination.label()), predRegNum, false);
             } else {
-                masm.bra(masm.nameOf(trueDestination.label()));
+                masm.bra(masm.nameOf(trueDestination.label()), predRegNum, true);
                 if (!crb.isSuccessorEdge(falseDestination)) {
                     masm.jmp(falseDestination.label());
                 }
@@ -238,7 +238,7 @@
                         default:
                             throw new GraalInternalError("switch only supported for int, long and object");
                     }
-                    masm.bra(masm.nameOf(target), predRegNum);
+                    masm.bra(masm.nameOf(target), predRegNum, true);
                 }
             };
             strategy.run(closure);
@@ -266,8 +266,6 @@
 
         @Override
         public void emitCode(CompilationResultBuilder crb, PTXMacroAssembler masm) {
-            Buffer buf = masm.codeBuffer;
-
             // Compare index against jump table bounds
 
             int highKey = lowKey + targets.length - 1;
@@ -281,11 +279,11 @@
 
             // Jump to default target if index is not within the jump table
             if (defaultTarget != null) {
-                masm.bra(masm.nameOf(defaultTarget.label()), predRegNum);
+                masm.bra(masm.nameOf(defaultTarget.label()), predRegNum, true);
             }
 
             // address of jump table
-            int tablePos = buf.position();
+            int tablePos = masm.position();
 
             JumpTable jt = new JumpTable(tablePos, lowKey, highKey, 4);
             String name = "jumptable" + jt.position;
--- a/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXFrameMap.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXFrameMap.java	Wed Mar 05 19:40:15 2014 -0800
@@ -24,6 +24,7 @@
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
 import com.oracle.graal.lir.*;
 
 /**
@@ -69,4 +70,10 @@
     protected StackSlot allocateNewSpillSlot(PlatformKind kind, int additionalOffset) {
         return StackSlot.get(kind, -spillSize + additionalOffset, true);
     }
+
+    @Override
+    public LIRInstruction createSpillMove(AllocatableValue result, Value input) {
+        throw GraalInternalError.shouldNotReachHere("Spill moves should never be necessary for PTX code");
+    }
+
 }
--- a/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXMemOp.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXMemOp.java	Wed Mar 05 19:40:15 2014 -0800
@@ -54,6 +54,7 @@
         public void emitCode(CompilationResultBuilder crb, PTXMacroAssembler masm) {
             PTXAddress addr = address.toAddress();
             switch (kind) {
+                case Boolean:
                 case Byte:
                 case Short:
                 case Char:
--- a/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXMove.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXMove.java	Wed Mar 05 19:40:15 2014 -0800
@@ -252,7 +252,7 @@
 
         @Override
         public void emitCode(CompilationResultBuilder crb, PTXMacroAssembler masm) {
-            crb.recordImplicitException(masm.codeBuffer.position(), state);
+            crb.recordImplicitException(masm.position(), state);
             masm.nullCheck(asRegister(input));
         }
 
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArithmetic.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArithmetic.java	Wed Mar 05 19:40:15 2014 -0800
@@ -490,6 +490,13 @@
             }
         } else if (isConstant(src2)) {
             switch (opcode) {
+                case IREM:
+                    assert isSimm13(crb.asIntConst(src2));
+                    new Sra(asIntReg(src1), 0, asIntReg(src1)).emit(masm);
+                    new Sdivx(asIntReg(src1), crb.asIntConst(src2), asIntReg(scratch1)).emit(masm);
+                    new Mulx(asIntReg(scratch1), crb.asIntConst(src2), asIntReg(scratch2)).emit(masm);
+                    new Sub(asIntReg(src1), asIntReg(scratch2), asIntReg(dst)).emit(masm);
+                    break;
                 case LREM:
                     assert isSimm13(crb.asIntConst(src2));
                     new Sdivx(asLongReg(src1), crb.asIntConst(src2), asLongReg(scratch1)).emit(masm);
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCCall.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCCall.java	Wed Mar 05 19:40:15 2014 -0800
@@ -147,7 +147,7 @@
         if (align) {
             // We don't need alignment on SPARC.
         }
-        int before = masm.codeBuffer.position();
+        int before = masm.position();
         if (scratch != null) {
             // offset might not fit a 30-bit displacement, generate an
             // indirect call with a 64-bit immediate
@@ -156,7 +156,7 @@
         } else {
             new Call(0).emit(masm);
         }
-        int after = masm.codeBuffer.position();
+        int after = masm.position();
         crb.recordDirectCall(before, after, callTarget, info);
         crb.recordExceptionHandlers(after, info);
         new Nop().emit(masm);  // delay slot
@@ -164,19 +164,19 @@
     }
 
     public static void indirectJmp(CompilationResultBuilder crb, SPARCMacroAssembler masm, Register dst, InvokeTarget target) {
-        int before = masm.codeBuffer.position();
+        int before = masm.position();
         new Sethix(0L, dst, true).emit(masm);
         new Jmp(new SPARCAddress(dst, 0)).emit(masm);
-        int after = masm.codeBuffer.position();
+        int after = masm.position();
         crb.recordIndirectCall(before, after, target, null);
         new Nop().emit(masm);  // delay slot
         masm.ensureUniquePC();
     }
 
     public static void indirectCall(CompilationResultBuilder crb, SPARCMacroAssembler masm, Register dst, InvokeTarget callTarget, LIRFrameState info) {
-        int before = masm.codeBuffer.position();
+        int before = masm.position();
         new Jmpl(dst, 0, o7).emit(masm);
-        int after = masm.codeBuffer.position();
+        int after = masm.position();
         crb.recordIndirectCall(before, after, callTarget, info);
         crb.recordExceptionHandlers(after, info);
         new Nop().emit(masm);  // delay slot
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java	Wed Mar 05 19:40:15 2014 -0800
@@ -57,6 +57,26 @@
 
 public class SPARCControlFlow {
 
+    public static class ReturnOp extends SPARCLIRInstruction implements BlockEndOp {
+
+        @Use({REG, ILLEGAL}) protected Value x;
+
+        public ReturnOp(Value x) {
+            this.x = x;
+        }
+
+        @Override
+        public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
+            emitCodeHelper(crb, masm);
+        }
+
+        public static void emitCodeHelper(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
+            new Ret().emit(masm);
+            // On SPARC we always leave the frame (in the delay slot).
+            crb.frameContext.leave(crb);
+        }
+    }
+
     public static class BranchOp extends SPARCLIRInstruction implements StandardOp.BranchOp {
 
         protected final Condition condition;
@@ -132,6 +152,121 @@
         }
     }
 
+    public static class StrategySwitchOp extends SPARCLIRInstruction implements BlockEndOp {
+        @Use({CONST}) protected Constant[] keyConstants;
+        private final LabelRef[] keyTargets;
+        private LabelRef defaultTarget;
+        @Alive({REG}) protected Value key;
+        @Temp({REG, ILLEGAL}) protected Value scratch;
+        private final SwitchStrategy strategy;
+
+        public StrategySwitchOp(SwitchStrategy strategy, LabelRef[] keyTargets, LabelRef defaultTarget, Value key, Value scratch) {
+            this.strategy = strategy;
+            this.keyConstants = strategy.keyConstants;
+            this.keyTargets = keyTargets;
+            this.defaultTarget = defaultTarget;
+            this.key = key;
+            this.scratch = scratch;
+            assert keyConstants.length == keyTargets.length;
+            assert keyConstants.length == strategy.keyProbabilities.length;
+            assert (scratch.getKind() == Kind.Illegal) == (key.getKind() == Kind.Int);
+        }
+
+        @Override
+        public void emitCode(final CompilationResultBuilder crb, final SPARCMacroAssembler masm) {
+            final Register keyRegister = asRegister(key);
+
+            BaseSwitchClosure closure = new BaseSwitchClosure(crb, masm, keyTargets, defaultTarget) {
+                @Override
+                protected void conditionalJump(int index, Condition condition, Label target) {
+                    switch (key.getKind()) {
+                        case Int:
+                            if (crb.codeCache.needsDataPatch(keyConstants[index])) {
+                                crb.recordInlineDataInCode(keyConstants[index]);
+                            }
+                            long lc = keyConstants[index].asLong();
+                            assert NumUtil.isInt(lc);
+                            new Cmp(keyRegister, (int) lc).emit(masm);
+                            emitCompare(masm, target, condition, CC.Icc);
+                            break;
+                        case Long: {
+                            Register temp = asLongReg(scratch);
+                            SPARCMove.move(crb, masm, temp.asValue(Kind.Long), keyConstants[index]);
+                            new Cmp(keyRegister, temp).emit(masm);
+                            emitCompare(masm, target, condition, CC.Xcc);
+                            break;
+                        }
+                        case Object: {
+                            Register temp = asObjectReg(scratch);
+                            SPARCMove.move(crb, masm, temp.asValue(Kind.Object), keyConstants[index]);
+                            new Cmp(keyRegister, temp).emit(masm);
+                            emitCompare(masm, target, condition, CC.Ptrcc);
+                            break;
+                        }
+                        default:
+                            throw new GraalInternalError("switch only supported for int, long and object");
+                    }
+                    new Nop().emit(masm);  // delay slot
+                }
+            };
+            strategy.run(closure);
+        }
+    }
+
+    public static class TableSwitchOp extends SPARCLIRInstruction implements BlockEndOp {
+
+        private final int lowKey;
+        private final LabelRef defaultTarget;
+        private final LabelRef[] targets;
+        @Alive protected Value index;
+        @Temp protected Value scratch;
+
+        public TableSwitchOp(final int lowKey, final LabelRef defaultTarget, final LabelRef[] targets, Variable index, Variable scratch) {
+            this.lowKey = lowKey;
+            this.defaultTarget = defaultTarget;
+            this.targets = targets;
+            this.index = index;
+            this.scratch = scratch;
+        }
+
+        @Override
+        public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
+            Register value = asIntReg(index);
+            Register scratchReg = asLongReg(scratch);
+
+            // Compare index against jump table bounds
+            int highKey = lowKey + targets.length - 1;
+            if (lowKey != 0) {
+                // subtract the low value from the switch value
+                new Sub(value, lowKey, value).emit(masm);
+                // masm.setp_gt_s32(value, highKey - lowKey);
+            } else {
+                // masm.setp_gt_s32(value, highKey);
+            }
+
+            // Jump to default target if index is not within the jump table
+            if (defaultTarget != null) {
+                new Bpgu(CC.Icc, defaultTarget.label()).emit(masm);
+                new Nop().emit(masm);  // delay slot
+            }
+
+            // Load jump table entry into scratch and jump to it
+            // masm.movslq(value, new AMD64Address(scratch, value, Scale.Times4, 0));
+            // masm.addq(scratch, value);
+            new Jmp(new SPARCAddress(scratchReg, 0)).emit(masm);
+            new Nop().emit(masm);  // delay slot
+
+            // address of jump table
+            int tablePos = masm.position();
+
+            JumpTable jt = new JumpTable(tablePos, lowKey, highKey, 4);
+            crb.compilationResult.addAnnotation(jt);
+
+            // SPARC: unimp: tableswitch extract
+            throw GraalInternalError.unimplemented();
+        }
+    }
+
     @Opcode("CMOVE")
     public static class CondMoveOp extends SPARCLIRInstruction {
 
@@ -262,140 +397,4 @@
                 throw GraalInternalError.shouldNotReachHere();
         }
     }
-
-    public static class ReturnOp extends SPARCLIRInstruction {
-
-        @Use({REG, ILLEGAL}) protected Value x;
-
-        public ReturnOp(Value x) {
-            this.x = x;
-        }
-
-        @Override
-        public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
-            emitCodeHelper(crb, masm);
-        }
-
-        public static void emitCodeHelper(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
-            new Ret().emit(masm);
-            // On SPARC we always leave the frame (in the delay slot).
-            crb.frameContext.leave(crb);
-        }
-    }
-
-    public static class StrategySwitchOp extends SPARCLIRInstruction implements BlockEndOp {
-        @Use({CONST}) protected Constant[] keyConstants;
-        private final LabelRef[] keyTargets;
-        private LabelRef defaultTarget;
-        @Alive({REG}) protected Value key;
-        @Temp({REG, ILLEGAL}) protected Value scratch;
-        private final SwitchStrategy strategy;
-
-        public StrategySwitchOp(SwitchStrategy strategy, LabelRef[] keyTargets, LabelRef defaultTarget, Value key, Value scratch) {
-            this.strategy = strategy;
-            this.keyConstants = strategy.keyConstants;
-            this.keyTargets = keyTargets;
-            this.defaultTarget = defaultTarget;
-            this.key = key;
-            this.scratch = scratch;
-            assert keyConstants.length == keyTargets.length;
-            assert keyConstants.length == strategy.keyProbabilities.length;
-            assert (scratch.getKind() == Kind.Illegal) == (key.getKind() == Kind.Int);
-        }
-
-        @Override
-        public void emitCode(final CompilationResultBuilder crb, final SPARCMacroAssembler masm) {
-            final Register keyRegister = asRegister(key);
-
-            BaseSwitchClosure closure = new BaseSwitchClosure(crb, masm, keyTargets, defaultTarget) {
-                @Override
-                protected void conditionalJump(int index, Condition condition, Label target) {
-                    switch (key.getKind()) {
-                        case Int:
-                            if (crb.codeCache.needsDataPatch(keyConstants[index])) {
-                                crb.recordInlineDataInCode(keyConstants[index]);
-                            }
-                            long lc = keyConstants[index].asLong();
-                            assert NumUtil.isInt(lc);
-                            new Cmp(keyRegister, (int) lc).emit(masm);
-                            emitCompare(masm, target, condition, CC.Icc);
-                            break;
-                        case Long: {
-                            Register temp = asLongReg(scratch);
-                            SPARCMove.move(crb, masm, temp.asValue(Kind.Long), keyConstants[index]);
-                            new Cmp(keyRegister, temp).emit(masm);
-                            emitCompare(masm, target, condition, CC.Xcc);
-                            break;
-                        }
-                        case Object: {
-                            Register temp = asObjectReg(scratch);
-                            SPARCMove.move(crb, masm, temp.asValue(Kind.Object), keyConstants[index]);
-                            new Cmp(keyRegister, temp).emit(masm);
-                            emitCompare(masm, target, condition, CC.Ptrcc);
-                            break;
-                        }
-                        default:
-                            throw new GraalInternalError("switch only supported for int, long and object");
-                    }
-                    new Nop().emit(masm);  // delay slot
-                }
-            };
-            strategy.run(closure);
-        }
-    }
-
-    public static class TableSwitchOp extends SPARCLIRInstruction implements BlockEndOp {
-
-        private final int lowKey;
-        private final LabelRef defaultTarget;
-        private final LabelRef[] targets;
-        @Alive protected Value index;
-        @Temp protected Value scratch;
-
-        public TableSwitchOp(final int lowKey, final LabelRef defaultTarget, final LabelRef[] targets, Variable index, Variable scratch) {
-            this.lowKey = lowKey;
-            this.defaultTarget = defaultTarget;
-            this.targets = targets;
-            this.index = index;
-            this.scratch = scratch;
-        }
-
-        @Override
-        public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
-            Register value = asIntReg(index);
-            Register scratchReg = asLongReg(scratch);
-
-            Buffer buf = masm.codeBuffer;
-            // Compare index against jump table bounds
-            int highKey = lowKey + targets.length - 1;
-            if (lowKey != 0) {
-                // subtract the low value from the switch value
-                new Sub(value, lowKey, value).emit(masm);
-                // masm.setp_gt_s32(value, highKey - lowKey);
-            } else {
-                // masm.setp_gt_s32(value, highKey);
-            }
-
-            // Jump to default target if index is not within the jump table
-            if (defaultTarget != null) {
-                new Bpgu(CC.Icc, defaultTarget.label()).emit(masm);
-                new Nop().emit(masm);  // delay slot
-            }
-
-            // Load jump table entry into scratch and jump to it
-            // masm.movslq(value, new AMD64Address(scratch, value, Scale.Times4, 0));
-            // masm.addq(scratch, value);
-            new Jmp(new SPARCAddress(scratchReg, 0)).emit(masm);
-            new Nop().emit(masm);  // delay slot
-
-            // address of jump table
-            int tablePos = buf.position();
-
-            JumpTable jt = new JumpTable(tablePos, lowKey, highKey, 4);
-            crb.compilationResult.addAnnotation(jt);
-
-            // SPARC: unimp: tableswitch extract
-            throw GraalInternalError.unimplemented();
-        }
-    }
 }
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCFrameMap.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCFrameMap.java	Wed Mar 05 19:40:15 2014 -0800
@@ -101,4 +101,9 @@
     protected StackSlot allocateNewSpillSlot(PlatformKind kind, int additionalOffset) {
         return StackSlot.get(kind, -spillSize + additionalOffset, true);
     }
+
+    @Override
+    public LIRInstruction createSpillMove(AllocatableValue result, Value input) {
+        return SPARCMove.createMove(result, input);
+    }
 }
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java	Wed Mar 05 19:40:15 2014 -0800
@@ -39,6 +39,16 @@
 
 public class SPARCMove {
 
+    public static SPARCLIRInstruction createMove(AllocatableValue dst, Value src) {
+        if (src instanceof SPARCAddressValue) {
+            return new LoadAddressOp(dst, (SPARCAddressValue) src);
+        } else if (isRegister(src) || isStackSlot(dst)) {
+            return new MoveFromRegOp(dst, src);
+        } else {
+            return new MoveToRegOp(dst, src);
+        }
+    }
+
     @Opcode("MOVE")
     public static class MoveToRegOp extends SPARCLIRInstruction implements MoveOp {
 
@@ -110,7 +120,7 @@
         @Override
         public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
             if (state != null) {
-                crb.recordImplicitException(masm.codeBuffer.position(), state);
+                crb.recordImplicitException(masm.position(), state);
             }
             emitMemAccess(masm);
         }
@@ -215,7 +225,7 @@
 
         @Override
         public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
-            crb.recordImplicitException(masm.codeBuffer.position(), state);
+            crb.recordImplicitException(masm.position(), state);
             new Ldx(new SPARCAddress(asRegister(input), 0), r0).emit(masm);
         }
 
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/ControlFlowOptimizer.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/ControlFlowOptimizer.java	Wed Mar 05 19:40:15 2014 -0800
@@ -45,6 +45,8 @@
     private ControlFlowOptimizer() {
     }
 
+    private static final DebugMetric BLOCKS_DELETED = Debug.metric("BlocksDeleted");
+
     /**
      * Checks whether a block can be deleted. Only blocks with exactly one successor and an
      * unconditional branch to this successor are eligable.
@@ -68,6 +70,16 @@
         return instructions.size() == 2 && !instructions.get(instructions.size() - 1).hasState() && !block.isExceptionEntry();
     }
 
+    private static void alignBlock(LIR lir, Block block) {
+        if (!block.isAligned()) {
+            block.setAlign(true);
+            List<LIRInstruction> instructions = lir.lir(block);
+            assert instructions.get(0) instanceof StandardOp.LabelOp : "first instruction must always be a label";
+            StandardOp.LabelOp label = (StandardOp.LabelOp) instructions.get(0);
+            instructions.set(0, new StandardOp.LabelOp(label.getLabel(), true));
+        }
+    }
+
     private static void deleteEmptyBlocks(LIR lir, List<Block> blocks) {
         assert verifyBlocks(lir, blocks);
         Iterator<Block> iterator = blocks.iterator();
@@ -87,7 +99,12 @@
                 }
                 block.getSuccessors().clear();
                 block.getPredecessors().clear();
-                Debug.metric("BlocksDeleted").increment();
+
+                if (block.isAligned()) {
+                    alignBlock(lir, other);
+                }
+
+                BLOCKS_DELETED.increment();
                 iterator.remove();
             }
         }
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/FrameMap.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/FrameMap.java	Wed Mar 05 19:40:15 2014 -0800
@@ -122,6 +122,10 @@
         return frameSize;
     }
 
+    public int outgoingSize() {
+        return outgoingSize;
+    }
+
     /**
      * Determines if any space is used in the frame apart from the
      * {@link Architecture#getReturnAddressSize() return address slot}.
@@ -316,7 +320,7 @@
         spillSize += (slots * target.wordSize);
 
         if (!objects.isEmpty()) {
-            assert objects.length() < slots;
+            assert objects.length() <= slots;
             StackSlot result = null;
             for (int slotIndex = 0; slotIndex < slots; slotIndex++) {
                 StackSlot objectSlot = null;
@@ -378,4 +382,6 @@
             }
         }
     }
+
+    public abstract LIRInstruction createSpillMove(AllocatableValue result, Value input);
 }
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/InfopointOp.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/InfopointOp.java	Wed Mar 05 19:40:15 2014 -0800
@@ -42,6 +42,6 @@
 
     @Override
     public void emitCode(CompilationResultBuilder crb) {
-        crb.recordInfopoint(crb.asm.codeBuffer.position(), state, reason);
+        crb.recordInfopoint(crb.asm.position(), state, reason);
     }
 }
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIR.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIR.java	Wed Mar 05 19:40:15 2014 -0800
@@ -24,7 +24,6 @@
 
 import java.util.*;
 
-import com.oracle.graal.api.meta.*;
 import com.oracle.graal.lir.LIRInstruction.StateProcedure;
 import com.oracle.graal.lir.StandardOp.BlockEndOp;
 import com.oracle.graal.nodes.*;
@@ -58,15 +57,8 @@
 
     private int numVariables;
 
-    public SpillMoveFactory spillMoveFactory;
-
     public final BlockMap<List<LIRInstruction>> lirInstructions;
 
-    public interface SpillMoveFactory {
-
-        LIRInstruction createMove(AllocatableValue result, Value input);
-    }
-
     private boolean hasArgInCallerFrame;
 
     /**
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/SwitchStrategy.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/SwitchStrategy.java	Wed Mar 05 19:40:15 2014 -0800
@@ -89,11 +89,11 @@
     public abstract static class BaseSwitchClosure implements SwitchClosure {
 
         private final CompilationResultBuilder crb;
-        private final AbstractAssembler masm;
+        private final Assembler masm;
         private final LabelRef[] keyTargets;
         private final LabelRef defaultTarget;
 
-        public BaseSwitchClosure(CompilationResultBuilder crb, AbstractAssembler masm, LabelRef[] keyTargets, LabelRef defaultTarget) {
+        public BaseSwitchClosure(CompilationResultBuilder crb, Assembler masm, LabelRef[] keyTargets, LabelRef defaultTarget) {
             this.crb = crb;
             this.masm = masm;
             this.keyTargets = keyTargets;
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/CompilationResultBuilder.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/CompilationResultBuilder.java	Wed Mar 05 19:40:15 2014 -0800
@@ -54,7 +54,7 @@
         }
     }
 
-    public final AbstractAssembler asm;
+    public final Assembler asm;
     public final CompilationResult compilationResult;
     public final TargetDescription target;
     public final CodeCacheProvider codeCache;
@@ -78,8 +78,7 @@
 
     private List<ExceptionInfo> exceptionInfoList;
 
-    public CompilationResultBuilder(CodeCacheProvider codeCache, ForeignCallsProvider foreignCalls, FrameMap frameMap, AbstractAssembler asm, FrameContext frameContext,
-                    CompilationResult compilationResult) {
+    public CompilationResultBuilder(CodeCacheProvider codeCache, ForeignCallsProvider foreignCalls, FrameMap frameMap, Assembler asm, FrameContext frameContext, CompilationResult compilationResult) {
         this.target = codeCache.getTarget();
         this.codeCache = codeCache;
         this.foreignCalls = foreignCalls;
@@ -97,15 +96,15 @@
     private static final CompilationResult.Mark[] NO_REFS = {};
 
     public CompilationResult.Mark recordMark(Object id) {
-        return compilationResult.recordMark(asm.codeBuffer.position(), id, NO_REFS);
+        return compilationResult.recordMark(asm.position(), id, NO_REFS);
     }
 
     public CompilationResult.Mark recordMark(Object id, CompilationResult.Mark... references) {
-        return compilationResult.recordMark(asm.codeBuffer.position(), id, references);
+        return compilationResult.recordMark(asm.position(), id, references);
     }
 
     public void blockComment(String s) {
-        compilationResult.addAnnotation(new CompilationResult.CodeComment(asm.codeBuffer.position(), s));
+        compilationResult.addAnnotation(new CompilationResult.CodeComment(asm.position(), s));
     }
 
     /**
@@ -114,7 +113,7 @@
      * the compilation result.
      */
     public void finish() {
-        compilationResult.setTargetCode(asm.codeBuffer.close(false), asm.codeBuffer.position());
+        compilationResult.setTargetCode(asm.close(false), asm.position());
 
         // Record exception handlers if they exist
         if (exceptionInfoList != null) {
@@ -159,8 +158,8 @@
 
     public void recordInlineDataInCode(Constant data) {
         assert data != null;
-        int pos = asm.codeBuffer.position();
-        Debug.log("Inline data in code: pos = %d, data = %s", pos, data.toString());
+        int pos = asm.position();
+        Debug.log("Inline data in code: pos = %d, data = %s", pos, data);
         compilationResult.recordInlineData(pos, data);
     }
 
@@ -171,8 +170,8 @@
 
     public AbstractAddress recordDataReferenceInCode(Data data) {
         assert data != null;
-        int pos = asm.codeBuffer.position();
-        Debug.log("Data reference in code: pos = %d, data = %s", pos, data.toString());
+        int pos = asm.position();
+        Debug.log("Data reference in code: pos = %d, data = %s", pos, data);
         compilationResult.recordDataReference(pos, data);
         return asm.getPlaceholder();
     }
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/CompilationResultBuilderFactory.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/CompilationResultBuilderFactory.java	Wed Mar 05 19:40:15 2014 -0800
@@ -34,7 +34,7 @@
     /**
      * Creates a new {@link CompilationResultBuilder}.
      */
-    CompilationResultBuilder createBuilder(CodeCacheProvider codeCache, ForeignCallsProvider foreignCalls, FrameMap frameMap, AbstractAssembler asm, FrameContext frameContext,
+    CompilationResultBuilder createBuilder(CodeCacheProvider codeCache, ForeignCallsProvider foreignCalls, FrameMap frameMap, Assembler asm, FrameContext frameContext,
                     CompilationResult compilationResult);
 
     /**
@@ -42,7 +42,7 @@
      */
     CompilationResultBuilderFactory Default = new CompilationResultBuilderFactory() {
 
-        public CompilationResultBuilder createBuilder(CodeCacheProvider codeCache, ForeignCallsProvider foreignCalls, FrameMap frameMap, AbstractAssembler asm, FrameContext frameContext,
+        public CompilationResultBuilder createBuilder(CodeCacheProvider codeCache, ForeignCallsProvider foreignCalls, FrameMap frameMap, Assembler asm, FrameContext frameContext,
                         CompilationResult compilationResult) {
             return new CompilationResultBuilder(codeCache, foreignCalls, frameMap, asm, frameContext, compilationResult);
         }
--- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/BasicInductionVariable.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/BasicInductionVariable.java	Wed Mar 05 19:40:15 2014 -0800
@@ -22,7 +22,6 @@
  */
 package com.oracle.graal.loop;
 
-import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
@@ -119,28 +118,28 @@
     }
 
     @Override
-    public ValueNode extremumNode(boolean assumePositiveTripCount, Kind kind) {
-        Kind fromKind = phi.kind();
+    public ValueNode extremumNode(boolean assumePositiveTripCount, Stamp stamp) {
+        Stamp fromStamp = phi.stamp();
         StructuredGraph graph = graph();
         ValueNode stride = strideNode();
         ValueNode initNode = this.initNode();
-        if (fromKind != kind) {
-            stride = graph.unique(new ConvertNode(fromKind, kind, stride));
-            initNode = graph.unique(new ConvertNode(fromKind, kind, initNode));
+        if (!fromStamp.isCompatible(stamp)) {
+            stride = IntegerConvertNode.convert(stride, stamp);
+            initNode = IntegerConvertNode.convert(initNode, stamp);
         }
         ValueNode maxTripCount = loop.counted().maxTripCountNode(assumePositiveTripCount);
-        if (maxTripCount.kind() != kind) {
-            maxTripCount = graph.unique(new ConvertNode(maxTripCount.kind(), kind, maxTripCount));
+        if (!maxTripCount.stamp().isCompatible(stamp)) {
+            maxTripCount = IntegerConvertNode.convert(maxTripCount, stamp);
         }
-        return IntegerArithmeticNode.add(graph, IntegerArithmeticNode.mul(graph, stride, IntegerArithmeticNode.sub(graph, maxTripCount, ConstantNode.forIntegerKind(kind, 1, graph))), initNode);
+        return IntegerArithmeticNode.add(graph, IntegerArithmeticNode.mul(graph, stride, IntegerArithmeticNode.sub(graph, maxTripCount, ConstantNode.forIntegerStamp(stamp, 1, graph))), initNode);
     }
 
     @Override
     public ValueNode exitValueNode() {
-        Kind kind = phi.kind();
+        Stamp stamp = phi.stamp();
         ValueNode maxTripCount = loop.counted().maxTripCountNode(false);
-        if (maxTripCount.kind() != kind) {
-            maxTripCount = graph().unique(new ConvertNode(maxTripCount.kind(), kind, maxTripCount));
+        if (!maxTripCount.stamp().isCompatible(stamp)) {
+            maxTripCount = IntegerConvertNode.convert(maxTripCount, stamp);
         }
         return IntegerArithmeticNode.add(graph(), IntegerArithmeticNode.mul(graph(), strideNode(), maxTripCount), initNode());
     }
--- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/CountedLoopInfo.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/CountedLoopInfo.java	Wed Mar 05 19:40:15 2014 -0800
@@ -29,6 +29,7 @@
 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 {
 
@@ -52,18 +53,18 @@
 
     public ValueNode maxTripCountNode(boolean assumePositive) {
         StructuredGraph graph = iv.valueNode().graph();
-        Kind kind = iv.valueNode().kind();
+        Stamp stamp = iv.valueNode().stamp();
         IntegerArithmeticNode range = IntegerArithmeticNode.sub(graph, end, iv.initNode());
         if (oneOff) {
             if (iv.direction() == Direction.Up) {
-                range = IntegerArithmeticNode.add(graph, range, ConstantNode.forIntegerKind(kind, 1, graph));
+                range = IntegerArithmeticNode.add(graph, range, ConstantNode.forIntegerStamp(stamp, 1, graph));
             } else {
-                range = IntegerArithmeticNode.sub(graph, range, ConstantNode.forIntegerKind(kind, 1, graph));
+                range = IntegerArithmeticNode.sub(graph, range, ConstantNode.forIntegerStamp(stamp, 1, graph));
             }
         }
-        IntegerDivNode div = graph.add(new IntegerDivNode(kind, range, iv.strideNode()));
+        IntegerDivNode div = graph.add(new IntegerDivNode(iv.valueNode().stamp().unrestricted(), range, iv.strideNode()));
         graph.addBeforeFixed(loop.entryPoint(), div);
-        ConstantNode zero = ConstantNode.forIntegerKind(kind, 0, graph);
+        ConstantNode zero = ConstantNode.forIntegerStamp(stamp, 0, graph);
         if (assumePositive) {
             return div;
         }
@@ -137,19 +138,19 @@
         if (overflowGuard != null) {
             return overflowGuard;
         }
-        Kind kind = iv.valueNode().kind();
+        IntegerStamp stamp = (IntegerStamp) iv.valueNode().stamp();
         StructuredGraph graph = iv.valueNode().graph();
         CompareNode cond; // we use a negated guard with a < condition to achieve a >=
-        ConstantNode one = ConstantNode.forIntegerKind(kind, 1, graph);
+        ConstantNode one = ConstantNode.forIntegerStamp(stamp, 1, graph);
         if (iv.direction() == Direction.Up) {
-            IntegerArithmeticNode v1 = sub(graph, ConstantNode.forIntegerKind(kind, kind.getMaxValue(), graph), sub(graph, iv.strideNode(), one));
+            IntegerArithmeticNode v1 = sub(graph, ConstantNode.forIntegerStamp(stamp, IntegerStamp.defaultMaxValue(stamp.getBits(), stamp.isUnsigned()), 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.forIntegerKind(kind, kind.getMinValue(), graph), sub(graph, one, iv.strideNode()));
+            IntegerArithmeticNode v1 = add(graph, ConstantNode.forIntegerStamp(stamp, IntegerStamp.defaultMinValue(stamp.getBits(), stamp.isUnsigned()), graph), sub(graph, one, iv.strideNode()));
             if (oneOff) {
                 v1 = add(graph, v1, one);
             }
@@ -161,7 +162,7 @@
         return overflowGuard;
     }
 
-    public Kind getKind() {
-        return iv.valueNode().kind();
+    public IntegerStamp getStamp() {
+        return (IntegerStamp) iv.valueNode().stamp();
     }
 }
--- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/DerivedOffsetInductionVariable.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/DerivedOffsetInductionVariable.java	Wed Mar 05 19:40:15 2014 -0800
@@ -22,10 +22,10 @@
  */
 package com.oracle.graal.loop;
 
-import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
+import com.oracle.graal.nodes.type.*;
 
 public class DerivedOffsetInductionVariable extends InductionVariable {
 
@@ -92,8 +92,8 @@
     }
 
     @Override
-    public ValueNode extremumNode(boolean assumePositiveTripCount, Kind kind) {
-        return op(base.extremumNode(assumePositiveTripCount, kind), ConvertNode.convert(graph(), kind, offset));
+    public ValueNode extremumNode(boolean assumePositiveTripCount, Stamp stamp) {
+        return op(base.extremumNode(assumePositiveTripCount, stamp), IntegerConvertNode.convert(offset, stamp));
     }
 
     @Override
--- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/DerivedScaledInductionVariable.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/DerivedScaledInductionVariable.java	Wed Mar 05 19:40:15 2014 -0800
@@ -22,7 +22,6 @@
  */
 package com.oracle.graal.loop;
 
-import com.oracle.graal.api.meta.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.type.*;
@@ -102,8 +101,8 @@
     }
 
     @Override
-    public ValueNode extremumNode(boolean assumePositiveTripCount, Kind kind) {
-        return IntegerArithmeticNode.mul(graph(), base.extremumNode(assumePositiveTripCount, kind), ConvertNode.convert(graph(), kind, scale));
+    public ValueNode extremumNode(boolean assumePositiveTripCount, Stamp stamp) {
+        return IntegerArithmeticNode.mul(graph(), base.extremumNode(assumePositiveTripCount, stamp), IntegerConvertNode.convert(scale, stamp));
     }
 
     @Override
--- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/InductionVariable.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/InductionVariable.java	Wed Mar 05 19:40:15 2014 -0800
@@ -22,9 +22,9 @@
  */
 package com.oracle.graal.loop;
 
-import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 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.
@@ -89,10 +89,10 @@
      * induction variable in the loop body of the last iteration.
      */
     public ValueNode extremumNode() {
-        return extremumNode(false, valueNode().kind());
+        return extremumNode(false, valueNode().stamp());
     }
 
-    public abstract ValueNode extremumNode(boolean assumePositiveTripCount, Kind kind);
+    public abstract ValueNode extremumNode(boolean assumePositiveTripCount, Stamp stamp);
 
     public abstract boolean isConstantExtremum();
 
--- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/phases/LoopSafepointEliminationPhase.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/phases/LoopSafepointEliminationPhase.java	Wed Mar 05 19:40:15 2014 -0800
@@ -22,7 +22,6 @@
  */
 package com.oracle.graal.loop.phases;
 
-import com.oracle.graal.api.meta.*;
 import com.oracle.graal.loop.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.cfg.*;
@@ -38,7 +37,7 @@
         if (context.getOptimisticOptimizations().useLoopLimitChecks()) {
             loops.detectedCountedLoops();
             for (LoopEx loop : loops.countedLoops()) {
-                if (loop.lirLoop().children.isEmpty() && loop.counted().getKind() == Kind.Int) {
+                if (loop.lirLoop().children.isEmpty() && loop.counted().getStamp().getBits() <= 32) {
                     boolean hasSafepoint = false;
                     for (LoopEndNode loopEnd : loop.loopBegin().loopEnds()) {
                         hasSafepoint |= loopEnd.canSafepoint();
--- a/graal/com.oracle.graal.nodes.test/src/com/oracle/graal/nodes/test/IntegerStampTest.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.nodes.test/src/com/oracle/graal/nodes/test/IntegerStampTest.java	Wed Mar 05 19:40:15 2014 -0800
@@ -44,83 +44,83 @@
 
     @Test
     public void testBooleanConstant() {
-        assertEquals(new IntegerStamp(Kind.Int, 1, 1, 0x1, 0x1), ConstantNode.forBoolean(true, graph).stamp());
-        assertEquals(new IntegerStamp(Kind.Int, 0, 0, 0x0, 0x0), ConstantNode.forBoolean(false, graph).stamp());
+        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());
     }
 
     @Test
     public void testByteConstant() {
-        assertEquals(new IntegerStamp(Kind.Int, 0, 0, 0x0, 0x0), ConstantNode.forByte((byte) 0, graph).stamp());
-        assertEquals(new IntegerStamp(Kind.Int, 16, 16, 0x10, 0x10), ConstantNode.forByte((byte) 16, graph).stamp());
-        assertEquals(new IntegerStamp(Kind.Int, -16, -16, 0xfffffff0L, 0xfffffff0L), ConstantNode.forByte((byte) -16, graph).stamp());
-        assertEquals(new IntegerStamp(Kind.Int, 127, 127, 0x7f, 0x7f), ConstantNode.forByte((byte) 127, graph).stamp());
-        assertEquals(new IntegerStamp(Kind.Int, -128, -128, 0xffffff80L, 0xffffff80L), ConstantNode.forByte((byte) -128, graph).stamp());
+        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());
     }
 
     @Test
     public void testShortConstant() {
-        assertEquals(new IntegerStamp(Kind.Int, 0, 0, 0x0, 0x0), ConstantNode.forShort((short) 0, graph).stamp());
-        assertEquals(new IntegerStamp(Kind.Int, 128, 128, 0x80, 0x80), ConstantNode.forShort((short) 128, graph).stamp());
-        assertEquals(new IntegerStamp(Kind.Int, -128, -128, 0xffffff80L, 0xffffff80L), ConstantNode.forShort((short) -128, graph).stamp());
-        assertEquals(new IntegerStamp(Kind.Int, 32767, 32767, 0x7fff, 0x7fff), ConstantNode.forShort((short) 32767, graph).stamp());
-        assertEquals(new IntegerStamp(Kind.Int, -32768, -32768, 0xffff8000L, 0xffff8000L), ConstantNode.forShort((short) -32768, graph).stamp());
+        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());
     }
 
     @Test
     public void testCharConstant() {
-        assertEquals(new IntegerStamp(Kind.Int, 0, 0, 0x0, 0x0), ConstantNode.forChar((char) 0, graph).stamp());
-        assertEquals(new IntegerStamp(Kind.Int, 'A', 'A', 'A', 'A'), ConstantNode.forChar('A', graph).stamp());
-        assertEquals(new IntegerStamp(Kind.Int, 128, 128, 0x80, 0x80), ConstantNode.forChar((char) 128, graph).stamp());
-        assertEquals(new IntegerStamp(Kind.Int, 65535, 65535, 0xffff, 0xffff), ConstantNode.forChar((char) 65535, graph).stamp());
+        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());
     }
 
     @Test
     public void testIntConstant() {
-        assertEquals(new IntegerStamp(Kind.Int, 0, 0, 0x0, 0x0), ConstantNode.forInt(0, graph).stamp());
-        assertEquals(new IntegerStamp(Kind.Int, 128, 128, 0x80, 0x80), ConstantNode.forInt(128, graph).stamp());
-        assertEquals(new IntegerStamp(Kind.Int, -128, -128, 0xffffff80L, 0xffffff80L), ConstantNode.forInt(-128, graph).stamp());
-        assertEquals(new IntegerStamp(Kind.Int, Integer.MAX_VALUE, Integer.MAX_VALUE, 0x7fffffff, 0x7fffffff), ConstantNode.forInt(Integer.MAX_VALUE, graph).stamp());
-        assertEquals(new IntegerStamp(Kind.Int, Integer.MIN_VALUE, Integer.MIN_VALUE, 0x80000000L, 0x80000000L), ConstantNode.forInt(Integer.MIN_VALUE, graph).stamp());
+        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());
     }
 
     @Test
     public void testLongConstant() {
-        assertEquals(new IntegerStamp(Kind.Long, 0, 0, 0x0, 0x0), ConstantNode.forLong(0, graph).stamp());
-        assertEquals(new IntegerStamp(Kind.Long, 128, 128, 0x80, 0x80), ConstantNode.forLong(128, graph).stamp());
-        assertEquals(new IntegerStamp(Kind.Long, -128, -128, 0xffffffffffffff80L, 0xffffffffffffff80L), ConstantNode.forLong(-128, graph).stamp());
-        assertEquals(new IntegerStamp(Kind.Long, Long.MAX_VALUE, Long.MAX_VALUE, 0x7fffffffffffffffL, 0x7fffffffffffffffL), ConstantNode.forLong(Long.MAX_VALUE, graph).stamp());
-        assertEquals(new IntegerStamp(Kind.Long, Long.MIN_VALUE, Long.MIN_VALUE, 0x8000000000000000L, 0x8000000000000000L), ConstantNode.forLong(Long.MIN_VALUE, graph).stamp());
+        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());
     }
 
     @Test
     public void testPositiveRanges() {
-        assertEquals(new IntegerStamp(Kind.Int, 0, 0, 0, 0), StampFactory.forInteger(Kind.Int, 0, 0));
-        assertEquals(new IntegerStamp(Kind.Int, 0, 1, 0, 1), StampFactory.forInteger(Kind.Int, 0, 1));
-        assertEquals(new IntegerStamp(Kind.Int, 0, 0x123, 0, 0x1ff), StampFactory.forInteger(Kind.Int, 0, 0x123));
-        assertEquals(new IntegerStamp(Kind.Int, 0x120, 0x123, 0x120, 0x123), StampFactory.forInteger(Kind.Int, 0x120, 0x123));
-        assertEquals(new IntegerStamp(Kind.Int, 10000, 15000, 0x2000, 0x3fff), StampFactory.forInteger(Kind.Int, 10000, 15000));
-        assertEquals(new IntegerStamp(Kind.Long, 0, 1, 0, 1), StampFactory.forInteger(Kind.Long, 0, 1));
-        assertEquals(new IntegerStamp(Kind.Long, 10000, 15000, 0x2000, 0x3fff), StampFactory.forInteger(Kind.Long, 10000, 15000));
-        assertEquals(new IntegerStamp(Kind.Long, 140000000000L, 150000000000L, 0x2000000000L, 0x23ffffffffL), StampFactory.forInteger(Kind.Long, 140000000000L, 150000000000L));
+        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));
     }
 
     @Test
     public void testNegativeRanges() {
-        assertEquals(new IntegerStamp(Kind.Int, -2, -1, 0xfffffffeL, 0xffffffffL), StampFactory.forInteger(Kind.Int, -2, -1));
-        assertEquals(new IntegerStamp(Kind.Int, -20, -10, 0xffffffe0L, 0xffffffffL), StampFactory.forInteger(Kind.Int, -20, -10));
-        assertEquals(new IntegerStamp(Kind.Int, -10000, 0, 0, 0xffffffffL), StampFactory.forInteger(Kind.Int, -10000, 0));
-        assertEquals(new IntegerStamp(Kind.Int, -10000, -1, 0xffffc000L, 0xffffffffL), StampFactory.forInteger(Kind.Int, -10000, -1));
-        assertEquals(new IntegerStamp(Kind.Int, -10010, -10000, 0xffffd8e0L, 0xffffd8ffL), StampFactory.forInteger(Kind.Int, -10010, -10000));
-        assertEquals(new IntegerStamp(Kind.Long, -2, -1, 0xfffffffffffffffeL, 0xffffffffffffffffL), StampFactory.forInteger(Kind.Long, -2, -1));
-        assertEquals(new IntegerStamp(Kind.Long, -10010, -10000, 0xffffffffffffd8e0L, 0xffffffffffffd8ffL), StampFactory.forInteger(Kind.Long, -10010, -10000));
-        assertEquals(new IntegerStamp(Kind.Long, -150000000000L, -140000000000L, 0xffffffdc00000000L, 0xffffffdfffffffffL), StampFactory.forInteger(Kind.Long, -150000000000L, -140000000000L));
+        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));
     }
 
     @Test
     public void testMixedRanges() {
-        assertEquals(new IntegerStamp(Kind.Int, -1, 0, 0, 0xffffffffL), StampFactory.forInteger(Kind.Int, -1, 0));
-        assertEquals(new IntegerStamp(Kind.Int, -10000, 1000, 0, 0xffffffffL), StampFactory.forInteger(Kind.Int, -10000, 1000));
-        assertEquals(new IntegerStamp(Kind.Long, -10000, 1000, 0, 0xffffffffffffffffL), StampFactory.forInteger(Kind.Long, -10000, 1000));
+        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));
     }
 
     @Test
@@ -159,15 +159,15 @@
 
     @Test
     public void testXor() {
-        assertEquals(new IntegerStamp(Kind.Int, 0, 0xff, 0, 0xff), StampTool.xor(new IntegerStamp(Kind.Int, 0, 0, 0, 0), new IntegerStamp(Kind.Int, 0, 0xff, 0, 0xff)));
-        assertEquals(new IntegerStamp(Kind.Int, 0x10, 0x1f, 0x10, 0x1f), StampTool.xor(new IntegerStamp(Kind.Int, 0, 0, 0, 0), new IntegerStamp(Kind.Int, 0x10, 0x1f, 0x10, 0x1f)));
-        assertEquals(new IntegerStamp(Kind.Int, 0x0, 0xf, 0x0, 0xf), StampTool.xor(new IntegerStamp(Kind.Int, 0x10, 0x10, 0x10, 0x10), new IntegerStamp(Kind.Int, 0x10, 0x1f, 0x10, 0x1f)));
-        assertEquals(new IntegerStamp(Kind.Int, 0x10, 0x1f, 0x10, 0x1f), StampTool.xor(new IntegerStamp(Kind.Int, 0x10, 0x10, 0x10, 0x10), new IntegerStamp(Kind.Int, 0x0, 0xf, 0x0, 0xf)));
+        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)));
     }
 
     @Test
     public void testNot() {
-        assertEquals(new IntegerStamp(Kind.Int, -11, -1, 0xffff_fff0L, 0xffff_ffffL), StampTool.not(new IntegerStamp(Kind.Int, 0, 10, 0, 0xf)));
+        assertEquals(new IntegerStamp(32, false, -11, -1, 0xffff_fff0L, 0xffff_ffffL), StampTool.not(new IntegerStamp(32, false, 0, 10, 0, 0xf)));
     }
 
     @Test
@@ -258,6 +258,70 @@
 
     @Test
     public void testAnd() {
-        assertEquals(new IntegerStamp(Kind.Int, Integer.MIN_VALUE, 0x40000000L, 0, 0xc0000000L), StampTool.and(StampFactory.forKind(Kind.Int), StampFactory.forConstant(Constant.forInt(0xc0000000))));
+        assertEquals(new IntegerStamp(32, false, 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 intStamp = StampTool.signExtend(shortStamp, 32);
+        assertEquals(StampFactory.forInteger(32, false, lower, upper), intStamp);
+    }
+
+    @Test
+    public void testSignExtend() {
+        testSignExtendShort(5, 7);
+        testSignExtendShort(0, 42);
+        testSignExtendShort(-42, -1);
+        testSignExtendShort(-42, 0);
+        testSignExtendShort(-1, 1);
+        testSignExtendShort(Short.MIN_VALUE, Short.MAX_VALUE);
+    }
+
+    private static void testZeroExtendShort(long lower, long upper, long newLower, long newUpper) {
+        Stamp shortStamp = StampFactory.forInteger(16, false, lower, upper);
+        Stamp intStamp = StampTool.zeroExtend(shortStamp, 32);
+        assertEquals(StampFactory.forInteger(32, false, newLower, newUpper), intStamp);
+    }
+
+    @Test
+    public void testZeroExtend() {
+        testZeroExtendShort(5, 7, 5, 7);
+        testZeroExtendShort(0, 42, 0, 42);
+        testZeroExtendShort(-42, -1, 0xFFFF - 41, 0xFFFF);
+        testZeroExtendShort(-42, 0, 0, 0xFFFF);
+        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);
     }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ConstantNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ConstantNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -70,7 +70,7 @@
      * Used to measure the impact of ConstantNodes not recording their usages. This and all code
      * predicated on this value being true will be removed at some point.
      */
-    public static final boolean ConstantNodeRecordsUsages = Boolean.getBoolean("graal.constantNodeRecordsUsages");
+    public static final boolean ConstantNodeRecordsUsages = Boolean.parseBoolean(System.getProperty("graal.constantNodeRecordsUsages", "true"));
 
     @Override
     public boolean recordsUsages() {
@@ -151,8 +151,18 @@
         }
     }
 
+    public static ConstantNode forConstant(Stamp stamp, Constant constant, MetaAccessProvider metaAccess, StructuredGraph graph) {
+        if (stamp instanceof PrimitiveStamp) {
+            return forPrimitive(stamp, constant, graph);
+        } else {
+            ConstantNode ret = forConstant(constant, metaAccess, graph);
+            assert ret.stamp().isCompatible(stamp);
+            return ret;
+        }
+    }
+
     /**
-     * Returns a node for a primitive constant.
+     * Returns a node for a Java primitive.
      */
     public static ConstantNode forPrimitive(Constant constant, StructuredGraph graph) {
         assert constant.getKind() != Kind.Object;
@@ -160,6 +170,19 @@
     }
 
     /**
+     * Returns a node for a primitive of a given type.
+     */
+    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);
+        } else {
+            assert constant.getKind().isNumericFloat() && stamp.getStackKind() == constant.getKind();
+            return forPrimitive(constant, graph);
+        }
+    }
+
+    /**
      * Returns a node for a double constant.
      * 
      * @param d the double value for which to create the instruction
@@ -255,6 +278,33 @@
         return graph.unique(node);
     }
 
+    /**
+     * 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)));
+    }
+
+    /**
+     * Returns a node for a constant integer that's compatible to a given stamp.
+     */
+    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);
+        } else {
+            return forIntegerKind(stamp.getStackKind(), value, graph);
+        }
+    }
+
     public static ConstantNode forIntegerKind(Kind kind, long value, StructuredGraph graph) {
         switch (kind) {
             case Byte:
@@ -279,6 +329,13 @@
         }
     }
 
+    /**
+     * Returns a node for a constant double that's compatible to a given stamp.
+     */
+    public static ConstantNode forFloatingStamp(Stamp stamp, double value, StructuredGraph graph) {
+        return forFloatingKind(stamp.getStackKind(), value, graph);
+    }
+
     public static ConstantNode defaultForKind(Kind kind, StructuredGraph graph) {
         switch (kind) {
             case Boolean:
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DirectCallTargetNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DirectCallTargetNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -36,6 +36,6 @@
 
     @Override
     public String targetName() {
-        return "Direct#" + ((JavaMethod) target()).getName();
+        return MetaUtil.format("Direct#%h.%n", target());
     }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedGuardNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedGuardNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -51,7 +51,7 @@
                     tool.deleteBranch(next);
                 }
 
-                DeoptimizeNode deopt = graph().add(new DeoptimizeNode(DeoptimizationAction.InvalidateRecompile, getReason()));
+                DeoptimizeNode deopt = graph().add(new DeoptimizeNode(getAction(), getReason()));
                 deopt.setDeoptimizationState(getDeoptimizationState());
                 setNext(deopt);
             }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FrameState.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FrameState.java	Wed Mar 05 19:40:15 2014 -0800
@@ -244,8 +244,8 @@
 
     /**
      * Creates a copy of this frame state with one stack element of type popKind popped from the
-     * stack and the values in pushedValues pushed on the stack. The pushedValues are expected to be
-     * in slot encoding: a long or double is followed by a null slot.
+     * stack and the values in pushedValues pushed on the stack. The pushedValues will be formatted
+     * correctly in slot encoding: a long or double will be followed by a null slot.
      */
     public FrameState duplicateModified(int newBci, boolean newRethrowException, Kind popKind, ValueNode... pushedValues) {
         ArrayList<ValueNode> copy = new ArrayList<>(values.subList(0, localsSize + stackSize));
@@ -257,7 +257,12 @@
             assert lastSlot.kind().getStackKind() == popKind.getStackKind();
             copy.remove(copy.size() - 1);
         }
-        Collections.addAll(copy, pushedValues);
+        for (ValueNode node : pushedValues) {
+            copy.add(node);
+            if (node.kind() == Kind.Long || node.kind() == Kind.Double) {
+                copy.add(null);
+            }
+        }
         int newStackSize = copy.size() - localsSize;
         copy.addAll(values.subList(localsSize + stackSize, values.size()));
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -109,11 +109,6 @@
             if (c.getValue() != negated) {
                 return graph().start();
             }
-        } else if (negated && condition() instanceof ShortCircuitOrNode) {
-            ShortCircuitOrNode or = (ShortCircuitOrNode) condition();
-            GuardNode firstGuard = graph().unique(new GuardNode(or.getX(), getGuard(), reason, action, !or.isXNegated(), speculation));
-            GuardNode secondGuard = graph().unique(new GuardNode(or.getY(), firstGuard, reason, action, !or.isYNegated(), speculation));
-            return secondGuard;
         }
         return this;
     }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopBeginNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopBeginNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -31,6 +31,7 @@
 import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.nodes.util.*;
 
 public class LoopBeginNode extends MergeNode implements IterableNodeType, LIRLowerable {
 
@@ -184,7 +185,11 @@
     public void removeExits() {
         for (LoopExitNode loopexit : loopExits().snapshot()) {
             loopexit.removeProxies();
+            FrameState stateAfter = loopexit.stateAfter();
             graph().replaceFixedWithFixed(loopexit, graph().add(new BeginNode()));
+            if (stateAfter != null && stateAfter.isAlive() && stateAfter.usages().isEmpty()) {
+                GraphUtil.killWithUnusedFloatingInputs(stateAfter);
+            }
         }
     }
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PiArrayNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PiArrayNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -30,7 +30,7 @@
 
 /**
  * A {@link PiNode} that also provides an array length in addition to a more refined stamp. A usage
- * that reads the array length, such as an {@link ArrayLengthNode}, can be canonicalized base on
+ * that reads the array length, such as an {@link ArrayLengthNode}, can be canonicalized based on
  * this information.
  */
 public final class PiArrayNode extends PiNode implements ArrayLengthProvider {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PiNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PiNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -22,6 +22,8 @@
  */
 package com.oracle.graal.nodes;
 
+//JaCoCo Exclude
+
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.spi.*;
@@ -102,9 +104,21 @@
     @NodeIntrinsic
     public static native <T> T piCast(Object object, @ConstantNodeParameter Stamp stamp, GuardingNode anchor);
 
+    public static <T> T piCastExactNonNull(Object object, @ConstantNodeParameter Class<T> toType) {
+        return piCast(object, toType, true, true);
+    }
+
+    public static <T> T piCast(Object object, @ConstantNodeParameter Class<T> toType) {
+        return piCast(object, toType, false, false);
+    }
+
+    public static <T> T piCastNonNull(Object object, @ConstantNodeParameter Class<T> toType) {
+        return piCast(object, toType, false, true);
+    }
+
     @SuppressWarnings("unused")
     @NodeIntrinsic
-    public static <T> T piCast(Object object, @ConstantNodeParameter Class<T> toType, @ConstantNodeParameter boolean exactType, @ConstantNodeParameter boolean nonNull) {
+    private static <T> T piCast(Object object, @ConstantNodeParameter Class<T> toType, @ConstantNodeParameter boolean exactType, @ConstantNodeParameter boolean nonNull) {
         return toType.cast(object);
     }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ProxyNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ProxyNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -36,7 +36,7 @@
  * loop.
  */
 @NodeInfo(nameTemplate = "{p#type/s}Proxy")
-public class ProxyNode extends FloatingNode implements IterableNodeType, ValueNumberable, Canonicalizable, Virtualizable, ValueProxy, GuardingNode {
+public class ProxyNode extends FloatingNode implements IterableNodeType, ValueNumberable, Canonicalizable, Virtualizable, ValueAndStampProxy, GuardingNode {
 
     @Input(notDataflow = true) private AbstractBeginNode proxyPoint;
     @Input private ValueNode value;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValueNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValueNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -80,7 +80,7 @@
     }
 
     public final Kind kind() {
-        return stamp().kind();
+        return stamp().getStackKind();
     }
 
     /**
@@ -126,13 +126,6 @@
         return null;
     }
 
-    @Override
-    public boolean verify() {
-        assertTrue(kind() != null, "Should have a valid kind");
-        assertTrue(kind() == kind().getStackKind(), "Should have a stack kind : %s", kind());
-        return super.verify();
-    }
-
     public ValueNode asNode() {
         return this;
     }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/AndNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/AndNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -30,10 +30,10 @@
 import com.oracle.graal.nodes.type.*;
 
 @NodeInfo(shortName = "&")
-public final class AndNode extends BitLogicNode implements Canonicalizable {
+public final class AndNode extends BitLogicNode implements Canonicalizable, NarrowableArithmeticNode {
 
-    public AndNode(Kind kind, ValueNode x, ValueNode y) {
-        super(kind, x, y);
+    public AndNode(Stamp stamp, ValueNode x, ValueNode y) {
+        super(stamp, x, y);
     }
 
     @Override
@@ -44,7 +44,7 @@
     @Override
     public Constant evalConst(Constant... inputs) {
         assert inputs.length == 2;
-        return Constant.forIntegerKind(kind(), inputs[0].asLong() & inputs[1].asLong(), null);
+        return Constant.forPrimitiveInt(PrimitiveStamp.getBits(stamp()), inputs[0].asLong() & inputs[1].asLong());
     }
 
     @Override
@@ -53,28 +53,18 @@
             return x();
         }
         if (x().isConstant() && !y().isConstant()) {
-            return graph().unique(new AndNode(kind(), y(), x()));
+            return graph().unique(new AndNode(stamp(), y(), x()));
         }
         if (x().isConstant()) {
-            return ConstantNode.forPrimitive(evalConst(x().asConstant(), y().asConstant()), graph());
+            return ConstantNode.forPrimitive(stamp(), evalConst(x().asConstant(), y().asConstant()), graph());
         } else if (y().isConstant()) {
-            if (kind() == Kind.Int) {
-                int c = y().asConstant().asInt();
-                if (c == -1) {
-                    return x();
-                }
-                if (c == 0) {
-                    return ConstantNode.forInt(0, graph());
-                }
-            } else {
-                assert kind() == Kind.Long;
-                long c = y().asConstant().asLong();
-                if (c == -1) {
-                    return x();
-                }
-                if (c == 0) {
-                    return ConstantNode.forLong(0, graph());
-                }
+            long rawY = y().asConstant().asLong();
+            long mask = IntegerStamp.defaultMask(PrimitiveStamp.getBits(stamp()));
+            if ((rawY & mask) == mask) {
+                return x();
+            }
+            if ((rawY & mask) == 0) {
+                return ConstantNode.forIntegerStamp(stamp(), 0, graph());
             }
             return BinaryNode.reassociate(this, ValueNode.isConstantPredicate());
         }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/BinaryNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/BinaryNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -22,7 +22,6 @@
  */
 package com.oracle.graal.nodes.calc;
 
-import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.iterators.*;
 import com.oracle.graal.nodes.*;
@@ -47,12 +46,12 @@
     /**
      * Creates a new BinaryNode instance.
      * 
-     * @param kind the result type of this instruction
+     * @param stamp the result type of this instruction
      * @param x the first input instruction
      * @param y the second input instruction
      */
-    public BinaryNode(Kind kind, ValueNode x, ValueNode y) {
-        super(StampFactory.forKind(kind));
+    public BinaryNode(Stamp stamp, ValueNode x, ValueNode y) {
+        super(stamp);
         this.x = x;
         this.y = y;
     }
@@ -84,53 +83,38 @@
     }
 
     public static BinaryNode add(StructuredGraph graph, ValueNode x, ValueNode y) {
-        assert x.kind() == y.kind();
-        switch (x.kind()) {
-            case Byte:
-            case Char:
-            case Short:
-            case Int:
-            case Long:
-                return IntegerArithmeticNode.add(graph, x, y);
-            case Float:
-            case Double:
-                return graph.unique(new FloatAddNode(x.kind(), x, y, false));
-            default:
-                throw GraalInternalError.shouldNotReachHere();
+        assert x.stamp().isCompatible(y.stamp());
+        Stamp stamp = x.stamp();
+        if (stamp instanceof IntegerStamp) {
+            return IntegerArithmeticNode.add(graph, x, y);
+        } else if (stamp instanceof FloatStamp) {
+            return graph.unique(new FloatAddNode(stamp, x, y, false));
+        } else {
+            throw GraalInternalError.shouldNotReachHere();
         }
     }
 
     public static BinaryNode sub(StructuredGraph graph, ValueNode x, ValueNode y) {
-        assert x.kind() == y.kind();
-        switch (x.kind()) {
-            case Byte:
-            case Char:
-            case Short:
-            case Int:
-            case Long:
-                return IntegerArithmeticNode.sub(graph, x, y);
-            case Float:
-            case Double:
-                return graph.unique(new FloatSubNode(x.kind(), x, y, false));
-            default:
-                throw GraalInternalError.shouldNotReachHere();
+        assert x.stamp().isCompatible(y.stamp());
+        Stamp stamp = x.stamp();
+        if (stamp instanceof IntegerStamp) {
+            return IntegerArithmeticNode.sub(graph, x, y);
+        } else if (stamp instanceof FloatStamp) {
+            return graph.unique(new FloatSubNode(stamp, x, y, false));
+        } else {
+            throw GraalInternalError.shouldNotReachHere();
         }
     }
 
     public static BinaryNode mul(StructuredGraph graph, ValueNode x, ValueNode y) {
-        assert x.kind() == y.kind();
-        switch (x.kind()) {
-            case Byte:
-            case Char:
-            case Short:
-            case Int:
-            case Long:
-                return IntegerArithmeticNode.mul(graph, x, y);
-            case Float:
-            case Double:
-                return graph.unique(new FloatMulNode(x.kind(), x, y, false));
-            default:
-                throw GraalInternalError.shouldNotReachHere();
+        assert x.stamp().isCompatible(y.stamp());
+        Stamp stamp = x.stamp();
+        if (stamp instanceof IntegerStamp) {
+            return IntegerArithmeticNode.mul(graph, x, y);
+        } else if (stamp instanceof FloatStamp) {
+            return graph.unique(new FloatMulNode(stamp, x, y, false));
+        } else {
+            throw GraalInternalError.shouldNotReachHere();
         }
     }
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/BitLogicNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/BitLogicNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -22,14 +22,14 @@
  */
 package com.oracle.graal.nodes.calc;
 
-import com.oracle.graal.api.meta.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.nodes.type.*;
 
 /**
  * The {@code LogicNode} class definition.
  */
-public abstract class BitLogicNode extends BinaryNode implements ArithmeticLIRLowerable {
+public abstract class BitLogicNode extends BinaryNode implements ArithmeticLIRLowerable, NarrowableArithmeticNode {
 
     /**
      * Constructs a new logic operation node.
@@ -37,44 +37,23 @@
      * @param x the first input into this node
      * @param y the second input into this node
      */
-    public BitLogicNode(Kind kind, ValueNode x, ValueNode y) {
-        super(kind, x, y);
-        assert kind == Kind.Int || kind == Kind.Long;
+    public BitLogicNode(Stamp stamp, ValueNode x, ValueNode y) {
+        super(stamp, x, y);
+        assert stamp instanceof IntegerStamp;
     }
 
     public static BitLogicNode and(StructuredGraph graph, ValueNode v1, ValueNode v2) {
-        assert v1.kind() == v2.kind();
-        switch (v1.kind()) {
-            case Int:
-                return graph.unique(new AndNode(Kind.Int, v1, v2));
-            case Long:
-                return graph.unique(new AndNode(Kind.Long, v1, v2));
-            default:
-                throw ValueNodeUtil.shouldNotReachHere();
-        }
+        assert v1.stamp().isCompatible(v2.stamp());
+        return graph.unique(new AndNode(StampTool.and(v1.stamp(), v2.stamp()), v1, v2));
     }
 
     public static BitLogicNode or(StructuredGraph graph, ValueNode v1, ValueNode v2) {
-        assert v1.kind() == v2.kind();
-        switch (v1.kind()) {
-            case Int:
-                return graph.unique(new OrNode(Kind.Int, v1, v2));
-            case Long:
-                return graph.unique(new OrNode(Kind.Long, v1, v2));
-            default:
-                throw ValueNodeUtil.shouldNotReachHere();
-        }
+        assert v1.stamp().isCompatible(v2.stamp());
+        return graph.unique(new OrNode(StampTool.or(v1.stamp(), v2.stamp()), v1, v2));
     }
 
     public static BitLogicNode xor(StructuredGraph graph, ValueNode v1, ValueNode v2) {
-        assert v1.kind() == v2.kind();
-        switch (v1.kind()) {
-            case Int:
-                return graph.unique(new XorNode(Kind.Int, v1, v2));
-            case Long:
-                return graph.unique(new XorNode(Kind.Long, v1, v2));
-            default:
-                throw ValueNodeUtil.shouldNotReachHere();
-        }
+        assert v1.stamp().isCompatible(v2.stamp());
+        return graph.unique(new XorNode(StampTool.xor(v1.stamp(), v2.stamp()), v1, v2));
     }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/CompareNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/CompareNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -136,15 +136,15 @@
         if (x() instanceof ConvertNode && y() instanceof ConvertNode) {
             ConvertNode convertX = (ConvertNode) x();
             ConvertNode convertY = (ConvertNode) y();
-            if (convertX.isLossless() && convertY.isLossless() && convertX.getFromKind() == convertY.getFromKind()) {
-                setX(convertX.value());
-                setY(convertY.value());
+            if (convertX.isLossless() && convertY.isLossless() && convertX.getInput().stamp().isCompatible(convertY.getInput().stamp())) {
+                setX(convertX.getInput());
+                setY(convertY.getInput());
             }
         } else if (x() instanceof ConvertNode && y().isConstant()) {
             ConvertNode convertX = (ConvertNode) x();
             ConstantNode newY = canonicalConvertConstant(convertX, y().asConstant());
             if (newY != null) {
-                setX(convertX.value());
+                setX(convertX.getInput());
                 setY(newY);
             }
         } else if (y() instanceof ConvertNode && x().isConstant()) {
@@ -152,7 +152,7 @@
             ConstantNode newX = canonicalConvertConstant(convertY, x().asConstant());
             if (newX != null) {
                 setX(newX);
-                setY(convertY.value());
+                setY(convertY.getInput());
             }
         }
         return this;
@@ -160,10 +160,9 @@
 
     private static ConstantNode canonicalConvertConstant(ConvertNode convert, Constant constant) {
         if (convert.isLossless()) {
-            assert constant.getKind() == convert.getToKind();
-            Constant reverseConverted = ConvertNode.convert(convert.getToKind(), convert.getFromKind(), constant);
-            if (convert.evalConst(reverseConverted).equals(constant)) {
-                return ConstantNode.forPrimitive(reverseConverted, convert.graph());
+            Constant reverseConverted = convert.reverse(constant);
+            if (convert.convert(reverseConverted).equals(constant)) {
+                return ConstantNode.forPrimitive(convert.getInput().stamp(), reverseConverted, convert.graph());
             }
         }
         return null;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ConditionalNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ConditionalNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -49,8 +49,8 @@
     }
 
     public ConditionalNode(LogicNode condition, ValueNode trueValue, ValueNode falseValue) {
-        super(trueValue.kind(), trueValue, falseValue);
-        assert trueValue.kind() == falseValue.kind();
+        super(trueValue.stamp().meet(falseValue.stamp()), trueValue, falseValue);
+        assert trueValue.stamp().isCompatible(falseValue.stamp());
         this.condition = condition;
     }
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ConvertNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ConvertNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -22,277 +22,36 @@
  */
 package com.oracle.graal.nodes.calc;
 
+import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
-import com.oracle.graal.graph.*;
-import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
 
 /**
- * The {@code ConvertNode} class represents a conversion between primitive types.
+ * Represents a conversion between primitive types.
  */
-public class ConvertNode extends FloatingNode implements Canonicalizable, Lowerable, ArithmeticLIRLowerable {
-
-    @Input private ValueNode value;
-
-    private final Kind from;
-    private final Kind to;
-
-    public ValueNode value() {
-        return value;
-    }
-
-    /**
-     * Constructs a new Convert instance.
-     * 
-     * @param from the kind of the incoming value
-     * @param to the result kind
-     * @param value the instruction producing the input value
-     */
-    public ConvertNode(Kind from, Kind to, ValueNode value) {
-        super(StampFactory.forKind(to.getStackKind()));
-        assert value.kind() == from.getStackKind() : "convert(" + from + ", " + to + ") : " + value.kind() + " != " + from;
-        this.from = from;
-        this.to = to;
-        this.value = value;
-    }
+public abstract class ConvertNode extends FloatingNode implements ArithmeticOperation {
 
-    public Kind getFromKind() {
-        return from;
-    }
-
-    public Kind getToKind() {
-        return to;
-    }
+    @Input private ValueNode input;
 
-    public boolean isLossless() {
-        if (from == to) {
-            return true;
-        }
-        switch (from) {
-            case Byte:
-                return true;
-            case Short:
-            case Char:
-                return to != Kind.Byte;
-            case Int:
-                return to == Kind.Long || to == Kind.Double;
-            case Float:
-                return to == Kind.Double;
-            case Long:
-            case Double:
-                return false;
-        }
-        throw GraalInternalError.shouldNotReachHere();
+    protected ConvertNode(Stamp stamp, ValueNode input) {
+        super(stamp);
+        this.input = input;
     }
 
-    public static Constant convert(Kind from, Kind to, Constant c) {
-        switch (from) {
-            case Byte:
-                byte byteVal = (byte) c.asInt();
-                switch (to) {
-                    case Byte:
-                        return Constant.forByte(byteVal);
-                    case Short:
-                        return Constant.forShort(byteVal);
-                    case Char:
-                        return Constant.forChar((char) byteVal);
-                    case Int:
-                        return Constant.forInt(byteVal);
-                    case Long:
-                        return Constant.forLong(byteVal);
-                    case Float:
-                        return Constant.forFloat(byteVal);
-                    case Double:
-                        return Constant.forDouble(byteVal);
-                }
-                break;
-            case Char:
-                char charVal = (char) c.asInt();
-                switch (to) {
-                    case Byte:
-                        return Constant.forByte((byte) charVal);
-                    case Short:
-                        return Constant.forShort((short) charVal);
-                    case Char:
-                        return Constant.forChar(charVal);
-                    case Int:
-                        return Constant.forInt(charVal);
-                    case Long:
-                        return Constant.forLong(charVal);
-                    case Float:
-                        return Constant.forFloat(charVal);
-                    case Double:
-                        return Constant.forDouble(charVal);
-                }
-                break;
-            case Short:
-                short shortVal = (short) c.asInt();
-                switch (to) {
-                    case Byte:
-                        return Constant.forByte((byte) shortVal);
-                    case Short:
-                        return Constant.forShort(shortVal);
-                    case Char:
-                        return Constant.forChar((char) shortVal);
-                    case Int:
-                        return Constant.forInt(shortVal);
-                    case Long:
-                        return Constant.forLong(shortVal);
-                    case Float:
-                        return Constant.forFloat(shortVal);
-                    case Double:
-                        return Constant.forDouble(shortVal);
-                }
-                break;
-            case Int:
-                int intVal = c.asInt();
-                switch (to) {
-                    case Byte:
-                        return Constant.forByte((byte) intVal);
-                    case Short:
-                        return Constant.forShort((short) intVal);
-                    case Char:
-                        return Constant.forChar((char) intVal);
-                    case Int:
-                        return Constant.forInt(intVal);
-                    case Long:
-                        return Constant.forLong(intVal);
-                    case Float:
-                        return Constant.forFloat(intVal);
-                    case Double:
-                        return Constant.forDouble(intVal);
-                }
-                break;
-            case Long:
-                long longVal = c.asLong();
-                switch (to) {
-                    case Byte:
-                        return Constant.forByte((byte) longVal);
-                    case Short:
-                        return Constant.forShort((short) longVal);
-                    case Char:
-                        return Constant.forChar((char) longVal);
-                    case Int:
-                        return Constant.forInt((int) longVal);
-                    case Long:
-                        return Constant.forLong(longVal);
-                    case Float:
-                        return Constant.forFloat(longVal);
-                    case Double:
-                        return Constant.forDouble(longVal);
-                }
-                break;
-            case Float:
-                float floatVal = c.asFloat();
-                switch (to) {
-                    case Byte:
-                        return Constant.forByte((byte) floatVal);
-                    case Short:
-                        return Constant.forShort((short) floatVal);
-                    case Char:
-                        return Constant.forChar((char) floatVal);
-                    case Int:
-                        return Constant.forInt((int) floatVal);
-                    case Long:
-                        return Constant.forLong((long) floatVal);
-                    case Float:
-                        return Constant.forFloat(floatVal);
-                    case Double:
-                        return Constant.forDouble(floatVal);
-                }
-                break;
-            case Double:
-                double doubleVal = c.asDouble();
-                switch (to) {
-                    case Byte:
-                        return Constant.forByte((byte) doubleVal);
-                    case Short:
-                        return Constant.forShort((short) doubleVal);
-                    case Char:
-                        return Constant.forChar((char) doubleVal);
-                    case Int:
-                        return Constant.forInt((int) doubleVal);
-                    case Long:
-                        return Constant.forLong((long) doubleVal);
-                    case Float:
-                        return Constant.forFloat((float) doubleVal);
-                    case Double:
-                        return Constant.forDouble(doubleVal);
-                }
-                break;
-        }
-        throw GraalInternalError.shouldNotReachHere();
+    public ValueNode getInput() {
+        return input;
     }
 
-    public Constant evalConst(Constant... inputs) {
-        assert inputs.length == 1;
-        return convert(from, to, inputs[0]);
-    }
+    public abstract Constant convert(Constant c);
 
-    @Override
-    public Node canonical(CanonicalizerTool tool) {
-        if (from == to) {
-            return value;
-        } else if (value.isConstant()) {
-            return ConstantNode.forPrimitive(evalConst(value.asConstant()), graph());
-        } else if (value instanceof ConvertNode) {
-            ConvertNode other = (ConvertNode) value;
-            if (other.isLossless() && other.to != Kind.Char) {
-                if (other.from == this.to) {
-                    return other.value();
-                } else {
-                    return graph().unique(new ConvertNode(other.from, this.to, other.value()));
-                }
-            }
-        }
-        return this;
-    }
+    public abstract Constant reverse(Constant c);
+
+    public abstract boolean isLossless();
 
     @Override
-    public boolean inferStamp() {
-        Stamp stamp = value.stamp();
-        if (!(stamp instanceof IntegerStamp)) {
-            if (stamp instanceof FloatStamp) {
-                return false;
-            }
-            assert stamp instanceof IllegalStamp;
-            return updateStamp(stamp);
-        }
-        Stamp newStamp;
-        IntegerStamp integerStamp = (IntegerStamp) stamp;
-        switch (to) {
-            case Byte:
-            case Short:
-            case Char:
-            case Int:
-                newStamp = StampTool.narrowingKindConversion(integerStamp, to);
-                break;
-            case Long:
-                newStamp = StampTool.intToLong(integerStamp);
-                break;
-            default:
-                return false;
-        }
-        return updateStamp(newStamp);
-    }
-
-    @Override
-    public void lower(LoweringTool tool) {
-        tool.getLowerer().lower(this, tool);
-    }
-
-    @Override
-    public void generate(ArithmeticLIRGenerator gen) {
-        gen.setResult(this, gen.emitConvert(from, to, gen.operand(value())));
-    }
-
-    public static ValueNode convert(StructuredGraph graph, Kind toKind, ValueNode value) {
-        Kind fromKind = value.kind();
-        if (fromKind == toKind) {
-            return value;
-        }
-        return graph.unique(new ConvertNode(fromKind, toKind, value));
+    public Constant evalConst(Constant... inputs) {
+        assert inputs.length == 1;
+        return convert(inputs[0]);
     }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FixedBinaryNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FixedBinaryNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -22,7 +22,6 @@
  */
 package com.oracle.graal.nodes.calc;
 
-import com.oracle.graal.api.meta.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.type.*;
 
@@ -39,8 +38,8 @@
         return y;
     }
 
-    public FixedBinaryNode(Kind kind, ValueNode x, ValueNode y) {
-        super(StampFactory.forKind(kind));
+    public FixedBinaryNode(Stamp stamp, ValueNode x, ValueNode y) {
+        super(stamp);
         this.x = x;
         this.y = y;
     }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatAddNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatAddNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -27,20 +27,22 @@
 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 final class FloatAddNode extends FloatArithmeticNode implements Canonicalizable {
 
-    public FloatAddNode(Kind kind, ValueNode x, ValueNode y, boolean isStrictFP) {
-        super(kind, x, y, isStrictFP);
+    public FloatAddNode(Stamp stamp, ValueNode x, ValueNode y, boolean isStrictFP) {
+        super(stamp, x, y, isStrictFP);
     }
 
     public Constant evalConst(Constant... inputs) {
         assert inputs.length == 2;
-        if (kind() == Kind.Float) {
+        assert inputs[0].getKind() == inputs[1].getKind();
+        if (inputs[0].getKind() == Kind.Float) {
             return Constant.forFloat(inputs[0].asFloat() + inputs[1].asFloat());
         } else {
-            assert kind() == Kind.Double;
+            assert inputs[0].getKind() == Kind.Double;
             return Constant.forDouble(inputs[0].asDouble() + inputs[1].asDouble());
         }
     }
@@ -48,22 +50,14 @@
     @Override
     public Node canonical(CanonicalizerTool tool) {
         if (x().isConstant() && !y().isConstant()) {
-            return graph().unique(new FloatAddNode(kind(), y(), x(), isStrictFP()));
+            return graph().unique(new FloatAddNode(stamp(), y(), x(), isStrictFP()));
         }
         if (x().isConstant()) {
             return ConstantNode.forPrimitive(evalConst(x().asConstant(), y().asConstant()), graph());
         } else if (y().isConstant()) {
-            if (kind() == Kind.Float) {
-                float c = y().asConstant().asFloat();
-                if (c == 0.0f) {
-                    return x();
-                }
-            } else {
-                assert kind() == Kind.Double;
-                double c = y().asConstant().asDouble();
-                if (c == 0.0) {
-                    return x();
-                }
+            Constant c = y().asConstant();
+            if ((c.getKind() == Kind.Float && c.asFloat() == 0.0f) || (c.getKind() == Kind.Double && c.asDouble() == 0.0)) {
+                return x();
             }
         }
         return this;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatArithmeticNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatArithmeticNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -22,17 +22,17 @@
  */
 package com.oracle.graal.nodes.calc;
 
-import com.oracle.graal.api.meta.*;
 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 {
 
     private final boolean isStrictFP;
 
-    public FloatArithmeticNode(Kind kind, ValueNode x, ValueNode y, boolean isStrictFP) {
-        super(kind, x, y);
-        assert kind.isNumericFloat();
+    public FloatArithmeticNode(Stamp stamp, ValueNode x, ValueNode y, boolean isStrictFP) {
+        super(stamp, x, y);
+        assert stamp instanceof FloatStamp;
         this.isStrictFP = isStrictFP;
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatConvertNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,197 @@
+/*
+ * 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.calc;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.nodes.type.*;
+
+/**
+ * A {@code FloatConvert} converts between integers and floating point numbers according to Java
+ * semantics.
+ */
+public class FloatConvertNode extends ConvertNode implements Canonicalizable, Lowerable, ArithmeticLIRLowerable {
+
+    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) {
+        super(createStamp(op, input), input);
+        this.op = op;
+    }
+
+    private static Stamp createStamp(FloatConvert op, ValueNode input) {
+        switch (op) {
+            case I2F:
+            case I2D:
+                assert input.stamp() instanceof IntegerStamp && ((IntegerStamp) input.stamp()).getBits() == 32;
+                break;
+            case L2F:
+            case L2D:
+                assert input.stamp() instanceof IntegerStamp && ((IntegerStamp) input.stamp()).getBits() == 64;
+                break;
+            case F2I:
+            case F2L:
+            case F2D:
+                assert input.stamp() instanceof FloatStamp && ((FloatStamp) input.stamp()).getBits() == 32;
+                break;
+            case D2I:
+            case D2L:
+            case D2F:
+                assert input.stamp() instanceof FloatStamp && ((FloatStamp) input.stamp()).getBits() == 64;
+                break;
+            default:
+                throw GraalInternalError.shouldNotReachHere();
+        }
+
+        switch (op) {
+            case F2I:
+            case D2I:
+                return StampFactory.forKind(Kind.Int);
+            case F2L:
+            case D2L:
+                return StampFactory.forKind(Kind.Long);
+            case I2F:
+            case L2F:
+            case D2F:
+                return StampFactory.forKind(Kind.Float);
+            case I2D:
+            case L2D:
+            case F2D:
+                return StampFactory.forKind(Kind.Double);
+            default:
+                throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+
+    public FloatConvert getOp() {
+        return op;
+    }
+
+    @Override
+    public boolean inferStamp() {
+        return updateStamp(createStamp(op, getInput()));
+    }
+
+    private static Constant convert(FloatConvert op, Constant value) {
+        switch (op) {
+            case F2I:
+                return Constant.forInt((int) value.asFloat());
+            case D2I:
+                return Constant.forInt((int) value.asDouble());
+            case F2L:
+                return Constant.forLong((long) value.asFloat());
+            case D2L:
+                return Constant.forLong((long) value.asDouble());
+            case I2F:
+                return Constant.forFloat(value.asInt());
+            case L2F:
+                return Constant.forFloat(value.asLong());
+            case D2F:
+                return Constant.forFloat((float) value.asDouble());
+            case I2D:
+                return Constant.forDouble(value.asInt());
+            case L2D:
+                return Constant.forDouble(value.asLong());
+            case F2D:
+                return Constant.forDouble(value.asFloat());
+            default:
+                throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+
+    @Override
+    public Constant convert(Constant c) {
+        return convert(op, c);
+    }
+
+    @Override
+    public Constant reverse(Constant c) {
+        return convert(op.reverse(), c);
+    }
+
+    @Override
+    public boolean isLossless() {
+        switch (op) {
+            case F2D:
+            case I2D:
+                return true;
+            default:
+                return false;
+        }
+    }
+
+    @Override
+    public Node canonical(CanonicalizerTool tool) {
+        if (getInput().isConstant()) {
+            return ConstantNode.forPrimitive(evalConst(getInput().asConstant()), graph());
+        } else if (getInput() instanceof FloatConvertNode) {
+            FloatConvertNode other = (FloatConvertNode) getInput();
+            if (other.isLossless() && other.op == this.op.reverse()) {
+                return other.getInput();
+            }
+        }
+        return this;
+    }
+
+    public void lower(LoweringTool tool) {
+        tool.getLowerer().lower(this, tool);
+    }
+
+    public void generate(ArithmeticLIRGenerator gen) {
+        gen.setResult(this, gen.emitFloatConvert(op, gen.operand(getInput())));
+    }
+}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatDivNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatDivNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -27,20 +27,22 @@
 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 final class FloatDivNode extends FloatArithmeticNode implements Canonicalizable {
 
-    public FloatDivNode(Kind kind, ValueNode x, ValueNode y, boolean isStrictFP) {
-        super(kind, x, y, isStrictFP);
+    public FloatDivNode(Stamp stamp, ValueNode x, ValueNode y, boolean isStrictFP) {
+        super(stamp, x, y, isStrictFP);
     }
 
     public Constant evalConst(Constant... inputs) {
         assert inputs.length == 2;
-        if (kind() == Kind.Float) {
+        assert inputs[0].getKind() == inputs[1].getKind();
+        if (inputs[0].getKind() == Kind.Float) {
             return Constant.forFloat(inputs[0].asFloat() / inputs[1].asFloat());
         } else {
-            assert kind() == Kind.Double;
+            assert inputs[0].getKind() == Kind.Double;
             return Constant.forDouble(inputs[0].asDouble() / inputs[1].asDouble());
         }
     }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatEqualsNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatEqualsNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -22,9 +22,9 @@
  */
 package com.oracle.graal.nodes.calc;
 
-import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.type.*;
 
 @NodeInfo(shortName = "==")
 public final class FloatEqualsNode extends CompareNode {
@@ -37,8 +37,8 @@
      */
     public FloatEqualsNode(ValueNode x, ValueNode y) {
         super(x, y);
-        assert x.kind() == Kind.Double || x.kind() == Kind.Float;
-        assert y.kind() == Kind.Double || y.kind() == Kind.Float;
+        assert x.stamp() instanceof FloatStamp && y.stamp() instanceof FloatStamp;
+        assert x.stamp().isCompatible(y.stamp());
     }
 
     @Override
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatLessThanNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatLessThanNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -22,10 +22,10 @@
  */
 package com.oracle.graal.nodes.calc;
 
-import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.type.*;
 
 @NodeInfo(shortName = "<")
 public final class FloatLessThanNode extends CompareNode {
@@ -42,8 +42,8 @@
      */
     public FloatLessThanNode(ValueNode x, ValueNode y, boolean unorderedIsTrue) {
         super(x, y);
-        assert x.kind() == Kind.Double || x.kind() == Kind.Float;
-        assert y.kind() == Kind.Double || y.kind() == Kind.Float;
+        assert x.stamp() instanceof FloatStamp && y.stamp() instanceof FloatStamp;
+        assert x.stamp().isCompatible(y.stamp());
         this.unorderedIsTrue = unorderedIsTrue;
     }
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatMulNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatMulNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -27,20 +27,22 @@
 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 final class FloatMulNode extends FloatArithmeticNode implements Canonicalizable {
 
-    public FloatMulNode(Kind kind, ValueNode x, ValueNode y, boolean isStrictFP) {
-        super(kind, x, y, isStrictFP);
+    public FloatMulNode(Stamp stamp, ValueNode x, ValueNode y, boolean isStrictFP) {
+        super(stamp, x, y, isStrictFP);
     }
 
     public Constant evalConst(Constant... inputs) {
         assert inputs.length == 2;
-        if (kind() == Kind.Float) {
+        assert inputs[0].getKind() == inputs[1].getKind();
+        if (inputs[0].getKind() == Kind.Float) {
             return Constant.forFloat(inputs[0].asFloat() * inputs[1].asFloat());
         } else {
-            assert kind() == Kind.Double;
+            assert inputs[0].getKind() == Kind.Double;
             return Constant.forDouble(inputs[0].asDouble() * inputs[1].asDouble());
         }
     }
@@ -48,7 +50,7 @@
     @Override
     public Node canonical(CanonicalizerTool tool) {
         if (x().isConstant() && !y().isConstant()) {
-            return graph().unique(new FloatMulNode(kind(), y(), x(), isStrictFP()));
+            return graph().unique(new FloatMulNode(stamp(), y(), x(), isStrictFP()));
         }
         if (x().isConstant()) {
             return ConstantNode.forPrimitive(evalConst(x().asConstant(), y().asConstant()), graph());
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatRemNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatRemNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -27,20 +27,22 @@
 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 final class FloatRemNode extends FloatArithmeticNode implements Canonicalizable {
 
-    public FloatRemNode(Kind kind, ValueNode x, ValueNode y, boolean isStrictFP) {
-        super(kind, x, y, isStrictFP);
+    public FloatRemNode(Stamp stamp, ValueNode x, ValueNode y, boolean isStrictFP) {
+        super(stamp, x, y, isStrictFP);
     }
 
     public Constant evalConst(Constant... inputs) {
         assert inputs.length == 2;
-        if (kind() == Kind.Float) {
+        assert inputs[0].getKind() == inputs[1].getKind();
+        if (inputs[0].getKind() == Kind.Float) {
             return Constant.forFloat(inputs[0].asFloat() % inputs[1].asFloat());
         } else {
-            assert kind() == Kind.Double;
+            assert inputs[0].getKind() == Kind.Double;
             return Constant.forDouble(inputs[0].asDouble() % inputs[1].asDouble());
         }
     }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatSubNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatSubNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -27,20 +27,22 @@
 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 final class FloatSubNode extends FloatArithmeticNode implements Canonicalizable {
 
-    public FloatSubNode(Kind kind, ValueNode x, ValueNode y, boolean isStrictFP) {
-        super(kind, x, y, isStrictFP);
+    public FloatSubNode(Stamp stamp, ValueNode x, ValueNode y, boolean isStrictFP) {
+        super(stamp, x, y, isStrictFP);
     }
 
     public Constant evalConst(Constant... inputs) {
         assert inputs.length == 2;
-        if (kind() == Kind.Float) {
+        assert inputs[0].getKind() == inputs[1].getKind();
+        if (inputs[0].getKind() == Kind.Float) {
             return Constant.forFloat(inputs[0].asFloat() - inputs[1].asFloat());
         } else {
-            assert kind() == Kind.Double;
+            assert inputs[0].getKind() == Kind.Double;
             return Constant.forDouble(inputs[0].asDouble() - inputs[1].asDouble());
         }
     }
@@ -48,24 +50,25 @@
     @Override
     public Node canonical(CanonicalizerTool tool) {
         if (x() == y()) {
-            return ConstantNode.forFloatingKind(kind(), 0.0f, graph());
+            return ConstantNode.forFloatingStamp(stamp(), 0.0f, graph());
         }
         if (x().isConstant() && y().isConstant()) {
             return ConstantNode.forPrimitive(evalConst(x().asConstant(), y().asConstant()), graph());
         } else if (y().isConstant()) {
-            if (kind() == Kind.Float) {
-                float c = y().asConstant().asFloat();
-                if (c == 0.0f) {
+            Constant c = y().asConstant();
+            if (c.getKind() == Kind.Float) {
+                float f = c.asFloat();
+                if (f == 0.0f) {
                     return x();
                 }
-                return graph().unique(new FloatAddNode(kind(), x(), ConstantNode.forFloat(-c, graph()), isStrictFP()));
+                return graph().unique(new FloatAddNode(stamp(), x(), ConstantNode.forFloat(-f, graph()), isStrictFP()));
             } else {
-                assert kind() == Kind.Double;
-                double c = y().asConstant().asDouble();
-                if (c == 0.0) {
+                assert c.getKind() == Kind.Double;
+                double d = c.asDouble();
+                if (d == 0.0) {
                     return x();
                 }
-                return graph().unique(new FloatAddNode(kind(), x(), ConstantNode.forDouble(-c, graph()), isStrictFP()));
+                return graph().unique(new FloatAddNode(stamp(), x(), ConstantNode.forDouble(-d, graph()), isStrictFP()));
             }
         }
         return this;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerAddNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerAddNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -30,10 +30,10 @@
 import com.oracle.graal.nodes.type.*;
 
 @NodeInfo(shortName = "+")
-public class IntegerAddNode extends IntegerArithmeticNode implements Canonicalizable {
+public class IntegerAddNode extends IntegerArithmeticNode implements Canonicalizable, NarrowableArithmeticNode {
 
-    public IntegerAddNode(Kind kind, ValueNode x, ValueNode y) {
-        super(kind, x, y);
+    public IntegerAddNode(Stamp stamp, ValueNode x, ValueNode y) {
+        super(stamp, x, y);
     }
 
     @Override
@@ -44,13 +44,13 @@
     @Override
     public Constant evalConst(Constant... inputs) {
         assert inputs.length == 2;
-        return Constant.forIntegerKind(kind(), inputs[0].asLong() + inputs[1].asLong(), null);
+        return Constant.forPrimitiveInt(PrimitiveStamp.getBits(stamp()), inputs[0].asLong() + inputs[1].asLong());
     }
 
     @Override
     public Node canonical(CanonicalizerTool tool) {
         if (x().isConstant() && !y().isConstant()) {
-            return graph().unique(new IntegerAddNode(kind(), y(), x()));
+            return graph().unique(new IntegerAddNode(stamp(), y(), x()));
         }
         if (x() instanceof IntegerSubNode) {
             IntegerSubNode sub = (IntegerSubNode) x();
@@ -79,12 +79,7 @@
                 return reassociated;
             }
             if (c < 0) {
-                if (kind() == Kind.Int) {
-                    return IntegerArithmeticNode.sub(graph(), x(), ConstantNode.forInt((int) -c, graph()));
-                } else {
-                    assert kind() == Kind.Long;
-                    return IntegerArithmeticNode.sub(graph(), x(), ConstantNode.forLong(-c, graph()));
-                }
+                return IntegerArithmeticNode.sub(graph(), x(), ConstantNode.forIntegerStamp(stamp(), -c, graph()));
             }
         }
         if (x() instanceof NegateNode) {
@@ -95,24 +90,6 @@
         return this;
     }
 
-    public static boolean isIntegerAddition(ValueNode result, ValueNode a, ValueNode b) {
-        Kind kind = result.kind();
-        if (kind != a.kind() || kind != b.kind() || !kind.isNumericInteger()) {
-            return false;
-        }
-        if (result.isConstant() && a.isConstant() && b.isConstant()) {
-            if (kind.getStackKind() == Kind.Int) {
-                return result.asConstant().asInt() == a.asConstant().asInt() + b.asConstant().asInt();
-            } else if (kind == Kind.Long) {
-                return result.asConstant().asLong() == a.asConstant().asLong() + b.asConstant().asLong();
-            }
-        } else if (result instanceof IntegerAddNode) {
-            IntegerAddNode add = (IntegerAddNode) result;
-            return (add.x() == a && add.y() == b) || (add.y() == a && add.x() == b);
-        }
-        return false;
-    }
-
     @Override
     public void generate(ArithmeticLIRGenerator gen) {
         Value op1 = gen.operand(x());
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerArithmeticNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerArithmeticNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -22,50 +22,27 @@
  */
 package com.oracle.graal.nodes.calc;
 
-import com.oracle.graal.api.meta.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.nodes.type.*;
 
 public abstract class IntegerArithmeticNode extends BinaryNode implements ArithmeticLIRLowerable {
 
-    public IntegerArithmeticNode(Kind kind, ValueNode x, ValueNode y) {
-        super(kind, x, y);
-        assert kind.isNumericInteger();
+    public IntegerArithmeticNode(Stamp stamp, ValueNode x, ValueNode y) {
+        super(stamp, x, y);
+        assert stamp instanceof IntegerStamp;
     }
 
     public static IntegerAddNode add(StructuredGraph graph, ValueNode v1, ValueNode v2) {
-        assert v1.kind() == v2.kind();
-        switch (v1.kind()) {
-            case Int:
-                return graph.unique(new IntegerAddNode(Kind.Int, v1, v2));
-            case Long:
-                return graph.unique(new IntegerAddNode(Kind.Long, v1, v2));
-            default:
-                throw ValueNodeUtil.shouldNotReachHere();
-        }
+        return graph.unique(new IntegerAddNode(StampTool.add(v1.stamp(), v2.stamp()), v1, v2));
     }
 
     public static IntegerMulNode mul(StructuredGraph graph, ValueNode v1, ValueNode v2) {
-        assert v1.kind() == v2.kind();
-        switch (v1.kind()) {
-            case Int:
-                return graph.unique(new IntegerMulNode(Kind.Int, v1, v2));
-            case Long:
-                return graph.unique(new IntegerMulNode(Kind.Long, v1, v2));
-            default:
-                throw ValueNodeUtil.shouldNotReachHere();
-        }
+        assert v1.stamp().isCompatible(v2.stamp());
+        return graph.unique(new IntegerMulNode(v1.stamp().unrestricted(), v1, v2));
     }
 
     public static IntegerSubNode sub(StructuredGraph graph, ValueNode v1, ValueNode v2) {
-        assert v1.kind() == v2.kind();
-        switch (v1.kind()) {
-            case Int:
-                return graph.unique(new IntegerSubNode(Kind.Int, v1, v2));
-            case Long:
-                return graph.unique(new IntegerSubNode(Kind.Long, v1, v2));
-            default:
-                throw ValueNodeUtil.shouldNotReachHere();
-        }
+        return graph.unique(new IntegerSubNode(StampTool.sub(v1.stamp(), v2.stamp()), v1, v2));
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerConvertNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,103 @@
+/*
+ * 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.calc;
+
+import com.oracle.graal.api.meta.*;
+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.
+ */
+public abstract class IntegerConvertNode extends ConvertNode implements ArithmeticLIRLowerable {
+
+    private final int resultBits;
+
+    protected IntegerConvertNode(Stamp stamp, ValueNode input, int resultBits) {
+        super(stamp, input);
+        this.resultBits = resultBits;
+    }
+
+    public int getResultBits() {
+        return resultBits;
+    }
+
+    public int getInputBits() {
+        if (getInput().stamp() instanceof IntegerStamp) {
+            return ((IntegerStamp) getInput().stamp()).getBits();
+        } else {
+            return 0;
+        }
+    }
+
+    public static long convert(long value, int bits, boolean unsigned) {
+        if (unsigned) {
+            return ZeroExtendNode.zeroExtend(value, bits);
+        } else {
+            return SignExtendNode.signExtend(value, bits);
+        }
+    }
+
+    protected ValueNode canonicalConvert() {
+        if (getInput().stamp() instanceof IntegerStamp) {
+            int inputBits = ((IntegerStamp) getInput().stamp()).getBits();
+            if (inputBits == resultBits) {
+                return getInput();
+            } else if (getInput().isConstant()) {
+                Constant ret = evalConst(getInput().asConstant());
+                return ConstantNode.forIntegerBits(resultBits, false, ret.asLong(), graph());
+            }
+        }
+
+        return null;
+    }
+
+    public static ValueNode convert(ValueNode input, Stamp stamp) {
+        StructuredGraph graph = input.graph();
+        IntegerStamp fromStamp = (IntegerStamp) input.stamp();
+        IntegerStamp toStamp = (IntegerStamp) stamp;
+
+        ValueNode result;
+        if (toStamp.getBits() == fromStamp.getBits()) {
+            result = input;
+        } else if (toStamp.getBits() < fromStamp.getBits()) {
+            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()));
+            }
+        }
+
+        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));
+        }
+    }
+}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerDivNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerDivNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -23,7 +23,6 @@
 package com.oracle.graal.nodes.calc;
 
 import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.*;
@@ -33,8 +32,8 @@
 @NodeInfo(shortName = "/")
 public class IntegerDivNode extends FixedBinaryNode implements Canonicalizable, Lowerable, LIRLowerable {
 
-    public IntegerDivNode(Kind kind, ValueNode x, ValueNode y) {
-        super(kind, x, y);
+    public IntegerDivNode(Stamp stamp, ValueNode x, ValueNode y) {
+        super(stamp, x, y);
     }
 
     @Override
@@ -45,16 +44,11 @@
     @Override
     public Node canonical(CanonicalizerTool tool) {
         if (x().isConstant() && y().isConstant()) {
-            long yConst = y().asConstant().asLong();
-            if (yConst == 0) {
+            long y = y().asConstant().asLong();
+            if (y == 0) {
                 return this; // this will trap, can not canonicalize
             }
-            if (kind() == Kind.Int) {
-                return ConstantNode.forInt(x().asConstant().asInt() / (int) yConst, graph());
-            } else {
-                assert kind() == Kind.Long;
-                return ConstantNode.forLong(x().asConstant().asLong() / yConst, graph());
-            }
+            return ConstantNode.forIntegerStamp(stamp(), x().asConstant().asLong() / y, graph());
         } else if (y().isConstant()) {
             long c = y().asConstant().asLong();
             if (c == 1) {
@@ -65,23 +59,18 @@
             }
             long abs = Math.abs(c);
             if (CodeUtil.isPowerOf2(abs) && x().stamp() instanceof IntegerStamp) {
+                Stamp unrestricted = stamp().unrestricted();
                 ValueNode dividend = x();
                 IntegerStamp stampX = (IntegerStamp) x().stamp();
                 int log2 = CodeUtil.log2(abs);
                 // no rounding if dividend is positive or if its low bits are always 0
                 if (stampX.canBeNegative() || (stampX.upMask() & (abs - 1)) != 0) {
-                    int bits;
-                    if (kind().getStackKind() == Kind.Int) {
-                        bits = 32;
-                    } else {
-                        assert kind() == Kind.Long;
-                        bits = 64;
-                    }
-                    RightShiftNode sign = graph().unique(new RightShiftNode(kind(), x(), ConstantNode.forInt(bits - 1, graph())));
-                    UnsignedRightShiftNode round = graph().unique(new UnsignedRightShiftNode(kind(), sign, ConstantNode.forInt(bits - log2, graph())));
+                    int bits = PrimitiveStamp.getBits(stamp());
+                    RightShiftNode sign = graph().unique(new RightShiftNode(unrestricted, x(), ConstantNode.forInt(bits - 1, graph())));
+                    UnsignedRightShiftNode round = graph().unique(new UnsignedRightShiftNode(unrestricted, sign, ConstantNode.forInt(bits - log2, graph())));
                     dividend = IntegerArithmeticNode.add(graph(), dividend, round);
                 }
-                RightShiftNode shift = graph().unique(new RightShiftNode(kind(), dividend, ConstantNode.forInt(log2, graph())));
+                RightShiftNode shift = graph().unique(new RightShiftNode(unrestricted, dividend, ConstantNode.forInt(log2, graph())));
                 if (c < 0) {
                     return graph().unique(new NegateNode(shift));
                 }
@@ -94,8 +83,9 @@
             IntegerSubNode integerSubNode = (IntegerSubNode) x();
             if (integerSubNode.y() instanceof IntegerRemNode) {
                 IntegerRemNode integerRemNode = (IntegerRemNode) integerSubNode.y();
-                if (integerSubNode.kind() == this.kind() && integerRemNode.kind() == this.kind() && integerSubNode.x() == integerRemNode.x() && this.y() == integerRemNode.y()) {
-                    return graph().add(new IntegerDivNode(kind(), integerSubNode.x(), this.y()));
+                if (integerSubNode.stamp().isCompatible(this.stamp()) && integerRemNode.stamp().isCompatible(this.stamp()) && integerSubNode.x() == integerRemNode.x() &&
+                                this.y() == integerRemNode.y()) {
+                    return graph().add(new IntegerDivNode(stamp(), integerSubNode.x(), this.y()));
                 }
             }
         }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerMulNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerMulNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -28,24 +28,25 @@
 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 IntegerMulNode extends IntegerArithmeticNode implements Canonicalizable {
+public class IntegerMulNode extends IntegerArithmeticNode implements Canonicalizable, NarrowableArithmeticNode {
 
-    public IntegerMulNode(Kind kind, ValueNode x, ValueNode y) {
-        super(kind, x, y);
+    public IntegerMulNode(Stamp stamp, ValueNode x, ValueNode y) {
+        super(stamp, x, y);
     }
 
     @Override
     public Constant evalConst(Constant... inputs) {
         assert inputs.length == 2;
-        return Constant.forIntegerKind(kind(), inputs[0].asLong() * inputs[1].asLong(), null);
+        return Constant.forPrimitiveInt(PrimitiveStamp.getBits(stamp()), inputs[0].asLong() * inputs[1].asLong());
     }
 
     @Override
     public Node canonical(CanonicalizerTool tool) {
         if (x().isConstant() && !y().isConstant()) {
-            return graph().unique(new IntegerMulNode(kind(), y(), x()));
+            return graph().unique(new IntegerMulNode(stamp(), y(), x()));
         }
         if (x().isConstant()) {
             return ConstantNode.forPrimitive(evalConst(x().asConstant(), y().asConstant()), graph());
@@ -55,11 +56,11 @@
                 return x();
             }
             if (c == 0) {
-                return ConstantNode.defaultForKind(kind(), graph());
+                return ConstantNode.forIntegerStamp(stamp(), 0, graph());
             }
             long abs = Math.abs(c);
             if (abs > 0 && CodeUtil.isPowerOf2(abs)) {
-                LeftShiftNode shift = graph().unique(new LeftShiftNode(kind(), x(), ConstantNode.forInt(CodeUtil.log2(abs), graph())));
+                LeftShiftNode shift = graph().unique(new LeftShiftNode(stamp().unrestricted(), x(), ConstantNode.forInt(CodeUtil.log2(abs), graph())));
                 if (c < 0) {
                     return graph().unique(new NegateNode(shift));
                 } else {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerRemNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerRemNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -23,7 +23,6 @@
 package com.oracle.graal.nodes.calc;
 
 import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.*;
@@ -33,29 +32,24 @@
 @NodeInfo(shortName = "%")
 public class IntegerRemNode extends FixedBinaryNode implements Canonicalizable, Lowerable, LIRLowerable {
 
-    public IntegerRemNode(Kind kind, ValueNode x, ValueNode y) {
-        super(kind, x, y);
+    public IntegerRemNode(Stamp stamp, ValueNode x, ValueNode y) {
+        super(stamp, x, y);
     }
 
     @Override
     public Node canonical(CanonicalizerTool tool) {
         if (x().isConstant() && y().isConstant()) {
-            long yConst = y().asConstant().asLong();
-            if (yConst == 0) {
+            long y = y().asConstant().asLong();
+            if (y == 0) {
                 return this; // this will trap, can not canonicalize
             }
-            if (kind() == Kind.Int) {
-                return ConstantNode.forInt(x().asConstant().asInt() % (int) yConst, graph());
-            } else {
-                assert kind() == Kind.Long;
-                return ConstantNode.forLong(x().asConstant().asLong() % yConst, graph());
-            }
+            return ConstantNode.forIntegerStamp(stamp(), x().asConstant().asLong() % y, graph());
         } else if (y().isConstant()) {
             long c = y().asConstant().asLong();
             if (c == 1 || c == -1) {
-                return ConstantNode.forIntegerKind(kind(), 0, graph());
+                return ConstantNode.forIntegerStamp(stamp(), 0, graph());
             } else if (c > 0 && CodeUtil.isPowerOf2(c) && x().stamp() instanceof IntegerStamp && ((IntegerStamp) x().stamp()).isPositive()) {
-                return graph().unique(new AndNode(kind(), x(), ConstantNode.forIntegerKind(kind(), c - 1, graph())));
+                return graph().unique(new AndNode(stamp(), x(), ConstantNode.forIntegerStamp(stamp(), c - 1, graph())));
             }
         }
         return this;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerSubNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerSubNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -30,10 +30,10 @@
 import com.oracle.graal.nodes.type.*;
 
 @NodeInfo(shortName = "-")
-public class IntegerSubNode extends IntegerArithmeticNode implements Canonicalizable {
+public class IntegerSubNode extends IntegerArithmeticNode implements Canonicalizable, NarrowableArithmeticNode {
 
-    public IntegerSubNode(Kind kind, ValueNode x, ValueNode y) {
-        super(kind, x, y);
+    public IntegerSubNode(Stamp stamp, ValueNode x, ValueNode y) {
+        super(stamp, x, y);
     }
 
     @Override
@@ -44,13 +44,13 @@
     @Override
     public Constant evalConst(Constant... inputs) {
         assert inputs.length == 2;
-        return Constant.forIntegerKind(kind(), inputs[0].asLong() - inputs[1].asLong(), null);
+        return Constant.forPrimitiveInt(PrimitiveStamp.getBits(stamp()), inputs[0].asLong() - inputs[1].asLong());
     }
 
     @Override
     public Node canonical(CanonicalizerTool tool) {
         if (x() == y()) {
-            return ConstantNode.forIntegerKind(kind(), 0, graph());
+            return ConstantNode.forIntegerStamp(stamp(), 0, graph());
         }
         if (x() instanceof IntegerAddNode) {
             IntegerAddNode x = (IntegerAddNode) x();
@@ -98,12 +98,7 @@
                 return reassociated;
             }
             if (c < 0) {
-                if (kind() == Kind.Int) {
-                    return IntegerArithmeticNode.add(graph(), x(), ConstantNode.forInt((int) -c, graph()));
-                } else {
-                    assert kind() == Kind.Long;
-                    return IntegerArithmeticNode.add(graph(), x(), ConstantNode.forLong(-c, graph()));
-                }
+                return IntegerArithmeticNode.add(graph(), x(), ConstantNode.forIntegerStamp(stamp(), -c, graph()));
             }
         } else if (x().isConstant()) {
             long c = x().asConstant().asLong();
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerTestNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerTestNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -53,7 +53,7 @@
      * @param y the instruction that produces the second input to this instruction
      */
     public IntegerTestNode(ValueNode x, ValueNode y) {
-        assert (x == null && y == null) || x.kind() == y.kind();
+        assert (x == null && y == null) || x.stamp().isCompatible(y.stamp());
         this.x = x;
         this.y = y;
     }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/LeftShiftNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/LeftShiftNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -32,8 +32,8 @@
 @NodeInfo(shortName = "<<")
 public final class LeftShiftNode extends ShiftNode implements Canonicalizable {
 
-    public LeftShiftNode(Kind kind, ValueNode x, ValueNode y) {
-        super(kind, x, y);
+    public LeftShiftNode(Stamp stamp, ValueNode x, ValueNode y) {
+        super(stamp, x, y);
     }
 
     @Override
@@ -79,19 +79,19 @@
                         if (total != (total & mask)) {
                             return ConstantNode.forIntegerKind(kind(), 0, graph());
                         }
-                        return graph().unique(new LeftShiftNode(kind(), other.x(), ConstantNode.forInt(total, graph())));
+                        return graph().unique(new LeftShiftNode(stamp(), other.x(), ConstantNode.forInt(total, graph())));
                     } else if ((other instanceof RightShiftNode || other instanceof UnsignedRightShiftNode) && otherAmount == amount) {
                         if (kind() == Kind.Long) {
-                            return graph().unique(new AndNode(kind(), other.x(), ConstantNode.forLong(-1L << amount, graph())));
+                            return graph().unique(new AndNode(stamp(), other.x(), ConstantNode.forLong(-1L << amount, graph())));
                         } else {
                             assert kind() == Kind.Int;
-                            return graph().unique(new AndNode(kind(), other.x(), ConstantNode.forInt(-1 << amount, graph())));
+                            return graph().unique(new AndNode(stamp(), other.x(), ConstantNode.forInt(-1 << amount, graph())));
                         }
                     }
                 }
             }
             if (originalAmout != amount) {
-                return graph().unique(new LeftShiftNode(kind(), x(), ConstantNode.forInt(amount, graph())));
+                return graph().unique(new LeftShiftNode(stamp(), x(), ConstantNode.forInt(amount, graph())));
             }
         }
         return this;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NarrowNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,142 @@
+/*
+ * 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.calc;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.nodes.type.*;
+
+/**
+ * The {@code NarrowNode} converts an integer to a narrower integer.
+ */
+public class NarrowNode extends IntegerConvertNode implements Simplifiable {
+
+    public NarrowNode(ValueNode input, int resultBits) {
+        super(StampTool.narrowingConversion(input.stamp(), resultBits), input, resultBits);
+    }
+
+    public static long narrow(long value, int resultBits) {
+        return value & IntegerStamp.defaultMask(resultBits);
+    }
+
+    @Override
+    public Constant convert(Constant c) {
+        return Constant.forPrimitiveInt(getResultBits(), narrow(c.asLong(), getResultBits()));
+    }
+
+    @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());
+        }
+        return Constant.forPrimitiveInt(getInputBits(), result);
+    }
+
+    @Override
+    public boolean isLossless() {
+        return false;
+    }
+
+    private ValueNode tryCanonicalize() {
+        ValueNode ret = canonicalConvert();
+        if (ret != null) {
+            return ret;
+        }
+
+        if (getInput() instanceof NarrowNode) {
+            // zzzzzzzz yyyyxxxx -(narrow)-> yyyyxxxx -(narrow)-> xxxx
+            // ==> zzzzzzzz yyyyxxxx -(narrow)-> xxxx
+            NarrowNode other = (NarrowNode) getInput();
+            return graph().unique(new NarrowNode(other.getInput(), getResultBits()));
+        } else if (getInput() instanceof IntegerConvertNode) {
+            // SignExtendNode or ZeroExtendNode
+            IntegerConvertNode other = (IntegerConvertNode) getInput();
+            if (getResultBits() == other.getInputBits()) {
+                // xxxx -(extend)-> yyyy xxxx -(narrow)-> xxxx
+                // ==> no-op
+                return other.getInput();
+            } else if (getResultBits() < other.getInputBits()) {
+                // yyyyxxxx -(extend)-> zzzzzzzz yyyyxxxx -(narrow)-> xxxx
+                // ==> yyyyxxxx -(narrow)-> xxxx
+                return graph().unique(new NarrowNode(other.getInput(), getResultBits()));
+            } else {
+                if (other instanceof SignExtendNode) {
+                    // sxxx -(sign-extend)-> ssssssss sssssxxx -(narrow)-> sssssxxx
+                    // ==> sxxx -(sign-extend)-> sssssxxx
+                    return graph().unique(new SignExtendNode(other.getInput(), getResultBits()));
+                } else if (other instanceof ZeroExtendNode) {
+                    // xxxx -(zero-extend)-> 00000000 00000xxx -(narrow)-> 0000xxxx
+                    // ==> xxxx -(zero-extend)-> 0000xxxx
+                    return graph().unique(new ZeroExtendNode(other.getInput(), getResultBits()));
+                }
+            }
+        }
+
+        return null;
+    }
+
+    private boolean tryNarrow(SimplifierTool tool, Stamp stamp, ValueNode node) {
+        boolean canNarrow = node instanceof NarrowableArithmeticNode && node.usages().count() == 1;
+
+        if (canNarrow) {
+            for (Node inputNode : node.inputs().snapshot()) {
+                ValueNode input = (ValueNode) inputNode;
+                if (!tryNarrow(tool, stamp, input)) {
+                    ValueNode narrow = graph().unique(new NarrowNode(input, getResultBits()));
+                    node.replaceFirstInput(input, narrow);
+                    tool.addToWorkList(narrow);
+                }
+            }
+            node.setStamp(stamp);
+        }
+
+        return canNarrow;
+    }
+
+    @Override
+    public void simplify(SimplifierTool tool) {
+        ValueNode ret = tryCanonicalize();
+        if (ret != null) {
+            graph().replaceFloating(this, ret);
+        } else if (tryNarrow(tool, stamp().unrestricted(), getInput())) {
+            graph().replaceFloating(this, getInput());
+        }
+    }
+
+    @Override
+    public boolean inferStamp() {
+        return updateStamp(StampTool.narrowingConversion(getInput().stamp(), getResultBits()));
+    }
+
+    @Override
+    public void generate(ArithmeticLIRGenerator gen) {
+        gen.setResult(this, gen.emitNarrow(gen.operand(getInput()), getResultBits()));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NarrowableArithmeticNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,31 @@
+/*
+ * 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.calc;
+
+/**
+ * Marker interface for nodes where it is valid to apply a {@link NarrowNode} to its inputs and do a
+ * narrow operation instead of doing the wide operation and applying the {@link NarrowNode} to the
+ * result.
+ */
+public interface NarrowableArithmeticNode {
+}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NegateNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NegateNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -32,7 +32,7 @@
 /**
  * The {@code NegateNode} node negates its operand.
  */
-public final class NegateNode extends FloatingNode implements Canonicalizable, ArithmeticLIRLowerable {
+public final class NegateNode extends FloatingNode implements Canonicalizable, ArithmeticLIRLowerable, NarrowableArithmeticNode {
 
     @Input private ValueNode x;
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NormalizeCompareNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NormalizeCompareNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -25,6 +25,7 @@
 import com.oracle.graal.api.meta.*;
 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 of the
@@ -43,7 +44,7 @@
      *            less, false when greater.
      */
     public NormalizeCompareNode(ValueNode x, ValueNode y, boolean isUnorderedLess) {
-        super(Kind.Int, x, y);
+        super(StampFactory.forKind(Kind.Int), x, y);
         this.isUnorderedLess = isUnorderedLess;
     }
 
@@ -51,7 +52,7 @@
     public void lower(LoweringTool tool) {
         LogicNode equalComp;
         LogicNode lessComp;
-        if (x().kind() == Kind.Double || x().kind() == Kind.Float) {
+        if (x().stamp() instanceof FloatStamp) {
             equalComp = graph().unique(new FloatEqualsNode(x(), y()));
             lessComp = graph().unique(new FloatLessThanNode(x(), y(), isUnorderedLess));
         } else {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NotNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NotNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -32,7 +32,7 @@
 /**
  * Binary negation of long or integer values.
  */
-public final class NotNode extends FloatingNode implements Canonicalizable, ArithmeticLIRLowerable {
+public final class NotNode extends FloatingNode implements Canonicalizable, ArithmeticLIRLowerable, NarrowableArithmeticNode {
 
     @Input private ValueNode x;
 
@@ -48,7 +48,7 @@
     @Override
     public Constant evalConst(Constant... inputs) {
         assert inputs.length == 1;
-        return Constant.forIntegerKind(kind(), ~inputs[0].asLong(), null);
+        return Constant.forPrimitiveInt(PrimitiveStamp.getBits(stamp()), ~inputs[0].asLong());
     }
 
     /**
@@ -58,7 +58,6 @@
      */
     public NotNode(ValueNode x) {
         super(StampTool.not(x.stamp()));
-        assert x.kind() == Kind.Int || x.kind() == Kind.Long;
         this.x = x;
     }
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/OrNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/OrNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -32,8 +32,8 @@
 @NodeInfo(shortName = "|")
 public final class OrNode extends BitLogicNode implements Canonicalizable {
 
-    public OrNode(Kind kind, ValueNode x, ValueNode y) {
-        super(kind, x, y);
+    public OrNode(Stamp stamp, ValueNode x, ValueNode y) {
+        super(stamp, x, y);
     }
 
     @Override
@@ -44,7 +44,7 @@
     @Override
     public Constant evalConst(Constant... inputs) {
         assert inputs.length == 2;
-        return Constant.forIntegerKind(kind(), inputs[0].asLong() | inputs[1].asLong(), null);
+        return Constant.forPrimitiveInt(PrimitiveStamp.getBits(stamp()), inputs[0].asLong() | inputs[1].asLong());
     }
 
     @Override
@@ -53,28 +53,18 @@
             return x();
         }
         if (x().isConstant() && !y().isConstant()) {
-            return graph().unique(new OrNode(kind(), y(), x()));
+            return graph().unique(new OrNode(stamp(), y(), x()));
         }
         if (x().isConstant()) {
-            return ConstantNode.forPrimitive(evalConst(x().asConstant(), y().asConstant()), graph());
+            return ConstantNode.forPrimitive(stamp(), evalConst(x().asConstant(), y().asConstant()), graph());
         } else if (y().isConstant()) {
-            if (kind() == Kind.Int) {
-                int c = y().asConstant().asInt();
-                if (c == -1) {
-                    return ConstantNode.forInt(-1, graph());
-                }
-                if (c == 0) {
-                    return x();
-                }
-            } else {
-                assert kind() == Kind.Long;
-                long c = y().asConstant().asLong();
-                if (c == -1) {
-                    return ConstantNode.forLong(-1, graph());
-                }
-                if (c == 0) {
-                    return x();
-                }
+            long rawY = y().asConstant().asLong();
+            long mask = IntegerStamp.defaultMask(PrimitiveStamp.getBits(stamp()));
+            if ((rawY & mask) == mask) {
+                return ConstantNode.forIntegerStamp(stamp(), mask, graph());
+            }
+            if ((rawY & mask) == 0) {
+                return x();
             }
             return BinaryNode.reassociate(this, ValueNode.isConstantPredicate());
         }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ReinterpretNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ReinterpretNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -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
@@ -30,7 +30,9 @@
 import com.oracle.graal.nodes.type.*;
 
 /**
- * The {@code ReinterpretNode} class represents a reinterpreting conversion between primitive types.
+ * The {@code ReinterpretNode} class represents a reinterpreting conversion that changes the stamp
+ * of a primitive value to some other incompatible stamp. The new stamp must have the same width as
+ * the old stamp.
  */
 public class ReinterpretNode extends FloatingNode implements Canonicalizable, ArithmeticLIRLowerable {
 
@@ -40,64 +42,45 @@
         return value;
     }
 
-    public ReinterpretNode(Kind to, ValueNode value) {
-        super(StampFactory.forKind(to.getStackKind()));
+    private ReinterpretNode(Kind to, ValueNode value) {
+        this(StampFactory.forKind(to), value);
+    }
+
+    public ReinterpretNode(Stamp to, ValueNode value) {
+        super(to);
+        assert to instanceof PrimitiveStamp;
         this.value = value;
     }
 
     public Constant evalConst(Constant... inputs) {
         assert inputs.length == 1;
         Constant c = inputs[0];
-        assert c.getKind() == value.kind();
+        assert c.getKind().getBitCount() == ((PrimitiveStamp) stamp()).getBits();
         switch (c.getKind()) {
             case Int:
-                switch (kind()) {
-                    case Int:
-                        return c;
-                    case Long:
-                        return Constant.forLong(c.asInt() & 0xFFFFFFFFL);
-                    case Float:
-                        return Constant.forFloat(Float.intBitsToFloat(c.asInt()));
-                    case Double:
-                        return Constant.forDouble(Double.longBitsToDouble(c.asInt() & 0xFFFFFFFFL));
+                if (stamp() instanceof FloatStamp) {
+                    return Constant.forFloat(Float.intBitsToFloat(c.asInt()));
+                } else {
+                    return c;
                 }
-                break;
             case Long:
-                switch (kind()) {
-                    case Int:
-                        return Constant.forInt((int) c.asLong());
-                    case Long:
-                        return c;
-                    case Float:
-                        return Constant.forFloat(Float.intBitsToFloat((int) c.asLong()));
-                    case Double:
-                        return Constant.forDouble(Double.longBitsToDouble(c.asLong()));
+                if (stamp() instanceof FloatStamp) {
+                    return Constant.forDouble(Double.longBitsToDouble(c.asLong()));
+                } else {
+                    return c;
                 }
-                break;
             case Float:
-                switch (kind()) {
-                    case Int:
-                        return Constant.forInt(Float.floatToRawIntBits(c.asFloat()));
-                    case Long:
-                        return Constant.forLong(Float.floatToRawIntBits(c.asFloat()) & 0xFFFFFFFFL);
-                    case Float:
-                        return c;
-                    case Double:
-                        return Constant.forDouble(Double.longBitsToDouble(Float.floatToRawIntBits(c.asFloat()) & 0xFFFFFFFFL));
+                if (stamp() instanceof IntegerStamp) {
+                    return Constant.forInt(Float.floatToRawIntBits(c.asFloat()));
+                } else {
+                    return c;
                 }
-                break;
             case Double:
-                switch (kind()) {
-                    case Int:
-                        return Constant.forInt((int) Double.doubleToRawLongBits(c.asDouble()));
-                    case Long:
-                        return Constant.forLong(Double.doubleToRawLongBits(c.asDouble()));
-                    case Float:
-                        return Constant.forFloat(Float.intBitsToFloat((int) Double.doubleToRawLongBits(c.asDouble())));
-                    case Double:
-                        return c;
+                if (stamp() instanceof IntegerStamp) {
+                    return Constant.forLong(Double.doubleToRawLongBits(c.asDouble()));
+                } else {
+                    return c;
                 }
-                break;
         }
         throw GraalInternalError.shouldNotReachHere();
     }
@@ -107,19 +90,19 @@
         if (value.isConstant()) {
             return ConstantNode.forPrimitive(evalConst(value.asConstant()), graph());
         }
+        if (stamp().isCompatible(value.stamp())) {
+            return value;
+        }
         return this;
     }
 
     @Override
     public void generate(ArithmeticLIRGenerator gen) {
-        gen.setResult(this, gen.emitReinterpret(kind(), gen.operand(value())));
+        PlatformKind kind = gen.getPlatformKind(stamp());
+        gen.setResult(this, gen.emitReinterpret(kind, gen.operand(value())));
     }
 
     public static ValueNode reinterpret(Kind toKind, ValueNode value) {
-        Kind fromKind = value.kind();
-        if (fromKind == toKind) {
-            return value;
-        }
         return value.graph().unique(new ReinterpretNode(toKind, value));
     }
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/RightShiftNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/RightShiftNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -32,8 +32,8 @@
 @NodeInfo(shortName = ">>")
 public final class RightShiftNode extends ShiftNode implements Canonicalizable {
 
-    public RightShiftNode(Kind kind, ValueNode x, ValueNode y) {
-        super(kind, x, y);
+    public RightShiftNode(Stamp stamp, ValueNode x, ValueNode y) {
+        super(stamp, x, y);
     }
 
     @Override
@@ -50,7 +50,7 @@
     @Override
     public Node canonical(CanonicalizerTool tool) {
         if (x().stamp() instanceof IntegerStamp && ((IntegerStamp) x().stamp()).isPositive()) {
-            return graph().unique(new UnsignedRightShiftNode(kind(), x(), y()));
+            return graph().unique(new UnsignedRightShiftNode(stamp(), x(), y()));
         }
         if (x().isConstant() && y().isConstant()) {
             return ConstantNode.forPrimitive(evalConst(x().asConstant(), y().asConstant()), graph());
@@ -90,14 +90,14 @@
                              * full shift for this kind
                              */
                             assert total >= mask;
-                            return graph().unique(new RightShiftNode(kind(), other.x(), ConstantNode.forInt(mask, graph())));
+                            return graph().unique(new RightShiftNode(stamp(), other.x(), ConstantNode.forInt(mask, graph())));
                         }
-                        return graph().unique(new RightShiftNode(kind(), other.x(), ConstantNode.forInt(total, graph())));
+                        return graph().unique(new RightShiftNode(stamp(), other.x(), ConstantNode.forInt(total, graph())));
                     }
                 }
             }
             if (originalAmout != amount) {
-                return graph().unique(new RightShiftNode(kind(), x(), ConstantNode.forInt(amount, graph())));
+                return graph().unique(new RightShiftNode(stamp(), x(), ConstantNode.forInt(amount, graph())));
             }
         }
         return this;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ShiftNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ShiftNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -22,9 +22,9 @@
  */
 package com.oracle.graal.nodes.calc;
 
-import com.oracle.graal.api.meta.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.nodes.type.*;
 
 /**
  * The {@code ShiftOp} class represents shift operations.
@@ -37,7 +37,7 @@
      * @param x the first input value
      * @param s the second input value
      */
-    public ShiftNode(Kind kind, ValueNode x, ValueNode s) {
-        super(kind, x, s);
+    public ShiftNode(Stamp stamp, ValueNode x, ValueNode s) {
+        super(stamp, x, s);
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/SignExtendNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -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.nodes.calc;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.nodes.type.*;
+
+/**
+ * The {@code SignExtendNode} converts an integer to a wider integer using sign extension.
+ */
+public class SignExtendNode extends IntegerConvertNode implements Canonicalizable {
+
+    public SignExtendNode(ValueNode input, int resultBits) {
+        super(StampTool.signExtend(input.stamp(), resultBits), input, resultBits);
+    }
+
+    public static long signExtend(long value, int inputBits) {
+        if (inputBits < 64) {
+            if ((value >>> (inputBits - 1) & 1) == 1) {
+                return value | (-1L << inputBits);
+            } else {
+                return value & ~(-1L << inputBits);
+            }
+        } else {
+            return value;
+        }
+    }
+
+    @Override
+    public Constant convert(Constant c) {
+        return Constant.forPrimitiveInt(getResultBits(), signExtend(c.asLong(), getInputBits()));
+    }
+
+    @Override
+    public Constant reverse(Constant c) {
+        return Constant.forPrimitiveInt(getInputBits(), NarrowNode.narrow(c.asLong(), getInputBits()));
+    }
+
+    @Override
+    public boolean isLossless() {
+        return true;
+    }
+
+    @Override
+    public Node canonical(CanonicalizerTool tool) {
+        ValueNode ret = canonicalConvert();
+        if (ret != null) {
+            return ret;
+        }
+
+        if (getInput() instanceof SignExtendNode) {
+            // sxxx -(sign-extend)-> ssss sxxx -(sign-extend)-> ssssssss sssssxxx
+            // ==> sxxx -(sign-extend)-> ssssssss sssssxxx
+            SignExtendNode other = (SignExtendNode) getInput();
+            return graph().unique(new SignExtendNode(other.getInput(), getResultBits()));
+        } else if (getInput() instanceof ZeroExtendNode) {
+            ZeroExtendNode other = (ZeroExtendNode) getInput();
+            if (other.getResultBits() > other.getInputBits()) {
+                // sxxx -(zero-extend)-> 0000 sxxx -(sign-extend)-> 00000000 0000sxxx
+                // ==> sxxx -(zero-extend)-> 00000000 0000sxxx
+                return graph().unique(new ZeroExtendNode(other.getInput(), getResultBits()));
+            }
+        }
+
+        if (getInput().stamp() instanceof IntegerStamp) {
+            IntegerStamp inputStamp = (IntegerStamp) getInput().stamp();
+            if ((inputStamp.upMask() & (1L << (getInputBits() - 1))) == 0L) {
+                // 0xxx -(sign-extend)-> 0000 0xxx
+                // ==> 0xxx -(zero-extend)-> 0000 0xxx
+                return graph().unique(new ZeroExtendNode(getInput(), getResultBits()));
+            }
+        }
+
+        return this;
+    }
+
+    @Override
+    public boolean inferStamp() {
+        return updateStamp(StampTool.signExtend(getInput().stamp(), getResultBits()));
+    }
+
+    @Override
+    public void generate(ArithmeticLIRGenerator gen) {
+        gen.setResult(this, gen.emitSignExtend(gen.operand(getInput()), getInputBits(), getResultBits()));
+    }
+}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedDivNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedDivNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -33,8 +33,16 @@
 @NodeInfo(shortName = "|/|")
 public class UnsignedDivNode extends FixedBinaryNode implements Canonicalizable, Lowerable, LIRLowerable {
 
-    public UnsignedDivNode(Kind kind, ValueNode x, ValueNode y) {
-        super(kind, x, y);
+    /**
+     * Used by {@code NodeIntrinsic} in {@code UnsignedMathSubstitutions}.
+     */
+    @SuppressWarnings("unused")
+    private UnsignedDivNode(Kind kind, ValueNode x, ValueNode y) {
+        this(StampFactory.forKind(kind), x, y);
+    }
+
+    public UnsignedDivNode(Stamp stamp, ValueNode x, ValueNode y) {
+        super(stamp, x, y);
     }
 
     @Override
@@ -44,19 +52,14 @@
             if (yConst == 0) {
                 return this; // this will trap, cannot canonicalize
             }
-            if (kind() == Kind.Int) {
-                return ConstantNode.forInt(UnsignedMath.divide(x().asConstant().asInt(), (int) yConst), graph());
-            } else {
-                assert kind() == Kind.Long;
-                return ConstantNode.forLong(UnsignedMath.divide(x().asConstant().asLong(), yConst), graph());
-            }
+            return ConstantNode.forIntegerStamp(stamp(), UnsignedMath.divide(x().asConstant().asLong(), yConst), graph());
         } else if (y().isConstant()) {
             long c = y().asConstant().asLong();
             if (c == 1) {
                 return x();
             }
             if (CodeUtil.isPowerOf2(c)) {
-                return graph().unique(new UnsignedRightShiftNode(kind(), x(), ConstantNode.forInt(CodeUtil.log2(c), graph())));
+                return graph().unique(new UnsignedRightShiftNode(stamp(), x(), ConstantNode.forInt(CodeUtil.log2(c), graph())));
             }
         }
         return this;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedRemNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedRemNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -33,8 +33,16 @@
 @NodeInfo(shortName = "|%|")
 public class UnsignedRemNode extends FixedBinaryNode implements Canonicalizable, Lowerable, LIRLowerable {
 
-    public UnsignedRemNode(Kind kind, ValueNode x, ValueNode y) {
-        super(kind, x, y);
+    /**
+     * Used by {@code NodeIntrinsic} in {@code UnsignedMathSubstitutions}.
+     */
+    @SuppressWarnings("unused")
+    private UnsignedRemNode(Kind kind, ValueNode x, ValueNode y) {
+        this(StampFactory.forKind(kind), x, y);
+    }
+
+    public UnsignedRemNode(Stamp stamp, ValueNode x, ValueNode y) {
+        super(stamp, x, y);
     }
 
     @Override
@@ -44,18 +52,13 @@
             if (yConst == 0) {
                 return this; // this will trap, cannot canonicalize
             }
-            if (kind() == Kind.Int) {
-                return ConstantNode.forInt(UnsignedMath.remainder(x().asConstant().asInt(), (int) yConst), graph());
-            } else {
-                assert kind() == Kind.Long;
-                return ConstantNode.forLong(UnsignedMath.remainder(x().asConstant().asLong(), yConst), graph());
-            }
+            return ConstantNode.forIntegerStamp(stamp(), UnsignedMath.remainder(x().asConstant().asLong(), yConst), graph());
         } else if (y().isConstant()) {
             long c = y().asConstant().asLong();
             if (c == 1) {
-                return ConstantNode.forIntegerKind(kind(), 0, graph());
+                return ConstantNode.forIntegerStamp(stamp(), 0, graph());
             } else if (CodeUtil.isPowerOf2(c)) {
-                return graph().unique(new AndNode(kind(), x(), ConstantNode.forIntegerKind(kind(), c - 1, graph())));
+                return graph().unique(new AndNode(stamp(), x(), ConstantNode.forIntegerStamp(stamp(), c - 1, graph())));
             }
         }
         return this;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedRightShiftNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedRightShiftNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -32,8 +32,8 @@
 @NodeInfo(shortName = ">>>")
 public final class UnsignedRightShiftNode extends ShiftNode implements Canonicalizable {
 
-    public UnsignedRightShiftNode(Kind kind, ValueNode x, ValueNode y) {
-        super(kind, x, y);
+    public UnsignedRightShiftNode(Stamp stamp, ValueNode x, ValueNode y) {
+        super(stamp, x, y);
     }
 
     @Override
@@ -79,19 +79,19 @@
                         if (total != (total & mask)) {
                             return ConstantNode.forIntegerKind(kind(), 0, graph());
                         }
-                        return graph().unique(new UnsignedRightShiftNode(kind(), other.x(), ConstantNode.forInt(total, graph())));
+                        return graph().unique(new UnsignedRightShiftNode(stamp(), other.x(), ConstantNode.forInt(total, graph())));
                     } else if (other instanceof LeftShiftNode && otherAmount == amount) {
                         if (kind() == Kind.Long) {
-                            return graph().unique(new AndNode(kind(), other.x(), ConstantNode.forLong(-1L >>> amount, graph())));
+                            return graph().unique(new AndNode(stamp(), other.x(), ConstantNode.forLong(-1L >>> amount, graph())));
                         } else {
                             assert kind() == Kind.Int;
-                            return graph().unique(new AndNode(kind(), other.x(), ConstantNode.forInt(-1 >>> amount, graph())));
+                            return graph().unique(new AndNode(stamp(), other.x(), ConstantNode.forInt(-1 >>> amount, graph())));
                         }
                     }
                 }
             }
             if (originalAmout != amount) {
-                return graph().unique(new UnsignedRightShiftNode(kind(), x(), ConstantNode.forInt(amount, graph())));
+                return graph().unique(new UnsignedRightShiftNode(stamp(), x(), ConstantNode.forInt(amount, graph())));
             }
         }
         return this;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/XorNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/XorNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -32,8 +32,8 @@
 @NodeInfo(shortName = "^")
 public final class XorNode extends BitLogicNode implements Canonicalizable {
 
-    public XorNode(Kind kind, ValueNode x, ValueNode y) {
-        super(kind, x, y);
+    public XorNode(Stamp stamp, ValueNode x, ValueNode y) {
+        super(stamp, x, y);
     }
 
     @Override
@@ -44,35 +44,26 @@
     @Override
     public Constant evalConst(Constant... inputs) {
         assert inputs.length == 2;
-        return Constant.forIntegerKind(kind(), inputs[0].asLong() ^ inputs[1].asLong(), null);
+        return Constant.forPrimitiveInt(PrimitiveStamp.getBits(stamp()), inputs[0].asLong() ^ inputs[1].asLong());
     }
 
     @Override
     public Node canonical(CanonicalizerTool tool) {
         if (x() == y()) {
-            return ConstantNode.forIntegerKind(kind(), 0, graph());
+            return ConstantNode.forIntegerStamp(stamp(), 0, graph());
         }
         if (x().isConstant() && !y().isConstant()) {
-            return graph().unique(new XorNode(kind(), y(), x()));
+            return graph().unique(new XorNode(stamp(), y(), x()));
         }
         if (x().isConstant()) {
-            return ConstantNode.forPrimitive(evalConst(x().asConstant(), y().asConstant()), graph());
+            return ConstantNode.forPrimitive(stamp(), evalConst(x().asConstant(), y().asConstant()), graph());
         } else if (y().isConstant()) {
-            if (kind() == Kind.Int) {
-                int c = y().asConstant().asInt();
-                if (c == 0) {
-                    return x();
-                } else if (c == -1) {
-                    return graph().unique(new NotNode(x()));
-                }
-            } else {
-                assert kind() == Kind.Long;
-                long c = y().asConstant().asLong();
-                if (c == 0) {
-                    return x();
-                } else if (c == -1) {
-                    return graph().unique(new NotNode(x()));
-                }
+            long rawY = y().asConstant().asLong();
+            long mask = IntegerStamp.defaultMask(PrimitiveStamp.getBits(stamp()));
+            if ((rawY & mask) == 0) {
+                return x();
+            } else if ((rawY & mask) == mask) {
+                return graph().unique(new NotNode(x()));
             }
             return BinaryNode.reassociate(this, ValueNode.isConstantPredicate());
         }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ZeroExtendNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,90 @@
+/*
+ * 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.calc;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.nodes.type.*;
+
+/**
+ * The {@code ZeroExtendNode} converts an integer to a wider integer using zero extension.
+ */
+public class ZeroExtendNode extends IntegerConvertNode implements Canonicalizable {
+
+    public ZeroExtendNode(ValueNode input, int resultBits) {
+        super(StampTool.zeroExtend(input.stamp(), resultBits), input, resultBits);
+    }
+
+    public static long zeroExtend(long value, int inputBits) {
+        if (inputBits < 64) {
+            return value & ~(-1L << inputBits);
+        } else {
+            return value;
+        }
+    }
+
+    @Override
+    public Constant convert(Constant c) {
+        return Constant.forPrimitiveInt(getResultBits(), zeroExtend(c.asLong(), getInputBits()));
+    }
+
+    @Override
+    public Constant reverse(Constant c) {
+        return Constant.forPrimitiveInt(getInputBits(), NarrowNode.narrow(c.asLong(), getInputBits()));
+    }
+
+    @Override
+    public boolean isLossless() {
+        return true;
+    }
+
+    @Override
+    public Node canonical(CanonicalizerTool tool) {
+        ValueNode ret = canonicalConvert();
+        if (ret != null) {
+            return ret;
+        }
+
+        if (getInput() instanceof ZeroExtendNode) {
+            // xxxx -(zero-extend)-> 0000 xxxx -(zero-extend)-> 00000000 0000xxxx
+            // ==> xxxx -(zero-extend)-> 00000000 0000xxxx
+            ZeroExtendNode other = (ZeroExtendNode) getInput();
+            return graph().unique(new ZeroExtendNode(other.getInput(), getResultBits()));
+        }
+
+        return this;
+    }
+
+    @Override
+    public boolean inferStamp() {
+        return updateStamp(StampTool.zeroExtend(getInput().stamp(), getResultBits()));
+    }
+
+    @Override
+    public void generate(ArithmeticLIRGenerator gen) {
+        gen.setResult(this, gen.emitZeroExtend(gen.operand(getInput()), getInputBits(), getResultBits()));
+    }
+}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ForeignCallNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ForeignCallNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -51,7 +51,11 @@
     }
 
     public ForeignCallNode(@InjectedNodeParameter ForeignCallsProvider foreignCalls, ForeignCallDescriptor descriptor, List<ValueNode> arguments) {
-        super(StampFactory.forKind(Kind.fromJavaClass(descriptor.getResultType())));
+        this(foreignCalls, descriptor, StampFactory.forKind(Kind.fromJavaClass(descriptor.getResultType())), arguments);
+    }
+
+    public ForeignCallNode(@InjectedNodeParameter ForeignCallsProvider foreignCalls, ForeignCallDescriptor descriptor, Stamp stamp, List<ValueNode> arguments) {
+        super(stamp);
         this.arguments = new NodeInputList<>(this, arguments);
         this.descriptor = descriptor;
         this.foreignCalls = foreignCalls;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -71,29 +71,39 @@
     public static ValueNode canonicalizeRead(ValueNode read, LocationNode location, ValueNode object, CanonicalizerTool tool, boolean compressible) {
         MetaAccessProvider metaAccess = tool.getMetaAccess();
         if (read.usages().isEmpty()) {
-            // Read without usages can be savely removed.
+            // Read without usages can be safely removed.
             return null;
         }
-        if (tool.canonicalizeReads() && metaAccess != null && object != null && object.isConstant()) {
-            if (location.getLocationIdentity() == LocationIdentity.FINAL_LOCATION && location instanceof ConstantLocationNode) {
-                long displacement = ((ConstantLocationNode) location).getDisplacement();
-                Kind kind = location.getValueKind();
-                if (object.kind() == Kind.Object) {
-                    Object base = object.asConstant().asObject();
-                    if (base != null) {
-                        Constant constant = tool.getConstantReflection().readUnsafeConstant(kind, base, displacement, compressible);
-                        if (constant != null) {
-                            return ConstantNode.forConstant(constant, metaAccess, read.graph());
+        if (tool.canonicalizeReads()) {
+            if (metaAccess != null && object != null && object.isConstant()) {
+                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.kind() == 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());
+                            }
+                        }
+                    } else if (object.kind().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());
+                            }
                         }
                     }
-                } else if (object.kind().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 (location.getLocationIdentity() == LocationIdentity.ARRAY_LENGTH_LOCATION && object instanceof ArrayLengthProvider) {
+                ValueNode length = ((ArrayLengthProvider) object).length();
+                if (length != null) {
+                    // TODO Does this need a PiCastNode to the positive range?
+                    return length;
                 }
             }
         }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessMonitorNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessMonitorNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -33,11 +33,34 @@
  * The Java bytecode specification allows non-balanced locking. Graal does not handle such cases and
  * throws a {@link BailoutException} instead during graph building.
  */
-public abstract class AccessMonitorNode extends AbstractMemoryCheckpoint implements MemoryCheckpoint {
+public abstract class AccessMonitorNode extends AbstractMemoryCheckpoint implements MemoryCheckpoint, DeoptimizingNode {
 
+    @Input private FrameState deoptState;
     @Input private ValueNode object;
     @Input private MonitorIdNode monitorId;
 
+    @Override
+    public boolean canDeoptimize() {
+        return true;
+    }
+
+    @Override
+    public FrameState getDeoptimizationState() {
+        return deoptState;
+    }
+
+    @Override
+    public void setDeoptimizationState(FrameState f) {
+        updateUsages(deoptState, f);
+        deoptState = f;
+    }
+
+    @Override
+    public FrameState getState() {
+        assert deoptState == null || stateAfter() == null;
+        return deoptState == null ? stateAfter() : deoptState;
+    }
+
     public ValueNode object() {
         return object;
     }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastDynamicNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastDynamicNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -76,7 +76,7 @@
         if (ObjectStamp.isObjectAlwaysNull(object())) {
             return object();
         }
-        if (hub.isConstant() && hub.kind() == Kind.Object && hub.asConstant().asObject() instanceof Class) {
+        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));
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CompareAndSwapNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CompareAndSwapNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -64,7 +64,7 @@
 
     public CompareAndSwapNode(ValueNode object, int displacement, ValueNode offset, ValueNode expected, ValueNode newValue) {
         super(StampFactory.forKind(Kind.Boolean.getStackKind()));
-        assert expected.kind() == newValue.kind();
+        assert expected.stamp().isCompatible(newValue.stamp());
         this.object = object;
         this.offset = offset;
         this.expected = expected;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadFieldNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadFieldNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -60,7 +60,7 @@
 
     @Override
     public Node canonical(CanonicalizerTool tool) {
-        if (usages().isEmpty() && (isStatic() || ObjectStamp.isObjectNonNull(object().stamp()))) {
+        if (usages().isEmpty() && !isVolatile() && (isStatic() || ObjectStamp.isObjectNonNull(object().stamp()))) {
             return null;
         }
         MetaAccessProvider metaAccess = tool.getMetaAccess();
@@ -74,6 +74,9 @@
                 return phi;
             }
         }
+        if (!isStatic() && object().isNullConstant()) {
+            return graph().add(new DeoptimizeNode(DeoptimizationAction.None, DeoptimizationReason.NullCheckException));
+        }
         return this;
     }
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -160,7 +160,7 @@
         if (targetMethod() == null) {
             return "??Invalid!";
         }
-        return targetMethod().getName();
+        return MetaUtil.format("%h.%n", targetMethod());
     }
 
     public static MethodCallTargetNode find(StructuredGraph graph, ResolvedJavaMethod method) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MonitorEnterNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MonitorEnterNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -23,6 +23,7 @@
 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.*;
@@ -30,7 +31,7 @@
 /**
  * The {@code MonitorEnterNode} represents the acquisition of a monitor.
  */
-public final class MonitorEnterNode extends AccessMonitorNode implements Virtualizable, Lowerable, MonitorEnter, MemoryCheckpoint.Single {
+public final class MonitorEnterNode extends AccessMonitorNode implements Virtualizable, Lowerable, IterableNodeType, MonitorEnter, MemoryCheckpoint.Single {
 
     /**
      * Creates a new MonitorEnterNode.
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MonitorExitNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MonitorExitNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -58,7 +58,7 @@
 
     @Override
     public void simplify(SimplifierTool tool) {
-        if (escapedReturnValue != null && stateAfter().bci != FrameState.AFTER_BCI) {
+        if (escapedReturnValue != null && stateAfter() != null && stateAfter().bci != FrameState.AFTER_BCI) {
             ValueNode returnValue = escapedReturnValue;
             setEscapedReturnValue(null);
             tool.removeIfUnused(returnValue);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewMultiArrayNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewMultiArrayNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -31,7 +31,7 @@
 /**
  * The {@code NewMultiArrayNode} represents an allocation of a multi-dimensional object array.
  */
-public final class NewMultiArrayNode extends DeoptimizingFixedWithNextNode implements Lowerable {
+public class NewMultiArrayNode extends DeoptimizingFixedWithNextNode implements Lowerable, ArrayLengthProvider {
 
     @Input private final NodeInputList<ValueNode> dimensions;
     private final ResolvedJavaType type;
@@ -74,4 +74,8 @@
     public boolean canDeoptimize() {
         return true;
     }
+
+    public ValueNode length() {
+        return dimension(0);
+    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/ArithmeticLIRGenerator.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/ArithmeticLIRGenerator.java	Wed Mar 05 19:40:15 2014 -0800
@@ -24,6 +24,8 @@
 
 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 (@see
@@ -35,6 +37,8 @@
 
     Value setResult(ValueNode x, Value operand);
 
+    PlatformKind getPlatformKind(Stamp stamp);
+
     Value emitNegate(Value input);
 
     Value emitAdd(Value a, Value b);
@@ -65,9 +69,15 @@
 
     Value emitUShr(Value a, Value b);
 
-    Value emitConvert(Kind from, Kind to, Value inputVal);
+    Value emitFloatConvert(FloatConvert op, Value inputVal);
+
+    Value emitReinterpret(PlatformKind to, Value inputVal);
 
-    Value emitReinterpret(Kind 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);
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LIRTypeTool.java	Wed Mar 05 19:40:15 2014 -0800
@@ -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.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();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/ValueAndStampProxy.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,32 @@
+/*
+ * 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.spi;
+
+/**
+ * This interface marks nodes whose result is the same as one of their inputs, and whose stamp is
+ * the same as one of their inputs.
+ * 
+ * For some algorithms it is necessary or advantageous to see through these proxies.
+ */
+public interface ValueAndStampProxy extends ValueProxy {
+}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/FloatStamp.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/FloatStamp.java	Wed Mar 05 19:40:15 2014 -0800
@@ -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
@@ -23,20 +23,21 @@
 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 Stamp {
+public class FloatStamp extends PrimitiveStamp {
 
     private final double lowerBound;
     private final double upperBound;
     private final boolean nonNaN;
 
-    protected FloatStamp(Kind kind) {
-        this(kind, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, false);
-        assert kind == Kind.Float || kind == Kind.Double;
+    protected FloatStamp(int bits) {
+        this(bits, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, false);
     }
 
-    protected FloatStamp(Kind kind, double lowerBound, double upperBound, boolean nonNaN) {
-        super(kind);
+    protected FloatStamp(int bits, double lowerBound, double upperBound, boolean nonNaN) {
+        super(bits);
         assert (!nonNaN && Double.isNaN(lowerBound) && Double.isNaN(upperBound)) || lowerBound <= upperBound;
         this.lowerBound = lowerBound;
         this.upperBound = upperBound;
@@ -44,8 +45,34 @@
     }
 
     @Override
+    public Stamp unrestricted() {
+        return new FloatStamp(getBits());
+    }
+
+    @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) {
-        return metaAccess.lookupJavaType(kind().toJavaClass());
+        switch (getBits()) {
+            case 32:
+                return metaAccess.lookupJavaType(Float.TYPE);
+            case 64:
+                return metaAccess.lookupJavaType(Double.TYPE);
+            default:
+                throw GraalInternalError.shouldNotReachHere();
+        }
     }
 
     /**
@@ -81,7 +108,8 @@
     @Override
     public String toString() {
         StringBuilder str = new StringBuilder();
-        str.append(kind().getTypeChar());
+        str.append('f');
+        str.append(getBits());
         str.append(nonNaN ? "!" : "");
         if (lowerBound == upperBound) {
             str.append(" [").append(lowerBound).append(']');
@@ -103,7 +131,7 @@
             return StampFactory.illegal(Kind.Illegal);
         }
         FloatStamp other = (FloatStamp) otherStamp;
-        assert kind() == other.kind();
+        assert getBits() == other.getBits();
         double meetUpperBound = Math.max(upperBound, other.upperBound);
         double meetLowerBound = Math.min(lowerBound, other.lowerBound);
         boolean meetNonNaN = nonNaN && other.nonNaN;
@@ -112,7 +140,7 @@
         } else if (meetLowerBound == other.lowerBound && meetUpperBound == other.upperBound && meetNonNaN == other.nonNaN) {
             return other;
         } else {
-            return new FloatStamp(kind(), meetLowerBound, meetUpperBound, meetNonNaN);
+            return new FloatStamp(getBits(), meetLowerBound, meetUpperBound, meetNonNaN);
         }
     }
 
@@ -128,7 +156,7 @@
             return StampFactory.illegal(Kind.Illegal);
         }
         FloatStamp other = (FloatStamp) otherStamp;
-        assert kind() == other.kind();
+        assert getBits() == other.getBits();
         double joinUpperBound = Math.min(upperBound, other.upperBound);
         double joinLowerBound = Math.max(lowerBound, other.lowerBound);
         boolean joinNonNaN = nonNaN || other.nonNaN;
@@ -137,9 +165,9 @@
         } else if (joinLowerBound == other.lowerBound && joinUpperBound == other.upperBound && joinNonNaN == other.nonNaN) {
             return other;
         } else if (joinLowerBound > joinUpperBound) {
-            return StampFactory.illegal(kind());
+            return illegal();
         } else {
-            return new FloatStamp(kind(), joinLowerBound, joinUpperBound, joinNonNaN);
+            return new FloatStamp(getBits(), joinLowerBound, joinUpperBound, joinNonNaN);
         }
     }
 
@@ -148,7 +176,7 @@
         final int prime = 31;
         int result = 1;
         long temp;
-        result = prime * result + kind().hashCode();
+        result = prime * result + super.hashCode();
         temp = Double.doubleToLongBits(lowerBound);
         result = prime * result + (int) (temp ^ (temp >>> 32));
         result = prime * result + (nonNaN ? 1231 : 1237);
@@ -158,17 +186,26 @@
     }
 
     @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()) {
+        if (obj == null || getClass() != obj.getClass() || !super.equals(obj)) {
             return false;
         }
         FloatStamp other = (FloatStamp) obj;
-        if (kind() != other.kind()) {
-            return false;
-        }
         if (Double.doubleToLongBits(lowerBound) != Double.doubleToLongBits(other.lowerBound)) {
             return false;
         }
@@ -184,10 +221,10 @@
     @Override
     public Constant asConstant() {
         if (nonNaN && lowerBound == upperBound) {
-            switch (kind()) {
-                case Float:
+            switch (getBits()) {
+                case 32:
                     return Constant.forFloat((float) lowerBound);
-                case Double:
+                case 64:
                     return Constant.forDouble(lowerBound);
             }
         }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/GenericStamp.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/GenericStamp.java	Wed Mar 05 19:40:15 2014 -0800
@@ -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
@@ -23,17 +23,18 @@
 package com.oracle.graal.nodes.type;
 
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.nodes.spi.*;
 
 public final class GenericStamp extends Stamp {
 
     public enum GenericStampType {
-        Dependency, Extension, Condition, Void
+        Dependency, Extension, Condition
     }
 
     private final GenericStampType type;
 
     protected GenericStamp(GenericStampType type) {
-        super(type == GenericStampType.Void ? Kind.Void : Kind.Illegal);
         this.type = type;
     }
 
@@ -42,8 +43,23 @@
     }
 
     @Override
+    public Stamp unrestricted() {
+        return this;
+    }
+
+    @Override
+    public Kind getStackKind() {
+        return Kind.Illegal;
+    }
+
+    @Override
+    public PlatformKind getPlatformKind(LIRTypeTool tool) {
+        throw GraalInternalError.shouldNotReachHere(type + " stamp has no value");
+    }
+
+    @Override
     public ResolvedJavaType javaType(MetaAccessProvider metaAccess) {
-        return metaAccess.lookupJavaType(kind().toJavaClass());
+        throw GraalInternalError.shouldNotReachHere(type + " stamp has not Java type");
     }
 
     @Override
@@ -79,6 +95,18 @@
     }
 
     @Override
+    public boolean isCompatible(Stamp stamp) {
+        if (this == stamp) {
+            return true;
+        }
+        if (stamp instanceof GenericStamp) {
+            GenericStamp other = (GenericStamp) stamp;
+            return type == other.type;
+        }
+        return false;
+    }
+
+    @Override
     public int hashCode() {
         return 31 + ((type == null) ? 0 : type.hashCode());
     }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/IllegalStamp.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/IllegalStamp.java	Wed Mar 05 19:40:15 2014 -0800
@@ -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
@@ -23,15 +23,43 @@
 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 {
+public final class IllegalStamp extends PrimitiveStamp {
+
+    private final Kind kind;
 
     public IllegalStamp(Kind kind) {
-        super(kind);
+        super(0);
+        this.kind = kind;
+    }
+
+    public Kind kind() {
+        return kind;
+    }
+
+    @Override
+    public Kind getStackKind() {
+        return kind;
+    }
+
+    @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
@@ -50,6 +78,18 @@
     }
 
     @Override
+    public boolean isCompatible(Stamp stamp) {
+        if (this == stamp) {
+            return true;
+        }
+        if (stamp instanceof IllegalStamp) {
+            IllegalStamp other = (IllegalStamp) stamp;
+            return kind == other.kind;
+        }
+        return false;
+    }
+
+    @Override
     public String toString() {
         return "ILLEGAL";
     }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/IntegerStamp.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/IntegerStamp.java	Wed Mar 05 19:40:15 2014 -0800
@@ -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
@@ -27,42 +27,89 @@
 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, signed) lower and upper bounds and up (may be set) and
- * down (always set) bit-masks.
+ * The description consists of (inclusive) lower and upper bounds and up (may be set) and down
+ * (always set) bit-masks.
  */
-public class IntegerStamp extends Stamp {
+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(Kind kind) {
-        this(kind.getStackKind(), kind.getMinValue(), kind.getMaxValue(), 0, defaultMask(isUnsignedKind(kind) ? kind : kind.getStackKind()));
-    }
-
-    public IntegerStamp(Kind kind, long lowerBound, long upperBound, long downMask, long upMask) {
-        super(kind);
+    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 <= upperBound : this;
-        assert lowerBound >= kind.getMinValue() : this;
-        assert upperBound <= kind.getMaxValue() : this;
-        assert (downMask & defaultMask(kind)) == downMask : this;
-        assert (upMask & defaultMask(kind)) == upMask : this;
+        assert lowerBound >= defaultMinValue(bits, unsigned) : this;
+        assert upperBound <= defaultMaxValue(bits, unsigned) : this;
+        assert (downMask & defaultMask(bits)) == downMask : this;
+        assert (upMask & defaultMask(bits)) == upMask : this;
         assert (lowerBound & downMask) == downMask : this;
         assert (upperBound & downMask) == downMask : this;
     }
 
     @Override
+    public Stamp unrestricted() {
+        return new IntegerStamp(getBits(), unsigned, defaultMinValue(getBits(), unsigned), defaultMaxValue(getBits(), unsigned), 0, defaultMask(getBits()));
+    }
+
+    @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) {
-        return metaAccess.lookupJavaType(kind().toJavaClass());
+        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;
     }
 
     /**
@@ -94,11 +141,11 @@
     }
 
     public boolean isUnrestricted() {
-        return lowerBound == kind().getMinValue() && upperBound == kind().getMaxValue() && downMask == 0 && upMask == defaultMask(kind());
+        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(kind()));
+        return value >= lowerBound && value <= upperBound && (value & downMask) == downMask && (value & upMask) == (value & defaultMask(getBits()));
     }
 
     public boolean isPositive() {
@@ -128,17 +175,18 @@
     @Override
     public String toString() {
         StringBuilder str = new StringBuilder();
-        str.append(kind().getTypeChar());
+        str.append(unsigned ? 'u' : 'i');
+        str.append(getBits());
         if (lowerBound == upperBound) {
             str.append(" [").append(lowerBound).append(']');
-        } else if (lowerBound != kind().getMinValue() || upperBound != kind().getMaxValue()) {
+        } 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(kind())) {
+        if (upMask != defaultMask(getBits())) {
             str.append(" \u21c8");
             new Formatter(str).format("%016x", upMask);
         }
@@ -146,15 +194,15 @@
     }
 
     private Stamp createStamp(IntegerStamp other, long newUpperBound, long newLowerBound, long newDownMask, long newUpMask) {
-        assert kind() == other.kind();
+        assert getBits() == other.getBits() && unsigned == other.unsigned;
         if (newLowerBound > newUpperBound || (newDownMask & (~newUpMask)) != 0) {
-            return StampFactory.illegal(kind());
+            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(kind(), newLowerBound, newUpperBound, newDownMask, newUpMask);
+            return new IntegerStamp(getBits(), unsigned, newLowerBound, newUpperBound, newDownMask, newUpMask);
         }
     }
 
@@ -191,10 +239,22 @@
     }
 
     @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 + kind().hashCode();
+        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));
@@ -207,41 +267,43 @@
         if (this == obj) {
             return true;
         }
-        if (obj == null || getClass() != obj.getClass()) {
+        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 || kind() != other.kind()) {
+        if (lowerBound != other.lowerBound || upperBound != other.upperBound || downMask != other.downMask || upMask != other.upMask) {
             return false;
         }
         return true;
     }
 
-    public static long defaultMask(Kind kind) {
-        switch (kind) {
-            case Boolean:
-                return 0x01L;
-            case Byte:
-                return 0xffL;
-            case Char:
-                return 0xffffL;
-            case Short:
-                return 0xffffL;
-            case Int:
-                return 0xffffffffL;
-            case Long:
-                return 0xffffffffffffffffL;
-            default:
-                throw GraalInternalError.shouldNotReachHere();
+    public static long defaultMask(int bits) {
+        assert 0 < bits && bits <= 64;
+        if (bits == 64) {
+            return 0xffffffffffffffffL;
+        } else {
+            return (1L << bits) - 1;
         }
     }
 
-    public static long upMaskFor(Kind kind, long lowerBound, long upperBound) {
+    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(kind);
+            return ((-1L) >>> Long.numberOfLeadingZeros(mask)) & defaultMask(bits);
         }
     }
 
@@ -259,12 +321,23 @@
     @Override
     public Constant asConstant() {
         if (lowerBound == upperBound) {
-            return Constant.forIntegerKind(kind(), lowerBound, null);
+            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;
     }
-
-    private static boolean isUnsignedKind(Kind kind) {
-        return kind == Kind.Char;
-    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/ObjectStamp.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/ObjectStamp.java	Wed Mar 05 19:40:15 2014 -0800
@@ -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
@@ -27,6 +27,7 @@
 
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.spi.*;
 
 public class ObjectStamp extends Stamp {
 
@@ -36,7 +37,6 @@
     private final boolean alwaysNull;
 
     public ObjectStamp(ResolvedJavaType type, boolean exactType, boolean nonNull, boolean alwaysNull) {
-        super(Kind.Object);
         assert !exactType || (type != null && (isConcreteType(type)));
         this.type = type;
         this.exactType = exactType;
@@ -45,6 +45,21 @@
     }
 
     @Override
+    public Stamp unrestricted() {
+        return StampFactory.object();
+    }
+
+    @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;
@@ -71,7 +86,7 @@
     @Override
     public String toString() {
         StringBuilder str = new StringBuilder();
-        str.append(kind().getTypeChar());
+        str.append('a');
         str.append(nonNull ? "!" : "").append(exactType ? "#" : "").append(' ').append(type == null ? "-" : type.getName()).append(alwaysNull ? " NULL" : "");
         return str.toString();
     }
@@ -123,6 +138,20 @@
         return join0(otherStamp, false);
     }
 
+    @Override
+    public boolean isCompatible(Stamp other) {
+        if (this == other) {
+            return true;
+        }
+        if (other instanceof ObjectStamp) {
+            return true;
+        }
+        if (other instanceof IllegalStamp) {
+            return ((IllegalStamp) other).kind() == Kind.Object;
+        }
+        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
@@ -294,4 +323,14 @@
         }
         return false;
     }
+
+    public static boolean isObject(Stamp stamp) {
+        if (stamp instanceof ObjectStamp) {
+            return true;
+        } else if (stamp instanceof IllegalStamp) {
+            return ((IllegalStamp) stamp).kind() == Kind.Object;
+        } else {
+            return false;
+        }
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/PrimitiveStamp.java	Wed Mar 05 19:40:15 2014 -0800
@@ -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.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;
+    }
+}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/Stamp.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/Stamp.java	Wed Mar 05 19:40:15 2014 -0800
@@ -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
@@ -24,20 +24,14 @@
 
 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 {
 
-    private final Kind kind;
-
-    protected Stamp(Kind kind) {
-        this.kind = kind;
-    }
-
-    public Kind kind() {
-        return kind;
+    protected Stamp() {
     }
 
     /**
@@ -51,6 +45,19 @@
     }
 
     /**
+     * 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 dependend {@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 PhiNode}s.
      * 
@@ -68,6 +75,23 @@
     public abstract Stamp join(Stamp other);
 
     /**
+     * Returns a stamp of the same kind, but allowing the full value range of the kind.
+     */
+    public abstract Stamp unrestricted();
+
+    /**
+     * Returns an illegal stamp that has the same kind, but no valid values.
+     */
+    public Stamp illegal() {
+        return StampFactory.illegal(getStackKind());
+    }
+
+    /**
+     * Test whether two stamps have the same base type.
+     */
+    public abstract boolean isCompatible(Stamp other);
+
+    /**
      * If this stamp represents a single value, the methods returns this single value. It returns
      * null otherwise.
      * 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampFactory.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampFactory.java	Wed Mar 05 19:40:15 2014 -0800
@@ -38,7 +38,6 @@
     private static final Stamp dependencyStamp = new GenericStamp(GenericStampType.Dependency);
     private static final Stamp extensionStamp = new GenericStamp(GenericStampType.Extension);
     private static final Stamp conditionStamp = new GenericStamp(GenericStampType.Condition);
-    private static final Stamp voidStamp = new GenericStamp(GenericStampType.Void);
     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);
 
@@ -46,31 +45,53 @@
         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 {
-        setCache(Kind.Boolean, new IntegerStamp(Kind.Boolean));
-        setCache(Kind.Byte, new IntegerStamp(Kind.Byte));
-        setCache(Kind.Short, new IntegerStamp(Kind.Short));
-        setCache(Kind.Char, new IntegerStamp(Kind.Char));
-        setCache(Kind.Int, new IntegerStamp(Kind.Int));
-        setCache(Kind.Long, new IntegerStamp(Kind.Long));
+        setIntCache(Kind.Boolean);
+        setIntCache(Kind.Byte);
+        setIntCache(Kind.Short);
+        setIntCache(Kind.Char);
+        setIntCache(Kind.Int);
+        setIntCache(Kind.Long);
 
-        setCache(Kind.Float, new FloatStamp(Kind.Float));
-        setCache(Kind.Double, new FloatStamp(Kind.Double));
+        setFloatCache(Kind.Float);
+        setFloatCache(Kind.Double);
 
         setCache(Kind.Object, objectStamp);
-        setCache(Kind.Void, voidStamp);
+        setCache(Kind.Void, VoidStamp.getInstance());
         for (Kind k : Kind.values()) {
             illegalStampCache[k.ordinal()] = new IllegalStamp(k);
         }
     }
 
+    /**
+     * 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;
+        return VoidStamp.getInstance();
     }
 
     /**
@@ -106,13 +127,21 @@
     }
 
     public static IntegerStamp forInteger(Kind kind, long lowerBound, long upperBound, long downMask, long upMask) {
-        return new IntegerStamp(kind, lowerBound, upperBound, downMask, upMask);
+        return new IntegerStamp(kind.getBitCount(), kind.isUnsigned(), lowerBound, upperBound, downMask, upMask);
     }
 
     public static IntegerStamp forInteger(Kind kind, long lowerBound, long upperBound) {
-        long defaultMask = IntegerStamp.defaultMask(kind);
+        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(kind, lowerBound, lowerBound, lowerBound & defaultMask, lowerBound & defaultMask);
+            return new IntegerStamp(bits, unsigned, lowerBound, lowerBound, lowerBound & defaultMask, lowerBound & defaultMask);
         }
         final long downMask;
         final long upMask;
@@ -136,11 +165,12 @@
                 downMask = lowerBound & ~(-1L >>> (lowerBoundLeadingOnes + sameBitCount)) | ~(-1L >>> lowerBoundLeadingOnes);
             }
         }
-        return forInteger(kind, lowerBound, upperBound, downMask & defaultMask, upMask & defaultMask);
+        return new IntegerStamp(bits, unsigned, lowerBound, upperBound, downMask & defaultMask, upMask & defaultMask);
     }
 
     public static FloatStamp forFloat(Kind kind, double lowerBound, double upperBound, boolean nonNaN) {
-        return new FloatStamp(kind, lowerBound, upperBound, nonNaN);
+        assert kind.isNumericFloat();
+        return new FloatStamp(kind.getBitCount(), lowerBound, upperBound, nonNaN);
     }
 
     public static Stamp forConstant(Constant value) {
@@ -152,7 +182,7 @@
             case Short:
             case Int:
             case Long:
-                long mask = value.asLong() & IntegerStamp.defaultMask(kind);
+                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()));
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampTool.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampTool.java	Wed Mar 05 19:40:15 2014 -0800
@@ -25,47 +25,55 @@
 import java.util.*;
 
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.nodes.calc.*;
 
 /**
  * Helper class that is used to keep all stamp-related operations in one place.
  */
 public class StampTool {
 
-    public static Kind joinKind(Kind a, Kind b) {
+    private static Kind joinKind(Kind a, Kind b) {
         if (a == b) {
             return a;
         }
         return Kind.Illegal;
     }
 
-    public static Kind joinKind(Stamp a, Stamp b) {
-        return joinKind(a.kind(), b.kind());
+    /**
+     * Create an {@link IllegalStamp} from two incompatible input stamps, joining the kind of the
+     * input stamps if possible.
+     */
+    private static Stamp joinIllegal(Stamp a, Stamp b) {
+        IllegalStamp ia = (IllegalStamp) a.illegal();
+        IllegalStamp ib = (IllegalStamp) b.illegal();
+        return StampFactory.illegal(joinKind(ia.kind(), ib.kind()));
     }
 
     public static Stamp negate(Stamp stamp) {
-        Kind kind = stamp.kind();
         if (stamp instanceof IntegerStamp) {
             IntegerStamp integerStamp = (IntegerStamp) stamp;
-            if (integerStamp.lowerBound() != kind.getMinValue()) {
+            int bits = integerStamp.getBits();
+            if (integerStamp.lowerBound() != IntegerStamp.defaultMinValue(bits, false)) {
                 // TODO(ls) check if the mask calculation is correct...
-                return StampFactory.forInteger(kind, -integerStamp.upperBound(), -integerStamp.lowerBound());
+                return StampFactory.forInteger(bits, false, -integerStamp.upperBound(), -integerStamp.lowerBound());
             }
         } else if (stamp instanceof FloatStamp) {
             FloatStamp floatStamp = (FloatStamp) stamp;
-            return new FloatStamp(kind, -floatStamp.upperBound(), -floatStamp.lowerBound(), floatStamp.isNonNaN());
+            return new FloatStamp(floatStamp.getBits(), -floatStamp.upperBound(), -floatStamp.lowerBound(), floatStamp.isNonNaN());
         }
 
-        return StampFactory.forKind(kind);
+        return stamp.unrestricted();
     }
 
     public static Stamp not(Stamp stamp) {
         if (stamp instanceof IntegerStamp) {
             IntegerStamp integerStamp = (IntegerStamp) stamp;
-            assert stamp.kind() == Kind.Int || stamp.kind() == Kind.Long;
-            long defaultMask = IntegerStamp.defaultMask(stamp.kind());
-            return new IntegerStamp(stamp.kind(), ~integerStamp.upperBound(), ~integerStamp.lowerBound(), (~integerStamp.upMask()) & defaultMask, (~integerStamp.downMask()) & defaultMask);
+            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 StampFactory.forKind(stamp.kind());
+        return stamp.unrestricted();
     }
 
     public static Stamp meet(Collection<? extends StampProvider> values) {
@@ -85,7 +93,7 @@
         if (stamp1 instanceof IntegerStamp && stamp2 instanceof IntegerStamp) {
             return add((IntegerStamp) stamp1, (IntegerStamp) stamp2);
         }
-        return StampFactory.illegal(joinKind(stamp1, stamp2));
+        return joinIllegal(stamp1, stamp2);
     }
 
     private static long carryBits(long x, long y) {
@@ -100,47 +108,56 @@
         if (stamp1 instanceof IntegerStamp && stamp2 instanceof IntegerStamp) {
             return div((IntegerStamp) stamp1, (IntegerStamp) stamp2);
         }
-        return StampFactory.illegal(joinKind(stamp1, stamp2));
+        return joinIllegal(stamp1, stamp2);
     }
 
     public static Stamp div(IntegerStamp stamp1, IntegerStamp stamp2) {
-        assert stamp1.kind() == stamp2.kind();
-        Kind kind = stamp1.kind();
+        assert stamp1.getBits() == stamp2.getBits() && stamp1.isUnsigned() == stamp2.isUnsigned();
         if (stamp2.isStrictlyPositive()) {
             long lowerBound = stamp1.lowerBound() / stamp2.lowerBound();
             long upperBound = stamp1.upperBound() / stamp2.lowerBound();
-            return StampFactory.forInteger(kind, lowerBound, upperBound);
+            return StampFactory.forInteger(stamp1.getBits(), stamp1.isUnsigned(), lowerBound, upperBound);
         }
-        return StampFactory.forKind(kind);
+        return stamp1.unrestricted();
     }
 
-    private static boolean addOverflowsPositively(long x, long y, Kind kind) {
+    private static boolean addOverflowsPositively(long x, long y, int bits, boolean unsigned) {
         long result = x + y;
-        if (kind == Kind.Long) {
-            return (~x & ~y & result) < 0;
+        if (bits == 64) {
+            if (unsigned) {
+                return ((x | y) & ~result) < 0;
+            } else {
+                return (~x & ~y & result) < 0;
+            }
         } else {
-            assert kind == Kind.Int;
-            return result > Integer.MAX_VALUE;
+            return result > IntegerStamp.defaultMaxValue(bits, unsigned);
         }
     }
 
-    private static boolean addOverflowsNegatively(long x, long y, Kind kind) {
+    private static boolean addOverflowsNegatively(long x, long y, int bits, boolean unsigned) {
+        if (unsigned) {
+            return false;
+        }
+
         long result = x + y;
-        if (kind == Kind.Long) {
+        if (bits == 64) {
             return (x & y & ~result) < 0;
         } else {
-            assert kind == Kind.Int;
-            return result < Integer.MIN_VALUE;
+            return result < IntegerStamp.defaultMinValue(bits, unsigned);
         }
     }
 
     public static IntegerStamp add(IntegerStamp stamp1, IntegerStamp stamp2) {
-        if (stamp1.isUnrestricted() || stamp2.isUnrestricted()) {
-            return (IntegerStamp) StampFactory.forKind(stamp1.kind());
+        int bits = stamp1.getBits();
+        boolean unsigned = stamp1.isUnsigned();
+        assert bits == stamp2.getBits() && unsigned == stamp2.isUnsigned();
+
+        if (stamp1.isUnrestricted()) {
+            return stamp1;
+        } else if (stamp2.isUnrestricted()) {
+            return stamp2;
         }
-        Kind kind = stamp1.kind();
-        assert stamp1.kind() == stamp2.kind();
-        long defaultMask = IntegerStamp.defaultMask(kind);
+        long defaultMask = IntegerStamp.defaultMask(bits);
         long variableBits = (stamp1.downMask() ^ stamp1.upMask()) | (stamp2.downMask() ^ stamp2.upMask());
         long variableBitsWithCarry = variableBits | (carryBits(stamp1.downMask(), stamp2.downMask()) ^ carryBits(stamp1.upMask(), stamp2.upMask()));
         long newDownMask = (stamp1.downMask() + stamp2.downMask()) & ~variableBitsWithCarry;
@@ -151,102 +168,107 @@
 
         long lowerBound;
         long upperBound;
-        boolean lowerOverflowsPositively = addOverflowsPositively(stamp1.lowerBound(), stamp2.lowerBound(), kind);
-        boolean upperOverflowsPositively = addOverflowsPositively(stamp1.upperBound(), stamp2.upperBound(), kind);
-        boolean lowerOverflowsNegatively = addOverflowsNegatively(stamp1.lowerBound(), stamp2.lowerBound(), kind);
-        boolean upperOverflowsNegatively = addOverflowsNegatively(stamp1.upperBound(), stamp2.upperBound(), kind);
+        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);
         if ((lowerOverflowsNegatively && !upperOverflowsNegatively) || (!lowerOverflowsPositively && upperOverflowsPositively)) {
-            lowerBound = kind.getMinValue();
-            upperBound = kind.getMaxValue();
+            lowerBound = IntegerStamp.defaultMinValue(bits, unsigned);
+            upperBound = IntegerStamp.defaultMaxValue(bits, unsigned);
         } else {
-            lowerBound = signExtend((stamp1.lowerBound() + stamp2.lowerBound()) & defaultMask, kind);
-            upperBound = signExtend((stamp1.upperBound() + stamp2.upperBound()) & defaultMask, kind);
+            lowerBound = (stamp1.lowerBound() + stamp2.lowerBound()) & defaultMask;
+            upperBound = (stamp1.upperBound() + stamp2.upperBound()) & defaultMask;
+            if (!unsigned) {
+                lowerBound = SignExtendNode.signExtend(lowerBound, bits);
+                upperBound = SignExtendNode.signExtend(upperBound, bits);
+            }
         }
-        IntegerStamp limit = StampFactory.forInteger(kind, lowerBound, upperBound);
+        IntegerStamp limit = StampFactory.forInteger(bits, unsigned, lowerBound, upperBound);
         newUpMask &= limit.upMask();
-        upperBound = signExtend(upperBound & newUpMask, kind);
+        upperBound &= newUpMask;
+        if (!unsigned) {
+            upperBound = SignExtendNode.signExtend(upperBound, bits);
+        }
         newDownMask |= limit.downMask();
         lowerBound |= newDownMask;
-        return new IntegerStamp(kind, lowerBound, upperBound, newDownMask, newUpMask);
+        return new IntegerStamp(bits, unsigned, lowerBound, upperBound, newDownMask, newUpMask);
     }
 
     public static Stamp sub(IntegerStamp stamp1, IntegerStamp stamp2) {
         if (stamp1.isUnrestricted() || stamp2.isUnrestricted()) {
-            return StampFactory.forKind(stamp1.kind());
+            return stamp1.unrestricted();
         }
         return add(stamp1, (IntegerStamp) StampTool.negate(stamp2));
     }
 
-    private static Stamp stampForMask(Kind kind, long downMask, long upMask) {
+    private static Stamp stampForMask(int bits, long downMask, long upMask) {
         long lowerBound;
         long upperBound;
-        if (((upMask >>> (kind.getBitCount() - 1)) & 1) == 0) {
+        if (((upMask >>> (bits - 1)) & 1) == 0) {
             lowerBound = downMask;
             upperBound = upMask;
-        } else if (((downMask >>> (kind.getBitCount() - 1)) & 1) == 1) {
+        } else if (((downMask >>> (bits - 1)) & 1) == 1) {
             lowerBound = downMask;
             upperBound = upMask;
         } else {
-            lowerBound = downMask | (-1L << (kind.getBitCount() - 1));
-            upperBound = kind.getMaxValue() & upMask;
+            lowerBound = downMask | (-1L << (bits - 1));
+            upperBound = IntegerStamp.defaultMaxValue(bits, false) & upMask;
         }
-        if (kind == Kind.Int) {
-            return StampFactory.forInteger(kind, (int) lowerBound, (int) upperBound, downMask, upMask);
-        } else {
-            return StampFactory.forInteger(kind, lowerBound, upperBound, downMask, upMask);
-        }
+        lowerBound = IntegerConvertNode.convert(lowerBound, bits, false);
+        upperBound = IntegerConvertNode.convert(upperBound, bits, false);
+        return new IntegerStamp(bits, false, lowerBound, upperBound, downMask, upMask);
     }
 
     public static Stamp and(Stamp stamp1, Stamp stamp2) {
         if (stamp1 instanceof IntegerStamp && stamp2 instanceof IntegerStamp) {
             return and((IntegerStamp) stamp1, (IntegerStamp) stamp2);
         }
-        return StampFactory.illegal(joinKind(stamp1, stamp2));
+        return joinIllegal(stamp1, stamp2);
     }
 
     public static Stamp and(IntegerStamp stamp1, IntegerStamp stamp2) {
-        assert stamp1.kind() == stamp2.kind();
-        return stampForMask(stamp1.kind(), stamp1.downMask() & stamp2.downMask(), stamp1.upMask() & stamp2.upMask());
+        assert stamp1.getBits() == stamp2.getBits();
+        return stampForMask(stamp1.getBits(), stamp1.downMask() & stamp2.downMask(), stamp1.upMask() & stamp2.upMask());
     }
 
     public static Stamp or(Stamp stamp1, Stamp stamp2) {
         if (stamp1 instanceof IntegerStamp && stamp2 instanceof IntegerStamp) {
             return or((IntegerStamp) stamp1, (IntegerStamp) stamp2);
         }
-        return StampFactory.illegal(joinKind(stamp1, stamp2));
+        return joinIllegal(stamp1, stamp2);
     }
 
     public static Stamp or(IntegerStamp stamp1, IntegerStamp stamp2) {
-        assert stamp1.kind() == stamp2.kind();
-        return stampForMask(stamp1.kind(), stamp1.downMask() | stamp2.downMask(), stamp1.upMask() | stamp2.upMask());
+        assert stamp1.getBits() == stamp2.getBits();
+        return stampForMask(stamp1.getBits(), stamp1.downMask() | stamp2.downMask(), stamp1.upMask() | stamp2.upMask());
     }
 
     public static Stamp xor(Stamp stamp1, Stamp stamp2) {
         if (stamp1 instanceof IntegerStamp && stamp2 instanceof IntegerStamp) {
             return xor((IntegerStamp) stamp1, (IntegerStamp) stamp2);
         }
-        return StampFactory.illegal(joinKind(stamp1, stamp2));
+        return joinIllegal(stamp1, stamp2);
     }
 
     public static Stamp xor(IntegerStamp stamp1, IntegerStamp stamp2) {
-        assert stamp1.kind() == stamp2.kind();
+        assert stamp1.getBits() == stamp2.getBits();
         long variableBits = (stamp1.downMask() ^ stamp1.upMask()) | (stamp2.downMask() ^ stamp2.upMask());
         long newDownMask = (stamp1.downMask() ^ stamp2.downMask()) & ~variableBits;
         long newUpMask = (stamp1.downMask() ^ stamp2.downMask()) | variableBits;
-        return stampForMask(stamp1.kind(), newDownMask, newUpMask);
+        return stampForMask(stamp1.getBits(), newDownMask, newUpMask);
     }
 
     public static Stamp unsignedRightShift(Stamp value, Stamp shift) {
         if (value instanceof IntegerStamp && shift instanceof IntegerStamp) {
             return unsignedRightShift((IntegerStamp) value, (IntegerStamp) shift);
         }
-        return StampFactory.illegal(value.kind());
+        return value.illegal();
     }
 
     public static Stamp unsignedRightShift(IntegerStamp value, IntegerStamp shift) {
-        Kind kind = value.kind();
+        int bits = value.getBits();
         if (shift.lowerBound() == shift.upperBound()) {
-            long shiftMask = kind == Kind.Int ? 0x1FL : 0x3FL;
+            long shiftMask = bits > 32 ? 0x3FL : 0x1FL;
             long shiftCount = shift.lowerBound() & shiftMask;
             if (shiftCount != 0) {
                 long lowerBound;
@@ -260,28 +282,28 @@
                     lowerBound = value.lowerBound() >>> shiftCount;
                     upperBound = value.upperBound() >>> shiftCount;
                 }
-                return new IntegerStamp(kind, lowerBound, upperBound, downMask, upMask);
+                return new IntegerStamp(bits, value.isUnsigned(), lowerBound, upperBound, downMask, upMask);
             }
         }
-        long mask = IntegerStamp.upMaskFor(kind, value.lowerBound(), value.upperBound());
-        return stampForMask(kind, 0, mask);
+        long mask = IntegerStamp.upMaskFor(bits, value.lowerBound(), value.upperBound());
+        return stampForMask(bits, 0, mask);
     }
 
     public static Stamp leftShift(Stamp value, Stamp shift) {
         if (value instanceof IntegerStamp && shift instanceof IntegerStamp) {
             return leftShift((IntegerStamp) value, (IntegerStamp) shift);
         }
-        return StampFactory.illegal(value.kind());
+        return value.illegal();
     }
 
     public static Stamp leftShift(IntegerStamp value, IntegerStamp shift) {
-        Kind kind = value.kind();
-        long defaultMask = IntegerStamp.defaultMask(kind);
+        int bits = value.getBits();
+        long defaultMask = IntegerStamp.defaultMask(bits);
         if (value.upMask() == 0) {
             return value;
         }
-        int shiftBits = kind == Kind.Int ? 5 : 6;
-        long shiftMask = kind == Kind.Int ? 0x1FL : 0x3FL;
+        int shiftBits = bits > 32 ? 6 : 5;
+        long shiftMask = bits > 32 ? 0x3FL : 0x1FL;
         if ((shift.lowerBound() >>> shiftBits) == (shift.upperBound() >>> shiftBits)) {
             long downMask = defaultMask;
             long upMask = 0;
@@ -291,14 +313,98 @@
                     upMask |= value.upMask() << (i & shiftMask);
                 }
             }
-            Stamp result = stampForMask(kind, downMask, upMask & IntegerStamp.defaultMask(kind));
+            Stamp result = stampForMask(bits, downMask, upMask & defaultMask);
             return result;
         }
-        return StampFactory.forKind(kind);
+        return value.unrestricted();
+    }
+
+    public static Stamp signExtend(Stamp input, int resultBits) {
+        if (input instanceof IntegerStamp) {
+            IntegerStamp inputStamp = (IntegerStamp) input;
+            int inputBits = inputStamp.getBits();
+            assert inputBits <= resultBits;
+
+            long defaultMask = IntegerStamp.defaultMask(resultBits);
+            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);
+        } else {
+            return input.illegal();
+        }
     }
 
-    public static Stamp intToLong(IntegerStamp intStamp) {
-        return StampFactory.forInteger(Kind.Long, intStamp.lowerBound(), intStamp.upperBound(), signExtend(intStamp.downMask(), Kind.Int), signExtend(intStamp.upMask(), Kind.Int));
+    public static Stamp zeroExtend(Stamp input, int resultBits) {
+        if (input instanceof IntegerStamp) {
+            IntegerStamp inputStamp = (IntegerStamp) input;
+            int inputBits = inputStamp.getBits();
+            assert inputBits <= resultBits;
+
+            long downMask = ZeroExtendNode.zeroExtend(inputStamp.downMask(), inputBits);
+            long upMask = ZeroExtendNode.zeroExtend(inputStamp.upMask(), inputBits);
+
+            if (inputStamp.lowerBound() < 0 && inputStamp.upperBound() >= 0) {
+                // signed range including 0 and -1
+                // after sign extension, the whole range from 0 to MAX_INT is possible
+                return stampForMask(resultBits, downMask, upMask);
+            }
+
+            long lowerBound = ZeroExtendNode.zeroExtend(inputStamp.lowerBound(), inputBits);
+            long upperBound = ZeroExtendNode.zeroExtend(inputStamp.upperBound(), inputBits);
+
+            return new IntegerStamp(resultBits, inputStamp.isUnsigned(), lowerBound, upperBound, downMask, upMask);
+        } else {
+            return input.illegal();
+        }
+    }
+
+    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) {
+                return inputStamp;
+            }
+
+            final long upperBound;
+            if (inputStamp.lowerBound() < IntegerStamp.defaultMinValue(resultBits, unsigned)) {
+                upperBound = IntegerStamp.defaultMaxValue(resultBits, unsigned);
+            } else {
+                upperBound = saturate(inputStamp.upperBound(), resultBits, unsigned);
+            }
+            final long lowerBound;
+            if (inputStamp.upperBound() > IntegerStamp.defaultMaxValue(resultBits, unsigned)) {
+                lowerBound = IntegerStamp.defaultMinValue(resultBits, unsigned);
+            } else {
+                lowerBound = saturate(inputStamp.lowerBound(), resultBits, unsigned);
+            }
+
+            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);
+        } else {
+            return input.illegal();
+        }
     }
 
     public static IntegerStamp narrowingKindConversion(IntegerStamp fromStamp, Kind toKind) {
@@ -316,11 +422,11 @@
             lowerBound = saturate(fromStamp.lowerBound(), toKind);
         }
 
-        long defaultMask = IntegerStamp.defaultMask(toKind);
-        long intMask = IntegerStamp.defaultMask(Kind.Int);
+        long defaultMask = IntegerStamp.defaultMask(toKind.getBitCount());
+        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(), (int) ((lowerBound | newDownMask) & newUpMask), (int) ((upperBound | newDownMask) & newUpMask), newDownMask, newUpMask);
+        return new IntegerStamp(toKind.getStackKind().getBitCount(), false, (int) ((lowerBound | newDownMask) & newUpMask), (int) ((upperBound | newDownMask) & newUpMask), newDownMask, newUpMask);
     }
 
     private static long signExtend(long value, Kind valueKind) {
@@ -331,7 +437,21 @@
         }
     }
 
-    public static long saturate(long v, Kind kind) {
+    private static long saturate(long v, int bits, boolean unsigned) {
+        if (bits < 64) {
+            long max = IntegerStamp.defaultMaxValue(bits, unsigned);
+            if (v > max) {
+                return max;
+            }
+            long min = IntegerStamp.defaultMinValue(bits, unsigned);
+            if (v < min) {
+                return min;
+            }
+        }
+        return v;
+    }
+
+    private static long saturate(long v, Kind kind) {
         long max = kind.getMaxValue();
         if (v > max) {
             return max;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/VoidStamp.java	Wed Mar 05 19:40:15 2014 -0800
@@ -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.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;
+    }
+
+    private static VoidStamp instance = new VoidStamp();
+
+    static VoidStamp getInstance() {
+        return instance;
+    }
+}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/GraphUtil.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/GraphUtil.java	Wed Mar 05 19:40:15 2014 -0800
@@ -137,6 +137,13 @@
         }
     }
 
+    public static void removeFixedWithUnusedInputs(FixedWithNextNode fixed) {
+        FixedNode next = fixed.next();
+        fixed.setNext(null);
+        fixed.replaceAtPredecessor(next);
+        killWithUnusedFloatingInputs(fixed);
+    }
+
     public static void checkRedundantPhi(PhiNode phiNode) {
         if (phiNode.isDeleted() || phiNode.valueCount() == 1) {
             return;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/AllocatedObjectNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/AllocatedObjectNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -22,6 +22,7 @@
  */
 package com.oracle.graal.nodes.virtual;
 
+import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
@@ -30,7 +31,7 @@
  * Selects one object from a {@link CommitAllocationNode}. The object is identified by its
  * {@link VirtualObjectNode}.
  */
-public class AllocatedObjectNode extends FloatingNode implements Virtualizable {
+public class AllocatedObjectNode extends FloatingNode implements Virtualizable, ArrayLengthProvider {
 
     @Input private VirtualObjectNode virtualObject;
     @Input private CommitAllocationNode commit;
@@ -57,4 +58,11 @@
     public void virtualize(VirtualizerTool tool) {
         tool.replaceWithVirtual(getVirtualObject());
     }
+
+    public ValueNode length() {
+        if (virtualObject instanceof ArrayLengthProvider) {
+            return ((ArrayLengthProvider) virtualObject).length();
+        }
+        return null;
+    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualArrayNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualArrayNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -30,7 +30,7 @@
 import com.oracle.graal.nodes.spi.*;
 
 @NodeInfo(nameTemplate = "VirtualArray {p#componentType/s}[{p#length}]")
-public class VirtualArrayNode extends VirtualObjectNode {
+public class VirtualArrayNode extends VirtualObjectNode implements ArrayLengthProvider {
 
     private final ResolvedJavaType componentType;
     private final int length;
@@ -144,4 +144,8 @@
     public ValueNode getMaterializedRepresentation(FixedNode fixed, ValueNode[] entries, LockState locks) {
         return new AllocatedObjectNode(this);
     }
+
+    public ValueNode length() {
+        return ConstantNode.forInt(length, graph());
+    }
 }
--- a/graal/com.oracle.graal.options/src/com/oracle/graal/options/OptionProcessor.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.options/src/com/oracle/graal/options/OptionProcessor.java	Wed Mar 05 19:40:15 2014 -0800
@@ -157,6 +157,7 @@
 
             boolean needPrivateFieldAccessor = false;
             int i = 0;
+            Collections.sort(info.options);
             for (OptionInfo option : info.options) {
                 String optionValue;
                 if (option.field.getModifiers().contains(Modifier.PRIVATE)) {
@@ -223,7 +224,7 @@
         }
     }
 
-    static class OptionInfo {
+    static class OptionInfo implements Comparable<OptionInfo> {
 
         final String name;
         final String help;
@@ -240,6 +241,11 @@
         }
 
         @Override
+        public int compareTo(OptionInfo other) {
+            return name.compareTo(other.name);
+        }
+
+        @Override
         public String toString() {
             return declaringClass + "." + field;
         }
--- a/graal/com.oracle.graal.options/src/com/oracle/graal/options/OptionValue.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.options/src/com/oracle/graal/options/OptionValue.java	Wed Mar 05 19:40:15 2014 -0800
@@ -128,7 +128,7 @@
         return new MultipleOverridesScope(current, map);
     }
 
-    private static ThreadLocal<OverrideScope> overrideScopes = new ThreadLocal<>();
+    private static final ThreadLocal<OverrideScope> overrideScopes = new ThreadLocal<>();
 
     /**
      * The raw option value.
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CanonicalizerPhase.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CanonicalizerPhase.java	Wed Mar 05 19:40:15 2014 -0800
@@ -185,7 +185,7 @@
                             boolean improvedStamp = tryInferStamp(valueNode);
                             Constant constant = valueNode.stamp().asConstant();
                             if (constant != null && !(node instanceof ConstantNode)) {
-                                performReplacement(valueNode, ConstantNode.forConstant(constant, context.getMetaAccess(), valueNode.graph()));
+                                performReplacement(valueNode, ConstantNode.forConstant(valueNode.stamp(), constant, context.getMetaAccess(), valueNode.graph()));
                             } else if (improvedStamp) {
                                 // the improved stamp may enable additional canonicalization
                                 tryCanonicalize(valueNode, nodeClass);
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java	Wed Mar 05 19:40:15 2014 -0800
@@ -315,9 +315,18 @@
 
         private void registerCondition(boolean isTrue, LogicNode condition, ValueNode anchor) {
             if (!isTrue && condition instanceof ShortCircuitOrNode) {
-                ShortCircuitOrNode disjunction = (ShortCircuitOrNode) condition;
-                registerCondition(disjunction.isXNegated(), disjunction.getX(), anchor);
-                registerCondition(disjunction.isYNegated(), disjunction.getY(), anchor);
+                /*
+                 * We can only do this for fixed nodes, because floating guards will be registered
+                 * at a BeginNode but might be "valid" only later due to data flow dependencies.
+                 * Therefore, registering both conditions of a ShortCircuitOrNode for a floating
+                 * guard could lead to cycles in data flow, because the guard will be used as anchor
+                 * for both conditions, and one condition could be depending on the other.
+                 */
+                if (anchor instanceof FixedNode) {
+                    ShortCircuitOrNode disjunction = (ShortCircuitOrNode) condition;
+                    registerCondition(disjunction.isXNegated(), disjunction.getX(), anchor);
+                    registerCondition(disjunction.isYNegated(), disjunction.getY(), anchor);
+                }
             }
             state.addCondition(isTrue, condition, anchor);
 
@@ -617,7 +626,7 @@
                         if (type != ObjectStamp.typeOrNull(receiver)) {
                             ResolvedJavaMethod method = type.resolveMethod(callTarget.targetMethod());
                             if (method != null) {
-                                if ((method.getModifiers() & Modifier.FINAL) != 0 || (type.getModifiers() & Modifier.FINAL) != 0) {
+                                if (Modifier.isFinal(method.getModifiers()) || Modifier.isFinal(type.getModifiers())) {
                                     callTarget.setInvokeKind(InvokeKind.Special);
                                     callTarget.setTargetMethod(method);
                                 }
@@ -630,6 +639,9 @@
         }
 
         private GuardingNode searchAnchor(ValueNode value, ResolvedJavaType type) {
+            if (!value.recordsUsages()) {
+                return null;
+            }
             for (Node n : value.usages()) {
                 if (n instanceof InstanceOfNode) {
                     InstanceOfNode instanceOfNode = (InstanceOfNode) n;
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningPhase.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningPhase.java	Wed Mar 05 19:40:15 2014 -0800
@@ -428,6 +428,10 @@
                 return InliningUtil.logInlinedMethod(info, inliningDepth, fullyProcessed, "intrinsic");
             }
 
+            if (info.shouldInline()) {
+                return InliningUtil.logInlinedMethod(info, inliningDepth, fullyProcessed, "forced inlining");
+            }
+
             double inliningBonus = getInliningBonus(info);
             int nodes = determineNodeCount(info);
             int lowLevelGraphSize = previousLowLevelGraphSize(info);
@@ -857,7 +861,7 @@
 
         @Override
         public String toString() {
-            return MetaUtil.format("%H.%n(%p)", method()) + remainingInvokes;
+            return (graph != null ? MetaUtil.format("%H.%n(%p)", method()) : "<null method>") + remainingInvokes;
         }
     }
 
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java	Wed Mar 05 19:40:15 2014 -0800
@@ -295,6 +295,8 @@
          * Try to make the call static bindable to avoid interface and virtual method calls.
          */
         void tryToDevirtualizeInvoke(MetaAccessProvider metaAccess, Assumptions assumptions);
+
+        boolean shouldInline();
     }
 
     public abstract static class AbstractInlineInfo implements InlineInfo {
@@ -411,6 +413,10 @@
             assert index == 0;
             this.inlineableElement = inlineableElement;
         }
+
+        public boolean shouldInline() {
+            return concrete.shouldBeInlined();
+        }
     }
 
     /**
@@ -497,6 +503,10 @@
         public String toString() {
             return "type-checked with type " + type.getName() + " and method " + MetaUtil.format("%H.%n(%p):%r", concrete);
         }
+
+        public boolean shouldInline() {
+            return concrete.shouldBeInlined();
+        }
     }
 
     /**
@@ -592,6 +602,15 @@
             }
         }
 
+        public boolean shouldInline() {
+            for (ResolvedJavaMethod method : concretes) {
+                if (method.shouldBeInlined()) {
+                    return true;
+                }
+            }
+            return false;
+        }
+
         private boolean hasSingleMethod() {
             return concretes.size() == 1 && !shouldFallbackToInvoke();
         }
@@ -1298,6 +1317,8 @@
         FixedNode invokeNode = invoke.asNode();
         StructuredGraph graph = invokeNode.graph();
         assert inlineGraph.getGuardsStage().ordinal() >= graph.getGuardsStage().ordinal();
+        assert !invokeNode.graph().isAfterFloatingReadPhase() : "inline isn't handled correctly after floating reads phase";
+
         Kind returnKind = invokeNode.kind();
 
         FrameState stateAfter = invoke.stateAfter();
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LockEliminationPhase.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LockEliminationPhase.java	Wed Mar 05 19:40:15 2014 -0800
@@ -36,19 +36,8 @@
             if (next instanceof MonitorEnterNode) {
                 MonitorEnterNode monitorEnterNode = (MonitorEnterNode) next;
                 if (monitorEnterNode.object() == node.object()) {
-                    FixedNode monitorEnterSuccessor = monitorEnterNode.next();
-                    monitorEnterNode.setNext(null);
-                    ((FixedWithNextNode) node.predecessor()).setNext(monitorEnterSuccessor);
-                    FrameState stateAfterFirst = node.stateAfter();
-                    FrameState stateAfterSecond = monitorEnterNode.stateAfter();
-                    node.safeDelete();
-                    monitorEnterNode.safeDelete();
-                    if (stateAfterFirst.usages().isEmpty()) {
-                        GraphUtil.killWithUnusedFloatingInputs(stateAfterFirst);
-                    }
-                    if (stateAfterSecond.usages().isEmpty()) {
-                        GraphUtil.killWithUnusedFloatingInputs(stateAfterSecond);
-                    }
+                    GraphUtil.removeFixedWithUnusedInputs(monitorEnterNode);
+                    GraphUtil.removeFixedWithUnusedInputs(node);
                 }
             }
         }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/NonNullParametersPhase.java	Wed Mar 05 19:40:15 2014 -0800
@@ -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.phases.common;
+
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.type.*;
+import com.oracle.graal.phases.*;
+
+/**
+ * Modifies the stamp of all object {@linkplain ParameterNode parameters} in a graph to denote they
+ * are non-null. This can be used for graphs where the caller null checks all arguments.
+ */
+public class NonNullParametersPhase extends Phase {
+
+    @Override
+    protected void run(StructuredGraph graph) {
+        for (ParameterNode param : graph.getNodes(ParameterNode.class)) {
+            if (param.stamp() instanceof ObjectStamp) {
+                param.setStamp(StampFactory.declaredNonNull(((ObjectStamp) param.stamp()).type()));
+            }
+        }
+    }
+}
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java	Wed Mar 05 19:40:15 2014 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -30,6 +30,8 @@
 // @formatter:off
 public final class GraalOptions {
 
+    @Option(help = "Use baseline compiler configuration")
+    public static final OptionValue<Boolean> UseBaselineCompiler = new OptionValue<>(false);
     @Option(help = "Enable use of compiler intrinsics")
     public static final OptionValue<Boolean> Intrinsify = new OptionValue<>(true);
     @Option(help = "Enable inlining of monomorphic calls")
@@ -232,6 +234,9 @@
     @Option(help = "Try to avoid emitting code where patching is required")
     public static final OptionValue<Boolean> ImmutableCode = new OptionValue<>(false);
 
+    @Option(help = "")
+    public static final OptionValue<Boolean> CallArrayCopy = new OptionValue<>(true);
+
     // Runtime settings
     @Option(help = "")
     public static final OptionValue<Boolean> SupportJsrBytecodes = new OptionValue<>(true);
@@ -251,8 +256,6 @@
     @Option(help = "")
     public static final OptionValue<Boolean> OptEliminateGuards = new OptionValue<>(true);
     @Option(help = "")
-    public static final OptionValue<Boolean> OptEliminateSafepoints = new OptionValue<>(true);
-    @Option(help = "")
     public static final OptionValue<Boolean> OptImplicitNullChecks = new OptionValue<>(true);
     @Option(help = "")
     public static final OptionValue<Boolean> OptLivenessAnalysis = new OptionValue<>(true);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/InferStamps.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.phases.graph;
+
+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 {
+
+    /**
+     * Infer the stamps for all Object nodes in the graph, to make the stamps as precise as
+     * possible. For example, this propagates the word-type through phi functions. To handle phi
+     * functions at loop headers, the stamp inference is called until a fix point is reached.
+     * <p>
+     * This method can be used when it is needed that stamps are inferred before the first run of
+     * the canonicalizer. For example, word type rewriting must run before the first run of the
+     * canonicalizer because many nodes are not prepared to see the word type during
+     * canonicalization.
+     */
+    public static void inferStamps(StructuredGraph graph) {
+        /*
+         * We want to make the stamps more precise. For cyclic phi functions, this means we have to
+         * ignore the initial stamp because the imprecise stamp would always propagate around the
+         * cycle. We therefore set the stamp to an illegal stamp, which is automatically ignored
+         * when the phi function performs the "meet" operator on its input stamps.
+         */
+        for (Node n : graph.getNodes()) {
+            if (n instanceof PhiNode || n instanceof ValueAndStampProxy) {
+                ValueNode node = (ValueNode) n;
+                if (ObjectStamp.isObject(node.stamp())) {
+                    assert !(node.stamp() instanceof IllegalStamp) : "We assume all Phi and Proxy stamps are legal before the analysis";
+                    node.setStamp(node.stamp().illegal());
+                }
+            }
+        }
+
+        boolean stampChanged;
+        do {
+            stampChanged = false;
+            /*
+             * We could use GraphOrder.forwardGraph() to process the nodes in a defined order and
+             * propagate long def-use chains in fewer iterations. However, measurements showed that
+             * we have few iterations anyway, and the overhead of computing the order is much higher
+             * than the benefit.
+             */
+            for (Node n : graph.getNodes()) {
+                if (n instanceof ValueNode) {
+                    ValueNode node = (ValueNode) n;
+                    if (ObjectStamp.isObject(node.stamp())) {
+                        stampChanged |= node.inferStamp();
+                    }
+                }
+            }
+        } while (stampChanged);
+
+        /*
+         * Check that all the illegal stamps we introduced above are correctly replaced with real
+         * stamps again.
+         */
+        assert checkNoIllegalStamp(graph);
+    }
+
+    private static boolean checkNoIllegalStamp(StructuredGraph graph) {
+        for (Node n : graph.getNodes()) {
+            if (n instanceof PhiNode || n instanceof ValueAndStampProxy) {
+                ValueNode node = (ValueNode) n;
+                assert !(node.stamp() instanceof IllegalStamp) : "Stamp is illegal after analysis. This is not necessarily an error, but a condition that we want to investigate (and then maybe relax or remove the assertion).";
+            }
+        }
+        return true;
+    }
+
+}
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/util/GraphOrder.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/util/GraphOrder.java	Wed Mar 05 19:40:15 2014 -0800
@@ -55,7 +55,7 @@
                         if (input instanceof FrameState && node instanceof StateSplit && input == ((StateSplit) node).stateAfter()) {
                             // nothing to do - after frame states are known, allowed cycles
                         } else {
-                            assert false : "cycle detected: " + node + " -> " + input;
+                            assert false : "unexpected cycle detected at input " + node + " -> " + input;
                         }
                     }
                 }
@@ -81,7 +81,7 @@
 
     private static void visitForward(ArrayList<Node> nodes, NodeBitMap visited, Node node, boolean floatingOnly) {
         if (node != null && !visited.isMarked(node)) {
-            assert !floatingOnly || !(node instanceof FixedNode) : "unexpected reference to fixed node: " + node;
+            assert !floatingOnly || !(node instanceof FixedNode) : "unexpected reference to fixed node: " + node + " (this indicates an unexpected cycle)";
             visited.mark(node);
             FrameState stateAfter = null;
             if (node instanceof StateSplit) {
--- a/graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64ConvertNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,58 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.replacements.amd64;
-
-import com.oracle.graal.api.meta.*;
-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 has the semantics of the AMD64 conversions. It is used in the lowering of the
- * {@link ConvertNode} which, on AMD64 needs a {@link AMD64ConvertNode} plus some fixup code that
- * handles the corner cases that differ between AMD64 and Java.
- */
-public class AMD64ConvertNode extends FloatingNode implements ArithmeticLIRLowerable {
-
-    @Input private ValueNode value;
-    private final Kind from;
-    private final Kind to;
-
-    public AMD64ConvertNode(Kind from, Kind to, ValueNode value) {
-        super(StampFactory.forKind(to.getStackKind()));
-        this.value = value;
-        this.from = from;
-        this.to = to;
-    }
-
-    public Constant evalConst(Constant... inputs) {
-        // this node should never have been created if its input is constant
-        assert false;
-        return null;
-    }
-
-    public void generate(ArithmeticLIRGenerator gen) {
-        gen.setResult(this, gen.emitConvert(from, to, gen.operand(value)));
-    }
-}
--- a/graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64ConvertSnippets.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64ConvertSnippets.java	Wed Mar 05 19:40:15 2014 -0800
@@ -158,42 +158,33 @@
             d2l = snippet(AMD64ConvertSnippets.class, "d2l");
         }
 
-        public void lower(ConvertNode convert, LoweringTool tool) {
-            SnippetInfo key = null;
-            switch (convert.getFromKind()) {
-                case Float:
-                    switch (convert.getToKind()) {
-                        case Int:
-                            key = f2i;
-                            break;
-                        case Long:
-                            key = f2l;
-                            break;
-                    }
+        public void lower(FloatConvertNode convert, LoweringTool tool) {
+            SnippetInfo key;
+            switch (convert.getOp()) {
+                case F2I:
+                    key = f2i;
+                    break;
+                case F2L:
+                    key = f2l;
                     break;
-                case Double:
-                    switch (convert.getToKind()) {
-                        case Int:
-                            key = d2i;
-                            break;
-                        case Long:
-                            key = d2l;
-                            break;
-                    }
+                case D2I:
+                    key = d2i;
                     break;
-            }
-            if (key == null) {
-                return;
+                case D2L:
+                    key = d2l;
+                    break;
+                default:
+                    return;
             }
 
             StructuredGraph graph = convert.graph();
 
             Arguments args = new Arguments(key, graph.getGuardsStage(), tool.getLoweringStage());
-            args.add("input", convert.value());
-            args.add("result", graph.unique(new AMD64ConvertNode(convert.getFromKind(), convert.getToKind(), convert.value())));
+            args.add("input", convert.getInput());
+            args.add("result", graph.unique(new AMD64FloatConvertNode(convert.stamp(), convert.getOp(), convert.getInput())));
 
             SnippetTemplate template = template(args);
-            Debug.log("Lowering %c2%c in %s: node=%s, template=%s, arguments=%s", convert.getFromKind().getTypeChar(), convert.getToKind().getTypeChar(), graph, convert, template, args);
+            Debug.log("Lowering %s in %s: node=%s, template=%s, arguments=%s", convert.getOp(), graph, convert, template, args);
             template.instantiate(providers.getMetaAccess(), convert, DEFAULT_REPLACER, tool, args);
             graph.removeFloating(convert);
         }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64FloatConvertNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,57 @@
+/*
+ * 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.replacements.amd64;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.calc.*;
+import com.oracle.graal.nodes.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
+ * of the {@link FloatConvertNode} which, on AMD64 needs a {@link AMD64FloatConvertNode} plus some
+ * fixup code that handles the corner cases that differ between AMD64 and Java.
+ */
+public class AMD64FloatConvertNode extends FloatingNode implements ArithmeticLIRLowerable {
+
+    private final FloatConvert op;
+    @Input private ValueNode value;
+
+    public AMD64FloatConvertNode(Stamp stamp, FloatConvert op, ValueNode value) {
+        super(stamp);
+        this.op = op;
+        this.value = value;
+    }
+
+    public Constant evalConst(Constant... inputs) {
+        // this node should never have been created if its input is constant
+        throw GraalInternalError.shouldNotReachHere();
+    }
+
+    public void generate(ArithmeticLIRGenerator gen) {
+        gen.setResult(this, gen.emitFloatConvert(op, gen.operand(value)));
+    }
+}
--- a/graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64Substitutions.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64Substitutions.java	Wed Mar 05 19:40:15 2014 -0800
@@ -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
@@ -39,6 +39,7 @@
 
     public void registerReplacements(MetaAccessProvider metaAccess, LoweringProvider lowerer, Replacements replacements, TargetDescription target) {
         if (Intrinsify.getValue()) {
+            replacements.registerSubstitutions(ArraysSubstitutions.class);
             replacements.registerSubstitutions(StringSubstitutions.class);
         }
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/ArraysSubstitutionsTest.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,332 @@
+/*
+ * 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 java.lang.reflect.*;
+import java.util.*;
+
+import org.junit.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.replacements.*;
+import com.oracle.graal.replacements.nodes.*;
+
+/**
+ * Tests {@link ArraysSubstitutions}.
+ */
+public class ArraysSubstitutionsTest 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 {
+            Object result = method.invoke(receiver, args);
+            return result;
+        } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public void testSubstitution(String testMethodName, Class<?> intrinsicClass, Class<?> holder, String methodName, Class<?>[] parameterTypes, boolean optional, Object[] args1, Object[] args2) {
+        Method realMethod = getMethod(holder, methodName, parameterTypes);
+        Method testMethod = getMethod(testMethodName);
+        StructuredGraph graph = test(testMethodName);
+
+        // Check to see if the resulting graph contains the expected node
+        StructuredGraph replacement = getReplacements().getMethodSubstitution(getMetaAccess().lookupJavaMethod(realMethod));
+        if (replacement == null && !optional) {
+            assertInGraph(graph, intrinsicClass);
+        }
+
+        // Force compilation
+        InstalledCode code = getCode(getMetaAccess().lookupJavaMethod(testMethod), parse(testMethod));
+        assert optional || code != null;
+
+        for (int i = 0; i < args1.length; i++) {
+            Object arg1 = args1[i];
+            Object arg2 = args2[i];
+            // Verify that the original method and the substitution produce the same value
+            assertEquals(invokeSafe(testMethod, null, arg1, arg2), invokeSafe(realMethod, null, arg1, arg2));
+            // Verify that the generated code and the original produce the same value
+            assertEquals(executeVarargsSafe(code, arg1, arg2), invokeSafe(realMethod, null, arg1, arg2));
+        }
+    }
+
+    private static final int N = 10;
+
+    @Test
+    public void testEqualsBoolean() {
+        Object[] args1 = new Object[N];
+        Object[] args2 = new Object[N];
+        int n = 0;
+
+        // equal arrays
+        for (int i = 0; i < N / 2; i++, n++) {
+            args1[n] = new boolean[i];
+            args2[n] = new boolean[i];
+        }
+
+        // non-equal arrays
+        for (int i = 0; i < N / 2; i++, n++) {
+            boolean[] a2 = new boolean[i];
+            if (i > 0) {
+                a2[i - 1] = true;
+            }
+            args1[n] = new boolean[i];
+            args2[n] = a2;
+        }
+        Class<?>[] parameterTypes = new Class<?>[]{boolean[].class, boolean[].class};
+        testSubstitution("arraysEqualsBoolean", ArrayEqualsNode.class, Arrays.class, "equals", parameterTypes, false, args1, args2);
+    }
+
+    @SuppressWarnings("all")
+    public static boolean arraysEqualsBoolean(boolean[] a, boolean[] b) {
+        return Arrays.equals(a, b);
+    }
+
+    @Test
+    public void testEqualsByte() {
+        Object[] args1 = new Object[N];
+        Object[] args2 = new Object[N];
+        int n = 0;
+
+        // equal arrays
+        for (int i = 0; i < N / 2; i++, n++) {
+            args1[n] = new byte[i];
+            args2[n] = new byte[i];
+        }
+
+        // non-equal arrays
+        for (int i = 0; i < N / 2; i++, n++) {
+            byte[] a2 = new byte[i];
+            if (i > 0) {
+                a2[i - 1] = 1;
+            }
+            args1[n] = new byte[i];
+            args2[n] = a2;
+        }
+
+        Class<?>[] parameterTypes = new Class<?>[]{byte[].class, byte[].class};
+        testSubstitution("arraysEqualsByte", ArrayEqualsNode.class, Arrays.class, "equals", parameterTypes, false, args1, args2);
+    }
+
+    @SuppressWarnings("all")
+    public static boolean arraysEqualsByte(byte[] a, byte[] b) {
+        return Arrays.equals(a, b);
+    }
+
+    @Test
+    public void testEqualsChar() {
+        Object[] args1 = new Object[N];
+        Object[] args2 = new Object[N];
+        int n = 0;
+
+        // equal arrays
+        for (int i = 0; i < N / 2; i++, n++) {
+            args1[n] = new char[i];
+            args2[n] = new char[i];
+        }
+
+        // non-equal arrays
+        for (int i = 0; i < N / 2; i++, n++) {
+            char[] a2 = new char[i];
+            if (i > 0) {
+                a2[i - 1] = 1;
+            }
+            args1[n] = new char[i];
+            args2[n] = a2;
+        }
+
+        Class<?>[] parameterTypes = new Class<?>[]{char[].class, char[].class};
+        testSubstitution("arraysEqualsChar", ArrayEqualsNode.class, Arrays.class, "equals", parameterTypes, false, args1, args2);
+    }
+
+    @SuppressWarnings("all")
+    public static boolean arraysEqualsChar(char[] a, char[] b) {
+        return Arrays.equals(a, b);
+    }
+
+    @Test
+    public void testEqualsShort() {
+        Object[] args1 = new Object[N];
+        Object[] args2 = new Object[N];
+        int n = 0;
+
+        // equal arrays
+        for (int i = 0; i < N / 2; i++, n++) {
+            args1[n] = new short[i];
+            args2[n] = new short[i];
+        }
+
+        // non-equal arrays
+        for (int i = 0; i < N / 2; i++, n++) {
+            short[] a2 = new short[i];
+            if (i > 0) {
+                a2[i - 1] = 1;
+            }
+            args1[n] = new short[i];
+            args2[n] = a2;
+        }
+
+        Class<?>[] parameterTypes = new Class<?>[]{short[].class, short[].class};
+        testSubstitution("arraysEqualsShort", ArrayEqualsNode.class, Arrays.class, "equals", parameterTypes, false, args1, args2);
+    }
+
+    @SuppressWarnings("all")
+    public static boolean arraysEqualsShort(short[] a, short[] b) {
+        return Arrays.equals(a, b);
+    }
+
+    @Test
+    public void testEqualsInt() {
+        Object[] args1 = new Object[N];
+        Object[] args2 = new Object[N];
+        int n = 0;
+
+        // equal arrays
+        for (int i = 0; i < N / 2; i++, n++) {
+            args1[n] = new int[i];
+            args2[n] = new int[i];
+        }
+
+        // non-equal arrays
+        for (int i = 0; i < N / 2; i++, n++) {
+            int[] a2 = new int[i];
+            if (i > 0) {
+                a2[i - 1] = 1;
+            }
+            args1[n] = new int[i];
+            args2[n] = a2;
+        }
+
+        Class<?>[] parameterTypes = new Class<?>[]{int[].class, int[].class};
+        testSubstitution("arraysEqualsInt", ArrayEqualsNode.class, Arrays.class, "equals", parameterTypes, false, args1, args2);
+    }
+
+    @SuppressWarnings("all")
+    public static boolean arraysEqualsInt(int[] a, int[] b) {
+        return Arrays.equals(a, b);
+    }
+
+    @Test
+    public void testEqualsLong() {
+        Object[] args1 = new Object[N];
+        Object[] args2 = new Object[N];
+        int n = 0;
+
+        // equal arrays
+        for (int i = 0; i < N / 2; i++, n++) {
+            args1[n] = new long[i];
+            args2[n] = new long[i];
+        }
+
+        // non-equal arrays
+        for (int i = 0; i < N / 2; i++, n++) {
+            long[] a2 = new long[i];
+            if (i > 0) {
+                a2[i - 1] = 1;
+            }
+            args1[n] = new long[i];
+            args2[n] = a2;
+        }
+
+        Class<?>[] parameterTypes = new Class<?>[]{long[].class, long[].class};
+        testSubstitution("arraysEqualsLong", ArrayEqualsNode.class, Arrays.class, "equals", parameterTypes, false, args1, args2);
+    }
+
+    @SuppressWarnings("all")
+    public static boolean arraysEqualsLong(long[] a, long[] b) {
+        return Arrays.equals(a, b);
+    }
+
+    @Test
+    public void testEqualsFloat() {
+        Object[] args1 = new Object[N];
+        Object[] args2 = new Object[N];
+        int n = 0;
+
+        // equal arrays
+        for (int i = 0; i < N / 2; i++, n++) {
+            args1[n] = new float[i];
+            args2[n] = new float[i];
+        }
+
+        // non-equal arrays
+        for (int i = 0; i < N / 2; i++, n++) {
+            float[] a2 = new float[i];
+            if (i > 0) {
+                a2[i - 1] = 1;
+            }
+            args1[n] = new float[i];
+            args2[n] = a2;
+        }
+
+        Class<?>[] parameterTypes = new Class<?>[]{float[].class, float[].class};
+        testSubstitution("arraysEqualsFloat", ArrayEqualsNode.class, Arrays.class, "equals", parameterTypes, false, args1, args2);
+    }
+
+    @SuppressWarnings("all")
+    public static boolean arraysEqualsFloat(float[] a, float[] b) {
+        return Arrays.equals(a, b);
+    }
+
+    @Test
+    public void testEqualsDouble() {
+        Object[] args1 = new Object[N];
+        Object[] args2 = new Object[N];
+        int n = 0;
+
+        // equal arrays
+        for (int i = 0; i < N / 2; i++, n++) {
+            args1[n] = new double[i];
+            args2[n] = new double[i];
+        }
+
+        // non-equal arrays
+        for (int i = 0; i < N / 2; i++, n++) {
+            double[] a2 = new double[i];
+            if (i > 0) {
+                a2[i - 1] = 1;
+            }
+            args1[n] = new double[i];
+            args2[n] = a2;
+        }
+
+        Class<?>[] parameterTypes = new Class<?>[]{double[].class, double[].class};
+        testSubstitution("arraysEqualsDouble", ArrayEqualsNode.class, Arrays.class, "equals", parameterTypes, false, args1, args2);
+    }
+
+    @SuppressWarnings("all")
+    public static boolean arraysEqualsDouble(double[] a, double[] b) {
+        return Arrays.equals(a, b);
+    }
+
+}
--- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/ObjectAccessTest.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/ObjectAccessTest.java	Wed Mar 05 19:40:15 2014 -0800
@@ -102,7 +102,7 @@
 
     private static void assertRead(StructuredGraph graph, Kind kind, boolean indexConvert, LocationIdentity locationIdentity) {
         ReadNode read = (ReadNode) graph.start().next();
-        Assert.assertEquals(kind.getStackKind(), read.kind());
+        Assert.assertEquals(kind.getStackKind(), read.stamp().getStackKind());
         Assert.assertEquals(graph.getParameter(0), read.object());
 
         IndexedLocationNode location = (IndexedLocationNode) read.location();
@@ -111,10 +111,10 @@
         Assert.assertEquals(1, location.getIndexScaling());
 
         if (indexConvert) {
-            ConvertNode convert = (ConvertNode) location.getIndex();
-            Assert.assertEquals(Kind.Int, convert.getFromKind());
-            Assert.assertEquals(Kind.Long, convert.getToKind());
-            Assert.assertEquals(graph.getParameter(1), convert.value());
+            SignExtendNode convert = (SignExtendNode) location.getIndex();
+            Assert.assertEquals(convert.getInputBits(), 32);
+            Assert.assertEquals(convert.getResultBits(), 64);
+            Assert.assertEquals(graph.getParameter(1), convert.getInput());
         } else {
             Assert.assertEquals(graph.getParameter(1), location.getIndex());
         }
@@ -127,7 +127,6 @@
         WriteNode write = (WriteNode) graph.start().next();
         Assert.assertEquals(graph.getParameter(2), write.value());
         Assert.assertEquals(graph.getParameter(0), write.object());
-        Assert.assertEquals(Kind.Void, write.kind());
         Assert.assertEquals(FrameState.AFTER_BCI, write.stateAfter().bci);
 
         IndexedLocationNode location = (IndexedLocationNode) write.location();
@@ -136,10 +135,10 @@
         Assert.assertEquals(1, location.getIndexScaling());
 
         if (indexConvert) {
-            ConvertNode convert = (ConvertNode) location.getIndex();
-            Assert.assertEquals(Kind.Int, convert.getFromKind());
-            Assert.assertEquals(Kind.Long, convert.getToKind());
-            Assert.assertEquals(graph.getParameter(1), convert.value());
+            SignExtendNode convert = (SignExtendNode) location.getIndex();
+            Assert.assertEquals(convert.getInputBits(), 32);
+            Assert.assertEquals(convert.getResultBits(), 64);
+            Assert.assertEquals(graph.getParameter(1), convert.getInput());
         } else {
             Assert.assertEquals(graph.getParameter(1), location.getIndex());
         }
--- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/PointerTest.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/PointerTest.java	Wed Mar 05 19:40:15 2014 -0800
@@ -110,11 +110,11 @@
         WordCastNode cast = (WordCastNode) graph.start().next();
 
         ReadNode read = (ReadNode) cast.next();
-        Assert.assertEquals(kind.getStackKind(), read.kind());
+        Assert.assertEquals(kind.getStackKind(), read.stamp().getStackKind());
 
         Assert.assertEquals(cast, read.object());
         Assert.assertEquals(graph.getParameter(0), cast.getInput());
-        Assert.assertEquals(target.wordKind, cast.kind());
+        Assert.assertEquals(target.wordKind, cast.stamp().getStackKind());
 
         IndexedLocationNode location = (IndexedLocationNode) read.location();
         Assert.assertEquals(kind, location.getValueKind());
@@ -122,10 +122,10 @@
         Assert.assertEquals(1, location.getIndexScaling());
 
         if (indexConvert) {
-            ConvertNode convert = (ConvertNode) location.getIndex();
-            Assert.assertEquals(Kind.Int, convert.getFromKind());
-            Assert.assertEquals(Kind.Long, convert.getToKind());
-            Assert.assertEquals(graph.getParameter(1), convert.value());
+            SignExtendNode convert = (SignExtendNode) location.getIndex();
+            Assert.assertEquals(convert.getInputBits(), 32);
+            Assert.assertEquals(convert.getResultBits(), 64);
+            Assert.assertEquals(graph.getParameter(1), convert.getInput());
         } else {
             Assert.assertEquals(graph.getParameter(1), location.getIndex());
         }
@@ -139,12 +139,11 @@
 
         WriteNode write = (WriteNode) cast.next();
         Assert.assertEquals(graph.getParameter(2), write.value());
-        Assert.assertEquals(Kind.Void, write.kind());
         Assert.assertEquals(FrameState.AFTER_BCI, write.stateAfter().bci);
 
         Assert.assertEquals(cast, write.object());
         Assert.assertEquals(graph.getParameter(0), cast.getInput());
-        Assert.assertEquals(target.wordKind, cast.kind());
+        Assert.assertEquals(target.wordKind, cast.stamp().getStackKind());
 
         IndexedLocationNode location = (IndexedLocationNode) write.location();
         Assert.assertEquals(kind, location.getValueKind());
@@ -152,10 +151,10 @@
         Assert.assertEquals(1, location.getIndexScaling());
 
         if (indexConvert) {
-            ConvertNode convert = (ConvertNode) location.getIndex();
-            Assert.assertEquals(Kind.Int, convert.getFromKind());
-            Assert.assertEquals(Kind.Long, convert.getToKind());
-            Assert.assertEquals(graph.getParameter(1), convert.value());
+            SignExtendNode convert = (SignExtendNode) location.getIndex();
+            Assert.assertEquals(convert.getInputBits(), 32);
+            Assert.assertEquals(convert.getResultBits(), 64);
+            Assert.assertEquals(graph.getParameter(1), convert.getInput());
         } else {
             Assert.assertEquals(graph.getParameter(1), location.getIndex());
         }
--- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/StandardMethodSubstitutionsTest.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/StandardMethodSubstitutionsTest.java	Wed Mar 05 19:40:15 2014 -0800
@@ -32,6 +32,7 @@
 
 import sun.misc.*;
 
+import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.replacements.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
@@ -350,19 +351,54 @@
         // Math.pow(value, 13);
     }
 
+    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... args) {
+        method.setAccessible(true);
+        try {
+            Object result = method.invoke(null, args);
+            return result;
+        } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public void testSubstitution(String testMethodName, Class<?> intrinsicClass, Class<?> holder, String methodName, boolean optional, Object... args) {
+        Method realMethod = getMethod(holder, methodName);
+        Method testMethod = getMethod(testMethodName);
+        StructuredGraph graph = test(testMethodName);
+
+        // Check to see if the resulting graph contains the expected node
+        StructuredGraph replacement = getReplacements().getMethodSubstitution(getMetaAccess().lookupJavaMethod(realMethod));
+        if (replacement == null && !optional) {
+            assertInGraph(graph, intrinsicClass);
+        }
+
+        // Force compilation
+        InstalledCode code = getCode(getMetaAccess().lookupJavaMethod(testMethod), parse(testMethod));
+        assert optional || code != null;
+        for (Object l : args) {
+            // Verify that the original method and the substitution produce the same value
+            assertEquals(invokeSafe(testMethod, l), invokeSafe(realMethod, l));
+            // Verify that the generated code and the original produce the same value
+            assertEquals(executeVarargsSafe(code, l), invokeSafe(realMethod, l));
+        }
+    }
+
     @Test
     public void testIntegerSubstitutions() {
-        assertInGraph(test("integerReverseBytes"), ReverseBytesNode.class);              // Java
-        assertInGraph(test("integerNumberOfLeadingZeros"), BitScanReverseNode.class);    // Java
-        assertInGraph(test("integerNumberOfTrailingZeros"), BitScanForwardNode.class);   // Java
-        assertInGraph(test("integerBitCount"), BitCountNode.class);                      // Java
+        Object[] args = new Object[]{Integer.MIN_VALUE, -1, 0, 1, Integer.MAX_VALUE};
 
-        for (int i : new int[]{Integer.MIN_VALUE, -1, 0, 1, Integer.MAX_VALUE}) {
-            assertEquals(Integer.reverseBytes(i), IntegerSubstitutions.reverseBytes(i));
-            assertEquals(Integer.numberOfLeadingZeros(i), IntegerSubstitutions.numberOfLeadingZeros(i));
-            assertEquals(Integer.numberOfTrailingZeros(i), IntegerSubstitutions.numberOfTrailingZeros(i));
-            assertEquals(Integer.bitCount(i), IntegerSubstitutions.bitCount(i));
-        }
+        testSubstitution("integerReverseBytes", ReverseBytesNode.class, Integer.class, "reverseBytes", false, args);
+        testSubstitution("integerNumberOfLeadingZeros", BitScanReverseNode.class, Integer.class, "numberOfLeadingZeros", true, args);
+        testSubstitution("integerNumberOfTrailingZeros", BitScanForwardNode.class, Integer.class, "numberOfTrailingZeros", false, args);
+        testSubstitution("integerBitCount", BitCountNode.class, Integer.class, "bitCount", true, args);
     }
 
     @SuppressWarnings("all")
@@ -387,17 +423,12 @@
 
     @Test
     public void testLongSubstitutions() {
-        assertInGraph(test("longReverseBytes"), ReverseBytesNode.class);              // Java
-        assertInGraph(test("longNumberOfLeadingZeros"), BitScanReverseNode.class);    // Java
-        assertInGraph(test("longNumberOfTrailingZeros"), BitScanForwardNode.class);   // Java
-        assertInGraph(test("longBitCount"), BitCountNode.class);                      // Java
+        Object[] args = new Object[]{Long.MIN_VALUE, -1L, 0L, 1L, Long.MAX_VALUE};
 
-        for (long l : new long[]{Long.MIN_VALUE, -1L, 0L, 1L, Long.MAX_VALUE}) {
-            assertEquals(Long.reverseBytes(l), LongSubstitutions.reverseBytes(l));
-            assertEquals(Long.numberOfLeadingZeros(l), LongSubstitutions.numberOfLeadingZeros(l));
-            assertEquals(Long.numberOfTrailingZeros(l), LongSubstitutions.numberOfTrailingZeros(l));
-            assertEquals(Long.bitCount(l), LongSubstitutions.bitCount(l));
-        }
+        testSubstitution("longReverseBytes", ReverseBytesNode.class, Long.class, "reverseBytes", false, args);
+        testSubstitution("longNumberOfLeadingZeros", BitScanReverseNode.class, Long.class, "numberOfLeadingZeros", true, args);
+        testSubstitution("longNumberOfTrailingZeros", BitScanForwardNode.class, Long.class, "numberOfTrailingZeros", false, args);
+        testSubstitution("longBitCount", BitCountNode.class, Long.class, "bitCount", true, args);
     }
 
     @SuppressWarnings("all")
@@ -406,12 +437,12 @@
     }
 
     @SuppressWarnings("all")
-    public static long longNumberOfLeadingZeros(long value) {
+    public static int longNumberOfLeadingZeros(long value) {
         return Long.numberOfLeadingZeros(value);
     }
 
     @SuppressWarnings("all")
-    public static long longNumberOfTrailingZeros(long value) {
+    public static int longNumberOfTrailingZeros(long value) {
         return Long.numberOfTrailingZeros(value);
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/StringSubstitutionsTest.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,116 @@
+/*
+ * 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 java.lang.reflect.*;
+
+import org.junit.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.replacements.*;
+import com.oracle.graal.replacements.nodes.*;
+
+/**
+ * Tests {@link StringSubstitutions}.
+ */
+public class StringSubstitutionsTest 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 {
+            Object result = method.invoke(receiver, args);
+            return result;
+        } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public void testSubstitution(String testMethodName, Class<?> intrinsicClass, Class<?> holder, String methodName, boolean optional, Object[] args1, Object[] args2) {
+        Method realMethod = getMethod(holder, methodName);
+        Method testMethod = getMethod(testMethodName);
+        StructuredGraph graph = test(testMethodName);
+
+        // Check to see if the resulting graph contains the expected node
+        StructuredGraph replacement = getReplacements().getMethodSubstitution(getMetaAccess().lookupJavaMethod(realMethod));
+        if (replacement == null && !optional) {
+            assertInGraph(graph, intrinsicClass);
+        }
+
+        // Force compilation
+        InstalledCode code = getCode(getMetaAccess().lookupJavaMethod(testMethod), parse(testMethod));
+        assert optional || code != null;
+
+        for (int i = 0; i < args1.length; i++) {
+            Object arg1 = args1[i];
+            Object arg2 = args2[i];
+            // Verify that the original method and the substitution produce the same value
+            assertEquals(invokeSafe(testMethod, null, arg1, arg2), invokeSafe(realMethod, arg1, arg2));
+            // Verify that the generated code and the original produce the same value
+            assertEquals(executeVarargsSafe(code, arg1, arg2), invokeSafe(realMethod, arg1, arg2));
+        }
+    }
+
+    @Test
+    public void testEquals() {
+        final int n = 1000;
+        Object[] args1 = new Object[n];
+        Object[] args2 = new Object[n];
+
+        // equal strings
+        String s1 = "";
+        String s2 = "";
+        for (int i = 0; i < n / 2; i++) {
+            args1[i] = s1;
+            args2[i] = s2;
+            s1 = s1 + "0";
+            s2 = s2 + "0";
+        }
+
+        // non-equal strings
+        s1 = "";
+        s2 = "";
+        for (int i = n / 2; i < n; i++) {
+            args1[i] = s1;
+            args2[i] = s2;
+            s2 = s1 + "1";
+            s1 = s1 + "0";
+        }
+
+        testSubstitution("stringEquals", ArrayEqualsNode.class, String.class, "equals", false, args1, args2);
+    }
+
+    @SuppressWarnings("all")
+    public static boolean stringEquals(String a, String b) {
+        return a.equals(b);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/UnsignedMathTest.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,116 @@
+/*
+ * 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 org.junit.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.compiler.test.*;
+
+/**
+ * Tests the substitutions for the {@link UnsignedMath} class.
+ */
+public class UnsignedMathTest extends GraalCompilerTest {
+
+    public static boolean aboveThanInt(int a, int b) {
+        return UnsignedMath.aboveThan(a, b);
+    }
+
+    public static boolean aboveOrEqualInt(int a, int b) {
+        return UnsignedMath.aboveOrEqual(a, b);
+    }
+
+    public static boolean belowThanInt(int a, int b) {
+        return UnsignedMath.belowThan(a, b);
+    }
+
+    public static boolean belowOrEqualInt(int a, int b) {
+        return UnsignedMath.belowOrEqual(a, b);
+    }
+
+    public static int divideInt(int a, int b) {
+        return UnsignedMath.divide(a, b);
+    }
+
+    public static int remainderInt(int a, int b) {
+        return UnsignedMath.remainder(a, b);
+    }
+
+    public static boolean aboveThanLong(long a, long b) {
+        return UnsignedMath.aboveThan(a, b);
+    }
+
+    public static boolean aboveOrEqualLong(long a, long b) {
+        return UnsignedMath.aboveOrEqual(a, b);
+    }
+
+    public static boolean belowThanLong(long a, long b) {
+        return UnsignedMath.belowThan(a, b);
+    }
+
+    public static boolean belowOrEqualLong(long a, long b) {
+        return UnsignedMath.belowOrEqual(a, b);
+    }
+
+    public static long divideLong(long a, long b) {
+        return UnsignedMath.divide(a, b);
+    }
+
+    public static long remainderLong(long a, long b) {
+        return UnsignedMath.remainder(a, b);
+    }
+
+    private void testInt(int a, int b) {
+        test("aboveThanInt", a, b);
+        test("aboveOrEqualInt", a, b);
+        test("belowThanInt", a, b);
+        test("belowOrEqualInt", a, b);
+        test("divideInt", a, b);
+        test("remainderInt", a, b);
+    }
+
+    private void testLong(long a, long b) {
+        test("aboveThanLong", a, b);
+        test("aboveOrEqualLong", a, b);
+        test("belowThanLong", a, b);
+        test("belowOrEqualLong", a, b);
+        test("divideLong", a, b);
+        test("remainderLong", a, b);
+    }
+
+    @Test
+    public void testInt() {
+        testInt(5, 7);
+        testInt(-3, -7);
+        testInt(-3, 7);
+        testInt(42, -5);
+    }
+
+    @Test
+    public void testLong() {
+        testLong(5, 7);
+        testLong(-3, -7);
+        testLong(-3, 7);
+        testLong(42, -5);
+    }
+}
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ArraySubstitutions.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ArraySubstitutions.java	Wed Mar 05 19:40:15 2014 -0800
@@ -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,4 +36,13 @@
     public static Object newInstance(Class<?> componentType, int length) throws NegativeArraySizeException {
         return DynamicNewArrayNode.newArray(GuardingPiNode.guardingNonNull(componentType), length);
     }
+
+    @MethodSubstitution
+    public static int getLength(Object array) {
+        if (!array.getClass().isArray()) {
+            throw new IllegalArgumentException("Argument is not an array");
+        }
+        return ArrayLengthNode.arrayLength(array);
+    }
+
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ArraysSubstitutions.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,121 @@
+/*
+ * 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.replacements;
+
+import com.oracle.graal.api.replacements.*;
+import com.oracle.graal.replacements.nodes.*;
+
+/**
+ * Substitutions for {@link java.util.Arrays} methods.
+ */
+@ClassSubstitution(java.util.Arrays.class)
+public class ArraysSubstitutions {
+
+    @MethodSubstitution
+    public static boolean equals(boolean[] a, boolean[] a2) {
+        if (a == a2) {
+            return true;
+        }
+        if (a == null || a2 == null || a.length != a2.length) {
+            return false;
+        }
+        return ArrayEqualsNode.equals(a, a2, a.length);
+    }
+
+    @MethodSubstitution
+    public static boolean equals(byte[] a, byte[] a2) {
+        if (a == a2) {
+            return true;
+        }
+        if (a == null || a2 == null || a.length != a2.length) {
+            return false;
+        }
+        return ArrayEqualsNode.equals(a, a2, a.length);
+    }
+
+    @MethodSubstitution
+    public static boolean equals(char[] a, char[] a2) {
+        if (a == a2) {
+            return true;
+        }
+        if (a == null || a2 == null || a.length != a2.length) {
+            return false;
+        }
+        return ArrayEqualsNode.equals(a, a2, a.length);
+    }
+
+    @MethodSubstitution
+    public static boolean equals(short[] a, short[] a2) {
+        if (a == a2) {
+            return true;
+        }
+        if (a == null || a2 == null || a.length != a2.length) {
+            return false;
+        }
+        return ArrayEqualsNode.equals(a, a2, a.length);
+    }
+
+    @MethodSubstitution
+    public static boolean equals(int[] a, int[] a2) {
+        if (a == a2) {
+            return true;
+        }
+        if (a == null || a2 == null || a.length != a2.length) {
+            return false;
+        }
+        return ArrayEqualsNode.equals(a, a2, a.length);
+    }
+
+    @MethodSubstitution
+    public static boolean equals(long[] a, long[] a2) {
+        if (a == a2) {
+            return true;
+        }
+        if (a == null || a2 == null || a.length != a2.length) {
+            return false;
+        }
+        return ArrayEqualsNode.equals(a, a2, a.length);
+    }
+
+    @MethodSubstitution
+    public static boolean equals(float[] a, float[] a2) {
+        if (a == a2) {
+            return true;
+        }
+        if (a == null || a2 == null || a.length != a2.length) {
+            return false;
+        }
+        return ArrayEqualsNode.equals(a, a2, a.length);
+    }
+
+    @MethodSubstitution
+    public static boolean equals(double[] a, double[] a2) {
+        if (a == a2) {
+            return true;
+        }
+        if (a == null || a2 == null || a.length != a2.length) {
+            return false;
+        }
+        return ArrayEqualsNode.equals(a, a2, a.length);
+    }
+}
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/CollapseFrameForSingleSideEffectPhase.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/CollapseFrameForSingleSideEffectPhase.java	Wed Mar 05 19:40:15 2014 -0800
@@ -24,6 +24,7 @@
 
 import java.util.*;
 
+import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.util.*;
 import com.oracle.graal.phases.*;
@@ -42,25 +43,94 @@
  * The invalid frame states ensure that no deoptimization to a snippet frame state will happen.
  */
 public class CollapseFrameForSingleSideEffectPhase extends Phase {
-    @Override
-    protected void run(StructuredGraph graph) {
-        ReentrantNodeIterator.apply(new CollapseFrameForSingleSideEffectClosure(), graph.start(), null, null);
+
+    private static class IterationState {
+        public final IterationState previous;
+        public final Node node;
+        public final Collection<IterationState> merge;
+        public final boolean invalid;
+
+        private IterationState(IterationState previous, Node node, Collection<IterationState> merge, boolean invalid) {
+            this.previous = previous;
+            this.node = node;
+            this.merge = merge;
+            this.invalid = invalid;
+        }
+
+        public IterationState() {
+            this(null, null, null, false);
+        }
+
+        public IterationState addSideEffect(StateSplit sideEffect) {
+            return new IterationState(this, sideEffect.asNode(), null, true);
+        }
+
+        public IterationState addBranch(AbstractBeginNode begin) {
+            return new IterationState(this, begin, null, this.invalid);
+        }
+
+        public static IterationState merge(MergeNode merge, Collection<IterationState> before, boolean invalid) {
+            return new IterationState(null, merge, before, invalid);
+        }
+
+        public void markAll(NodeBitMap set) {
+            IterationState state = this;
+            while (state != null && state.node != null && !set.contains(state.node)) {
+                set.mark(state.node);
+                if (state.merge != null) {
+                    for (IterationState branch : state.merge) {
+                        branch.markAll(set);
+                    }
+                }
+                state = state.previous;
+            }
+        }
+
+        public void markMasked(NodeBitMap unmasked, NodeBitMap masked) {
+            IterationState state = this;
+            while (state != null && state.node != null && !masked.contains(state.node)) {
+                if (state.node instanceof StateSplit) {
+                    unmasked.mark(state.node);
+                    StateSplit split = (StateSplit) state.node;
+                    if (split.hasSideEffect() && state.previous != null) {
+                        state.previous.markAll(masked);
+                        return;
+                    }
+                }
+
+                if (state.merge != null) {
+                    for (IterationState branch : state.merge) {
+                        branch.markMasked(unmasked, masked);
+                    }
+                }
+                state = state.previous;
+            }
+        }
     }
 
-    private static class CollapseFrameForSingleSideEffectClosure extends NodeIteratorClosure<StateSplit> {
+    @Override
+    protected void run(StructuredGraph graph) {
+        CollapseFrameForSingleSideEffectClosure closure = new CollapseFrameForSingleSideEffectClosure();
+        ReentrantNodeIterator.apply(closure, graph.start(), new IterationState(), null);
+        closure.finishProcessing(graph);
+    }
+
+    private static class CollapseFrameForSingleSideEffectClosure extends NodeIteratorClosure<IterationState> {
+
+        private List<IterationState> returnStates = new ArrayList<>();
+        private List<IterationState> unwindStates = new ArrayList<>();
 
         @Override
-        protected StateSplit processNode(FixedNode node, StateSplit currentState) {
-            StateSplit state = currentState;
+        protected IterationState processNode(FixedNode node, IterationState currentState) {
+            IterationState state = currentState;
             if (node instanceof StateSplit) {
                 StateSplit stateSplit = (StateSplit) node;
                 FrameState frameState = stateSplit.stateAfter();
                 if (frameState != null) {
-                    // the stateSplit == currentState case comes from merge handling
-                    if (stateSplit.hasSideEffect() || stateSplit == currentState) {
+                    if (stateSplit.hasSideEffect()) {
                         stateSplit.setStateAfter(createInvalidFrameState(node));
-                        state = stateSplit;
-                    } else if (hasInvalidState(state)) {
+                        state = state.addSideEffect(stateSplit);
+                    } else if (currentState.invalid) {
                         stateSplit.setStateAfter(createInvalidFrameState(node));
                     } else {
                         stateSplit.setStateAfter(null);
@@ -70,53 +140,77 @@
                     }
                 }
             }
-            if (node instanceof ControlSinkNode && state != null) {
-                state.setStateAfter(node.graph().add(new FrameState(FrameState.AFTER_BCI)));
+            if (node instanceof ReturnNode) {
+                returnStates.add(currentState);
+            } else if (node instanceof UnwindNode) {
+                unwindStates.add(currentState);
             }
             return state;
         }
 
         @Override
-        protected StateSplit merge(MergeNode merge, List<StateSplit> states) {
+        protected IterationState merge(MergeNode merge, List<IterationState> states) {
             boolean invalid = false;
-            for (StateSplit state : states) {
-                if (state != null && state.stateAfter() != null && state.stateAfter().bci == FrameState.INVALID_FRAMESTATE_BCI) {
+            for (IterationState state : states) {
+                if (state.invalid) {
                     invalid = true;
-                    state.setStateAfter(merge.graph().add(new FrameState(FrameState.AFTER_BCI)));
+                    break;
                 }
             }
-            if (invalid) {
-                // at the next processNode call, stateSplit == currentState == merge
-                return merge;
-            } else {
-                return null;
+            return IterationState.merge(merge, states, invalid);
+        }
+
+        public void finishProcessing(StructuredGraph graph) {
+            NodeBitMap maskedSideEffects = new NodeBitMap(graph);
+            NodeBitMap returnSideEffects = new NodeBitMap(graph);
+            NodeBitMap unwindSideEffects = new NodeBitMap(graph);
+
+            for (IterationState returnState : returnStates) {
+                returnState.markMasked(returnSideEffects, maskedSideEffects);
+            }
+            for (IterationState unwindState : unwindStates) {
+                unwindState.markMasked(unwindSideEffects, maskedSideEffects);
+            }
+
+            for (Node returnSideEffect : returnSideEffects) {
+                if (!unwindSideEffects.contains(returnSideEffect) && !maskedSideEffects.contains(returnSideEffect)) {
+                    StateSplit split = (StateSplit) returnSideEffect;
+                    if (split.getState() != null) {
+                        split.setStateAfter(graph.add(new FrameState(FrameState.AFTER_BCI)));
+                    }
+                }
+            }
+
+            for (Node unwindSideEffect : unwindSideEffects) {
+                if (!returnSideEffects.contains(unwindSideEffect) && !maskedSideEffects.contains(unwindSideEffect)) {
+                    StateSplit split = (StateSplit) unwindSideEffect;
+                    if (split.getState() != null) {
+                        split.setStateAfter(graph.add(new FrameState(FrameState.AFTER_EXCEPTION_BCI)));
+                    }
+                }
             }
         }
 
         @Override
-        protected StateSplit afterSplit(AbstractBeginNode node, StateSplit oldState) {
-            return oldState;
+        protected IterationState afterSplit(AbstractBeginNode node, IterationState oldState) {
+            return oldState.addBranch(node);
         }
 
         @Override
-        protected Map<LoopExitNode, StateSplit> processLoop(LoopBeginNode loop, StateSplit initialState) {
-            LoopInfo<StateSplit> info = ReentrantNodeIterator.processLoop(this, loop, initialState);
-            if (!hasInvalidState(initialState)) {
-                boolean isNowInvalid = false;
-                for (StateSplit endState : info.endStates.values()) {
-                    isNowInvalid |= hasInvalidState(endState);
-                }
-                if (isNowInvalid) {
-                    loop.setStateAfter(createInvalidFrameState(loop));
-                    info = ReentrantNodeIterator.processLoop(this, loop, loop);
-                }
+        protected Map<LoopExitNode, IterationState> processLoop(LoopBeginNode loop, IterationState initialState) {
+            LoopInfo<IterationState> info = ReentrantNodeIterator.processLoop(this, loop, initialState);
+
+            boolean isNowInvalid = initialState.invalid;
+            for (IterationState endState : info.endStates.values()) {
+                isNowInvalid |= endState.invalid;
             }
-            return info.exitStates;
-        }
 
-        private static boolean hasInvalidState(StateSplit state) {
-            assert state == null || (state.stateAfter() != null && state.stateAfter().bci == FrameState.INVALID_FRAMESTATE_BCI) : state + " " + state.stateAfter();
-            return state != null;
+            if (isNowInvalid) {
+                loop.setStateAfter(createInvalidFrameState(loop));
+            }
+
+            IterationState endState = IterationState.merge(loop, info.endStates.values(), isNowInvalid);
+            return ReentrantNodeIterator.processLoop(this, loop, endState).exitStates;
         }
 
         private static FrameState createInvalidFrameState(FixedNode node) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/GraphKit.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,321 @@
+/*
+ * 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;
+
+import java.lang.reflect.*;
+import java.util.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.java.*;
+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;
+import com.oracle.graal.phases.common.*;
+import com.oracle.graal.phases.util.*;
+import com.oracle.graal.replacements.ReplacementsImpl.FrameStateProcessing;
+import com.oracle.graal.word.phases.*;
+
+/**
+ * A utility for manually creating a graph. This will be expanded as necessary to support all
+ * subsystems that employ manual graph creation (as opposed to {@linkplain GraphBuilderPhase
+ * bytecode parsing} based graph creation).
+ */
+public class GraphKit {
+
+    protected final Providers providers;
+    protected final StructuredGraph graph;
+    protected FixedWithNextNode lastFixedNode;
+
+    private final List<Structure> structures;
+
+    abstract static class Structure {
+    }
+
+    public GraphKit(StructuredGraph graph, Providers providers) {
+        this.providers = providers;
+        this.graph = graph;
+        this.lastFixedNode = graph.start();
+
+        structures = new ArrayList<>();
+        /* Add a dummy element, so that the access of the last element never leads to an exception. */
+        structures.add(new Structure() {
+        });
+    }
+
+    public StructuredGraph getGraph() {
+        return graph;
+    }
+
+    /**
+     * Ensures a floating node is added to or already present in the graph via {@link Graph#unique}.
+     * 
+     * @return a node similar to {@code node} if one exists, otherwise {@code node}
+     */
+    public <T extends FloatingNode> T unique(T node) {
+        return graph.unique(node);
+    }
+
+    /**
+     * Appends a fixed node to the graph.
+     */
+    public <T extends FixedNode> T append(T node) {
+        T result = graph.add(node);
+        assert lastFixedNode != null;
+        assert result.predecessor() == null;
+        graph.addAfterFixed(lastFixedNode, result);
+        if (result instanceof FixedWithNextNode) {
+            lastFixedNode = (FixedWithNextNode) result;
+        } else {
+            lastFixedNode = null;
+        }
+        return result;
+    }
+
+    public InvokeNode createInvoke(Class<?> declaringClass, String name, ValueNode... args) {
+        return createInvoke(declaringClass, name, InvokeKind.Static, null, FrameState.UNKNOWN_BCI, args);
+    }
+
+    /**
+     * Creates and appends an {@link InvokeNode} for a call to a given method with a given set of
+     * arguments. The method is looked up via reflection based on the declaring class and name.
+     * 
+     * @param declaringClass the class declaring the invoked method
+     * @param name the name of the invoked method
+     * @param args the arguments to the invocation
+     */
+    public InvokeNode createInvoke(Class<?> declaringClass, String name, InvokeKind invokeKind, FrameStateBuilder frameStateBuilder, int bci, ValueNode... args) {
+        boolean isStatic = invokeKind == InvokeKind.Static;
+        ResolvedJavaMethod method = null;
+        for (Method m : declaringClass.getDeclaredMethods()) {
+            if (Modifier.isStatic(m.getModifiers()) == isStatic && m.getName().equals(name)) {
+                assert method == null : "found more than one method in " + declaringClass + " named " + name;
+                method = providers.getMetaAccess().lookupJavaMethod(m);
+            }
+        }
+        assert method != null : "did not find method in " + declaringClass + " named " + name;
+        return createInvoke(method, invokeKind, frameStateBuilder, bci, args);
+    }
+
+    /**
+     * Creates and appends an {@link InvokeNode} for a call to a given method with a given set of
+     * arguments.
+     */
+    public InvokeNode createInvoke(ResolvedJavaMethod method, InvokeKind invokeKind, FrameStateBuilder frameStateBuilder, int bci, ValueNode... args) {
+        assert Modifier.isStatic(method.getModifiers()) == (invokeKind == InvokeKind.Static);
+        Signature signature = method.getSignature();
+        JavaType returnType = signature.getReturnType(null);
+        assert checkArgs(method, args);
+        MethodCallTargetNode callTarget = graph.add(createMethodCallTarget(invokeKind, method, args, returnType, bci));
+        InvokeNode invoke = append(new InvokeNode(callTarget, bci));
+
+        if (frameStateBuilder != null) {
+            if (invoke.kind() != Kind.Void) {
+                frameStateBuilder.push(invoke.kind(), invoke);
+            }
+            invoke.setStateAfter(frameStateBuilder.create(0));
+            if (invoke.kind() != Kind.Void) {
+                frameStateBuilder.pop(invoke.kind());
+            }
+        }
+        return invoke;
+    }
+
+    protected MethodCallTargetNode createMethodCallTarget(InvokeKind invokeKind, ResolvedJavaMethod targetMethod, ValueNode[] args, JavaType returnType, @SuppressWarnings("unused") int bci) {
+        return new MethodCallTargetNode(invokeKind, targetMethod, args, returnType);
+    }
+
+    /**
+     * Determines if a given set of arguments is compatible with the signature of a given method.
+     * 
+     * @return true if {@code args} are compatible with the signature if {@code method}
+     * @throws AssertionError if {@code args} are not compatible with the signature if
+     *             {@code method}
+     */
+    public boolean checkArgs(ResolvedJavaMethod method, ValueNode... args) {
+        Signature signature = method.getSignature();
+        boolean isStatic = Modifier.isStatic(method.getModifiers());
+        if (signature.getParameterCount(!isStatic) != args.length) {
+            throw new AssertionError(graph + ": wrong number of arguments to " + method);
+        }
+        int paramNum = 0;
+        for (int i = 0; i != args.length; i++) {
+            Kind expected;
+            if (i == 0 && !isStatic) {
+                expected = Kind.Object;
+            } else {
+                expected = signature.getParameterKind(paramNum++).getStackKind();
+            }
+            Kind actual = args[i].stamp().getStackKind();
+            if (expected != actual) {
+                throw new AssertionError(graph + ": wrong kind of value for argument " + i + " of call to " + method + " [" + actual + " != " + expected + "]");
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Rewrite all word types in the graph.
+     */
+    public void rewriteWordTypes() {
+        new WordTypeRewriterPhase(providers.getMetaAccess(), providers.getCodeCache().getTarget().wordKind).apply(graph);
+    }
+
+    /**
+     * {@linkplain #inline(InvokeNode) Inlines} all invocations currently in the graph.
+     */
+    public void inlineInvokes() {
+        for (InvokeNode invoke : graph.getNodes().filter(InvokeNode.class).snapshot()) {
+            inline(invoke);
+        }
+
+        // Clean up all code that is now dead after inlining.
+        new DeadCodeEliminationPhase().apply(graph);
+        assert graph.getNodes().filter(InvokeNode.class).isEmpty();
+    }
+
+    /**
+     * Inlines a given invocation to a method. The graph of the inlined method is
+     * {@linkplain ReplacementsImpl#makeGraph processed} in the same manner as for snippets and
+     * method substitutions.
+     */
+    public void inline(InvokeNode invoke) {
+        ResolvedJavaMethod method = ((MethodCallTargetNode) invoke.callTarget()).targetMethod();
+        ReplacementsImpl repl = new ReplacementsImpl(providers, new Assumptions(false), providers.getCodeCache().getTarget());
+        StructuredGraph calleeGraph = repl.makeGraph(method, null, method, null, FrameStateProcessing.CollapseFrameForSingleSideEffect);
+        InliningUtil.inline(invoke, calleeGraph, false);
+    }
+
+    protected void pushStructure(Structure structure) {
+        structures.add(structure);
+    }
+
+    protected <T extends Structure> T getTopStructure(Class<T> expectedClass) {
+        return expectedClass.cast(structures.get(structures.size() - 1));
+    }
+
+    protected void popStructure() {
+        structures.remove(structures.size() - 1);
+    }
+
+    protected enum IfState {
+        CONDITION, THEN_PART, ELSE_PART, FINISHED
+    }
+
+    static class IfStructure extends Structure {
+        protected IfState state;
+        protected FixedNode thenPart;
+        protected FixedNode elsePart;
+    }
+
+    /**
+     * Starts an if-block. This call can be followed by a call to {@link #thenPart} to start
+     * emitting the code executed when the condition hold; and a call to {@link #elsePart} to start
+     * emititng the code when the condition does not hold. It must be followed by a call to
+     * {@link #endIf} to close the if-block.
+     * 
+     * @param condition The condition for the if-block
+     * @param trueProbability The estimated probability the the condition is true
+     */
+    public void startIf(LogicNode condition, double trueProbability) {
+        BeginNode thenSuccessor = graph.add(new BeginNode());
+        BeginNode elseSuccessor = graph.add(new BeginNode());
+        append(new IfNode(condition, thenSuccessor, elseSuccessor, trueProbability));
+        lastFixedNode = null;
+
+        IfStructure s = new IfStructure();
+        s.state = IfState.CONDITION;
+        s.thenPart = thenSuccessor;
+        s.elsePart = elseSuccessor;
+        pushStructure(s);
+    }
+
+    private IfStructure saveLastNode() {
+        IfStructure s = getTopStructure(IfStructure.class);
+        switch (s.state) {
+            case CONDITION:
+                assert lastFixedNode == null;
+                break;
+            case THEN_PART:
+                s.thenPart = lastFixedNode;
+                break;
+            case ELSE_PART:
+                s.elsePart = lastFixedNode;
+                break;
+            case FINISHED:
+                assert false;
+                break;
+        }
+        lastFixedNode = null;
+        return s;
+    }
+
+    public void thenPart() {
+        IfStructure s = saveLastNode();
+        lastFixedNode = (FixedWithNextNode) s.thenPart;
+        s.state = IfState.THEN_PART;
+    }
+
+    public void elsePart() {
+        IfStructure s = saveLastNode();
+        lastFixedNode = (FixedWithNextNode) s.elsePart;
+        s.state = IfState.ELSE_PART;
+    }
+
+    public void endIf() {
+        IfStructure s = saveLastNode();
+
+        FixedWithNextNode thenPart = s.thenPart instanceof FixedWithNextNode ? (FixedWithNextNode) s.thenPart : null;
+        FixedWithNextNode elsePart = s.elsePart instanceof FixedWithNextNode ? (FixedWithNextNode) s.elsePart : null;
+
+        if (thenPart != null && elsePart != null) {
+            /* Both parts are alive, we need a real merge. */
+            EndNode thenEnd = graph.add(new EndNode());
+            graph.addAfterFixed(thenPart, thenEnd);
+            EndNode elseEnd = graph.add(new EndNode());
+            graph.addAfterFixed(elsePart, elseEnd);
+
+            MergeNode merge = graph.add(new MergeNode());
+            merge.addForwardEnd(thenEnd);
+            merge.addForwardEnd(elseEnd);
+
+            lastFixedNode = merge;
+
+        } else if (thenPart != null) {
+            /* elsePart ended with a control sink, so we can continue with thenPart. */
+            lastFixedNode = thenPart;
+
+        } else if (elsePart != null) {
+            /* thenPart ended with a control sink, so we can continue with elsePart. */
+            lastFixedNode = elsePart;
+
+        } else {
+            /* Both parts ended with a control sink, so no nodes can be added after the if. */
+            assert lastFixedNode == null;
+        }
+        s.state = IfState.FINISHED;
+        popStructure();
+    }
+}
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeClassSubstitutions.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeClassSubstitutions.java	Wed Mar 05 19:40:15 2014 -0800
@@ -64,12 +64,12 @@
 
     @MethodSubstitution
     private static Node getNode(Node node, long offset) {
-        return PiNode.piCast(UnsafeLoadNode.load(node, offset, Kind.Object, LocationIdentity.ANY_LOCATION), Node.class, false, false);
+        return PiNode.piCast(UnsafeLoadNode.load(node, offset, Kind.Object, LocationIdentity.ANY_LOCATION), Node.class);
     }
 
     @MethodSubstitution
     private static NodeList getNodeList(Node node, long offset) {
-        return PiNode.piCast(UnsafeLoadNode.load(node, offset, Kind.Object, LocationIdentity.ANY_LOCATION), NodeList.class, false, false);
+        return PiNode.piCast(UnsafeLoadNode.load(node, offset, Kind.Object, LocationIdentity.ANY_LOCATION), NodeList.class);
     }
 
     @MethodSubstitution
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java	Wed Mar 05 19:40:15 2014 -0800
@@ -133,9 +133,12 @@
         }
         StructuredGraph graph = graphs.get(substitute);
         if (graph == null) {
-            graphs.putIfAbsent(substitute, makeGraph(substitute, original, substitute, inliningPolicy(substitute), FrameStateProcessing.None));
+            graph = makeGraph(substitute, original, substitute, inliningPolicy(substitute), FrameStateProcessing.None);
+            graph.freeze();
+            graphs.putIfAbsent(substitute, graph);
             graph = graphs.get(substitute);
         }
+        assert graph.isFrozen();
         return graph;
 
     }
@@ -198,7 +201,9 @@
                     }
                 }
             }
-            if (macroSubstitution != null) {
+            // We don't have per method guards for macro substitutions but at least respect the
+            // defaultGuard if there is one.
+            if (macroSubstitution != null && (defaultGuard == null || defaultGuard.execute())) {
                 String originalName = originalName(substituteMethod, macroSubstitution.value());
                 JavaSignature originalSignature = originalSignature(substituteMethod, macroSubstitution.signature(), macroSubstitution.isStatic());
                 Member originalMethod = originalMethod(classSubstitution, macroSubstitution.optional(), originalName, originalSignature);
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java	Wed Mar 05 19:40:15 2014 -0800
@@ -526,8 +526,10 @@
                 ParameterNode[] params = new ParameterNode[length];
                 Stamp stamp = varargs.stamp;
                 for (int j = 0; j < length; j++) {
-                    assert (parameterCount & 0xFFFF) == parameterCount;
-                    int idx = i << 16 | j;
+                    // Use a decimal friendly numbering make it more obvious how values map
+                    assert parameterCount < 10000;
+                    int idx = (i + 1) * 10000 + j;
+                    assert idx >= parameterCount : "collision in parameter numbering";
                     ParameterNode local = snippetCopy.unique(new ParameterNode(idx, stamp));
                     params[j] = local;
                 }
@@ -542,6 +544,11 @@
                         LoadSnippetVarargParameterNode loadSnippetParameter = snippetCopy.add(new LoadSnippetVarargParameterNode(params, loadIndexed.index(), loadIndexed.stamp()));
                         snippetCopy.replaceFixedWithFixed(loadIndexed, loadSnippetParameter);
                         Debug.dump(snippetCopy, "After replacing %s", loadIndexed);
+                    } else if (usage instanceof StoreIndexedNode) {
+                        // The template lowering doesn't really treat this as an array so you can't
+                        // store back into the varargs. Allocate your own array if you really need
+                        // this and EA should eliminate it.
+                        throw new GraalInternalError("Can't store into VarargsParameter array");
                     }
                 }
             } else {
@@ -569,11 +576,7 @@
                     LoopTransformations.fullUnroll(loop, phaseContext, new CanonicalizerPhase(true));
                     new CanonicalizerPhase(true).applyIncremental(snippetCopy, phaseContext, mark);
                 }
-                FixedNode explodeLoopNext = explodeLoop.next();
-                explodeLoop.clearSuccessors();
-                explodeLoop.replaceAtPredecessor(explodeLoopNext);
-                explodeLoop.replaceAtUsages(null);
-                GraphUtil.killCFG(explodeLoop);
+                GraphUtil.removeFixedWithUnusedInputs(explodeLoop);
                 exploded = true;
             }
         } while (exploded);
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/StringSubstitutions.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/StringSubstitutions.java	Wed Mar 05 19:40:15 2014 -0800
@@ -66,9 +66,9 @@
             return true;
         }
 
-        final char[] thisArray = (char[]) unsafe.getObject(thisString, valueOffset);
-        final char[] thatArray = (char[]) unsafe.getObject(thatString, valueOffset);
+        final char[] array1 = (char[]) unsafe.getObject(thisString, valueOffset);
+        final char[] array2 = (char[]) unsafe.getObject(thatString, valueOffset);
 
-        return CharArrayEqualsNode.equals(thisArray, thatArray, thisArray.length);
+        return ArrayEqualsNode.equals(array1, array2, array1.length);
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/ArrayEqualsNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,137 @@
+/*
+ * 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.replacements.nodes;
+
+import java.util.*;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.compiler.gen.*;
+import com.oracle.graal.compiler.target.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
+import com.oracle.graal.lir.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.calc.*;
+import com.oracle.graal.nodes.type.*;
+
+/**
+ * Compares two arrays with the same length.
+ */
+public class ArrayEqualsNode extends FloatingNode implements LIRGenLowerable, Canonicalizable {
+
+    /** {@link Kind} of the arrays to compare. */
+    private final Kind kind;
+
+    /** One array to be tested for equality. */
+    @Input private ValueNode array1;
+
+    /** The other array to be tested for equality. */
+    @Input private ValueNode array2;
+
+    /** Length of both arrays. */
+    @Input private ValueNode length;
+
+    public ArrayEqualsNode(ValueNode array1, ValueNode array2, ValueNode length) {
+        super(StampFactory.forKind(Kind.Boolean));
+
+        assert array1.stamp().equals(array2.stamp());
+        ObjectStamp stamp = (ObjectStamp) array1.stamp();
+        ResolvedJavaType componentType = stamp.type().getComponentType();
+        this.kind = componentType.getKind();
+
+        this.array1 = array1;
+        this.array2 = array2;
+        this.length = length;
+    }
+
+    @Override
+    public Node canonical(CanonicalizerTool tool) {
+        if (!array1.isConstant() || !array2.isConstant()) {
+            return this;
+        }
+
+        Object a1 = array1.asConstant().asObject();
+        Object a2 = array2.asConstant().asObject();
+        boolean x;
+        switch (kind) {
+            case Boolean:
+                x = Arrays.equals((boolean[]) a1, (boolean[]) a2);
+                break;
+            case Byte:
+                x = Arrays.equals((byte[]) a1, (byte[]) a2);
+                break;
+            case Char:
+                x = Arrays.equals((char[]) a1, (char[]) a2);
+                break;
+            case Short:
+                x = Arrays.equals((short[]) a1, (short[]) a2);
+                break;
+            case Int:
+                x = Arrays.equals((int[]) a1, (int[]) a2);
+                break;
+            case Long:
+                x = Arrays.equals((long[]) a1, (long[]) a2);
+                break;
+            case Float:
+                x = Arrays.equals((float[]) a1, (float[]) a2);
+                break;
+            case Double:
+                x = Arrays.equals((double[]) a1, (double[]) a2);
+                break;
+            default:
+                throw GraalInternalError.shouldNotReachHere("unknown kind " + kind);
+        }
+        return ConstantNode.forBoolean(x, graph());
+    }
+
+    @NodeIntrinsic
+    public static native boolean equals(boolean[] array1, boolean[] array2, int length);
+
+    @NodeIntrinsic
+    public static native boolean equals(byte[] array1, byte[] array2, int length);
+
+    @NodeIntrinsic
+    public static native boolean equals(char[] array1, char[] array2, int length);
+
+    @NodeIntrinsic
+    public static native boolean equals(short[] array1, short[] array2, int length);
+
+    @NodeIntrinsic
+    public static native boolean equals(int[] array1, int[] array2, int length);
+
+    @NodeIntrinsic
+    public static native boolean equals(long[] array1, long[] array2, int length);
+
+    @NodeIntrinsic
+    public static native boolean equals(float[] array1, float[] array2, int length);
+
+    @NodeIntrinsic
+    public static native boolean equals(double[] array1, double[] array2, int length);
+
+    @Override
+    public void generate(LIRGenerator gen) {
+        Variable result = gen.newVariable(Kind.Int);
+        gen.emitArrayEquals(kind, result, gen.operand(array1), gen.operand(array2), gen.operand(length));
+        gen.setResult(this, result);
+    }
+}
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BitCountNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BitCountNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -37,18 +37,18 @@
     @Input private ValueNode value;
 
     public BitCountNode(ValueNode value) {
-        super(StampFactory.forInteger(Kind.Int, 0, value.kind().getBitCount()));
+        super(StampFactory.forInteger(Kind.Int, 0, ((PrimitiveStamp) value.stamp()).getBits()));
         this.value = value;
     }
 
     @Override
     public Node canonical(CanonicalizerTool tool) {
         if (value.isConstant()) {
-            long v = value.asConstant().asLong();
-            if (value.kind().getStackKind() == Kind.Int) {
-                return ConstantNode.forInt(Integer.bitCount((int) v), graph());
-            } else if (value.kind() == Kind.Long) {
-                return ConstantNode.forInt(Long.bitCount(v), graph());
+            Constant c = value.asConstant();
+            if (c.getKind() == Kind.Int) {
+                return ConstantNode.forInt(Integer.bitCount(c.asInt()), graph());
+            } else if (c.getKind() == Kind.Long) {
+                return ConstantNode.forInt(Long.bitCount(c.asLong()), graph());
             }
         }
         return this;
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BitScanForwardNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BitScanForwardNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -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
@@ -37,18 +37,18 @@
     @Input private ValueNode value;
 
     public BitScanForwardNode(ValueNode value) {
-        super(StampFactory.forInteger(Kind.Int, 0, value.kind().getBitCount()));
+        super(StampFactory.forInteger(Kind.Int, 0, ((PrimitiveStamp) value.stamp()).getBits()));
         this.value = value;
     }
 
     @Override
     public Node canonical(CanonicalizerTool tool) {
         if (value.isConstant()) {
-            long v = value.asConstant().asLong();
-            if (value.kind().getStackKind() == Kind.Int) {
-                return ConstantNode.forInt(Integer.numberOfTrailingZeros((int) v), graph());
-            } else if (value.kind() == Kind.Long) {
-                return ConstantNode.forInt(Long.numberOfTrailingZeros(v), graph());
+            Constant c = value.asConstant();
+            if (c.getKind() == Kind.Int) {
+                return ConstantNode.forInt(Integer.numberOfTrailingZeros(c.asInt()), graph());
+            } else if (c.getKind() == Kind.Long) {
+                return ConstantNode.forInt(Long.numberOfTrailingZeros(c.asLong()), graph());
             }
         }
         return this;
@@ -66,6 +66,11 @@
         return index;
     }
 
+    @NodeIntrinsic
+    public static int scan(int v) {
+        return scan(v & 0xFFFFFFFFL);
+    }
+
     @Override
     public void generate(LIRGenerator gen) {
         Variable result = gen.newVariable(Kind.Int);
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BitScanReverseNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BitScanReverseNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -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
@@ -37,18 +37,18 @@
     @Input private ValueNode value;
 
     public BitScanReverseNode(ValueNode value) {
-        super(StampFactory.forInteger(Kind.Int, 0, value.kind().getBitCount()));
+        super(StampFactory.forInteger(Kind.Int, 0, ((PrimitiveStamp) value.stamp()).getBits()));
         this.value = value;
     }
 
     @Override
     public Node canonical(CanonicalizerTool tool) {
         if (value.isConstant()) {
-            long v = value.asConstant().asLong();
-            if (value.kind().getStackKind() == Kind.Int) {
-                return ConstantNode.forInt(31 - Integer.numberOfLeadingZeros((int) v), graph());
-            } else if (value.kind() == Kind.Long) {
-                return ConstantNode.forInt(63 - Long.numberOfLeadingZeros(v), graph());
+            Constant c = value.asConstant();
+            if (c.getKind() == Kind.Int) {
+                return ConstantNode.forInt(31 - Integer.numberOfLeadingZeros(c.asInt()), graph());
+            } else if (c.getKind() == Kind.Long) {
+                return ConstantNode.forInt(63 - Long.numberOfLeadingZeros(c.asLong()), graph());
             }
         }
         return this;
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/CharArrayEqualsNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,73 +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.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle 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.nodes;
-
-import java.util.*;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.compiler.gen.*;
-import com.oracle.graal.compiler.target.*;
-import com.oracle.graal.graph.*;
-import com.oracle.graal.graph.spi.*;
-import com.oracle.graal.lir.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.calc.*;
-import com.oracle.graal.nodes.type.*;
-
-/**
- * Compares two {@code char} arrays with the same length.
- */
-public class CharArrayEqualsNode extends FloatingNode implements LIRGenLowerable, Canonicalizable {
-
-    @Input private ValueNode thisArray;
-    @Input private ValueNode thatArray;
-    @Input private ValueNode length;
-
-    public CharArrayEqualsNode(ValueNode thisArray, ValueNode thatArray, ValueNode length) {
-        super(StampFactory.forKind(Kind.Boolean));
-        this.thisArray = thisArray;
-        this.thatArray = thatArray;
-        this.length = length;
-    }
-
-    @Override
-    public Node canonical(CanonicalizerTool tool) {
-        if (thisArray.isConstant() && thatArray.isConstant()) {
-            char[] array1 = (char[]) thisArray.asConstant().asObject();
-            char[] array2 = (char[]) thatArray.asConstant().asObject();
-            final boolean result = Arrays.equals(array1, array2);
-            return ConstantNode.forBoolean(result, graph());
-        }
-        return this;
-    }
-
-    @NodeIntrinsic
-    public static native boolean equals(char[] thisArray, char[] thatArray, int length);
-
-    @Override
-    public void generate(LIRGenerator gen) {
-        Variable result = gen.newVariable(Kind.Boolean);
-        gen.emitCharArrayEquals(result, gen.operand(thisArray), gen.operand(thatArray), gen.operand(length));
-        gen.setResult(this, result);
-    }
-}
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MacroNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MacroNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -24,8 +24,6 @@
 
 import static java.lang.reflect.Modifier.*;
 
-import java.lang.reflect.*;
-
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.debug.Debug.Scope;
@@ -47,6 +45,7 @@
     private final int bci;
     private final ResolvedJavaMethod targetMethod;
     private final JavaType returnType;
+    private final InvokeKind invokeKind;
 
     protected MacroNode(Invoke invoke) {
         super(invoke.asNode().stamp(), invoke.stateAfter());
@@ -55,6 +54,7 @@
         this.bci = invoke.bci();
         this.targetMethod = methodCallTarget.targetMethod();
         this.returnType = methodCallTarget.returnType();
+        this.invokeKind = methodCallTarget.invokeKind();
     }
 
     public int getBci() {
@@ -148,17 +148,21 @@
         }
     }
 
-    private InvokeNode replaceWithInvoke() {
+    protected InvokeNode replaceWithInvoke() {
         InvokeNode invoke = createInvoke();
         graph().replaceFixedWithFixed(this, invoke);
         return invoke;
     }
 
     protected InvokeNode createInvoke() {
-        InvokeKind invokeKind = Modifier.isStatic(targetMethod.getModifiers()) ? InvokeKind.Static : InvokeKind.Special;
         MethodCallTargetNode callTarget = graph().add(new MethodCallTargetNode(invokeKind, targetMethod, arguments.toArray(new ValueNode[arguments.size()]), returnType));
         InvokeNode invoke = graph().add(new InvokeNode(callTarget, bci));
-        invoke.setStateAfter(stateAfter());
+        if (stateAfter() != null) {
+            invoke.setStateAfter(stateAfter().duplicate());
+            if (kind() != Kind.Void) {
+                invoke.stateAfter().replaceFirstInput(this, invoke);
+            }
+        }
         return invoke;
     }
 
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MathIntrinsicNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MathIntrinsicNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -48,8 +48,8 @@
     }
 
     public MathIntrinsicNode(ValueNode x, Operation op) {
-        super(StampFactory.forKind(x.kind()));
-        assert x.kind() == Kind.Double;
+        super(StampFactory.forKind(Kind.Double));
+        assert x.stamp() instanceof FloatStamp && PrimitiveStamp.getBits(x.stamp()) == 64;
         this.x = x;
         this.operation = op;
     }
--- a/graal/com.oracle.graal.test/src/com/oracle/graal/test/GraalTest.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.test/src/com/oracle/graal/test/GraalTest.java	Wed Mar 05 19:40:15 2014 -0800
@@ -23,6 +23,7 @@
 package com.oracle.graal.test;
 
 import java.lang.reflect.*;
+import java.util.*;
 
 import org.junit.*;
 import org.junit.runner.*;
@@ -36,8 +37,12 @@
 public class GraalTest {
 
     protected Method getMethod(String methodName) {
+        return getMethod(getClass(), methodName);
+    }
+
+    protected Method getMethod(Class<?> clazz, String methodName) {
         Method found = null;
-        for (Method m : this.getClass().getMethods()) {
+        for (Method m : clazz.getMethods()) {
             if (m.getName().equals(methodName)) {
                 Assert.assertNull(found);
                 found = m;
@@ -49,4 +54,12 @@
             throw new RuntimeException("method not found: " + methodName);
         }
     }
+
+    protected Method getMethod(Class<?> clazz, String methodName, Class<?>[] parameterTypes) {
+        try {
+            return clazz.getMethod(methodName, parameterTypes);
+        } catch (NoSuchMethodException | SecurityException e) {
+            throw new RuntimeException("method not found: " + methodName + "" + Arrays.toString(parameterTypes));
+        }
+    }
 }
--- a/graal/com.oracle.graal.truffle.hotspot.amd64/src/com/oracle/graal/truffle/hotspot/amd64/AMD64OptimizedCallTargetInstrumentationFactory.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.truffle.hotspot.amd64/src/com/oracle/graal/truffle/hotspot/amd64/AMD64OptimizedCallTargetInstrumentationFactory.java	Wed Mar 05 19:40:15 2014 -0800
@@ -41,7 +41,7 @@
 @ServiceProvider(OptimizedCallTargetInstrumentationFactory.class)
 public class AMD64OptimizedCallTargetInstrumentationFactory implements OptimizedCallTargetInstrumentationFactory {
 
-    public CompilationResultBuilder createBuilder(CodeCacheProvider codeCache, ForeignCallsProvider foreignCalls, FrameMap frameMap, AbstractAssembler asm, FrameContext frameContext,
+    public CompilationResultBuilder createBuilder(CodeCacheProvider codeCache, ForeignCallsProvider foreignCalls, FrameMap frameMap, Assembler asm, FrameContext frameContext,
                     CompilationResult compilationResult) {
         return new OptimizedCallTargetInstrumentation(codeCache, foreignCalls, frameMap, asm, frameContext, compilationResult) {
             @Override
@@ -51,14 +51,14 @@
                 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.codeBuffer.position();
+                int verifiedEntryPoint = asm.position();
                 if (config.useCompressedOops) {
                     asm.movl(spillRegister, nMethodAddress);
-                    asm.nop(AMD64HotSpotBackend.PATCHED_VERIFIED_ENTRY_POINT_INSTRUCTION_SIZE - (asm.codeBuffer.position() - verifiedEntryPoint));
+                    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.codeBuffer.position() - verifiedEntryPoint));
+                    asm.nop(AMD64HotSpotBackend.PATCHED_VERIFIED_ENTRY_POINT_INSTRUCTION_SIZE - (asm.position() - verifiedEntryPoint));
                 }
                 Label doProlog = new Label();
 
@@ -81,7 +81,7 @@
 
     public void setInstrumentedMethod(ResolvedJavaMethod method) {
         HotSpotResolvedJavaMethod hsMethod = (HotSpotResolvedJavaMethod) method;
-        hsMethod.setDontInline();
+        hsMethod.setNotInlineable();
     }
 
     public String getArchitecture() {
--- a/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/OptimizedCallTargetInstrumentation.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/OptimizedCallTargetInstrumentation.java	Wed Mar 05 19:40:15 2014 -0800
@@ -43,7 +43,7 @@
  */
 public abstract class OptimizedCallTargetInstrumentation extends CompilationResultBuilder {
 
-    public OptimizedCallTargetInstrumentation(CodeCacheProvider codeCache, ForeignCallsProvider foreignCalls, FrameMap frameMap, AbstractAssembler asm, FrameContext frameContext,
+    public OptimizedCallTargetInstrumentation(CodeCacheProvider codeCache, ForeignCallsProvider foreignCalls, FrameMap frameMap, Assembler asm, FrameContext frameContext,
                     CompilationResult compilationResult) {
         super(codeCache, foreignCalls, frameMap, asm, frameContext, compilationResult);
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/ControlFlowExceptionPartialEvaluationTest.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,102 @@
+/*
+ * 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.test;
+
+import org.junit.*;
+
+import com.oracle.graal.truffle.test.nodes.*;
+import com.oracle.truffle.api.frame.*;
+import com.oracle.truffle.api.nodes.*;
+
+@Ignore("Currently ignored due to problems with code coverage tools.")
+public class ControlFlowExceptionPartialEvaluationTest extends PartialEvaluationTest {
+
+    public static Object constant42() {
+        return 42;
+    }
+
+    @Test
+    public void catchControlFlowException() {
+        FrameDescriptor fd = new FrameDescriptor();
+        AbstractTestNode result = new CatchControlFlowExceptionTestNode(new ThrowControlFlowExceptionTestNode());
+        assertPartialEvalEquals("constant42", new RootTestNode(fd, "catchControlFlowException", result));
+    }
+
+    @Test
+    public void catchSlowPathAndControlFlowException() {
+        FrameDescriptor fd = new FrameDescriptor();
+        AbstractTestNode result = new CatchSlowPathAndControlFlowExceptionTestNode(new ThrowControlFlowExceptionTestNode());
+        assertPartialEvalEquals("constant42", new RootTestNode(fd, "catchSlowPathAndControlFlowException", result));
+    }
+
+    public static class ThrowControlFlowExceptionTestNode extends AbstractTestNode {
+
+        @Override
+        public int execute(VirtualFrame frame) {
+            throw new ControlFlowException();
+        }
+    }
+
+    public static class CatchControlFlowExceptionTestNode extends AbstractTestNode {
+
+        @Child private AbstractTestNode child;
+
+        public CatchControlFlowExceptionTestNode(AbstractTestNode child) {
+            this.child = adoptChild(child);
+        }
+
+        @Override
+        public int execute(VirtualFrame frame) {
+            try {
+                return child.execute(frame);
+            } catch (ControlFlowException e) {
+                return 42;
+            }
+        }
+    }
+
+    public static class CatchSlowPathAndControlFlowExceptionTestNode extends AbstractTestNode {
+
+        @Child private AbstractTestNode child;
+
+        public CatchSlowPathAndControlFlowExceptionTestNode(AbstractTestNode child) {
+            this.child = adoptChild(child);
+        }
+
+        @Override
+        public int execute(VirtualFrame frame) {
+            try {
+                return executeChild(frame);
+            } catch (SlowPathException spe) {
+                return -1;
+            } catch (ControlFlowException e) {
+                return 42;
+            }
+        }
+
+        @SuppressWarnings("unused")
+        private int executeChild(VirtualFrame frame) throws SlowPathException {
+            return child.execute(frame);
+        }
+    }
+}
--- a/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/PartialEvaluationTest.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/PartialEvaluationTest.java	Wed Mar 05 19:40:15 2014 -0800
@@ -27,7 +27,6 @@
 import org.junit.*;
 
 import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.runtime.*;
 import com.oracle.graal.compiler.test.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.debug.Debug.Scope;
@@ -39,9 +38,7 @@
 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.graal.virtual.phases.ea.*;
 import com.oracle.truffle.api.*;
@@ -50,15 +47,12 @@
 public class PartialEvaluationTest extends GraalCompilerTest {
 
     private static final long UNROLL_LIMIT = 100;
-    private final PartialEvaluator partialEvaluator;
+    private final TruffleCompilerImpl truffleCompiler;
 
     public PartialEvaluationTest() {
         // Make sure Truffle runtime is initialized.
         Assert.assertTrue(Truffle.getRuntime() instanceof GraalTruffleRuntime);
-        Replacements truffleReplacements = ((GraalTruffleRuntime) Truffle.getRuntime()).getReplacements();
-        Providers providers = getProviders().copyWith(truffleReplacements);
-        TruffleCache truffleCache = new TruffleCache(providers, GraphBuilderConfiguration.getDefault(), TruffleCompilerImpl.Optimizations);
-        this.partialEvaluator = new PartialEvaluator(Graal.getRequiredCapability(RuntimeProvider.class), providers, truffleCache);
+        this.truffleCompiler = new TruffleCompilerImpl();
 
         DebugEnvironment.initialize(System.out);
     }
@@ -70,7 +64,7 @@
     protected InstalledCode assertPartialEvalEquals(String methodName, RootNode root, Arguments arguments) {
         Assumptions assumptions = new Assumptions(true);
         StructuredGraph actual = partialEval(root, arguments, assumptions, true);
-        InstalledCode result = new TruffleCompilerImpl().compileMethodHelper(actual, GraphBuilderConfiguration.getDefault(), assumptions, root.toString());
+        InstalledCode result = truffleCompiler.compileMethodHelper(actual, assumptions, root.toString(), getSpeculationLog());
         StructuredGraph expected = parseForComparison(methodName);
         removeFrameStates(actual);
         Assert.assertEquals(getCanonicalGraphString(expected, true), getCanonicalGraphString(actual, true));
@@ -94,15 +88,14 @@
         final OptimizedCallTarget compilable = (OptimizedCallTarget) Truffle.getRuntime().createCallTarget(root);
 
         // Executed AST so that all classes are loaded and initialized.
-        do {
-            compilable.call(null, arguments);
-            compilable.call(null, arguments);
-            compilable.call(null, arguments);
-        } while (compilable.inline());
+        compilable.call(null, arguments);
+        compilable.call(null, arguments);
+        compilable.call(null, arguments);
+        compilable.performInlining();
 
         try (Scope s = Debug.scope("TruffleCompilation", new TruffleDebugJavaMethod(compilable))) {
 
-            StructuredGraph resultGraph = partialEvaluator.createGraph(compilable, assumptions);
+            StructuredGraph resultGraph = truffleCompiler.getPartialEvaluator().createGraph(compilable, assumptions);
             CanonicalizerPhase canonicalizer = new CanonicalizerPhase(canonicalizeReads);
             PhaseContext context = new PhaseContext(getProviders(), assumptions);
 
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/CompilationProfile.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/CompilationProfile.java	Wed Mar 05 19:40:15 2014 -0800
@@ -24,11 +24,10 @@
 
 import static com.oracle.graal.truffle.TruffleCompilerOptions.*;
 
+import java.util.*;
+
 public class CompilationProfile {
 
-    private int invokeCounter;
-    private int originalInvokeCounter;
-    private int loopAndInvokeCounter;
     /**
      * Number of times an installed code for this tree was invalidated.
      */
@@ -41,17 +40,41 @@
 
     private long previousTimestamp;
 
-    private final int compilationThreshold;
     private final String name;
 
+    private int callCount;
+    private int callAndLoopCount;
+    private int compilationCallThreshold;
+    private int compilationCallAndLoopThreshold;
+
+    private final int originalInvokeCounter;
+    private final int originalCompilationThreshold;
+
     public CompilationProfile(final int compilationThreshold, final int initialInvokeCounter, final String name) {
-        this.invokeCounter = initialInvokeCounter;
-        this.loopAndInvokeCounter = compilationThreshold;
-        this.originalInvokeCounter = compilationThreshold;
         this.previousTimestamp = System.nanoTime();
+        this.compilationCallThreshold = initialInvokeCounter;
+        this.compilationCallAndLoopThreshold = compilationThreshold;
+        this.originalInvokeCounter = initialInvokeCounter;
+        this.originalCompilationThreshold = compilationThreshold;
+        this.name = name;
+    }
 
-        this.compilationThreshold = compilationThreshold;
-        this.name = name;
+    public Map<String, Object> getDebugProperties() {
+        Map<String, Object> properties = new LinkedHashMap<>();
+        String callsThreshold = String.format("%7d/%5d", getCallCount(), getCompilationCallThreshold());
+        String loopsThreshold = String.format("%7d/%5d", getCallAndLoopCount(), getCompilationCallAndLoopThreshold());
+        String invalidationReplace = String.format("%5d/%5d", invalidationCount, nodeReplaceCount);
+        properties.put("C/T", callsThreshold);
+        properties.put("L/T", loopsThreshold);
+        properties.put("Inval#/Replace#", invalidationReplace);
+        return properties;
+    }
+
+    public void reset() {
+        callCount = 0;
+        callAndLoopCount = 0;
+        compilationCallAndLoopThreshold = originalCompilationThreshold;
+        compilationCallThreshold = originalInvokeCounter;
     }
 
     public long getPreviousTimestamp() {
@@ -70,54 +93,64 @@
         return nodeReplaceCount;
     }
 
-    public int getInvokeCounter() {
-        return invokeCounter;
+    public int getCallAndLoopCount() {
+        return callAndLoopCount;
+    }
+
+    public int getCallCount() {
+        return callCount;
+    }
+
+    public int getCompilationCallAndLoopThreshold() {
+        return compilationCallAndLoopThreshold;
     }
 
-    public int getOriginalInvokeCounter() {
-        return originalInvokeCounter;
+    public int getCompilationCallThreshold() {
+        return compilationCallThreshold;
     }
 
-    public int getLoopAndInvokeCounter() {
-        return loopAndInvokeCounter;
+    void ensureProfiling(int calls, int callsAndLoop) {
+        int increaseCallAndLoopThreshold = callsAndLoop - (this.compilationCallAndLoopThreshold - this.callAndLoopCount);
+        if (increaseCallAndLoopThreshold > 0) {
+            this.compilationCallAndLoopThreshold += increaseCallAndLoopThreshold;
+        }
+
+        int increaseCallsThreshold = calls - (this.compilationCallThreshold - this.callCount);
+        if (increaseCallsThreshold > 0) {
+            this.compilationCallThreshold += increaseCallsThreshold;
+        }
     }
 
     void reportTiminingFailed(long timestamp) {
-        this.loopAndInvokeCounter = compilationThreshold;
-        this.originalInvokeCounter = compilationThreshold;
+        ensureProfiling(0, originalCompilationThreshold);
         this.previousTimestamp = timestamp;
     }
 
     void reportInvalidated() {
         invalidationCount++;
-        int invalidationReprofileCount = TruffleInvalidationReprofileCount.getValue();
-        invokeCounter = invalidationReprofileCount;
-        originalInvokeCounter += invalidationReprofileCount;
+        int reprofile = TruffleInvalidationReprofileCount.getValue();
+        ensureProfiling(reprofile, reprofile);
     }
 
     void reportInterpreterCall() {
-        invokeCounter--;
-        loopAndInvokeCounter--;
+        callCount++;
+        callAndLoopCount++;
     }
 
-    void reportInliningPerformed(TruffleInlining inlining) {
-        invokeCounter = inlining.getInvocationReprofileCount();
-        int inliningReprofileCount = inlining.getReprofileCount();
-        loopAndInvokeCounter = inliningReprofileCount;
-        originalInvokeCounter = inliningReprofileCount;
+    void reportInterpreterCalls(int calls) {
+        this.callCount += calls;
+        this.callAndLoopCount += calls;
     }
 
     void reportLoopCount(int count) {
-        loopAndInvokeCounter = Math.max(0, loopAndInvokeCounter - count);
+        callAndLoopCount += count;
     }
 
     void reportNodeReplaced() {
         nodeReplaceCount++;
         // delay compilation until tree is deemed stable enough
         int replaceBackoff = TruffleReplaceReprofileCount.getValue();
-        if (loopAndInvokeCounter < replaceBackoff) {
-            loopAndInvokeCounter = replaceBackoff;
-        }
+        ensureProfiling(1, replaceBackoff);
     }
 
 }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/DefaultCompilationPolicy.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/DefaultCompilationPolicy.java	Wed Mar 05 19:40:15 2014 -0800
@@ -25,7 +25,7 @@
 public class DefaultCompilationPolicy implements CompilationPolicy {
 
     public boolean shouldCompile(CompilationProfile profile) {
-        return profile.getInvokeCounter() <= 0 && profile.getLoopAndInvokeCounter() <= 0;
+        return profile.getCallCount() >= profile.getCompilationCallThreshold() && profile.getCallAndLoopCount() >= profile.getCompilationCallAndLoopThreshold();
     }
 
 }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/GraalTruffleRuntime.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/GraalTruffleRuntime.java	Wed Mar 05 19:40:15 2014 -0800
@@ -73,14 +73,19 @@
         return "Graal Truffle Runtime";
     }
 
-    public CallTarget createCallTarget(RootNode rootNode) {
-        if (!acceptForCompilation(rootNode)) {
-            return new DefaultCallTarget(rootNode);
-        }
+    public RootCallTarget createCallTarget(RootNode rootNode) {
         if (truffleCompiler == null) {
             truffleCompiler = new TruffleCompilerImpl();
         }
-        return new OptimizedCallTarget(rootNode, truffleCompiler, TruffleMinInvokeThreshold.getValue(), TruffleCompilationThreshold.getValue());
+        return new OptimizedCallTarget(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);
+        }
     }
 
     @Override
@@ -198,8 +203,8 @@
         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, cc, javaMethod, providers, backend, providers.getCodeCache().getTarget(), null, graphBuilderSuite, OptimisticOptimizations.ALL, getProfilingInfo(graph),
-                        new SpeculationLog(), suites, true, new CompilationResult(), factory);
+        return compileGraph(graph, cc, javaMethod, providers, backend, providers.getCodeCache().getTarget(), null, graphBuilderSuite, OptimisticOptimizations.ALL, getProfilingInfo(graph), null,
+                        suites, true, new CompilationResult(), factory);
     }
 
     private static Providers getGraalProviders() {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,292 @@
+/*
+ * 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.frame.*;
+import com.oracle.truffle.api.impl.*;
+import com.oracle.truffle.api.nodes.*;
+import com.oracle.truffle.api.nodes.NodeInfo.Kind;
+
+/**
+ * Call target that is optimized by Graal upon surpassing a specific invocation threshold.
+ */
+abstract class OptimizedCallNode extends DefaultCallNode {
+
+    protected int callCount;
+
+    private OptimizedCallNode(OptimizedCallTarget target) {
+        super(target);
+    }
+
+    @Override
+    public final boolean isSplittable() {
+        return getCallTarget().getRootNode().isSplittable();
+    }
+
+    @Override
+    public final OptimizedCallTarget getCallTarget() {
+        return (OptimizedCallTarget) super.getCallTarget();
+    }
+
+    public final int getCallCount() {
+        return callCount;
+    }
+
+    public TruffleInliningProfile createInliningProfile(OptimizedCallTarget target) {
+        return new OptimizedCallNodeProfile(target, this);
+    }
+
+    @SuppressWarnings("unused")
+    public void nodeReplaced(Node oldNode, Node newNode, String reason) {
+    }
+
+    @Override
+    public final OptimizedCallTarget getCurrentCallTarget() {
+        return (OptimizedCallTarget) super.getCurrentCallTarget();
+    }
+
+    @Override
+    public OptimizedCallTarget getSplitCallTarget() {
+        return null;
+    }
+
+    protected OptimizedCallNode inlineImpl() {
+        if (getParent() == null) {
+            throw new IllegalStateException("CallNode must be adopted before it is split.");
+        }
+
+        return replace(new InlinedOptimizedCallNode(getCallTarget(), getSplitCallTarget(), getCurrentCallTarget().getRootNode(), callCount));
+    }
+
+    public static OptimizedCallNode create(OptimizedCallTarget target) {
+        return new DefaultOptimizedCallNode(target);
+    }
+
+    private static final class DefaultOptimizedCallNode extends OptimizedCallNode {
+
+        private boolean trySplit = true;
+
+        DefaultOptimizedCallNode(OptimizedCallTarget target) {
+            super(target);
+            registerCallTarget(this);
+        }
+
+        @Override
+        public Object call(PackedFrame caller, Arguments arguments) {
+            if (CompilerDirectives.inInterpreter()) {
+                callCount++;
+                if (trySplit && callCount > 1) {
+                    trySplit = false;
+                    return trySplit(caller, arguments);
+                }
+            }
+            return callTarget.call(caller, arguments);
+        }
+
+        private Object trySplit(PackedFrame caller, Arguments arguments) {
+            if (shouldSplit()) {
+                return splitImpl(true).call(caller, arguments);
+            }
+            return callTarget.call(caller, arguments);
+        }
+
+        private boolean shouldSplit() {
+            if (!TruffleCompilerOptions.TruffleSplittingEnabled.getValue()) {
+                return false;
+            }
+            if (!isSplittable()) {
+                return false;
+            }
+            int nodeCount = NodeUtil.countNodes(getCallTarget().getRootNode(), null, false);
+            if (nodeCount > TruffleCompilerOptions.TruffleSplittingMaxCalleeSize.getValue()) {
+                return false;
+            }
+
+            // // is the only call target -> do not split
+            // if (getCallTarget().getRootNode().getCachedCallNodes().size() == 1 &&
+            // getCallTarget().getRootNode().getCachedCallNodes().contains(this)) {
+            // return false;
+            // }
+
+            // max one child call and callCount > 2 and kind of small number of nodes
+            if (isMaxSingleCall()) {
+                return true;
+            }
+            return countPolymorphic() >= 1 || countGeneric() > 0;
+        }
+
+        @Override
+        public void nodeReplaced(Node oldNode, Node newNode, String reason) {
+            trySplit = true;
+        }
+
+        @Override
+        protected void notifyCallNodeAdded() {
+            trySplit = true;
+        }
+
+        private boolean isMaxSingleCall() {
+            final AtomicInteger count = new AtomicInteger(0);
+            getCurrentCallTarget().getRootNode().accept(new NodeVisitor() {
+
+                public boolean visit(Node node) {
+                    if (node instanceof CallNode) {
+                        return count.incrementAndGet() > 1;
+                    }
+                    return true;
+                }
+            });
+            return count.get() <= 1;
+        }
+
+        private int countPolymorphic() {
+            return NodeUtil.countNodes(getCallTarget().getRootNode(), null, Kind.POLYMORPHIC, false);
+        }
+
+        private int countGeneric() {
+            return NodeUtil.countNodes(getCallTarget().getRootNode(), null, Kind.GENERIC, false);
+        }
+
+        @Override
+        public boolean isInlined() {
+            return false;
+        }
+
+        @Override
+        public boolean split() {
+            if (!isSplittable()) {
+                // split is only allowed once and if the root node supports it
+                return false;
+            }
+            if (getParent() == null) {
+                throw new IllegalStateException("CallNode must be adopted before it is split.");
+            }
+            splitImpl(false);
+            return true;
+        }
+
+        private OptimizedCallNode splitImpl(boolean heuristic) {
+            OptimizedCallTarget splitCallTarget = (OptimizedCallTarget) Truffle.getRuntime().createCallTarget(getCallTarget().getRootNode().split());
+            splitCallTarget.setSplitSource(getCallTarget());
+            if (heuristic) {
+                OptimizedCallTarget.logSplit(this, getCallTarget(), splitCallTarget);
+            }
+            return replace(new SplitOptimizedCallNode(getCallTarget(), splitCallTarget, callCount));
+        }
+
+        @Override
+        public void inline() {
+            inlineImpl();
+        }
+
+        @Override
+        public OptimizedCallTarget getSplitCallTarget() {
+            return null;
+        }
+
+    }
+
+    private static final class InlinedOptimizedCallNode extends OptimizedCallNode {
+
+        private final RootNode inlinedRoot;
+        private final OptimizedCallTarget splittedTarget;
+
+        public InlinedOptimizedCallNode(OptimizedCallTarget target, OptimizedCallTarget splittedTarget, RootNode inlinedRoot, int callCount) {
+            super(target);
+            this.inlinedRoot = inlinedRoot;
+            this.splittedTarget = splittedTarget;
+            this.callCount = callCount;
+        }
+
+        @Override
+        public Object call(PackedFrame caller, Arguments arguments) {
+            if (CompilerDirectives.inInterpreter()) {
+                callCount++;
+            }
+            return inlinedRoot.execute(Truffle.getRuntime().createVirtualFrame(caller, arguments, inlinedRoot.getFrameDescriptor()));
+        }
+
+        @Override
+        public void inline() {
+        }
+
+        @Override
+        public boolean split() {
+            return false;
+        }
+
+        @Override
+        public boolean isInlined() {
+            return true;
+        }
+
+        @Override
+        public OptimizedCallTarget getSplitCallTarget() {
+            return splittedTarget;
+        }
+    }
+
+    private static class SplitOptimizedCallNode extends OptimizedCallNode {
+
+        private final OptimizedCallTarget splittedTarget;
+
+        public SplitOptimizedCallNode(OptimizedCallTarget target, OptimizedCallTarget splittedTarget, int callCount) {
+            super(target);
+            this.callCount = callCount;
+            this.splittedTarget = splittedTarget;
+        }
+
+        @Override
+        public Object call(PackedFrame caller, Arguments arguments) {
+            if (CompilerDirectives.inInterpreter()) {
+                callCount++;
+            }
+            return splittedTarget.call(caller, arguments);
+        }
+
+        @Override
+        public boolean isInlined() {
+            return false;
+        }
+
+        @Override
+        public final boolean split() {
+            return false;
+        }
+
+        @Override
+        public void inline() {
+            inlineImpl();
+        }
+
+        @Override
+        public final OptimizedCallTarget getSplitCallTarget() {
+            return splittedTarget;
+        }
+
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallNodeProfile.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,229 @@
+/*
+ * 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.*;
+
+import com.oracle.truffle.api.nodes.*;
+
+public class OptimizedCallNodeProfile implements TruffleInliningProfile {
+
+    private static final String REASON_RECURSION = "recursion";
+    private static final String REASON_FREQUENCY_CUTOFF = "frequency < " + TruffleInliningMinFrequency.getValue();
+    private static final String REASON_MAXIMUM_NODE_COUNT = "shallowTargetCount  > " + TruffleInliningMaxCalleeSize.getValue();
+    private static final String REASON_MAXIMUM_TOTAL_NODE_COUNT = "inlinedTotalCount > " + TruffleInliningMaxCallerSize.getValue();
+
+    private final OptimizedCallTarget callTarget;
+    private final OptimizedCallNode callNode;
+
+    private int targetDeepNodeCount;
+    private List<OptimizedCallTarget> compilationRoots;
+    private final int targetShallowNodeCount;
+    private final double averageFrequency;
+    private final double score;
+    private String reason;
+
+    public OptimizedCallNodeProfile(OptimizedCallTarget target, OptimizedCallNode callNode) {
+        this.callNode = callNode;
+        RootNode inlineRoot = callNode.getCurrentCallTarget().getRootNode();
+        this.callTarget = target;
+        this.targetShallowNodeCount = NodeUtil.countNodes(inlineRoot, null, false);
+        this.targetDeepNodeCount = NodeUtil.countNodes(inlineRoot, null, true);
+        this.compilationRoots = findCompilationRoots(callNode);
+        this.averageFrequency = calculateFrequency();
+        this.score = calculateScore();
+    }
+
+    private double calculateFrequency() {
+        return calculateAdvancedFrequency();
+    }
+
+    public OptimizedCallNode getCallNode() {
+        return callNode;
+    }
+
+    public double getScore() {
+        return score;
+    }
+
+    public double calculateScore() {
+        return averageFrequency / targetDeepNodeCount;
+    }
+
+    public boolean isInliningAllowed() {
+        this.compilationRoots = findCompilationRoots(getCallNode());
+
+        OptimizedCallTarget inlineTarget = callNode.getCurrentCallTarget();
+        for (OptimizedCallTarget compilationRoot : compilationRoots) {
+            if (compilationRoot == inlineTarget) {
+                // recursive call found
+                reason = REASON_RECURSION;
+                return false;
+            }
+        }
+
+        // frequency cut-off
+        if (averageFrequency < TruffleInliningMinFrequency.getValue() && targetDeepNodeCount > TruffleInliningTrivialSize.getValue()) {
+            reason = REASON_FREQUENCY_CUTOFF;
+            return false;
+        }
+
+        if (targetShallowNodeCount > TruffleInliningMaxCalleeSize.getValue()) {
+            reason = REASON_MAXIMUM_NODE_COUNT;
+            return false;
+        }
+
+        this.targetDeepNodeCount = NodeUtil.countNodes(inlineTarget.getRootNode(), null, true);
+        // The maximum total node count cannot be cached since it may change during inlining.
+        int nextNodeCount = calculateInlinedTotalNodeCount(getCallNode());
+        if (nextNodeCount > TruffleInliningMaxCallerSize.getValue()) {
+            reason = REASON_MAXIMUM_TOTAL_NODE_COUNT;
+            return false;
+        }
+
+        return true;
+    }
+
+    private int calculateInlinedTotalNodeCount(OptimizedCallNode node) {
+        int currentNodeCount = 0;
+        for (OptimizedCallTarget compilationRoot : compilationRoots) {
+            TotalNodeCountVisitor visitor = new TotalNodeCountVisitor(node, targetDeepNodeCount);
+            compilationRoot.getRootNode().accept(visitor);
+            currentNodeCount = Math.max(currentNodeCount, visitor.count);
+        }
+        return currentNodeCount;
+    }
+
+    private static class TotalNodeCountVisitor implements NodeVisitor {
+
+        private final OptimizedCallNode inlinedNode;
+        private final int inlinedNodeCount;
+
+        private int count;
+
+        public TotalNodeCountVisitor(OptimizedCallNode inlinedNode, int inlinedNodeCount) {
+            this.inlinedNode = inlinedNode;
+            this.inlinedNodeCount = inlinedNodeCount;
+        }
+
+        public boolean visit(Node node) {
+            count++;
+            if (node instanceof OptimizedCallNode) {
+                OptimizedCallNode callNode = ((OptimizedCallNode) node);
+                if (callNode == inlinedNode) {
+                    count += inlinedNodeCount;
+                } else if (callNode.isInlined()) {
+                    callNode.getCurrentRootNode().accept(this);
+                }
+            }
+            return true;
+        }
+
+    }
+
+    double calculateAdvancedFrequency() {
+        // get the call hierarchy from call target to the call node
+        final ArrayDeque<OptimizedCallNode> callStack = new ArrayDeque<>();
+        callTarget.getRootNode().accept(new NodeVisitor() {
+            private boolean found = false;
+
+            public boolean visit(Node node) {
+                if (node == callNode) {
+                    // found our call
+                    callStack.push((OptimizedCallNode) node);
+                    found = true;
+                    return false;
+                }
+
+                if (node instanceof OptimizedCallNode) {
+                    OptimizedCallNode c = ((OptimizedCallNode) node);
+                    if (c.isInlined()) {
+                        if (!found) {
+                            callStack.push(c);
+                        }
+                        c.getCurrentRootNode().accept(this);
+                        if (!found) {
+                            callStack.pop();
+                        }
+                    }
+                }
+                return !found;
+            }
+        });
+
+        int parentCallCount = callTarget.getCompilationProfile().getCallCount();
+        double frequency = 1.0d;
+        for (OptimizedCallNode c : callStack) {
+            int childCallCount = c.getCallCount();
+            frequency *= childCallCount / (double) parentCallCount;
+            if (c.isInlined() || c.isSplit()) {
+                parentCallCount = childCallCount;
+            } else {
+                parentCallCount = c.getCurrentCallTarget().getCompilationProfile().getCallCount();
+            }
+        }
+        return frequency;
+    }
+
+    double calculateSimpleFrequency() {
+        return callNode.getCallCount() / (double) callTarget.getCompilationProfile().getCallCount();
+    }
+
+    private static List<OptimizedCallTarget> findCompilationRoots(Node call) {
+        RootNode root = call.getRootNode();
+        if (root == null) {
+            return Collections.emptyList();
+        }
+        List<OptimizedCallTarget> roots = new ArrayList<>();
+        roots.add((OptimizedCallTarget) root.getCallTarget());
+        for (CallNode callNode : root.getCachedCallNodes()) {
+            if (callNode.isInlined()) {
+                roots.addAll(findCompilationRoots(callNode));
+            }
+        }
+        return roots;
+    }
+
+    public int compareTo(TruffleInliningProfile o) {
+        if (o instanceof OptimizedCallNodeProfile) {
+            return Double.compare(((OptimizedCallNodeProfile) o).getScore(), getScore());
+        }
+        return 0;
+    }
+
+    public Map<String, Object> getDebugProperties() {
+        Map<String, Object> properties = new LinkedHashMap<>();
+        OptimizedCallTarget.addASTSizeProperty(getCallNode().getCurrentRootNode().getRootNode(), properties);
+        properties.put("shallowCount", targetShallowNodeCount);
+        properties.put("currentCount", calculateInlinedTotalNodeCount(null));
+        properties.put("inlinedTotalCount", calculateInlinedTotalNodeCount(getCallNode()));
+        properties.put("score", score);
+        properties.put("frequency", averageFrequency);
+        properties.put("callCount", callNode.getCallCount());
+        properties.put("reason", reason);
+        return properties;
+    }
+
+}
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java	Wed Mar 05 19:40:15 2014 -0800
@@ -34,41 +34,66 @@
 import com.oracle.truffle.api.frame.*;
 import com.oracle.truffle.api.impl.*;
 import com.oracle.truffle.api.nodes.*;
+import com.oracle.truffle.api.nodes.NodeInfo.Kind;
 
 /**
  * Call target that is optimized by Graal upon surpassing a specific invocation threshold.
  */
-public final class OptimizedCallTarget extends DefaultCallTarget implements FrameFactory, LoopCountReceiver, ReplaceObserver {
+public final class OptimizedCallTarget extends DefaultCallTarget implements LoopCountReceiver, ReplaceObserver {
 
     private static final PrintStream OUT = TTY.out().out();
 
     private InstalledCode installedCode;
     private Future<InstalledCode> installedCodeTask;
+    private boolean compilationEnabled;
+    private boolean inlined;
+    private int callCount;
+
     private final TruffleCompiler compiler;
     private final CompilationProfile compilationProfile;
     private final CompilationPolicy compilationPolicy;
-    private final TruffleInlining inlining;
-    private boolean compilationEnabled;
-    private int callCount;
+    private final SpeculationLog speculationLog = new SpeculationLog();
+    private OptimizedCallTarget splitSource;
 
-    protected OptimizedCallTarget(RootNode rootNode, TruffleCompiler compiler, int invokeCounter, int compilationThreshold) {
+    OptimizedCallTarget(RootNode rootNode, TruffleCompiler compiler, int invokeCounter, int compilationThreshold, boolean compilationEnabled) {
         super(rootNode);
         this.compiler = compiler;
         this.compilationProfile = new CompilationProfile(compilationThreshold, invokeCounter, rootNode.toString());
-        this.rootNode.setCallTarget(this);
 
         if (TruffleUseTimeForCompilationDecision.getValue()) {
             compilationPolicy = new TimedCompilationPolicy();
         } else {
             compilationPolicy = new DefaultCompilationPolicy();
         }
-        this.compilationEnabled = true;
+        this.compilationEnabled = compilationEnabled;
 
         if (TruffleCallTargetProfiling.getValue()) {
             registerCallTarget(this);
         }
-        this.inlining = new TruffleInliningImpl();
+    }
+
+    public OptimizedCallTarget getSplitSource() {
+        return splitSource;
+    }
+
+    public void setSplitSource(OptimizedCallTarget splitSource) {
+        this.splitSource = splitSource;
+    }
 
+    @Override
+    public String toString() {
+        String superString = super.toString();
+        if (installedCode != null) {
+            superString += " <compiled>";
+        }
+        if (splitSource != null) {
+            superString += " <split>";
+        }
+        return superString;
+    }
+
+    public boolean isOptimized() {
+        return installedCode != null || installedCodeTask != null;
     }
 
     @CompilerDirectives.SlowPath
@@ -79,13 +104,7 @@
 
     private Object callHelper(PackedFrame caller, Arguments args) {
         if (installedCode != null && installedCode.isValid()) {
-            TruffleRuntime runtime = Truffle.getRuntime();
-            if (runtime instanceof GraalTruffleRuntime) {
-                if (TraceTruffleCompilation.getValue()) {
-                    OUT.println("[truffle] reinstall OptimizedCallTarget.call code with frame prolog shortcut.");
-                }
-                GraalTruffleRuntime.installOptimizedCallTargetCallMethod();
-            }
+            reinstallCallMethodShortcut();
         }
         if (TruffleCallTargetProfiling.getValue()) {
             callCount++;
@@ -101,31 +120,39 @@
         }
     }
 
+    private static void reinstallCallMethodShortcut() {
+        if (TraceTruffleCompilation.getValue()) {
+            OUT.println("[truffle] reinstall OptimizedCallTarget.call code with frame prolog shortcut.");
+        }
+        GraalTruffleRuntime.installOptimizedCallTargetCallMethod();
+    }
+
     public CompilationProfile getCompilationProfile() {
         return compilationProfile;
     }
 
     private Object compiledCodeInvalidated(PackedFrame caller, Arguments args) {
-        invalidate();
+        invalidate(null, null, "Compiled code invalidated");
         return call(caller, args);
     }
 
-    private void invalidate() {
+    private void invalidate(Node oldNode, Node newNode, String reason) {
         InstalledCode m = this.installedCode;
         if (m != null) {
             CompilerAsserts.neverPartOfCompilation();
             installedCode = null;
             compilationProfile.reportInvalidated();
-            if (TraceTruffleCompilation.getValue()) {
-                OUT.printf("[truffle] invalidated %-48s |Inv# %d                                     |Replace# %d\n", rootNode, compilationProfile.getInvalidationCount(),
-                                compilationProfile.getNodeReplaceCount());
-            }
+            logOptimizedInvalidated(this, oldNode, newNode, reason);
         }
+        cancelInstalledTask(oldNode, newNode, reason);
+    }
 
+    private void cancelInstalledTask(Node oldNode, Node newNode, String reason) {
         Future<InstalledCode> task = this.installedCodeTask;
         if (task != null) {
             task.cancel(true);
             this.installedCodeTask = null;
+            logOptimizingUnqueued(this, oldNode, newNode, reason);
             compilationProfile.reportInvalidated();
         }
     }
@@ -133,29 +160,77 @@
     private Object interpreterCall(PackedFrame caller, Arguments args) {
         CompilerAsserts.neverPartOfCompilation();
         compilationProfile.reportInterpreterCall();
-        if (compilationEnabled && shouldCompile()) {
-            if (isCompiling()) {
-                return waitForCompilation(caller, args);
-            }
-            boolean inlined = shouldInline() && inline();
-            if (!inlined) {
-                compile();
+
+        if (compilationEnabled && compilationPolicy.shouldCompile(compilationProfile)) {
+            InstalledCode code = compile();
+            if (code != null && code.isValid()) {
+                this.installedCode = code;
+                try {
+                    return code.execute(this, caller, args);
+                } catch (InvalidInstalledCodeException ex) {
+                    return compiledCodeInvalidated(caller, args);
+                }
             }
         }
         return executeHelper(caller, args);
     }
 
-    private boolean shouldCompile() {
-        return compilationPolicy.shouldCompile(compilationProfile);
+    public void performInlining() {
+        if (!TruffleCompilerOptions.TruffleFunctionInlining.getValue()) {
+            return;
+        }
+        if (inlined) {
+            return;
+        }
+        inlined = true;
+
+        logInliningStart(this);
+        PriorityQueue<TruffleInliningProfile> queue = new PriorityQueue<>();
+
+        // Used to avoid running in cycles or inline nodes in Truffle trees
+        // which do not suffice the tree property.
+        Set<CallNode> visitedCallNodes = new HashSet<>();
+
+        queueCallSitesForInlining(this, getRootNode(), visitedCallNodes, queue);
+        TruffleInliningProfile callSite = queue.poll();
+        while (callSite != null) {
+            if (callSite.isInliningAllowed()) {
+                OptimizedCallNode callNode = callSite.getCallNode();
+                logInlined(this, callSite);
+                RootNode inlinedRoot = callNode.inlineImpl().getCurrentRootNode();
+                assert inlinedRoot != null;
+                queueCallSitesForInlining(this, inlinedRoot, visitedCallNodes, queue);
+            } else {
+                logInliningFailed(callSite);
+            }
+            callSite = queue.poll();
+        }
+        logInliningDone(this);
     }
 
-    private static boolean shouldInline() {
-        return TruffleFunctionInlining.getValue();
+    private static void queueCallSitesForInlining(final OptimizedCallTarget target, RootNode rootNode, final Set<CallNode> visitedCallSites, final PriorityQueue<TruffleInliningProfile> queue) {
+        rootNode.accept(new NodeVisitor() {
+            public boolean visit(Node node) {
+                if (node instanceof OptimizedCallNode) {
+                    OptimizedCallNode call = ((OptimizedCallNode) node);
+                    if (!call.isInlined() && !visitedCallSites.contains(call)) {
+                        queue.add(call.createInliningProfile(target));
+                        visitedCallSites.add(call);
+                    }
+                    RootNode root = call.getCurrentRootNode();
+                    if (root != null && call.isInlined()) {
+                        root.accept(this);
+                    }
+                }
+                return true;
+            }
+        });
     }
 
     private boolean isCompiling() {
-        if (installedCodeTask != null) {
-            if (installedCodeTask.isCancelled()) {
+        Future<InstalledCode> codeTask = this.installedCodeTask;
+        if (codeTask != null) {
+            if (codeTask.isCancelled()) {
                 installedCodeTask = null;
                 return false;
             }
@@ -164,18 +239,21 @@
         return false;
     }
 
-    public void compile() {
-        this.installedCodeTask = compiler.compile(this);
-        if (!TruffleBackgroundCompilation.getValue()) {
-            installedCode = receiveInstalledCode();
+    public InstalledCode compile() {
+        if (isCompiling()) {
+            if (installedCodeTask.isDone()) {
+                return receiveInstalledCode();
+            }
+            return null;
+        } else {
+            performInlining();
+            logOptimizingQueued(this);
+            this.installedCodeTask = compiler.compile(this);
+            if (!TruffleBackgroundCompilation.getValue()) {
+                return receiveInstalledCode();
+            }
         }
-    }
-
-    private Object waitForCompilation(PackedFrame caller, Arguments args) {
-        if (installedCodeTask.isDone()) {
-            installedCode = receiveInstalledCode();
-        }
-        return executeHelper(caller, args);
+        return null;
     }
 
     private InstalledCode receiveInstalledCode() {
@@ -183,7 +261,7 @@
             return installedCodeTask.get();
         } catch (InterruptedException | ExecutionException e) {
             compilationEnabled = false;
-            OUT.printf("[truffle] opt failed %-48s  %s\n", rootNode, e.getMessage());
+            logOptimizingFailed(this, e.getMessage());
             if (e.getCause() instanceof BailoutException) {
                 // Bailout => move on.
             } else {
@@ -198,22 +276,9 @@
         }
     }
 
-    /**
-     * Forces inlining whether or not function inlining is enabled.
-     * 
-     * @return true if an inlining was performed
-     */
-    public boolean inline() {
-        boolean result = inlining.performInlining(this);
-        if (result) {
-            compilationProfile.reportInliningPerformed(inlining);
-        }
-        return result;
-    }
-
     public Object executeHelper(PackedFrame caller, Arguments args) {
-        VirtualFrame frame = createFrame(rootNode.getFrameDescriptor(), caller, args);
-        return rootNode.execute(frame);
+        VirtualFrame frame = createFrame(getRootNode().getFrameDescriptor(), caller, args);
+        return getRootNode().execute(frame);
     }
 
     protected static FrameWithoutBoxing createFrame(FrameDescriptor descriptor, PackedFrame caller, Arguments args) {
@@ -221,19 +286,216 @@
     }
 
     @Override
-    public VirtualFrame create(FrameDescriptor descriptor, PackedFrame caller, Arguments args) {
-        return createFrame(descriptor, caller, args);
+    public void reportLoopCount(int count) {
+        compilationProfile.reportLoopCount(count);
+
+        // delegate to inlined call sites
+        for (CallNode callNode : getRootNode().getCachedCallNodes()) {
+            if (callNode.isInlined()) {
+                callNode.getRootNode().reportLoopCount(count);
+            }
+        }
     }
 
     @Override
-    public void reportLoopCount(int count) {
-        compilationProfile.reportLoopCount(count);
+    public void nodeReplaced(Node oldNode, Node newNode, String reason) {
+        compilationProfile.reportNodeReplaced();
+        invalidate(oldNode, newNode, reason);
+
+        // delegate to inlined call sites
+        for (CallNode callNode : getRootNode().getCachedCallNodes()) {
+            if (callNode.isInlined()) {
+                CallTarget target = callNode.getRootNode().getCallTarget();
+                if (target instanceof ReplaceObserver) {
+                    ((ReplaceObserver) target).nodeReplaced(oldNode, newNode, reason);
+                }
+            }
+            if (callNode instanceof OptimizedCallNode) {
+                ((OptimizedCallNode) callNode).nodeReplaced(oldNode, newNode, reason);
+            }
+        }
+    }
+
+    public SpeculationLog getSpeculationLog() {
+        return speculationLog;
+    }
+
+    public Map<String, Object> getDebugProperties() {
+        Map<String, Object> properties = new LinkedHashMap<>();
+        addASTSizeProperty(getRootNode(), properties);
+        properties.putAll(getCompilationProfile().getDebugProperties());
+        return properties;
+
+    }
+
+    private static void logInliningFailed(TruffleInliningProfile callSite) {
+        if (TraceTruffleInliningDetails.getValue()) {
+            log(2, "inline failed", callSite.getCallNode().getCurrentCallTarget().toString(), callSite.getDebugProperties());
+        }
+    }
+
+    private static void logInlined(@SuppressWarnings("unused") final OptimizedCallTarget target, TruffleInliningProfile callSite) {
+        if (TraceTruffleInliningDetails.getValue() || TraceTruffleInlining.getValue()) {
+            log(2, "inline success", callSite.getCallNode().getCurrentCallTarget().toString(), callSite.getDebugProperties());
+
+            if (TraceTruffleInliningDetails.getValue()) {
+                RootNode root = callSite.getCallNode().getCurrentCallTarget().getRootNode();
+                root.accept(new NodeVisitor() {
+                    int depth = 1;
+
+                    public boolean visit(Node node) {
+                        if (node instanceof OptimizedCallNode) {
+                            OptimizedCallNode callNode = ((OptimizedCallNode) node);
+                            RootNode inlinedRoot = callNode.getCurrentRootNode();
+
+                            if (inlinedRoot != null && callNode.isInlined()) {
+                                Map<String, Object> properties = new LinkedHashMap<>();
+                                addASTSizeProperty(callNode.getCurrentRootNode(), properties);
+                                log(2 + (depth * 2), "inline success", callNode.getCurrentCallTarget().toString(), properties);
+                                depth++;
+                                inlinedRoot.accept(this);
+                                depth--;
+                            }
+                        }
+                        return true;
+                    }
+                });
+            }
+        }
+    }
+
+    private static void logInliningStart(OptimizedCallTarget target) {
+        if (TraceTruffleInliningDetails.getValue()) {
+            log(0, "inline start", target.toString(), target.getDebugProperties());
+        }
+    }
+
+    private static void logInliningDone(OptimizedCallTarget target) {
+        if (TraceTruffleInliningDetails.getValue()) {
+            log(0, "inline done", target.toString(), target.getDebugProperties());
+        }
+    }
+
+    private static void logOptimizingQueued(OptimizedCallTarget target) {
+        if (TraceTruffleCompilationDetails.getValue()) {
+            log(0, "opt queued", target.toString(), target.getDebugProperties());
+        }
+    }
+
+    private static void logOptimizingUnqueued(OptimizedCallTarget target, Node oldNode, Node newNode, String reason) {
+        if (TraceTruffleCompilationDetails.getValue()) {
+            Map<String, Object> properties = new LinkedHashMap<>();
+            addReplaceProperties(properties, oldNode, newNode);
+            properties.put("Reason", reason);
+            log(0, "opt unqueued", target.toString(), properties);
+        }
     }
 
-    @Override
-    public void nodeReplaced() {
-        compilationProfile.reportNodeReplaced();
-        invalidate();
+    private static void addReplaceProperties(Map<String, Object> 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());
+        }
+    }
+
+    private static void logOptimizedInvalidated(OptimizedCallTarget target, Node oldNode, Node newNode, String reason) {
+        if (TraceTruffleCompilation.getValue()) {
+            Map<String, Object> properties = new LinkedHashMap<>();
+            addReplaceProperties(properties, oldNode, newNode);
+            properties.put("Reason", reason);
+            log(0, "opt invalidated", target.toString(), properties);
+        }
+    }
+
+    private static void logOptimizingFailed(OptimizedCallTarget callSite, String reason) {
+        Map<String, Object> properties = new LinkedHashMap<>();
+        properties.put("Reason", reason);
+        log(0, "opt fail", callSite.toString(), properties);
+    }
+
+    static void logOptimizingDone(OptimizedCallTarget target, Map<String, Object> 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) {
+                    Kind kind = node.getKind();
+                    if (kind == Kind.POLYMORPHIC || kind == Kind.GENERIC) {
+                        Map<String, Object> props = new LinkedHashMap<>();
+                        props.put("simpleName", node.getClass().getSimpleName());
+                        String msg = kind == Kind.GENERIC ? "generic" : "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<String, Object> properties = new LinkedHashMap<>();
+            addASTSizeProperty(target.getRootNode(), properties);
+            properties.put("Split#", ++splitCount);
+            properties.put("Source", callNode.getEncapsulatingSourceSection());
+            log(0, "split", newTarget.toString(), properties);
+        }
+    }
+
+    static void addASTSizeProperty(RootNode target, Map<String, Object> properties) {
+        String value = String.format("%4d (%d/%d)", NodeUtil.countNodes(target.getRootNode(), null, true), //
+                        NodeUtil.countNodes(target.getRootNode(), null, Kind.POLYMORPHIC, true), NodeUtil.countNodes(target.getRootNode(), null, Kind.GENERIC, true)); //
+
+        properties.put("ASTSize", value);
+    }
+
+    static synchronized void log(int indent, String msg, String details, Map<String, Object> properties) {
+        OUT.printf("[truffle] %-16s ", msg);
+        for (int i = 0; i < indent; i++) {
+            OUT.print(" ");
+        }
+        OUT.printf("%-" + (60 - indent) + "s", details);
+        if (properties != null) {
+            for (String property : properties.keySet()) {
+                Object value = properties.get(property);
+                if (value == null) {
+                    continue;
+                }
+                OUT.print("|");
+                OUT.print(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());
+                OUT.printf(" %" + length + "s ", propertyBuilder.toString());
+            }
+        }
+        OUT.println();
     }
 
     private static void printProfiling() {
@@ -248,7 +510,6 @@
 
         int totalCallCount = 0;
         int totalInlinedCallSiteCount = 0;
-        int totalNotInlinedCallSiteCount = 0;
         int totalNodeCount = 0;
         int totalInvalidationCount = 0;
 
@@ -259,21 +520,34 @@
                 continue;
             }
 
-            int notInlinedCallSiteCount = TruffleInliningImpl.getInlinableCallSites(callTarget).size();
-            int nodeCount = NodeUtil.countNodes(callTarget.rootNode);
-            int inlinedCallSiteCount = NodeUtil.countNodes(callTarget.rootNode, InlinedCallSite.class);
+            int nodeCount = NodeUtil.countNodes(callTarget.getRootNode(), null, true);
+            int inlinedCallSiteCount = countInlinedNodes(callTarget.getRootNode());
             String comment = callTarget.installedCode == null ? " int" : "";
             comment += callTarget.compilationEnabled ? "" : " fail";
-            OUT.printf("%-50s | %10d | %15d | %15d | %10d | %3d%s\n", callTarget.getRootNode(), callTarget.callCount, inlinedCallSiteCount, notInlinedCallSiteCount, nodeCount,
+            OUT.printf("%-50s | %10d | %15d | %10d | %3d%s\n", callTarget.getRootNode(), callTarget.callCount, inlinedCallSiteCount, nodeCount,
                             callTarget.getCompilationProfile().getInvalidationCount(), comment);
 
             totalCallCount += callTarget.callCount;
             totalInlinedCallSiteCount += inlinedCallSiteCount;
-            totalNotInlinedCallSiteCount += notInlinedCallSiteCount;
             totalNodeCount += nodeCount;
             totalInvalidationCount += callTarget.getCompilationProfile().getInvalidationCount();
         }
-        OUT.printf("%-50s | %10d | %15d | %15d | %10d | %3d\n", "Total", totalCallCount, totalInlinedCallSiteCount, totalNotInlinedCallSiteCount, totalNodeCount, totalInvalidationCount);
+        OUT.printf("%-50s | %10d | %15d | %10d | %3d\n", "Total", totalCallCount, totalInlinedCallSiteCount, totalNodeCount, totalInvalidationCount);
+    }
+
+    private static int countInlinedNodes(Node rootNode) {
+        List<CallNode> callers = NodeUtil.findAllNodeInstances(rootNode, CallNode.class);
+        int count = 0;
+        for (CallNode callNode : callers) {
+            if (callNode.isInlined()) {
+                count++;
+                RootNode root = callNode.getCurrentRootNode();
+                if (root != null) {
+                    count += countInlinedNodes(root);
+                }
+            }
+        }
+        return count;
     }
 
     private static void registerCallTarget(OptimizedCallTarget callTarget) {
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java	Wed Mar 05 19:40:15 2014 -0800
@@ -68,16 +68,16 @@
     private final Providers providers;
     private final ResolvedJavaMethod executeHelperMethod;
     private final CanonicalizerPhase canonicalizer;
-    private final ResolvedJavaType[] skippedExceptionTypes;
+    private final GraphBuilderConfiguration config;
     private Set<Constant> constantReceivers;
     private final GraphCache cache;
     private final TruffleCache truffleCache;
 
-    public PartialEvaluator(RuntimeProvider runtime, Providers providers, TruffleCache truffleCache) {
+    public PartialEvaluator(RuntimeProvider runtime, Providers providers, TruffleCache truffleCache, GraphBuilderConfiguration config) {
         this.providers = providers;
         CustomCanonicalizer customCanonicalizer = new PartialEvaluatorCanonicalizer(providers.getMetaAccess(), providers.getConstantReflection());
         this.canonicalizer = new CanonicalizerPhase(!ImmutableCode.getValue(), customCanonicalizer);
-        this.skippedExceptionTypes = TruffleCompilerImpl.getSkippedExceptionTypes(providers.getMetaAccess());
+        this.config = config;
         this.cache = runtime.getGraphCache();
         this.truffleCache = truffleCache;
         try {
@@ -94,13 +94,10 @@
             throw Debug.handle(e);
         }
 
-        if (TraceTruffleCompilationDetails.getValue()) {
+        if (TraceTruffleCompilationHistogram.getValue()) {
             constantReceivers = new HashSet<>();
         }
 
-        final GraphBuilderConfiguration config = GraphBuilderConfiguration.getDefault();
-        config.setSkippedExceptionTypes(skippedExceptionTypes);
-
         final StructuredGraph graph = new StructuredGraph(executeHelperMethod);
 
         try (Scope s = Debug.scope("createGraph", graph)) {
@@ -133,7 +130,7 @@
 
             new VerifyFrameDoesNotEscapePhase().apply(graph, false);
 
-            if (TraceTruffleCompilationDetails.getValue() && constantReceivers != null) {
+            if (TraceTruffleCompilationHistogram.getValue() && constantReceivers != null) {
                 DebugHistogram histogram = Debug.createHistogram("Expanded Truffle Nodes");
                 for (Constant c : constantReceivers) {
                     histogram.add(c.asObject().getClass().getSimpleName());
@@ -187,7 +184,7 @@
             for (MethodCallTargetNode methodCallTargetNode : graph.getNodes(MethodCallTargetNode.class)) {
                 InvokeKind kind = methodCallTargetNode.invokeKind();
                 if (kind == InvokeKind.Static || (kind == InvokeKind.Special && (methodCallTargetNode.receiver().isConstant() || methodCallTargetNode.receiver() instanceof NewFrameNode))) {
-                    if (TraceTruffleCompilationDetails.getValue() && kind == InvokeKind.Special) {
+                    if (TraceTruffleCompilationHistogram.getValue() && kind == InvokeKind.Special) {
                         ConstantNode constantNode = (ConstantNode) methodCallTargetNode.arguments().first();
                         constantReceivers.add(constantNode.asConstant());
                     }
@@ -211,6 +208,7 @@
                         if (TraceTruffleExpansion.getValue()) {
                             expansionLogger.preExpand(methodCallTargetNode, inlineGraph);
                         }
+                        List<Node> invokeUsages = methodCallTargetNode.invoke().asNode().usages().snapshot();
                         Map<Node, Node> inlined = InliningUtil.inline(methodCallTargetNode.invoke(), inlineGraph, false);
                         if (TraceTruffleExpansion.getValue()) {
                             expansionLogger.postExpand(inlined);
@@ -219,7 +217,7 @@
                             int nodeCountAfter = graph.getNodeCount();
                             Debug.dump(graph, "After inlining %s %+d (%d)", methodCallTargetNode.targetMethod().toString(), nodeCountAfter - nodeCountBefore, nodeCountAfter);
                         }
-                        canonicalizer.applyIncremental(graph, phaseContext, mark);
+                        canonicalizer.applyIncremental(graph, phaseContext, invokeUsages, mark);
                         changed = true;
                     }
                 }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCache.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCache.java	Wed Mar 05 19:40:15 2014 -0800
@@ -26,6 +26,7 @@
 
 import java.lang.reflect.*;
 import java.util.*;
+import java.util.Map.Entry;
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
@@ -60,8 +61,10 @@
     private final OptimisticOptimizations optimisticOptimizations;
 
     private final HashMap<List<Object>, StructuredGraph> cache = new HashMap<>();
+    private final HashMap<List<Object>, Long> lastUsed = new HashMap<>();
     private final StructuredGraph markerGraph = new StructuredGraph();
     private final ResolvedJavaType stringBuilderClass;
+    private long counter;
 
     public TruffleCache(Providers providers, GraphBuilderConfiguration config, OptimisticOptimizations optimisticOptimizations) {
         this.providers = providers;
@@ -82,6 +85,7 @@
         }
         StructuredGraph resultGraph = cache.get(key);
         if (resultGraph != null) {
+            lastUsed.put(key, counter++);
             return resultGraph;
         }
 
@@ -90,6 +94,28 @@
             return null;
         }
 
+        if (lastUsed.values().size() >= TruffleCompilerOptions.TruffleMaxCompilationCacheSize.getValue()) {
+            List<Long> lastUsedList = new ArrayList<>();
+            for (long l : lastUsed.values()) {
+                lastUsedList.add(l);
+            }
+            Collections.sort(lastUsedList);
+            long mid = lastUsedList.get(lastUsedList.size() / 2);
+
+            List<List<Object>> toRemoveList = new ArrayList<>();
+            for (Entry<List<Object>, Long> entry : lastUsed.entrySet()) {
+                if (entry.getValue() < mid) {
+                    toRemoveList.add(entry.getKey());
+                }
+            }
+
+            for (List<Object> entry : toRemoveList) {
+                cache.remove(entry);
+                lastUsed.remove(entry);
+            }
+        }
+
+        lastUsed.put(key, counter++);
         cache.put(key, markerGraph);
         try (Scope s = Debug.scope("TruffleCache", new Object[]{providers.getMetaAccess(), method})) {
 
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java	Wed Mar 05 19:40:15 2014 -0800
@@ -36,7 +36,6 @@
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.api.runtime.*;
 import com.oracle.graal.compiler.*;
-import com.oracle.graal.compiler.CompilerThreadFactory.*;
 import com.oracle.graal.compiler.target.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.debug.Debug.Scope;
@@ -65,12 +64,12 @@
     private final Suites suites;
     private final PartialEvaluator partialEvaluator;
     private final Backend backend;
-    private final ResolvedJavaType[] skippedExceptionTypes;
+    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[]{SlowPathException.class, UnexpectedResultException.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);
@@ -81,10 +80,9 @@
         Replacements truffleReplacements = ((GraalTruffleRuntime) Truffle.getRuntime()).getReplacements();
         this.providers = backend.getProviders().copyWith(truffleReplacements);
         this.suites = backend.getSuites().getDefaultSuites();
-        this.skippedExceptionTypes = getSkippedExceptionTypes(providers.getMetaAccess());
 
         // Create compilation queue.
-        CompilerThreadFactory factory = new CompilerThreadFactory("TruffleCompilerThread", new DebugConfigAccess() {
+        CompilerThreadFactory factory = new CompilerThreadFactory("TruffleCompilerThread", new CompilerThreadFactory.DebugConfigAccess() {
             public GraalDebugConfig getDebugConfig() {
                 if (Debug.isEnabled()) {
                     GraalDebugConfig debugConfig = DebugEnvironment.initialize(TTY.out().out());
@@ -97,18 +95,21 @@
         });
         compileQueue = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(), factory);
 
-        final GraphBuilderConfiguration config = GraphBuilderConfiguration.getEagerDefault();
-        config.setSkippedExceptionTypes(skippedExceptionTypes);
-        this.truffleCache = new TruffleCache(providers, config, TruffleCompilerImpl.Optimizations);
+        ResolvedJavaType[] skippedExceptionTypes = getSkippedExceptionTypes(providers.getMetaAccess());
+        GraphBuilderConfiguration eagerConfig = GraphBuilderConfiguration.getEagerDefault();
+        eagerConfig.setSkippedExceptionTypes(skippedExceptionTypes);
+        this.truffleCache = new TruffleCache(providers, eagerConfig, TruffleCompilerImpl.Optimizations);
 
-        this.partialEvaluator = new PartialEvaluator(runtime, providers, truffleCache);
+        this.config = GraphBuilderConfiguration.getDefault();
+        this.config.setSkippedExceptionTypes(skippedExceptionTypes);
+        this.partialEvaluator = new PartialEvaluator(runtime, providers, truffleCache, config);
 
         if (Debug.isEnabled()) {
             DebugEnvironment.initialize(System.out);
         }
     }
 
-    static ResolvedJavaType[] getSkippedExceptionTypes(MetaAccessProvider metaAccess) {
+    private static ResolvedJavaType[] getSkippedExceptionTypes(MetaAccessProvider metaAccess) {
         ResolvedJavaType[] skippedExceptionTypes = new ResolvedJavaType[SKIPPED_EXCEPTION_CLASSES.length];
         for (int i = 0; i < SKIPPED_EXCEPTION_CLASSES.length; i++) {
             skippedExceptionTypes[i] = metaAccess.lookupJavaType(SKIPPED_EXCEPTION_CLASSES[i]);
@@ -135,15 +136,17 @@
 
     private InstalledCode compileMethodImpl(final OptimizedCallTarget compilable) {
         final StructuredGraph graph;
-        final GraphBuilderConfiguration config = GraphBuilderConfiguration.getDefault();
-        config.setSkippedExceptionTypes(skippedExceptionTypes);
         GraphCache graphCache = runtime.getGraphCache();
         if (graphCache != null) {
             graphCache.removeStaleGraphs();
         }
 
+        if (TraceTruffleCompilation.getValue()) {
+            OptimizedCallTarget.logOptimizingStart(compilable);
+        }
+
         if (TraceTruffleInliningTree.getValue()) {
-            printInlineTree(compilable.getRootNode());
+            NodeUtil.printInliningTree(OUT, compilable.getRootNode());
         }
 
         long timeCompilationStarted = System.nanoTime();
@@ -156,7 +159,7 @@
         }
         long timePartialEvaluationFinished = System.nanoTime();
         int nodeCountPartialEval = graph.getNodeCount();
-        InstalledCode compiledMethod = compileMethodHelper(graph, config, assumptions, compilable.toString());
+        InstalledCode compiledMethod = compileMethodHelper(graph, assumptions, compilable.toString(), compilable.getSpeculationLog());
         long timeCompilationFinished = System.nanoTime();
         int nodeCountLowered = graph.getNodeCount();
 
@@ -168,47 +171,27 @@
         }
 
         if (TraceTruffleCompilation.getValue()) {
-            int nodeCountTruffle = NodeUtil.countNodes(compilable.getRootNode());
             byte[] code = compiledMethod.getCode();
-            OUT.printf("[truffle] optimized %-50s %x |Nodes %7d |Time %5.0f(%4.0f+%-4.0f)ms |Nodes %5d/%5d |CodeSize %d\n", compilable.getRootNode(), compilable.hashCode(), nodeCountTruffle,
-                            (timeCompilationFinished - timeCompilationStarted) / 1e6, (timePartialEvaluationFinished - timeCompilationStarted) / 1e6,
-                            (timeCompilationFinished - timePartialEvaluationFinished) / 1e6, nodeCountPartialEval, nodeCountLowered, code != null ? code.length : 0);
+            Map<String, Object> properties = new LinkedHashMap<>();
+            OptimizedCallTarget.addASTSizeProperty(compilable.getRootNode(), properties);
+            properties.put("Time", String.format("%5.0f(%4.0f+%-4.0f)ms", //
+                            (timeCompilationFinished - timeCompilationStarted) / 1e6, //
+                            (timePartialEvaluationFinished - timeCompilationStarted) / 1e6, //
+                            (timeCompilationFinished - timePartialEvaluationFinished) / 1e6));
+            properties.put("Nodes", String.format("%5d/%5d", nodeCountPartialEval, nodeCountLowered));
+            properties.put("CodeSize", code != null ? code.length : 0);
+            properties.put("Source", formatSourceSection(compilable.getRootNode().getSourceSection()));
+
+            OptimizedCallTarget.logOptimizingDone(compilable, properties);
         }
         return compiledMethod;
     }
 
-    private void printInlineTree(RootNode rootNode) {
-        OUT.println();
-        OUT.println("Inlining tree for: " + rootNode);
-        rootNode.accept(new InlineTreeVisitor());
+    private static String formatSourceSection(SourceSection sourceSection) {
+        return sourceSection != null ? sourceSection.toString() : "n/a";
     }
 
-    private class InlineTreeVisitor implements NodeVisitor {
-
-        public boolean visit(Node node) {
-            if (node instanceof InlinedCallSite) {
-                InlinedCallSite inlinedCallSite = (InlinedCallSite) node;
-                int indent = this.indent(node);
-                for (int i = 0; i < indent; ++i) {
-                    OUT.print("   ");
-                }
-                OUT.println(inlinedCallSite.getCallTarget());
-            }
-            return true;
-        }
-
-        private int indent(Node n) {
-            if (n instanceof RootNode) {
-                return 0;
-            } else if (n instanceof InlinedCallSite) {
-                return indent(n.getParent()) + 1;
-            } else {
-                return indent(n.getParent());
-            }
-        }
-    }
-
-    public InstalledCode compileMethodHelper(StructuredGraph graph, GraphBuilderConfiguration config, Assumptions assumptions, String name) {
+    public InstalledCode compileMethodHelper(StructuredGraph graph, Assumptions assumptions, String name, SpeculationLog speculationLog) {
         try (Scope s = Debug.scope("TruffleFinal")) {
             Debug.dump(graph, "After TruffleTier");
         } catch (Throwable e) {
@@ -220,8 +203,8 @@
             CodeCacheProvider codeCache = providers.getCodeCache();
             CallingConvention cc = getCallingConvention(codeCache, Type.JavaCallee, graph.method(), false);
             CompilationResult compilationResult = new CompilationResult(name);
-            result = compileGraph(graph, cc, graph.method(), providers, backend, codeCache.getTarget(), null, createGraphBuilderSuite(config), OptimisticOptimizations.ALL, getProfilingInfo(graph),
-                            new SpeculationLog(), suites, false, compilationResult, CompilationResultBuilderFactory.Default);
+            result = compileGraph(graph, cc, graph.method(), providers, backend, codeCache.getTarget(), null, createGraphBuilderSuite(), Optimizations, getProfilingInfo(graph), speculationLog,
+                            suites, false, compilationResult, CompilationResultBuilderFactory.Default);
         } catch (Throwable e) {
             throw Debug.handle(e);
         }
@@ -244,7 +227,7 @@
 
         InstalledCode installedCode = null;
         try (Scope s = Debug.scope("CodeInstall", providers.getCodeCache()); TimerCloseable a = CodeInstallationTime.start()) {
-            installedCode = providers.getCodeCache().addMethod(graph.method(), result, null);
+            installedCode = providers.getCodeCache().addMethod(graph.method(), result, speculationLog);
         } catch (Throwable e) {
             throw Debug.handle(e);
         }
@@ -259,7 +242,7 @@
         return installedCode;
     }
 
-    private PhaseSuite<HighTierContext> createGraphBuilderSuite(GraphBuilderConfiguration config) {
+    private PhaseSuite<HighTierContext> createGraphBuilderSuite() {
         PhaseSuite<HighTierContext> suite = backend.getSuites().getDefaultGraphBuilderSuite().copy();
         ListIterator<BasePhase<? super HighTierContext>> iterator = suite.findPhase(GraphBuilderPhase.class);
         iterator.remove();
@@ -277,4 +260,8 @@
             }
         }
     }
+
+    public PartialEvaluator getPartialEvaluator() {
+        return partialEvaluator;
+    }
 }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerOptions.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerOptions.java	Wed Mar 05 19:40:15 2014 -0800
@@ -41,40 +41,42 @@
      * Element = Include | '~' Exclude ;
      * </pre>
      */
-    @Option(help = "")
+    @Option(help = "Restrict compilation to comma-separated list of includes (or excludes prefixed with tilde)")
     public static final OptionValue<String> TruffleCompileOnly = new OptionValue<>(null);
-    @Option(help = "")
+    @Option(help = "Compile call target when call count exceeds this threshold")
     public static final OptionValue<Integer> TruffleCompilationThreshold = new OptionValue<>(1000);
-    @Option(help = "")
+    @Option(help = "Minimum number of calls before a call target is compiled")
     public static final OptionValue<Integer> TruffleMinInvokeThreshold = new OptionValue<>(3);
-    @Option(help = "")
+    @Option(help = "Delay compilation after an invalidation to allow for reprofiling")
     public static final OptionValue<Integer> TruffleInvalidationReprofileCount = new OptionValue<>(3);
-    @Option(help = "")
+    @Option(help = "Delay compilation after a node replacement")
     public static final OptionValue<Integer> TruffleReplaceReprofileCount = new OptionValue<>(10);
-    @Option(help = "")
-    public static final OptionValue<Integer> TruffleInliningReprofileCount = new OptionValue<>(100);
-    @Option(help = "")
+    @Option(help = "Enable automatic inlining of call targets")
     public static final OptionValue<Boolean> TruffleFunctionInlining = new OptionValue<>(true);
-    @Option(help = "")
-    public static final OptionValue<Integer> TruffleGraphMaxNodes = new OptionValue<>(25000);
-    @Option(help = "")
-    public static final OptionValue<Integer> TruffleInliningMaxRecursiveDepth = new OptionValue<>(2);
-    @Option(help = "")
+    @Option(help = "Maximum number of Graal IR nodes during partial evaluation")
+    public static final OptionValue<Integer> TruffleGraphMaxNodes = new OptionValue<>(30000);
+    @Option(help = "Stop inlining if caller's cumulative tree size would exceed this limit")
     public static final OptionValue<Integer> TruffleInliningMaxCallerSize = new OptionValue<>(2250);
-    @Option(help = "")
+    @Option(help = "Skip inlining candidate if its tree size exceeds this limit")
     public static final OptionValue<Integer> TruffleInliningMaxCalleeSize = new OptionValue<>(250);
-    @Option(help = "")
+    @Option(help = "Call frequency relative to call target")
+    public static final OptionValue<Double> TruffleInliningMinFrequency = new OptionValue<>(0.3);
+    @Option(help = "Allow inlining of less hot candidates if tree size is small")
     public static final OptionValue<Integer> TruffleInliningTrivialSize = new OptionValue<>(10);
-    @Option(help = "")
-    public static final OptionValue<Double> TruffleInliningMinFrequency = new OptionValue<>(0.3);
+    @Option(help = "Enable call target splitting")
+    public static final OptionValue<Boolean> TruffleSplittingEnabled = new OptionValue<>(true);
+    @Option(help = "Disable call target splitting if tree size exceeds this limit")
+    public static final OptionValue<Integer> TruffleSplittingMaxCalleeSize = new OptionValue<>(100);
+    @Option(help = "Number of most recently used methods in truffle cache")
+    public static final OptionValue<Integer> TruffleMaxCompilationCacheSize = new OptionValue<>(512);
+    @Option(help = "Enable asynchronous truffle compilation in background thread")
+    public static final OptionValue<Boolean> TruffleBackgroundCompilation = new OptionValue<>(true);
     @Option(help = "")
     public static final OptionValue<Boolean> TruffleUseTimeForCompilationDecision = new OptionValue<>(false);
     @Option(help = "")
     public static final OptionValue<Integer> TruffleCompilationDecisionTime = new OptionValue<>(100);
     @Option(help = "")
     public static final OptionValue<Boolean> TruffleCompilationDecisionTimePrintFail = new OptionValue<>(false);
-    @Option(help = "")
-    public static final OptionValue<Boolean> TruffleBackgroundCompilation = new OptionValue<>(true);
 
     // tracing
     @Option(help = "")
@@ -82,6 +84,10 @@
     @Option(help = "")
     public static final OptionValue<Boolean> TraceTruffleCompilationDetails = new OptionValue<>(false);
     @Option(help = "")
+    public static final OptionValue<Boolean> TraceTruffleCompilationHistogram = new OptionValue<>(false);
+    @Option(help = "Prints out all polymorphic and generic nodes after compilation.")
+    public static final OptionValue<Boolean> TraceTruffleCompilationPolymorphism = new OptionValue<>(false);
+    @Option(help = "")
     public static final OptionValue<Boolean> TraceTruffleExpansion = new OptionValue<>(false);
     @Option(help = "")
     public static final OptionValue<Boolean> TraceTruffleExpansionSource = new OptionValue<>(false);
@@ -92,12 +98,14 @@
     @Option(help = "")
     public static final OptionValue<Boolean> TruffleCompilationExceptionsAreFatal = new OptionValue<>(true);
     @Option(help = "")
-    public static final OptionValue<Boolean> TraceTruffleInlining = new OptionValue<>(true);
+    public static final OptionValue<Boolean> TraceTruffleInlining = new OptionValue<>(false);
     @Option(help = "")
     public static final OptionValue<Boolean> TraceTruffleInliningTree = new OptionValue<>(false);
     @Option(help = "")
     public static final OptionValue<Boolean> TraceTruffleInliningDetails = new OptionValue<>(false);
     @Option(help = "")
+    public static final OptionValue<Boolean> TraceTruffleSplitting = new OptionValue<>(false);
+    @Option(help = "")
     public static final OptionValue<Boolean> TruffleCallTargetProfiling = new StableOptionValue<>(false);
     // @formatter:on
 }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleDebugJavaMethod.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleDebugJavaMethod.java	Wed Mar 05 19:40:15 2014 -0800
@@ -26,14 +26,14 @@
 
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.debug.*;
-import com.oracle.truffle.api.impl.*;
+import com.oracle.truffle.api.*;
 
 /**
  * Enables a Truffle compilable to masquerade as a {@link JavaMethod} for use as a context value in
  * {@linkplain Debug#scope(String, Object...) debug scopes}.
  */
 public class TruffleDebugJavaMethod implements JavaMethod {
-    private final DefaultCallTarget compilable;
+    private final RootCallTarget compilable;
 
     private static final JavaType declaringClass = new JavaType() {
 
@@ -95,7 +95,7 @@
         }
     };
 
-    public TruffleDebugJavaMethod(DefaultCallTarget compilable) {
+    public TruffleDebugJavaMethod(RootCallTarget compilable) {
         this.compilable = compilable;
     }
 
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleInlining.java	Sun Feb 23 17:00:35 2014 -0800
+++ /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;
-
-public interface TruffleInlining {
-
-    /** Returns true if reprofiling is required else false. */
-    boolean performInlining(OptimizedCallTarget callTarget);
-
-    /**
-     * Returns the minimum number of invocations required until the next inlining can occur. Only
-     * used if {@link #performInlining(OptimizedCallTarget)} returned true.
-     */
-    int getInvocationReprofileCount();
-
-    /**
-     * Returns the number of invocations or loop invocations required until the next inlining can
-     * occur. Only used if {@link #performInlining(OptimizedCallTarget)} returned true.
-     */
-    int getReprofileCount();
-}
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleInliningImpl.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,217 +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.*;
-import java.util.*;
-
-import com.oracle.graal.debug.*;
-import com.oracle.truffle.api.impl.*;
-import com.oracle.truffle.api.nodes.*;
-
-class TruffleInliningImpl implements TruffleInlining {
-
-    private static final int MIN_INVOKES_AFTER_INLINING = 2;
-
-    private static final PrintStream OUT = TTY.out().out();
-
-    public int getReprofileCount() {
-        return TruffleCompilerOptions.TruffleInliningReprofileCount.getValue();
-    }
-
-    public int getInvocationReprofileCount() {
-        return MIN_INVOKES_AFTER_INLINING;
-    }
-
-    @Override
-    public boolean performInlining(OptimizedCallTarget target) {
-        final InliningPolicy policy = new InliningPolicy(target);
-        if (!policy.continueInlining()) {
-            if (TraceTruffleInliningDetails.getValue()) {
-                List<InlinableCallSiteInfo> inlinableCallSites = getInlinableCallSites(target);
-                if (!inlinableCallSites.isEmpty()) {
-                    OUT.printf("[truffle] inlining hit caller size limit (%3d >= %3d).%3d remaining call sites in %s:\n", policy.callerNodeCount, TruffleInliningMaxCallerSize.getValue(),
-                                    inlinableCallSites.size(), target.getRootNode());
-                    policy.sortByRelevance(inlinableCallSites);
-                    printCallSiteInfo(policy, inlinableCallSites, "");
-                }
-            }
-            return false;
-        }
-
-        List<InlinableCallSiteInfo> inlinableCallSites = getInlinableCallSites(target);
-        if (inlinableCallSites.isEmpty()) {
-            return false;
-        }
-
-        policy.sortByRelevance(inlinableCallSites);
-
-        boolean inlined = false;
-        for (InlinableCallSiteInfo inlinableCallSite : inlinableCallSites) {
-            if (!policy.isWorthInlining(inlinableCallSite)) {
-                break;
-            }
-            if (inlinableCallSite.getCallSite().inline(target)) {
-                if (TraceTruffleInlining.getValue()) {
-                    printCallSiteInfo(policy, inlinableCallSite, "inlined");
-                }
-                inlined = true;
-                break;
-            }
-        }
-
-        if (inlined) {
-            for (InlinableCallSiteInfo callSite : inlinableCallSites) {
-                callSite.getCallSite().resetCallCount();
-            }
-        } else {
-            if (TraceTruffleInliningDetails.getValue()) {
-                OUT.printf("[truffle] inlining stopped.%3d remaining call sites in %s:\n", inlinableCallSites.size(), target.getRootNode());
-                printCallSiteInfo(policy, inlinableCallSites, "");
-            }
-        }
-
-        return inlined;
-    }
-
-    private static void printCallSiteInfo(InliningPolicy policy, List<InlinableCallSiteInfo> inlinableCallSites, String msg) {
-        for (InlinableCallSiteInfo candidate : inlinableCallSites) {
-            printCallSiteInfo(policy, candidate, msg);
-        }
-    }
-
-    private static void printCallSiteInfo(InliningPolicy policy, InlinableCallSiteInfo callSite, String msg) {
-        String calls = String.format("%4s/%4s", callSite.getCallCount(), policy.callerInvocationCount);
-        String nodes = String.format("%3s/%3s", callSite.getInlineNodeCount(), policy.callerNodeCount);
-        OUT.printf("[truffle] %-9s %-50s |Nodes %6s |Calls %6s %7.3f |%s\n", msg, callSite.getCallSite(), nodes, calls, policy.metric(callSite), callSite.getCallSite().getCallTarget());
-    }
-
-    private static final class InliningPolicy {
-
-        private final int callerNodeCount;
-        private final int callerInvocationCount;
-
-        public InliningPolicy(OptimizedCallTarget caller) {
-            this.callerNodeCount = NodeUtil.countNodes(caller.getRootNode());
-            this.callerInvocationCount = caller.getCompilationProfile().getOriginalInvokeCounter();
-        }
-
-        public boolean continueInlining() {
-            return callerNodeCount < TruffleInliningMaxCallerSize.getValue();
-        }
-
-        public boolean isWorthInlining(InlinableCallSiteInfo callSite) {
-            return callSite.getInlineNodeCount() <= TruffleInliningMaxCalleeSize.getValue() && callSite.getInlineNodeCount() + callerNodeCount <= TruffleInliningMaxCallerSize.getValue() &&
-                            callSite.getCallCount() > 0 && callSite.getRecursiveDepth() < TruffleInliningMaxRecursiveDepth.getValue() &&
-                            (frequency(callSite) >= TruffleInliningMinFrequency.getValue() || callSite.getInlineNodeCount() <= TruffleInliningTrivialSize.getValue());
-        }
-
-        public double metric(InlinableCallSiteInfo callSite) {
-            double cost = callSite.getInlineNodeCount();
-            double metric = frequency(callSite) / cost;
-            return metric;
-        }
-
-        private double frequency(InlinableCallSiteInfo callSite) {
-            return (double) callSite.getCallCount() / (double) callerInvocationCount;
-        }
-
-        public void sortByRelevance(List<InlinableCallSiteInfo> inlinableCallSites) {
-            Collections.sort(inlinableCallSites, new Comparator<InlinableCallSiteInfo>() {
-
-                @Override
-                public int compare(InlinableCallSiteInfo cs1, InlinableCallSiteInfo cs2) {
-                    int result = (isWorthInlining(cs2) ? 1 : 0) - (isWorthInlining(cs1) ? 1 : 0);
-                    if (result == 0) {
-                        return Double.compare(metric(cs2), metric(cs1));
-                    }
-                    return result;
-                }
-            });
-        }
-    }
-
-    private static final class InlinableCallSiteInfo {
-
-        private final InlinableCallSite callSite;
-        private final int callCount;
-        private final int nodeCount;
-        private final int recursiveDepth;
-
-        public InlinableCallSiteInfo(InlinableCallSite callSite) {
-            this.callSite = callSite;
-            this.callCount = callSite.getCallCount();
-            this.nodeCount = NodeUtil.countNodes(callSite.getInlineTree());
-            this.recursiveDepth = calculateRecursiveDepth();
-        }
-
-        public int getRecursiveDepth() {
-            return recursiveDepth;
-        }
-
-        private int calculateRecursiveDepth() {
-            int depth = 0;
-            Node parent = ((Node) callSite).getParent();
-            while (!(parent instanceof RootNode)) {
-                assert parent != null;
-                if (parent instanceof InlinedCallSite && ((InlinedCallSite) parent).getCallTarget() == callSite.getCallTarget()) {
-                    depth++;
-                }
-                parent = parent.getParent();
-            }
-            if (((RootNode) parent).getCallTarget() == callSite.getCallTarget()) {
-                depth++;
-            }
-            return depth;
-        }
-
-        public InlinableCallSite getCallSite() {
-            return callSite;
-        }
-
-        public int getCallCount() {
-            return callCount;
-        }
-
-        public int getInlineNodeCount() {
-            return nodeCount;
-        }
-    }
-
-    static List<InlinableCallSiteInfo> getInlinableCallSites(final DefaultCallTarget target) {
-        final ArrayList<InlinableCallSiteInfo> inlinableCallSites = new ArrayList<>();
-        target.getRootNode().accept(new NodeVisitor() {
-
-            @Override
-            public boolean visit(Node node) {
-                if (node instanceof InlinableCallSite) {
-                    inlinableCallSites.add(new InlinableCallSiteInfo((InlinableCallSite) node));
-                }
-                return true;
-            }
-        });
-        return inlinableCallSites;
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleInliningProfile.java	Wed Mar 05 19:40:15 2014 -0800
@@ -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;
+
+import java.util.*;
+
+public interface TruffleInliningProfile extends Comparable<TruffleInliningProfile> {
+
+    OptimizedCallNode getCallNode();
+
+    boolean isInliningAllowed();
+
+    int compareTo(TruffleInliningProfile o);
+
+    Map<String, Object> getDebugProperties();
+
+}
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleReplacements.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleReplacements.java	Wed Mar 05 19:40:15 2014 -0800
@@ -58,7 +58,6 @@
         truffleReplacements.registerSubstitutions(FrameWithoutBoxingSubstitutions.class);
         truffleReplacements.registerSubstitutions(OptimizedAssumptionSubstitutions.class);
         truffleReplacements.registerSubstitutions(OptimizedCallTargetSubstitutions.class);
-        truffleReplacements.registerSubstitutions(DefaultCallTargetSubstitutions.class);
 
         return truffleReplacements;
     }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleTreeDumpHandler.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleTreeDumpHandler.java	Wed Mar 05 19:40:15 2014 -0800
@@ -23,17 +23,17 @@
 package com.oracle.graal.truffle;
 
 import com.oracle.graal.debug.*;
-import com.oracle.truffle.api.impl.*;
+import com.oracle.truffle.api.*;
 import com.oracle.truffle.api.nodes.*;
 
 public class TruffleTreeDumpHandler implements DebugDumpHandler {
 
     @Override
     public void dump(Object object, final String message) {
-        if (object instanceof DefaultCallTarget) {
-            DefaultCallTarget callTarget = (DefaultCallTarget) object;
+        if (object instanceof RootCallTarget) {
+            RootCallTarget callTarget = (RootCallTarget) object;
             if (callTarget.getRootNode() != null) {
-                new GraphPrintVisitor().beginGroup(callTarget.toString()).beginGraph(message).visit(callTarget.getRootNode()).printToNetwork();
+                new GraphPrintVisitor().beginGroup(callTarget.toString()).beginGraph(message).visit(callTarget.getRootNode()).printToNetwork(false);
             }
         }
     }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerAddExactNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerAddExactNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -38,8 +38,8 @@
 public class IntegerAddExactNode extends IntegerAddNode implements Canonicalizable, IntegerExactArithmeticNode {
 
     public IntegerAddExactNode(ValueNode x, ValueNode y) {
-        super(x.kind(), x, y);
-        assert x.kind() == y.kind() && (x.kind() == Kind.Int || x.kind() == Kind.Long);
+        super(x.stamp().unrestricted(), x, y);
+        assert x.stamp().isCompatible(y.stamp()) && x.stamp() instanceof IntegerStamp;
     }
 
     @Override
@@ -54,12 +54,15 @@
             return graph().unique(new IntegerAddExactNode(y(), x()));
         }
         if (x().isConstant()) {
+            Constant xConst = x().asConstant();
+            Constant yConst = y().asConstant();
+            assert xConst.getKind() == yConst.getKind();
             try {
-                if (kind() == Kind.Int) {
-                    return ConstantNode.forInt(ExactMath.addExact(x().asConstant().asInt(), y().asConstant().asInt()), graph());
+                if (xConst.getKind() == Kind.Int) {
+                    return ConstantNode.forInt(ExactMath.addExact(xConst.asInt(), yConst.asInt()), graph());
                 } else {
-                    assert kind() == Kind.Long;
-                    return ConstantNode.forLong(ExactMath.addExact(x().asConstant().asLong(), y().asConstant().asLong()), graph());
+                    assert xConst.getKind() == Kind.Long;
+                    return ConstantNode.forLong(ExactMath.addExact(xConst.asLong(), yConst.asLong()), graph());
                 }
             } catch (ArithmeticException ex) {
                 // The operation will result in an overflow exception, so do not canonicalize.
@@ -84,8 +87,12 @@
     }
 
     @NodeIntrinsic
-    public static native int addExact(int a, int b);
+    public static int addExact(int a, int b) {
+        return ExactMath.addExact(a, b);
+    }
 
     @NodeIntrinsic
-    public static native long addExact(long a, long b);
+    public static long addExact(long a, long b) {
+        return ExactMath.addExact(a, b);
+    }
 }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerExactArithmeticSplitNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerExactArithmeticSplitNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -74,7 +74,7 @@
     @Override
     public void generate(LIRGenerator generator) {
         generator.setResult(this, generateArithmetic(generator));
-        generator.emitOverflowCheckBranch(generator.getLIRBlock(getNext()), generator.getLIRBlock(getOverflowSuccessor()));
+        generator.emitOverflowCheckBranch(generator.getLIRBlock(getOverflowSuccessor()), generator.getLIRBlock(getNext()), probability(getOverflowSuccessor()));
     }
 
     protected abstract Value generateArithmetic(LIRGeneratorTool generator);
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerMulExactNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerMulExactNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -28,6 +28,7 @@
 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.*;
 
 /**
@@ -37,8 +38,8 @@
 public class IntegerMulExactNode extends IntegerMulNode implements Canonicalizable, IntegerExactArithmeticNode {
 
     public IntegerMulExactNode(ValueNode x, ValueNode y) {
-        super(x.kind(), x, y);
-        assert x.kind() == y.kind() && (x.kind() == Kind.Int || x.kind() == Kind.Long);
+        super(x.stamp().unrestricted(), x, y);
+        assert x.stamp().isCompatible(y.stamp()) && x.stamp() instanceof IntegerStamp;
     }
 
     @Override
@@ -47,12 +48,15 @@
             return graph().unique(new IntegerMulExactNode(y(), x()));
         }
         if (x().isConstant()) {
+            Constant xConst = x().asConstant();
+            Constant yConst = y().asConstant();
+            assert xConst.getKind() == yConst.getKind();
             try {
-                if (kind() == Kind.Int) {
-                    return ConstantNode.forInt(ExactMath.multiplyExact(x().asConstant().asInt(), y().asConstant().asInt()), graph());
+                if (xConst.getKind() == Kind.Int) {
+                    return ConstantNode.forInt(ExactMath.multiplyExact(xConst.asInt(), yConst.asInt()), graph());
                 } else {
-                    assert kind() == Kind.Long;
-                    return ConstantNode.forLong(ExactMath.multiplyExact(x().asConstant().asLong(), y().asConstant().asLong()), graph());
+                    assert xConst.getKind() == Kind.Long;
+                    return ConstantNode.forLong(ExactMath.multiplyExact(xConst.asLong(), yConst.asLong()), graph());
                 }
             } catch (ArithmeticException ex) {
                 // The operation will result in an overflow exception, so do not canonicalize.
@@ -63,7 +67,7 @@
                 return x();
             }
             if (c == 0) {
-                return ConstantNode.defaultForKind(kind(), graph());
+                return ConstantNode.forIntegerStamp(stamp(), 0, graph());
             }
         }
         return this;
@@ -80,8 +84,12 @@
     }
 
     @NodeIntrinsic
-    public static native int multiplyExact(int a, int b);
+    public static int multiplyExact(int a, int b) {
+        return ExactMath.multiplyExact(a, b);
+    }
 
     @NodeIntrinsic
-    public static native long multiplyExact(long a, long b);
+    public static long multiplyExact(long a, long b) {
+        return ExactMath.multiplyExact(a, b);
+    }
 }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerSubExactNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerSubExactNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -38,8 +38,8 @@
 public class IntegerSubExactNode extends IntegerSubNode implements Canonicalizable, IntegerExactArithmeticNode {
 
     public IntegerSubExactNode(ValueNode x, ValueNode y) {
-        super(x.kind(), x, y);
-        assert x.kind() == y.kind() && (x.kind() == Kind.Int || x.kind() == Kind.Long);
+        super(StampTool.sub(x.stamp(), y.stamp()), x, y);
+        assert x.stamp().isCompatible(y.stamp()) && x.stamp() instanceof IntegerStamp;
     }
 
     @Override
@@ -51,15 +51,18 @@
     @Override
     public Node canonical(CanonicalizerTool tool) {
         if (x() == y()) {
-            return ConstantNode.forIntegerKind(kind(), 0, graph());
+            return ConstantNode.forIntegerStamp(stamp(), 0, graph());
         }
         if (x().isConstant() && y().isConstant()) {
+            Constant xConst = x().asConstant();
+            Constant yConst = y().asConstant();
+            assert xConst.getKind() == yConst.getKind();
             try {
-                if (kind() == Kind.Int) {
-                    return ConstantNode.forInt(ExactMath.subtractExact(x().asConstant().asInt(), y().asConstant().asInt()), graph());
+                if (xConst.getKind() == Kind.Int) {
+                    return ConstantNode.forInt(ExactMath.subtractExact(xConst.asInt(), yConst.asInt()), graph());
                 } else {
-                    assert kind() == Kind.Long;
-                    return ConstantNode.forLong(ExactMath.subtractExact(x().asConstant().asLong(), y().asConstant().asLong()), graph());
+                    assert xConst.getKind() == Kind.Long;
+                    return ConstantNode.forLong(ExactMath.subtractExact(xConst.asLong(), yConst.asLong()), graph());
                 }
             } catch (ArithmeticException ex) {
                 // The operation will result in an overflow exception, so do not canonicalize.
@@ -84,8 +87,12 @@
     }
 
     @NodeIntrinsic
-    public static native int subtractExact(int a, int b);
+    public static int subtractExact(int a, int b) {
+        return ExactMath.subtractExact(a, b);
+    }
 
     @NodeIntrinsic
-    public static native long subtractExact(long a, long b);
+    public static long subtractExact(long a, long b) {
+        return ExactMath.subtractExact(a, b);
+    }
 }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/NewFrameNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/NewFrameNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -25,7 +25,6 @@
 import java.util.*;
 
 import com.oracle.graal.api.meta.*;
-import com.oracle.graal.api.runtime.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.*;
@@ -34,7 +33,6 @@
 import com.oracle.graal.nodes.type.*;
 import com.oracle.graal.nodes.util.*;
 import com.oracle.graal.nodes.virtual.*;
-import com.oracle.graal.runtime.*;
 import com.oracle.graal.truffle.*;
 import com.oracle.graal.truffle.nodes.*;
 import com.oracle.truffle.api.*;
@@ -46,8 +44,6 @@
  */
 public class NewFrameNode extends FixedWithNextNode implements IterableNodeType, VirtualizableAllocation, Canonicalizable {
 
-    static final ResolvedJavaType FRAME_TYPE = Graal.getRequiredCapability(RuntimeProvider.class).getHostBackend().getProviders().getMetaAccess().lookupJavaType(FrameWithoutBoxing.class);
-
     @Input private ValueNode descriptor;
     @Input private ValueNode caller;
     @Input private ValueNode arguments;
@@ -59,8 +55,8 @@
         this.arguments = arguments;
     }
 
-    public NewFrameNode(ValueNode descriptor, ValueNode caller, ValueNode arguments) {
-        this(StampFactory.exactNonNull(FRAME_TYPE), descriptor, caller, arguments);
+    public NewFrameNode(ResolvedJavaType frameType, ValueNode descriptor, ValueNode caller, ValueNode arguments) {
+        this(StampFactory.exactNonNull(frameType), descriptor, caller, arguments);
     }
 
     public ValueNode getDescriptor() {
@@ -233,5 +229,5 @@
     }
 
     @NodeIntrinsic
-    public static native FrameWithoutBoxing allocate(FrameDescriptor descriptor, PackedFrame caller, Arguments args);
+    public static native FrameWithoutBoxing allocate(@ConstantNodeParameter Class<? extends VirtualFrame> frameType, FrameDescriptor descriptor, PackedFrame caller, Arguments args);
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeLoadFinalNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,106 @@
+/*
+ * 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.typesystem;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.calc.*;
+import com.oracle.graal.nodes.extended.*;
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.nodes.type.*;
+import com.oracle.truffle.api.*;
+
+/**
+ * Load of a final value from a location specified as an offset relative to an object.
+ * 
+ * Substitution for method {@link CompilerDirectives#unsafeGetFinalObject} and friends.
+ */
+public class CustomizedUnsafeLoadFinalNode extends FixedWithNextNode implements Canonicalizable, Virtualizable, Lowerable {
+    @Input private ValueNode object;
+    @Input private ValueNode offset;
+    @Input private ValueNode condition;
+    @Input private ValueNode location;
+    private final Kind accessKind;
+
+    public CustomizedUnsafeLoadFinalNode(ValueNode object, ValueNode offset, ValueNode condition, ValueNode location, Kind accessKind) {
+        super(StampFactory.forKind(accessKind.getStackKind()));
+        this.object = object;
+        this.offset = offset;
+        this.condition = condition;
+        this.location = location;
+        this.accessKind = accessKind;
+    }
+
+    @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);
+            return ConstantNode.forConstant(constant, tool.getMetaAccess(), graph());
+        }
+        return this;
+    }
+
+    /**
+     * @see UnsafeLoadNode#virtualize(VirtualizerTool)
+     */
+    @Override
+    public void virtualize(VirtualizerTool tool) {
+        State state = tool.getObjectState(object);
+        if (state != null && state.getState() == EscapeState.Virtual) {
+            ValueNode offsetValue = tool.getReplacedValue(offset);
+            if (offsetValue.isConstant()) {
+                long constantOffset = offsetValue.asConstant().asLong();
+                int entryIndex = state.getVirtualObject().entryIndexForOffset(constantOffset);
+                if (entryIndex != -1) {
+                    ValueNode entry = state.getEntry(entryIndex);
+                    if (entry.kind() == kind() || state.getVirtualObject().entryKind(entryIndex) == accessKind) {
+                        tool.replaceWith(entry);
+                    }
+                }
+            }
+        }
+    }
+
+    @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) {
+            locationIdentity = LocationIdentity.ANY_LOCATION;
+        } else {
+            locationIdentity = ObjectLocationIdentity.create(locationIdentityObject);
+        }
+        UnsafeLoadNode result = graph().add(new UnsafeLoadNode(object, offset, accessKind, locationIdentity, compare));
+        graph().replaceFixedWithFixed(this, result);
+        result.lower(tool);
+    }
+
+    @SuppressWarnings("unused")
+    @NodeIntrinsic
+    public static <T> T load(Object object, long offset, boolean condition, Object locationIdentity, @ConstantNodeParameter Kind kind) {
+        return UnsafeLoadNode.load(object, offset, kind, null);
+    }
+}
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/CompilerDirectivesSubstitutions.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/CompilerDirectivesSubstitutions.java	Wed Mar 05 19:40:15 2014 -0800
@@ -91,6 +91,9 @@
     public static native int unsafeGetInt(Object receiver, long offset, boolean condition, Object locationIdentity);
 
     @MacroSubstitution(macro = CustomizedUnsafeLoadMacroNode.class, isStatic = true)
+    public static native long unsafeGetLong(Object receiver, long offset, boolean condition, Object locationIdentity);
+
+    @MacroSubstitution(macro = CustomizedUnsafeLoadMacroNode.class, isStatic = true)
     public static native float unsafeGetFloat(Object receiver, long offset, boolean condition, Object locationIdentity);
 
     @MacroSubstitution(macro = CustomizedUnsafeLoadMacroNode.class, isStatic = true)
@@ -122,4 +125,44 @@
 
     @MacroSubstitution(macro = CustomizedUnsafeStoreMacroNode.class, isStatic = true)
     public static native void unsafePutObject(Object receiver, long offset, Object value, Object locationIdentity);
+
+    @MethodSubstitution
+    public static boolean unsafeGetFinalBoolean(Object receiver, long offset, boolean condition, Object locationIdentity) {
+        return CustomizedUnsafeLoadFinalNode.load(receiver, offset, condition, locationIdentity, Kind.Boolean);
+    }
+
+    @MethodSubstitution
+    public static byte unsafeGetFinalByte(Object receiver, long offset, boolean condition, Object locationIdentity) {
+        return CustomizedUnsafeLoadFinalNode.load(receiver, offset, condition, locationIdentity, Kind.Byte);
+    }
+
+    @MethodSubstitution
+    public static short unsafeGetFinalShort(Object receiver, long offset, boolean condition, Object locationIdentity) {
+        return CustomizedUnsafeLoadFinalNode.load(receiver, offset, condition, locationIdentity, Kind.Short);
+    }
+
+    @MethodSubstitution
+    public static int unsafeGetFinalInt(Object receiver, long offset, boolean condition, Object locationIdentity) {
+        return CustomizedUnsafeLoadFinalNode.load(receiver, offset, condition, locationIdentity, Kind.Int);
+    }
+
+    @MethodSubstitution
+    public static long unsafeGetFinalLong(Object receiver, long offset, boolean condition, Object locationIdentity) {
+        return CustomizedUnsafeLoadFinalNode.load(receiver, offset, condition, locationIdentity, Kind.Long);
+    }
+
+    @MethodSubstitution
+    public static float unsafeGetFinalFloat(Object receiver, long offset, boolean condition, Object locationIdentity) {
+        return CustomizedUnsafeLoadFinalNode.load(receiver, offset, condition, locationIdentity, Kind.Float);
+    }
+
+    @MethodSubstitution
+    public static double unsafeGetFinalDouble(Object receiver, long offset, boolean condition, Object locationIdentity) {
+        return CustomizedUnsafeLoadFinalNode.load(receiver, offset, condition, locationIdentity, Kind.Double);
+    }
+
+    @MethodSubstitution
+    public static Object unsafeGetFinalObject(Object receiver, long offset, boolean condition, Object locationIdentity) {
+        return CustomizedUnsafeLoadFinalNode.load(receiver, offset, condition, locationIdentity, Kind.Object);
+    }
 }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/DefaultCallTargetSubstitutions.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +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.nodes.asserts.*;
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.impl.*;
-
-@ClassSubstitution(DefaultCallTarget.class)
-public class DefaultCallTargetSubstitutions {
-
-    @MacroSubstitution(macro = NeverInlineMacroNode.class, isStatic = false)
-    public static native Object call(DefaultCallTarget target, PackedFrame caller, Arguments args);
-}
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/OptimizedCallTargetSubstitutions.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/OptimizedCallTargetSubstitutions.java	Wed Mar 05 19:40:15 2014 -0800
@@ -44,12 +44,6 @@
 
     @MethodSubstitution
     private static FrameWithoutBoxing createFrame(FrameDescriptor descriptor, PackedFrame caller, Arguments args) {
-        return NewFrameNode.allocate(descriptor, caller, args);
-    }
-
-    @SuppressWarnings("unused")
-    @MethodSubstitution(isStatic = false)
-    private static VirtualFrame create(OptimizedCallTarget target, FrameDescriptor descriptor, PackedFrame caller, Arguments args) {
-        return createFrame(descriptor, caller, args);
+        return NewFrameNode.allocate(FrameWithoutBoxing.class, descriptor, caller, args);
     }
 }
--- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeRewriterPhase.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeRewriterPhase.java	Wed Mar 05 19:40:15 2014 -0800
@@ -36,6 +36,7 @@
 import com.oracle.graal.nodes.type.*;
 import com.oracle.graal.nodes.util.*;
 import com.oracle.graal.phases.*;
+import com.oracle.graal.phases.graph.*;
 import com.oracle.graal.word.*;
 import com.oracle.graal.word.Word.Opcode;
 import com.oracle.graal.word.Word.Operation;
@@ -63,7 +64,7 @@
 
     @Override
     protected void run(StructuredGraph graph) {
-        inferStamps(graph);
+        InferStamps.inferStamps(graph);
 
         for (Node n : graph.getNodes()) {
             if (n instanceof ValueNode) {
@@ -77,68 +78,6 @@
     }
 
     /**
-     * Infer the stamps for all Object nodes in the graph, to make the stamps as precise as
-     * possible. For example, this propagates the word-type through phi functions. To handle phi
-     * functions at loop headers, the stamp inference is called until a fix point is reached.
-     * <p>
-     * Note that we cannot rely on the normal canonicalizer to propagate stamps: The word type
-     * rewriting must run before the first run of the canonicalizer because many nodes are not
-     * prepared to see the word type during canonicalization.
-     */
-    protected void inferStamps(StructuredGraph graph) {
-        /*
-         * We want to make the stamps more precise. For cyclic phi functions, this means we have to
-         * ignore the initial stamp because the imprecise stamp would always propagate around the
-         * cycle. We therefore set the stamp to an illegal stamp, which is automatically ignored
-         * when the phi function performs the "meet" operator on its input stamps.
-         */
-        for (Node n : graph.getNodes()) {
-            if (n instanceof PhiNode || n instanceof ProxyNode) {
-                ValueNode node = (ValueNode) n;
-                if (node.kind() == Kind.Object) {
-                    assert !(node.stamp() instanceof IllegalStamp) : "We assume all Phi and Proxy stamps are legal before the analysis";
-                    node.setStamp(StampFactory.illegal(node.kind()));
-                }
-            }
-        }
-
-        boolean stampChanged;
-        do {
-            stampChanged = false;
-            /*
-             * We could use GraphOrder.forwardGraph() to process the nodes in a defined order and
-             * propagate long def-use chains in fewer iterations. However, measurements showed that
-             * we have few iterations anyway, and the overhead of computing the order is much higher
-             * than the benefit.
-             */
-            for (Node n : graph.getNodes()) {
-                if (n instanceof ValueNode) {
-                    ValueNode node = (ValueNode) n;
-                    if (node.kind() == Kind.Object) {
-                        stampChanged |= node.inferStamp();
-                    }
-                }
-            }
-        } while (stampChanged);
-
-        /*
-         * Check that all the illegal stamps we introduced above are correctly replaced with real
-         * stamps again.
-         */
-        assert checkNoIllegalStamp(graph);
-    }
-
-    private static boolean checkNoIllegalStamp(StructuredGraph graph) {
-        for (Node n : graph.getNodes()) {
-            if (n instanceof PhiNode || n instanceof ProxyNode) {
-                ValueNode node = (ValueNode) n;
-                assert !(node.stamp() instanceof IllegalStamp) : "Stamp is illegal after analysis. This is not necessarily an error, but a condition that we want to investigate (and then maybe relax or remove the assertion).";
-            }
-        }
-        return true;
-    }
-
-    /**
      * Change the stamp for word nodes from the object stamp ({@link WordBase} or anything extending
      * or implementing that interface) to the primitive word stamp.
      */
@@ -263,7 +202,7 @@
 
             case NOT:
                 assert arguments.size() == 1;
-                replace(invoke, graph.unique(new XorNode(wordKind, arguments.get(0), ConstantNode.forIntegerKind(wordKind, -1, graph))));
+                replace(invoke, graph.unique(new XorNode(StampFactory.forKind(wordKind), arguments.get(0), ConstantNode.forIntegerKind(wordKind, -1, graph))));
                 break;
 
             case READ: {
@@ -362,14 +301,14 @@
 
         if (toKind == Kind.Int) {
             assert value.kind() == Kind.Long;
-            return graph.unique(new ConvertNode(Kind.Long, Kind.Int, value));
+            return graph.unique(new NarrowNode(value, 32));
         } else {
             assert toKind == Kind.Long;
             assert value.kind().getStackKind() == Kind.Int;
             if (unsigned) {
-                return graph.unique(new ReinterpretNode(Kind.Long, value));
+                return graph.unique(new ZeroExtendNode(value, 64));
             } else {
-                return graph.unique(new ConvertNode(Kind.Int, Kind.Long, value));
+                return graph.unique(new SignExtendNode(value, 64));
             }
         }
     }
@@ -381,8 +320,8 @@
      */
     private static ValueNode createBinaryNodeInstance(Class<? extends ValueNode> nodeClass, Kind kind, ValueNode left, ValueNode right) {
         try {
-            Constructor<? extends ValueNode> constructor = nodeClass.getConstructor(Kind.class, ValueNode.class, ValueNode.class);
-            return constructor.newInstance(kind, left, right);
+            Constructor<? extends ValueNode> constructor = nodeClass.getConstructor(Stamp.class, ValueNode.class, ValueNode.class);
+            return constructor.newInstance(StampFactory.forKind(kind), left, right);
         } catch (Throwable ex) {
             throw new GraalInternalError(ex).addContext(nodeClass.getName());
         }
@@ -431,7 +370,7 @@
     }
 
     protected ValueNode readOp(StructuredGraph graph, ValueNode base, Invoke invoke, LocationNode location, Kind readKind, BarrierType barrierType, boolean compressible) {
-        ReadNode read = graph.add(new ReadNode(base, location, StampFactory.forKind(readKind), barrierType, compressible));
+        ReadNode read = graph.add(new ReadNode(base, location, StampFactory.forKind(readKind.getStackKind()), barrierType, compressible));
         graph.addBeforeFixed(invoke.asNode(), read);
         /*
          * The read must not float outside its block otherwise it may float above an explicit zero
--- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeVerificationPhase.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeVerificationPhase.java	Wed Mar 05 19:40:15 2014 -0800
@@ -32,6 +32,7 @@
 import com.oracle.graal.nodes.java.*;
 import com.oracle.graal.nodes.util.*;
 import com.oracle.graal.phases.*;
+import com.oracle.graal.phases.graph.*;
 import com.oracle.graal.word.*;
 import com.oracle.graal.word.Word.Operation;
 
@@ -58,7 +59,7 @@
          * modifies the stamp of nodes, we copy the graph before running the verification.
          */
         StructuredGraph graph = inputGraph.copy();
-        wordAccess.inferStamps(graph);
+        InferStamps.inferStamps(graph);
 
         for (ValueNode node : graph.getNodes().filter(ValueNode.class)) {
             if (!node.recordsUsages()) {
@@ -81,7 +82,6 @@
                 } else if (usage instanceof StoreIndexedNode) {
                     verify(!isWord(node) || ((StoreIndexedNode) usage).array() != node, node, usage, "cannot store to word value");
                     verify(!isWord(node) || ((StoreIndexedNode) usage).index() != node, node, usage, "cannot use word value as index");
-                    verify(!isWord(node) || ((StoreIndexedNode) usage).value() != node, node, usage, "cannot store word value to array");
                 } else if (usage instanceof MethodCallTargetNode) {
                     MethodCallTargetNode callTarget = (MethodCallTargetNode) usage;
                     verifyInvoke(node, callTarget);
--- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/TestHelper.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/TestHelper.java	Wed Mar 05 19:40:15 2014 -0800
@@ -24,6 +24,7 @@
 
 import static org.junit.Assert.*;
 
+import java.lang.reflect.*;
 import java.util.*;
 
 import com.oracle.truffle.api.*;
@@ -61,7 +62,17 @@
     }
 
     static <E extends ValueNode> E createGenericNode(NodeFactory<E> factory, Object... constants) {
-        return factory.createNodeGeneric(createNode(factory, constants));
+        Method createGenericMethod;
+        try {
+            createGenericMethod = factory.getClass().getMethod("createGeneric", factory.getNodeClass());
+        } catch (NoSuchMethodException e) {
+            throw new RuntimeException(e);
+        }
+        try {
+            return factory.getNodeClass().cast(createGenericMethod.invoke(null, createNode(factory, constants)));
+        } catch (IllegalAccessException | InvocationTargetException e) {
+            throw new RuntimeException(e);
+        }
     }
 
     static <E extends ValueNode> TestRootNode<E> createRoot(NodeFactory<E> factory, Object... constants) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/UnsupportedSpecializationTest.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.api.dsl.test;
+
+import java.util.*;
+
+import org.junit.*;
+
+import com.oracle.truffle.api.dsl.*;
+import com.oracle.truffle.api.dsl.test.TypeSystemTest.TestRootNode;
+import com.oracle.truffle.api.dsl.test.TypeSystemTest.ValueNode;
+import com.oracle.truffle.api.dsl.test.UnsupportedSpecializationTestFactory.Unsupported1Factory;
+import com.oracle.truffle.api.dsl.test.UnsupportedSpecializationTestFactory.Unsupported2Factory;
+import com.oracle.truffle.api.nodes.*;
+
+public class UnsupportedSpecializationTest {
+
+    @Test
+    public void testUnsupported1() {
+        TestRootNode<Unsupported1> root = TestHelper.createRoot(Unsupported1Factory.getInstance());
+        try {
+            TestHelper.executeWith(root, "");
+            Assert.fail();
+        } catch (UnsupportedSpecializationException e) {
+            Assert.assertNotNull(e.getSuppliedValues());
+            Assert.assertEquals(1, e.getSuppliedValues().length);
+            Assert.assertEquals("", e.getSuppliedValues()[0]);
+            Assert.assertSame(root.getNode().getChildren().iterator().next(), e.getSuppliedNodes()[0]);
+            Assert.assertEquals(root.getNode(), e.getNode());
+        }
+    }
+
+    @NodeChild("a")
+    abstract static class Unsupported1 extends ValueNode {
+
+        @Specialization
+        public int doInteger(@SuppressWarnings("unused") int a) {
+            throw new AssertionError();
+        }
+    }
+
+    @Test
+    public void testUnsupported2() {
+        TestRootNode<Unsupported2> root = TestHelper.createRoot(Unsupported2Factory.getInstance());
+        try {
+            TestHelper.executeWith(root, "", 1);
+            Assert.fail();
+        } catch (UnsupportedSpecializationException e) {
+            Assert.assertNotNull(e.getSuppliedValues());
+            Assert.assertNotNull(e.getSuppliedNodes());
+            Assert.assertEquals(3, e.getSuppliedValues().length);
+            Assert.assertEquals(3, e.getSuppliedNodes().length);
+            Assert.assertEquals("", e.getSuppliedValues()[0]);
+            Assert.assertEquals(false, e.getSuppliedValues()[1]);
+            Assert.assertEquals(null, e.getSuppliedValues()[2]);
+            List<Node> children = NodeUtil.findNodeChildren(root.getNode());
+            Assert.assertSame(children.get(0), e.getSuppliedNodes()[0]);
+            Assert.assertNull(e.getSuppliedNodes()[1]);
+            Assert.assertSame(children.get(1), e.getSuppliedNodes()[2]);
+            Assert.assertEquals(root.getNode(), e.getNode());
+        }
+    }
+
+    @SuppressWarnings("unused")
+    @NodeChildren({@NodeChild("a"), @NodeChild("b")})
+    abstract static class Unsupported2 extends ValueNode {
+
+        @ShortCircuit("b")
+        public boolean needsB(Object a) {
+            return false;
+        }
+
+        @Specialization
+        public int doInteger(int a, boolean hasB, int b) {
+            throw new AssertionError();
+        }
+    }
+
+}
--- a/graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/NodeFactory.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/NodeFactory.java	Wed Mar 05 19:40:15 2014 -0800
@@ -46,15 +46,6 @@
     T createNode(Object... arguments);
 
     /**
-     * Instantiates a new generic variant of the node. This is an optional method and throws an
-     * {@link UnsupportedOperationException} if not supported.
-     * 
-     * @param thisNode the current node
-     * @return the specialized node
-     */
-    T createNodeGeneric(T thisNode);
-
-    /**
      * Returns the node class that will get created by {@link #createNode(Object...)}. The node
      * class does not match exactly to the instantiated object but they are guaranteed to be
      * assignable.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/UnsupportedSpecializationException.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,80 @@
+/*
+ * 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.  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.dsl;
+
+import java.util.*;
+
+import com.oracle.truffle.api.nodes.*;
+
+/**
+ * Thrown by the generated code of Truffle-DSL if no compatible Specialization could be found for
+ * the provided values.
+ */
+public final class UnsupportedSpecializationException extends RuntimeException {
+
+    private static final long serialVersionUID = -2122892028296836269L;
+
+    private final Node node;
+    private final Node[] suppliedNodes;
+    private final Object[] suppliedValues;
+
+    public UnsupportedSpecializationException(Node node, Node[] suppliedNodes, Object... suppliedValues) {
+        super("Unexpected values provided for " + node + ": " + Arrays.toString(suppliedValues));
+        Objects.requireNonNull(suppliedNodes, "The suppliedNodes parameter must not be null.");
+        if (suppliedNodes.length != suppliedValues.length) {
+            throw new IllegalArgumentException("The length of suppliedNodes must match the length of suppliedValues.");
+        }
+        this.node = node;
+        this.suppliedNodes = suppliedNodes;
+        this.suppliedValues = suppliedValues;
+    }
+
+    /**
+     * Returns the {@link Node} that caused the this {@link UnsupportedSpecializationException}.
+     */
+    public Node getNode() {
+        return node;
+    }
+
+    /**
+     * Returns the children of the {@link Node} returned by {@link #getNode()} which produced the
+     * values returned by {@link #getSuppliedValues()}. The array returned by
+     * {@link #getSuppliedNodes()} has the same length as the array returned by
+     * {@link #getSuppliedValues()}. Never returns null.
+     */
+    public Node[] getSuppliedNodes() {
+        return suppliedNodes;
+    }
+
+    /**
+     * Returns the dynamic values that were supplied to the node.The array returned by
+     * {@link #getSuppliedNodes()} has the same length as the array returned by
+     * {@link #getSuppliedValues()}. Never returns null.
+     */
+    public Object[] getSuppliedValues() {
+        return suppliedValues;
+    }
+
+}
--- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/FrameTest.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/FrameTest.java	Wed Mar 05 19:40:15 2014 -0800
@@ -37,7 +37,8 @@
  * {@link FrameDescriptor} represents the current structure of the frame. The method
  * {@link FrameDescriptor#addFrameSlot(Object, FrameSlotKind)} can be used to create predefined
  * frame slots. The setter and getter methods in the {@link Frame} class can be used to access the
- * current value of a particular frame slot.
+ * current value of a particular frame slot. Values can be removed from a frame via the
+ * {@link FrameDescriptor#removeFrameSlot(Object)} method.
  * </p>
  * 
  * <p>
@@ -64,11 +65,20 @@
     public void test() {
         TruffleRuntime runtime = Truffle.getRuntime();
         FrameDescriptor frameDescriptor = new FrameDescriptor();
-        FrameSlot slot = frameDescriptor.addFrameSlot("localVar", FrameSlotKind.Int);
+        String varName = "localVar";
+        FrameSlot slot = frameDescriptor.addFrameSlot(varName, FrameSlotKind.Int);
         TestRootNode rootNode = new TestRootNode(frameDescriptor, new AssignLocal(slot), new ReadLocal(slot));
         CallTarget target = runtime.createCallTarget(rootNode);
         Object result = target.call();
         Assert.assertEquals(42, result);
+        frameDescriptor.removeFrameSlot(varName);
+        boolean slotMissing = false;
+        try {
+            result = target.call();
+        } catch (IllegalArgumentException iae) {
+            slotMissing = true;
+        }
+        Assert.assertTrue(slotMissing);
     }
 
     class TestRootNode extends RootNode {
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/CallTarget.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/CallTarget.java	Wed Mar 05 19:40:15 2014 -0800
@@ -27,8 +27,7 @@
 import com.oracle.truffle.api.frame.*;
 
 /**
- * Represents the target of a call. Instances of this interface can be created using the
- * {@link TruffleRuntime#createCallTarget(com.oracle.truffle.api.nodes.RootNode)} method.
+ * Represents the target of a call.
  */
 public abstract class CallTarget {
 
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/CompilerDirectives.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/CompilerDirectives.java	Wed Mar 05 19:40:15 2014 -0800
@@ -242,7 +242,7 @@
     }
 
     /**
-     * Unsafe access to a int value within an object. The condition parameter gives a hint to the
+     * Unsafe access to an int value within an object. The condition parameter gives a hint to the
      * compiler under which circumstances this access can be moved to an earlier location in the
      * program. The location identity gives a hint to the compiler for improved global value
      * numbering.
@@ -314,8 +314,8 @@
     }
 
     /**
-     * Unsafe access to a Object value within an object. The condition parameter gives a hint to the
-     * compiler under which circumstances this access can be moved to an earlier location in the
+     * Unsafe access to an Object value within an object. The condition parameter gives a hint to
+     * the compiler under which circumstances this access can be moved to an earlier location in the
      * program. The location identity gives a hint to the compiler for improved global value
      * numbering.
      * 
@@ -374,7 +374,7 @@
     }
 
     /**
-     * Write a int value within an object. The location identity gives a hint to the compiler for
+     * Write an int value within an object. The location identity gives a hint to the compiler for
      * improved global value numbering.
      * 
      * @param receiver the object that is written to
@@ -430,8 +430,8 @@
     }
 
     /**
-     * Write a Object value within an object. The location identity gives a hint to the compiler for
-     * improved global value numbering.
+     * Write an Object value within an object. The location identity gives a hint to the compiler
+     * for improved global value numbering.
      * 
      * @param receiver the object that is written to
      * @param offset the offset at which to write to the object in bytes
@@ -444,6 +444,150 @@
     }
 
     /**
+     * Unsafe access to a final boolean value within an object. The condition parameter gives a hint
+     * to the compiler under which circumstances this access can be moved to an earlier location in
+     * the program. The location identity gives a hint to the compiler for improved global value
+     * numbering.
+     * 
+     * @param receiver the object that is accessed
+     * @param offset the offset at which to access the object in bytes
+     * @param condition the condition that makes this access safe also at an earlier location in the
+     *            program
+     * @param locationIdentity the location identity token that can be used for improved global
+     *            value numbering or null
+     * @return the accessed value
+     */
+    public static boolean unsafeGetFinalBoolean(Object receiver, long offset, boolean condition, Object locationIdentity) {
+        return UNSAFE.getBoolean(receiver, offset);
+    }
+
+    /**
+     * Unsafe access to a final byte value within an object. The condition parameter gives a hint to
+     * the compiler under which circumstances this access can be moved to an earlier location in the
+     * program. The location identity gives a hint to the compiler for improved global value
+     * numbering.
+     * 
+     * @param receiver the object that is accessed
+     * @param offset the offset at which to access the object in bytes
+     * @param condition the condition that makes this access safe also at an earlier location in the
+     *            program
+     * @param locationIdentity the location identity token that can be used for improved global
+     *            value numbering or null
+     * @return the accessed value
+     */
+    public static byte unsafeGetFinalByte(Object receiver, long offset, boolean condition, Object locationIdentity) {
+        return UNSAFE.getByte(receiver, offset);
+    }
+
+    /**
+     * Unsafe access to a final short value within an object. The condition parameter gives a hint
+     * to the compiler under which circumstances this access can be moved to an earlier location in
+     * the program. The location identity gives a hint to the compiler for improved global value
+     * numbering.
+     * 
+     * @param receiver the object that is accessed
+     * @param offset the offset at which to access the object in bytes
+     * @param condition the condition that makes this access safe also at an earlier location in the
+     *            program
+     * @param locationIdentity the location identity token that can be used for improved global
+     *            value numbering or null
+     * @return the accessed value
+     */
+    public static short unsafeGetFinalShort(Object receiver, long offset, boolean condition, Object locationIdentity) {
+        return UNSAFE.getShort(receiver, offset);
+    }
+
+    /**
+     * Unsafe access to a final int value within an object. The condition parameter gives a hint to
+     * the compiler under which circumstances this access can be moved to an earlier location in the
+     * program. The location identity gives a hint to the compiler for improved global value
+     * numbering.
+     * 
+     * @param receiver the object that is accessed
+     * @param offset the offset at which to access the object in bytes
+     * @param condition the condition that makes this access safe also at an earlier location in the
+     *            program
+     * @param locationIdentity the location identity token that can be used for improved global
+     *            value numbering or null
+     * @return the accessed value
+     */
+    public static int unsafeGetFinalInt(Object receiver, long offset, boolean condition, Object locationIdentity) {
+        return UNSAFE.getInt(receiver, offset);
+    }
+
+    /**
+     * Unsafe access to a final long value within an object. The condition parameter gives a hint to
+     * the compiler under which circumstances this access can be moved to an earlier location in the
+     * program. The location identity gives a hint to the compiler for improved global value
+     * numbering.
+     * 
+     * @param receiver the object that is accessed
+     * @param offset the offset at which to access the object in bytes
+     * @param condition the condition that makes this access safe also at an earlier location in the
+     *            program
+     * @param locationIdentity the location identity token that can be used for improved global
+     *            value numbering or null
+     * @return the accessed value
+     */
+    public static long unsafeGetFinalLong(Object receiver, long offset, boolean condition, Object locationIdentity) {
+        return UNSAFE.getLong(receiver, offset);
+    }
+
+    /**
+     * Unsafe access to a final float value within an object. The condition parameter gives a hint
+     * to the compiler under which circumstances this access can be moved to an earlier location in
+     * the program. The location identity gives a hint to the compiler for improved global value
+     * numbering.
+     * 
+     * @param receiver the object that is accessed
+     * @param offset the offset at which to access the object in bytes
+     * @param condition the condition that makes this access safe also at an earlier location in the
+     *            program
+     * @param locationIdentity the location identity token that can be used for improved global
+     *            value numbering or null
+     * @return the accessed value
+     */
+    public static float unsafeGetFinalFloat(Object receiver, long offset, boolean condition, Object locationIdentity) {
+        return UNSAFE.getFloat(receiver, offset);
+    }
+
+    /**
+     * Unsafe access to a final double value within an object. The condition parameter gives a hint
+     * to the compiler under which circumstances this access can be moved to an earlier location in
+     * the program. The location identity gives a hint to the compiler for improved global value
+     * numbering.
+     * 
+     * @param receiver the object that is accessed
+     * @param offset the offset at which to access the object in bytes
+     * @param condition the condition that makes this access safe also at an earlier location in the
+     *            program
+     * @param locationIdentity the location identity token that can be used for improved global
+     *            value numbering or null
+     * @return the accessed value
+     */
+    public static double unsafeGetFinalDouble(Object receiver, long offset, boolean condition, Object locationIdentity) {
+        return UNSAFE.getDouble(receiver, offset);
+    }
+
+    /**
+     * Unsafe access to a final Object value within an object. The condition parameter gives a hint
+     * to the compiler under which circumstances this access can be moved to an earlier location in
+     * the program. The location identity gives a hint to the compiler for improved global value
+     * numbering.
+     * 
+     * @param receiver the object that is accessed
+     * @param offset the offset at which to access the object in bytes
+     * @param condition the condition that makes this access safe also at an earlier location in the
+     *            program
+     * @param locationIdentity the location identity token that can be used for improved global
+     *            value numbering or null
+     * @return the accessed value
+     */
+    public static Object unsafeGetFinalObject(Object receiver, long offset, boolean condition, Object locationIdentity) {
+        return UNSAFE.getObject(receiver, offset);
+    }
+
+    /**
      * Marks methods that are considered slowpath and should therefore not be inlined by default.
      */
     @Retention(RetentionPolicy.RUNTIME)
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/LoopCountReceiver.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/LoopCountReceiver.java	Wed Mar 05 19:40:15 2014 -0800
@@ -24,6 +24,10 @@
  */
 package com.oracle.truffle.api;
 
+/**
+ * Accepts the execution count of a loop that is a child of this node. The optimization heuristics
+ * can use the loop count to guide compilation and inlining.
+ */
 public interface LoopCountReceiver {
 
     void reportLoopCount(int count);
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/ReplaceObserver.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/ReplaceObserver.java	Wed Mar 05 19:40:15 2014 -0800
@@ -24,7 +24,12 @@
  */
 package com.oracle.truffle.api;
 
+import com.oracle.truffle.api.nodes.*;
+
+/**
+ * An observer that is notified whenever a child node is replaced.
+ */
 public interface ReplaceObserver {
 
-    void nodeReplaced();
+    void nodeReplaced(Node oldNode, Node newNode, String reason);
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/RootCallTarget.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,50 @@
+/*
+ * 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;
+
+import com.oracle.truffle.api.nodes.*;
+
+/**
+ * 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);
+    }
+
+    @Override
+    public String toString() {
+        return rootNode.toString();
+    }
+
+    public RootNode getRootNode() {
+        return rootNode;
+    }
+}
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/TruffleOptions.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/TruffleOptions.java	Wed Mar 05 19:40:15 2014 -0800
@@ -33,7 +33,7 @@
 public class TruffleOptions {
 
     /**
-     * Enables/disables the rewriting of traces in the truffle runtime to stdout.
+     * Enables/disables the rewriting of traces in the Truffle runtime to stdout.
      * <p>
      * Can be set with {@code -Dtruffle.TraceRewrites=true}.
      */
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/TruffleRuntime.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/TruffleRuntime.java	Wed Mar 05 19:40:15 2014 -0800
@@ -48,7 +48,9 @@
      *            represents the entry point
      * @return the new call target object
      */
-    CallTarget createCallTarget(RootNode rootNode);
+    RootCallTarget createCallTarget(RootNode rootNode);
+
+    CallNode createCallNode(CallTarget target);
 
     /**
      * Creates a new assumption object that can be checked and invalidated.
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameDescriptor.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameDescriptor.java	Wed Mar 05 19:40:15 2014 -0800
@@ -86,6 +86,14 @@
         return addFrameSlot(identifier, kind);
     }
 
+    public void removeFrameSlot(Object identifier) {
+        assert identifierToSlotMap.containsKey(identifier);
+        slots.remove(identifierToSlotMap.get(identifier));
+        identifierToSlotMap.remove(identifier);
+        updateVersion();
+        getNotInFrameAssumption(identifier);
+    }
+
     public int getSize() {
         return slots.size();
     }
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultAssumption.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultAssumption.java	Wed Mar 05 19:40:15 2014 -0800
@@ -24,11 +24,16 @@
  */
 package com.oracle.truffle.api.impl;
 
+import com.oracle.truffle.api.*;
 import com.oracle.truffle.api.nodes.*;
 
-public final class DefaultAssumption extends AbstractAssumption {
+/**
+ * This is an implementation-specific class. Do not use or instantiate it. Instead, use
+ * {@link TruffleRuntime#createAssumption()} to create an {@link Assumption}.
+ */
+final class DefaultAssumption extends AbstractAssumption {
 
-    public DefaultAssumption(String name) {
+    DefaultAssumption(String name) {
         super(name);
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultCallNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  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.*;
+
+public class DefaultCallNode extends CallNode {
+
+    public DefaultCallNode(CallTarget target) {
+        super(target);
+    }
+
+    @Override
+    public Object call(PackedFrame caller, Arguments arguments) {
+        return getCallTarget().call(caller, 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 String toString() {
+        return getParent() != null ? getParent().toString() : super.toString();
+    }
+}
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultCallTarget.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultCallTarget.java	Wed Mar 05 19:40:15 2014 -0800
@@ -28,27 +28,19 @@
 import com.oracle.truffle.api.frame.*;
 import com.oracle.truffle.api.nodes.*;
 
-public class DefaultCallTarget extends CallTarget {
-
-    protected final RootNode rootNode;
+/**
+ * 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 DefaultCallTarget(RootNode function) {
-        this.rootNode = function;
-        this.rootNode.setCallTarget(this);
-    }
-
-    @Override
-    public String toString() {
-        return rootNode.toString();
+    protected DefaultCallTarget(RootNode function) {
+        super(function);
     }
 
     @Override
     public Object call(PackedFrame caller, Arguments args) {
-        VirtualFrame frame = new DefaultVirtualFrame(rootNode.getFrameDescriptor(), caller, args);
-        return rootNode.execute(frame);
-    }
-
-    public RootNode getRootNode() {
-        return rootNode;
+        VirtualFrame frame = new DefaultVirtualFrame(getRootNode().getFrameDescriptor(), caller, args);
+        return getRootNode().execute(frame);
     }
 }
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultMaterializedFrame.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultMaterializedFrame.java	Wed Mar 05 19:40:15 2014 -0800
@@ -27,11 +27,16 @@
 import com.oracle.truffle.api.*;
 import com.oracle.truffle.api.frame.*;
 
+/**
+ * This is an implementation-specific class. Do not use or instantiate it. Instead, use
+ * {@link TruffleRuntime#createMaterializedFrame(Arguments)} or {@link Frame#materialize()} to
+ * create a {@link MaterializedFrame}.
+ */
 final class DefaultMaterializedFrame implements MaterializedFrame, PackedFrame {
 
     private final DefaultVirtualFrame wrapped;
 
-    protected DefaultMaterializedFrame(DefaultVirtualFrame wrapped) {
+    DefaultMaterializedFrame(DefaultVirtualFrame wrapped) {
         this.wrapped = wrapped;
     }
 
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultPackedFrame.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultPackedFrame.java	Wed Mar 05 19:40:15 2014 -0800
@@ -26,11 +26,15 @@
 
 import com.oracle.truffle.api.frame.*;
 
+/**
+ * This is an implementation-specific class. Do not use or instantiate it. Instead, use
+ * {@link Frame#pack()} to create a {@link PackedFrame}.
+ */
 final class DefaultPackedFrame implements PackedFrame {
 
     private final DefaultVirtualFrame wrapped;
 
-    protected DefaultPackedFrame(DefaultVirtualFrame wrapped) {
+    DefaultPackedFrame(DefaultVirtualFrame wrapped) {
         this.wrapped = wrapped;
     }
 
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultTruffleRuntime.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultTruffleRuntime.java	Wed Mar 05 19:40:15 2014 -0800
@@ -31,19 +31,32 @@
 /**
  * Default implementation of the Truffle runtime if the virtual machine does not provide a better
  * performing alternative.
+ * <p>
+ * This is an implementation-specific class. Do not use or instantiate it. Instead, use
+ * {@link Truffle#getRuntime()} to retrieve the current {@link TruffleRuntime}.
  */
 public final class DefaultTruffleRuntime implements TruffleRuntime {
 
+    public DefaultTruffleRuntime() {
+        if (Truffle.getRuntime() != null) {
+            throw new IllegalArgumentException("Cannot instantiate DefaultTruffleRuntime. Use Truffle.getRuntime() instead.");
+        }
+    }
+
     @Override
     public String getName() {
         return "Default Truffle Runtime";
     }
 
     @Override
-    public CallTarget createCallTarget(RootNode rootNode) {
+    public RootCallTarget createCallTarget(RootNode rootNode) {
         return new DefaultCallTarget(rootNode);
     }
 
+    public CallNode createCallNode(CallTarget target) {
+        return new DefaultCallNode(target);
+    }
+
     @Override
     public VirtualFrame createVirtualFrame(PackedFrame caller, Arguments arguments, FrameDescriptor frameDescriptor) {
         return new DefaultVirtualFrame(frameDescriptor, caller, arguments);
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultVirtualFrame.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultVirtualFrame.java	Wed Mar 05 19:40:15 2014 -0800
@@ -29,7 +29,12 @@
 import com.oracle.truffle.api.*;
 import com.oracle.truffle.api.frame.*;
 
-public final class DefaultVirtualFrame implements VirtualFrame {
+/**
+ * This is an implementation-specific class. Do not use or instantiate it. Instead, use
+ * {@link TruffleRuntime#createVirtualFrame(PackedFrame, Arguments, FrameDescriptor)} to create a
+ * {@link VirtualFrame}.
+ */
+final class DefaultVirtualFrame implements VirtualFrame {
 
     private final FrameDescriptor descriptor;
     private final PackedFrame caller;
@@ -37,7 +42,7 @@
     private Object[] locals;
     private byte[] tags;
 
-    public DefaultVirtualFrame(FrameDescriptor descriptor, PackedFrame caller, Arguments arguments) {
+    DefaultVirtualFrame(FrameDescriptor descriptor, PackedFrame caller, Arguments arguments) {
         this.descriptor = descriptor;
         this.caller = caller;
         this.arguments = arguments;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/CallNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,171 @@
+/*
+ * 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.*;
+
+/**
+ * This node represents a call to a static {@link CallTarget}. This node should be used whenever a
+ * {@link CallTarget} is considered constant at a certain location in the tree. This enables the
+ * Truffle runtime to perform inlining or other optimizations for this call-site. This class is
+ * intended to be implemented by truffle runtime implementors and not by guest language
+ * implementors.
+ * 
+ * @see #create(CallTarget) to create a CallNode instance.
+ */
+public abstract class CallNode extends Node {
+
+    protected final CallTarget callTarget;
+
+    protected CallNode(CallTarget callTarget) {
+        this.callTarget = callTarget;
+    }
+
+    /**
+     * Calls this constant target passing a caller frame and arguments.
+     * 
+     * @param caller the caller frame
+     * @param arguments the arguments that should be passed to the callee
+     * @return the return result of the call
+     */
+    public abstract Object call(PackedFrame caller, Arguments 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;
+    }
+
+    /**
+     * @return true if this {@link CallNode} was already inlined.
+     */
+    public abstract boolean isInlined();
+
+    public abstract void inline();
+
+    public abstract boolean isSplittable();
+
+    public abstract boolean split();
+
+    public final boolean isSplit() {
+        return getSplitCallTarget() != null;
+    }
+
+    public abstract CallTarget getSplitCallTarget();
+
+    /**
+     * Returns the used call target when {@link #call(PackedFrame, Arguments)} is invoked. If the
+     * {@link CallNode} was split this method returns the {@link CallTarget} returned by
+     * {@link #getSplitCallTarget()}. If not split this method returns the original supplied
+     * {@link CallTarget}.
+     * 
+     * @return the used {@link CallTarget} when node is called
+     */
+    public CallTarget getCurrentCallTarget() {
+        CallTarget split = getSplitCallTarget();
+        if (split != null) {
+            return split;
+        } else {
+            return getCallTarget();
+        }
+    }
+
+    @Override
+    protected void onReplace(Node newNode, String reason) {
+        super.onReplace(newNode, reason);
+
+        /*
+         * Old call nodes are removed in the old target root node.
+         */
+        CallNode oldCall = this;
+        RootNode oldRoot = getCurrentRootNode();
+        if (oldRoot != null) {
+            oldRoot.removeCachedCallNode(oldCall);
+        }
+
+        registerCallTarget((CallNode) newNode);
+    }
+
+    protected static final void registerCallTarget(CallNode newNode) {
+        RootNode newRoot = newNode.getCurrentRootNode();
+        if (newRoot != null) {
+            newRoot.addCachedCallNode(newNode);
+        }
+    }
+
+    protected void notifyCallNodeAdded() {
+
+    }
+
+    /**
+     * Returns the {@link RootNode} associated with {@link CallTarget} returned by
+     * {@link #getCurrentCallTarget()}.
+     * 
+     * @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;
+    }
+
+    /**
+     * @deprecated always returns <code>true</code> now.
+     */
+    @Deprecated
+    public boolean isInlinable() {
+        return true;
+    }
+
+    /**
+     * @deprecated instead use {@link #getCurrentRootNode()} and check for {@link #isInlined()} for
+     *             true.
+     */
+    @Deprecated
+    public RootNode getInlinedRoot() {
+        if (!isInlined()) {
+            return null;
+        }
+        return getCurrentRootNode();
+    }
+
+    /**
+     * @deprecated use {@link TruffleRuntime#createCallNode(CallTarget)} instead
+     */
+    @Deprecated
+    public static CallNode create(CallTarget target) {
+        return Truffle.getRuntime().createCallNode(target);
+    }
+
+}
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/ControlFlowException.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/ControlFlowException.java	Wed Mar 05 19:40:15 2014 -0800
@@ -36,6 +36,12 @@
      * Creates an exception thrown to model control flow.
      */
     public ControlFlowException() {
+        /*
+         * We use the super constructor that initializes the cause to null. Without that, the cause
+         * would be this exception itself. This helps escape analysis: it avoids the circle of an
+         * object pointing to itself.
+         */
+        super((Throwable) null);
     }
 
     /**
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/FrameFactory.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +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.nodes;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-
-/**
- * Factory for virtual frame creation.
- */
-public interface FrameFactory {
-
-    /**
-     * Creates a new virtual frame from the given frame descriptor and arguments.
-     * 
-     * @param descriptor describes the frame to be created
-     * @param caller the packed caller frame or {@code null}
-     * @param args {@link Arguments} object to be stored in the frame
-     * @return a new virtual frame
-     */
-    VirtualFrame create(FrameDescriptor descriptor, PackedFrame caller, Arguments args);
-}
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/GraphPrintVisitor.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/GraphPrintVisitor.java	Wed Mar 05 19:40:15 2014 -0800
@@ -169,7 +169,7 @@
         }
     }
 
-    public void printToNetwork() {
+    public void printToNetwork(boolean ignoreErrors) {
         try {
             Transformer tr = TransformerFactory.newInstance().newTransformer();
             tr.setOutputProperty(OutputKeys.METHOD, "xml");
@@ -178,7 +178,9 @@
             BufferedOutputStream stream = new BufferedOutputStream(socket.getOutputStream(), 0x4000);
             tr.transform(new DOMSource(dom), new StreamResult(stream));
         } catch (TransformerException | IOException e) {
-            e.printStackTrace();
+            if (!ignoreErrors) {
+                e.printStackTrace();
+            }
         }
     }
 
@@ -341,6 +343,13 @@
         LinkedHashMap<String, Node> nodes = new LinkedHashMap<>();
         NodeClass nodeClass = NodeClass.get(node.getClass());
 
+        if (node instanceof CallNode) {
+            CallNode callNode = ((CallNode) node);
+            RootNode inlinedRoot = callNode.getCurrentRootNode();
+            if (inlinedRoot != null && callNode.isInlined()) {
+                nodes.put("inlinedRoot", inlinedRoot);
+            }
+        }
         for (NodeField field : nodeClass.getFields()) {
             NodeFieldKind kind = field.getKind();
             if (kind == NodeFieldKind.CHILD || kind == NodeFieldKind.CHILDREN) {
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/InlinableCallSite.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,69 +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.nodes;
-
-import com.oracle.truffle.api.*;
-
-/**
- * Denotes a call node that can inline the tree of its associated call target.
- * 
- * @see InlinedCallSite
- */
-public interface InlinableCallSite {
-
-    /**
-     * Returns the number of calls since the last reset of the call count.
-     * 
-     * @return the current call count.
-     */
-    int getCallCount();
-
-    /**
-     * Resets the call count to 0.
-     */
-    void resetCallCount();
-
-    /**
-     * Returns the tree that would be inlined by a call to {@link #inline(FrameFactory)}.
-     * 
-     * @return the node tree to be inlined.
-     */
-    Node getInlineTree();
-
-    /**
-     * Returns the call target associated with this call site.
-     * 
-     * @return the inlinable {@link CallTarget}.
-     */
-    CallTarget getCallTarget();
-
-    /**
-     * Instructs the call node to inline the associated call target.
-     * 
-     * @param factory Frame factory for creating new virtual frames for inlined calls.
-     * @return {@code true} if call target was inlined; {@code false} otherwise.
-     */
-    boolean inline(FrameFactory factory);
-}
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/InlinedCallSite.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,42 +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.nodes;
-
-import com.oracle.truffle.api.*;
-
-/**
- * Denotes a call node with an inlined call target. Allows for recursive call detection.
- * 
- * @see InlinableCallSite
- */
-public interface InlinedCallSite {
-
-    /**
-     * Returns the call target that has been inlined at this call site.
-     * 
-     * @return the inlined call target.
-     */
-    CallTarget getCallTarget();
-}
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/Node.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/Node.java	Wed Mar 05 19:40:15 2014 -0800
@@ -82,6 +82,14 @@
         this.sourceSection = section;
     }
 
+    public Kind getKind() {
+        NodeInfo info = getClass().getAnnotation(NodeInfo.class);
+        if (info != null) {
+            return info.kind();
+        }
+        return Kind.SPECIALIZED;
+    }
+
     /**
      * Clears any previously assigned guest language source code from this node.
      */
@@ -172,7 +180,7 @@
      * @return the new node
      */
     public final <T extends Node> T replace(T newNode, String reason) {
-        CompilerDirectives.transferToInterpreter();
+        CompilerDirectives.transferToInterpreterAndInvalidate();
         if (this.getParent() == null) {
             throw new IllegalStateException("This node cannot be replaced, because it does not yet have a parent.");
         }
@@ -185,7 +193,7 @@
         if (!NodeUtil.replaceChild(this.parent, this, newNode)) {
             fixupTree();
         }
-        reportReplace();
+        reportReplace(this, newNode, reason);
         return newNode;
     }
 
@@ -245,11 +253,12 @@
         return false;
     }
 
-    private void reportReplace() {
+    private void reportReplace(Node oldNode, Node newNode, String reason) {
         RootNode rootNode = getRootNode();
         if (rootNode != null) {
-            if (rootNode.getCallTarget() instanceof ReplaceObserver) {
-                ((ReplaceObserver) rootNode.getCallTarget()).nodeReplaced();
+            CallTarget target = rootNode.getCallTarget();
+            if (target instanceof ReplaceObserver) {
+                ((ReplaceObserver) target).nodeReplaced(oldNode, newNode, reason);
             }
         }
     }
@@ -395,7 +404,7 @@
      * 
      * @return the {@link RootNode} or {@code null} if there is none.
      */
-    protected final RootNode getRootNode() {
+    public final RootNode getRootNode() {
         Node rootNode = this;
         while (rootNode.getParent() != null) {
             assert !(rootNode instanceof RootNode) : "root node must not have a parent";
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java	Wed Mar 05 19:40:15 2014 -0800
@@ -34,6 +34,7 @@
 import com.oracle.truffle.api.*;
 import com.oracle.truffle.api.nodes.Node.Child;
 import com.oracle.truffle.api.nodes.Node.Children;
+import com.oracle.truffle.api.nodes.NodeInfo.Kind;
 
 /**
  * Utility class that manages the special access methods for node instances.
@@ -451,6 +452,48 @@
         return null;
     }
 
+    /**
+     * @deprecated will be removed, exposed Truffle runtime specific functionality.
+     */
+    @Deprecated
+    public static List<CallTarget> findOutermostCallTargets(Node node) {
+        RootNode root = node.getRootNode();
+        if (root == null) {
+            return Collections.emptyList();
+        }
+        List<CallTarget> roots = new ArrayList<>();
+        roots.add(root.getCallTarget());
+        for (CallNode callNode : root.getCachedCallNodes()) {
+            if (callNode.isInlined()) {
+                roots.addAll(findOutermostCallTargets(callNode));
+            }
+        }
+        return roots;
+    }
+
+    /**
+     * @deprecated will be removed, exposed Truffle runtime specific functionality.
+     */
+    @Deprecated
+    public static RootNode findOutermostRootNode(Node node) {
+        Node parent = node;
+        while (parent != null) {
+            if (parent instanceof RootNode) {
+                RootNode root = (RootNode) parent;
+                @SuppressWarnings("deprecation")
+                Node next = root.getParentInlinedCall();
+                if (next != null) {
+                    parent = next;
+                } else {
+                    return root;
+                }
+            } else {
+                parent = parent.getParent();
+            }
+        }
+        return null;
+    }
+
     public static <T> T findParent(Node start, Class<T> clazz) {
         Node parent = start.getParent();
         if (parent == null) {
@@ -571,36 +614,87 @@
     }
 
     public static int countNodes(Node root) {
-        return countNodes(root, null);
+        return countNodes(root, null, null, false);
     }
 
-    public static int countNodes(Node root, Class<?> clazz) {
-        NodeCountVisitor nodeCount = new NodeCountVisitor(root, clazz);
+    public static int countNodes(Node root, Class<?> clazz, Kind nodeKind, boolean countInlinedCallNodes) {
+        NodeCountVisitor nodeCount = new NodeCountVisitor(clazz, nodeKind, countInlinedCallNodes);
         root.accept(nodeCount);
         return nodeCount.nodeCount;
     }
 
+    public static int countNodes(Node root, Class<?> clazz, boolean countInlinedCallNodes) {
+        return countNodes(root, clazz, null, countInlinedCallNodes);
+    }
+
     private static final class NodeCountVisitor implements NodeVisitor {
 
+        private final boolean inspectInlinedCalls;
         int nodeCount;
-        private final Node root;
+        private final Kind kind;
         private final Class<?> clazz;
 
-        private NodeCountVisitor(Node root, Class<?> clazz) {
-            this.root = root;
+        private NodeCountVisitor(Class<?> clazz, Kind kind, boolean inspectInlinedCalls) {
             this.clazz = clazz;
+            this.kind = kind;
+            this.inspectInlinedCalls = inspectInlinedCalls;
         }
 
         @Override
         public boolean visit(Node node) {
-            if (node instanceof RootNode && node != root) {
-                return false;
-            }
-            if (clazz == null || clazz.isInstance(node)) {
+            if ((clazz == null || clazz.isInstance(node)) && (kind == null || isKind(node))) {
                 nodeCount++;
             }
+
+            if (inspectInlinedCalls && node instanceof CallNode) {
+                CallNode call = (CallNode) node;
+                if (call.isInlined()) {
+                    Node target = ((RootCallTarget) call.getCurrentCallTarget()).getRootNode();
+                    if (target != null) {
+                        target.accept(this);
+                    }
+                }
+            }
+
             return true;
         }
+
+        private boolean isKind(Node n) {
+            return kind == n.getKind();
+        }
+    }
+
+    public static void printInliningTree(final PrintStream stream, RootNode root) {
+        printRootNode(stream, 0, root);
+        root.accept(new NodeVisitor() {
+            int depth = 1;
+
+            public boolean visit(Node node) {
+                if (node instanceof CallNode) {
+                    CallNode callNode = ((CallNode) node);
+                    RootNode inlinedRoot = callNode.getCurrentRootNode();
+                    if (inlinedRoot != null && callNode.isInlined()) {
+                        depth++;
+                        printRootNode(stream, depth * 2, inlinedRoot);
+                        inlinedRoot.accept(this);
+                        depth--;
+                    }
+                }
+                return true;
+            }
+        });
+    }
+
+    private static void printRootNode(PrintStream stream, int indent, RootNode root) {
+        for (int i = 0; i < indent; i++) {
+            stream.print(" ");
+        }
+        stream.print(root.toString());
+        stream.print(" (");
+        stream.print(countNodes(root));
+        stream.print("/");
+        stream.print(countNodes(root, null, true));
+        stream.println(")");
     }
 
     public static String printCompactTreeToString(Node node) {
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/RootNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/RootNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -24,6 +24,8 @@
  */
 package com.oracle.truffle.api.nodes;
 
+import java.util.*;
+
 import com.oracle.truffle.api.*;
 import com.oracle.truffle.api.frame.*;
 
@@ -37,6 +39,11 @@
     private CallTarget callTarget;
     private final FrameDescriptor frameDescriptor;
 
+    /*
+     * Internal set to keep back-references to the call-sites.
+     */
+    private final Set<CallNode> cachedCallNodes = Collections.newSetFromMap(new WeakHashMap<CallNode, Boolean>());
+
     protected RootNode() {
         this(null, null);
     }
@@ -55,6 +62,51 @@
     }
 
     /**
+     * @deprecated Not required anymore. Do not use.
+     */
+    @Deprecated
+    public RootNode inline() {
+        if (!isInlinable()) {
+            throw new UnsupportedOperationException("Inlining is not enabled.");
+        }
+        return split();
+    }
+
+    /**
+     * @deprecated Not required anymore. Do not use.
+     */
+    @Deprecated
+    public int getInlineNodeCount() {
+        return 0;
+    }
+
+    /**
+     * @deprecated Not required anymore. Do not use.
+     */
+    @Deprecated
+    public boolean isInlinable() {
+        return true;
+    }
+
+    public RootNode split() {
+        return NodeUtil.cloneNode(this);
+    }
+
+    public boolean isSplittable() {
+        return false;
+    }
+
+    /**
+     * Reports the execution count of a loop that is a child of this node. The optimization
+     * heuristics can use the loop count to guide compilation and inlining.
+     */
+    public void reportLoopCount(int count) {
+        if (getCallTarget() instanceof LoopCountReceiver) {
+            ((LoopCountReceiver) getCallTarget()).reportLoopCount(count);
+        }
+    }
+
+    /**
      * Executes this function using the specified frame and returns the result value.
      * 
      * @param frame the frame of the currently executing guest language method
@@ -66,11 +118,47 @@
         return callTarget;
     }
 
-    public FrameDescriptor getFrameDescriptor() {
+    public final FrameDescriptor getFrameDescriptor() {
         return frameDescriptor;
     }
 
-    public void setCallTarget(CallTarget callTarget) {
+    public final void setCallTarget(CallTarget callTarget) {
         this.callTarget = callTarget;
     }
+
+    /* Internal API. Do not use. */
+    void addCachedCallNode(CallNode callSite) {
+        if (cachedCallNodes.add(callSite)) {
+            for (CallNode callNode : cachedCallNodes) {
+                if (callSite != callNode) {
+                    callNode.notifyCallNodeAdded();
+                }
+            }
+        }
+    }
+
+    /* Internal API. Do not use. */
+    void removeCachedCallNode(CallNode callSite) {
+        this.cachedCallNodes.remove(callSite);
+    }
+
+    /**
+     * Returns a {@link Set} of {@link CallNode} nodes which are created to invoke this RootNode.
+     * This method does not make any guarantees to contain all the {@link CallNode} nodes that are
+     * invoking this method. Due to its weak nature the elements returned by this method may change
+     * with each consecutive call.
+     * 
+     * @return a set of {@link CallNode} nodes
+     */
+    public final Set<CallNode> getCachedCallNodes() {
+        return Collections.unmodifiableSet(cachedCallNodes);
+    }
+
+    /**
+     * @deprecated use {@link #getCachedCallNodes()} instead.
+     */
+    @Deprecated
+    public final CallNode getParentInlinedCall() {
+        return cachedCallNodes.isEmpty() ? null : cachedCallNodes.iterator().next();
+    }
 }
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/instrument/InstrumentationProbeNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/instrument/InstrumentationProbeNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -211,27 +211,35 @@
         }
 
         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) {
--- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/TruffleTypes.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/TruffleTypes.java	Wed Mar 05 19:40:15 2014 -0800
@@ -43,8 +43,8 @@
 
     public static final String OPTION_DETAILED_REWRITE_REASONS = "DetailedRewriteReasons";
 
-    private final TypeMirror node;
-    private final TypeMirror nodeArray;
+    private final DeclaredType node;
+    private final ArrayType nodeArray;
     private final TypeMirror unexpectedValueException;
     private final TypeMirror frame;
     private final TypeMirror assumption;
@@ -131,11 +131,11 @@
         return compilerDirectives;
     }
 
-    public TypeMirror getNode() {
+    public DeclaredType getNode() {
         return node;
     }
 
-    public TypeMirror getNodeArray() {
+    public ArrayType getNodeArray() {
         return nodeArray;
     }
 
--- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/api/ExtensionProcessor.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,31 +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.truffle.dsl.processor.api;
-
-import javax.lang.model.element.*;
-
-public interface ExtensionProcessor {
-
-    void process(ExtensionContext context, AnnotationMirror mirror, Element element);
-
-}
--- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/ast/CodeTreeVariable.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,60 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.dsl.processor.ast;
-
-public class CodeTreeVariable extends CodeTree {
-
-    private final String name;
-
-    private CodeTree value;
-
-    public CodeTreeVariable() {
-        super(CodeTreeKind.GROUP, null, null);
-        this.name = "";
-    }
-
-    public CodeTreeVariable(String name) {
-        super(CodeTreeKind.GROUP, null, null);
-        this.name = name;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public void set(CodeTree tree) {
-        if (value == tree) {
-            return;
-        }
-        if (this.value != null) {
-            remove(this.value);
-        }
-        this.value = tree;
-        add(tree);
-    }
-
-    public CodeTree get() {
-        return value;
-    }
-
-}
--- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeCodeGenerator.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeCodeGenerator.java	Wed Mar 05 19:40:15 2014 -0800
@@ -99,6 +99,22 @@
         return param.getLocalName();
     }
 
+    private static CodeTree createAccessChild(NodeExecutionData targetExecution) {
+        CodeTreeBuilder builder = CodeTreeBuilder.createBuilder();
+        Element accessElement = targetExecution.getChild().getAccessElement();
+        if (accessElement == null || accessElement.getKind() == ElementKind.METHOD) {
+            builder.string("this.").string(targetExecution.getChild().getName());
+        } else if (accessElement.getKind() == ElementKind.FIELD) {
+            builder.string("this.").string(accessElement.getSimpleName().toString());
+        } else {
+            throw new AssertionError();
+        }
+        if (targetExecution.isIndexed()) {
+            builder.string("[" + targetExecution.getIndex() + "]");
+        }
+        return builder.getRoot();
+    }
+
     private static String castValueName(ActualParameter parameter) {
         return valueName(parameter) + "Cast";
     }
@@ -155,18 +171,14 @@
     }
 
     private String valueName(ActualParameter sourceParameter, ActualParameter targetParameter) {
-        if (sourceParameter != null) {
-            if (!sourceParameter.getSpecification().isSignature()) {
-                return valueName(targetParameter);
-            } else if (sourceParameter.getTypeSystemType() != null && targetParameter.getTypeSystemType() != null) {
-                if (sourceParameter.getTypeSystemType().needsCastTo(getContext(), targetParameter.getTypeSystemType())) {
-                    return castValueName(targetParameter);
-                }
+        if (!sourceParameter.getSpecification().isSignature()) {
+            return valueName(targetParameter);
+        } else if (sourceParameter.getTypeSystemType() != null && targetParameter.getTypeSystemType() != null) {
+            if (sourceParameter.getTypeSystemType().needsCastTo(getContext(), targetParameter.getTypeSystemType())) {
+                return castValueName(targetParameter);
             }
-            return valueName(targetParameter);
-        } else {
-            return valueName(targetParameter);
         }
+        return valueName(targetParameter);
     }
 
     private CodeTree createTemplateMethodCall(CodeTreeBuilder parent, CodeTree target, TemplateMethod sourceMethod, TemplateMethod targetMethod, String unexpectedValueName,
@@ -331,11 +343,36 @@
     }
 
     protected void emitEncounteredSynthetic(CodeTreeBuilder builder, TemplateMethod current) {
-        builder.startThrow().startNew(getContext().getType(UnsupportedOperationException.class));
-        builder.startCall("createInfo0");
-        builder.doubleQuote("Unsupported values");
-        addInternalValueParameterNames(builder, current, current, null, false, null);
-        builder.end().end().end();
+        CodeTreeBuilder nodes = builder.create();
+        CodeTreeBuilder arguments = builder.create();
+        nodes.startCommaGroup();
+        arguments.startCommaGroup();
+        boolean empty = true;
+        for (ActualParameter parameter : current.getParameters()) {
+            NodeExecutionData executionData = parameter.getSpecification().getExecution();
+            if (executionData != null) {
+                if (executionData.isShortCircuit()) {
+                    nodes.nullLiteral();
+                    arguments.string(valueName(parameter.getPreviousParameter()));
+                }
+                nodes.tree(createAccessChild(executionData));
+                arguments.string(valueName(parameter));
+                empty = false;
+            }
+        }
+        nodes.end();
+        arguments.end();
+
+        builder.startThrow().startNew(getContext().getType(UnsupportedSpecializationException.class));
+        builder.string("this");
+        builder.startNewArray(getContext().getTruffleTypes().getNodeArray(), null);
+
+        builder.tree(nodes.getRoot());
+        builder.end();
+        if (!empty) {
+            builder.tree(arguments.getRoot());
+        }
+        builder.end().end();
     }
 
     private static List<ExecutableElement> findUserConstructors(TypeMirror nodeType) {
@@ -502,7 +539,6 @@
                 TypeMirror nodeFactory = Utils.getDeclaredType(Utils.fromTypeMirror(getContext().getType(NodeFactory.class)), node.getNodeType());
                 clazz.getImplements().add(nodeFactory);
                 clazz.add(createCreateNodeMethod(node));
-                clazz.add(createCreateNodeGenericMethod(node));
                 clazz.add(createGetNodeClassMethod(node));
                 clazz.add(createGetNodeSignaturesMethod());
                 clazz.add(createGetChildrenSignatureMethod(node));
@@ -672,22 +708,6 @@
             return method;
         }
 
-        private CodeExecutableElement createCreateNodeGenericMethod(NodeData node) {
-            CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), node.getNodeType(), "createNodeGeneric");
-            CodeVariableElement nodeParam = new CodeVariableElement(node.getNodeType(), THIS_NODE_LOCAL_VAR_NAME);
-            method.addParameter(nodeParam);
-
-            CodeTreeBuilder builder = method.createBuilder();
-            if (!node.needsRewrites(getContext())) {
-                builder.startThrow().startNew(getContext().getType(UnsupportedOperationException.class)).doubleQuote("No specialized version.").end().end();
-            } else {
-                builder.startReturn().startCall("createGeneric");
-                builder.string(THIS_NODE_LOCAL_VAR_NAME);
-                builder.end().end();
-            }
-            return method;
-        }
-
         private ExecutableElement createGetInstanceMethod(NodeData node, Modifier visibility) {
             TypeElement nodeFactoryType = Utils.fromTypeMirror(getContext().getType(NodeFactory.class));
             TypeMirror returnType = Utils.getDeclaredType(nodeFactoryType, node.getNodeType());
@@ -933,12 +953,32 @@
             if (node.getGenericSpecialization() != null && node.getGenericSpecialization().isReachable()) {
                 clazz.add(createGenericExecute(node, rootGroup));
             }
+
+            clazz.add(createGetKind(node, null, Kind.SPECIALIZED));
         }
 
         protected boolean needsInvokeCopyConstructorMethod() {
             return getModel().getNode().isPolymorphic();
         }
 
+        protected CodeExecutableElement createGetKind(NodeData node, SpecializationData specialization, Kind kind) {
+            CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), context.getTruffleTypes().getNodeInfoKind(), "getKind");
+
+            TypeMirror nodeInfoKind = context.getTruffleTypes().getNodeInfoKind();
+
+            CodeTreeBuilder builder = method.createBuilder();
+            if (node.isPolymorphic() && specialization == null) {
+                // assume next0 exists
+                builder.startIf().string("next0 != null && next0.getKind() == ").staticReference(nodeInfoKind, "SPECIALIZED").end();
+                builder.startBlock();
+                builder.startReturn().staticReference(nodeInfoKind, "POLYMORPHIC").end();
+                builder.end();
+            }
+
+            builder.startReturn().staticReference(nodeInfoKind, kind.name()).end();
+            return method;
+        }
+
         protected CodeExecutableElement createInvokeCopyConstructor(TypeMirror baseType, SpecializationData specialization) {
             CodeExecutableElement method = new CodeExecutableElement(modifiers(PROTECTED), baseType, "invokeCopyConstructor");
             if (specialization == null) {
@@ -966,16 +1006,12 @@
             for (ActualParameter param : getModel().getSignatureParameters()) {
                 NodeExecutionData execution = param.getSpecification().getExecution();
 
-                CodeTreeBuilder access = builder.create();
-                access.string("this.").string(execution.getChild().getName());
-                if (execution.isIndexed()) {
-                    access.string("[").string(String.valueOf(execution.getIndex())).string("]");
-                }
+                CodeTree access = createAccessChild(execution);
 
                 String oldName = "old" + Utils.firstLetterUpperCase(param.getLocalName());
                 oldBuilder.declaration(execution.getChild().getNodeData().getNodeType(), oldName, access);
-                nullBuilder.startStatement().tree(access.getRoot()).string(" = null").end();
-                resetBuilder.startStatement().tree(access.getRoot()).string(" = ").string(oldName).end();
+                nullBuilder.startStatement().tree(access).string(" = null").end();
+                resetBuilder.startStatement().tree(access).string(" = ").string(oldName).end();
             }
 
             builder.tree(oldBuilder.getRoot());
@@ -2275,7 +2311,7 @@
         private CodeTree createExecuteChildExpression(CodeTreeBuilder parent, NodeExecutionData targetExecution, ExecutableTypeData targetExecutable, ActualParameter unexpectedParameter) {
             CodeTreeBuilder builder = new CodeTreeBuilder(parent);
             if (targetExecution != null) {
-                builder.tree(createAccessChild(builder, targetExecution));
+                builder.tree(createAccessChild(targetExecution));
                 builder.string(".");
             }
 
@@ -2329,22 +2365,6 @@
             return builder.getRoot();
         }
 
-        private CodeTree createAccessChild(CodeTreeBuilder parent, NodeExecutionData targetExecution) throws AssertionError {
-            CodeTreeBuilder builder = parent.create();
-            Element accessElement = targetExecution.getChild().getAccessElement();
-            if (accessElement == null || accessElement.getKind() == ElementKind.METHOD) {
-                builder.string("this.").string(targetExecution.getChild().getName());
-            } else if (accessElement.getKind() == ElementKind.FIELD) {
-                builder.string("this.").string(accessElement.getSimpleName().toString());
-            } else {
-                throw new AssertionError();
-            }
-            if (targetExecution.isIndexed()) {
-                builder.string("[" + targetExecution.getIndex() + "]");
-            }
-            return builder.getRoot();
-        }
-
         private CodeTree createShortCircuitTree(CodeTreeBuilder parent, CodeTree body, SpecializationData specialization, ActualParameter parameter, ActualParameter exceptionParam) {
             NodeExecutionData execution = parameter.getSpecification().getExecution();
             if (execution == null || !execution.isShortCircuit()) {
@@ -2503,7 +2523,7 @@
             }
 
             createCachedExecuteMethods(specialization);
-
+            clazz.add(createGetKind(specialization.getNode(), specialization, Kind.SPECIALIZED));
         }
 
         private ExecutableElement createUpdateType(ActualParameter parameter) {
@@ -2587,6 +2607,12 @@
             if (needsInvokeCopyConstructorMethod()) {
                 clazz.add(createInvokeCopyConstructor(nodeGen.asType(), specialization));
             }
+
+            if (specialization.isGeneric()) {
+                clazz.add(createGetKind(specialization.getNode(), specialization, Kind.GENERIC));
+            } else if (specialization.isUninitialized()) {
+                clazz.add(createGetKind(specialization.getNode(), specialization, Kind.UNINITIALIZED));
+            }
         }
 
         protected void createConstructors(CodeTypeElement clazz) {
--- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/SpecializationListenerData.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +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.truffle.dsl.processor.node;
-
-import com.oracle.truffle.dsl.processor.template.*;
-
-public class SpecializationListenerData extends TemplateMethod {
-
-    public SpecializationListenerData(TemplateMethod method) {
-        super(method);
-    }
-
-}
--- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/JavaName.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,50 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.dsl.processor.template;
-
-import java.util.*;
-import java.util.regex.*;
-
-public final class JavaName {
-
-    private static final String[] RESERVED_NAMES = new String[]{"abstract", "continue", "for", "new", "switch", "assert", "default", "goto", "package", "synchronized", "boolean", "do", "if",
-                    "private", "this", "break", "double", "implements", "protected", "throw", "byte", "else", "import", "public", "throws", "case", "enum", "instanceof", "return", "transient",
-                    "catch", "extends", "int", "short", "try", "char", "final", "interface", "static", "void", "class", "finally", "long", "strictfp", "volatile", "const", "float", "native", "super",
-                    "while"};
-
-    private static final Set<String> RESERVED_NAMES_SET = Collections.unmodifiableSet(new HashSet<>(Arrays.asList(RESERVED_NAMES)));
-
-    private static final Pattern VALID_JAVA_NAME_PATTERN = Pattern.compile("[_a-zA-z][_a-zA-Z0-9]*");
-
-    private JavaName() {
-        super();
-    }
-
-    public static boolean isReserved(String name) {
-        return RESERVED_NAMES_SET.contains(name);
-    }
-
-    public static boolean isValid(String typeName) {
-        return VALID_JAVA_NAME_PATTERN.matcher(typeName).matches();
-    }
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/CoreSource.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,72 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes;
-
-import java.io.*;
-
-import com.oracle.truffle.api.*;
-
-/**
- * Singleton source used for core method nodes.
- */
-public final class CoreSource implements Source {
-
-    private final String name;
-
-    public CoreSource(String name) {
-        this.name = name;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public String getCode() {
-        return name;
-    }
-
-    @Override
-    public String toString() {
-        return name;
-    }
-
-    public String getPath() {
-        return null;
-    }
-
-    public Reader getReader() {
-        return null;
-    }
-
-    public InputStream getInputStream() {
-        return null;
-    }
-
-    public String getCode(int lineNumber) {
-        return null;
-    }
-
-    public int getLineCount() {
-        return 0;
-    }
-
-    public int getLineNumber(int offset) {
-        return 0;
-    }
-
-    public int getLineStartOffset(int lineNumber) {
-        return 0;
-    }
-
-    public int getLineLength(int lineNumber) {
-        return 0;
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/CoreSourceSection.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,63 +0,0 @@
-/*
- * Copyright (c) 2013, 2014 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes;
-
-import com.oracle.truffle.api.*;
-
-/**
- * Source sections used for core method nodes.
- */
-public final class CoreSourceSection implements NullSourceSection {
-
-    private final String name;
-
-    public CoreSourceSection(String name) {
-        this.name = name;
-    }
-
-    public Source getSource() {
-        return new CoreSource(name);
-    }
-
-    public int getStartLine() {
-        return 0;
-    }
-
-    public int getStartColumn() {
-        return 0;
-    }
-
-    public int getCharIndex() {
-        return 0;
-    }
-
-    @Override
-    public int getCharLength() {
-        return 0;
-    }
-
-    public int getCharEndIndex() {
-        return 0;
-    }
-
-    public String getIdentifier() {
-        return null;
-    }
-
-    public String getCode() {
-        return name;
-    }
-
-    @Override
-    public String toString() {
-        return name;
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/DefinedNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /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. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-
-/**
- * Switches execution to the parallel {@link RubyNode#isDefined} semantic path. Represents the
- * {@code defined?} keyword in Ruby.
- */
-@NodeInfo(shortName = "defined")
-public class DefinedNode extends RubyNode {
-
-    @Child protected RubyNode child;
-
-    public DefinedNode(RubyContext context, SourceSection sourceSection, RubyNode child) {
-        super(context, sourceSection);
-        this.child = adoptChild(child);
-    }
-
-    @Override
-    public Object execute(VirtualFrame frame) {
-        return child.isDefined(frame);
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/InlinableMethodImplementation.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,67 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.nodes.call.*;
-import com.oracle.truffle.ruby.runtime.methods.*;
-
-/**
- * A method implementation that also carries the pristine root node and frame descriptor, from which
- * we can inline.
- * 
- * @see InlinedUnboxedDispatchNode
- * @see InlinedBoxedDispatchNode
- * @see InlineHeuristic
- */
-public class InlinableMethodImplementation extends CallTargetMethodImplementation {
-
-    private final FrameDescriptor frameDescriptor;
-    private final RubyRootNode pristineRootNode;
-
-    public final boolean alwaysInline;
-    public final boolean shouldAppendCallNode;
-
-    public InlinableMethodImplementation(CallTarget callTarget, MaterializedFrame declarationFrame, FrameDescriptor frameDescriptor, RubyRootNode pristineRootNode, boolean alwaysInline,
-                    boolean shouldAppendCallNode) {
-        super(callTarget, declarationFrame);
-
-        assert frameDescriptor != null;
-        assert pristineRootNode != null;
-
-        this.frameDescriptor = frameDescriptor;
-        this.pristineRootNode = pristineRootNode;
-        this.alwaysInline = alwaysInline;
-        this.shouldAppendCallNode = shouldAppendCallNode;
-    }
-
-    public FrameDescriptor getFrameDescriptor() {
-        return frameDescriptor;
-    }
-
-    public RubyRootNode getPristineRootNode() {
-        return pristineRootNode;
-    }
-
-    public RubyRootNode getCloneOfPristineRootNode() {
-        return NodeUtil.cloneNode(pristineRootNode);
-    }
-
-    public boolean alwaysInline() {
-        return alwaysInline;
-    }
-
-    public boolean getShouldAppendCallNode() {
-        return shouldAppendCallNode;
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/ReadNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,24 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes;
-
-/**
- * Interface for all nodes which read something, providing a method to transform them to write the
- * same thing.
- */
-public interface ReadNode {
-
-    /**
-     * Return a new node that performs the equivalent write operation to this node's read, using the
-     * supplied node for the right-hand-side.
-     */
-    RubyNode makeWriteNode(RubyNode rhs);
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/RubyNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,216 +0,0 @@
-/*
- * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes;
-
-import java.math.*;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.dsl.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.nodes.call.*;
-import com.oracle.truffle.ruby.nodes.instrument.*;
-import com.oracle.truffle.ruby.nodes.yield.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-import com.oracle.truffle.ruby.runtime.core.array.*;
-import com.oracle.truffle.ruby.runtime.core.range.*;
-import com.oracle.truffle.ruby.runtime.methods.*;
-import com.oracle.truffle.ruby.runtime.objects.*;
-
-/**
- * Base class for most nodes in Ruby.
- * 
- * @see DispatchNode
- * @see YieldDispatchNode
- */
-@TypeSystemReference(RubyTypes.class)
-public abstract class RubyNode extends Node {
-
-    private final RubyContext context;
-
-    public RubyNode(RubyContext context, SourceSection sourceSection) {
-        super(sourceSection);
-
-        assert context != null;
-        assert sourceSection != null;
-
-        this.context = context;
-    }
-
-    public RubyNode(RubyNode prev) {
-        this(prev.context, prev.getSourceSection());
-    }
-
-    public abstract Object execute(VirtualFrame frame);
-
-    /**
-     * Ruby's parallel semantic path.
-     * 
-     * @see DefinedNode
-     */
-    public Object isDefined(@SuppressWarnings("unused") VirtualFrame frame) {
-        throw new UnsupportedOperationException("no definition for " + getClass().getName());
-    }
-
-    public RubyArray executeArray(VirtualFrame frame) throws UnexpectedResultException {
-        return RubyTypesGen.RUBYTYPES.expectRubyArray(execute(frame));
-    }
-
-    public BigInteger executeBignum(VirtualFrame frame) throws UnexpectedResultException {
-        return RubyTypesGen.RUBYTYPES.expectBigInteger(execute(frame));
-    }
-
-    public boolean executeBoolean(VirtualFrame frame) throws UnexpectedResultException {
-        return RubyTypesGen.RUBYTYPES.expectBoolean(execute(frame));
-    }
-
-    public RubyBignum executeBoxedBignum(VirtualFrame frame) throws UnexpectedResultException {
-        return RubyTypesGen.RUBYTYPES.expectRubyBignum(execute(frame));
-    }
-
-    public RubyFixnum executeBoxedFixnum(VirtualFrame frame) throws UnexpectedResultException {
-        return RubyTypesGen.RUBYTYPES.expectRubyFixnum(execute(frame));
-    }
-
-    public RubyFloat executeBoxedFloat(VirtualFrame frame) throws UnexpectedResultException {
-        return RubyTypesGen.RUBYTYPES.expectRubyFloat(execute(frame));
-    }
-
-    public int executeFixnum(VirtualFrame frame) throws UnexpectedResultException {
-        return RubyTypesGen.RUBYTYPES.expectInteger(execute(frame));
-    }
-
-    public FixnumRange executeFixnumRange(VirtualFrame frame) throws UnexpectedResultException {
-        return RubyTypesGen.RUBYTYPES.expectFixnumRange(execute(frame));
-    }
-
-    public double executeFloat(VirtualFrame frame) throws UnexpectedResultException {
-        return RubyTypesGen.RUBYTYPES.expectDouble(execute(frame));
-    }
-
-    public NilPlaceholder executeNilPlaceholder(VirtualFrame frame) throws UnexpectedResultException {
-        return RubyTypesGen.RUBYTYPES.expectNilPlaceholder(execute(frame));
-    }
-
-    public Node executeNode(VirtualFrame frame) throws UnexpectedResultException {
-        return RubyTypesGen.RUBYTYPES.expectNode(execute(frame));
-    }
-
-    public Object[] executeObjectArray(VirtualFrame frame) throws UnexpectedResultException {
-        return RubyTypesGen.RUBYTYPES.expectObjectArray(execute(frame));
-    }
-
-    public ObjectRange executeObjectRange(VirtualFrame frame) throws UnexpectedResultException {
-        return RubyTypesGen.RUBYTYPES.expectObjectRange(execute(frame));
-    }
-
-    public RubyBasicObject executeRubyBasicObject(VirtualFrame frame) throws UnexpectedResultException {
-        return RubyTypesGen.RUBYTYPES.expectRubyBasicObject(execute(frame));
-    }
-
-    public RubyBinding executeRubyBinding(VirtualFrame frame) throws UnexpectedResultException {
-        return RubyTypesGen.RUBYTYPES.expectRubyBinding(execute(frame));
-    }
-
-    public RubyClass executeRubyClass(VirtualFrame frame) throws UnexpectedResultException {
-        return RubyTypesGen.RUBYTYPES.expectRubyClass(execute(frame));
-    }
-
-    public RubyContinuation executeRubyContinuation(VirtualFrame frame) throws UnexpectedResultException {
-        return RubyTypesGen.RUBYTYPES.expectRubyContinuation(execute(frame));
-    }
-
-    public RubyException executeRubyException(VirtualFrame frame) throws UnexpectedResultException {
-        return RubyTypesGen.RUBYTYPES.expectRubyException(execute(frame));
-    }
-
-    public RubyFiber executeRubyFiber(VirtualFrame frame) throws UnexpectedResultException {
-        return RubyTypesGen.RUBYTYPES.expectRubyFiber(execute(frame));
-    }
-
-    public RubyFile executeRubyFile(VirtualFrame frame) throws UnexpectedResultException {
-        return RubyTypesGen.RUBYTYPES.expectRubyFile(execute(frame));
-    }
-
-    public RubyHash executeRubyHash(VirtualFrame frame) throws UnexpectedResultException {
-        return RubyTypesGen.RUBYTYPES.expectRubyHash(execute(frame));
-    }
-
-    public RubyMatchData executeRubyMatchData(VirtualFrame frame) throws UnexpectedResultException {
-        return RubyTypesGen.RUBYTYPES.expectRubyMatchData(execute(frame));
-    }
-
-    public RubyMethod executeRubyMethod(VirtualFrame frame) throws UnexpectedResultException {
-        return RubyTypesGen.RUBYTYPES.expectRubyMethod(execute(frame));
-    }
-
-    public RubyModule executeRubyModule(VirtualFrame frame) throws UnexpectedResultException {
-        return RubyTypesGen.RUBYTYPES.expectRubyModule(execute(frame));
-    }
-
-    public RubyNilClass executeRubyNilClass(VirtualFrame frame) throws UnexpectedResultException {
-        return RubyTypesGen.RUBYTYPES.expectRubyNilClass(execute(frame));
-    }
-
-    public RubyObject executeRubyObject(VirtualFrame frame) throws UnexpectedResultException {
-        return RubyTypesGen.RUBYTYPES.expectRubyObject(execute(frame));
-    }
-
-    public RubyProc executeRubyProc(VirtualFrame frame) throws UnexpectedResultException {
-        return RubyTypesGen.RUBYTYPES.expectRubyProc(execute(frame));
-    }
-
-    public RubyRange executeRubyRange(VirtualFrame frame) throws UnexpectedResultException {
-        return RubyTypesGen.RUBYTYPES.expectRubyRange(execute(frame));
-    }
-
-    public RubyRegexp executeRubyRegexp(VirtualFrame frame) throws UnexpectedResultException {
-        return RubyTypesGen.RUBYTYPES.expectRubyRegexp(execute(frame));
-    }
-
-    public RubySymbol executeRubySymbol(VirtualFrame frame) throws UnexpectedResultException {
-        return RubyTypesGen.RUBYTYPES.expectRubySymbol(execute(frame));
-    }
-
-    public RubyThread executeRubyThread(VirtualFrame frame) throws UnexpectedResultException {
-        return RubyTypesGen.RUBYTYPES.expectRubyThread(execute(frame));
-    }
-
-    public RubyTime executeRubyTime(VirtualFrame frame) throws UnexpectedResultException {
-        return RubyTypesGen.RUBYTYPES.expectRubyTime(execute(frame));
-    }
-
-    public RubyString executeString(VirtualFrame frame) throws UnexpectedResultException {
-        return RubyTypesGen.RUBYTYPES.expectRubyString(execute(frame));
-    }
-
-    public UndefinedPlaceholder executeUndefinedPlaceholder(VirtualFrame frame) throws UnexpectedResultException {
-        return RubyTypesGen.RUBYTYPES.expectUndefinedPlaceholder(execute(frame));
-    }
-
-    public void executeVoid(VirtualFrame frame) {
-        execute(frame);
-    }
-
-    /**
-     * If you aren't sure whether you have a normal {@link RubyNode} or a {@link RubyProxyNode},
-     * this method will return the real node, whether that is this node, or whether this node is a
-     * proxy and you actually need the child.
-     */
-    public RubyNode getNonProxyNode() {
-        return this;
-    }
-
-    public RubyContext getContext() {
-        return context;
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/RubyRootNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,47 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-
-/**
- * The root node in an AST for a method. Unlike {@link RubyNode}, this has a single entry point,
- * {@link #execute}, which Truffle knows about and can create a {@link CallTarget} from.
- */
-public class RubyRootNode extends RootNode {
-
-    protected final String indicativeName;
-    @Child protected RubyNode body;
-
-    public RubyRootNode(SourceSection sourceSection, FrameDescriptor descriptor, String indicativeName, RubyNode body) {
-        super(sourceSection, descriptor);
-
-        assert indicativeName != null;
-        assert body != null;
-
-        this.body = adoptChild(body);
-        this.indicativeName = indicativeName;
-    }
-
-    @Override
-    public Object execute(VirtualFrame frame) {
-        return body.execute(frame);
-    }
-
-    @Override
-    public String toString() {
-        final SourceSection sourceSection = getSourceSection();
-        final String source = sourceSection == null ? "<unknown>" : sourceSection.toString();
-        return "Method " + indicativeName + ":" + source + "@" + Integer.toHexString(hashCode());
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/RubyTypes.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,88 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes;
-
-import java.math.*;
-
-import com.oracle.truffle.api.dsl.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-import com.oracle.truffle.ruby.runtime.core.array.*;
-import com.oracle.truffle.ruby.runtime.core.range.*;
-import com.oracle.truffle.ruby.runtime.methods.*;
-import com.oracle.truffle.ruby.runtime.objects.*;
-
-/**
- * The list of types and type conversions that the AST interpreter knows about and can specialise
- * using. Used by the DSL.
- */
-@TypeSystem({UndefinedPlaceholder.class, //
-                NilPlaceholder.class, //
-                boolean.class, //
-                int.class, //
-                double.class, //
-                BigInteger.class, //
-                FixnumRange.class, //
-                ObjectRange.class, //
-                RubyArray.class, //
-                RubyBignum.class, //
-                RubyBinding.class, //
-                RubyClass.class, //
-                RubyContinuation.class, //
-                RubyException.class, //
-                RubyFiber.class, //
-                RubyFile.class, //
-                RubyFixnum.class, //
-                RubyFloat.class, //
-                RubyHash.class, //
-                RubyMatchData.class, //
-                RubyMethod.class, //
-                RubyModule.class, //
-                RubyNilClass.class, //
-                RubyProc.class, //
-                RubyRange.class, //
-                RubyRegexp.class, //
-                RubyString.class, //
-                RubySymbol.class, //
-                RubyThread.class, //
-                RubyTime.class, //
-                RubyObject.class, //
-                RubyBasicObject.class, //
-                Node.class, //
-                Object[].class})
-public class RubyTypes {
-
-    /*
-     * The implicit casts allow the DSL to convert from an object of one type to another to satisfy
-     * specializations.
-     */
-
-    @ImplicitCast
-    public NilPlaceholder unboxNil(@SuppressWarnings("unused") RubyNilClass value) {
-        return NilPlaceholder.INSTANCE;
-    }
-
-    @ImplicitCast
-    public int unboxFixnum(RubyFixnum value) {
-        return value.getValue();
-    }
-
-    @ImplicitCast
-    public BigInteger unboxBignum(RubyBignum value) {
-        return value.getValue();
-    }
-
-    @ImplicitCast
-    public double unboxFloat(RubyFloat value) {
-        return value.getValue();
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/WriteNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,23 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes;
-
-/**
- * Interface for all nodes which write something, providing a method to transform them to read the
- * same thing.
- */
-public interface WriteNode {
-
-    /**
-     * Return a new node that performs the equivalent read operation to this node's write.
-     */
-    RubyNode makeReadNode();
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/call/BooleanDispatchNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,96 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.call;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-import com.oracle.truffle.ruby.runtime.methods.*;
-
-/**
- * An unboxed node in the dispatch chain that dispatches if the node is a boolean. In normal unboxed
- * dispatch we look at the Java class of the receiver. However, in Ruby true and false are two
- * separate classes, so in this situation we have to dispatch on the value, as well as the Java
- * class when we are dealing with booleans.
- * <p>
- * TODO(CS): it would be nice if we could {@link RubyNode#executeBoolean} the receiver, but by the
- * time we get to this dispatch node the receiver is already executed.
- */
-public class BooleanDispatchNode extends UnboxedDispatchNode {
-
-    private final Assumption falseUnmodifiedAssumption;
-    private final RubyMethod falseMethod;
-
-    private final Assumption trueUnmodifiedAssumption;
-    private final RubyMethod trueMethod;
-
-    @Child protected UnboxedDispatchNode next;
-
-    public BooleanDispatchNode(RubyContext context, SourceSection sourceSection, Assumption falseUnmodifiedAssumption, RubyMethod falseMethod, Assumption trueUnmodifiedAssumption,
-                    RubyMethod trueMethod, UnboxedDispatchNode next) {
-        super(context, sourceSection);
-
-        assert falseUnmodifiedAssumption != null;
-        assert falseMethod != null;
-        assert trueUnmodifiedAssumption != null;
-        assert trueMethod != null;
-
-        this.falseUnmodifiedAssumption = falseUnmodifiedAssumption;
-        this.falseMethod = falseMethod;
-
-        this.trueUnmodifiedAssumption = trueUnmodifiedAssumption;
-        this.trueMethod = trueMethod;
-
-        this.next = adoptChild(next);
-    }
-
-    @Override
-    public Object dispatch(VirtualFrame frame, Object receiverObject, RubyProc blockObject, Object[] argumentsObjects) {
-        // Check it's a boolean
-
-        if (!(receiverObject instanceof Boolean)) {
-            return next.dispatch(frame, receiverObject, blockObject, argumentsObjects);
-        }
-
-        // Check the value
-
-        Assumption unmodifiedAssumption;
-        RubyMethod method;
-
-        if ((boolean) receiverObject) {
-            unmodifiedAssumption = trueUnmodifiedAssumption;
-            method = trueMethod;
-        } else {
-            unmodifiedAssumption = falseUnmodifiedAssumption;
-            method = falseMethod;
-        }
-
-        // Check the class has not been modified
-
-        try {
-            unmodifiedAssumption.check();
-        } catch (InvalidAssumptionException e) {
-            return respecialize("class modified", frame, receiverObject, blockObject, argumentsObjects);
-        }
-
-        // Call the method
-
-        return method.call(frame.pack(), receiverObject, blockObject, argumentsObjects);
-    }
-
-    @Override
-    public void setNext(UnboxedDispatchNode next) {
-        this.next = adoptChild(next);
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/call/BoxedDispatchNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,30 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.call;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-import com.oracle.truffle.ruby.runtime.objects.*;
-
-/**
- * A node in the dispatch chain that expects the receiver to be an object boxed into a full
- * {@link RubyBasicObject}.
- */
-public abstract class BoxedDispatchNode extends DispatchNode {
-
-    public BoxedDispatchNode(RubyContext context, SourceSection sourceSection) {
-        super(context, sourceSection);
-    }
-
-    public abstract Object dispatch(VirtualFrame frame, RubyBasicObject receiverObject, RubyProc blockObject, Object[] argumentsObjects);
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/call/BoxingDispatchNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /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. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.call;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.utilities.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-import com.oracle.truffle.ruby.runtime.objects.*;
-
-/**
- * A node in the dispatch chain that boxes the receiver into a full Ruby {@link RubyBasicObject}.
- * This node is initially created as an {@link UninitializedBoxingDispatchNode} and only becomes
- * this node when we know that we do need to box on the fast path. Within this node we specialized
- * for the case that the receiver is always already boxed.
- */
-public class BoxingDispatchNode extends UnboxedDispatchNode {
-
-    @Child protected BoxedDispatchNode next;
-
-    private final BranchProfile boxBranch = new BranchProfile();
-
-    public BoxingDispatchNode(RubyContext context, SourceSection sourceSection, BoxedDispatchNode next) {
-        super(context, sourceSection);
-
-        this.next = adoptChild(next);
-    }
-
-    @Override
-    public Object dispatch(VirtualFrame frame, Object receiverObject, RubyProc blockObject, Object[] argumentsObjects) {
-        RubyBasicObject boxedReceiverObject;
-
-        if (receiverObject instanceof RubyBasicObject) {
-            boxedReceiverObject = (RubyBasicObject) receiverObject;
-        } else {
-            boxBranch.enter();
-            boxedReceiverObject = getContext().getCoreLibrary().box(receiverObject);
-        }
-
-        return next.dispatch(frame, boxedReceiverObject, blockObject, argumentsObjects);
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/call/CachedBoxedDispatchNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,67 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.call;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-import com.oracle.truffle.ruby.runtime.lookup.*;
-import com.oracle.truffle.ruby.runtime.methods.*;
-import com.oracle.truffle.ruby.runtime.objects.*;
-
-/**
- * A node in the dispatch chain that comes after the boxing point and caches a method on a full
- * boxed Ruby BasicObject, matching it by looking at the lookup node and assuming it has not been
- * modified.
- */
-public class CachedBoxedDispatchNode extends BoxedDispatchNode {
-
-    private final LookupNode expectedLookupNode;
-    private final Assumption unmodifiedAssumption;
-    private final RubyMethod method;
-
-    @Child protected BoxedDispatchNode next;
-
-    public CachedBoxedDispatchNode(RubyContext context, SourceSection sourceSection, LookupNode expectedLookupNode, RubyMethod method, BoxedDispatchNode next) {
-        super(context, sourceSection);
-
-        assert expectedLookupNode != null;
-        assert method != null;
-
-        this.expectedLookupNode = expectedLookupNode;
-        unmodifiedAssumption = expectedLookupNode.getUnmodifiedAssumption();
-        this.method = method;
-        this.next = adoptChild(next);
-    }
-
-    @Override
-    public Object dispatch(VirtualFrame frame, RubyBasicObject receiverObject, RubyProc blockObject, Object[] argumentsObjects) {
-        // Check the lookup node is what we expect
-
-        if (receiverObject.getLookupNode() != expectedLookupNode) {
-            return next.dispatch(frame, receiverObject, blockObject, argumentsObjects);
-        }
-
-        // Check the class has not been modified
-
-        try {
-            unmodifiedAssumption.check();
-        } catch (InvalidAssumptionException e) {
-            return respecialize("class modified", frame, receiverObject, blockObject, argumentsObjects);
-        }
-
-        // Call the method
-
-        return method.call(frame.pack(), receiverObject, blockObject, argumentsObjects);
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/call/CachedUnboxedDispatchNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,70 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.call;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-import com.oracle.truffle.ruby.runtime.methods.*;
-
-/**
- * A node in the dispatch chain that comes before the boxing point and caches a method on a Java
- * object, matching it by looking at the class and assuming it has not been modified.
- */
-public class CachedUnboxedDispatchNode extends UnboxedDispatchNode {
-
-    private final Class expectedClass;
-    private final Assumption unmodifiedAssumption;
-    private final RubyMethod method;
-
-    @Child protected UnboxedDispatchNode next;
-
-    public CachedUnboxedDispatchNode(RubyContext context, SourceSection sourceSection, Class expectedClass, Assumption unmodifiedAssumption, RubyMethod method, UnboxedDispatchNode next) {
-        super(context, sourceSection);
-
-        assert expectedClass != null;
-        assert unmodifiedAssumption != null;
-        assert method != null;
-
-        this.expectedClass = expectedClass;
-        this.unmodifiedAssumption = unmodifiedAssumption;
-        this.method = method;
-        this.next = adoptChild(next);
-    }
-
-    @Override
-    public Object dispatch(VirtualFrame frame, Object receiverObject, RubyProc blockObject, Object[] argumentsObjects) {
-        // Check the class is what we expect
-
-        if (receiverObject.getClass() != expectedClass) {
-            return next.dispatch(frame, receiverObject, blockObject, argumentsObjects);
-        }
-
-        // Check the class has not been modified
-
-        try {
-            unmodifiedAssumption.check();
-        } catch (InvalidAssumptionException e) {
-            return respecialize("class modified", frame, receiverObject, blockObject, argumentsObjects);
-        }
-
-        // Call the method
-
-        return method.call(frame.pack(), receiverObject, blockObject, argumentsObjects);
-    }
-
-    @Override
-    public void setNext(UnboxedDispatchNode next) {
-        this.next = adoptChild(next);
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/call/CallNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,158 +0,0 @@
-/*
- * Copyright (c) 2013, 2014 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.call;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-import com.oracle.truffle.ruby.runtime.core.array.*;
-import com.oracle.truffle.ruby.runtime.methods.*;
-import com.oracle.truffle.ruby.runtime.objects.*;
-
-/**
- * A call node that has a chain of dispatch nodes.
- * <p>
- * The dispatch chain starts as {@link CallNode} -&gt; {@link DispatchHeadNode} -&gt;
- * {@link UninitializedBoxingDispatchNode} -&gt; {@link UninitializedDispatchNode}.
- * <p>
- * When the {@link UninitializedDispatchNode} is reached a new node is inserted into the chain. If
- * the node dispatches based on some unboxed value (unboxed as in it's not a Ruby object, just a
- * Java object) such as {@link Integer}, then that node is inserted before the
- * {@link UninitializedBoxingDispatchNode}, otherwise if it dispatches based on some Ruby
- * BasicObject, it is inserted afterwards.
- * <p>
- * The {@link UninitializedBoxingDispatchNode} becomes a {@link BoxingDispatchNode} when we find
- * that the boxing has to be done on the fast path - when there is some boxed dispatch node.
- * <p>
- * So the general format is {@link CallNode} -&gt; {@link DispatchHeadNode} -&gt; zero or more
- * unboxed dispatches -&gt; {@link UninitializedBoxingDispatchNode} | {@link BoxingDispatchNode}
- * -&gt; zero or more boxed dispatches -&gt; {@link UninitializedDispatchNode}.
- * <p>
- * There are several special cases of unboxed and boxed dispatch nodes based on the types and
- * methods involved.
- * <p>
- * If we have too many dispatch nodes we replace the whole chain with {@link DispatchHeadNode} -&gt;
- * {@link BoxingDispatchNode} -&gt; {@link GeneralBoxedDispatchNode}.
- * <p>
- * This system allows us to dispatch based purely on Java class, before we have to turn the object
- * into a full {@link RubyBasicObject} and consider the full Ruby lookup process, and something such
- * as a math call which may work on Fixnum or Float to work as just a couple of applications of
- * {@code instanceof} and assumption checks.
- */
-public class CallNode extends RubyNode {
-
-    @Child protected RubyNode receiver;
-    @Child protected ProcOrNullNode block;
-    @Children protected final RubyNode[] arguments;
-
-    private final String name;
-    private final boolean isSplatted;
-
-    @Child protected DispatchHeadNode dispatchHead;
-
-    public CallNode(RubyContext context, SourceSection section, String name, RubyNode receiver, RubyNode block, boolean isSplatted, RubyNode[] arguments) {
-        super(context, section);
-
-        assert receiver != null;
-        assert arguments != null;
-        assert name != null;
-
-        this.receiver = adoptChild(receiver);
-
-        if (block == null) {
-            this.block = null;
-        } else {
-            this.block = adoptChild(ProcOrNullNodeFactory.create(context, section, block));
-        }
-
-        this.arguments = adoptChildren(arguments);
-        this.name = name;
-        this.isSplatted = isSplatted;
-
-        dispatchHead = adoptChild(new DispatchHeadNode(context, section, name, isSplatted));
-    }
-
-    @Override
-    public Object execute(VirtualFrame frame) {
-        final Object receiverObject = receiver.execute(frame);
-        final Object[] argumentsObjects = executeArguments(frame);
-        final RubyProc blockObject = executeBlock(frame);
-
-        return dispatchHead.dispatch(frame, receiverObject, blockObject, argumentsObjects);
-    }
-
-    private RubyProc executeBlock(VirtualFrame frame) {
-        if (block != null) {
-            return block.executeRubyProc(frame);
-        } else {
-            return null;
-        }
-    }
-
-    @ExplodeLoop
-    private Object[] executeArguments(VirtualFrame frame) {
-        final Object[] argumentsObjects = new Object[arguments.length];
-
-        for (int i = 0; i < arguments.length; i++) {
-            argumentsObjects[i] = arguments[i].execute(frame);
-            assert RubyContext.shouldObjectBeVisible(argumentsObjects[i]) : argumentsObjects[i].getClass();
-        }
-
-        if (isSplatted) {
-            assert argumentsObjects[0] instanceof RubyArray;
-            return ((RubyArray) argumentsObjects[0]).toObjectArray();
-        } else {
-            return argumentsObjects;
-        }
-    }
-
-    @Override
-    public Object isDefined(VirtualFrame frame) {
-        final RubyContext context = getContext();
-
-        Object receiverObject;
-
-        try {
-            /*
-             * TODO(CS): Getting a node via an accessor like this doesn't work with Truffle at the
-             * moment and will cause frame escape errors, so we don't use it in compilation mode.
-             */
-
-            CompilerAsserts.neverPartOfCompilation();
-
-            receiverObject = receiver.execute(frame);
-        } catch (Exception e) {
-            return NilPlaceholder.INSTANCE;
-        }
-
-        final RubyBasicObject receiverBasicObject = context.getCoreLibrary().box(receiverObject);
-
-        final RubyMethod method = receiverBasicObject.getLookupNode().lookupMethod(name);
-
-        final RubyBasicObject self = context.getCoreLibrary().box(frame.getArguments(RubyArguments.class).getSelf());
-
-        if (method == null || method.isUndefined()) {
-            return NilPlaceholder.INSTANCE;
-        }
-
-        if (!method.isVisibleTo(self)) {
-            return NilPlaceholder.INSTANCE;
-        }
-
-        return context.makeString("method");
-    }
-
-    public String getName() {
-        return name;
-    }
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/call/DispatchHeadNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,68 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.call;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-import com.oracle.truffle.ruby.runtime.methods.*;
-import com.oracle.truffle.ruby.runtime.objects.*;
-
-/**
- * The head of a chain of dispatch nodes. Can be used with {@link CallNode} or on its own.
- */
-public class DispatchHeadNode extends DispatchNode {
-
-    private final RubyContext context;
-    private final String name;
-    private final boolean isSplatted;
-
-    @Child protected UnboxedDispatchNode dispatch;
-
-    public DispatchHeadNode(RubyContext context, SourceSection sourceSection, String name, boolean isSplatted) {
-        super(context, sourceSection);
-
-        assert context != null;
-        assert name != null;
-
-        this.context = context;
-        this.name = name;
-        this.isSplatted = isSplatted;
-
-        final UninitializedDispatchNode uninitializedDispatch = new UninitializedDispatchNode(context, sourceSection, name);
-        dispatch = adoptChild(new UninitializedBoxingDispatchNode(context, sourceSection, uninitializedDispatch));
-    }
-
-    public Object dispatch(VirtualFrame frame, Object receiverObject, RubyProc blockObject, Object... argumentsObjects) {
-        return dispatch.dispatch(frame, receiverObject, blockObject, argumentsObjects);
-    }
-
-    /**
-     * Replace the entire dispatch chain with a fresh chain. Used when the situation has changed in
-     * such a significant way that it's best to start again rather than add new specializations to
-     * the chain. Used for example when methods appear to have been monkey-patched.
-     */
-    public Object respecialize(VirtualFrame frame, String reason, Object receiverObject, RubyProc blockObject, Object... argumentObjects) {
-        CompilerAsserts.neverPartOfCompilation();
-
-        replace(new DispatchHeadNode(context, getSourceSection(), name, isSplatted), reason);
-
-        final RubyBasicObject receiverBasicObject = context.getCoreLibrary().box(receiverObject);
-
-        final RubyMethod method = lookup(frame, receiverBasicObject, name);
-        return method.call(frame.pack(), receiverBasicObject, blockObject, argumentObjects);
-    }
-
-    public UnboxedDispatchNode getDispatch() {
-        return dispatch;
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/call/DispatchNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,87 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.call;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.control.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-import com.oracle.truffle.ruby.runtime.methods.*;
-import com.oracle.truffle.ruby.runtime.objects.*;
-
-/**
- * Any node in the dispatch chain.
- */
-public class DispatchNode extends Node {
-
-    private final RubyContext context;
-
-    public DispatchNode(RubyContext context, SourceSection sourceSection) {
-        super(sourceSection);
-
-        assert context != null;
-        assert sourceSection != null;
-
-        this.context = context;
-    }
-
-    /**
-     * Get the depth of this node in the dispatch chain. The first node below
-     * {@link DispatchHeadNode} is at depth 1.
-     */
-    public int getDepth() {
-        int depth = 1;
-        Node parent = this.getParent();
-
-        while (!(parent instanceof DispatchHeadNode)) {
-            parent = parent.getParent();
-            depth++;
-        }
-
-        return depth;
-    }
-
-    public Object respecialize(String reason, VirtualFrame frame, Object receiverObject, RubyProc blockObject, Object... argumentsObjects) {
-        CompilerAsserts.neverPartOfCompilation();
-
-        final int depth = getDepth();
-        final DispatchHeadNode head = (DispatchHeadNode) NodeUtil.getNthParent(this, depth);
-
-        return head.respecialize(frame, reason, receiverObject, blockObject, argumentsObjects);
-    }
-
-    /**
-     * The central point for method lookup.
-     */
-    protected RubyMethod lookup(VirtualFrame frame, RubyBasicObject receiverBasicObject, String name) {
-        final RubyMethod method = receiverBasicObject.getLookupNode().lookupMethod(name);
-
-        final RubyBasicObject self = context.getCoreLibrary().box(frame.getArguments(RubyArguments.class).getSelf());
-
-        if (method == null || method.isUndefined()) {
-            CompilerDirectives.transferToInterpreter();
-            throw new RaiseException(context.getCoreLibrary().nameErrorNoMethod(name, receiverBasicObject.toString()));
-        }
-
-        if (!method.isVisibleTo(self)) {
-            CompilerDirectives.transferToInterpreter();
-            throw new RaiseException(context.getCoreLibrary().noMethodError(name, receiverBasicObject.toString()));
-        }
-
-        return method;
-    }
-
-    public RubyContext getContext() {
-        return context;
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/call/GeneralBoxedDispatchNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,46 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.call;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-import com.oracle.truffle.ruby.runtime.methods.*;
-import com.oracle.truffle.ruby.runtime.objects.*;
-
-/**
- * A node in the dispatch chain that does no caching and looks up methods from scratch each time it
- * is called.
- */
-public class GeneralBoxedDispatchNode extends BoxedDispatchNode {
-
-    private final String name;
-
-    public GeneralBoxedDispatchNode(RubyContext context, SourceSection sourceSection, String name) {
-        super(context, sourceSection);
-
-        assert name != null;
-
-        this.name = name;
-    }
-
-    @Override
-    public Object dispatch(VirtualFrame frame, RubyBasicObject receiverObject, RubyProc blockObject, Object[] argumentsObjects) {
-        /*
-         * TODO(CS): we should probably have some kind of cache here - even if it's just a hash map.
-         * MRI and JRuby do and might avoid some pathological cases.
-         */
-
-        final RubyMethod method = lookup(frame, receiverObject, name);
-        return method.call(frame.pack(), receiverObject, blockObject, argumentsObjects);
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/call/GeneralSuperCallNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,128 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.call;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.control.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-import com.oracle.truffle.ruby.runtime.core.array.*;
-import com.oracle.truffle.ruby.runtime.methods.*;
-import com.oracle.truffle.ruby.runtime.objects.*;
-
-/**
- * Represents a super call - that is a call with self as the receiver, but the superclass of self
- * used for lookup. Currently implemented without any caching, and needs to be replaced with the
- * same caching mechanism as for normal calls without complicating the existing calls too much.
- */
-@NodeInfo(shortName = "general-super-call")
-public class GeneralSuperCallNode extends RubyNode {
-
-    private final String name;
-    private final boolean isSplatted;
-    @Child protected RubyNode block;
-    @Children protected final RubyNode[] arguments;
-
-    public GeneralSuperCallNode(RubyContext context, SourceSection sourceSection, String name, RubyNode block, RubyNode[] arguments, boolean isSplatted) {
-        super(context, sourceSection);
-
-        assert name != null;
-        assert arguments != null;
-        assert !isSplatted || arguments.length == 1;
-
-        this.name = name;
-        this.block = adoptChild(block);
-        this.arguments = adoptChildren(arguments);
-        this.isSplatted = isSplatted;
-    }
-
-    @ExplodeLoop
-    @Override
-    public final Object execute(VirtualFrame frame) {
-        // This method is only a simple implementation - it needs proper caching
-
-        CompilerAsserts.neverPartOfCompilation();
-
-        final RubyBasicObject self = (RubyBasicObject) frame.getArguments(RubyArguments.class).getSelf();
-
-        // Execute the arguments
-
-        final Object[] argumentsObjects = new Object[arguments.length];
-
-        CompilerAsserts.compilationConstant(arguments.length);
-        for (int i = 0; i < arguments.length; i++) {
-            argumentsObjects[i] = arguments[i].execute(frame);
-        }
-
-        // Execute the block
-
-        RubyProc blockObject;
-
-        if (block != null) {
-            final Object blockTempObject = block.execute(frame);
-
-            if (blockTempObject instanceof NilPlaceholder) {
-                blockObject = null;
-            } else {
-                blockObject = (RubyProc) blockTempObject;
-            }
-        } else {
-            blockObject = null;
-        }
-
-        // Lookup method
-
-        final RubyClass selfClass = self.getRubyClass();
-        final RubyMethod method = selfClass.getSuperclass().lookupMethod(name);
-
-        if (method == null || method.isUndefined()) {
-            CompilerDirectives.transferToInterpreter();
-            throw new RaiseException(getContext().getCoreLibrary().nameErrorNoMethod(name, self.toString()));
-        }
-
-        if (!method.isVisibleTo(self)) {
-            CompilerDirectives.transferToInterpreter();
-            throw new RaiseException(getContext().getCoreLibrary().noMethodError("(unknown)"));
-        }
-
-        // Call the method
-
-        if (isSplatted) {
-            final RubyArray argumentsArray = (RubyArray) argumentsObjects[0];
-            return method.call(frame.pack(), self, blockObject, argumentsArray.asList().toArray());
-        } else {
-            return method.call(frame.pack(), self, blockObject, argumentsObjects);
-        }
-    }
-
-    @Override
-    public Object isDefined(VirtualFrame frame) {
-        final RubyContext context = getContext();
-
-        try {
-            final RubyBasicObject self = context.getCoreLibrary().box(frame.getArguments(RubyArguments.class).getSelf());
-            final RubyBasicObject receiverRubyObject = context.getCoreLibrary().box(self);
-
-            final RubyMethod method = receiverRubyObject.getRubyClass().getSuperclass().lookupMethod(name);
-
-            if (method == null || method.isUndefined() || !method.isVisibleTo(self)) {
-                return NilPlaceholder.INSTANCE;
-            } else {
-                return context.makeString("super");
-            }
-        } catch (Exception e) {
-            return NilPlaceholder.INSTANCE;
-        }
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/call/InlineHeuristic.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.call;
-
-import com.oracle.truffle.ruby.nodes.*;
-
-public class InlineHeuristic {
-
-    public static boolean shouldInline(InlinableMethodImplementation method) {
-        if (method.alwaysInline()) {
-            return true;
-        }
-
-        return false;
-    }
-
-    public static boolean shouldInlineYield(@SuppressWarnings("unused") InlinableMethodImplementation method) {
-        return true;
-    }
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/call/InlinedBoxedDispatchNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,84 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.call;
-
-import java.util.*;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-import com.oracle.truffle.ruby.runtime.lookup.*;
-import com.oracle.truffle.ruby.runtime.objects.*;
-
-/**
- * A node in the dispatch chain that comes after the boxing point and caches a method on a full
- * boxed {@link RubyBasicObject}, matching it by looking at the lookup node and assuming it has not
- * been modified.
- */
-public class InlinedBoxedDispatchNode extends BoxedDispatchNode {
-
-    private final LookupNode expectedLookupNode;
-    private final Assumption unmodifiedAssumption;
-
-    private final InlinableMethodImplementation method;
-    private final RubyRootNode rootNode;
-
-    @Child protected BoxedDispatchNode next;
-
-    public InlinedBoxedDispatchNode(RubyContext context, SourceSection sourceSection, LookupNode expectedLookupNode, InlinableMethodImplementation method, BoxedDispatchNode next) {
-        super(context, sourceSection);
-
-        assert expectedLookupNode != null;
-        assert method != null;
-
-        this.expectedLookupNode = expectedLookupNode;
-        unmodifiedAssumption = expectedLookupNode.getUnmodifiedAssumption();
-        this.method = method;
-        this.rootNode = method.getCloneOfPristineRootNode();
-        this.next = adoptChild(next);
-    }
-
-    @Override
-    public Object dispatch(VirtualFrame frame, RubyBasicObject receiverObject, RubyProc blockObject, Object[] argumentsObjects) {
-        // Check the lookup node is what we expect
-
-        if (receiverObject.getLookupNode() != expectedLookupNode) {
-            return next.dispatch(frame, receiverObject, blockObject, argumentsObjects);
-        }
-
-        // Check the class has not been modified
-
-        try {
-            unmodifiedAssumption.check();
-        } catch (InvalidAssumptionException e) {
-            return respecialize("class modified", frame, receiverObject, blockObject, argumentsObjects);
-        }
-
-        // Call the method
-
-        Object[] modifiedArgumentsObjects;
-
-        CompilerAsserts.compilationConstant(method.getShouldAppendCallNode());
-
-        if (method.getShouldAppendCallNode()) {
-            modifiedArgumentsObjects = Arrays.copyOf(argumentsObjects, argumentsObjects.length + 1);
-            modifiedArgumentsObjects[modifiedArgumentsObjects.length - 1] = this;
-        } else {
-            modifiedArgumentsObjects = argumentsObjects;
-        }
-
-        final RubyArguments arguments = new RubyArguments(method.getDeclarationFrame(), receiverObject, blockObject, modifiedArgumentsObjects);
-        final VirtualFrame inlinedFrame = Truffle.getRuntime().createVirtualFrame(frame.pack(), arguments, method.getFrameDescriptor());
-        return rootNode.execute(inlinedFrame);
-    }
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/call/InlinedUnboxedDispatchNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,71 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.call;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-
-public class InlinedUnboxedDispatchNode extends UnboxedDispatchNode {
-
-    private final Class expectedClass;
-    private final Assumption unmodifiedAssumption;
-
-    private final InlinableMethodImplementation method;
-    private final RubyRootNode rootNode;
-
-    @Child protected UnboxedDispatchNode next;
-
-    public InlinedUnboxedDispatchNode(RubyContext context, SourceSection sourceSection, Class expectedClass, Assumption unmodifiedAssumption, InlinableMethodImplementation method,
-                    UnboxedDispatchNode next) {
-        super(context, sourceSection);
-
-        assert expectedClass != null;
-        assert method != null;
-
-        this.expectedClass = expectedClass;
-        this.unmodifiedAssumption = unmodifiedAssumption;
-        this.method = method;
-        this.rootNode = method.getCloneOfPristineRootNode();
-        this.next = adoptChild(next);
-    }
-
-    @Override
-    public Object dispatch(VirtualFrame frame, Object receiverObject, RubyProc blockObject, Object[] argumentsObjects) {
-        // Check the class is what we expect
-
-        if (receiverObject.getClass() != expectedClass) {
-            return next.dispatch(frame, receiverObject, blockObject, argumentsObjects);
-        }
-
-        // Check the class has not been modified
-
-        try {
-            unmodifiedAssumption.check();
-        } catch (InvalidAssumptionException e) {
-            return respecialize("class modified", frame, receiverObject, blockObject, argumentsObjects);
-        }
-
-        // Call the method
-
-        final RubyArguments arguments = new RubyArguments(method.getDeclarationFrame(), receiverObject, blockObject, argumentsObjects);
-        final VirtualFrame inlinedFrame = Truffle.getRuntime().createVirtualFrame(frame.pack(), arguments, method.getFrameDescriptor());
-        return rootNode.execute(inlinedFrame);
-    }
-
-    @Override
-    public void setNext(UnboxedDispatchNode next) {
-        this.next = adoptChild(next);
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/call/ProcOrNullNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,56 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.call;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.dsl.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-
-/**
- * Wraps some node that will produce either a {@link RubyProc} or a {@link NilPlaceholder} and
- * returns {@code null} in case of the latter. Used in parts of the dispatch chain.
- */
-@NodeInfo(shortName = "proc-or-null")
-@NodeChild(value = "child", type = RubyNode.class)
-public abstract class ProcOrNullNode extends RubyNode {
-
-    public ProcOrNullNode(RubyContext context, SourceSection sourceSection) {
-        super(context, sourceSection);
-    }
-
-    public ProcOrNullNode(ProcOrNullNode prev) {
-        super(prev);
-    }
-
-    @Specialization
-    public Object doNil(@SuppressWarnings("unused") NilPlaceholder nil) {
-        return null;
-    }
-
-    @Specialization
-    public Object doProc(RubyProc proc) {
-        return proc;
-    }
-
-    @Override
-    public RubyProc executeRubyProc(VirtualFrame frame) {
-        final Object proc = execute(frame);
-
-        // The standard asRubyProc test doesn't allow for null
-        assert proc == null || RubyTypesGen.RUBYTYPES.isRubyProc(proc);
-
-        return (RubyProc) proc;
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/call/UnboxedDispatchNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.call;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-import com.oracle.truffle.ruby.runtime.objects.*;
-
-/**
- * A node in the dispatch chain that expects the receiver to be a simple Java object such as a boxed
- * primitive, rather than a full {@link RubyBasicObject}. This allows calls to be made with a
- * receiver such as {@link Integer} without having to turn it into a {@link RubyFixnum}. Followed at
- * some point by an {@link UninitializedBoxingDispatchNode} or {@link BoxingDispatchNode} before we
- * try to dispatch on a Ruby BasicObject or the {@link UninitializedDispatchNode}.
- */
-public abstract class UnboxedDispatchNode extends DispatchNode {
-
-    public UnboxedDispatchNode(RubyContext context, SourceSection sourceSection) {
-        super(context, sourceSection);
-    }
-
-    public abstract Object dispatch(VirtualFrame frame, Object receiverObject, RubyProc blockObject, Object[] argumentsObjects);
-
-    public void setNext(@SuppressWarnings("unused") UnboxedDispatchNode next) {
-        throw new UnsupportedOperationException();
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/call/UninitializedBoxingDispatchNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,50 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.call;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-
-/**
- * A node in the dispatch chain that transfers to interpreter and then boxes the receiver.
- */
-public class UninitializedBoxingDispatchNode extends UnboxedDispatchNode {
-
-    @Child protected BoxedDispatchNode next;
-
-    public UninitializedBoxingDispatchNode(RubyContext context, SourceSection sourceSection, BoxedDispatchNode next) {
-        super(context, sourceSection);
-
-        this.next = adoptChild(next);
-    }
-
-    @Override
-    public Object dispatch(VirtualFrame frame, Object receiverObject, RubyProc blockObject, Object[] argumentsObjects) {
-        CompilerDirectives.transferToInterpreter();
-
-        /*
-         * If the next dispatch node is something other than the uninitialized dispatch node then we
-         * need to replace this node because it's now on the fast path. If the receiver was already
-         * boxed.
-         * 
-         * Note that with this scheme it will take a couple of calls for the chain to become fully
-         * specialized.
-         */
-
-        if (next instanceof UninitializedDispatchNode) {
-            this.replace(new BoxingDispatchNode(getContext(), getSourceSection(), next));
-        }
-
-        return next.dispatch(frame, getContext().getCoreLibrary().box(receiverObject), blockObject, argumentsObjects);
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/call/UninitializedDispatchNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,127 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.call;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-import com.oracle.truffle.ruby.runtime.methods.*;
-import com.oracle.truffle.ruby.runtime.objects.*;
-
-/**
- * The uninitialized dispatch node. Only reached when the method is not expected by any node in the
- * dispatch chain, and only creates new nodes or modifies the existing chain.
- */
-public class UninitializedDispatchNode extends BoxedDispatchNode {
-
-    /*
-     * Node at depth 5 is 4 actual dispatches, the boxing dispatch and the final uninitalized
-     * dispatch.
-     */
-
-    private static final int MAX_DEPTH = 5;
-
-    private final String name;
-
-    public UninitializedDispatchNode(RubyContext context, SourceSection sourceSection, String name) {
-        super(context, sourceSection);
-
-        assert name != null;
-
-        this.name = name;
-    }
-
-    @Override
-    public Object dispatch(VirtualFrame frame, RubyBasicObject receiverObject, RubyProc blockObject, Object[] argumentsObjects) {
-        CompilerDirectives.transferToInterpreter();
-
-        final RubyContext context = getContext();
-
-        final RubyMethod method = lookup(frame, receiverObject, name);
-
-        final int depth = getDepth();
-
-        final DispatchHeadNode dispatchHead = (DispatchHeadNode) NodeUtil.getNthParent(this, depth);
-
-        if (depth == MAX_DEPTH) {
-            /*
-             * Replace the chain with DispatchHeadNode -> ExpectBoxedDispatchNode ->
-             * GeneralDispatchNode.
-             */
-
-            context.implementationMessage("resorting to a general call node at %s", getSourceSection());
-            NodeUtil.printTree(System.err, dispatchHead);
-
-            final GeneralBoxedDispatchNode newGeneralDispatch = new GeneralBoxedDispatchNode(getContext(), getSourceSection(), name);
-            final BoxingDispatchNode newBoxing = new BoxingDispatchNode(getContext(), getSourceSection(), newGeneralDispatch);
-
-            dispatchHead.getDispatch().replace(newBoxing);
-            return newBoxing.dispatch(frame, receiverObject, blockObject, argumentsObjects);
-        } else if (receiverObject instanceof Unboxable) {
-            /*
-             * Unboxed dispatch nodes are prepended to the chain of dispatch nodes, so they're
-             * before the point where receivers will definitely be boxed.
-             */
-
-            final Object receiverUnboxed = ((Unboxable) receiverObject).unbox();
-
-            final UnboxedDispatchNode firstDispatch = dispatchHead.getDispatch();
-
-            if (receiverObject instanceof RubyTrueClass || receiverObject instanceof RubyFalseClass) {
-                final Assumption falseUnmodifiedAssumption = context.getCoreLibrary().getFalseClass().getUnmodifiedAssumption();
-                final RubyMethod falseMethod = lookup(frame, context.getCoreLibrary().box(false), name);
-                final Assumption trueUnmodifiedAssumption = context.getCoreLibrary().getTrueClass().getUnmodifiedAssumption();
-                final RubyMethod trueMethod = lookup(frame, context.getCoreLibrary().box(true), name);
-
-                final BooleanDispatchNode newDispatch = new BooleanDispatchNode(getContext(), getSourceSection(), falseUnmodifiedAssumption, falseMethod, trueUnmodifiedAssumption, trueMethod, null);
-                firstDispatch.replace(newDispatch, "prepending new unboxed dispatch node to chain");
-                newDispatch.setNext(firstDispatch);
-                return newDispatch.dispatch(frame, receiverUnboxed, blockObject, argumentsObjects);
-            } else {
-                UnboxedDispatchNode newDispatch;
-
-                if (method.getImplementation() instanceof InlinableMethodImplementation && InlineHeuristic.shouldInline((InlinableMethodImplementation) method.getImplementation())) {
-                    newDispatch = new InlinedUnboxedDispatchNode(getContext(), getSourceSection(), receiverUnboxed.getClass(), receiverObject.getRubyClass().getUnmodifiedAssumption(),
-                                    (InlinableMethodImplementation) method.getImplementation(), null);
-                } else {
-                    newDispatch = new CachedUnboxedDispatchNode(getContext(), getSourceSection(), receiverUnboxed.getClass(), receiverObject.getRubyClass().getUnmodifiedAssumption(), method, null);
-                }
-
-                firstDispatch.replace(newDispatch, "prepending new unboxed dispatch node to chain");
-                newDispatch.setNext(firstDispatch);
-
-                return newDispatch.dispatch(frame, receiverUnboxed, blockObject, argumentsObjects);
-            }
-        } else {
-            /*
-             * Boxed dispatch nodes are appended to the chain of dispatch nodes, so they're after
-             * the point where receivers are guaranteed to be boxed.
-             */
-
-            final UninitializedDispatchNode newUninitializedDispatch = new UninitializedDispatchNode(getContext(), getSourceSection(), name);
-
-            BoxedDispatchNode newDispatch;
-
-            if (method.getImplementation() instanceof InlinableMethodImplementation && InlineHeuristic.shouldInline((InlinableMethodImplementation) method.getImplementation())) {
-                newDispatch = new InlinedBoxedDispatchNode(getContext(), getSourceSection(), receiverObject.getLookupNode(), (InlinableMethodImplementation) method.getImplementation(),
-                                newUninitializedDispatch);
-            } else {
-                newDispatch = new CachedBoxedDispatchNode(getContext(), getSourceSection(), receiverObject.getLookupNode(), method, newUninitializedDispatch);
-            }
-
-            replace(newDispatch, "appending new boxed dispatch node to chain");
-
-            return newDispatch.dispatch(frame, receiverObject, blockObject, argumentsObjects);
-        }
-    }
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/cast/BooleanCastNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,60 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.cast;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.dsl.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-
-/**
- * Casts a value into a boolean. Works at the language level, so doesn't call any Ruby methods to
- * cast non-core or monkey-patched objects.
- */
-@NodeInfo(shortName = "cast-boolean")
-@NodeChild(value = "child", type = RubyNode.class)
-public abstract class BooleanCastNode extends RubyNode {
-
-    public BooleanCastNode(RubyContext context, SourceSection sourceSection) {
-        super(context, sourceSection);
-    }
-
-    public BooleanCastNode(BooleanCastNode copy) {
-        super(copy.getContext(), copy.getSourceSection());
-    }
-
-    @Specialization
-    public boolean doBoolean(boolean value) {
-        return value;
-    }
-
-    @Specialization
-    public boolean doNil(@SuppressWarnings("unused") NilPlaceholder nil) {
-        return false;
-    }
-
-    @Generic
-    public boolean doGeneric(Object object) {
-        if (object instanceof Boolean) {
-            return (boolean) object;
-        } else if (object instanceof NilPlaceholder || object instanceof RubyNilClass) {
-            return false;
-        } else {
-            return true;
-        }
-    }
-
-    @Override
-    public abstract boolean executeBoolean(VirtualFrame frame);
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/cast/LambdaNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,40 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.cast;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-import com.oracle.truffle.ruby.runtime.methods.*;
-
-@NodeInfo(shortName = "lambda")
-public class LambdaNode extends RubyNode {
-
-    @Child private RubyNode definition;
-
-    public LambdaNode(RubyContext context, SourceSection sourceSection, RubyNode definition) {
-        super(context, sourceSection);
-        this.definition = adoptChild(definition);
-    }
-
-    @Override
-    public Object execute(VirtualFrame frame) {
-        return new RubyProc(getContext().getCoreLibrary().getProcClass(), RubyProc.Type.LAMBDA, frame.getArguments(RubyArguments.class).getSelf(), null, (RubyMethod) definition.execute(frame));
-    }
-
-    @Override
-    public void executeVoid(VirtualFrame frame) {
-        definition.executeVoid(frame);
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/cast/ProcCastNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,56 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.cast;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.dsl.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.nodes.call.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-import com.oracle.truffle.ruby.runtime.objects.*;
-
-/**
- * Casts an object to a Ruby Proc object.
- */
-@NodeInfo(shortName = "cast-proc")
-@NodeChild("child")
-public abstract class ProcCastNode extends RubyNode {
-
-    @Child protected DispatchHeadNode toProc;
-
-    public ProcCastNode(RubyContext context, SourceSection sourceSection) {
-        super(context, sourceSection);
-        toProc = adoptChild(new DispatchHeadNode(context, getSourceSection(), "to_proc", false));
-    }
-
-    public ProcCastNode(ProcCastNode prev) {
-        super(prev);
-        toProc = adoptChild(prev.toProc);
-    }
-
-    @Specialization
-    public NilPlaceholder doNil(NilPlaceholder nil) {
-        return nil;
-    }
-
-    @Specialization
-    public RubyProc doRubyProc(RubyProc proc) {
-        return proc;
-    }
-
-    @Specialization
-    public RubyProc doObject(VirtualFrame frame, RubyBasicObject object) {
-        return (RubyProc) toProc.dispatch(frame, object, null);
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/cast/SplatCastNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,56 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.cast;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.dsl.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.array.*;
-
-/**
- * Splat as used to cast a value to an array if it isn't already, as in {@code *value}.
- */
-@NodeInfo(shortName = "cast-splat")
-@NodeChild("child")
-public abstract class SplatCastNode extends RubyNode {
-
-    public SplatCastNode(RubyContext context, SourceSection sourceSection) {
-        super(context, sourceSection);
-    }
-
-    public SplatCastNode(SplatCastNode prev) {
-        super(prev);
-    }
-
-    protected abstract RubyNode getChild();
-
-    @Specialization
-    public RubyArray doArray(RubyArray array) {
-        return array;
-    }
-
-    @Specialization
-    public RubyArray doObject(Object object) {
-        if (object instanceof RubyArray) {
-            return (RubyArray) object;
-        } else {
-            return RubyArray.specializedFromObject(getContext().getCoreLibrary().getArrayClass(), object);
-        }
-    }
-
-    @Override
-    public void executeVoid(VirtualFrame frame) {
-        getChild().executeVoid(frame);
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/cast/StringToRegexpNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.cast;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.dsl.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-
-/**
- * Creates a regex from a string.
- */
-@NodeInfo(shortName = "cast-string-to-regexp")
-@NodeChild("string")
-public abstract class StringToRegexpNode extends RubyNode {
-
-    public StringToRegexpNode(RubyContext context, SourceSection sourceSection) {
-        super(context, sourceSection);
-    }
-
-    public StringToRegexpNode(StringToRegexpNode prev) {
-        super(prev);
-    }
-
-    @Specialization
-    public RubyRegexp doString(RubyString string) {
-        return new RubyRegexp(getContext().getCoreLibrary().getRegexpClass(), string.toString());
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/cast/StringToSymbolNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.cast;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.dsl.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-
-/**
- * Creates a symbol from a string.
- */
-@NodeInfo(shortName = "cast-string-to-symbol")
-@NodeChild("string")
-public abstract class StringToSymbolNode extends RubyNode {
-
-    public StringToSymbolNode(RubyContext context, SourceSection sourceSection) {
-        super(context, sourceSection);
-    }
-
-    public StringToSymbolNode(StringToSymbolNode prev) {
-        super(prev);
-    }
-
-    @Specialization
-    public RubySymbol doString(RubyString string) {
-        return new RubySymbol(getContext().getCoreLibrary().getSymbolClass(), string.toString());
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/constants/CachedReadConstantNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,177 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.constants;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.api.utilities.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-import com.oracle.truffle.ruby.runtime.objects.*;
-
-/**
- * Represents a constant read from some object and cached, with the assumption that the object it
- * was read from is unmodified. If that assumption does not hold the read is uninitialized. If the
- * class of the receiver changes we also uninitialize.
- */
-@NodeInfo(shortName = "cached-read-constant")
-public class CachedReadConstantNode extends ReadConstantNode {
-
-    private final RubyClass expectedClass;
-    private final Assumption unmodifiedAssumption;
-
-    private final Object value;
-
-    private final boolean hasBoolean;
-    private final boolean booleanValue;
-
-    private final boolean hasInt;
-    private final int intValue;
-
-    private final boolean hasDouble;
-    private final double doubleValue;
-
-    private final BranchProfile boxBranchProfile = new BranchProfile();
-
-    public CachedReadConstantNode(RubyContext context, SourceSection sourceSection, String name, RubyNode receiver, RubyClass expectedClass, Object value) {
-        super(context, sourceSection, name, receiver);
-
-        this.expectedClass = expectedClass;
-        unmodifiedAssumption = expectedClass.getUnmodifiedAssumption();
-
-        this.value = value;
-
-        /*
-         * We could do this lazily as needed, but I'm sure the compiler will appreciate the fact
-         * that these fields are all final.
-         */
-
-        if (value instanceof Boolean) {
-            hasBoolean = true;
-            booleanValue = (boolean) value;
-
-            hasInt = false;
-            intValue = -1;
-
-            hasDouble = false;
-            doubleValue = -1;
-        } else if (value instanceof Integer) {
-            hasBoolean = false;
-            booleanValue = false;
-
-            hasInt = true;
-            intValue = (int) value;
-
-            hasDouble = true;
-            doubleValue = (int) value;
-        } else if (value instanceof Double) {
-            hasBoolean = false;
-            booleanValue = false;
-
-            hasInt = false;
-            intValue = -1;
-
-            hasDouble = true;
-            doubleValue = (double) value;
-        } else {
-            hasBoolean = false;
-            booleanValue = false;
-
-            hasInt = false;
-            intValue = -1;
-
-            hasDouble = false;
-            doubleValue = -1;
-        }
-    }
-
-    @Override
-    public Object execute(VirtualFrame frame) {
-        try {
-            guard(frame);
-        } catch (UnexpectedResultException e) {
-            return e.getResult();
-        }
-
-        return value;
-    }
-
-    @Override
-    public boolean executeBoolean(VirtualFrame frame) throws UnexpectedResultException {
-        guard(frame);
-
-        if (hasBoolean) {
-            return booleanValue;
-        } else {
-            throw new UnexpectedResultException(value);
-        }
-    }
-
-    @Override
-    public int executeFixnum(VirtualFrame frame) throws UnexpectedResultException {
-        guard(frame);
-
-        if (hasInt) {
-            return intValue;
-        } else {
-            throw new UnexpectedResultException(value);
-        }
-    }
-
-    @Override
-    public double executeFloat(VirtualFrame frame) throws UnexpectedResultException {
-        guard(frame);
-
-        if (hasDouble) {
-            return doubleValue;
-        } else {
-            throw new UnexpectedResultException(value);
-        }
-    }
-
-    @Override
-    public void executeVoid(VirtualFrame frame) {
-    }
-
-    public void guard(VirtualFrame frame) throws UnexpectedResultException {
-        final RubyContext context = getContext();
-
-        final Object receiverObject = receiver.execute(frame);
-
-        RubyBasicObject receiverRubyObject;
-
-        // TODO(CS): put the boxing into a separate node that can specialize for each type it sees
-
-        if (receiverObject instanceof RubyBasicObject) {
-            receiverRubyObject = (RubyBasicObject) receiverObject;
-        } else {
-            boxBranchProfile.enter();
-            receiverRubyObject = context.getCoreLibrary().box(receiverObject);
-        }
-
-        if (receiverRubyObject.getRubyClass() != expectedClass) {
-            CompilerDirectives.transferToInterpreter();
-            throw new UnexpectedResultException(uninitialize(receiverRubyObject));
-        }
-
-        try {
-            unmodifiedAssumption.check();
-        } catch (InvalidAssumptionException e) {
-            throw new UnexpectedResultException(uninitialize(receiverRubyObject));
-        }
-    }
-
-    private Object uninitialize(RubyBasicObject receiverObject) {
-        return replace(new UninitializedReadConstantNode(getContext(), getSourceSection(), name, receiver)).execute(receiverObject);
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/constants/ReadConstantNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,64 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.constants;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.control.*;
-
-public abstract class ReadConstantNode extends RubyNode {
-
-    protected final String name;
-    @Child protected RubyNode receiver;
-
-    public ReadConstantNode(RubyContext context, SourceSection sourceSection, String name, RubyNode receiver) {
-        super(context, sourceSection);
-        this.name = name;
-        this.receiver = adoptChild(receiver);
-    }
-
-    @Override
-    public Object isDefined(VirtualFrame frame) {
-        final RubyContext context = getContext();
-
-        if (name.equals("Encoding")) {
-            /*
-             * Work-around so I don't have to load the iconv library - runners/formatters/junit.rb.
-             */
-            return context.makeString("constant");
-        }
-
-        Object value;
-
-        try {
-            value = context.getCoreLibrary().box(receiver.execute(frame)).getLookupNode().lookupConstant(name);
-        } catch (RaiseException e) {
-            /*
-             * If we are looking up a constant in a constant that is itself undefined, we return Nil
-             * rather than raising the error. Eg.. defined?(Defined::Undefined1::Undefined2)
-             */
-
-            if (e.getRubyException().getRubyClass() == context.getCoreLibrary().getNameErrorClass()) {
-                return NilPlaceholder.INSTANCE;
-            }
-
-            throw e;
-        }
-
-        if (value == null) {
-            return NilPlaceholder.INSTANCE;
-        } else {
-            return context.makeString("constant");
-        }
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/constants/UninitializedReadConstantNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,78 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.constants;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.control.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-import com.oracle.truffle.ruby.runtime.objects.*;
-
-/**
- * Represents an uninitialized constant read from some object. After the first read it will be
- * specialized to some other node. This is the starting point for all constant reads.
- */
-@NodeInfo(shortName = "uninitialized-read-constant")
-public class UninitializedReadConstantNode extends ReadConstantNode {
-
-    public UninitializedReadConstantNode(RubyContext context, SourceSection sourceSection, String name, RubyNode receiver) {
-        super(context, sourceSection, name, receiver);
-    }
-
-    /**
-     * This execute method allows us to pass in the already executed receiver object, so that during
-     * uninitialization it is not executed once by the specialized node and again by this node.
-     */
-    public Object execute(RubyBasicObject receiverObject) {
-        CompilerAsserts.neverPartOfCompilation();
-
-        final RubyContext context = receiverObject.getRubyClass().getContext();
-
-        Object value;
-
-        value = receiverObject.getLookupNode().lookupConstant(name);
-
-        if (value == null && receiverObject instanceof RubyModule) {
-            /*
-             * FIXME(CS): I'm obviously doing something wrong with constant lookup in nested modules
-             * here, but explicitly looking in the Module itself, not its lookup node, seems to fix
-             * it for now.
-             */
-
-            value = ((RubyModule) receiverObject).lookupConstant(name);
-        }
-
-        if (value == null) {
-            throw new RaiseException(context.getCoreLibrary().nameErrorUninitializedConstant(name));
-        }
-
-        replace(new CachedReadConstantNode(context, getSourceSection(), name, receiver, receiverObject.getRubyClass(), value));
-
-        assert RubyContext.shouldObjectBeVisible(value);
-
-        return value;
-    }
-
-    @Override
-    public Object execute(VirtualFrame frame) {
-        CompilerDirectives.transferToInterpreter();
-
-        final RubyContext context = getContext();
-
-        final Object receiverObject = receiver.execute(frame);
-        final RubyBasicObject receiverRubyObject = context.getCoreLibrary().box(receiverObject);
-
-        return execute(receiverRubyObject);
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/constants/WriteConstantNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.constants;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-
-/**
- * Represents writing a constant into some module.
- */
-@NodeInfo(shortName = "write-constant")
-public class WriteConstantNode extends RubyNode {
-
-    private final String name;
-    @Child protected RubyNode module;
-    @Child protected RubyNode rhs;
-
-    public WriteConstantNode(RubyContext context, SourceSection sourceSection, String name, RubyNode module, RubyNode rhs) {
-        super(context, sourceSection);
-        this.name = name;
-        this.module = adoptChild(module);
-        this.rhs = adoptChild(rhs);
-    }
-
-    @Override
-    public Object execute(VirtualFrame frame) {
-        // TODO(cs): can module ever not evaluate to a RubyModule?
-
-        final RubyModule moduleObject = (RubyModule) module.execute(frame);
-
-        final Object rhsValue = rhs.execute(frame);
-
-        assert rhsValue != null;
-        assert !(rhsValue instanceof String);
-
-        moduleObject.setModuleConstant(name, rhsValue);
-
-        return rhsValue;
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/control/AndNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,58 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.control;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.dsl.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-
-/**
- * Represents a Ruby {@code and} or {@code &&} expression.
- */
-@NodeInfo(shortName = "and")
-@NodeChildren({@NodeChild("left"), @NodeChild("right")})
-public abstract class AndNode extends RubyNode {
-
-    public AndNode(RubyContext context, SourceSection sourceSection) {
-        super(context, sourceSection);
-    }
-
-    public AndNode(AndNode copy) {
-        super(copy.getContext(), copy.getSourceSection());
-    }
-
-    @ShortCircuit("right")
-    public boolean needsRightNode(Object a) {
-        return GeneralConversions.toBoolean(a);
-    }
-
-    @ShortCircuit("right")
-    public boolean needsRightNode(boolean a) {
-        return a;
-    }
-
-    @Specialization
-    public boolean doBoolean(boolean a, boolean hasB, boolean b) {
-        return hasB ? b : a;
-    }
-
-    @Specialization
-    public Object doObject(boolean a, boolean hasB, Object b) {
-        return hasB ? b : a;
-    }
-
-    @Generic
-    public Object doGeneric(Object a, boolean hasB, Object b) {
-        return hasB ? b : a;
-    }
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/control/BreakNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.control;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.nodes.literal.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.control.*;
-
-@NodeInfo(shortName = "break")
-public class BreakNode extends RubyNode {
-
-    @Child private RubyNode child;
-
-    public BreakNode(RubyContext context, SourceSection sourceSection, RubyNode child) {
-        super(context, sourceSection);
-        this.child = adoptChild(child);
-    }
-
-    @Override
-    public Object execute(VirtualFrame frame) {
-        if (child instanceof NilNode) {
-            throw BreakException.NIL;
-        } else {
-            throw new BreakException(child.execute(frame));
-        }
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/control/ElidableResultNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,65 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.control;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-
-/**
- * This node has a pair of children - one required and one elidable result. The required node is
- * always executed, but its result is discarded. Therefore it should perform some useful side
- * effects. The elidable node is executed, and its result value returned, if an execute method with
- * a non-void type is used. It is not executed at all if a void typed execute method is used.
- * Therefore it should not perform any observable side effects.
- */
-@NodeInfo(shortName = "elidable-result")
-public class ElidableResultNode extends RubyNode {
-
-    @Child protected RubyNode required;
-    @Child protected RubyNode elidableResult;
-
-    public ElidableResultNode(RubyContext context, SourceSection sourceSection, RubyNode required, RubyNode elidableResult) {
-        super(context, sourceSection);
-        this.required = adoptChild(required);
-        this.elidableResult = adoptChild(elidableResult);
-    }
-
-    @Override
-    public int executeFixnum(VirtualFrame frame) throws UnexpectedResultException {
-        required.executeVoid(frame);
-        return elidableResult.executeFixnum(frame);
-    }
-
-    @Override
-    public double executeFloat(VirtualFrame frame) throws UnexpectedResultException {
-        required.executeVoid(frame);
-        return elidableResult.executeFloat(frame);
-    }
-
-    @Override
-    public Object execute(VirtualFrame frame) {
-        required.executeVoid(frame);
-        return elidableResult.execute(frame);
-    }
-
-    @Override
-    public void executeVoid(VirtualFrame frame) {
-        required.execute(frame);
-    }
-
-    @Override
-    public Object isDefined(VirtualFrame frame) {
-        return elidableResult.isDefined(frame);
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/control/EnsureNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /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. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.control;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-
-/**
- * Represents an ensure clause in exception handling. Represented separately to the try part.
- */
-@NodeInfo(shortName = "ensure")
-public class EnsureNode extends RubyNode {
-
-    @Child protected RubyNode tryPart;
-    @Child protected RubyNode ensurePart;
-
-    public EnsureNode(RubyContext context, SourceSection sourceSection, RubyNode tryPart, RubyNode ensurePart) {
-        super(context, sourceSection);
-        this.tryPart = adoptChild(tryPart);
-        this.ensurePart = adoptChild(ensurePart);
-    }
-
-    @Override
-    public Object execute(VirtualFrame frame) {
-        try {
-            return tryPart.execute(frame);
-        } finally {
-            ensurePart.executeVoid(frame);
-        }
-    }
-
-    @Override
-    public void executeVoid(VirtualFrame frame) {
-        try {
-            tryPart.executeVoid(frame);
-        } finally {
-            ensurePart.executeVoid(frame);
-        }
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/control/FlipFlopNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,74 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.control;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.nodes.cast.*;
-import com.oracle.truffle.ruby.nodes.methods.locals.*;
-import com.oracle.truffle.ruby.runtime.*;
-
-@NodeInfo(shortName = "flip-flop")
-public class FlipFlopNode extends RubyNode {
-
-    @Child protected BooleanCastNode begin;
-    @Child protected BooleanCastNode end;
-    @Child protected FlipFlopStateNode stateNode;
-
-    private final boolean exclusive;
-
-    public FlipFlopNode(RubyContext context, SourceSection sourceSection, BooleanCastNode begin, BooleanCastNode end, FlipFlopStateNode stateNode, boolean exclusive) {
-        super(context, sourceSection);
-        this.begin = adoptChild(begin);
-        this.end = adoptChild(end);
-        this.stateNode = adoptChild(stateNode);
-        this.exclusive = exclusive;
-    }
-
-    @Override
-    public boolean executeBoolean(VirtualFrame frame) {
-        if (exclusive) {
-            if (stateNode.getState(frame)) {
-                if (end.executeBoolean(frame)) {
-                    stateNode.setState(frame, false);
-                }
-
-                return true;
-            } else {
-                final boolean newState = begin.executeBoolean(frame);
-                stateNode.setState(frame, newState);
-                return newState;
-            }
-        } else {
-            if (stateNode.getState(frame)) {
-                if (end.executeBoolean(frame)) {
-                    stateNode.setState(frame, false);
-                }
-
-                return true;
-            } else {
-                if (begin.executeBoolean(frame)) {
-                    stateNode.setState(frame, !end.executeBoolean(frame));
-                    return true;
-                }
-
-                return false;
-            }
-        }
-    }
-
-    @Override
-    public Object execute(VirtualFrame frame) {
-        return executeBoolean(frame);
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/control/IfNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.control;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.api.utilities.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.nodes.cast.*;
-import com.oracle.truffle.ruby.runtime.*;
-
-/**
- * Represents a Ruby {@code if} expression. Note that in this representation we always have an
- * {@code else} part.
- */
-@NodeInfo(shortName = "if")
-public class IfNode extends RubyNode {
-
-    @Child protected BooleanCastNode condition;
-    @Child protected RubyNode thenBody;
-    @Child protected RubyNode elseBody;
-
-    private final BranchProfile thenProfile = new BranchProfile();
-    private final BranchProfile elseProfile = new BranchProfile();
-
-    public IfNode(RubyContext context, SourceSection sourceSection, BooleanCastNode condition, RubyNode thenBody, RubyNode elseBody) {
-        super(context, sourceSection);
-        this.condition = adoptChild(condition);
-        this.thenBody = adoptChild(thenBody);
-        this.elseBody = adoptChild(elseBody);
-    }
-
-    @Override
-    public Object execute(VirtualFrame frame) {
-        if (condition.executeBoolean(frame)) {
-            thenProfile.enter();
-            return thenBody.execute(frame);
-        } else {
-            elseProfile.enter();
-            return elseBody.execute(frame);
-        }
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/control/NextNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.control;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.nodes.literal.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.control.*;
-
-@NodeInfo(shortName = "next")
-public class NextNode extends RubyNode {
-
-    @Child private RubyNode child;
-
-    public NextNode(RubyContext context, SourceSection sourceSection, RubyNode child) {
-        super(context, sourceSection);
-
-        this.child = adoptChild(child);
-    }
-
-    @Override
-    public Object execute(VirtualFrame frame) {
-        if (child instanceof NilNode) {
-            throw NextException.NIL;
-        } else {
-            throw new NextException(child.execute(frame));
-        }
-    }
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/control/NotNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,42 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.control;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.nodes.cast.*;
-import com.oracle.truffle.ruby.runtime.*;
-
-/**
- * Represents a Ruby {@code not} or {@code !} expression.
- */
-@NodeInfo(shortName = "not")
-public class NotNode extends RubyNode {
-
-    @Child protected BooleanCastNode child;
-
-    public NotNode(RubyContext context, SourceSection sourceSection, BooleanCastNode child) {
-        super(context, sourceSection);
-        this.child = adoptChild(child);
-    }
-
-    @Override
-    public boolean executeBoolean(VirtualFrame frame) {
-        return !child.executeBoolean(frame);
-    }
-
-    @Override
-    public Object execute(VirtualFrame frame) {
-        return executeBoolean(frame);
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/control/OrNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,54 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.control;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.dsl.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-
-/**
- * Represents a Ruby {@code or} or {@code ||} expression.
- */
-@NodeInfo(shortName = "or")
-@NodeChildren({@NodeChild("left"), @NodeChild("right")})
-public abstract class OrNode extends RubyNode {
-
-    public OrNode(RubyContext context, SourceSection sourceSection) {
-        super(context, sourceSection);
-    }
-
-    public OrNode(OrNode copy) {
-        super(copy.getContext(), copy.getSourceSection());
-    }
-
-    @ShortCircuit("right")
-    public boolean needsRightNode(Object a) {
-        return !GeneralConversions.toBoolean(a);
-    }
-
-    @ShortCircuit("right")
-    public boolean needsRightNode(boolean a) {
-        return !a;
-    }
-
-    @Specialization
-    public Object doBoolean(boolean a, boolean hasB, Object b) {
-        return hasB ? b : a;
-    }
-
-    @Generic
-    public Object doGeneric(Object a, boolean hasB, Object b) {
-        return hasB ? b : a;
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/control/RedoNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /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. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.control;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.control.*;
-
-@NodeInfo(shortName = "redo")
-public class RedoNode extends RubyNode {
-
-    public RedoNode(RubyContext context, SourceSection sourceSection) {
-        super(context, sourceSection);
-    }
-
-    @Override
-    public Object execute(VirtualFrame frame) {
-        throw new RedoException();
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/control/RescueAnyNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,34 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.control;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.objects.*;
-
-/**
- * Rescues any exception.
- */
-@NodeInfo(shortName = "rescue-any")
-public class RescueAnyNode extends RescueNode {
-
-    public RescueAnyNode(RubyContext context, SourceSection sourceSection, RubyNode body) {
-        super(context, sourceSection, body);
-    }
-
-    @Override
-    public boolean canHandle(VirtualFrame frame, RubyBasicObject exception) {
-        return true;
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/control/RescueClassesNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,50 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.control;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-import com.oracle.truffle.ruby.runtime.objects.*;
-
-/**
- * Rescues any of a set of classes.
- */
-@NodeInfo(shortName = "rescue-classes")
-public class RescueClassesNode extends RescueNode {
-
-    @Children final RubyNode[] handlingClassNodes;
-
-    public RescueClassesNode(RubyContext context, SourceSection sourceSection, RubyNode[] handlingClassNodes, RubyNode body) {
-        super(context, sourceSection, body);
-        this.handlingClassNodes = adoptChildren(handlingClassNodes);
-    }
-
-    @ExplodeLoop
-    @Override
-    public boolean canHandle(VirtualFrame frame, RubyBasicObject exception) {
-        final RubyClass exceptionRubyClass = exception.getRubyClass();
-
-        for (RubyNode handlingClassNode : handlingClassNodes) {
-            // TODO(CS): what if we don't get a class?
-
-            final RubyClass handlingClass = (RubyClass) handlingClassNode.execute(frame);
-
-            if (exceptionRubyClass.assignableTo(handlingClass)) {
-                return true;
-            }
-        }
-
-        return false;
-    }
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/control/RescueNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,43 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.control;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.objects.*;
-
-/**
- * Base node for all nodes which may be able to rescue an exception. They have a test method
- * {@link #canHandle} and a body to execute if that test passes.
- */
-public abstract class RescueNode extends RubyNode {
-
-    @Child protected RubyNode body;
-
-    public RescueNode(RubyContext context, SourceSection sourceSection, RubyNode body) {
-        super(context, sourceSection);
-        this.body = adoptChild(body);
-    }
-
-    public abstract boolean canHandle(VirtualFrame frame, RubyBasicObject exception);
-
-    @Override
-    public Object execute(VirtualFrame frame) {
-        return body.execute(frame);
-    }
-
-    @Override
-    public void executeVoid(VirtualFrame frame) {
-        body.executeVoid(frame);
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/control/RescueSplatNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.control;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-import com.oracle.truffle.ruby.runtime.core.array.*;
-import com.oracle.truffle.ruby.runtime.objects.*;
-
-/**
- * Rescue any of several classes, that we get from an expression that evaluates to an array of
- * classes.
- * 
- */
-@NodeInfo(shortName = "rescue-splat")
-public class RescueSplatNode extends RescueNode {
-
-    @Child RubyNode handlingClassesArray;
-
-    public RescueSplatNode(RubyContext context, SourceSection sourceSection, RubyNode handlingClassesArray, RubyNode body) {
-        super(context, sourceSection, body);
-        this.handlingClassesArray = adoptChild(handlingClassesArray);
-    }
-
-    @ExplodeLoop
-    @Override
-    public boolean canHandle(VirtualFrame frame, RubyBasicObject exception) {
-        final RubyArray handlingClasses = (RubyArray) handlingClassesArray.execute(frame);
-
-        final RubyClass exceptionRubyClass = exception.getRubyClass();
-
-        for (Object handlingClass : handlingClasses.asList()) {
-            if (exceptionRubyClass.assignableTo((RubyClass) handlingClass)) {
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/control/RetryNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /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. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.control;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.control.*;
-
-@NodeInfo(shortName = "retry")
-public class RetryNode extends RubyNode {
-
-    public RetryNode(RubyContext context, SourceSection sourceSection) {
-        super(context, sourceSection);
-    }
-
-    @Override
-    public Object execute(VirtualFrame frame) {
-        throw new RetryException();
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/control/ReturnNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.control;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.control.*;
-
-/**
- * Represents an explicit return. The return ID indicates where we should be returning to - this can
- * be non-trivial if you have blocks.
- */
-@NodeInfo(shortName = "return")
-public class ReturnNode extends RubyNode {
-
-    private final long returnID;
-    @Child protected RubyNode value;
-
-    public ReturnNode(RubyContext context, SourceSection sourceSection, long returnID, RubyNode value) {
-        super(context, sourceSection);
-        this.returnID = returnID;
-        this.value = adoptChild(value);
-    }
-
-    @Override
-    public Object execute(VirtualFrame frame) {
-        throw new ReturnException(returnID, value.execute(frame));
-    }
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/control/SequenceNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,49 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.control;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-
-/**
- * A sequence of statements to be executed in serial.
- */
-@NodeInfo(shortName = "sequence")
-public final class SequenceNode extends RubyNode {
-
-    @Children protected final RubyNode[] body;
-
-    public SequenceNode(RubyContext context, SourceSection sourceSection, RubyNode... body) {
-        super(context, sourceSection);
-        this.body = adoptChildren(body);
-    }
-
-    @ExplodeLoop
-    @Override
-    public Object execute(VirtualFrame frame) {
-        for (int n = 0; n < body.length - 1; n++) {
-            body[n].executeVoid(frame);
-        }
-
-        return body[body.length - 1].execute(frame);
-    }
-
-    @ExplodeLoop
-    @Override
-    public void executeVoid(VirtualFrame frame) {
-        for (int n = 0; n < body.length; n++) {
-            body[n].executeVoid(frame);
-        }
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/control/TryNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,82 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.control;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.api.utilities.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.control.*;
-import com.oracle.truffle.ruby.runtime.objects.*;
-
-/**
- * Represents a block of code run with exception handlers. There's no {@code try} keyword in Ruby -
- * it's implicit - but it's similar to a try statement in any other language.
- */
-@NodeInfo(shortName = "try")
-public class TryNode extends RubyNode {
-
-    @Child protected RubyNode tryPart;
-    @Children final RescueNode[] rescueParts;
-    @Child protected RubyNode elsePart;
-
-    private final BranchProfile controlFlowProfile = new BranchProfile();
-
-    public TryNode(RubyContext context, SourceSection sourceSection, RubyNode tryPart, RescueNode[] rescueParts, RubyNode elsePart) {
-        super(context, sourceSection);
-        this.tryPart = adoptChild(tryPart);
-        this.rescueParts = adoptChildren(rescueParts);
-        this.elsePart = adoptChild(elsePart);
-    }
-
-    @Override
-    public Object execute(VirtualFrame frame) {
-        while (true) {
-            try {
-                final Object result = tryPart.execute(frame);
-                elsePart.executeVoid(frame);
-                return result;
-            } catch (ControlFlowException exception) {
-                controlFlowProfile.enter();
-
-                throw exception;
-            } catch (RuntimeException exception) {
-                CompilerDirectives.transferToInterpreter();
-
-                try {
-                    return handleException(frame, exception);
-                } catch (RetryException e) {
-                    continue;
-                }
-            }
-        }
-    }
-
-    private Object handleException(VirtualFrame frame, RuntimeException exception) {
-        CompilerAsserts.neverPartOfCompilation();
-
-        final RubyContext context = getContext();
-
-        final RubyBasicObject rubyException = ExceptionTranslator.translateException(context, exception);
-
-        context.getCoreLibrary().getGlobalVariablesObject().setInstanceVariable("$!", rubyException);
-
-        for (RescueNode rescue : rescueParts) {
-            if (rescue.canHandle(frame, rubyException)) {
-                return rescue.execute(frame);
-            }
-        }
-
-        throw exception;
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/control/WhileNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,62 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.control;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.api.utilities.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.nodes.cast.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.control.*;
-
-/**
- * Represents a Ruby {@code while} statement.
- */
-@NodeInfo(shortName = "while")
-public class WhileNode extends RubyNode {
-
-    @Child protected BooleanCastNode condition;
-    @Child protected RubyNode body;
-
-    private final BranchProfile breakProfile = new BranchProfile();
-    private final BranchProfile nextProfile = new BranchProfile();
-    private final BranchProfile redoProfile = new BranchProfile();
-
-    public WhileNode(RubyContext context, SourceSection sourceSection, BooleanCastNode condition, RubyNode body) {
-        super(context, sourceSection);
-        this.condition = adoptChild(condition);
-        this.body = adoptChild(body);
-    }
-
-    @Override
-    public Object execute(VirtualFrame frame) {
-        outer: while (condition.executeBoolean(frame)) {
-            while (true) {
-                try {
-                    body.execute(frame);
-                    continue outer;
-                } catch (BreakException e) {
-                    breakProfile.enter();
-                    return e.getResult();
-                } catch (NextException e) {
-                    nextProfile.enter();
-                    continue outer;
-                } catch (RedoException e) {
-                    redoProfile.enter();
-                }
-            }
-        }
-
-        return NilPlaceholder.INSTANCE;
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/ArrayConcatNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,61 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.core;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.array.*;
-
-/**
- * Concatenate arrays.
- */
-@NodeInfo(shortName = "array-concat")
-public final class ArrayConcatNode extends RubyNode {
-
-    @Children protected final RubyNode[] children;
-
-    public ArrayConcatNode(RubyContext context, SourceSection sourceSection, RubyNode[] children) {
-        super(context, sourceSection);
-        assert children.length > 1;
-        this.children = adoptChildren(children);
-    }
-
-    @ExplodeLoop
-    @Override
-    public Object execute(VirtualFrame frame) {
-        final RubyArray array = new RubyArray(getContext().getCoreLibrary().getArrayClass());
-
-        for (int n = 0; n < children.length; n++) {
-            final Object childObject = children[n].execute(frame);
-
-            if (childObject instanceof RubyArray) {
-                // setRangeArray has special cases for setting a zero-length range at the end
-                final int end = array.size();
-                array.setRangeArrayExclusive(end, end, (RubyArray) childObject);
-            } else {
-                array.push(childObject);
-            }
-        }
-
-        return array;
-    }
-
-    @ExplodeLoop
-    @Override
-    public void executeVoid(VirtualFrame frame) {
-        for (int n = 0; n < children.length; n++) {
-            children[n].executeVoid(frame);
-        }
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/ArrayCoreMethodNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,46 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.core;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.array.*;
-
-public abstract class ArrayCoreMethodNode extends CoreMethodNode {
-
-    public ArrayCoreMethodNode(RubyContext context, SourceSection sourceSection) {
-        super(context, sourceSection);
-    }
-
-    public ArrayCoreMethodNode(ArrayCoreMethodNode prev) {
-        super(prev);
-    }
-
-    protected boolean isEmptyStore(RubyArray receiver) {
-        return receiver.getArrayStore() instanceof EmptyArrayStore;
-    }
-
-    protected boolean isFixnumStore(RubyArray receiver) {
-        return receiver.getArrayStore() instanceof FixnumArrayStore;
-    }
-
-    protected boolean isFixnumImmutablePairStore(RubyArray receiver) {
-        return receiver.getArrayStore() instanceof FixnumImmutablePairArrayStore;
-    }
-
-    protected boolean isObjectStore(RubyArray receiver) {
-        return receiver.getArrayStore() instanceof ObjectArrayStore;
-    }
-
-    protected boolean isObjectImmutablePairStore(RubyArray receiver) {
-        return receiver.getArrayStore() instanceof ObjectImmutablePairArrayStore;
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/ArrayIndexNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,110 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.core;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.dsl.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.array.*;
-
-/**
- * Index an array, without using any method lookup. This isn't a call - it's an operation on a core
- * class.
- */
-@NodeInfo(shortName = "array-index")
-@NodeChildren({@NodeChild(value = "array", type = RubyNode.class)})
-public abstract class ArrayIndexNode extends RubyNode {
-
-    final int index;
-
-    public ArrayIndexNode(RubyContext context, SourceSection sourceSection, int index) {
-        super(context, sourceSection);
-        this.index = index;
-    }
-
-    public ArrayIndexNode(ArrayIndexNode prev) {
-        super(prev);
-        index = prev.index;
-    }
-
-    @Specialization(guards = "isEmptyStore", order = 1)
-    public NilPlaceholder indexEmpty(@SuppressWarnings("unused") RubyArray array) {
-        return NilPlaceholder.INSTANCE;
-    }
-
-    @Specialization(guards = "isFixnumStore", rewriteOn = UnexpectedResultException.class, order = 2)
-    public int indexFixnum(RubyArray array) throws UnexpectedResultException {
-        final FixnumArrayStore store = (FixnumArrayStore) array.getArrayStore();
-        return store.getFixnum(ArrayUtilities.normaliseIndex(store.size(), index));
-    }
-
-    @Specialization(guards = "isFixnumStore", order = 3)
-    public Object indexMaybeFixnum(RubyArray array) {
-        final FixnumArrayStore store = (FixnumArrayStore) array.getArrayStore();
-
-        try {
-            return store.getFixnum(ArrayUtilities.normaliseIndex(store.size(), index));
-        } catch (UnexpectedResultException e) {
-            return e.getResult();
-        }
-    }
-
-    @Specialization(guards = "isFixnumImmutablePairStore", rewriteOn = UnexpectedResultException.class, order = 4)
-    public int indexFixnumImmutablePair(RubyArray array) throws UnexpectedResultException {
-        final FixnumImmutablePairArrayStore store = (FixnumImmutablePairArrayStore) array.getArrayStore();
-        return store.getFixnum(ArrayUtilities.normaliseIndex(store.size(), index));
-    }
-
-    @Specialization(guards = "isFixnumImmutablePairStore", order = 5)
-    public Object indexMaybeFixnumImmutablePair(RubyArray array) {
-        final FixnumImmutablePairArrayStore store = (FixnumImmutablePairArrayStore) array.getArrayStore();
-
-        try {
-            return store.getFixnum(ArrayUtilities.normaliseIndex(store.size(), index));
-        } catch (UnexpectedResultException e) {
-            return e.getResult();
-        }
-    }
-
-    @Specialization(guards = "isObjectStore", order = 6)
-    public Object indexObject(RubyArray array) {
-        final ObjectArrayStore store = (ObjectArrayStore) array.getArrayStore();
-        return store.get(ArrayUtilities.normaliseIndex(store.size(), index));
-    }
-
-    @Specialization(guards = "isObjectImmutablePairStore", order = 7)
-    public Object indexObjectImmutablePair(RubyArray array) {
-        final ObjectImmutablePairArrayStore store = (ObjectImmutablePairArrayStore) array.getArrayStore();
-        return store.get(ArrayUtilities.normaliseIndex(store.size(), index));
-    }
-
-    protected boolean isEmptyStore(RubyArray receiver) {
-        return receiver.getArrayStore() instanceof EmptyArrayStore;
-    }
-
-    protected boolean isFixnumStore(RubyArray receiver) {
-        return receiver.getArrayStore() instanceof FixnumArrayStore;
-    }
-
-    protected boolean isFixnumImmutablePairStore(RubyArray receiver) {
-        return receiver.getArrayStore() instanceof FixnumImmutablePairArrayStore;
-    }
-
-    protected boolean isObjectStore(RubyArray receiver) {
-        return receiver.getArrayStore() instanceof ObjectArrayStore;
-    }
-
-    protected boolean isObjectImmutablePairStore(RubyArray receiver) {
-        return receiver.getArrayStore() instanceof ObjectImmutablePairArrayStore;
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/ArrayNodes.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1080 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.core;
-
-import java.util.*;
-
-import com.oracle.truffle.api.CompilerDirectives.SlowPath;
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.dsl.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.api.utilities.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.control.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-import com.oracle.truffle.ruby.runtime.core.array.*;
-import com.oracle.truffle.ruby.runtime.core.range.*;
-import com.oracle.truffle.ruby.runtime.objects.*;
-
-@CoreClass(name = "Array")
-public abstract class ArrayNodes {
-
-    @CoreMethod(names = "+", minArgs = 1, maxArgs = 1)
-    public abstract static class AddNode extends CoreMethodNode {
-
-        public AddNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public AddNode(AddNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public RubyArray equal(RubyArray a, RubyArray b) {
-            final RubyArray result = new RubyArray(getContext().getCoreLibrary().getArrayClass());
-            result.setRangeArrayExclusive(0, 0, a);
-            result.setRangeArrayExclusive(a.size(), a.size(), b);
-            return result;
-        }
-
-    }
-
-    @CoreMethod(names = "-", minArgs = 1, maxArgs = 1)
-    public abstract static class SubNode extends CoreMethodNode {
-
-        public SubNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public SubNode(SubNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public RubyArray equal(RubyArray a, RubyArray b) {
-            return a.relativeComplement(b);
-        }
-
-    }
-
-    @CoreMethod(names = "*", minArgs = 1, maxArgs = 1)
-    public abstract static class MulNode extends CoreMethodNode {
-
-        public MulNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public MulNode(MulNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public RubyArray mul(RubyArray array, int count) {
-            // TODO(CS): use the same storage type
-
-            final RubyArray result = new RubyArray(array.getRubyClass().getContext().getCoreLibrary().getArrayClass());
-
-            for (int n = 0; n < count; n++) {
-                for (int i = 0; i < array.size(); i++) {
-                    result.push(array.get(i));
-                }
-            }
-
-            return result;
-        }
-
-    }
-
-    @CoreMethod(names = "==", minArgs = 1, maxArgs = 1)
-    public abstract static class EqualNode extends CoreMethodNode {
-
-        public EqualNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public EqualNode(EqualNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public boolean equal(RubyArray a, RubyArray b) {
-            // TODO(CS)
-            return a.equals(b);
-        }
-
-    }
-
-    @CoreMethod(names = "[]", minArgs = 1, maxArgs = 2)
-    public abstract static class IndexNode extends ArrayCoreMethodNode {
-
-        public IndexNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public IndexNode(IndexNode prev) {
-            super(prev);
-        }
-
-        @Specialization(guards = "isEmptyStore", order = 1)
-        public NilPlaceholder indexEmpty(@SuppressWarnings("unused") RubyArray array, @SuppressWarnings("unused") int index, @SuppressWarnings("unused") UndefinedPlaceholder unused) {
-            return NilPlaceholder.INSTANCE;
-        }
-
-        @Specialization(guards = "isFixnumStore", rewriteOn = UnexpectedResultException.class, order = 2)
-        public int indexFixnum(RubyArray array, int index, @SuppressWarnings("unused") UndefinedPlaceholder unused) throws UnexpectedResultException {
-            final FixnumArrayStore store = (FixnumArrayStore) array.getArrayStore();
-            return store.getFixnum(ArrayUtilities.normaliseIndex(store.size(), index));
-        }
-
-        @Specialization(guards = "isFixnumStore", order = 3)
-        public Object indexMaybeFixnum(RubyArray array, int index, @SuppressWarnings("unused") UndefinedPlaceholder unused) {
-            final FixnumArrayStore store = (FixnumArrayStore) array.getArrayStore();
-
-            try {
-                return store.getFixnum(ArrayUtilities.normaliseIndex(store.size(), index));
-            } catch (UnexpectedResultException e) {
-                return e.getResult();
-            }
-        }
-
-        @Specialization(guards = "isFixnumImmutablePairStore", rewriteOn = UnexpectedResultException.class, order = 4)
-        public int indexFixnumImmutablePair(RubyArray array, int index, @SuppressWarnings("unused") UndefinedPlaceholder unused) throws UnexpectedResultException {
-            final FixnumImmutablePairArrayStore store = (FixnumImmutablePairArrayStore) array.getArrayStore();
-            return store.getFixnum(ArrayUtilities.normaliseIndex(store.size(), index));
-        }
-
-        @Specialization(guards = "isFixnumImmutablePairStore", order = 5)
-        public Object indexMaybeFixnumImmutablePair(RubyArray array, int index, @SuppressWarnings("unused") UndefinedPlaceholder unused) {
-            final FixnumImmutablePairArrayStore store = (FixnumImmutablePairArrayStore) array.getArrayStore();
-
-            try {
-                return store.getFixnum(ArrayUtilities.normaliseIndex(store.size(), index));
-            } catch (UnexpectedResultException e) {
-                return e.getResult();
-            }
-        }
-
-        @Specialization(guards = "isObjectStore", order = 6)
-        public Object indexObject(RubyArray array, int index, @SuppressWarnings("unused") UndefinedPlaceholder unused) {
-            final ObjectArrayStore store = (ObjectArrayStore) array.getArrayStore();
-            return store.get(ArrayUtilities.normaliseIndex(store.size(), index));
-        }
-
-        @Specialization(guards = "isObjectImmutablePairStore", order = 7)
-        public Object indexObjectImmutablePair(RubyArray array, int index, @SuppressWarnings("unused") UndefinedPlaceholder unused) {
-            final ObjectImmutablePairArrayStore store = (ObjectImmutablePairArrayStore) array.getArrayStore();
-            return store.get(ArrayUtilities.normaliseIndex(store.size(), index));
-        }
-
-        @Specialization(order = 8)
-        public Object indexRange(RubyArray array, int begin, int rangeLength) {
-            final int length = array.size();
-            final int normalisedBegin = ArrayUtilities.normaliseIndex(length, begin);
-            return array.getRangeExclusive(normalisedBegin, normalisedBegin + rangeLength);
-        }
-
-        @Specialization(order = 9)
-        public Object indexRange(RubyArray array, FixnumRange range, @SuppressWarnings("unused") UndefinedPlaceholder unused) {
-            if (range.doesExcludeEnd()) {
-                return array.getRangeExclusive(range.getBegin(), range.getExclusiveEnd());
-            } else {
-                return array.getRangeInclusive(range.getBegin(), range.getInclusiveEnd());
-            }
-        }
-
-    }
-
-    @CoreMethod(names = "[]=", minArgs = 2, maxArgs = 3)
-    public abstract static class IndexSetNode extends ArrayCoreMethodNode {
-
-        public IndexSetNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public IndexSetNode(IndexSetNode prev) {
-            super(prev);
-        }
-
-        @Specialization(guards = "isEmptyStore", order = 1)
-        public Object indexSetEmpty(RubyArray array, int index, Object value, @SuppressWarnings("unused") UndefinedPlaceholder unused) {
-            array.set(index, value);
-            return value;
-        }
-
-        @Specialization(guards = "isFixnumStore", rewriteOn = GeneraliseArrayStoreException.class, order = 2)
-        public int indexSetFixnum(RubyArray array, int index, int value, @SuppressWarnings("unused") UndefinedPlaceholder unused) throws GeneraliseArrayStoreException {
-            final FixnumArrayStore store = (FixnumArrayStore) array.getArrayStore();
-            final int normalisedIndex = ArrayUtilities.normaliseIndex(store.size(), index);
-            store.setFixnum(normalisedIndex, value);
-            return value;
-        }
-
-        @Specialization(guards = "isFixnumStore", order = 3)
-        public int indexSetFixnumMayGeneralise(RubyArray array, int index, int value, @SuppressWarnings("unused") UndefinedPlaceholder unused) {
-            final FixnumArrayStore store = (FixnumArrayStore) array.getArrayStore();
-            final int normalisedIndex = ArrayUtilities.normaliseIndex(store.size(), index);
-
-            try {
-                store.setFixnum(normalisedIndex, value);
-            } catch (GeneraliseArrayStoreException e) {
-                array.set(normalisedIndex, value);
-            }
-
-            return value;
-        }
-
-        @Specialization(guards = "isObjectStore", order = 4)
-        public Object indexSetObject(RubyArray array, int index, Object value, @SuppressWarnings("unused") UndefinedPlaceholder unused) {
-            final ObjectArrayStore store = (ObjectArrayStore) array.getArrayStore();
-            final int normalisedIndex = ArrayUtilities.normaliseIndex(store.size(), index);
-
-            try {
-                store.set(normalisedIndex, value);
-            } catch (GeneraliseArrayStoreException e) {
-                array.set(normalisedIndex, value);
-            }
-
-            return value;
-        }
-
-        @Specialization(order = 5)
-        public RubyArray indexSetRange(RubyArray array, FixnumRange range, RubyArray value, @SuppressWarnings("unused") UndefinedPlaceholder unused) {
-            if (range.doesExcludeEnd()) {
-                array.setRangeArrayExclusive(range.getBegin(), range.getExclusiveEnd(), value);
-            } else {
-                array.setRangeArrayInclusive(range.getBegin(), range.getInclusiveEnd(), value);
-            }
-
-            return value;
-        }
-
-        @Specialization(order = 6)
-        public Object indexSetRange(RubyArray array, FixnumRange range, Object value, @SuppressWarnings("unused") UndefinedPlaceholder unused) {
-            if (range.doesExcludeEnd()) {
-                array.setRangeSingleExclusive(range.getBegin(), range.getExclusiveEnd(), value);
-            } else {
-                array.setRangeSingleInclusive(range.getBegin(), range.getInclusiveEnd(), value);
-            }
-
-            return value;
-        }
-
-        @Specialization(order = 7)
-        public RubyArray indexSetRange(RubyArray array, int begin, int rangeLength, RubyArray value) {
-            array.setRangeArrayExclusive(begin, begin + rangeLength, value);
-            return value;
-        }
-
-        @Specialization(order = 8)
-        public Object indexSetRange(RubyArray array, int begin, int rangeLength, Object value) {
-            if (value instanceof UndefinedPlaceholder) {
-                if (array.getArrayStore() instanceof EmptyArrayStore) {
-                    return indexSetEmpty(array, begin, rangeLength, UndefinedPlaceholder.INSTANCE);
-                } else if (array.getArrayStore() instanceof FixnumArrayStore) {
-                    return indexSetFixnumMayGeneralise(array, begin, rangeLength, UndefinedPlaceholder.INSTANCE);
-                } else {
-                    return indexSetObject(array, begin, rangeLength, UndefinedPlaceholder.INSTANCE);
-                }
-            }
-
-            array.setRangeSingleExclusive(begin, begin + rangeLength, value);
-            return value;
-        }
-
-    }
-
-    @CoreMethod(names = "all?", needsBlock = true, maxArgs = 0)
-    public abstract static class AllNode extends YieldingCoreMethodNode {
-
-        public AllNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public AllNode(AllNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public boolean all(VirtualFrame frame, RubyArray array, RubyProc block) {
-            for (Object value : array.asList()) {
-                if (!yieldBoolean(frame, block, value)) {
-                    return false;
-                }
-            }
-
-            return true;
-        }
-
-    }
-
-    @CoreMethod(names = "any?", needsBlock = true, maxArgs = 0)
-    public abstract static class AnyNode extends YieldingCoreMethodNode {
-
-        public AnyNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public AnyNode(AnyNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public boolean any(VirtualFrame frame, RubyArray array, RubyProc block) {
-            for (Object value : array.asList()) {
-                if (yieldBoolean(frame, block, value)) {
-                    return true;
-                }
-            }
-
-            return false;
-        }
-
-    }
-
-    @CoreMethod(names = "compact", maxArgs = 0)
-    public abstract static class CompactNode extends ArrayCoreMethodNode {
-
-        public CompactNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public CompactNode(CompactNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public RubyArray compat(RubyArray array) {
-            final RubyArray result = new RubyArray(array.getRubyClass().getContext().getCoreLibrary().getArrayClass());
-
-            for (Object value : array.asList()) {
-                if (!(value instanceof NilPlaceholder || value instanceof RubyNilClass)) {
-                    result.push(value);
-                }
-            }
-
-            return result;
-        }
-
-    }
-
-    @CoreMethod(names = "concat", minArgs = 1, maxArgs = 1)
-    public abstract static class ConcatNode extends CoreMethodNode {
-
-        public ConcatNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public ConcatNode(ConcatNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public RubyArray concat(RubyArray array, RubyArray other) {
-            array.setRangeArrayExclusive(array.size(), array.size(), other);
-            return array;
-        }
-
-    }
-
-    @CoreMethod(names = "delete", minArgs = 1, maxArgs = 1)
-    public abstract static class DeleteNode extends CoreMethodNode {
-
-        public DeleteNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public DeleteNode(DeleteNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public Object delete(RubyArray array, Object value) {
-            boolean deleted = false;
-            int n = 0;
-
-            while (n < array.size()) {
-                if (array.get(n) == value) {
-                    array.deleteAt(n);
-                    deleted = true;
-                } else {
-                    n++;
-                }
-            }
-
-            if (deleted) {
-                return value;
-            } else {
-                return NilPlaceholder.INSTANCE;
-            }
-        }
-
-    }
-
-    @CoreMethod(names = "delete_at", minArgs = 1, maxArgs = 1)
-    public abstract static class DeleteAtNode extends CoreMethodNode {
-
-        public DeleteAtNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public DeleteAtNode(DeleteAtNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public Object deleteAt(RubyArray array, int index) {
-            return array.deleteAt(index);
-        }
-
-    }
-
-    @CoreMethod(names = "dup", maxArgs = 0)
-    public abstract static class DupNode extends ArrayCoreMethodNode {
-
-        public DupNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public DupNode(DupNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public Object dup(RubyArray array) {
-            return array.dup();
-        }
-
-    }
-
-    @CoreMethod(names = "each", needsBlock = true, maxArgs = 0)
-    public abstract static class EachNode extends YieldingCoreMethodNode {
-
-        private final BranchProfile breakProfile = new BranchProfile();
-        private final BranchProfile nextProfile = new BranchProfile();
-        private final BranchProfile redoProfile = new BranchProfile();
-
-        public EachNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public EachNode(EachNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public Object each(VirtualFrame frame, RubyArray array, RubyProc block) {
-            outer: for (int n = 0; n < array.size(); n++) {
-                while (true) {
-                    try {
-                        yield(frame, block, array.get(n));
-                        continue outer;
-                    } catch (BreakException e) {
-                        breakProfile.enter();
-                        return e.getResult();
-                    } catch (NextException e) {
-                        nextProfile.enter();
-                        continue outer;
-                    } catch (RedoException e) {
-                        redoProfile.enter();
-                    }
-                }
-            }
-
-            return NilPlaceholder.INSTANCE;
-        }
-
-    }
-
-    @CoreMethod(names = "each_with_index", needsBlock = true, maxArgs = 0)
-    public abstract static class EachWithIndexNode extends YieldingCoreMethodNode {
-
-        public EachWithIndexNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public EachWithIndexNode(EachWithIndexNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public NilPlaceholder eachWithIndex(VirtualFrame frame, RubyArray array, RubyProc block) {
-            for (int n = 0; n < array.size(); n++) {
-                try {
-                    yield(frame, block, array.get(n), n);
-                } catch (BreakException e) {
-                    break;
-                }
-            }
-
-            return NilPlaceholder.INSTANCE;
-        }
-
-    }
-
-    @CoreMethod(names = "empty?", maxArgs = 0)
-    public abstract static class EmptyNode extends ArrayCoreMethodNode {
-
-        public EmptyNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public EmptyNode(EmptyNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public boolean isEmpty(RubyArray array) {
-            return array.isEmpty();
-        }
-
-    }
-
-    @CoreMethod(names = "find", needsBlock = true, maxArgs = 0)
-    public abstract static class FindNode extends YieldingCoreMethodNode {
-
-        public FindNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public FindNode(FindNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public Object find(VirtualFrame frame, RubyArray array, RubyProc block) {
-            for (int n = 0; n < array.size(); n++) {
-                try {
-                    final Object value = array.get(n);
-
-                    if (yieldBoolean(frame, block, value)) {
-                        return value;
-                    }
-                } catch (BreakException e) {
-                    break;
-                }
-            }
-
-            return NilPlaceholder.INSTANCE;
-        }
-    }
-
-    @CoreMethod(names = "first", maxArgs = 0)
-    public abstract static class FirstNode extends ArrayCoreMethodNode {
-
-        public FirstNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public FirstNode(FirstNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public Object first(RubyArray array) {
-            if (array.size() == 0) {
-                return NilPlaceholder.INSTANCE;
-            } else {
-                return array.get(0);
-            }
-        }
-
-    }
-
-    @CoreMethod(names = "flatten", maxArgs = 0)
-    public abstract static class FlattenNode extends ArrayCoreMethodNode {
-
-        public FlattenNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public FlattenNode(FlattenNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public RubyArray flatten(RubyArray array) {
-            final RubyArray result = new RubyArray(array.getRubyClass().getContext().getCoreLibrary().getArrayClass());
-            array.flattenTo(result);
-            return result;
-        }
-
-    }
-
-    @CoreMethod(names = "include?", minArgs = 1, maxArgs = 1)
-    public abstract static class IncludeNode extends ArrayCoreMethodNode {
-
-        public IncludeNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public IncludeNode(IncludeNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public boolean include(RubyArray array, Object value) {
-            return array.contains(value);
-        }
-
-    }
-
-    @CoreMethod(names = {"inject", "reduce"}, needsBlock = true, minArgs = 0, maxArgs = 1)
-    public abstract static class InjectNode extends YieldingCoreMethodNode {
-
-        public InjectNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public InjectNode(InjectNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public Object inject(VirtualFrame frame, RubyArray array, @SuppressWarnings("unused") UndefinedPlaceholder initial, RubyProc block) {
-            Object accumulator = array.get(0);
-
-            for (int n = 1; n < array.size(); n++) {
-                accumulator = yield(frame, block, accumulator, array.get(n));
-            }
-
-            return accumulator;
-        }
-
-        @Specialization
-        public Object inject(VirtualFrame frame, RubyArray array, Object initial, RubyProc block) {
-            if (initial instanceof UndefinedPlaceholder) {
-                return inject(frame, array, UndefinedPlaceholder.INSTANCE, block);
-            }
-
-            Object accumulator = initial;
-
-            for (int n = 0; n < array.size(); n++) {
-                accumulator = yield(frame, block, accumulator, array.get(n));
-            }
-
-            return accumulator;
-        }
-
-    }
-
-    @CoreMethod(names = "insert", minArgs = 2, maxArgs = 2)
-    public abstract static class InsertNode extends ArrayCoreMethodNode {
-
-        public InsertNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public InsertNode(InsertNode prev) {
-            super(prev);
-        }
-
-        @Specialization(guards = "isFixnumStore", rewriteOn = GeneraliseArrayStoreException.class)
-        public int insert(RubyArray array, int index, int value) throws GeneraliseArrayStoreException {
-            final FixnumArrayStore store = (FixnumArrayStore) array.getArrayStore();
-            store.insertFixnum(ArrayUtilities.normaliseIndex(store.size(), index), value);
-            return value;
-        }
-
-        @Specialization
-        public Object insert(RubyArray array, int index, Object value) {
-            array.insert(ArrayUtilities.normaliseIndex(array.size(), index), value);
-            return value;
-        }
-
-    }
-
-    @CoreMethod(names = {"inspect", "to_s"}, maxArgs = 0)
-    public abstract static class InspectNode extends CoreMethodNode {
-
-        public InspectNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public InspectNode(InspectNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public RubyString inspect(RubyArray array) {
-            final RubyContext context = getContext();
-            return getContext().makeString(inspect(context, array));
-        }
-
-        @SlowPath
-        private static String inspect(RubyContext context, RubyArray array) {
-            final StringBuilder builder = new StringBuilder();
-
-            builder.append("[");
-
-            for (int n = 0; n < array.size(); n++) {
-                if (n > 0) {
-                    builder.append(", ");
-                }
-
-                // TODO(CS): slow path send
-                builder.append(context.getCoreLibrary().box(array.get(n)).send("inspect", null));
-            }
-
-            builder.append("]");
-
-            return builder.toString();
-        }
-
-    }
-
-    @CoreMethod(names = "join", minArgs = 1, maxArgs = 1)
-    public abstract static class JoinNode extends ArrayCoreMethodNode {
-
-        public JoinNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public JoinNode(JoinNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public RubyString join(RubyArray array, RubyString separator) {
-            return array.getRubyClass().getContext().makeString(array.join(separator.toString()));
-        }
-
-    }
-
-    @CoreMethod(names = "last", maxArgs = 0)
-    public abstract static class LastNode extends ArrayCoreMethodNode {
-
-        public LastNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public LastNode(LastNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public Object last(RubyArray array) {
-            final int size = array.size();
-            if (size == 0) {
-                return NilPlaceholder.INSTANCE;
-            } else {
-                return array.get(size - 1);
-            }
-        }
-
-    }
-
-    @CoreMethod(names = {"map", "collect"}, needsBlock = true, maxArgs = 0)
-    public abstract static class MapNode extends YieldingCoreMethodNode {
-
-        public MapNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public MapNode(MapNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public RubyArray map(VirtualFrame frame, RubyArray array, RubyProc block) {
-            final RubyArray result = new RubyArray(array.getRubyClass().getContext().getCoreLibrary().getArrayClass());
-
-            for (int n = 0; n < array.size(); n++) {
-                result.push(yield(frame, block, array.get(n)));
-            }
-
-            return result;
-        }
-    }
-
-    @CoreMethod(names = {"map!", "collect!"}, needsBlock = true, maxArgs = 0)
-    public abstract static class MapInPlaceNode extends YieldingCoreMethodNode {
-
-        public MapInPlaceNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public MapInPlaceNode(MapInPlaceNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public RubyArray mapInPlace(VirtualFrame frame, RubyArray array, RubyProc block) {
-            for (int n = 0; n < array.size(); n++) {
-                array.set(n, yield(frame, block, array.get(n)));
-            }
-
-            return array;
-        }
-    }
-
-    @CoreMethod(names = "pop", maxArgs = 0)
-    public abstract static class PopNode extends ArrayCoreMethodNode {
-
-        public PopNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public PopNode(PopNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public Object pop(RubyArray array) {
-            final int size = array.size();
-
-            if (size == 0) {
-                return NilPlaceholder.INSTANCE;
-            } else {
-                return array.deleteAt(size - 1);
-            }
-        }
-
-    }
-
-    @CoreMethod(names = "product", isSplatted = true)
-    public abstract static class ProductNode extends ArrayCoreMethodNode {
-
-        public ProductNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public ProductNode(ProductNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public Object product(RubyArray array, Object... args) {
-            final RubyArray[] arrays = new RubyArray[1 + args.length];
-            arrays[0] = array;
-            System.arraycopy(args, 0, arrays, 1, args.length);
-            return RubyArray.product(array.getRubyClass().getContext().getCoreLibrary().getArrayClass(), arrays, arrays.length);
-        }
-
-    }
-
-    @CoreMethod(names = {"push", "<<"}, isSplatted = true)
-    public abstract static class PushNode extends CoreMethodNode {
-
-        public PushNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public PushNode(PushNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public RubyArray push(RubyArray array, Object... args) {
-            for (int n = 0; n < args.length; n++) {
-                array.push(args[n]);
-            }
-
-            return array;
-        }
-
-    }
-
-    @CoreMethod(names = "reject!", needsBlock = true, maxArgs = 0)
-    public abstract static class RejectInPlaceNode extends YieldingCoreMethodNode {
-
-        public RejectInPlaceNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public RejectInPlaceNode(RejectInPlaceNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public Object rejectInPlace(VirtualFrame frame, RubyArray array, RubyProc block) {
-            boolean modified = false;
-            int n = 0;
-
-            while (n < array.size()) {
-                if (yieldBoolean(frame, block, array.get(n))) {
-                    array.deleteAt(n);
-                    modified = true;
-                } else {
-                    n++;
-                }
-            }
-
-            if (modified) {
-                return array;
-            } else {
-                return NilPlaceholder.INSTANCE;
-            }
-        }
-
-    }
-
-    @CoreMethod(names = "select", needsBlock = true, maxArgs = 0)
-    public abstract static class SelectNode extends YieldingCoreMethodNode {
-
-        public SelectNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public SelectNode(SelectNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public Object select(VirtualFrame frame, RubyArray array, RubyProc block) {
-            final RubyArray result = new RubyArray(getContext().getCoreLibrary().getArrayClass());
-
-            for (int n = 0; n < array.size(); n++) {
-                final Object value = array.get(n);
-
-                if (yieldBoolean(frame, block, value)) {
-                    result.push(value);
-                }
-            }
-
-            return result;
-        }
-
-    }
-
-    @CoreMethod(names = "shift", maxArgs = 0)
-    public abstract static class ShiftNode extends CoreMethodNode {
-
-        public ShiftNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public ShiftNode(ShiftNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public Object shift(RubyArray array) {
-            final int size = array.size();
-
-            if (size == 0) {
-                return NilPlaceholder.INSTANCE;
-            } else {
-                return array.deleteAt(0);
-            }
-        }
-
-    }
-
-    @CoreMethod(names = {"size", "length"}, maxArgs = 0)
-    public abstract static class SizeNode extends ArrayCoreMethodNode {
-
-        public SizeNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public SizeNode(SizeNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public int size(RubyArray array) {
-            return array.size();
-        }
-
-    }
-
-    @CoreMethod(names = "sort", maxArgs = 0)
-    public abstract static class SortNode extends CoreMethodNode {
-
-        public SortNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public SortNode(SortNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public RubyArray sort(RubyArray array) {
-            final RubyContext context = array.getRubyClass().getContext();
-
-            final Object[] objects = array.asList().toArray();
-
-            Arrays.sort(objects, new Comparator<Object>() {
-
-                @Override
-                public int compare(Object a, Object b) {
-                    final RubyBasicObject aBoxed = context.getCoreLibrary().box(a);
-                    return (int) aBoxed.getLookupNode().lookupMethod("<=>").call(null, aBoxed, null, b);
-                }
-
-            });
-
-            return RubyArray.specializedFromObjects(context.getCoreLibrary().getArrayClass(), objects);
-        }
-
-    }
-
-    @CoreMethod(names = "unshift", isSplatted = true)
-    public abstract static class UnshiftNode extends CoreMethodNode {
-
-        public UnshiftNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public UnshiftNode(UnshiftNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public Object unshift(RubyArray array, Object... args) {
-            for (int n = 0; n < args.length; n++) {
-                array.unshift(args[n]);
-            }
-
-            return array;
-        }
-
-    }
-
-    @CoreMethod(names = "zip", isSplatted = true)
-    public abstract static class ZipNode extends CoreMethodNode {
-
-        public ZipNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public ZipNode(ZipNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public RubyArray zip(RubyArray array, Object... args) {
-            final RubyContext context = getContext();
-            final RubyClass arrayClass = context.getCoreLibrary().getArrayClass();
-
-            final RubyArray result = new RubyArray(arrayClass);
-
-            for (int n = 0; n < array.size(); n++) {
-                final RubyArray tuple = new RubyArray(arrayClass);
-
-                tuple.push(array.get(n));
-
-                for (Object arg : args) {
-                    final RubyArray argArray = (RubyArray) arg;
-                    tuple.push(argArray.get(n));
-                }
-
-                result.push(tuple);
-            }
-
-            return result;
-        }
-
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/ArrayPushNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.core;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.array.*;
-
-public class ArrayPushNode extends RubyNode {
-
-    @Child protected RubyNode array;
-    @Child protected RubyNode pushed;
-
-    public ArrayPushNode(RubyContext context, SourceSection sourceSection, RubyNode array, RubyNode pushed) {
-        super(context, sourceSection);
-        this.array = adoptChild(array);
-        this.pushed = adoptChild(pushed);
-    }
-
-    @Override
-    public Object execute(VirtualFrame frame) {
-        RubyArray a = (RubyArray) array.execute(frame);
-        a = (RubyArray) a.dup();
-        a.push(pushed.execute(frame));
-        return a;
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/ArrayRestNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /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. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.core;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.array.*;
-
-/**
- * Take the rest of values in an array after an index, without using any method lookup. This isn't a
- * call - it's an operation on a core class.
- */
-@NodeInfo(shortName = "array-rest")
-public final class ArrayRestNode extends RubyNode {
-
-    final int begin;
-    @Child protected RubyNode array;
-
-    public ArrayRestNode(RubyContext context, SourceSection sourceSection, int begin, RubyNode array) {
-        super(context, sourceSection);
-        this.begin = begin;
-        this.array = adoptChild(array);
-    }
-
-    @Override
-    public Object execute(VirtualFrame frame) {
-        final RubyArray arrayObject = (RubyArray) array.execute(frame);
-        return arrayObject.getRangeExclusive(begin, arrayObject.size());
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/BasicObjectNodes.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,162 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.core;
-
-import java.math.*;
-import java.util.*;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.dsl.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-import com.oracle.truffle.ruby.runtime.objects.*;
-
-@CoreClass(name = "BasicObject")
-public abstract class BasicObjectNodes {
-
-    @CoreMethod(names = "!", needsSelf = false, maxArgs = 0)
-    public abstract static class NotNode extends CoreMethodNode {
-
-        public NotNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public NotNode(NotNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public boolean not() {
-            return false;
-        }
-
-    }
-
-    @CoreMethod(names = "==", minArgs = 1, maxArgs = 1)
-    public abstract static class EqualNode extends CoreMethodNode {
-
-        public EqualNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public EqualNode(EqualNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public boolean equal(Object a, Object b) {
-            // TODO(CS) ideally all classes would do this in their own nodes
-            return a.equals(b);
-        }
-
-    }
-
-    @CoreMethod(names = "!=", minArgs = 1, maxArgs = 1)
-    public abstract static class NotEqualNode extends CoreMethodNode {
-
-        public NotEqualNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public NotEqualNode(NotEqualNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public boolean notEqual(Object a, Object b) {
-            // TODO(CS) ideally all classes would do this in their own nodes
-            return !a.equals(b);
-        }
-
-    }
-
-    @CoreMethod(names = "equal?", minArgs = 1, maxArgs = 1)
-    public abstract static class ReferenceEqualNode extends CoreMethodNode {
-
-        public ReferenceEqualNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public ReferenceEqualNode(ReferenceEqualNode prev) {
-            super(prev);
-        }
-
-        @Specialization(order = 1)
-        public boolean equal(@SuppressWarnings("unused") NilPlaceholder a, @SuppressWarnings("unused") NilPlaceholder b) {
-            return true;
-        }
-
-        @Specialization(order = 2)
-        public boolean equal(int a, int b) {
-            return a == b;
-        }
-
-        @Specialization(order = 3)
-        public boolean equal(double a, double b) {
-            return a == b;
-        }
-
-        @Specialization(order = 4)
-        public boolean equal(BigInteger a, BigInteger b) {
-            return a.compareTo(b) == 0;
-        }
-
-        @Specialization(order = 5)
-        public boolean equal(RubyBasicObject a, RubyBasicObject b) {
-            return a == b;
-        }
-    }
-
-    @CoreMethod(names = "initialize", needsSelf = false, maxArgs = 0)
-    public abstract static class InitializeNode extends CoreMethodNode {
-
-        public InitializeNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public InitializeNode(InitializeNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public NilPlaceholder initiailze() {
-            return NilPlaceholder.INSTANCE;
-        }
-
-    }
-
-    @CoreMethod(names = {"send", "__send__"}, needsSelf = true, needsBlock = true, minArgs = 1, isSplatted = true)
-    public abstract static class SendNode extends CoreMethodNode {
-
-        public SendNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public SendNode(SendNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public Object send(RubyBasicObject self, Object[] args, @SuppressWarnings("unused") UndefinedPlaceholder block) {
-            final String name = args[0].toString();
-            final Object[] sendArgs = Arrays.copyOfRange(args, 1, args.length);
-            return self.send(name, null, sendArgs);
-        }
-
-        @Specialization
-        public Object send(RubyBasicObject self, Object[] args, RubyProc block) {
-            final String name = args[0].toString();
-            final Object[] sendArgs = Arrays.copyOfRange(args, 1, args.length);
-            return self.send(name, block, sendArgs);
-        }
-
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/BignumNodes.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,661 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.core;
-
-import java.math.*;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.dsl.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.utilities.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.control.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-import com.oracle.truffle.ruby.runtime.core.array.*;
-
-@CoreClass(name = "Bignum")
-public abstract class BignumNodes {
-
-    @CoreMethod(names = "+@", maxArgs = 0)
-    public abstract static class PosNode extends CoreMethodNode {
-
-        public PosNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public PosNode(PosNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public BigInteger pos(BigInteger value) {
-            return value;
-        }
-
-    }
-
-    @CoreMethod(names = "-@", maxArgs = 0)
-    public abstract static class NegNode extends CoreMethodNode {
-
-        public NegNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public NegNode(NegNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public BigInteger neg(BigInteger value) {
-            return value.negate();
-        }
-
-    }
-
-    @CoreMethod(names = "+", minArgs = 1, maxArgs = 1)
-    public abstract static class AddNode extends CoreMethodNode {
-
-        public AddNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public AddNode(AddNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public Object add(BigInteger a, int b) {
-            return a.add(BigInteger.valueOf(b));
-        }
-
-        @Specialization
-        public double add(BigInteger a, double b) {
-            return a.doubleValue() + b;
-        }
-
-        @Specialization
-        public Object add(BigInteger a, BigInteger b) {
-            return GeneralConversions.fixnumOrBignum(a.add(b));
-        }
-
-    }
-
-    @CoreMethod(names = "-", minArgs = 1, maxArgs = 1)
-    public abstract static class SubNode extends CoreMethodNode {
-
-        public SubNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public SubNode(SubNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public Object sub(BigInteger a, int b) {
-            return a.subtract(BigInteger.valueOf(b));
-        }
-
-        @Specialization
-        public double sub(BigInteger a, double b) {
-            return a.doubleValue() - b;
-        }
-
-        @Specialization
-        public Object sub(BigInteger a, BigInteger b) {
-            return GeneralConversions.fixnumOrBignum(a.subtract(b));
-        }
-
-    }
-
-    @CoreMethod(names = "*", minArgs = 1, maxArgs = 1)
-    public abstract static class MulNode extends CoreMethodNode {
-
-        public MulNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public MulNode(MulNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public Object mul(BigInteger a, int b) {
-            return a.multiply(BigInteger.valueOf(b));
-        }
-
-        @Specialization
-        public double mul(BigInteger a, double b) {
-            return a.doubleValue() * b;
-        }
-
-        @Specialization
-        public Object mul(BigInteger a, BigInteger b) {
-            return GeneralConversions.fixnumOrBignum(a.multiply(b));
-        }
-
-    }
-
-    @CoreMethod(names = "**", minArgs = 1, maxArgs = 1)
-    public abstract static class PowNode extends CoreMethodNode {
-
-        public PowNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public PowNode(PowNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public BigInteger pow(BigInteger a, int b) {
-            return a.pow(b);
-        }
-
-        @Specialization
-        public double pow(BigInteger a, double b) {
-            return Math.pow(a.doubleValue(), b);
-        }
-
-        @Specialization
-        public BigInteger pow(BigInteger a, BigInteger b) {
-            BigInteger result = BigInteger.ONE;
-
-            for (BigInteger n = BigInteger.ZERO; b.compareTo(b) < 0; n = n.add(BigInteger.ONE)) {
-                result = result.multiply(a);
-            }
-
-            return result;
-        }
-
-    }
-
-    @CoreMethod(names = "/", minArgs = 1, maxArgs = 1)
-    public abstract static class DivNode extends CoreMethodNode {
-
-        public DivNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public DivNode(DivNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public Object div(BigInteger a, int b) {
-            return a.divide(BigInteger.valueOf(b));
-        }
-
-        @Specialization
-        public double div(BigInteger a, double b) {
-            return a.doubleValue() / b;
-        }
-
-        @Specialization
-        public Object div(BigInteger a, BigInteger b) {
-            return GeneralConversions.fixnumOrBignum(a.divide(b));
-        }
-
-    }
-
-    @CoreMethod(names = "%", minArgs = 1, maxArgs = 1)
-    public abstract static class ModNode extends CoreMethodNode {
-
-        public ModNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public ModNode(ModNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public Object mod(BigInteger a, int b) {
-            return GeneralConversions.fixnumOrBignum(a.mod(BigInteger.valueOf(b)));
-        }
-
-        @Specialization
-        public Object mod(@SuppressWarnings("unused") BigInteger a, @SuppressWarnings("unused") double b) {
-            throw new UnsupportedOperationException();
-        }
-
-        @Specialization
-        public Object mod(BigInteger a, BigInteger b) {
-            return GeneralConversions.fixnumOrBignum(a.mod(b));
-        }
-
-    }
-
-    @CoreMethod(names = "divmod", minArgs = 1, maxArgs = 1)
-    public abstract static class DivModNode extends CoreMethodNode {
-
-        public DivModNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public DivModNode(DivModNode prev) {
-            super(prev);
-        }
-
-        @SuppressWarnings("unused")
-        @Specialization
-        public RubyArray divMod(VirtualFrame frame, BigInteger a, int b) {
-            return RubyBignum.divMod(getContext(), a, BigInteger.valueOf(b));
-        }
-
-        @Specialization
-        public RubyArray divMod(@SuppressWarnings("unused") BigInteger a, @SuppressWarnings("unused") double b) {
-            throw new UnsupportedOperationException();
-        }
-
-        @Specialization
-        public RubyArray divMod(BigInteger a, BigInteger b) {
-            return RubyBignum.divMod(getContext(), a, b);
-        }
-
-    }
-
-    @CoreMethod(names = "<", minArgs = 1, maxArgs = 1)
-    public abstract static class LessNode extends CoreMethodNode {
-
-        public LessNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public LessNode(LessNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public boolean less(BigInteger a, int b) {
-            return a.compareTo(BigInteger.valueOf(b)) < 0;
-        }
-
-        @Specialization
-        public boolean less(BigInteger a, double b) {
-            return a.compareTo(BigInteger.valueOf((long) b)) < 0;
-        }
-
-        @Specialization
-        public boolean less(BigInteger a, BigInteger b) {
-            return a.compareTo(b) < 0;
-        }
-    }
-
-    @CoreMethod(names = "<=", minArgs = 1, maxArgs = 1)
-    public abstract static class LessEqualNode extends CoreMethodNode {
-
-        public LessEqualNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public LessEqualNode(LessEqualNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public boolean lessEqual(BigInteger a, int b) {
-            return a.compareTo(BigInteger.valueOf(b)) <= 0;
-        }
-
-        @Specialization
-        public boolean lessEqual(BigInteger a, double b) {
-            return a.compareTo(BigInteger.valueOf((long) b)) <= 0;
-        }
-
-        @Specialization
-        public boolean lessEqual(BigInteger a, BigInteger b) {
-            return a.compareTo(b) <= 0;
-        }
-    }
-
-    @CoreMethod(names = "==", minArgs = 1, maxArgs = 1)
-    public abstract static class EqualNode extends CoreMethodNode {
-
-        public EqualNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public EqualNode(EqualNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public boolean equal(BigInteger a, int b) {
-            return a.compareTo(BigInteger.valueOf(b)) == 0;
-        }
-
-        @Specialization
-        public boolean equal(BigInteger a, double b) {
-            return a.compareTo(BigInteger.valueOf((long) b)) == 0;
-        }
-
-        @Specialization
-        public boolean equal(BigInteger a, BigInteger b) {
-            return a.compareTo(b) == 0;
-        }
-    }
-
-    @CoreMethod(names = "<=>", minArgs = 1, maxArgs = 1)
-    public abstract static class CompareNode extends CoreMethodNode {
-
-        public CompareNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public CompareNode(CompareNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public int compare(BigInteger a, int b) {
-            return a.compareTo(BigInteger.valueOf(b));
-        }
-
-        @Specialization
-        public int compare(BigInteger a, double b) {
-            return a.compareTo(BigInteger.valueOf((long) b));
-        }
-
-        @Specialization
-        public int compare(BigInteger a, BigInteger b) {
-            return a.compareTo(b);
-        }
-    }
-
-    @CoreMethod(names = "!=", minArgs = 1, maxArgs = 1)
-    public abstract static class NotEqualNode extends CoreMethodNode {
-
-        public NotEqualNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public NotEqualNode(NotEqualNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public boolean notEqual(BigInteger a, int b) {
-            return a.compareTo(BigInteger.valueOf(b)) != 0;
-        }
-
-        @Specialization
-        public boolean notEqual(BigInteger a, double b) {
-            return a.compareTo(BigInteger.valueOf((long) b)) != 0;
-        }
-
-        @Specialization
-        public boolean notEqual(BigInteger a, BigInteger b) {
-            return a.compareTo(b) != 0;
-        }
-    }
-
-    @CoreMethod(names = ">=", minArgs = 1, maxArgs = 1)
-    public abstract static class GreaterEqualNode extends CoreMethodNode {
-
-        public GreaterEqualNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public GreaterEqualNode(GreaterEqualNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public boolean greaterEqual(BigInteger a, int b) {
-            return a.compareTo(BigInteger.valueOf(b)) >= 0;
-        }
-
-        @Specialization
-        public boolean greaterEqual(BigInteger a, double b) {
-            return a.compareTo(BigInteger.valueOf((long) b)) >= 0;
-        }
-
-        @Specialization
-        public boolean greaterEqual(BigInteger a, BigInteger b) {
-            return a.compareTo(b) >= 0;
-        }
-    }
-
-    @CoreMethod(names = ">", minArgs = 1, maxArgs = 1)
-    public abstract static class GreaterNode extends CoreMethodNode {
-
-        public GreaterNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public GreaterNode(GreaterNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public boolean equal(BigInteger a, int b) {
-            return a.compareTo(BigInteger.valueOf(b)) > 0;
-        }
-
-        @Specialization
-        public boolean equal(BigInteger a, double b) {
-            return a.compareTo(BigInteger.valueOf((long) b)) > 0;
-        }
-
-        @Specialization
-        public boolean equal(BigInteger a, BigInteger b) {
-            return a.compareTo(b) > 0;
-        }
-    }
-
-    @CoreMethod(names = "&", minArgs = 1, maxArgs = 1)
-    public abstract static class BitAndNode extends CoreMethodNode {
-
-        public BitAndNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public BitAndNode(BitAndNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public Object bitAnd(BigInteger a, int b) {
-            return GeneralConversions.fixnumOrBignum(a.and(BigInteger.valueOf(b)));
-        }
-
-        @Specialization
-        public Object bitAnd(BigInteger a, BigInteger b) {
-            return GeneralConversions.fixnumOrBignum(a.and(b));
-        }
-    }
-
-    @CoreMethod(names = "|", minArgs = 1, maxArgs = 1)
-    public abstract static class BitOrNode extends CoreMethodNode {
-
-        public BitOrNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public BitOrNode(BitOrNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public Object bitOr(BigInteger a, int b) {
-            return GeneralConversions.fixnumOrBignum(a.or(BigInteger.valueOf(b)));
-        }
-
-        @Specialization
-        public Object bitOr(BigInteger a, BigInteger b) {
-            return GeneralConversions.fixnumOrBignum(a.or(b));
-        }
-    }
-
-    @CoreMethod(names = "^", minArgs = 1, maxArgs = 1)
-    public abstract static class BitXOrNode extends CoreMethodNode {
-
-        public BitXOrNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public BitXOrNode(BitXOrNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public Object bitXOr(BigInteger a, int b) {
-            return GeneralConversions.fixnumOrBignum(a.xor(BigInteger.valueOf(b)));
-        }
-
-        @Specialization
-        public Object bitXOr(BigInteger a, BigInteger b) {
-            return GeneralConversions.fixnumOrBignum(a.xor(b));
-        }
-    }
-
-    @CoreMethod(names = "<<", minArgs = 1, maxArgs = 1)
-    public abstract static class LeftShiftNode extends CoreMethodNode {
-
-        public LeftShiftNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public LeftShiftNode(LeftShiftNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public Object leftShift(BigInteger a, int b) {
-            if (b >= 0) {
-                return GeneralConversions.fixnumOrBignum(a.shiftLeft(b));
-            } else {
-                return GeneralConversions.fixnumOrBignum(a.shiftRight(-b));
-            }
-        }
-
-    }
-
-    @CoreMethod(names = ">>", minArgs = 1, maxArgs = 1)
-    public abstract static class RightShiftNode extends CoreMethodNode {
-
-        public RightShiftNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public RightShiftNode(RightShiftNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public Object leftShift(BigInteger a, int b) {
-            if (b >= 0) {
-                return GeneralConversions.fixnumOrBignum(a.shiftRight(b));
-            } else {
-                return GeneralConversions.fixnumOrBignum(a.shiftLeft(-b));
-            }
-        }
-
-    }
-
-    @CoreMethod(names = "inspect", maxArgs = 0)
-    public abstract static class InpsectNode extends CoreMethodNode {
-
-        public InpsectNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public InpsectNode(InpsectNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public RubyString inspect(BigInteger n) {
-            return getContext().makeString(n.toString());
-        }
-
-    }
-
-    @CoreMethod(names = "nonzero?", maxArgs = 0)
-    public abstract static class NonZeroNode extends CoreMethodNode {
-
-        public NonZeroNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public NonZeroNode(NonZeroNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public Object nonZero(BigInteger value) {
-            if (value.compareTo(BigInteger.ZERO) == 0) {
-                return false;
-            } else {
-                return value;
-            }
-        }
-
-    }
-
-    @CoreMethod(names = "times", needsBlock = true, maxArgs = 0)
-    public abstract static class TimesNode extends YieldingCoreMethodNode {
-
-        private final BranchProfile breakProfile = new BranchProfile();
-        private final BranchProfile nextProfile = new BranchProfile();
-        private final BranchProfile redoProfile = new BranchProfile();
-
-        public TimesNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public TimesNode(TimesNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public Object times(VirtualFrame frame, BigInteger n, RubyProc block) {
-            outer: for (BigInteger i = BigInteger.ZERO; i.compareTo(n) < 0; i = i.add(BigInteger.ONE)) {
-                while (true) {
-                    try {
-                        yield(frame, block, i);
-                        continue outer;
-                    } catch (BreakException e) {
-                        breakProfile.enter();
-                        return e.getResult();
-                    } catch (NextException e) {
-                        nextProfile.enter();
-                        continue outer;
-                    } catch (RedoException e) {
-                        redoProfile.enter();
-                    }
-                }
-            }
-
-            return n;
-        }
-
-    }
-
-    @CoreMethod(names = "to_s", maxArgs = 0)
-    public abstract static class ToSNode extends CoreMethodNode {
-
-        public ToSNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public ToSNode(ToSNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public RubyString toS(BigInteger value) {
-            return getContext().makeString(value.toString());
-        }
-
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/ClassNodes.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,90 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.core;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.dsl.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.ruby.nodes.call.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-import com.oracle.truffle.ruby.runtime.objects.*;
-
-@CoreClass(name = "Class")
-public abstract class ClassNodes {
-
-    @CoreMethod(names = "===", minArgs = 1, maxArgs = 1)
-    public abstract static class ContainsInstanceNode extends CoreMethodNode {
-
-        public ContainsInstanceNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public ContainsInstanceNode(ContainsInstanceNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public boolean containsInstance(RubyClass rubyClass, RubyBasicObject instance) {
-            return instance.getRubyClass().assignableTo(rubyClass);
-        }
-    }
-
-    @CoreMethod(names = "new", needsBlock = true, isSplatted = true)
-    public abstract static class NewNode extends CoreMethodNode {
-
-        @Child protected DispatchHeadNode initialize;
-
-        public NewNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-            initialize = adoptChild(new DispatchHeadNode(context, getSourceSection(), "initialize", false));
-        }
-
-        public NewNode(NewNode prev) {
-            super(prev);
-            initialize = adoptChild(prev.initialize);
-        }
-
-        @Specialization
-        public RubyBasicObject newInstance(VirtualFrame frame, RubyClass rubyClass, Object[] args, @SuppressWarnings("unused") UndefinedPlaceholder block) {
-            return doNewInstance(frame, rubyClass, args, null);
-        }
-
-        @Specialization
-        public RubyBasicObject newInstance(VirtualFrame frame, RubyClass rubyClass, Object[] args, RubyProc block) {
-            return doNewInstance(frame, rubyClass, args, block);
-        }
-
-        private RubyBasicObject doNewInstance(VirtualFrame frame, RubyClass rubyClass, Object[] args, RubyProc block) {
-            final RubyBasicObject instance = rubyClass.newInstance();
-            initialize.dispatch(frame, instance, block, args);
-            return instance;
-        }
-
-    }
-
-    @CoreMethod(names = "to_s", maxArgs = 0)
-    public abstract static class ToSNode extends CoreMethodNode {
-
-        public ToSNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public ToSNode(ToSNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public RubyString toS(RubyClass rubyClass) {
-            return getContext().makeString(rubyClass.getName());
-        }
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/ComparableNodes.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,158 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.core;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.dsl.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.ruby.nodes.call.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.objects.*;
-
-@CoreClass(name = "Comparable")
-public abstract class ComparableNodes {
-
-    public abstract static class ComparableCoreMethodNode extends CoreMethodNode {
-
-        @Child protected DispatchHeadNode compareNode;
-
-        public ComparableCoreMethodNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-            compareNode = adoptChild(new DispatchHeadNode(context, getSourceSection(), "<=>", false));
-        }
-
-        public ComparableCoreMethodNode(ComparableCoreMethodNode prev) {
-            super(prev);
-            compareNode = adoptChild(prev.compareNode);
-        }
-
-        public int compare(VirtualFrame frame, RubyBasicObject receiverObject, Object comparedTo) {
-            return (int) compareNode.dispatch(frame, receiverObject, null, comparedTo);
-        }
-
-    }
-
-    @CoreMethod(names = "<", isModuleMethod = true, minArgs = 1, maxArgs = 1)
-    public abstract static class LessNode extends ComparableCoreMethodNode {
-
-        public LessNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public LessNode(LessNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public boolean less(VirtualFrame frame, RubyBasicObject self, Object comparedTo) {
-            return compare(frame, self, comparedTo) < 0;
-        }
-
-    }
-
-    @CoreMethod(names = "<=", isModuleMethod = true, minArgs = 1, maxArgs = 1)
-    public abstract static class LessEqualNode extends ComparableCoreMethodNode {
-
-        public LessEqualNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public LessEqualNode(LessEqualNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public boolean lessEqual(VirtualFrame frame, RubyBasicObject self, Object comparedTo) {
-            return compare(frame, self, comparedTo) <= 0;
-        }
-
-    }
-
-    @CoreMethod(names = "==", isModuleMethod = true, minArgs = 1, maxArgs = 1)
-    public abstract static class EqualNode extends ComparableCoreMethodNode {
-
-        public EqualNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public EqualNode(EqualNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public boolean equal(VirtualFrame frame, RubyBasicObject self, Object comparedTo) {
-            if (self == comparedTo) {
-                return true;
-            }
-
-            try {
-                return compare(frame, self, comparedTo) == 0;
-            } catch (Exception e) {
-                // Comparable#== catches and ignores all exceptions in <=>, returning false
-                return false;
-            }
-        }
-    }
-
-    @CoreMethod(names = ">=", isModuleMethod = true, minArgs = 1, maxArgs = 1)
-    public abstract static class GreaterEqualNode extends ComparableCoreMethodNode {
-
-        public GreaterEqualNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public GreaterEqualNode(GreaterEqualNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public boolean greaterEqual(VirtualFrame frame, RubyBasicObject self, Object comparedTo) {
-            return compare(frame, self, comparedTo) >= 0;
-        }
-
-    }
-
-    @CoreMethod(names = ">", isModuleMethod = true, minArgs = 1, maxArgs = 1)
-    public abstract static class GreaterNode extends ComparableCoreMethodNode {
-
-        public GreaterNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public GreaterNode(GreaterNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public boolean greater(VirtualFrame frame, RubyBasicObject self, Object comparedTo) {
-            return compare(frame, self, comparedTo) > 0;
-        }
-
-    }
-
-    @CoreMethod(names = "between?", isModuleMethod = true, minArgs = 2, maxArgs = 2)
-    public abstract static class BetweenNode extends ComparableCoreMethodNode {
-
-        public BetweenNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public BetweenNode(BetweenNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public boolean between(VirtualFrame frame, RubyBasicObject self, Object min, Object max) {
-            return !(compare(frame, self, min) < 0 || compare(frame, self, max) > 0);
-        }
-
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/ContinuationNodes.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.core;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.dsl.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-
-@CoreClass(name = "Continuation")
-public abstract class ContinuationNodes {
-
-    @CoreMethod(names = "call", isSplatted = true)
-    public abstract static class CallNode extends CoreMethodNode {
-
-        public CallNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public CallNode(CallNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public Object call(RubyContinuation continuation, Object[] args) {
-            continuation.call(args);
-            return null;
-        }
-
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/CoreClass.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,20 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.core;
-
-import java.lang.annotation.*;
-
-@Target(ElementType.TYPE)
-@Retention(RetentionPolicy.RUNTIME)
-public @interface CoreClass {
-
-    String name();
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/CoreMethod.java	Sun Feb 23 17:00:35 2014 -0800
+++ /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. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.core;
-
-import java.lang.annotation.*;
-
-import com.oracle.truffle.ruby.runtime.methods.*;
-
-@Target(ElementType.TYPE)
-@Retention(RetentionPolicy.RUNTIME)
-public @interface CoreMethod {
-
-    String[] names();
-
-    boolean isModuleMethod() default false;
-
-    boolean needsSelf() default true;
-
-    boolean isSplatted() default false;
-
-    boolean needsBlock() default false;
-
-    boolean appendCallNode() default false;
-
-    int minArgs() default Arity.NO_MINIMUM;
-
-    int maxArgs() default Arity.NO_MAXIMUM;
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/CoreMethodNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,28 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.core;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.dsl.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-
-@NodeChild(value = "arguments", type = RubyNode[].class)
-public abstract class CoreMethodNode extends RubyNode {
-
-    public CoreMethodNode(RubyContext context, SourceSection sourceSection) {
-        super(context, sourceSection);
-    }
-
-    public CoreMethodNode(CoreMethodNode prev) {
-        super(prev);
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/CoreMethodNodeManager.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,209 +0,0 @@
-/*
- * Copyright (c) 2013, 2014 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.core;
-
-import java.util.*;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.dsl.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.nodes.control.*;
-import com.oracle.truffle.ruby.nodes.methods.arguments.*;
-import com.oracle.truffle.ruby.nodes.objects.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-import com.oracle.truffle.ruby.runtime.methods.*;
-
-public abstract class CoreMethodNodeManager {
-
-    /**
-     * Register all the nodes that represent core methods as methods with their respective classes,
-     * given the Object class object, which should already be initialized with all the core classes.
-     */
-    public static void addMethods(RubyClass rubyObjectClass) {
-        for (MethodDetails methodDetails : getMethods()) {
-            addMethod(rubyObjectClass, methodDetails);
-        }
-    }
-
-    /**
-     * Collect up all the core method nodes. Abstracted to allow the SVM to implement at compile
-     * type.
-     */
-    public static List<MethodDetails> getMethods() {
-        final List<MethodDetails> methods = new ArrayList<>();
-        getMethods(methods, ArrayNodesFactory.getFactories());
-        getMethods(methods, BasicObjectNodesFactory.getFactories());
-        getMethods(methods, BignumNodesFactory.getFactories());
-        getMethods(methods, ClassNodesFactory.getFactories());
-        getMethods(methods, ContinuationNodesFactory.getFactories());
-        getMethods(methods, ComparableNodesFactory.getFactories());
-        getMethods(methods, DirNodesFactory.getFactories());
-        getMethods(methods, ExceptionNodesFactory.getFactories());
-        getMethods(methods, FalseClassNodesFactory.getFactories());
-        getMethods(methods, FiberNodesFactory.getFactories());
-        getMethods(methods, FileNodesFactory.getFactories());
-        getMethods(methods, FixnumNodesFactory.getFactories());
-        getMethods(methods, FloatNodesFactory.getFactories());
-        getMethods(methods, HashNodesFactory.getFactories());
-        getMethods(methods, KernelNodesFactory.getFactories());
-        getMethods(methods, MainNodesFactory.getFactories());
-        getMethods(methods, MatchDataNodesFactory.getFactories());
-        getMethods(methods, MathNodesFactory.getFactories());
-        getMethods(methods, ModuleNodesFactory.getFactories());
-        getMethods(methods, NilClassNodesFactory.getFactories());
-        getMethods(methods, ObjectNodesFactory.getFactories());
-        getMethods(methods, ObjectSpaceNodesFactory.getFactories());
-        getMethods(methods, ProcessNodesFactory.getFactories());
-        getMethods(methods, ProcNodesFactory.getFactories());
-        getMethods(methods, RangeNodesFactory.getFactories());
-        getMethods(methods, RegexpNodesFactory.getFactories());
-        getMethods(methods, SignalNodesFactory.getFactories());
-        getMethods(methods, StringNodesFactory.getFactories());
-        getMethods(methods, StructNodesFactory.getFactories());
-        getMethods(methods, SymbolNodesFactory.getFactories());
-        getMethods(methods, ThreadNodesFactory.getFactories());
-        getMethods(methods, TimeNodesFactory.getFactories());
-        getMethods(methods, TrueClassNodesFactory.getFactories());
-        return methods;
-    }
-
-    /**
-     * Collect up the core methods created by a factory.
-     */
-    private static void getMethods(List<MethodDetails> methods, List<? extends NodeFactory<? extends CoreMethodNode>> nodeFactories) {
-        for (NodeFactory<? extends RubyNode> nodeFactory : nodeFactories) {
-            final GeneratedBy generatedBy = nodeFactory.getClass().getAnnotation(GeneratedBy.class);
-            final Class<?> nodeClass = generatedBy.value();
-            final CoreClass classAnnotation = nodeClass.getEnclosingClass().getAnnotation(CoreClass.class);
-            final CoreMethod methodAnnotation = nodeClass.getAnnotation(CoreMethod.class);
-            methods.add(new MethodDetails(classAnnotation, methodAnnotation, nodeFactory));
-        }
-    }
-
-    /**
-     * Take a core method node factory, the annotations for the class and method, and add it as a
-     * method on the correct class.
-     */
-    private static void addMethod(RubyClass rubyObjectClass, MethodDetails methodDetails) {
-        assert rubyObjectClass != null;
-        assert methodDetails != null;
-
-        final RubyContext context = rubyObjectClass.getContext();
-
-        RubyModule module;
-
-        if (methodDetails.getClassAnnotation().name().equals("main")) {
-            module = context.getCoreLibrary().getMainObject().getSingletonClass();
-        } else {
-            module = (RubyModule) rubyObjectClass.lookupConstant(methodDetails.getClassAnnotation().name());
-        }
-
-        assert module != null : methodDetails.getClassAnnotation().name();
-
-        final List<String> names = Arrays.asList(methodDetails.getMethodAnnotation().names());
-        assert names.size() >= 1;
-
-        final String canonicalName = names.get(0);
-        final List<String> aliases = names.subList(1, names.size());
-
-        final UniqueMethodIdentifier uniqueIdentifier = new UniqueMethodIdentifier();
-        final Visibility visibility = Visibility.PUBLIC;
-
-        final RubyRootNode pristineRootNode = makeGenericMethod(context, methodDetails);
-        final CallTarget callTarget = Truffle.getRuntime().createCallTarget(NodeUtil.cloneNode(pristineRootNode));
-
-        final String intrinsicName = methodDetails.getClassAnnotation().name() + "#" + canonicalName;
-
-        final InlinableMethodImplementation methodImplementation = new InlinableMethodImplementation(callTarget, null, new FrameDescriptor(), pristineRootNode, true,
-                        methodDetails.getMethodAnnotation().appendCallNode());
-        final RubyMethod method = new RubyMethod(pristineRootNode.getSourceSection(), module, uniqueIdentifier, intrinsicName, canonicalName, visibility, false, methodImplementation);
-
-        module.addMethod(method);
-
-        if (methodDetails.getMethodAnnotation().isModuleMethod()) {
-            module.getSingletonClass().addMethod(method);
-        }
-
-        for (String alias : aliases) {
-            final RubyMethod withAlias = method.withNewName(alias);
-
-            module.addMethod(withAlias);
-
-            if (methodDetails.getMethodAnnotation().isModuleMethod()) {
-                module.getSingletonClass().addMethod(withAlias);
-            }
-        }
-    }
-
-    private static RubyRootNode makeGenericMethod(RubyContext context, MethodDetails methodDetails) {
-        final SourceSection sourceSection = new CoreSourceSection(methodDetails.getClassAnnotation().name() + "#" + methodDetails.getMethodAnnotation().names()[0]);
-
-        final Arity arity = new Arity(methodDetails.getMethodAnnotation().minArgs(), methodDetails.getMethodAnnotation().maxArgs());
-
-        final List<RubyNode> argumentsNodes = new ArrayList<>();
-
-        if (methodDetails.getMethodAnnotation().needsSelf()) {
-            argumentsNodes.add(new SelfNode(context, sourceSection));
-        }
-
-        if (methodDetails.getMethodAnnotation().isSplatted()) {
-            argumentsNodes.add(new ReadAllArgumentsNode(context, sourceSection));
-        } else {
-            assert arity.getMaximum() != Arity.NO_MAXIMUM;
-
-            for (int n = 0; n < arity.getMaximum(); n++) {
-                argumentsNodes.add(new ReadPreArgumentNode(context, sourceSection, n, true));
-            }
-        }
-
-        if (methodDetails.getMethodAnnotation().needsBlock()) {
-            argumentsNodes.add(new ReadBlockArgumentNode(context, sourceSection, true));
-        }
-
-        final RubyNode methodNode = methodDetails.getNodeFactory().createNode(context, sourceSection, argumentsNodes.toArray(new RubyNode[argumentsNodes.size()]));
-        final CheckArityNode checkArity = new CheckArityNode(context, sourceSection, arity);
-        final SequenceNode block = new SequenceNode(context, sourceSection, checkArity, methodNode);
-
-        return new RubyRootNode(sourceSection, null, methodDetails.getClassAnnotation().name() + "#" + methodDetails.getMethodAnnotation().names()[0] + "(core)", block);
-    }
-
-    public static class MethodDetails {
-
-        private final CoreClass classAnnotation;
-        private final CoreMethod methodAnnotation;
-        private final NodeFactory<? extends RubyNode> nodeFactory;
-
-        public MethodDetails(CoreClass classAnnotation, CoreMethod methodAnnotation, NodeFactory<? extends RubyNode> nodeFactory) {
-            assert classAnnotation != null;
-            assert methodAnnotation != null;
-            assert nodeFactory != null;
-            this.classAnnotation = classAnnotation;
-            this.methodAnnotation = methodAnnotation;
-            this.nodeFactory = nodeFactory;
-        }
-
-        public CoreClass getClassAnnotation() {
-            return classAnnotation;
-        }
-
-        public CoreMethod getMethodAnnotation() {
-            return methodAnnotation;
-        }
-
-        public NodeFactory<? extends RubyNode> getNodeFactory() {
-            return nodeFactory;
-        }
-
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/DirNodes.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,168 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.core;
-
-import java.io.*;
-import java.nio.file.*;
-import java.nio.file.attribute.*;
-
-import com.oracle.truffle.api.CompilerDirectives.SlowPath;
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.dsl.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-import com.oracle.truffle.ruby.runtime.core.array.*;
-
-@CoreClass(name = "Dir")
-public abstract class DirNodes {
-
-    @CoreMethod(names = "[]", isModuleMethod = true, needsSelf = false, minArgs = 1, maxArgs = 1)
-    public abstract static class GlobNode extends CoreMethodNode {
-
-        public GlobNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public GlobNode(GlobNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public RubyArray glob(RubyString glob) {
-            return glob(getContext(), glob.toString());
-        }
-
-        @SlowPath
-        private static RubyArray glob(final RubyContext context, String glob) {
-            /*
-             * Globbing is quite complicated. We've implemented a subset of the functionality that
-             * satisfies MSpec, but it will likely break for anyone else.
-             */
-
-            context.implementationMessage("globbing %s", glob);
-
-            String absoluteGlob;
-
-            if (!glob.startsWith("/")) {
-                absoluteGlob = new File(".", glob).getAbsolutePath().toString();
-            } else {
-                absoluteGlob = glob;
-            }
-
-            // Get the first star
-
-            final int firstStar = absoluteGlob.indexOf('*');
-            assert firstStar >= 0;
-
-            // Walk back from that to the first / before that star
-
-            int prefixLength = firstStar;
-
-            while (prefixLength > 0 && absoluteGlob.charAt(prefixLength) == File.separatorChar) {
-                prefixLength--;
-            }
-
-            final String prefix = absoluteGlob.substring(0, prefixLength - 1);
-
-            final PathMatcher matcher = FileSystems.getDefault().getPathMatcher("glob:" + absoluteGlob.substring(prefixLength));
-
-            final RubyArray array = new RubyArray(context.getCoreLibrary().getArrayClass());
-
-            try {
-                Files.walkFileTree(FileSystems.getDefault().getPath(prefix), new SimpleFileVisitor<Path>() {
-
-                    @Override
-                    public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
-                        if (matcher.matches(file)) {
-                            array.push(context.makeString(file.toString()));
-                        }
-
-                        return FileVisitResult.CONTINUE;
-                    }
-
-                });
-            } catch (IOException e) {
-                throw new RuntimeException(e);
-            }
-
-            return array;
-        }
-
-    }
-
-    @CoreMethod(names = "chdir", isModuleMethod = true, needsSelf = false, needsBlock = true, minArgs = 1, maxArgs = 1)
-    public abstract static class ChdirNode extends YieldingCoreMethodNode {
-
-        public ChdirNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public ChdirNode(ChdirNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public Object chdir(VirtualFrame frame, RubyString path, RubyProc block) {
-            final RubyContext context = getContext();
-
-            final String previous = context.getCurrentDirectory();
-            context.setCurrentDirectory(path.toString());
-
-            if (block != null) {
-                try {
-                    return yield(frame, block, path);
-                } finally {
-                    context.setCurrentDirectory(previous);
-                }
-            } else {
-                return 0;
-            }
-        }
-
-    }
-
-    @CoreMethod(names = {"exist?", "exists?"}, isModuleMethod = true, needsSelf = false, maxArgs = 1)
-    public abstract static class ExistsNode extends CoreMethodNode {
-
-        public ExistsNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public ExistsNode(ExistsNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public boolean exists(RubyString path) {
-            return new File(path.toString()).isDirectory();
-        }
-
-    }
-
-    @CoreMethod(names = "pwd", isModuleMethod = true, needsSelf = false, maxArgs = 0)
-    public abstract static class PwdNode extends CoreMethodNode {
-
-        public PwdNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public PwdNode(PwdNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public RubyString pwd() {
-            return getContext().makeString(getContext().getCurrentDirectory());
-        }
-
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/ExceptionNodes.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,82 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.core;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.dsl.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-import com.oracle.truffle.ruby.runtime.core.array.*;
-
-@CoreClass(name = "Exception")
-public abstract class ExceptionNodes {
-
-    @CoreMethod(names = "initialize", minArgs = 0, maxArgs = 1)
-    public abstract static class InitializeNode extends CoreMethodNode {
-
-        public InitializeNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public InitializeNode(InitializeNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public NilPlaceholder initialize(RubyException exception, @SuppressWarnings("unused") UndefinedPlaceholder message) {
-            exception.initialize(getContext().makeString(" "));
-            return NilPlaceholder.INSTANCE;
-        }
-
-        @Specialization
-        public NilPlaceholder initialize(RubyException exception, RubyString message) {
-            exception.initialize(message);
-            return NilPlaceholder.INSTANCE;
-        }
-
-    }
-
-    @CoreMethod(names = "backtrace", needsSelf = false, maxArgs = 0)
-    public abstract static class BacktraceNode extends CoreMethodNode {
-
-        public BacktraceNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public BacktraceNode(BacktraceNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public RubyArray backtrace() {
-            return new RubyArray(getContext().getCoreLibrary().getArrayClass());
-        }
-
-    }
-
-    @CoreMethod(names = "message", maxArgs = 0)
-    public abstract static class MessageNode extends CoreMethodNode {
-
-        public MessageNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public MessageNode(MessageNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public RubyString message(RubyException exception) {
-            return exception.getMessage();
-        }
-
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/FalseClassNodes.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,97 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.core;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.dsl.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-
-@CoreClass(name = "FalseClass")
-public abstract class FalseClassNodes {
-
-    @CoreMethod(names = "!", needsSelf = false, maxArgs = 0)
-    public abstract static class NotNode extends CoreMethodNode {
-
-        public NotNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public NotNode(NotNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public boolean not() {
-            return true;
-        }
-
-    }
-
-    @CoreMethod(names = {"==", "===", "=~"}, needsSelf = false, minArgs = 1, maxArgs = 1)
-    public abstract static class EqualNode extends CoreMethodNode {
-
-        public EqualNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public EqualNode(EqualNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public boolean equal(boolean other) {
-            return !other;
-        }
-
-        @Specialization
-        public boolean equal(Object other) {
-            return other instanceof Boolean && !((boolean) other);
-        }
-
-    }
-
-    @CoreMethod(names = "^", needsSelf = false, minArgs = 1, maxArgs = 1)
-    public abstract static class XorNode extends CoreMethodNode {
-
-        public XorNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public XorNode(XorNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public boolean xor(boolean other) {
-            return false ^ other;
-        }
-
-    }
-
-    @CoreMethod(names = "to_s", needsSelf = false, maxArgs = 0)
-    public abstract static class ToSNode extends CoreMethodNode {
-
-        public ToSNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public ToSNode(ToSNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public RubyString toS() {
-            return getContext().makeString("false");
-        }
-
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/FiberNodes.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,84 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.core;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.dsl.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-
-@CoreClass(name = "Fiber")
-public abstract class FiberNodes {
-
-    @CoreMethod(names = "resume", isSplatted = true)
-    public abstract static class ResumeNode extends CoreMethodNode {
-
-        public ResumeNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public ResumeNode(ResumeNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public Object resume(RubyFiber fiberBeingResumed, Object[] args) {
-            final RubyFiber sendingFiber = getContext().getFiberManager().getCurrentFiber();
-
-            fiberBeingResumed.resume(sendingFiber, args);
-
-            return sendingFiber.waitForResume();
-        }
-
-    }
-
-    @CoreMethod(names = "initialize", needsBlock = true, maxArgs = 0)
-    public abstract static class InitializeNode extends CoreMethodNode {
-
-        public InitializeNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public InitializeNode(InitializeNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public NilPlaceholder initialize(RubyFiber fiber, RubyProc block) {
-            fiber.initialize(block);
-            return NilPlaceholder.INSTANCE;
-        }
-
-    }
-
-    @CoreMethod(names = "yield", isModuleMethod = true, needsSelf = false, isSplatted = true)
-    public abstract static class YieldNode extends CoreMethodNode {
-
-        public YieldNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public YieldNode(YieldNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public Object yield(Object[] args) {
-            final RubyFiber yieldingFiber = getContext().getFiberManager().getCurrentFiber();
-            final RubyFiber fiberYieldedTo = yieldingFiber.lastResumedByFiber;
-
-            fiberYieldedTo.resume(yieldingFiber, args);
-
-            return yieldingFiber.waitForResume();
-        }
-
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/FileNodes.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,291 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.core;
-
-import java.io.*;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.dsl.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-import com.oracle.truffle.ruby.runtime.core.array.*;
-
-@CoreClass(name = "File")
-public abstract class FileNodes {
-
-    @CoreMethod(names = "absolute_path", isModuleMethod = true, needsSelf = false, minArgs = 1, maxArgs = 1)
-    public abstract static class AbsolutePathNode extends CoreMethodNode {
-
-        public AbsolutePathNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public AbsolutePathNode(AbsolutePathNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public RubyString absolutePath(RubyString path) {
-            return getContext().makeString(new File(path.toString()).getAbsolutePath());
-        }
-
-    }
-
-    @CoreMethod(names = "close", maxArgs = 0)
-    public abstract static class CloseNode extends CoreMethodNode {
-
-        public CloseNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public CloseNode(CloseNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public NilPlaceholder close(RubyFile file) {
-            file.close();
-            return NilPlaceholder.INSTANCE;
-        }
-
-    }
-
-    @CoreMethod(names = "directory?", isModuleMethod = true, needsSelf = false, maxArgs = 1)
-    public abstract static class DirectoryNode extends CoreMethodNode {
-
-        public DirectoryNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public DirectoryNode(DirectoryNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public boolean directory(RubyString path) {
-            return new File(path.toString()).isDirectory();
-        }
-
-    }
-
-    @CoreMethod(names = "dirname", isModuleMethod = true, needsSelf = false, minArgs = 1, maxArgs = 1)
-    public abstract static class DirnameNode extends CoreMethodNode {
-
-        public DirnameNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public DirnameNode(DirnameNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public RubyString dirname(RubyString path) {
-            final String parent = new File(path.toString()).getParent();
-
-            if (parent == null) {
-                return getContext().makeString(".");
-            } else {
-                return getContext().makeString(parent);
-            }
-        }
-
-    }
-
-    @CoreMethod(names = "each_line", needsBlock = true, maxArgs = 0)
-    public abstract static class EachLineNode extends YieldingCoreMethodNode {
-
-        public EachLineNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public EachLineNode(EachLineNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public NilPlaceholder eachLine(VirtualFrame frame, RubyFile file, RubyProc block) {
-            final RubyContext context = getContext();
-
-            // TODO(cs): this buffered reader may consume too much
-
-            final BufferedReader lineReader = new BufferedReader(file.getReader());
-
-            while (true) {
-                String line;
-
-                try {
-                    line = lineReader.readLine();
-                } catch (IOException e) {
-                    throw new RuntimeException(e);
-                }
-
-                if (line == null) {
-                    break;
-                }
-
-                yield(frame, block, context.makeString(line));
-            }
-
-            return NilPlaceholder.INSTANCE;
-        }
-
-    }
-
-    @CoreMethod(names = {"exist?", "exists?"}, isModuleMethod = true, needsSelf = false, minArgs = 1, maxArgs = 1)
-    public abstract static class ExistsNode extends CoreMethodNode {
-
-        public ExistsNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public ExistsNode(ExistsNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public boolean exists(RubyString path) {
-            return new File(path.toString()).isFile();
-        }
-
-    }
-
-    @CoreMethod(names = "executable?", isModuleMethod = true, needsSelf = false, minArgs = 1, maxArgs = 1)
-    public abstract static class ExecutableNode extends CoreMethodNode {
-
-        public ExecutableNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public ExecutableNode(ExecutableNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public boolean executable(RubyString path) {
-            return new File(path.toString()).canExecute();
-        }
-
-    }
-
-    @CoreMethod(names = "expand_path", isModuleMethod = true, needsSelf = false, minArgs = 1, maxArgs = 2)
-    public abstract static class ExpandPathNode extends CoreMethodNode {
-
-        public ExpandPathNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public ExpandPathNode(ExpandPathNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public RubyString expandPath(RubyString path, @SuppressWarnings("unused") UndefinedPlaceholder dir) {
-            return getContext().makeString(RubyFile.expandPath(path.toString()));
-        }
-
-        @Specialization
-        public RubyString expandPath(RubyString path, RubyString dir) {
-            return getContext().makeString(RubyFile.expandPath(path.toString(), dir.toString()));
-        }
-
-    }
-
-    @CoreMethod(names = "file?", isModuleMethod = true, needsSelf = false, minArgs = 1, maxArgs = 1)
-    public abstract static class FileNode extends CoreMethodNode {
-
-        public FileNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public FileNode(FileNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public boolean file(RubyString path) {
-            return new File(path.toString()).isFile();
-        }
-
-    }
-
-    @CoreMethod(names = "join", isModuleMethod = true, needsSelf = false, isSplatted = true)
-    public abstract static class JoinNode extends CoreMethodNode {
-
-        public JoinNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public JoinNode(JoinNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public RubyString join(Object[] parts) {
-            return getContext().makeString(RubyArray.join(parts, File.separator));
-        }
-    }
-
-    @CoreMethod(names = "open", isModuleMethod = true, needsSelf = false, needsBlock = true, minArgs = 2, maxArgs = 2)
-    public abstract static class OpenNode extends YieldingCoreMethodNode {
-
-        public OpenNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public OpenNode(OpenNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public Object open(VirtualFrame frame, RubyString fileName, RubyString mode, RubyProc block) {
-            final RubyFile file = RubyFile.open(getContext(), fileName.toString(), mode.toString());
-
-            if (block != null) {
-                try {
-                    yield(frame, block, file);
-                } finally {
-                    file.close();
-                }
-            }
-
-            return file;
-        }
-
-    }
-
-    @CoreMethod(names = "write", maxArgs = 0)
-    public abstract static class WriteNode extends CoreMethodNode {
-
-        public WriteNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public WriteNode(WriteNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public NilPlaceholder write(RubyFile file, RubyString string) {
-            try {
-                final Writer writer = file.getWriter();
-                writer.write(string.toString());
-                writer.flush();
-            } catch (IOException e) {
-                throw new RuntimeException(e);
-            }
-
-            return NilPlaceholder.INSTANCE;
-        }
-
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/FixnumNodes.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,889 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.core;
-
-import java.math.*;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.dsl.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.utilities.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.control.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-import com.oracle.truffle.ruby.runtime.core.array.*;
-
-@CoreClass(name = "Fixnum")
-public abstract class FixnumNodes {
-
-    @CoreMethod(names = "+@", maxArgs = 0)
-    public abstract static class PosNode extends CoreMethodNode {
-
-        public PosNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public PosNode(PosNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public int pos(int value) {
-            return value;
-        }
-
-    }
-
-    @CoreMethod(names = "-@", maxArgs = 0)
-    public abstract static class NegNode extends CoreMethodNode {
-
-        public NegNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public NegNode(NegNode prev) {
-            super(prev);
-        }
-
-        @Specialization(rewriteOn = ArithmeticException.class)
-        public int neg(int value) {
-            return ExactMath.subtractExact(0, value);
-        }
-
-        @Specialization
-        public BigInteger negWithOverflow(int value) {
-            return BigInteger.valueOf(value).negate();
-        }
-
-    }
-
-    @CoreMethod(names = "+", minArgs = 1, maxArgs = 1)
-    public abstract static class AddNode extends CoreMethodNode {
-
-        public AddNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public AddNode(AddNode prev) {
-            super(prev);
-        }
-
-        @Specialization(rewriteOn = ArithmeticException.class)
-        public int add(int a, int b) {
-            return ExactMath.addExact(a, b);
-        }
-
-        @Specialization
-        public Object addWithOverflow(int a, int b) {
-            return GeneralConversions.fixnumOrBignum(BigInteger.valueOf(a).add(BigInteger.valueOf(b)));
-        }
-
-        @Specialization
-        public double add(int a, double b) {
-            return a + b;
-        }
-
-        @Specialization
-        public Object add(int a, BigInteger b) {
-            return GeneralConversions.fixnumOrBignum(BigInteger.valueOf(a).add(b));
-        }
-
-    }
-
-    @CoreMethod(names = "-", minArgs = 1, maxArgs = 1)
-    public abstract static class SubNode extends CoreMethodNode {
-
-        public SubNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public SubNode(SubNode prev) {
-            super(prev);
-        }
-
-        @Specialization(rewriteOn = ArithmeticException.class)
-        public int sub(int a, int b) {
-            return ExactMath.subtractExact(a, b);
-        }
-
-        @Specialization
-        public Object subWithOverflow(int a, int b) {
-            return GeneralConversions.fixnumOrBignum(BigInteger.valueOf(a).subtract(BigInteger.valueOf(b)));
-        }
-
-        @Specialization
-        public double sub(int a, double b) {
-            return a - b;
-        }
-
-        @Specialization
-        public Object sub(int a, BigInteger b) {
-            return GeneralConversions.fixnumOrBignum(BigInteger.valueOf(a).subtract(b));
-        }
-
-    }
-
-    @CoreMethod(names = "*", minArgs = 1, maxArgs = 1)
-    public abstract static class MulNode extends CoreMethodNode {
-
-        public MulNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public MulNode(MulNode prev) {
-            super(prev);
-        }
-
-        @Specialization(rewriteOn = ArithmeticException.class)
-        public int mul(int a, int b) {
-            return ExactMath.multiplyExact(a, b);
-        }
-
-        @Specialization
-        public Object mulWithOverflow(int a, int b) {
-            return GeneralConversions.fixnumOrBignum(BigInteger.valueOf(a).multiply(BigInteger.valueOf(b)));
-        }
-
-        @Specialization
-        public double mul(int a, double b) {
-            return a * b;
-        }
-
-        @Specialization
-        public Object mul(int a, BigInteger b) {
-            return GeneralConversions.fixnumOrBignum(BigInteger.valueOf(a).multiply(b));
-        }
-
-    }
-
-    @CoreMethod(names = "**", minArgs = 1, maxArgs = 1)
-    public abstract static class PowNode extends CoreMethodNode {
-
-        public PowNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public PowNode(PowNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public Object pow(int a, int b) {
-            return GeneralConversions.fixnumOrBignum(BigInteger.valueOf(a).pow(b));
-        }
-
-        @Specialization
-        public double pow(int a, double b) {
-            return Math.pow(a, b);
-        }
-
-        @Specialization
-        public Object pow(int a, BigInteger b) {
-            final BigInteger bigA = BigInteger.valueOf(a);
-
-            BigInteger result = BigInteger.ONE;
-
-            for (BigInteger n = BigInteger.ZERO; b.compareTo(b) < 0; n = n.add(BigInteger.ONE)) {
-                result = result.multiply(bigA);
-            }
-
-            return result;
-        }
-
-    }
-
-    @CoreMethod(names = "/", minArgs = 1, maxArgs = 1)
-    public abstract static class DivNode extends CoreMethodNode {
-
-        public DivNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public DivNode(DivNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public int div(int a, int b) {
-            return a / b;
-        }
-
-        @Specialization
-        public double div(int a, double b) {
-            return a / b;
-        }
-
-        @Specialization
-        public int div(@SuppressWarnings("unused") int a, @SuppressWarnings("unused") BigInteger b) {
-            return 0;
-        }
-    }
-
-    @CoreMethod(names = "%", minArgs = 1, maxArgs = 1)
-    public abstract static class ModNode extends CoreMethodNode {
-
-        public ModNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public ModNode(ModNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public int mod(int a, int b) {
-            return a % b;
-        }
-
-        @Specialization
-        public double mod(@SuppressWarnings("unused") int a, @SuppressWarnings("unused") double b) {
-            throw new UnsupportedOperationException();
-        }
-
-        @Specialization
-        public BigInteger mod(@SuppressWarnings("unused") int a, BigInteger b) {
-            return b;
-        }
-    }
-
-    @CoreMethod(names = "divmod", minArgs = 1, maxArgs = 1)
-    public abstract static class DivModNode extends CoreMethodNode {
-
-        public DivModNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public DivModNode(DivModNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public RubyArray divMod(int a, int b) {
-            int q;
-
-            if (b < 0) {
-                if (a < 0) {
-                    q = -a / -b;
-                } else {
-                    q = -(a / -b);
-                }
-            } else {
-                if (a < 0) {
-                    q = -(-a / b);
-                } else {
-                    q = a / b;
-                }
-            }
-
-            int r = a - q * b;
-
-            if ((r < 0 && b > 0) || (r > 0 && b < 0)) {
-                r += b;
-                q -= 1;
-            }
-
-            final FixnumImmutablePairArrayStore store = new FixnumImmutablePairArrayStore(q, r);
-            return new RubyArray(getContext().getCoreLibrary().getArrayClass(), store);
-        }
-
-        @Specialization
-        public RubyArray divMod(@SuppressWarnings("unused") int a, @SuppressWarnings("unused") double b) {
-            throw new UnsupportedOperationException();
-        }
-
-        @Specialization
-        public RubyArray divMod(int a, BigInteger b) {
-            return RubyBignum.divMod(getContext(), BigInteger.valueOf(a), b);
-        }
-    }
-
-    @CoreMethod(names = "<", minArgs = 1, maxArgs = 1)
-    public abstract static class LessNode extends CoreMethodNode {
-
-        public LessNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public LessNode(LessNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public boolean less(int a, int b) {
-            return a < b;
-        }
-
-        @Specialization
-        public boolean less(int a, double b) {
-            return a < b;
-        }
-
-        @Specialization
-        public boolean less(int a, BigInteger b) {
-            return BigInteger.valueOf(a).compareTo(b) < 0;
-        }
-    }
-
-    @CoreMethod(names = "<=", minArgs = 1, maxArgs = 1)
-    public abstract static class LessEqualNode extends CoreMethodNode {
-
-        public LessEqualNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public LessEqualNode(LessEqualNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public boolean lessEqual(int a, int b) {
-            return a <= b;
-        }
-
-        @Specialization
-        public boolean lessEqual(int a, double b) {
-            return a <= b;
-        }
-
-        @Specialization
-        public boolean lessEqual(int a, BigInteger b) {
-            return BigInteger.valueOf(a).compareTo(b) <= 0;
-        }
-    }
-
-    @CoreMethod(names = {"==", "==="}, minArgs = 1, maxArgs = 1)
-    public abstract static class EqualNode extends CoreMethodNode {
-
-        public EqualNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public EqualNode(EqualNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public boolean equal(int a, int b) {
-            return a == b;
-        }
-
-        @Specialization
-        public boolean equal(int a, double b) {
-            return a == b;
-        }
-
-        @Specialization
-        public boolean equal(int a, BigInteger b) {
-            return BigInteger.valueOf(a).compareTo(b) == 0;
-        }
-    }
-
-    @CoreMethod(names = "<=>", minArgs = 1, maxArgs = 1)
-    public abstract static class CompareNode extends CoreMethodNode {
-
-        public CompareNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public CompareNode(CompareNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public int compare(int a, int b) {
-            return Integer.compare(a, b);
-        }
-
-        @Specialization
-        public int compare(int a, double b) {
-            return Double.compare(a, b);
-        }
-
-        @Specialization
-        public int compare(int a, BigInteger b) {
-            return BigInteger.valueOf(a).compareTo(b);
-        }
-    }
-
-    @CoreMethod(names = "!=", minArgs = 1, maxArgs = 1)
-    public abstract static class NotEqualNode extends CoreMethodNode {
-
-        public NotEqualNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public NotEqualNode(NotEqualNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public boolean notEqual(int a, int b) {
-            return a != b;
-        }
-
-        @Specialization
-        public boolean notEqual(int a, double b) {
-            return a != b;
-        }
-
-        @Specialization
-        public boolean notEqual(int a, BigInteger b) {
-            return BigInteger.valueOf(a).compareTo(b) != 0;
-        }
-    }
-
-    @CoreMethod(names = ">=", minArgs = 1, maxArgs = 1)
-    public abstract static class GreaterEqualNode extends CoreMethodNode {
-
-        public GreaterEqualNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public GreaterEqualNode(GreaterEqualNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public boolean greaterEqual(int a, int b) {
-            return a >= b;
-        }
-
-        @Specialization
-        public boolean greaterEqual(int a, double b) {
-            return a >= b;
-        }
-
-        @Specialization
-        public boolean greaterEqual(int a, BigInteger b) {
-            return BigInteger.valueOf(a).compareTo(b) >= 0;
-        }
-    }
-
-    @CoreMethod(names = ">", minArgs = 1, maxArgs = 1)
-    public abstract static class GreaterNode extends CoreMethodNode {
-
-        public GreaterNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public GreaterNode(GreaterNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public boolean equal(int a, int b) {
-            return a > b;
-        }
-
-        @Specialization
-        public boolean equal(int a, double b) {
-            return a > b;
-        }
-
-        @Specialization
-        public boolean equal(int a, BigInteger b) {
-            return BigInteger.valueOf(a).compareTo(b) > 0;
-        }
-    }
-
-    @CoreMethod(names = "~", maxArgs = 0)
-    public abstract static class ComplementNode extends CoreMethodNode {
-
-        public ComplementNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public ComplementNode(ComplementNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public int complement(int n) {
-            return ~n;
-        }
-
-    }
-
-    @CoreMethod(names = "&", minArgs = 1, maxArgs = 1)
-    public abstract static class BitAndNode extends CoreMethodNode {
-
-        public BitAndNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public BitAndNode(BitAndNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public int bitAnd(int a, int b) {
-            return a & b;
-        }
-
-        @Specialization
-        public Object bitAnd(int a, BigInteger b) {
-            return GeneralConversions.fixnumOrBignum(BigInteger.valueOf(a).and(b));
-        }
-    }
-
-    @CoreMethod(names = "|", minArgs = 1, maxArgs = 1)
-    public abstract static class BitOrNode extends CoreMethodNode {
-
-        public BitOrNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public BitOrNode(BitOrNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public int bitOr(int a, int b) {
-            return a | b;
-        }
-
-        @Specialization
-        public Object bitOr(int a, BigInteger b) {
-            return GeneralConversions.fixnumOrBignum(BigInteger.valueOf(a).or(b));
-        }
-    }
-
-    @CoreMethod(names = "^", minArgs = 1, maxArgs = 1)
-    public abstract static class BitXOrNode extends CoreMethodNode {
-
-        public BitXOrNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public BitXOrNode(BitXOrNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public int bitXOr(int a, int b) {
-            return a ^ b;
-        }
-
-        @Specialization
-        public Object bitXOr(int a, BigInteger b) {
-            return GeneralConversions.fixnumOrBignum(BigInteger.valueOf(a).xor(b));
-        }
-    }
-
-    @CoreMethod(names = "<<", minArgs = 1, maxArgs = 1)
-    public abstract static class LeftShiftNode extends CoreMethodNode {
-
-        public LeftShiftNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public LeftShiftNode(LeftShiftNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public Object leftShift(int a, int b) {
-            if (b > 0) {
-                if (RubyFixnum.SIZE - Integer.numberOfLeadingZeros(a) + b > RubyFixnum.SIZE - 1) {
-                    return GeneralConversions.fixnumOrBignum(BigInteger.valueOf(a).shiftLeft(b));
-                } else {
-                    return a << b;
-                }
-            } else {
-                if (-b >= Integer.SIZE) {
-                    return 0;
-                } else {
-                    return a >> -b;
-                }
-            }
-        }
-
-    }
-
-    @CoreMethod(names = ">>", minArgs = 1, maxArgs = 1)
-    public abstract static class RightShiftNode extends CoreMethodNode {
-
-        public RightShiftNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public RightShiftNode(RightShiftNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public int rightShift(int a, int b) {
-            if (b > 0) {
-                return a >> b;
-            } else {
-                if (-b >= RubyFixnum.SIZE) {
-                    return 0;
-                } else {
-                    return a >> -b;
-                }
-            }
-        }
-
-    }
-
-    @CoreMethod(names = "[]", minArgs = 1, maxArgs = 1)
-    public abstract static class GetIndexNode extends CoreMethodNode {
-
-        public GetIndexNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public GetIndexNode(GetIndexNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public int getIndex(int self, int index) {
-            if ((self & (1 << index)) == 0) {
-                return 0;
-            } else {
-                return 1;
-            }
-        }
-
-    }
-
-    @CoreMethod(names = "chr", maxArgs = 0)
-    public abstract static class ChrNode extends CoreMethodNode {
-
-        public ChrNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public ChrNode(ChrNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public RubyString chr(int n) {
-            // TODO(CS): not sure about encoding here
-            return getContext().makeString((char) n);
-        }
-
-    }
-
-    @CoreMethod(names = "inspect", maxArgs = 0)
-    public abstract static class InpsectNode extends CoreMethodNode {
-
-        public InpsectNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public InpsectNode(InpsectNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public RubyString inspect(int n) {
-            return getContext().makeString(Integer.toString(n));
-        }
-
-    }
-
-    @CoreMethod(names = "nonzero?", maxArgs = 0)
-    public abstract static class NonZeroNode extends CoreMethodNode {
-
-        public NonZeroNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public NonZeroNode(NonZeroNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public Object nonZero(int value) {
-            if (value == 0) {
-                return false;
-            } else {
-                return value;
-            }
-        }
-
-    }
-
-    @CoreMethod(names = "size", needsSelf = false, maxArgs = 0)
-    public abstract static class SizeNode extends CoreMethodNode {
-
-        public SizeNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public SizeNode(SizeNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public int size() {
-            return Integer.SIZE / Byte.SIZE;
-        }
-
-    }
-
-    @CoreMethod(names = "step", needsBlock = true, minArgs = 2, maxArgs = 2)
-    public abstract static class StepNode extends YieldingCoreMethodNode {
-
-        public StepNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public StepNode(StepNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public NilPlaceholder step(VirtualFrame frame, int from, int to, int step, RubyProc block) {
-            for (int i = from; i <= to; i += step) {
-                yield(frame, block, i);
-            }
-
-            return NilPlaceholder.INSTANCE;
-        }
-
-    }
-
-    @CoreMethod(names = "times", needsBlock = true, maxArgs = 0)
-    public abstract static class TimesNode extends YieldingCoreMethodNode {
-
-        private final BranchProfile breakProfile = new BranchProfile();
-        private final BranchProfile nextProfile = new BranchProfile();
-        private final BranchProfile redoProfile = new BranchProfile();
-
-        public TimesNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public TimesNode(TimesNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public Object times(VirtualFrame frame, int n, RubyProc block) {
-            outer: for (int i = 0; i < n; i++) {
-                while (true) {
-                    try {
-                        yield(frame, block, i);
-                        continue outer;
-                    } catch (BreakException e) {
-                        breakProfile.enter();
-                        return e.getResult();
-                    } catch (NextException e) {
-                        nextProfile.enter();
-                        continue outer;
-                    } catch (RedoException e) {
-                        redoProfile.enter();
-                    }
-                }
-            }
-
-            return n;
-        }
-
-    }
-
-    @CoreMethod(names = {"to_i", "to_int"}, maxArgs = 0)
-    public abstract static class ToINode extends CoreMethodNode {
-
-        public ToINode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public ToINode(ToINode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public int toI(int n) {
-            return n;
-        }
-
-    }
-
-    @CoreMethod(names = "to_f", maxArgs = 0)
-    public abstract static class ToFNode extends CoreMethodNode {
-
-        public ToFNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public ToFNode(ToFNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public double toF(int n) {
-            return n;
-        }
-
-    }
-
-    @CoreMethod(names = "to_s", maxArgs = 0)
-    public abstract static class ToSNode extends CoreMethodNode {
-
-        public ToSNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public ToSNode(ToSNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public RubyString toS(int n) {
-            return getContext().makeString(Integer.toString(n));
-        }
-
-    }
-
-    @CoreMethod(names = "upto", needsBlock = true, minArgs = 1, maxArgs = 1)
-    public abstract static class UpToNode extends YieldingCoreMethodNode {
-
-        private final BranchProfile breakProfile = new BranchProfile();
-        private final BranchProfile nextProfile = new BranchProfile();
-        private final BranchProfile redoProfile = new BranchProfile();
-
-        public UpToNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public UpToNode(UpToNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public Object upto(VirtualFrame frame, int from, int to, RubyProc block) {
-            outer: for (int i = from; i <= to; i++) {
-                while (true) {
-                    try {
-                        yield(frame, block, i);
-                        continue outer;
-                    } catch (BreakException e) {
-                        breakProfile.enter();
-                        return e.getResult();
-                    } catch (NextException e) {
-                        nextProfile.enter();
-                        continue outer;
-                    } catch (RedoException e) {
-                        redoProfile.enter();
-                    }
-                }
-            }
-
-            return NilPlaceholder.INSTANCE;
-        }
-
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/FloatNodes.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,493 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.core;
-
-import java.math.*;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.dsl.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-import com.oracle.truffle.ruby.runtime.core.array.*;
-
-@CoreClass(name = "Float")
-public abstract class FloatNodes {
-
-    @CoreMethod(names = "+@", maxArgs = 0)
-    public abstract static class PosNode extends CoreMethodNode {
-
-        public PosNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public PosNode(PosNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public double pos(double value) {
-            return value;
-        }
-
-    }
-
-    @CoreMethod(names = "-@", maxArgs = 0)
-    public abstract static class NegNode extends CoreMethodNode {
-
-        public NegNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public NegNode(NegNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public double neg(double value) {
-            return -value;
-        }
-
-    }
-
-    @CoreMethod(names = "+", minArgs = 1, maxArgs = 1)
-    public abstract static class AddNode extends CoreMethodNode {
-
-        public AddNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public AddNode(AddNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public double add(double a, int b) {
-            return a + b;
-        }
-
-        @Specialization
-        public double add(double a, double b) {
-            return a + b;
-        }
-
-        @Specialization
-        public double add(double a, BigInteger b) {
-            return a + b.doubleValue();
-        }
-
-    }
-
-    @CoreMethod(names = "-", minArgs = 1, maxArgs = 1)
-    public abstract static class SubNode extends CoreMethodNode {
-
-        public SubNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public SubNode(SubNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public double sub(double a, int b) {
-            return a - b;
-        }
-
-        @Specialization
-        public double sub(double a, double b) {
-            return a - b;
-        }
-
-        @Specialization
-        public double sub(double a, BigInteger b) {
-            return a - b.doubleValue();
-        }
-
-    }
-
-    @CoreMethod(names = "*", minArgs = 1, maxArgs = 1)
-    public abstract static class MulNode extends CoreMethodNode {
-
-        public MulNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public MulNode(MulNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public double mul(double a, int b) {
-            return a * b;
-        }
-
-        @Specialization
-        public double mul(double a, double b) {
-            return a * b;
-        }
-
-        @Specialization
-        public double mul(double a, BigInteger b) {
-            return a * b.doubleValue();
-        }
-
-    }
-
-    @CoreMethod(names = "**", minArgs = 1, maxArgs = 1)
-    public abstract static class PowNode extends CoreMethodNode {
-
-        public PowNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public PowNode(PowNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public double mul(double a, int b) {
-            return Math.pow(a, b);
-        }
-
-        @Specialization
-        public double mul(double a, double b) {
-            return Math.pow(a, b);
-        }
-
-        @Specialization
-        public double mul(double a, BigInteger b) {
-            return Math.pow(a, b.doubleValue());
-        }
-
-    }
-
-    @CoreMethod(names = "/", minArgs = 1, maxArgs = 1)
-    public abstract static class DivNode extends CoreMethodNode {
-
-        public DivNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public DivNode(DivNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public double div(double a, int b) {
-            return a / b;
-        }
-
-        @Specialization
-        public double div(double a, double b) {
-            return a / b;
-        }
-
-        @Specialization
-        public double div(double a, BigInteger b) {
-            return a / b.doubleValue();
-        }
-
-    }
-
-    @CoreMethod(names = "%", minArgs = 1, maxArgs = 1)
-    public abstract static class ModNode extends CoreMethodNode {
-
-        public ModNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public ModNode(ModNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public double mod(@SuppressWarnings("unused") double a, @SuppressWarnings("unused") int b) {
-            throw new UnsupportedOperationException();
-        }
-
-        @Specialization
-        public double mod(@SuppressWarnings("unused") double a, @SuppressWarnings("unused") double b) {
-            throw new UnsupportedOperationException();
-        }
-
-        @Specialization
-        public double mod(@SuppressWarnings("unused") double a, @SuppressWarnings("unused") BigInteger b) {
-            throw new UnsupportedOperationException();
-        }
-
-    }
-
-    @CoreMethod(names = "divmod", minArgs = 1, maxArgs = 1)
-    public abstract static class DivModNode extends CoreMethodNode {
-
-        public DivModNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public DivModNode(DivModNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public RubyArray divMod(@SuppressWarnings("unused") double a, @SuppressWarnings("unused") int b) {
-            throw new UnsupportedOperationException();
-        }
-
-        @Specialization
-        public RubyArray divMod(@SuppressWarnings("unused") double a, @SuppressWarnings("unused") double b) {
-            throw new UnsupportedOperationException();
-        }
-
-        @Specialization
-        public RubyArray divMod(@SuppressWarnings("unused") double a, @SuppressWarnings("unused") BigInteger b) {
-            throw new UnsupportedOperationException();
-        }
-
-    }
-
-    @CoreMethod(names = "<", minArgs = 1, maxArgs = 1)
-    public abstract static class LessNode extends CoreMethodNode {
-
-        public LessNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public LessNode(LessNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public boolean less(double a, int b) {
-            return a < b;
-        }
-
-        @Specialization
-        public boolean less(double a, double b) {
-            return a < b;
-        }
-
-        @Specialization
-        public boolean less(double a, BigInteger b) {
-            return BigInteger.valueOf((long) a).compareTo(b) < 0;
-        }
-    }
-
-    @CoreMethod(names = "<=", minArgs = 1, maxArgs = 1)
-    public abstract static class LessEqualNode extends CoreMethodNode {
-
-        public LessEqualNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public LessEqualNode(LessEqualNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public boolean lessEqual(double a, int b) {
-            return a <= b;
-        }
-
-        @Specialization
-        public boolean lessEqual(double a, double b) {
-            return a <= b;
-        }
-
-        @Specialization
-        public boolean lessEqual(double a, BigInteger b) {
-            return BigInteger.valueOf((long) a).compareTo(b) <= 0;
-        }
-    }
-
-    @CoreMethod(names = "==", minArgs = 1, maxArgs = 1)
-    public abstract static class EqualNode extends CoreMethodNode {
-
-        public EqualNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public EqualNode(EqualNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public boolean equal(double a, int b) {
-            return a == b;
-        }
-
-        @Specialization
-        public boolean equal(double a, double b) {
-            return a == b;
-        }
-
-        @Specialization
-        public boolean equal(double a, BigInteger b) {
-            return BigInteger.valueOf((long) a).compareTo(b) == 0;
-        }
-    }
-
-    @CoreMethod(names = "!=", minArgs = 1, maxArgs = 1)
-    public abstract static class NotEqualNode extends CoreMethodNode {
-
-        public NotEqualNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public NotEqualNode(NotEqualNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public boolean notEqual(double a, int b) {
-            return a != b;
-        }
-
-        @Specialization
-        public boolean notEqual(double a, double b) {
-            return a != b;
-        }
-
-        @Specialization
-        public boolean notEqual(double a, BigInteger b) {
-            return BigInteger.valueOf((long) a).compareTo(b) != 0;
-        }
-    }
-
-    @CoreMethod(names = ">=", minArgs = 1, maxArgs = 1)
-    public abstract static class GreaterEqualNode extends CoreMethodNode {
-
-        public GreaterEqualNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public GreaterEqualNode(GreaterEqualNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public boolean greaterEqual(double a, int b) {
-            return a >= b;
-        }
-
-        @Specialization
-        public boolean greaterEqual(double a, double b) {
-            return a >= b;
-        }
-
-        @Specialization
-        public boolean greaterEqual(double a, BigInteger b) {
-            return BigInteger.valueOf((long) a).compareTo(b) >= 0;
-        }
-    }
-
-    @CoreMethod(names = ">", minArgs = 1, maxArgs = 1)
-    public abstract static class GreaterNode extends CoreMethodNode {
-
-        public GreaterNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public GreaterNode(GreaterNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public boolean equal(double a, int b) {
-            return a > b;
-        }
-
-        @Specialization
-        public boolean equal(double a, double b) {
-            return a > b;
-        }
-
-        @Specialization
-        public boolean equal(double a, BigInteger b) {
-            return BigInteger.valueOf((long) a).compareTo(b) > 0;
-        }
-    }
-
-    @CoreMethod(names = "abs", maxArgs = 0)
-    public abstract static class AbsNode extends CoreMethodNode {
-
-        public AbsNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public AbsNode(AbsNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public double abs(double n) {
-            return Math.abs(n);
-        }
-
-    }
-
-    @CoreMethod(names = "inspect", maxArgs = 0)
-    public abstract static class InpsectNode extends CoreMethodNode {
-
-        public InpsectNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public InpsectNode(InpsectNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public RubyString inspect(double n) {
-            return getContext().makeString(Double.toString(n));
-        }
-
-    }
-
-    @CoreMethod(names = "nonzero?", maxArgs = 0)
-    public abstract static class NonZeroNode extends CoreMethodNode {
-
-        public NonZeroNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public NonZeroNode(NonZeroNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public Object nonZero(double value) {
-            if (value == 0) {
-                return false;
-            } else {
-                return value;
-            }
-        }
-
-    }
-
-    @CoreMethod(names = "to_s", maxArgs = 0)
-    public abstract static class ToSNode extends CoreMethodNode {
-
-        public ToSNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public ToSNode(ToSNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public RubyString toS(double value) {
-            return getContext().makeString(Double.toString(value));
-        }
-
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/HashNodes.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,308 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.core;
-
-import java.util.*;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.dsl.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-import com.oracle.truffle.ruby.runtime.core.array.*;
-
-@CoreClass(name = "Hash")
-public abstract class HashNodes {
-
-    @CoreMethod(names = "[]", isModuleMethod = true, needsSelf = false, isSplatted = true)
-    public abstract static class ConstructNode extends CoreMethodNode {
-
-        public ConstructNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public ConstructNode(ConstructNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public RubyHash construct(Object[] args) {
-            final RubyHash hash = new RubyHash(getContext().getCoreLibrary().getHashClass());
-
-            if (args.length == 1) {
-                final RubyArray array = (RubyArray) args[0];
-
-                for (int n = 0; n < array.size(); n++) {
-                    final RubyArray keyValue = (RubyArray) array.get(n);
-                    hash.put(keyValue.get(0), keyValue.get(1));
-                }
-            } else {
-                if (args.length % 2 != 0) {
-                    // TODO(CS): figure out what error to throw here
-                    throw new UnsupportedOperationException();
-                }
-
-                for (int n = 0; n < args.length; n += 2) {
-                    hash.put(args[n], args[n + 1]);
-                }
-            }
-
-            return hash;
-        }
-
-    }
-
-    @CoreMethod(names = "[]", minArgs = 1, maxArgs = 1)
-    public abstract static class GetIndexNode extends CoreMethodNode {
-
-        public GetIndexNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public GetIndexNode(GetIndexNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public Object construct(VirtualFrame frame, RubyHash hash, Object index) {
-            final Object value = hash.get(index);
-
-            if (value == null) {
-                if (hash.defaultBlock == null) {
-                    return NilPlaceholder.INSTANCE;
-                } else {
-                    return hash.defaultBlock.call(frame.pack(), hash, index);
-                }
-            } else {
-                return value;
-            }
-        }
-
-    }
-
-    @CoreMethod(names = "[]=", minArgs = 2, maxArgs = 2)
-    public abstract static class SetIndexNode extends CoreMethodNode {
-
-        public SetIndexNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public SetIndexNode(SetIndexNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public Object construct(RubyHash hash, Object index, Object value) {
-            hash.put(index, value);
-            return value;
-        }
-
-    }
-
-    @CoreMethod(names = "delete", minArgs = 1, maxArgs = 1)
-    public abstract static class DeleteNode extends CoreMethodNode {
-
-        public DeleteNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public DeleteNode(DeleteNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public Object delete(RubyHash hash, Object index) {
-            hash.checkFrozen();
-
-            final Object value = hash.getMap().remove(index);
-
-            if (value == null) {
-                return NilPlaceholder.INSTANCE;
-            } else {
-                return value;
-            }
-        }
-
-    }
-
-    @CoreMethod(names = "each", needsBlock = true, maxArgs = 0)
-    public abstract static class EachNode extends YieldingCoreMethodNode {
-
-        public EachNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public EachNode(EachNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public NilPlaceholder each(VirtualFrame frame, RubyHash hash, RubyProc block) {
-            for (Map.Entry<Object, Object> entry : hash.storage.entrySet()) {
-                yield(frame, block, entry.getKey(), entry.getValue());
-            }
-
-            return NilPlaceholder.INSTANCE;
-        }
-
-    }
-
-    @CoreMethod(names = "empty?", maxArgs = 0)
-    public abstract static class EmptyNode extends CoreMethodNode {
-
-        public EmptyNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public EmptyNode(EmptyNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public boolean empty(RubyHash hash) {
-            return hash.storage.isEmpty();
-        }
-
-    }
-
-    @CoreMethod(names = "initialize", needsBlock = true, maxArgs = 0)
-    public abstract static class InitializeNode extends CoreMethodNode {
-
-        public InitializeNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public InitializeNode(InitializeNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public NilPlaceholder initialize(RubyHash hash, @SuppressWarnings("unused") UndefinedPlaceholder block) {
-            hash.initialize(null);
-            return NilPlaceholder.INSTANCE;
-        }
-
-        @Specialization
-        public NilPlaceholder initialize(RubyHash hash, RubyProc block) {
-            hash.initialize(block);
-            return NilPlaceholder.INSTANCE;
-        }
-
-    }
-
-    @CoreMethod(names = {"map", "collect"}, needsBlock = true, maxArgs = 0)
-    public abstract static class MapNode extends YieldingCoreMethodNode {
-
-        public MapNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public MapNode(MapNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public RubyArray map(VirtualFrame frame, RubyHash hash, RubyProc block) {
-            final RubyArray result = new RubyArray(getContext().getCoreLibrary().getArrayClass());
-
-            for (Map.Entry<Object, Object> entry : hash.storage.entrySet()) {
-                result.push(yield(frame, block, entry.getKey(), entry.getValue()));
-            }
-
-            return result;
-        }
-
-    }
-
-    @CoreMethod(names = "key?", minArgs = 1, maxArgs = 1)
-    public abstract static class KeyNode extends CoreMethodNode {
-
-        public KeyNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public KeyNode(KeyNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public boolean key(RubyHash hash, Object key) {
-            return hash.storage.containsKey(key);
-        }
-
-    }
-
-    @CoreMethod(names = "keys", maxArgs = 0)
-    public abstract static class KeysNode extends CoreMethodNode {
-
-        public KeysNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public KeysNode(KeysNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public RubyArray keys(RubyHash hash) {
-            final RubyArray array = new RubyArray(getContext().getCoreLibrary().getArrayClass());
-
-            for (Object key : hash.storage.keySet()) {
-                array.push(key);
-            }
-
-            return array;
-        }
-
-    }
-
-    @CoreMethod(names = "size", maxArgs = 0)
-    public abstract static class SizeNode extends CoreMethodNode {
-
-        public SizeNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public SizeNode(SizeNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public int size(RubyHash hash) {
-            return hash.storage.size();
-        }
-
-    }
-
-    @CoreMethod(names = "values", maxArgs = 0)
-    public abstract static class ValuesNode extends CoreMethodNode {
-
-        public ValuesNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public ValuesNode(ValuesNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public RubyArray values(RubyHash hash) {
-            final RubyArray array = new RubyArray(getContext().getCoreLibrary().getArrayClass());
-
-            for (Object value : hash.storage.values()) {
-                array.push(value);
-            }
-
-            return array;
-        }
-
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/InterpolatedStringNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,59 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.core;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-
-/**
- * A list of expressions to build up into a string.
- */
-@NodeInfo(shortName = "interpolated-string")
-public final class InterpolatedStringNode extends RubyNode {
-
-    @CompilationFinal private int expectedLength = 64;
-
-    @Children protected final RubyNode[] children;
-
-    public InterpolatedStringNode(RubyContext context, SourceSection sourceSection, RubyNode[] children) {
-        super(context, sourceSection);
-        this.children = adoptChildren(children);
-    }
-
-    @ExplodeLoop
-    @Override
-    public Object execute(VirtualFrame frame) {
-        final StringBuilder builder = new StringBuilder(expectedLength);
-
-        for (int n = 0; n < children.length; n++) {
-            builder.append(children[n].execute(frame).toString());
-        }
-
-        if (builder.length() > expectedLength) {
-            CompilerDirectives.transferToInterpreterAndInvalidate();
-            expectedLength = builder.length() * 2;
-        }
-
-        return getContext().makeString(builder.toString());
-    }
-
-    @ExplodeLoop
-    @Override
-    public void executeVoid(VirtualFrame frame) {
-        for (int n = 0; n < children.length; n++) {
-            children[n].executeVoid(frame);
-        }
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/KernelNodes.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,797 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.core;
-
-import java.io.*;
-import java.math.*;
-import java.util.*;
-
-import com.oracle.truffle.api.CompilerDirectives.SlowPath;
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.dsl.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.nodes.call.*;
-import com.oracle.truffle.ruby.nodes.cast.*;
-import com.oracle.truffle.ruby.nodes.control.*;
-import com.oracle.truffle.ruby.nodes.literal.*;
-import com.oracle.truffle.ruby.nodes.yield.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.control.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-import com.oracle.truffle.ruby.runtime.core.array.*;
-import com.oracle.truffle.ruby.runtime.objects.*;
-import com.oracle.truffle.ruby.runtime.subsystems.*;
-
-@CoreClass(name = "Kernel")
-public abstract class KernelNodes {
-
-    @CoreMethod(names = "Array", isModuleMethod = true, needsSelf = false, isSplatted = true)
-    public abstract static class ArrayNode extends CoreMethodNode {
-
-        public ArrayNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public ArrayNode(ArrayNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public RubyArray array(Object[] args) {
-            if (args.length == 1 && args[0] instanceof RubyArray) {
-                return (RubyArray) args[0];
-            } else {
-                return RubyArray.specializedFromObjects(getContext().getCoreLibrary().getArrayClass(), args);
-            }
-        }
-
-    }
-
-    @CoreMethod(names = "at_exit", isModuleMethod = true, needsSelf = false, needsBlock = true, maxArgs = 0)
-    public abstract static class AtExitNode extends CoreMethodNode {
-
-        public AtExitNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public AtExitNode(AtExitNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public Object atExit(RubyProc block) {
-            getContext().getAtExitManager().add(block);
-            return NilPlaceholder.INSTANCE;
-        }
-    }
-
-    @CoreMethod(names = "binding", isModuleMethod = true, needsSelf = true, maxArgs = 0)
-    public abstract static class BindingNode extends CoreMethodNode {
-
-        public BindingNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public BindingNode(BindingNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public Object binding(VirtualFrame frame, Object self) {
-            return new RubyBinding(getContext().getCoreLibrary().getBindingClass(), self, frame.getCaller().unpack().materialize());
-        }
-    }
-
-    @CoreMethod(names = "block_given?", isModuleMethod = true, needsSelf = false, maxArgs = 0)
-    public abstract static class BlockGivenNode extends CoreMethodNode {
-
-        public BlockGivenNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public BlockGivenNode(BlockGivenNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public boolean blockGiven(VirtualFrame frame) {
-            return frame.getCaller().unpack().getArguments(RubyArguments.class).getBlock() != null;
-        }
-    }
-
-    // TODO(CS): should hide this in a feature
-
-    @CoreMethod(names = "callcc", isModuleMethod = true, needsSelf = false, needsBlock = true, maxArgs = 0)
-    public abstract static class CallccNode extends CoreMethodNode {
-
-        public CallccNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public CallccNode(CallccNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public Object callcc(RubyProc block) {
-            final RubyContext context = getContext();
-
-            if (block == null) {
-                // TODO(CS): should really have acceptsBlock and needsBlock to do this automatically
-                throw new RaiseException(context.getCoreLibrary().localJumpError("no block given"));
-            }
-
-            final RubyContinuation continuation = new RubyContinuation(context.getCoreLibrary().getContinuationClass());
-            return continuation.enter(block);
-        }
-    }
-
-    @CoreMethod(names = "catch", isModuleMethod = true, needsSelf = false, needsBlock = true, minArgs = 1, maxArgs = 1)
-    public abstract static class CatchNode extends YieldingCoreMethodNode {
-
-        public CatchNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public CatchNode(CatchNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public Object doCatch(VirtualFrame frame, Object tag, RubyProc block) {
-            try {
-                return yield(frame, block);
-            } catch (ThrowException e) {
-                if (e.getTag().equals(tag)) {
-                    // TODO(cs): unset rather than set to Nil?
-                    getContext().getCoreLibrary().getGlobalVariablesObject().setInstanceVariable("$!", NilPlaceholder.INSTANCE);
-                    return e.getValue();
-                } else {
-                    throw e;
-                }
-            }
-        }
-    }
-
-    @CoreMethod(names = "eval", isModuleMethod = true, needsSelf = false, minArgs = 1, maxArgs = 2)
-    public abstract static class EvalNode extends CoreMethodNode {
-
-        public EvalNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public EvalNode(EvalNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public Object eval(RubyString source, @SuppressWarnings("unused") UndefinedPlaceholder binding) {
-            return getContext().eval(source.toString());
-        }
-
-        @Specialization
-        public Object eval(RubyString source, RubyBinding binding) {
-            return getContext().eval(source.toString(), binding);
-        }
-
-    }
-
-    @CoreMethod(names = "exec", isModuleMethod = true, needsSelf = false, minArgs = 1, isSplatted = true)
-    public abstract static class ExecNode extends CoreMethodNode {
-
-        public ExecNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public ExecNode(ExecNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public Object require(Object[] args) {
-            final String[] commandLine = new String[args.length];
-
-            for (int n = 0; n < args.length; n++) {
-                commandLine[n] = args[n].toString();
-            }
-
-            exec(getContext(), commandLine);
-
-            return null;
-        }
-
-        @SlowPath
-        private static void exec(RubyContext context, String[] commandLine) {
-            context.implementationMessage("starting child process to simulate exec: ");
-
-            for (int n = 0; n < commandLine.length; n++) {
-                if (n > 0) {
-                    System.err.print(" ");
-                }
-
-                System.err.print(commandLine[n]);
-            }
-
-            final ProcessBuilder builder = new ProcessBuilder(commandLine);
-            builder.inheritIO();
-
-            final RubyHash env = (RubyHash) context.getCoreLibrary().getObjectClass().lookupConstant("ENV");
-
-            for (Map.Entry<Object, Object> entry : env.getMap().entrySet()) {
-                builder.environment().put(entry.getKey().toString(), entry.getValue().toString());
-            }
-
-            Process process;
-
-            try {
-                process = builder.start();
-            } catch (IOException e) {
-                // TODO(cs): proper Ruby exception
-                throw new RuntimeException(e);
-            }
-
-            int exitCode;
-
-            while (true) {
-                try {
-                    exitCode = process.waitFor();
-                    break;
-                } catch (InterruptedException e) {
-                    continue;
-                }
-            }
-
-            context.implementationMessage("child process simulating exec finished");
-
-            System.exit(exitCode);
-        }
-
-    }
-
-    @CoreMethod(names = "exit", isModuleMethod = true, needsSelf = false, minArgs = 0, maxArgs = 1)
-    public abstract static class ExitNode extends CoreMethodNode {
-
-        public ExitNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public ExitNode(ExitNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public Object exit(@SuppressWarnings("unused") UndefinedPlaceholder exitCode) {
-            getContext().shutdown();
-            System.exit(0);
-            return null;
-        }
-
-        @Specialization
-        public Object exit(int exitCode) {
-            getContext().shutdown();
-            System.exit(exitCode);
-            return null;
-        }
-
-    }
-
-    @CoreMethod(names = "gets", isModuleMethod = true, needsSelf = false, maxArgs = 0)
-    public abstract static class GetsNode extends CoreMethodNode {
-
-        public GetsNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public GetsNode(GetsNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public RubyString gets(VirtualFrame frame) {
-            final RubyContext context = getContext();
-
-            final ThreadManager threadManager = context.getThreadManager();
-
-            RubyString line;
-
-            try {
-                final RubyThread runningThread = threadManager.leaveGlobalLock();
-
-                try {
-                    line = context.makeString(context.getConfiguration().getInputReader().readLine(""));
-                } finally {
-                    threadManager.enterGlobalLock(runningThread);
-                }
-            } catch (IOException e) {
-                throw new RuntimeException(e);
-            }
-
-            // Set the local variable $_ in the caller
-
-            final Frame unpacked = frame.getCaller().unpack();
-            final FrameSlot slot = unpacked.getFrameDescriptor().findFrameSlot("$_");
-
-            if (slot != null) {
-                unpacked.setObject(slot, line);
-            }
-
-            return line;
-        }
-    }
-
-    @CoreMethod(names = "Integer", isModuleMethod = true, needsSelf = false, minArgs = 1, maxArgs = 1)
-    public abstract static class IntegerNode extends CoreMethodNode {
-
-        @Child protected DispatchHeadNode toInt;
-
-        public IntegerNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-            toInt = adoptChild(new DispatchHeadNode(context, getSourceSection(), "to_int", false));
-        }
-
-        public IntegerNode(IntegerNode prev) {
-            super(prev);
-            toInt = adoptChild(prev.toInt);
-        }
-
-        @Specialization
-        public int integer(int value) {
-            return value;
-        }
-
-        @Specialization
-        public BigInteger integer(BigInteger value) {
-            return value;
-        }
-
-        @Specialization
-        public int integer(double value) {
-            return (int) value;
-        }
-
-        @Specialization
-        public Object integer(RubyString value) {
-            return value.toInteger();
-        }
-
-        @Specialization
-        public Object integer(VirtualFrame frame, Object value) {
-            return toInt.dispatch(frame, value, null);
-        }
-
-    }
-
-    @CoreMethod(names = "lambda", isModuleMethod = true, needsBlock = true, maxArgs = 0)
-    public abstract static class LambdaNode extends CoreMethodNode {
-
-        public LambdaNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public LambdaNode(LambdaNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public RubyProc proc(Object self, RubyProc block) {
-            return new RubyProc(getContext().getCoreLibrary().getProcClass(), RubyProc.Type.LAMBDA, self, block, block.getMethod());
-
-        }
-    }
-
-    @CoreMethod(names = "load", isModuleMethod = true, needsSelf = false, minArgs = 1, maxArgs = 1)
-    public abstract static class LoadNode extends CoreMethodNode {
-
-        public LoadNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public LoadNode(LoadNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public boolean load(RubyString file) {
-            getContext().loadFile(file.toString());
-            return true;
-        }
-    }
-
-    @CoreMethod(names = "loop", isModuleMethod = true, needsSelf = false, maxArgs = 0)
-    public abstract static class LoopNode extends CoreMethodNode {
-
-        @Child protected WhileNode whileNode;
-
-        public LoopNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-            whileNode = adoptChild(new WhileNode(context, sourceSection, BooleanCastNodeFactory.create(context, sourceSection, new BooleanLiteralNode(context, sourceSection, true)), new YieldNode(
-                            context, getSourceSection(), new RubyNode[]{})));
-        }
-
-        public LoopNode(LoopNode prev) {
-            super(prev);
-            whileNode = adoptChild(prev.whileNode);
-        }
-
-        @Specialization
-        public Object loop(VirtualFrame frame) {
-            return whileNode.execute(frame);
-        }
-    }
-
-    @CoreMethod(names = "print", isModuleMethod = true, needsSelf = false, isSplatted = true)
-    public abstract static class PrintNode extends CoreMethodNode {
-
-        public PrintNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public PrintNode(PrintNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public NilPlaceholder print(Object[] args) {
-            final RubyContext context = getContext();
-            final ThreadManager threadManager = context.getThreadManager();
-
-            final RubyThread runningThread = threadManager.leaveGlobalLock();
-
-            try {
-                for (Object arg : args) {
-                    /*
-                     * TODO(cs): If it's a RubyString and made up of bytes, just write the bytes out
-                     * - using toString will mess up the encoding. We need to stop using toString
-                     * everywhere, and write our own bytes, possibly using JRuby's library for this.
-                     */
-
-                    if (arg instanceof RubyString && !((RubyString) arg).isFromJavaString()) {
-                        try {
-                            context.getConfiguration().getStandardOut().write(((RubyString) arg).getBytes());
-                        } catch (IOException e) {
-                            throw new RuntimeException(e);
-                        }
-                    } else {
-                        context.getConfiguration().getStandardOut().print(arg);
-                    }
-                }
-            } finally {
-                threadManager.enterGlobalLock(runningThread);
-            }
-
-            return NilPlaceholder.INSTANCE;
-        }
-    }
-
-    @CoreMethod(names = "printf", isModuleMethod = true, needsSelf = false, isSplatted = true)
-    public abstract static class PrintfNode extends CoreMethodNode {
-
-        public PrintfNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public PrintfNode(PrintfNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public NilPlaceholder printf(Object[] args) {
-            final RubyContext context = getContext();
-            final ThreadManager threadManager = context.getThreadManager();
-
-            if (args.length > 0) {
-                final String format = ((RubyString) args[0]).toString();
-                final List<Object> values = Arrays.asList(args).subList(1, args.length);
-
-                final RubyThread runningThread = threadManager.leaveGlobalLock();
-
-                try {
-                    StringFormatter.format(context.getConfiguration().getStandardOut(), format, values);
-                } finally {
-                    threadManager.enterGlobalLock(runningThread);
-                }
-            }
-
-            return NilPlaceholder.INSTANCE;
-        }
-    }
-
-    /*
-     * Kernel#pretty_inspect is normally part of stdlib, in pp.rb, but we aren't able to execute
-     * that file yet. Instead we implement a very simple version here, which is the solution
-     * suggested by RubySpec.
-     */
-
-    @CoreMethod(names = "pretty_inspect", maxArgs = 0)
-    public abstract static class PrettyInspectNode extends CoreMethodNode {
-
-        @Child protected DispatchHeadNode toS;
-
-        public PrettyInspectNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-            toS = adoptChild(new DispatchHeadNode(context, getSourceSection(), "to_s", false));
-        }
-
-        public PrettyInspectNode(PrettyInspectNode prev) {
-            super(prev);
-            toS = adoptChild(prev.toS);
-        }
-
-        @Specialization
-        public Object prettyInspect(VirtualFrame frame, Object self) {
-            return toS.dispatch(frame, self, null);
-
-        }
-    }
-
-    @CoreMethod(names = "proc", isModuleMethod = true, needsBlock = true, maxArgs = 0)
-    public abstract static class ProcNode extends CoreMethodNode {
-
-        public ProcNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public ProcNode(ProcNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public RubyProc proc(Object self, RubyProc block) {
-            return new RubyProc(getContext().getCoreLibrary().getProcClass(), RubyProc.Type.PROC, self, block, block.getMethod());
-
-        }
-    }
-
-    @CoreMethod(names = "puts", isModuleMethod = true, needsSelf = false, isSplatted = true)
-    public abstract static class PutsNode extends CoreMethodNode {
-
-        public PutsNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public PutsNode(PutsNode prev) {
-            super(prev);
-        }
-
-        @ExplodeLoop
-        @Specialization
-        public NilPlaceholder puts(Object[] args) {
-            final RubyContext context = getContext();
-            final ThreadManager threadManager = context.getThreadManager();
-            final PrintStream standardOut = context.getConfiguration().getStandardOut();
-
-            final RubyThread runningThread = threadManager.leaveGlobalLock();
-
-            try {
-                if (args.length == 0) {
-                    standardOut.println();
-                } else {
-                    for (int n = 0; n < args.length; n++) {
-                        puts(context, standardOut, args[n]);
-                    }
-                }
-            } finally {
-                threadManager.enterGlobalLock(runningThread);
-            }
-
-            return NilPlaceholder.INSTANCE;
-        }
-
-        @SlowPath
-        private void puts(RubyContext context, PrintStream standardOut, Object value) {
-            if (value instanceof RubyArray) {
-                final RubyArray array = (RubyArray) value;
-
-                for (int n = 0; n < array.size(); n++) {
-                    puts(context, standardOut, array.get(n));
-                }
-            } else {
-                // TODO(CS): slow path send
-                standardOut.println(context.getCoreLibrary().box(value).send("to_s", null));
-            }
-        }
-
-    }
-
-    @CoreMethod(names = "raise", isModuleMethod = true, needsSelf = false, minArgs = 1, maxArgs = 2)
-    public abstract static class RaiseNode extends CoreMethodNode {
-
-        @Child protected DispatchHeadNode initialize;
-
-        public RaiseNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-            initialize = adoptChild(new DispatchHeadNode(context, getSourceSection(), "initialize", false));
-        }
-
-        public RaiseNode(RaiseNode prev) {
-            super(prev);
-            initialize = adoptChild(prev.initialize);
-        }
-
-        @Specialization(order = 1)
-        public Object raise(VirtualFrame frame, RubyString message, @SuppressWarnings("unused") UndefinedPlaceholder undefined) {
-            return raise(frame, getContext().getCoreLibrary().getRuntimeErrorClass(), message);
-        }
-
-        @Specialization(order = 2)
-        public Object raise(VirtualFrame frame, RubyClass exceptionClass, @SuppressWarnings("unused") UndefinedPlaceholder undefined) {
-            return raise(frame, exceptionClass, getContext().makeString(""));
-        }
-
-        @Specialization(order = 3)
-        public Object raise(VirtualFrame frame, RubyClass exceptionClass, RubyString message) {
-            final RubyBasicObject exception = exceptionClass.newInstance();
-            initialize.dispatch(frame, exception, null, message);
-            throw new RaiseException(exception);
-        }
-
-    }
-
-    @CoreMethod(names = "require", isModuleMethod = true, needsSelf = false, minArgs = 1, maxArgs = 1)
-    public abstract static class RequireNode extends CoreMethodNode {
-
-        public RequireNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public RequireNode(RequireNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public boolean require(RubyString feature) {
-            try {
-                getContext().getFeatureManager().require(feature.toString());
-            } catch (IOException e) {
-                throw new RuntimeException(e);
-            }
-
-            return true;
-        }
-    }
-
-    @CoreMethod(names = "set_trace_func", isModuleMethod = true, needsSelf = false, minArgs = 1, maxArgs = 1)
-    public abstract static class SetTraceFuncNode extends CoreMethodNode {
-
-        public SetTraceFuncNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public SetTraceFuncNode(SetTraceFuncNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public NilPlaceholder setTraceFunc(NilPlaceholder proc) {
-            getContext().getTraceManager().setTraceProc(null);
-            return proc;
-        }
-
-        @Specialization
-        public RubyProc setTraceFunc(RubyProc proc) {
-            getContext().getTraceManager().setTraceProc(proc);
-            return proc;
-        }
-
-    }
-
-    @CoreMethod(names = "String", isModuleMethod = true, needsSelf = false, minArgs = 1, maxArgs = 1)
-    public abstract static class StringNode extends CoreMethodNode {
-
-        @Child protected DispatchHeadNode toS;
-
-        public StringNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-            toS = adoptChild(new DispatchHeadNode(context, getSourceSection(), "to_s", false));
-        }
-
-        public StringNode(StringNode prev) {
-            super(prev);
-            toS = adoptChild(prev.toS);
-        }
-
-        @Specialization
-        public RubyString string(int value) {
-            return getContext().makeString(Integer.toString(value));
-        }
-
-        @Specialization
-        public RubyString string(BigInteger value) {
-            return getContext().makeString(value.toString());
-        }
-
-        @Specialization
-        public RubyString string(double value) {
-            return getContext().makeString(Double.toString(value));
-        }
-
-        @Specialization
-        public RubyString string(RubyString value) {
-            return value;
-        }
-
-        @Specialization
-        public Object string(VirtualFrame frame, Object value) {
-            return toS.dispatch(frame, value, null);
-        }
-
-    }
-
-    @CoreMethod(names = "sleep", isModuleMethod = true, needsSelf = false, maxArgs = 1)
-    public abstract static class SleepNode extends CoreMethodNode {
-
-        public SleepNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public SleepNode(SleepNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public double sleep(double duration) {
-            final RubyContext context = getContext();
-
-            final RubyThread runningThread = context.getThreadManager().leaveGlobalLock();
-
-            try {
-                final long start = System.nanoTime();
-
-                try {
-                    Thread.sleep((long) (duration * 1000));
-                } catch (InterruptedException e) {
-                    // Ignore interruption
-                }
-
-                final long end = System.nanoTime();
-
-                return (end - start) / 1e9;
-            } finally {
-                context.getThreadManager().enterGlobalLock(runningThread);
-            }
-        }
-
-        @Specialization
-        public double sleep(int duration) {
-            return sleep((double) duration);
-        }
-
-    }
-
-    @CoreMethod(names = "throw", isModuleMethod = true, needsSelf = false, minArgs = 1, maxArgs = 2)
-    public abstract static class ThrowNode extends CoreMethodNode {
-
-        public ThrowNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public ThrowNode(ThrowNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public Object doThrow(Object tag, UndefinedPlaceholder value) {
-            return doThrow(tag, (Object) value);
-        }
-
-        @Specialization
-        public Object doThrow(Object tag, Object value) {
-            if (value instanceof UndefinedPlaceholder) {
-                throw new ThrowException(tag, NilPlaceholder.INSTANCE);
-            } else {
-                throw new ThrowException(tag, value);
-            }
-        }
-
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/MainNodes.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,70 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.core;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.dsl.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-
-@CoreClass(name = "main")
-public abstract class MainNodes {
-
-    @CoreMethod(names = "include", isSplatted = true, minArgs = 1)
-    public abstract static class IncludeNode extends CoreMethodNode {
-
-        public IncludeNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public IncludeNode(IncludeNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public NilPlaceholder include(RubyObject main, Object[] args) {
-            // TODO(cs): copied from Module - but where does this method really come from?
-
-            // Note that we traverse the arguments backwards
-
-            for (int n = args.length - 1; n >= 0; n--) {
-                if (args[n] instanceof RubyModule) {
-                    final RubyModule included = (RubyModule) args[n];
-
-                    // Note that we do appear to do full method lookup here
-                    included.getLookupNode().lookupMethod("append_features").call(null, included, null, main.getSingletonClass());
-
-                    // TODO(cs): call included hook
-                }
-            }
-
-            return NilPlaceholder.INSTANCE;
-        }
-    }
-
-    @CoreMethod(names = "to_s", needsSelf = false, maxArgs = 0)
-    public abstract static class ToSNode extends CoreMethodNode {
-
-        public ToSNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public ToSNode(ToSNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public RubyString toS() {
-            return getContext().makeString("main");
-        }
-
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/MatchDataNodes.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,81 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.core;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.dsl.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-import com.oracle.truffle.ruby.runtime.core.array.*;
-
-@CoreClass(name = "MatchData")
-public abstract class MatchDataNodes {
-
-    @CoreMethod(names = "[]", minArgs = 1, maxArgs = 1)
-    public abstract static class GetIndexNode extends CoreMethodNode {
-
-        public GetIndexNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public GetIndexNode(GetIndexNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public Object getIndex(RubyMatchData matchData, int index) {
-            return matchData.getValues()[index];
-        }
-
-    }
-
-    @CoreMethod(names = "to_a", maxArgs = 0)
-    public abstract static class ToANode extends CoreMethodNode {
-
-        public ToANode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public ToANode(ToANode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public RubyArray toA(RubyMatchData matchData) {
-            return RubyArray.specializedFromObjects(getContext().getCoreLibrary().getArrayClass(), matchData.getValues());
-        }
-
-    }
-
-    @CoreMethod(names = "values_at", isSplatted = true)
-    public abstract static class ValuesAtNode extends CoreMethodNode {
-
-        public ValuesAtNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public ValuesAtNode(ValuesAtNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public RubyArray valuesAt(RubyMatchData matchData, Object[] args) {
-            final int[] indicies = new int[args.length];
-
-            for (int n = 0; n < args.length; n++) {
-                indicies[n] = (int) args[n];
-            }
-
-            return RubyArray.specializedFromObjects(getContext().getCoreLibrary().getArrayClass(), matchData.valuesAt(indicies));
-        }
-
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/MathNodes.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,77 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.core;
-
-import java.math.*;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.dsl.*;
-import com.oracle.truffle.ruby.runtime.*;
-
-@CoreClass(name = "Math")
-public abstract class MathNodes {
-
-    @CoreMethod(names = "sqrt", isModuleMethod = true, needsSelf = false, minArgs = 1, maxArgs = 1)
-    public abstract static class SqrtNode extends CoreMethodNode {
-
-        public SqrtNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public SqrtNode(SqrtNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public double sqrt(int a) {
-            return Math.sqrt(a);
-        }
-
-        @Specialization
-        public double sqrt(BigInteger a) {
-            return Math.sqrt(a.doubleValue());
-        }
-
-        @Specialization
-        public double sqrt(double a) {
-            return Math.sqrt(a);
-        }
-
-    }
-
-    @CoreMethod(names = "exp", isModuleMethod = true, needsSelf = false, minArgs = 1, maxArgs = 1)
-    public abstract static class ExpNode extends CoreMethodNode {
-
-        public ExpNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public ExpNode(ExpNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public double exp(int a) {
-            return Math.exp(a);
-        }
-
-        @Specialization
-        public double exp(BigInteger a) {
-            return Math.exp(a.doubleValue());
-        }
-
-        @Specialization
-        public double exp(double a) {
-            return Math.exp(a);
-        }
-
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/ModuleNodes.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,652 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.core;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.dsl.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.nodes.control.*;
-import com.oracle.truffle.ruby.nodes.methods.arguments.*;
-import com.oracle.truffle.ruby.nodes.objects.*;
-import com.oracle.truffle.ruby.nodes.objects.instancevariables.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.RubyParser.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-import com.oracle.truffle.ruby.runtime.core.array.*;
-import com.oracle.truffle.ruby.runtime.methods.*;
-
-@CoreClass(name = "Module")
-public abstract class ModuleNodes {
-
-    @CoreMethod(names = "alias_method", minArgs = 2, maxArgs = 2)
-    public abstract static class AliasMethodNode extends CoreMethodNode {
-
-        public AliasMethodNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public AliasMethodNode(AliasMethodNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public RubyModule aliasMethod(RubyModule module, RubySymbol newName, RubySymbol oldName) {
-            module.alias(newName.toString(), oldName.toString());
-            return module;
-        }
-    }
-
-    @CoreMethod(names = "append_features", minArgs = 1, maxArgs = 1)
-    public abstract static class AppendFeaturesNode extends CoreMethodNode {
-
-        public AppendFeaturesNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public AppendFeaturesNode(AppendFeaturesNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public NilPlaceholder appendFeatures(RubyModule module, RubyModule other) {
-            module.appendFeatures(other);
-            return NilPlaceholder.INSTANCE;
-        }
-    }
-
-    @CoreMethod(names = "attr_reader", isSplatted = true, appendCallNode = true)
-    public abstract static class AttrReaderNode extends CoreMethodNode {
-
-        public AttrReaderNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public AttrReaderNode(AttrReaderNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public NilPlaceholder attrReader(RubyModule module, Object[] args) {
-            final Node callSite = (Node) args[args.length - 1];
-            final SourceSection sourceSection = callSite.getSourceSection();
-
-            for (int n = 0; n < args.length - 1; n++) {
-                attrReader(getContext(), sourceSection, module, args[n].toString());
-            }
-
-            return NilPlaceholder.INSTANCE;
-        }
-
-        public static void attrReader(RubyContext context, SourceSection sourceSection, RubyModule module, String name) {
-            CompilerDirectives.transferToInterpreter();
-
-            final CheckArityNode checkArity = new CheckArityNode(context, sourceSection, Arity.NO_ARGS);
-
-            final SelfNode self = new SelfNode(context, sourceSection);
-            final UninitializedReadInstanceVariableNode readInstanceVariable = new UninitializedReadInstanceVariableNode(context, sourceSection, name, self);
-
-            final SequenceNode block = new SequenceNode(context, sourceSection, checkArity, readInstanceVariable);
-
-            final RubyRootNode pristineRoot = new RubyRootNode(sourceSection, null, name + "(attr_reader)", block);
-            final CallTarget callTarget = Truffle.getRuntime().createCallTarget(NodeUtil.cloneNode(pristineRoot));
-            final InlinableMethodImplementation methodImplementation = new InlinableMethodImplementation(callTarget, null, new FrameDescriptor(), pristineRoot, true, false);
-            final RubyMethod method = new RubyMethod(sourceSection, module, new UniqueMethodIdentifier(), null, name, Visibility.PUBLIC, false, methodImplementation);
-
-            module.addMethod(method);
-        }
-    }
-
-    @CoreMethod(names = "attr_writer", isSplatted = true, appendCallNode = true)
-    public abstract static class AttrWriterNode extends CoreMethodNode {
-
-        public AttrWriterNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public AttrWriterNode(AttrWriterNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public NilPlaceholder attrWriter(RubyModule module, Object[] args) {
-            final Node callSite = (Node) args[args.length - 1];
-            final SourceSection sourceSection = callSite.getSourceSection();
-
-            for (int n = 0; n < args.length - 1; n++) {
-                attrWriter(getContext(), sourceSection, module, args[n].toString());
-            }
-
-            return NilPlaceholder.INSTANCE;
-        }
-
-        public static void attrWriter(RubyContext context, SourceSection sourceSection, RubyModule module, String name) {
-            CompilerDirectives.transferToInterpreter();
-
-            final CheckArityNode checkArity = new CheckArityNode(context, sourceSection, Arity.ONE_ARG);
-
-            final SelfNode self = new SelfNode(context, sourceSection);
-            final ReadPreArgumentNode readArgument = new ReadPreArgumentNode(context, sourceSection, 0, false);
-            final UninitializedWriteInstanceVariableNode writeInstanceVariable = new UninitializedWriteInstanceVariableNode(context, sourceSection, name, self, readArgument);
-
-            final SequenceNode block = new SequenceNode(context, sourceSection, checkArity, writeInstanceVariable);
-
-            final RubyRootNode pristineRoot = new RubyRootNode(sourceSection, null, name + "(attr_writer)", block);
-            final CallTarget callTarget = Truffle.getRuntime().createCallTarget(NodeUtil.cloneNode(pristineRoot));
-            final InlinableMethodImplementation methodImplementation = new InlinableMethodImplementation(callTarget, null, new FrameDescriptor(), pristineRoot, true, false);
-            final RubyMethod method = new RubyMethod(sourceSection, module, new UniqueMethodIdentifier(), null, name + "=", Visibility.PUBLIC, false, methodImplementation);
-
-            module.addMethod(method);
-        }
-    }
-
-    @CoreMethod(names = {"attr_accessor", "attr"}, isSplatted = true, appendCallNode = true)
-    public abstract static class AttrAccessorNode extends CoreMethodNode {
-
-        public AttrAccessorNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public AttrAccessorNode(AttrAccessorNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public NilPlaceholder attrAccessor(RubyModule module, Object[] args) {
-            final Node callSite = (Node) args[args.length - 1];
-            final SourceSection sourceSection = callSite.getSourceSection();
-
-            for (int n = 0; n < args.length - 1; n++) {
-                attrAccessor(getContext(), sourceSection, module, args[n].toString());
-            }
-
-            return NilPlaceholder.INSTANCE;
-        }
-
-        public static void attrAccessor(RubyContext context, SourceSection sourceSection, RubyModule module, String name) {
-            CompilerDirectives.transferToInterpreter();
-            AttrReaderNode.attrReader(context, sourceSection, module, name);
-            AttrWriterNode.attrWriter(context, sourceSection, module, name);
-        }
-
-    }
-
-    @CoreMethod(names = "class_eval", minArgs = 1, maxArgs = 3)
-    public abstract static class ClassEvalNode extends CoreMethodNode {
-
-        public ClassEvalNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public ClassEvalNode(ClassEvalNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public Object classEval(VirtualFrame frame, RubyModule module, RubyString code, @SuppressWarnings("unused") UndefinedPlaceholder file, @SuppressWarnings("unused") UndefinedPlaceholder line) {
-            final Source source = getContext().getSourceManager().get("(eval)", code.toString());
-            return getContext().execute(getContext(), source, ParserContext.MODULE, module, frame.materialize());
-        }
-
-        @Specialization
-        public Object classEval(VirtualFrame frame, RubyModule module, RubyString code, RubyString file, @SuppressWarnings("unused") UndefinedPlaceholder line) {
-            final Source source = getContext().getSourceManager().get(file.toString(), code.toString());
-            return getContext().execute(getContext(), source, ParserContext.MODULE, module, frame.materialize());
-        }
-
-        @Specialization
-        public Object classEval(VirtualFrame frame, RubyModule module, RubyString code, RubyString file, @SuppressWarnings("unused") int line) {
-            final Source source = getContext().getSourceManager().get(file.toString(), code.toString());
-            return getContext().execute(getContext(), source, ParserContext.MODULE, module, frame.materialize());
-        }
-
-    }
-
-    @CoreMethod(names = "class_variable_defined?", maxArgs = 0)
-    public abstract static class ClassVariableDefinedNode extends CoreMethodNode {
-
-        public ClassVariableDefinedNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public ClassVariableDefinedNode(ClassVariableDefinedNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public boolean isClassVariableDefined(RubyModule module, RubyString name) {
-            return module.lookupClassVariable(name.toString()) != null;
-        }
-
-        @Specialization
-        public boolean isClassVariableDefined(RubyModule module, RubySymbol name) {
-            return module.lookupClassVariable(name.toString()) != null;
-        }
-
-    }
-
-    @CoreMethod(names = "constants", maxArgs = 0)
-    public abstract static class ConstantsNode extends CoreMethodNode {
-
-        public ConstantsNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public ConstantsNode(ConstantsNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public RubyArray constants(@SuppressWarnings("unused") RubyModule module) {
-            getContext().implementationMessage("Module#constants returns an empty array");
-            return new RubyArray(getContext().getCoreLibrary().getArrayClass());
-        }
-    }
-
-    @CoreMethod(names = "const_defined?", minArgs = 1, maxArgs = 2)
-    public abstract static class ConstDefinedNode extends CoreMethodNode {
-
-        public ConstDefinedNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public ConstDefinedNode(ConstDefinedNode prev) {
-            super(prev);
-        }
-
-        @Specialization(order = 1)
-        public boolean isConstDefined(RubyModule module, RubyString name, @SuppressWarnings("unused") UndefinedPlaceholder inherit) {
-            return module.lookupConstant(name.toString()) != null;
-        }
-
-        @Specialization(order = 2)
-        public boolean isConstDefined(RubyModule module, RubyString name, boolean inherit) {
-            if (inherit) {
-                return module.lookupConstant(name.toString()) != null;
-            } else {
-                return module.getConstants().containsKey(name.toString());
-            }
-        }
-
-        @Specialization(order = 3)
-        public boolean isConstDefined(RubyModule module, RubySymbol name, @SuppressWarnings("unused") UndefinedPlaceholder inherit) {
-            return module.lookupConstant(name.toString()) != null;
-        }
-
-        public boolean isConstDefined(RubyModule module, RubySymbol name, boolean inherit) {
-            if (inherit) {
-                return module.lookupConstant(name.toString()) != null;
-            } else {
-                return module.getConstants().containsKey(name.toString());
-            }
-        }
-
-    }
-
-    @CoreMethod(names = "define_method", needsBlock = true, minArgs = 1, maxArgs = 2)
-    public abstract static class DefineMethodNode extends CoreMethodNode {
-
-        public DefineMethodNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public DefineMethodNode(DefineMethodNode prev) {
-            super(prev);
-        }
-
-        @Specialization(order = 1)
-        public RubyMethod defineMethod(RubyModule module, RubyString name, @SuppressWarnings("unused") UndefinedPlaceholder proc, RubyProc block) {
-            final RubyMethod method = block.getMethod();
-            module.addMethod(method.withNewName(name.toString()));
-            return method;
-        }
-
-        @Specialization(order = 2)
-        public RubyMethod defineMethod(RubyModule module, RubyString name, RubyProc proc, @SuppressWarnings("unused") UndefinedPlaceholder block) {
-            final RubyMethod method = proc.getMethod();
-            module.addMethod(method.withNewName(name.toString()));
-            return method;
-        }
-
-        @Specialization(order = 3)
-        public RubyMethod defineMethod(RubyModule module, RubySymbol name, @SuppressWarnings("unused") UndefinedPlaceholder proc, RubyProc block) {
-            final RubyMethod method = block.getMethod();
-            module.addMethod(method.withNewName(name.toString()));
-            return method;
-        }
-
-        @Specialization(order = 4)
-        public RubyMethod defineMethod(RubyModule module, RubySymbol name, RubyProc proc, @SuppressWarnings("unused") UndefinedPlaceholder block) {
-            final RubyMethod method = proc.getMethod();
-            module.addMethod(method.withNewName(name.toString()));
-            return method;
-        }
-
-    }
-
-    @CoreMethod(names = "include", isSplatted = true, minArgs = 1)
-    public abstract static class IncludeNode extends CoreMethodNode {
-
-        public IncludeNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public IncludeNode(IncludeNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public NilPlaceholder include(RubyModule module, Object[] args) {
-            // Note that we traverse the arguments backwards
-
-            for (int n = args.length - 1; n >= 0; n--) {
-                if (args[n] instanceof RubyModule) {
-                    final RubyModule included = (RubyModule) args[n];
-
-                    // Note that we do appear to do full method lookup here
-                    included.getLookupNode().lookupMethod("append_features").call(null, included, null, module);
-
-                    // TODO(cs): call included hook
-                }
-            }
-
-            return NilPlaceholder.INSTANCE;
-        }
-    }
-
-    @CoreMethod(names = "method_defined?", minArgs = 1, maxArgs = 2)
-    public abstract static class MethodDefinedNode extends CoreMethodNode {
-
-        public MethodDefinedNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public MethodDefinedNode(MethodDefinedNode prev) {
-            super(prev);
-        }
-
-        @Specialization(order = 1)
-        public boolean isMethodDefined(RubyModule module, RubyString name, @SuppressWarnings("unused") UndefinedPlaceholder inherit) {
-            return module.lookupMethod(name.toString()) != null;
-        }
-
-        @Specialization(order = 2)
-        public boolean isMethodDefined(RubyModule module, RubyString name, boolean inherit) {
-            if (inherit) {
-                return module.lookupMethod(name.toString()) != null;
-            } else {
-                return module.getMethods().containsKey(name.toString());
-            }
-        }
-
-        @Specialization(order = 3)
-        public boolean isMethodDefined(RubyModule module, RubySymbol name, @SuppressWarnings("unused") UndefinedPlaceholder inherit) {
-            return module.lookupMethod(name.toString()) != null;
-        }
-
-        public boolean isMethodDefined(RubyModule module, RubySymbol name, boolean inherit) {
-            if (inherit) {
-                return module.lookupMethod(name.toString()) != null;
-            } else {
-                return module.getMethods().containsKey(name.toString());
-            }
-        }
-    }
-
-    @CoreMethod(names = "module_eval", minArgs = 1, maxArgs = 3)
-    public abstract static class ModuleEvalNode extends CoreMethodNode {
-
-        public ModuleEvalNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public ModuleEvalNode(ModuleEvalNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public RubyModule moduleEval(RubyModule module, RubyString code, @SuppressWarnings("unused") Object file, @SuppressWarnings("unused") Object line) {
-            module.moduleEval(code.toString());
-            return module;
-        }
-    }
-
-    @CoreMethod(names = "module_function", isSplatted = true)
-    public abstract static class ModuleFunctionNode extends CoreMethodNode {
-
-        public ModuleFunctionNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public ModuleFunctionNode(ModuleFunctionNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public NilPlaceholder moduleFunction(VirtualFrame frame, RubyModule module, Object... args) {
-            if (args.length == 0) {
-                final Frame unpacked = frame.getCaller().unpack();
-
-                final FrameSlot slot = unpacked.getFrameDescriptor().findFrameSlot(RubyModule.MODULE_FUNCTION_FLAG_FRAME_SLOT_ID);
-
-                /*
-                 * setObject, even though it's a boolean, so we can getObject and either get the
-                 * default Nil or the boolean value without triggering deoptimization.
-                 */
-
-                unpacked.setObject(slot, true);
-            } else {
-                for (Object argument : args) {
-                    final String methodName = argument.toString();
-                    module.getSingletonClass().addMethod(module.lookupMethod(methodName));
-                }
-            }
-
-            return NilPlaceholder.INSTANCE;
-        }
-    }
-
-    @CoreMethod(names = "public", isSplatted = true)
-    public abstract static class PublicNode extends CoreMethodNode {
-
-        public PublicNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public PublicNode(PublicNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public RubyModule doPublic(VirtualFrame frame, RubyModule module, Object... args) {
-            module.visibilityMethod(frame.getCaller(), args, Visibility.PUBLIC);
-            return module;
-        }
-    }
-
-    @CoreMethod(names = "private", isSplatted = true)
-    public abstract static class PrivateNode extends CoreMethodNode {
-
-        public PrivateNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public PrivateNode(PrivateNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public RubyModule doPrivate(VirtualFrame frame, RubyModule module, Object... args) {
-            module.visibilityMethod(frame.getCaller(), args, Visibility.PRIVATE);
-            return module;
-        }
-    }
-
-    @CoreMethod(names = "private_class_method", isSplatted = true)
-    public abstract static class PrivateClassMethodNode extends CoreMethodNode {
-
-        public PrivateClassMethodNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public PrivateClassMethodNode(PrivateClassMethodNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public RubyModule privateClassMethod(RubyModule module, Object... args) {
-            final RubyClass moduleSingleton = module.getSingletonClass();
-
-            for (Object arg : args) {
-                final RubyMethod method = moduleSingleton.lookupMethod(arg.toString());
-
-                if (method == null) {
-                    throw new RuntimeException("Couldn't find method " + arg.toString());
-                }
-
-                moduleSingleton.addMethod(method.withNewVisibility(Visibility.PRIVATE));
-            }
-
-            return module;
-        }
-    }
-
-    @CoreMethod(names = "private_constant", isSplatted = true)
-    public abstract static class PrivateConstantNode extends CoreMethodNode {
-
-        public PrivateConstantNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public PrivateConstantNode(PrivateConstantNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public RubyModule privateConstnat(RubyModule module, @SuppressWarnings("unused") Object... args) {
-            getContext().implementationMessage("private_constant does nothing at the moment");
-            return module;
-        }
-    }
-
-    @CoreMethod(names = "protected", isSplatted = true)
-    public abstract static class ProtectedNode extends CoreMethodNode {
-
-        public ProtectedNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public ProtectedNode(ProtectedNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public RubyModule doProtected(RubyModule module, @SuppressWarnings("unused") Object... args) {
-            getContext().implementationMessage("protected does nothing at the moment");
-            return module;
-        }
-    }
-
-    @CoreMethod(names = "remove_class_variable", minArgs = 1, maxArgs = 1)
-    public abstract static class RemoveClassVariableNode extends CoreMethodNode {
-
-        public RemoveClassVariableNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public RemoveClassVariableNode(RemoveClassVariableNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public RubyModule removeClassVariable(RubyModule module, RubyString name) {
-            module.removeClassVariable(name.toString());
-            return module;
-        }
-
-        @Specialization
-        public RubyModule removeClassVariable(RubyModule module, RubySymbol name) {
-            module.removeClassVariable(name.toString());
-            return module;
-        }
-
-    }
-
-    @CoreMethod(names = "remove_method", minArgs = 1, maxArgs = 1)
-    public abstract static class RemoveMethodNode extends CoreMethodNode {
-
-        public RemoveMethodNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public RemoveMethodNode(RemoveMethodNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public RubyModule removeMethod(RubyModule module, RubyString name) {
-            module.removeMethod(name.toString());
-            return module;
-        }
-
-        @Specialization
-        public RubyModule removeMethod(RubyModule module, RubySymbol name) {
-            module.removeMethod(name.toString());
-            return module;
-        }
-
-    }
-
-    @CoreMethod(names = "to_s", maxArgs = 0)
-    public abstract static class ToSNode extends CoreMethodNode {
-
-        public ToSNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public ToSNode(ToSNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public RubyString toS(RubyModule module) {
-            return getContext().makeString(module.getName());
-        }
-    }
-
-    @CoreMethod(names = "undef_method", minArgs = 1, maxArgs = 1)
-    public abstract static class UndefMethodNode extends CoreMethodNode {
-
-        public UndefMethodNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public UndefMethodNode(UndefMethodNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public RubyModule undefMethod(RubyModule module, RubyString name) {
-            final RubyMethod method = module.lookupMethod(name.toString());
-            module.undefMethod(method);
-            return module;
-        }
-
-        @Specialization
-        public RubyModule undefMethod(RubyModule module, RubySymbol name) {
-            final RubyMethod method = module.lookupMethod(name.toString());
-            module.undefMethod(method);
-            return module;
-        }
-
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/NilClassNodes.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,141 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.core;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.dsl.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-
-@CoreClass(name = "NilClass")
-public abstract class NilClassNodes {
-
-    @CoreMethod(names = "!", needsSelf = false, maxArgs = 0)
-    public abstract static class NotNode extends CoreMethodNode {
-
-        public NotNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public NotNode(NotNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public boolean not() {
-            return true;
-        }
-    }
-
-    @CoreMethod(names = "==", needsSelf = false, minArgs = 1, maxArgs = 1)
-    public abstract static class EqualNode extends CoreMethodNode {
-
-        public EqualNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public EqualNode(EqualNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public boolean equal(Object b) {
-            return b instanceof NilPlaceholder || b instanceof RubyNilClass;
-        }
-
-    }
-
-    @CoreMethod(names = "!=", needsSelf = false, minArgs = 1, maxArgs = 1)
-    public abstract static class NotEqualNode extends CoreMethodNode {
-
-        public NotEqualNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public NotEqualNode(NotEqualNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public boolean equal(Object b) {
-            return !(b instanceof NilPlaceholder || b instanceof RubyNilClass);
-        }
-
-    }
-
-    @CoreMethod(names = "inspect", needsSelf = false, maxArgs = 0)
-    public abstract static class InpsectNode extends CoreMethodNode {
-
-        public InpsectNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public InpsectNode(InpsectNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public RubyString inspect() {
-            return getContext().makeString("nil");
-        }
-    }
-
-    @CoreMethod(names = "nil?", needsSelf = false, maxArgs = 0)
-    public abstract static class NilNode extends CoreMethodNode {
-
-        public NilNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public NilNode(NilNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public boolean nil() {
-            return true;
-        }
-    }
-
-    @CoreMethod(names = "to_i", needsSelf = false, maxArgs = 0)
-    public abstract static class ToINode extends CoreMethodNode {
-
-        public ToINode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public ToINode(ToINode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public int toI() {
-            return 0;
-        }
-    }
-
-    @CoreMethod(names = "to_s", needsSelf = false, maxArgs = 0)
-    public abstract static class ToSNode extends CoreMethodNode {
-
-        public ToSNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public ToSNode(ToSNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public RubyString toS() {
-            return getContext().makeString("");
-        }
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/ObjectNodes.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,514 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.core;
-
-import java.math.*;
-import java.util.*;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.dsl.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-import com.oracle.truffle.ruby.runtime.core.array.*;
-import com.oracle.truffle.ruby.runtime.methods.*;
-import com.oracle.truffle.ruby.runtime.objects.*;
-
-@CoreClass(name = "Object")
-public abstract class ObjectNodes {
-
-    @CoreMethod(names = "class", maxArgs = 0)
-    public abstract static class ClassNode extends CoreMethodNode {
-
-        public ClassNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public ClassNode(ClassNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public RubyClass getClass(boolean value) {
-            if (value) {
-                return getContext().getCoreLibrary().getTrueClass();
-            } else {
-                return getContext().getCoreLibrary().getFalseClass();
-            }
-        }
-
-        @Specialization
-        public RubyClass getClass(@SuppressWarnings("unused") int value) {
-            return getContext().getCoreLibrary().getFixnumClass();
-        }
-
-        @Specialization
-        public RubyClass getClass(@SuppressWarnings("unused") BigInteger value) {
-            return getContext().getCoreLibrary().getBignumClass();
-        }
-
-        @Specialization
-        public RubyClass getClass(@SuppressWarnings("unused") double value) {
-            return getContext().getCoreLibrary().getFloatClass();
-        }
-
-        @Specialization
-        public RubyClass getClass(RubyBasicObject self) {
-            return self.getRubyClass();
-        }
-
-    }
-
-    @CoreMethod(names = "dup", maxArgs = 0)
-    public abstract static class DupNode extends CoreMethodNode {
-
-        public DupNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public DupNode(DupNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public Object dup(RubyObject self) {
-            return self.dup();
-        }
-
-    }
-
-    @CoreMethod(names = "extend", isSplatted = true, minArgs = 1)
-    public abstract static class ExtendNode extends CoreMethodNode {
-
-        public ExtendNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public ExtendNode(ExtendNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public RubyBasicObject extend(RubyBasicObject self, Object[] args) {
-            for (int n = 0; n < args.length; n++) {
-                self.extend((RubyModule) args[n]);
-            }
-
-            return self;
-        }
-
-    }
-
-    @CoreMethod(names = "freeze", maxArgs = 0)
-    public abstract static class FreezeNode extends CoreMethodNode {
-
-        public FreezeNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public FreezeNode(FreezeNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public RubyObject freeze(RubyObject self) {
-            self.frozen = true;
-            return self;
-        }
-
-    }
-
-    @CoreMethod(names = "frozen?", maxArgs = 0)
-    public abstract static class FrozenNode extends CoreMethodNode {
-
-        public FrozenNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public FrozenNode(FrozenNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public boolean isFrozen(RubyObject self) {
-            return self.frozen;
-        }
-
-    }
-
-    @CoreMethod(names = "inspect", maxArgs = 0)
-    public abstract static class InspectNode extends CoreMethodNode {
-
-        public InspectNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public InspectNode(InspectNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public RubyString inspect(boolean value) {
-            return getContext().makeString(Boolean.toString(value));
-        }
-
-        @Specialization
-        public RubyString inspect(int value) {
-            return getContext().makeString(Integer.toString(value));
-        }
-
-        @Specialization
-        public RubyString inspect(BigInteger value) {
-            return getContext().makeString(value.toString());
-        }
-
-        @Specialization
-        public RubyString inspect(double value) {
-            return getContext().makeString(Double.toString(value));
-        }
-
-        @Specialization
-        public RubyString inspect(RubyObject self) {
-            return getContext().makeString(self.inspect());
-        }
-
-    }
-
-    @CoreMethod(names = "instance_eval", needsBlock = true, maxArgs = 0)
-    public abstract static class InstanceEvalNode extends CoreMethodNode {
-
-        public InstanceEvalNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public InstanceEvalNode(InstanceEvalNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public Object instanceEval(VirtualFrame frame, RubyObject self, RubyProc block) {
-            return block.callWithModifiedSelf(frame.pack(), self);
-        }
-
-    }
-
-    @CoreMethod(names = "instance_variable_defined?", minArgs = 1, maxArgs = 1)
-    public abstract static class InstanceVariableDefinedNode extends CoreMethodNode {
-
-        public InstanceVariableDefinedNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public InstanceVariableDefinedNode(InstanceVariableDefinedNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public boolean isInstanceVariableDefined(RubyBasicObject object, RubyString name) {
-            return object.isInstanceVariableDefined(RubyObject.checkInstanceVariableName(getContext(), name.toString()));
-        }
-
-        @Specialization
-        public boolean isInstanceVariableDefined(RubyBasicObject object, RubySymbol name) {
-            return object.isInstanceVariableDefined(RubyObject.checkInstanceVariableName(getContext(), name.toString()));
-        }
-
-    }
-
-    @CoreMethod(names = "instance_variable_get", minArgs = 1, maxArgs = 1)
-    public abstract static class InstanceVariableGetNode extends CoreMethodNode {
-
-        public InstanceVariableGetNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public InstanceVariableGetNode(InstanceVariableGetNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public Object isInstanceVariableGet(RubyBasicObject object, RubyString name) {
-            return object.getInstanceVariable(RubyObject.checkInstanceVariableName(getContext(), name.toString()));
-        }
-
-        @Specialization
-        public Object isInstanceVariableGet(RubyBasicObject object, RubySymbol name) {
-            return object.getInstanceVariable(RubyObject.checkInstanceVariableName(getContext(), name.toString()));
-        }
-
-    }
-
-    @CoreMethod(names = "instance_variable_set", minArgs = 2, maxArgs = 2)
-    public abstract static class InstanceVariableSetNode extends CoreMethodNode {
-
-        public InstanceVariableSetNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public InstanceVariableSetNode(InstanceVariableSetNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public Object isInstanceVariableSet(RubyBasicObject object, RubyString name, Object value) {
-            object.setInstanceVariable(RubyObject.checkInstanceVariableName(getContext(), name.toString()), value);
-            return value;
-        }
-
-        @Specialization
-        public Object isInstanceVariableSet(RubyBasicObject object, RubySymbol name, Object value) {
-            object.setInstanceVariable(RubyObject.checkInstanceVariableName(getContext(), name.toString()), value);
-            return value;
-        }
-
-    }
-
-    @CoreMethod(names = "instance_variables", maxArgs = 0)
-    public abstract static class InstanceVariablesNode extends CoreMethodNode {
-
-        public InstanceVariablesNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public InstanceVariablesNode(InstanceVariablesNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public RubyArray instanceVariables(RubyObject self) {
-            final String[] instanceVariableNames = self.getInstanceVariableNames();
-
-            Arrays.sort(instanceVariableNames);
-
-            final RubyArray array = new RubyArray(getContext().getCoreLibrary().getArrayClass());
-
-            for (String name : instanceVariableNames) {
-                array.push(new RubyString(getContext().getCoreLibrary().getStringClass(), name));
-            }
-
-            return array;
-        }
-
-    }
-
-    @CoreMethod(names = {"is_a?", "instance_of?", "kind_of?"}, minArgs = 1, maxArgs = 1)
-    public abstract static class IsANode extends CoreMethodNode {
-
-        public IsANode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public IsANode(IsANode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public boolean isA(@SuppressWarnings("unused") RubyObject self, @SuppressWarnings("unused") NilPlaceholder nil) {
-            return false;
-        }
-
-        @Specialization
-        public boolean isA(RubyObject self, RubyClass rubyClass) {
-            return self.getRubyClass().assignableTo(rubyClass);
-        }
-
-    }
-
-    @CoreMethod(names = "methods", minArgs = 0, maxArgs = 1)
-    public abstract static class MethodsNode extends CoreMethodNode {
-
-        public MethodsNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public MethodsNode(MethodsNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public RubyArray methods(RubyObject self, boolean includeInherited) {
-            if (!includeInherited) {
-                self.getRubyClass().getContext().implementationMessage("Object#methods always returns inherited methods at the moment");
-            }
-
-            return methods(self, UndefinedPlaceholder.INSTANCE);
-        }
-
-        @Specialization
-        public RubyArray methods(RubyObject self, @SuppressWarnings("unused") UndefinedPlaceholder includeInherited) {
-            final RubyArray array = new RubyArray(self.getRubyClass().getContext().getCoreLibrary().getArrayClass());
-
-            final Map<String, RubyMethod> methods = new HashMap<>();
-
-            self.getLookupNode().getMethods(methods);
-
-            for (RubyMethod method : methods.values()) {
-                if (method.getVisibility() == Visibility.PUBLIC || method.getVisibility() == Visibility.PROTECTED) {
-                    array.push(new RubySymbol(self.getRubyClass().getContext().getCoreLibrary().getSymbolClass(), method.getName()));
-                }
-            }
-
-            return array;
-        }
-
-    }
-
-    @CoreMethod(names = "nil?", needsSelf = false, maxArgs = 0)
-    public abstract static class NilNode extends CoreMethodNode {
-
-        public NilNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public NilNode(NilNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public boolean nil() {
-            return false;
-        }
-    }
-
-    @CoreMethod(names = "object_id", needsSelf = true, maxArgs = 0)
-    public abstract static class ObjectIDNode extends CoreMethodNode {
-
-        public ObjectIDNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public ObjectIDNode(ObjectIDNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public Object objectID(RubyBasicObject object) {
-            return GeneralConversions.fixnumOrBignum(object.getObjectID());
-        }
-
-    }
-
-    @CoreMethod(names = "respond_to?", minArgs = 1, maxArgs = 2)
-    public abstract static class RespondToNode extends CoreMethodNode {
-
-        public RespondToNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public RespondToNode(RespondToNode prev) {
-            super(prev);
-        }
-
-        @Specialization(order = 1)
-        public boolean doesRespondTo(Object object, RubyString name, @SuppressWarnings("unused") UndefinedPlaceholder checkVisibility) {
-            return doesRespondTo(getContext().getCoreLibrary().box(object), name.toString(), false);
-        }
-
-        @Specialization(order = 2)
-        public boolean doesRespondTo(Object object, RubyString name, boolean dontCheckVisibility) {
-            return doesRespondTo(getContext().getCoreLibrary().box(object), name.toString(), dontCheckVisibility);
-        }
-
-        @Specialization(order = 3)
-        public boolean doesRespondTo(Object object, RubySymbol name, @SuppressWarnings("unused") UndefinedPlaceholder checkVisibility) {
-            return doesRespondTo(getContext().getCoreLibrary().box(object), name.toString(), false);
-        }
-
-        @Specialization(order = 4)
-        public boolean doesRespondTo(Object object, RubySymbol name, boolean dontCheckVisibility) {
-            return doesRespondTo(getContext().getCoreLibrary().box(object), name.toString(), dontCheckVisibility);
-        }
-
-        private static boolean doesRespondTo(RubyBasicObject object, String name, boolean dontCheckVisibility) {
-            final RubyMethod method = object.getLookupNode().lookupMethod(name);
-
-            if (method == null || method.isUndefined()) {
-                return false;
-            }
-
-            if (dontCheckVisibility) {
-                return true;
-            } else {
-                return method.getVisibility() == Visibility.PUBLIC;
-            }
-        }
-
-    }
-
-    @CoreMethod(names = "singleton_class", maxArgs = 0)
-    public abstract static class SingletonClassNode extends CoreMethodNode {
-
-        public SingletonClassNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public SingletonClassNode(SingletonClassNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public RubyClass singletonClass(RubyBasicObject self) {
-            return self.getSingletonClass();
-        }
-
-    }
-
-    @CoreMethod(names = "singleton_methods", minArgs = 0, maxArgs = 1)
-    public abstract static class SingletonMethodsNode extends CoreMethodNode {
-
-        public SingletonMethodsNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public SingletonMethodsNode(SingletonMethodsNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public RubyArray singletonMethods(RubyObject self, boolean includeInherited) {
-            if (!includeInherited) {
-                self.getRubyClass().getContext().implementationMessage("Object#singleton_methods always returns inherited methods at the moment");
-            }
-
-            return singletonMethods(self, UndefinedPlaceholder.INSTANCE);
-        }
-
-        @Specialization
-        public RubyArray singletonMethods(RubyObject self, @SuppressWarnings("unused") UndefinedPlaceholder includeInherited) {
-            final RubyArray array = new RubyArray(self.getRubyClass().getContext().getCoreLibrary().getArrayClass());
-
-            for (RubyMethod method : self.getSingletonClass().getDeclaredMethods()) {
-                array.push(new RubySymbol(self.getRubyClass().getContext().getCoreLibrary().getSymbolClass(), method.getName()));
-            }
-
-            return array;
-        }
-
-    }
-
-    @CoreMethod(names = "to_s", maxArgs = 0)
-    public abstract static class ToSNode extends CoreMethodNode {
-
-        public ToSNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public ToSNode(ToSNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public RubyString toS(RubyObject self) {
-            return getContext().makeString(self.toString());
-        }
-
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/ObjectSpaceNodes.java	Sun Feb 23 17:00:35 2014 -0800
+++ /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. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.core;
-
-import java.math.*;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.dsl.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-import com.oracle.truffle.ruby.runtime.objects.*;
-
-@CoreClass(name = "ObjectSpace")
-public abstract class ObjectSpaceNodes {
-
-    @CoreMethod(names = "_id2ref", isModuleMethod = true, needsSelf = false, minArgs = 1, maxArgs = 1)
-    public abstract static class ID2RefNode extends CoreMethodNode {
-
-        public ID2RefNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public ID2RefNode(ID2RefNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public Object id2Ref(int id) {
-            final Object object = getContext().getObjectSpaceManager().lookupId(id);
-
-            if (object == null) {
-                return NilPlaceholder.INSTANCE;
-            } else {
-                return object;
-            }
-        }
-
-        @Specialization
-        public Object id2Ref(BigInteger id) {
-            final Object object = getContext().getObjectSpaceManager().lookupId(id.longValue());
-
-            if (object == null) {
-                return NilPlaceholder.INSTANCE;
-            } else {
-                return object;
-            }
-        }
-
-    }
-
-    @CoreMethod(names = "each_object", isModuleMethod = true, needsSelf = false, needsBlock = true, minArgs = 0, maxArgs = 1)
-    public abstract static class EachObjectNode extends YieldingCoreMethodNode {
-
-        public EachObjectNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public EachObjectNode(EachObjectNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public NilPlaceholder eachObject(VirtualFrame frame, @SuppressWarnings("unused") UndefinedPlaceholder ofClass, RubyProc block) {
-            for (RubyBasicObject object : getContext().getObjectSpaceManager().getObjects()) {
-                yield(frame, block, object);
-            }
-            return NilPlaceholder.INSTANCE;
-        }
-
-        @Specialization
-        public NilPlaceholder eachObject(VirtualFrame frame, RubyClass ofClass, RubyProc block) {
-            for (RubyBasicObject object : getContext().getObjectSpaceManager().getObjects()) {
-                if (object.getRubyClass().assignableTo(ofClass)) {
-                    yield(frame, block, object);
-                }
-            }
-            return NilPlaceholder.INSTANCE;
-        }
-
-    }
-
-    @CoreMethod(names = "define_finalizer", isModuleMethod = true, needsSelf = false, minArgs = 2, maxArgs = 2)
-    public abstract static class DefineFinalizerNode extends CoreMethodNode {
-
-        public DefineFinalizerNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public DefineFinalizerNode(DefineFinalizerNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public RubyProc defineFinalizer(Object object, RubyProc finalizer) {
-            getContext().getObjectSpaceManager().defineFinalizer((RubyBasicObject) object, finalizer);
-            return finalizer;
-        }
-    }
-
-    @CoreMethod(names = {"garbage_collect", "start"}, isModuleMethod = true, needsSelf = false, maxArgs = 0)
-    public abstract static class GarbageCollectNode extends CoreMethodNode {
-
-        public GarbageCollectNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public GarbageCollectNode(GarbageCollectNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public NilPlaceholder garbageCollect() {
-            final RubyThread runningThread = getContext().getThreadManager().leaveGlobalLock();
-
-            try {
-                System.gc();
-            } finally {
-                getContext().getThreadManager().enterGlobalLock(runningThread);
-            }
-
-            return NilPlaceholder.INSTANCE;
-        }
-    }
-
-    @CoreMethod(names = "undefine_finalizer", isModuleMethod = true, needsSelf = false, minArgs = 1, maxArgs = 1)
-    public abstract static class UndefineFinalizerNode extends CoreMethodNode {
-
-        public UndefineFinalizerNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public UndefineFinalizerNode(UndefineFinalizerNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public Object undefineFinalizer(Object object) {
-            getContext().getObjectSpaceManager().undefineFinalizer((RubyBasicObject) object);
-            return object;
-        }
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/ProcNodes.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,77 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.core;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.dsl.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-
-@CoreClass(name = "Proc")
-public abstract class ProcNodes {
-
-    @CoreMethod(names = {"call", "[]"}, isSplatted = true)
-    public abstract static class CallNode extends CoreMethodNode {
-
-        public CallNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public CallNode(CallNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public Object call(VirtualFrame frame, RubyProc proc, Object[] args) {
-            return proc.call(frame.getCaller(), args);
-        }
-
-    }
-
-    @CoreMethod(names = "initialize", needsBlock = true, maxArgs = 0)
-    public abstract static class InitializeNode extends CoreMethodNode {
-
-        public InitializeNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public InitializeNode(InitializeNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public NilPlaceholder initialize(VirtualFrame frame, RubyProc proc, RubyProc block) {
-            final RubyArguments callerArguments = frame.getCaller().unpack().getArguments(RubyArguments.class);
-            proc.initialize(RubyProc.Type.PROC, callerArguments.getSelf(), callerArguments.getBlock(), block.getMethod());
-            return NilPlaceholder.INSTANCE;
-        }
-
-    }
-
-    @CoreMethod(names = "lambda?", maxArgs = 0)
-    public abstract static class LambdaNode extends CoreMethodNode {
-
-        public LambdaNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public LambdaNode(LambdaNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public boolean lambda(RubyProc proc) {
-            return proc.getType() == RubyProc.Type.LAMBDA;
-        }
-
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/ProcessNodes.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.core;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.dsl.*;
-import com.oracle.truffle.ruby.runtime.*;
-
-@CoreClass(name = "Process")
-public abstract class ProcessNodes {
-
-    @CoreMethod(names = "pid", isModuleMethod = true, needsSelf = false, maxArgs = 0)
-    public abstract static class PidNode extends CoreMethodNode {
-
-        public PidNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public PidNode(PidNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public int pid() {
-            return getContext().getPOSIX().getpid();
-        }
-
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/RangeNodes.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,275 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.core;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.dsl.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.utilities.*;
-import com.oracle.truffle.ruby.nodes.call.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.control.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-import com.oracle.truffle.ruby.runtime.core.array.*;
-import com.oracle.truffle.ruby.runtime.core.range.*;
-
-@CoreClass(name = "Range")
-public abstract class RangeNodes {
-
-    @CoreMethod(names = {"collect", "map"}, needsBlock = true, maxArgs = 0)
-    public abstract static class CollectNode extends YieldingCoreMethodNode {
-
-        public CollectNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public CollectNode(CollectNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public RubyArray collect(VirtualFrame frame, FixnumRange range, RubyProc block) {
-            final RubyContext context = getContext();
-
-            final RubyArray array = new RubyArray(context.getCoreLibrary().getArrayClass());
-
-            for (int n = range.getBegin(); n < range.getExclusiveEnd(); n++) {
-                array.push(yield(frame, block, n));
-            }
-
-            return array;
-        }
-
-    }
-
-    @CoreMethod(names = "each", needsBlock = true, maxArgs = 0)
-    public abstract static class EachNode extends YieldingCoreMethodNode {
-
-        private final BranchProfile breakProfile = new BranchProfile();
-        private final BranchProfile nextProfile = new BranchProfile();
-        private final BranchProfile redoProfile = new BranchProfile();
-
-        public EachNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public EachNode(EachNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public Object each(VirtualFrame frame, FixnumRange range, RubyProc block) {
-            outer: for (int n = range.getBegin(); n < range.getExclusiveEnd(); n++) {
-                while (true) {
-                    try {
-                        yield(frame, block, n);
-                        continue outer;
-                    } catch (BreakException e) {
-                        breakProfile.enter();
-                        return e.getResult();
-                    } catch (NextException e) {
-                        nextProfile.enter();
-                        continue outer;
-                    } catch (RedoException e) {
-                        redoProfile.enter();
-                    }
-                }
-            }
-
-            return range;
-        }
-
-    }
-
-    @CoreMethod(names = "exclude_end?", maxArgs = 0)
-    public abstract static class ExcludeEndNode extends CoreMethodNode {
-
-        public ExcludeEndNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public ExcludeEndNode(ExcludeEndNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public boolean excludeEnd(RubyRange range) {
-            return range.doesExcludeEnd();
-        }
-
-    }
-
-    @CoreMethod(names = "first", maxArgs = 0)
-    public abstract static class FirstNode extends CoreMethodNode {
-
-        public FirstNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public FirstNode(FirstNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public int each(FixnumRange range) {
-            return range.getBegin();
-        }
-
-        @Specialization
-        public Object each(ObjectRange range) {
-            return range.getBegin();
-        }
-
-    }
-
-    @CoreMethod(names = "include?", maxArgs = 1)
-    public abstract static class IncludeNode extends CoreMethodNode {
-
-        @Child protected DispatchHeadNode callLess;
-        @Child protected DispatchHeadNode callGreater;
-        @Child protected DispatchHeadNode callGreaterEqual;
-
-        public IncludeNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-            callLess = adoptChild(new DispatchHeadNode(context, getSourceSection(), "<", false));
-            callGreater = adoptChild(new DispatchHeadNode(context, getSourceSection(), ">", false));
-            callGreaterEqual = adoptChild(new DispatchHeadNode(context, getSourceSection(), ">=", false));
-        }
-
-        public IncludeNode(IncludeNode prev) {
-            super(prev);
-            callLess = adoptChild(prev.callLess);
-            callGreater = adoptChild(prev.callGreater);
-            callGreaterEqual = adoptChild(prev.callGreaterEqual);
-        }
-
-        @Specialization
-        public boolean include(FixnumRange range, int value) {
-            return value >= range.getBegin() && value < range.getExclusiveEnd();
-        }
-
-        @Specialization
-        public boolean include(VirtualFrame frame, ObjectRange range, Object value) {
-            if ((boolean) callLess.dispatch(frame, value, null, range.getBegin())) {
-                return false;
-            }
-
-            if (range.doesExcludeEnd()) {
-                if ((boolean) callGreaterEqual.dispatch(frame, value, null, range.getEnd())) {
-                    return false;
-                }
-            } else {
-                if ((boolean) callGreater.dispatch(frame, value, null, range.getEnd())) {
-                    return false;
-                }
-            }
-
-            return true;
-        }
-    }
-
-    @CoreMethod(names = "last", maxArgs = 0)
-    public abstract static class LastNode extends CoreMethodNode {
-
-        public LastNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public LastNode(LastNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public int last(FixnumRange range) {
-            return range.getEnd();
-        }
-
-        @Specialization
-        public Object last(ObjectRange range) {
-            return range.getEnd();
-        }
-
-    }
-
-    @CoreMethod(names = "step", needsBlock = true, minArgs = 1, maxArgs = 1)
-    public abstract static class StepNode extends YieldingCoreMethodNode {
-
-        private final BranchProfile breakProfile = new BranchProfile();
-        private final BranchProfile nextProfile = new BranchProfile();
-        private final BranchProfile redoProfile = new BranchProfile();
-
-        public StepNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public StepNode(StepNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public Object step(VirtualFrame frame, FixnumRange range, int step, RubyProc block) {
-            outer: for (int n = range.getBegin(); n < range.getExclusiveEnd(); n += step) {
-                while (true) {
-                    try {
-                        yield(frame, block, n);
-                        continue outer;
-                    } catch (BreakException e) {
-                        breakProfile.enter();
-                        return e.getResult();
-                    } catch (NextException e) {
-                        nextProfile.enter();
-                        continue outer;
-                    } catch (RedoException e) {
-                        redoProfile.enter();
-                    }
-                }
-            }
-
-            return range;
-        }
-
-    }
-
-    @CoreMethod(names = "to_a", maxArgs = 0)
-    public abstract static class ToANode extends CoreMethodNode {
-
-        public ToANode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public ToANode(ToANode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public RubyArray toA(RubyRange range) {
-            return range.toArray();
-        }
-
-    }
-
-    @CoreMethod(names = "to_s", maxArgs = 0)
-    public abstract static class ToSNode extends CoreMethodNode {
-
-        public ToSNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public ToSNode(ToSNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public RubyString toS(RubyRange range) {
-            return getContext().makeString(range.toString());
-        }
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/RegexpNodes.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,114 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.core;
-
-import java.util.regex.*;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.dsl.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-
-@CoreClass(name = "Regexp")
-public abstract class RegexpNodes {
-
-    @CoreMethod(names = {"=~", "==="}, minArgs = 1, maxArgs = 1)
-    public abstract static class MatchOperatorNode extends CoreMethodNode {
-
-        public MatchOperatorNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public MatchOperatorNode(MatchOperatorNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public Object match(VirtualFrame frame, RubyRegexp regexp, RubyString string) {
-            return regexp.matchOperator(frame.getCaller().unpack(), string.toString());
-        }
-
-    }
-
-    @CoreMethod(names = "!~", minArgs = 1, maxArgs = 1)
-    public abstract static class NotMatchOperatorNode extends CoreMethodNode {
-
-        public NotMatchOperatorNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public NotMatchOperatorNode(NotMatchOperatorNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public Object match(VirtualFrame frame, RubyRegexp regexp, RubyString string) {
-            return regexp.matchOperator(frame.getCaller().unpack(), string.toString()) == NilPlaceholder.INSTANCE;
-        }
-
-    }
-
-    @CoreMethod(names = "escape", isModuleMethod = true, needsSelf = false, minArgs = 1, maxArgs = 1)
-    public abstract static class EscapeNode extends CoreMethodNode {
-
-        public EscapeNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public EscapeNode(EscapeNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public RubyString sqrt(RubyString pattern) {
-            return getContext().makeString(Pattern.quote(pattern.toString()));
-        }
-
-    }
-
-    @CoreMethod(names = "initialize", minArgs = 1, maxArgs = 1)
-    public abstract static class InitializeNode extends CoreMethodNode {
-
-        public InitializeNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public InitializeNode(InitializeNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public NilPlaceholder initialize(RubyRegexp regexp, RubyString string) {
-            regexp.initialize(string.toString());
-            return NilPlaceholder.INSTANCE;
-        }
-
-    }
-
-    @CoreMethod(names = "match", minArgs = 1, maxArgs = 1)
-    public abstract static class MatchNode extends CoreMethodNode {
-
-        public MatchNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public MatchNode(MatchNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public Object match(RubyRegexp regexp, RubyString string) {
-            return regexp.match(string.toString());
-        }
-
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/SignalNodes.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.core;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.dsl.*;
-import com.oracle.truffle.ruby.runtime.*;
-
-@CoreClass(name = "Signal")
-public abstract class SignalNodes {
-
-    @CoreMethod(names = "trap", isModuleMethod = true, needsSelf = false, minArgs = 1, maxArgs = 1)
-    public abstract static class SignalNode extends CoreMethodNode {
-
-        public SignalNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public SignalNode(SignalNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public NilPlaceholder trap(@SuppressWarnings("unused") Object signal) {
-            getContext().implementationMessage("Signal#trap doesn't do anything");
-            return NilPlaceholder.INSTANCE;
-        }
-
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/StringNodes.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,559 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.core;
-
-import java.util.*;
-import java.util.regex.*;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.dsl.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-import com.oracle.truffle.ruby.runtime.core.array.*;
-
-@CoreClass(name = "String")
-public abstract class StringNodes {
-
-    @CoreMethod(names = "+", minArgs = 1, maxArgs = 1)
-    public abstract static class AddNode extends CoreMethodNode {
-
-        public AddNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public AddNode(AddNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public RubyString add(RubyString a, RubyString b) {
-            return new RubyString(a.getRubyClass().getContext().getCoreLibrary().getStringClass(), a.toString() + b.toString());
-        }
-    }
-
-    @CoreMethod(names = {"==", "==="}, minArgs = 1, maxArgs = 1)
-    public abstract static class EqualNode extends CoreMethodNode {
-
-        public EqualNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public EqualNode(EqualNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public boolean equal(@SuppressWarnings("unused") RubyString a, @SuppressWarnings("unused") NilPlaceholder b) {
-            return false;
-        }
-
-        @Specialization
-        public boolean equal(RubyString a, RubyString b) {
-            return a.toString().equals(b.toString());
-        }
-    }
-
-    @CoreMethod(names = "!=", minArgs = 1, maxArgs = 1)
-    public abstract static class NotEqualNode extends CoreMethodNode {
-
-        public NotEqualNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public NotEqualNode(NotEqualNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public boolean equal(@SuppressWarnings("unused") RubyString a, @SuppressWarnings("unused") NilPlaceholder b) {
-            return true;
-        }
-
-        @Specialization
-        public boolean notEqual(RubyString a, RubyString b) {
-            return !a.toString().equals(b.toString());
-        }
-
-    }
-
-    @CoreMethod(names = "<=>", minArgs = 1, maxArgs = 1)
-    public abstract static class CompareNode extends CoreMethodNode {
-
-        public CompareNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public CompareNode(CompareNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public int compare(RubyString a, RubyString b) {
-            return a.toString().compareTo(b.toString());
-        }
-    }
-
-    @CoreMethod(names = "<<", minArgs = 1, maxArgs = 1)
-    public abstract static class ConcatNode extends CoreMethodNode {
-
-        public ConcatNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public ConcatNode(ConcatNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public RubyString concat(RubyString string, RubyString other) {
-            string.replace(string.toString() + other.toString());
-            return string;
-        }
-    }
-
-    @CoreMethod(names = "%", minArgs = 1, maxArgs = 1, isSplatted = true)
-    public abstract static class FormatNode extends CoreMethodNode {
-
-        public FormatNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public FormatNode(FormatNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public RubyString format(RubyString format, Object[] args) {
-            final RubyContext context = getContext();
-
-            if (args.length == 1 && args[0] instanceof RubyArray) {
-                return context.makeString(StringFormatter.format(format.toString(), ((RubyArray) args[0]).asList()));
-            } else {
-                return context.makeString(StringFormatter.format(format.toString(), Arrays.asList(args)));
-            }
-        }
-    }
-
-    @CoreMethod(names = "[]", minArgs = 1, maxArgs = 2, isSplatted = true)
-    public abstract static class GetIndexNode extends CoreMethodNode {
-
-        public GetIndexNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public GetIndexNode(GetIndexNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public Object getIndex(RubyString string, Object[] args) {
-            return RubyString.getIndex(getContext(), string.toString(), args);
-        }
-    }
-
-    @CoreMethod(names = "=~", minArgs = 1, maxArgs = 1)
-    public abstract static class MatchOperatorNode extends CoreMethodNode {
-
-        public MatchOperatorNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public MatchOperatorNode(MatchOperatorNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public Object match(VirtualFrame frame, RubyString string, RubyRegexp regexp) {
-            return regexp.matchOperator(frame, string.toString());
-        }
-    }
-
-    @CoreMethod(names = "chomp", maxArgs = 0)
-    public abstract static class ChompNode extends CoreMethodNode {
-
-        public ChompNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public ChompNode(ChompNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public RubyString chomp(RubyString string) {
-            return string.getRubyClass().getContext().makeString(string.toString().trim());
-        }
-    }
-
-    @CoreMethod(names = "chomp!", maxArgs = 0)
-    public abstract static class ChompBangNode extends CoreMethodNode {
-
-        public ChompBangNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public ChompBangNode(ChompBangNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public RubyString chompBang(RubyString string) {
-            string.replace(string.toString().trim());
-            return string;
-        }
-    }
-
-    @CoreMethod(names = "downcase", maxArgs = 0)
-    public abstract static class DowncaseNode extends CoreMethodNode {
-
-        public DowncaseNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public DowncaseNode(DowncaseNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public RubyString downcase(RubyString string) {
-            return string.getRubyClass().getContext().makeString(string.toString().toLowerCase());
-        }
-    }
-
-    @CoreMethod(names = "downcase!", maxArgs = 0)
-    public abstract static class DowncaseBangNode extends CoreMethodNode {
-
-        public DowncaseBangNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public DowncaseBangNode(DowncaseBangNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public RubyString downcase(RubyString string) {
-            string.replace(string.toString().toLowerCase());
-            return string;
-        }
-    }
-
-    @CoreMethod(names = "empty?", maxArgs = 0)
-    public abstract static class EmptyNode extends CoreMethodNode {
-
-        public EmptyNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public EmptyNode(EmptyNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public boolean empty(RubyString string) {
-            return string.toString().isEmpty();
-        }
-    }
-
-    @CoreMethod(names = "end_with?", minArgs = 1, maxArgs = 1)
-    public abstract static class EndWithNode extends CoreMethodNode {
-
-        public EndWithNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public EndWithNode(EndWithNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public boolean endWith(RubyString string, RubyString b) {
-            return string.toString().endsWith(b.toString());
-        }
-    }
-
-    @CoreMethod(names = "gsub", minArgs = 2, maxArgs = 2)
-    public abstract static class GsubNode extends CoreMethodNode {
-
-        public GsubNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public GsubNode(GsubNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public RubyString gsub(RubyString string, RubyString regexpString, RubyString replacement) {
-            final RubyRegexp regexp = new RubyRegexp(getContext().getCoreLibrary().getRegexpClass(), regexpString.toString());
-            return gsub(string, regexp, replacement);
-        }
-
-        @Specialization
-        public RubyString gsub(RubyString string, RubyRegexp regexp, RubyString replacement) {
-            return getContext().makeString(regexp.getPattern().matcher(string.toString()).replaceAll(replacement.toString()));
-        }
-    }
-
-    @CoreMethod(names = "inspect", maxArgs = 0)
-    public abstract static class InspectNode extends CoreMethodNode {
-
-        public InspectNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public InspectNode(InspectNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public RubyString inspect(RubyString string) {
-            return getContext().makeString("\"" + string.toString().replace("\\", "\\\\").replace("\"", "\\\"") + "\"");
-        }
-    }
-
-    @CoreMethod(names = "ljust", minArgs = 1, maxArgs = 2)
-    public abstract static class LjustNode extends CoreMethodNode {
-
-        public LjustNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public LjustNode(LjustNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public RubyString ljust(RubyString string, int length, @SuppressWarnings("unused") UndefinedPlaceholder padding) {
-            return getContext().makeString(RubyString.ljust(string.toString(), length, " "));
-        }
-
-        @Specialization
-        public RubyString ljust(RubyString string, int length, RubyString padding) {
-            return getContext().makeString(RubyString.ljust(string.toString(), length, padding.toString()));
-        }
-
-    }
-
-    @CoreMethod(names = "size", maxArgs = 0)
-    public abstract static class SizeNode extends CoreMethodNode {
-
-        public SizeNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public SizeNode(SizeNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public int size(RubyString string) {
-            return string.toString().length();
-        }
-    }
-
-    @CoreMethod(names = "match", minArgs = 1, maxArgs = 1)
-    public abstract static class MatchNode extends CoreMethodNode {
-
-        public MatchNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public MatchNode(MatchNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public Object match(RubyString string, RubyString regexpString) {
-            final RubyRegexp regexp = new RubyRegexp(getContext().getCoreLibrary().getRegexpClass(), regexpString.toString());
-            return regexp.match(string.toString());
-        }
-
-        @Specialization
-        public Object match(RubyString string, RubyRegexp regexp) {
-            return regexp.match(string.toString());
-        }
-    }
-
-    @CoreMethod(names = "rjust", minArgs = 1, maxArgs = 2)
-    public abstract static class RjustNode extends CoreMethodNode {
-
-        public RjustNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public RjustNode(RjustNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public RubyString rjust(RubyString string, int length, @SuppressWarnings("unused") UndefinedPlaceholder padding) {
-            return getContext().makeString(RubyString.rjust(string.toString(), length, " "));
-        }
-
-        @Specialization
-        public RubyString rjust(RubyString string, int length, RubyString padding) {
-            return getContext().makeString(RubyString.rjust(string.toString(), length, padding.toString()));
-        }
-
-    }
-
-    @CoreMethod(names = "scan", minArgs = 1, maxArgs = 1)
-    public abstract static class ScanNode extends CoreMethodNode {
-
-        public ScanNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public ScanNode(ScanNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public RubyArray scan(RubyString string, RubyString regexp) {
-            return RubyString.scan(getContext(), string.toString(), Pattern.compile(regexp.toString()));
-        }
-
-        @Specialization
-        public RubyArray scan(RubyString string, RubyRegexp regexp) {
-            return RubyString.scan(getContext(), string.toString(), regexp.getPattern());
-        }
-
-    }
-
-    @CoreMethod(names = "split", minArgs = 1, maxArgs = 1)
-    public abstract static class SplitNode extends CoreMethodNode {
-
-        public SplitNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public SplitNode(SplitNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public RubyArray split(RubyString string, RubyString sep) {
-            final RubyContext context = getContext();
-
-            final String[] components = string.toString().split(Pattern.quote(sep.toString()));
-
-            final Object[] objects = new Object[components.length];
-
-            for (int n = 0; n < objects.length; n++) {
-                objects[n] = context.makeString(components[n]);
-            }
-
-            return RubyArray.specializedFromObjects(context.getCoreLibrary().getArrayClass(), objects);
-        }
-
-        @Specialization
-        public RubyArray split(RubyString string, RubyRegexp sep) {
-            final RubyContext context = getContext();
-
-            final String[] components = string.toString().split(sep.getPattern().pattern());
-
-            final Object[] objects = new Object[components.length];
-
-            for (int n = 0; n < objects.length; n++) {
-                objects[n] = context.makeString(components[n]);
-            }
-
-            return RubyArray.specializedFromObjects(context.getCoreLibrary().getArrayClass(), objects);
-        }
-    }
-
-    @CoreMethod(names = "start_with?", minArgs = 1, maxArgs = 1)
-    public abstract static class StartWithNode extends CoreMethodNode {
-
-        public StartWithNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public StartWithNode(StartWithNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public boolean endWith(RubyString string, RubyString b) {
-            return string.toString().startsWith(b.toString());
-        }
-    }
-
-    @CoreMethod(names = "to_f", maxArgs = 0)
-    public abstract static class ToFNode extends CoreMethodNode {
-
-        public ToFNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public ToFNode(ToFNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public double toF(RubyString string) {
-            return Double.parseDouble(string.toString());
-        }
-    }
-
-    @CoreMethod(names = "to_i", maxArgs = 0)
-    public abstract static class ToINode extends CoreMethodNode {
-
-        public ToINode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public ToINode(ToINode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public Object toI(RubyString string) {
-            return string.toInteger();
-        }
-    }
-
-    @CoreMethod(names = "to_s", maxArgs = 0)
-    public abstract static class ToSNode extends CoreMethodNode {
-
-        public ToSNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public ToSNode(ToSNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public RubyString toF(RubyString string) {
-            return string;
-        }
-    }
-
-    @CoreMethod(names = {"to_sym", "intern"}, maxArgs = 0)
-    public abstract static class ToSymNode extends CoreMethodNode {
-
-        public ToSymNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public ToSymNode(ToSymNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public RubySymbol toSym(RubyString string) {
-            return new RubySymbol(getContext().getCoreLibrary().getSymbolClass(), string.toString());
-        }
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/StructNodes.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,56 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.core;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.dsl.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-
-@CoreClass(name = "Struct")
-public abstract class StructNodes {
-
-    @CoreMethod(names = "initialize", needsBlock = true, appendCallNode = true, isSplatted = true)
-    public abstract static class InitalizeNode extends CoreMethodNode {
-
-        public InitalizeNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public InitalizeNode(InitalizeNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public NilPlaceholder initialize(VirtualFrame frame, RubyClass struct, Object[] args, Object block, Node callSite) {
-            CompilerDirectives.transferToInterpreter();
-
-            final RubySymbol[] symbols = new RubySymbol[args.length];
-
-            for (int n = 0; n < args.length; n++) {
-                symbols[n] = (RubySymbol) args[n];
-            }
-
-            for (RubySymbol symbol : symbols) {
-                ModuleNodes.AttrAccessorNode.attrAccessor(getContext(), callSite.getSourceSection(), struct, symbol.toString());
-            }
-
-            if (!RubyNilClass.isNil(block)) {
-                ((RubyProc) block).callWithModifiedSelf(frame.pack(), struct);
-            }
-
-            return NilPlaceholder.INSTANCE;
-        }
-
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/SymbolNodes.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,107 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.core;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.dsl.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-
-@CoreClass(name = "Symbol")
-public abstract class SymbolNodes {
-
-    @CoreMethod(names = {"==", "==="}, minArgs = 1, maxArgs = 1)
-    public abstract static class EqualNode extends CoreMethodNode {
-
-        public EqualNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public EqualNode(EqualNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public boolean equal(@SuppressWarnings("unused") RubyString a, @SuppressWarnings("unused") NilPlaceholder b) {
-            return false;
-        }
-
-        @Specialization
-        public boolean equal(RubySymbol a, RubySymbol b) {
-            return a.toString().equals(b.toString());
-        }
-
-        @Specialization
-        public boolean equal(RubySymbol a, RubyString b) {
-            return a.toString().equals(b.toString());
-        }
-
-        @Specialization
-        public boolean equal(RubySymbol a, int b) {
-            return a.toString().equals(Integer.toString(b));
-        }
-
-    }
-
-    @CoreMethod(names = "empty?", maxArgs = 0)
-    public abstract static class EmptyNode extends CoreMethodNode {
-
-        public EmptyNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public EmptyNode(EmptyNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public boolean empty(RubySymbol symbol) {
-            return symbol.toString().isEmpty();
-        }
-
-    }
-
-    @CoreMethod(names = "to_proc", maxArgs = 0)
-    public abstract static class ToProcNode extends CoreMethodNode {
-
-        public ToProcNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public ToProcNode(ToProcNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public RubyProc toProc(RubySymbol symbol) {
-            // TODO(CS): this should be doing all kinds of caching
-            return symbol.toProc();
-        }
-    }
-
-    @CoreMethod(names = "to_sym", maxArgs = 0)
-    public abstract static class ToSymNode extends CoreMethodNode {
-
-        public ToSymNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public ToSymNode(ToSymNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public RubySymbol toSym(RubySymbol symbol) {
-            return symbol;
-        }
-
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/SystemNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,69 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.core;
-
-import java.io.*;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-
-/**
- * Represents an expression that is evaluated by running it as a system command via forking and
- * execing, and then taking stdout as a string.
- */
-@NodeInfo(shortName = "system")
-public class SystemNode extends RubyNode {
-
-    @Child protected RubyNode child;
-
-    public SystemNode(RubyContext context, SourceSection sourceSection, RubyNode child) {
-        super(context, sourceSection);
-        this.child = adoptChild(child);
-    }
-
-    @Override
-    public Object execute(VirtualFrame frame) {
-        final RubyContext context = getContext();
-
-        final String command = child.execute(frame).toString();
-
-        Process process;
-
-        try {
-            // We need to run via bash to get the variable and other expansion we expect
-            process = Runtime.getRuntime().exec(new String[]{"bash", "-c", command});
-        } catch (IOException e) {
-            throw new RuntimeException(e);
-        }
-
-        final InputStream stdout = process.getInputStream();
-        final BufferedReader reader = new BufferedReader(new InputStreamReader(stdout));
-
-        final StringBuilder resultBuilder = new StringBuilder();
-
-        String line;
-
-        // TODO(cs): this isn't great for binary output
-
-        try {
-            while ((line = reader.readLine()) != null) {
-                resultBuilder.append(line);
-                resultBuilder.append("\n");
-            }
-        } catch (IOException e) {
-            throw new RuntimeException(e);
-        }
-
-        return context.makeString(resultBuilder.toString());
-    }
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/ThreadNodes.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,58 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.core;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.dsl.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-
-@CoreClass(name = "Thread")
-public abstract class ThreadNodes {
-
-    @CoreMethod(names = "initialize", needsBlock = true, maxArgs = 0)
-    public abstract static class InitializeNode extends CoreMethodNode {
-
-        public InitializeNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public InitializeNode(InitializeNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public NilPlaceholder initialize(RubyThread thread, RubyProc block) {
-            thread.initialize(block);
-            return NilPlaceholder.INSTANCE;
-        }
-
-    }
-
-    @CoreMethod(names = "join", maxArgs = 0)
-    public abstract static class JoinNode extends CoreMethodNode {
-
-        public JoinNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public JoinNode(JoinNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public RubyThread join(RubyThread self) {
-            self.join();
-            return self;
-        }
-
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/TimeNodes.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,56 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.core;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.dsl.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-
-@CoreClass(name = "Time")
-public abstract class TimeNodes {
-
-    @CoreMethod(names = "-", minArgs = 1, maxArgs = 1)
-    public abstract static class SubNode extends CoreMethodNode {
-
-        public SubNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public SubNode(SubNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public double sub(RubyTime a, RubyTime b) {
-            return a.subtract(b);
-        }
-
-    }
-
-    @CoreMethod(names = "now", isModuleMethod = true, needsSelf = false, maxArgs = 0)
-    public abstract static class NowNode extends CoreMethodNode {
-
-        public NowNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public NowNode(NowNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public RubyTime now() {
-            return RubyTime.fromDate(getContext().getCoreLibrary().getTimeClass(), System.currentTimeMillis());
-        }
-
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/TrueClassNodes.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,97 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.core;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.dsl.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-
-@CoreClass(name = "TrueClass")
-public abstract class TrueClassNodes {
-
-    @CoreMethod(names = "!", needsSelf = false, maxArgs = 0)
-    public abstract static class NotNode extends CoreMethodNode {
-
-        public NotNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public NotNode(NotNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public boolean not() {
-            return false;
-        }
-
-    }
-
-    @CoreMethod(names = {"==", "===", "=~"}, needsSelf = false, minArgs = 1, maxArgs = 1)
-    public abstract static class EqualNode extends CoreMethodNode {
-
-        public EqualNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public EqualNode(EqualNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public boolean equal(boolean other) {
-            return other;
-        }
-
-        @Specialization
-        public boolean equal(Object other) {
-            return other instanceof Boolean && ((boolean) other);
-        }
-
-    }
-
-    @CoreMethod(names = "^", needsSelf = false, minArgs = 1, maxArgs = 1)
-    public abstract static class XorNode extends CoreMethodNode {
-
-        public XorNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public XorNode(XorNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public boolean xor(boolean other) {
-            return true ^ other;
-        }
-
-    }
-
-    @CoreMethod(names = "to_s", needsSelf = false, maxArgs = 0)
-    public abstract static class ToSNode extends CoreMethodNode {
-
-        public ToSNode(RubyContext context, SourceSection sourceSection) {
-            super(context, sourceSection);
-        }
-
-        public ToSNode(ToSNode prev) {
-            super(prev);
-        }
-
-        @Specialization
-        public RubyString toS() {
-            return getContext().makeString("true");
-        }
-
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/YieldingCoreMethodNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,40 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.core;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.ruby.nodes.yield.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-
-public abstract class YieldingCoreMethodNode extends CoreMethodNode {
-
-    @Child protected YieldDispatchNode dispatchNode;
-
-    public YieldingCoreMethodNode(RubyContext context, SourceSection sourceSection) {
-        super(context, sourceSection);
-        dispatchNode = adoptChild(new UninitializedYieldDispatchNode(context, getSourceSection()));
-    }
-
-    public YieldingCoreMethodNode(YieldingCoreMethodNode prev) {
-        super(prev);
-        dispatchNode = adoptChild(prev.dispatchNode);
-    }
-
-    public Object yield(VirtualFrame frame, RubyProc block, Object... arguments) {
-        return dispatchNode.dispatch(frame, block, arguments);
-    }
-
-    public boolean yieldBoolean(VirtualFrame frame, RubyProc block, Object... arguments) {
-        return GeneralConversions.toBoolean(dispatchNode.dispatch(frame, block, arguments));
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/instrument/MinimalRubyNodeInstrumenter.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,48 +0,0 @@
-/*
- * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.instrument;
-
-import com.oracle.truffle.api.nodes.instrument.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.debug.*;
-import com.oracle.truffle.ruby.runtime.methods.*;
-
-/**
- * Utility for instrumenting Ruby AST nodes to support the language's built-in <A
- * href="http://www.ruby-doc.org/core-2.0.0/Kernel.html#method-i-set_trace_func">tracing
- * facility</A>. It ignores nodes other than {@linkplain NodePhylum#STATEMENT statements}.
- */
-public final class MinimalRubyNodeInstrumenter extends DefaultNodeInstrumenter implements RubyNodeInstrumenter {
-
-    // TODO (mlvdv) convert methods to the general interface? will help with dependencies
-
-    public RubyNode instrumentAsStatement(RubyNode rubyNode) {
-        assert rubyNode != null;
-        assert !(rubyNode instanceof RubyProxyNode);
-        final RubyContext context = rubyNode.getContext();
-        if (context.getConfiguration().getTrace()) {
-            final RubyProxyNode proxy = new RubyProxyNode(context, rubyNode);
-            proxy.markAs(NodePhylum.STATEMENT);
-            proxy.getProbeChain().appendProbe(new RubyTraceProbe(context));
-            return proxy;
-        }
-        return rubyNode;
-    }
-
-    public RubyNode instrumentAsCall(RubyNode node, String callName) {
-        return node;
-    }
-
-    public RubyNode instrumentAsLocalAssignment(RubyNode node, UniqueMethodIdentifier methodIdentifier, String localName) {
-        return node;
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/instrument/RubyNodeInstrumenter.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,54 +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.ruby.nodes.instrument;
-
-import com.oracle.truffle.api.nodes.instrument.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.methods.*;
-
-public interface RubyNodeInstrumenter extends NodeInstrumenter {
-
-    /**
-     * Adds instrumentation support at a node that should be considered a member of
-     * {@link NodePhylum#STATEMENT}, possibly returning a new {@link InstrumentationProxyNode} that
-     * holds the original as its child.
-     */
-    RubyNode instrumentAsStatement(RubyNode node);
-
-    /**
-     * Adds instrumentation support at a node that should be considered a member of
-     * {@link NodePhylum#CALL}, possibly returning a new {@link InstrumentationProxyNode} that holds
-     * the original as its child.
-     */
-    RubyNode instrumentAsCall(RubyNode node, String callName);
-
-    /**
-     * Adds instrumentation support at a node that should be considered a member of
-     * {@link NodePhylum#ASSIGNMENT}, possibly returning a new {@link InstrumentationProxyNode} that
-     * holds the original as its child.
-     */
-    RubyNode instrumentAsLocalAssignment(RubyNode node, UniqueMethodIdentifier methodIdentifier, String localName);
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/instrument/RubyProxyNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,229 +0,0 @@
-/*
- * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.instrument;
-
-import java.math.*;
-import java.util.*;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.debug.*;
-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;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-import com.oracle.truffle.ruby.runtime.core.array.*;
-
-/**
- * An <strong>instrumentation proxy node</strong> that forwards all Ruby execution calls through to
- * a child node and returns results back to the parent, but which also sends notifications to an
- * attached {@linkplain ProbeChain chain} of {@linkplain InstrumentationProbeNode probes}.
- */
-public class RubyProxyNode extends RubyNode implements InstrumentationProxyNode {
-
-    @Child private RubyNode child;
-
-    private final ProbeChain probeChain;
-
-    public RubyProxyNode(RubyContext context, RubyNode child) {
-        super(context, SourceSection.NULL);
-        assert !(child instanceof RubyProxyNode);
-        this.child = adoptChild(child);
-        this.probeChain = context.getDebugContext().getDebugManager().getProbeChain(child.getSourceSection());
-    }
-
-    public RubyProxyNode(RubyContext context, RubyNode child, ProbeChain probeChain) {
-        super(context, SourceSection.NULL);
-        assert !(child instanceof RubyProxyNode);
-        this.child = adoptChild(child);
-        this.probeChain = probeChain;
-    }
-
-    @Override
-    public RubyNode getNonProxyNode() {
-        return child;
-    }
-
-    public RubyNode getChild() {
-        return child;
-    }
-
-    public ProbeChain getProbeChain() {
-        return probeChain;
-    }
-
-    @Override
-    public Object execute(VirtualFrame frame) {
-        probeChain.notifyEnter(child, frame);
-
-        Object result;
-
-        try {
-            result = child.execute(frame);
-            probeChain.notifyLeave(child, frame, result);
-        } catch (KillException e) {
-            throw (e);
-        } catch (Exception e) {
-            probeChain.notifyLeaveExceptional(child, frame, e);
-            throw (e);
-        }
-
-        return result;
-    }
-
-    @Override
-    public RubyArray executeArray(VirtualFrame frame) throws UnexpectedResultException {
-        probeChain.notifyEnter(child, frame);
-
-        RubyArray result;
-
-        try {
-            result = child.executeArray(frame);
-            probeChain.notifyLeave(child, frame, result);
-        } catch (KillException e) {
-            throw (e);
-        } catch (Exception e) {
-            probeChain.notifyLeaveExceptional(child, frame, e);
-            throw (e);
-        }
-
-        return result;
-    }
-
-    @Override
-    public BigInteger executeBignum(VirtualFrame frame) throws UnexpectedResultException {
-        probeChain.notifyEnter(child, frame);
-
-        BigInteger result;
-
-        try {
-            result = child.executeBignum(frame);
-            probeChain.notifyLeave(child, frame, result);
-        } catch (KillException e) {
-            throw (e);
-        } catch (Exception e) {
-            probeChain.notifyLeaveExceptional(child, frame, e);
-            throw (e);
-        }
-
-        return result;
-    }
-
-    @Override
-    public boolean executeBoolean(VirtualFrame frame) throws UnexpectedResultException {
-        probeChain.notifyEnter(child, frame);
-
-        boolean result;
-
-        try {
-            result = child.executeBoolean(frame);
-            probeChain.notifyLeave(child, frame, result);
-        } catch (KillException e) {
-            throw (e);
-        } catch (Exception e) {
-            probeChain.notifyLeaveExceptional(child, frame, e);
-            throw (e);
-        }
-
-        return result;
-    }
-
-    @Override
-    public Object isDefined(VirtualFrame frame) {
-        return child.isDefined(frame);
-    }
-
-    @Override
-    public int executeFixnum(VirtualFrame frame) throws UnexpectedResultException {
-        probeChain.notifyEnter(child, frame);
-
-        int result;
-
-        try {
-            result = child.executeFixnum(frame);
-            probeChain.notifyLeave(child, frame, result);
-        } catch (KillException e) {
-            throw (e);
-        } catch (Exception e) {
-            probeChain.notifyLeaveExceptional(child, frame, e);
-            throw (e);
-        }
-
-        return result;
-    }
-
-    @Override
-    public double executeFloat(VirtualFrame frame) throws UnexpectedResultException {
-        probeChain.notifyEnter(child, frame);
-
-        double result;
-
-        try {
-            result = child.executeFloat(frame);
-            probeChain.notifyLeave(child, frame, result);
-        } catch (KillException e) {
-            throw (e);
-        } catch (Exception e) {
-            probeChain.notifyLeaveExceptional(child, frame, e);
-            throw (e);
-        }
-
-        return result;
-    }
-
-    @Override
-    public RubyString executeString(VirtualFrame frame) throws UnexpectedResultException {
-        probeChain.notifyEnter(child, frame);
-
-        RubyString result;
-
-        try {
-            result = child.executeString(frame);
-            probeChain.notifyLeave(child, frame, result);
-        } catch (KillException e) {
-            throw (e);
-        } catch (Exception e) {
-            probeChain.notifyLeaveExceptional(child, frame, e);
-            throw (e);
-        }
-
-        return result;
-    }
-
-    @Override
-    public void executeVoid(VirtualFrame frame) {
-        probeChain.notifyEnter(child, frame);
-
-        try {
-            child.executeVoid(frame);
-            probeChain.notifyLeave(child, frame);
-        } catch (KillException e) {
-            throw (e);
-        } catch (Exception e) {
-            probeChain.notifyLeaveExceptional(child, frame, e);
-            throw (e);
-        }
-    }
-
-    public boolean isMarkedAs(NodePhylum phylum) {
-        return probeChain.isMarkedAs(phylum);
-    }
-
-    public Set<NodePhylum> getPhylumMarks() {
-        return probeChain.getPhylumMarks();
-    }
-
-    public void markAs(NodePhylum phylum) {
-        probeChain.markAs(phylum);
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/literal/BignumLiteralNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,40 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.literal;
-
-import java.math.*;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-
-@NodeInfo(shortName = "bignum")
-public class BignumLiteralNode extends RubyNode {
-
-    private final BigInteger value;
-
-    public BignumLiteralNode(RubyContext context, SourceSection sourceSection, BigInteger value) {
-        super(context, sourceSection);
-        this.value = value;
-    }
-
-    @Override
-    public BigInteger executeBignum(VirtualFrame frame) {
-        return value;
-    }
-
-    @Override
-    public Object execute(VirtualFrame frame) {
-        return value;
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/literal/BooleanLiteralNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.literal;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-
-@NodeInfo(shortName = "boolean")
-public class BooleanLiteralNode extends RubyNode {
-
-    private final boolean value;
-
-    public BooleanLiteralNode(RubyContext context, SourceSection sourceSection, boolean value) {
-        super(context, sourceSection);
-        this.value = value;
-    }
-
-    @Override
-    public Object execute(VirtualFrame frame) {
-        return executeBoolean(frame);
-    }
-
-    @Override
-    public boolean executeBoolean(VirtualFrame frame) {
-        return value;
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/literal/FixnumLiteralNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,42 +0,0 @@
-/*
- * Copyright (c) 2013, 2014 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.literal;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-
-@NodeInfo(shortName = "fixnum")
-public class FixnumLiteralNode extends RubyNode {
-
-    private final int value;
-
-    public FixnumLiteralNode(RubyContext context, SourceSection sourceSection, int value) {
-        super(context, sourceSection);
-        this.value = value;
-    }
-
-    @Override
-    public Object execute(VirtualFrame frame) {
-        return executeFixnum(frame);
-    }
-
-    @Override
-    public int executeFixnum(VirtualFrame frame) {
-        return value;
-    }
-
-    public int getValue() {
-        return value;
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/literal/FloatLiteralNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.literal;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-
-@NodeInfo(shortName = "float")
-public class FloatLiteralNode extends RubyNode {
-
-    private final double value;
-
-    public FloatLiteralNode(RubyContext context, SourceSection sourceSection, double value) {
-        super(context, sourceSection);
-        this.value = value;
-    }
-
-    @Override
-    public Object execute(VirtualFrame frame) {
-        return executeFloat(frame);
-    }
-
-    @Override
-    public double executeFloat(VirtualFrame frame) {
-        return value;
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/literal/HashLiteralNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,49 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.literal;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-
-@NodeInfo(shortName = "hash")
-public class HashLiteralNode extends RubyNode {
-
-    @Children protected final RubyNode[] keys;
-    @Children protected final RubyNode[] values;
-
-    public HashLiteralNode(SourceSection sourceSection, RubyNode[] keys, RubyNode[] values, RubyContext context) {
-        super(context, sourceSection);
-        assert keys.length == values.length;
-        this.keys = adoptChildren(keys);
-        this.values = adoptChildren(values);
-    }
-
-    @ExplodeLoop
-    @Override
-    public Object execute(VirtualFrame frame) {
-        final RubyHash hash = new RubyHash(getContext().getCoreLibrary().getHashClass());
-
-        for (int n = 0; n < keys.length; n++) {
-            hash.put(keys[n].execute(frame), values[n].execute(frame));
-        }
-
-        return hash;
-    }
-
-    @Override
-    public Object isDefined(VirtualFrame frame) {
-        return getContext().makeString("expression");
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/literal/NilNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,42 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.literal;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-
-/**
- * A node that does nothing and evaluates to Nil. A no-op.
- */
-@NodeInfo(shortName = "nil")
-public final class NilNode extends RubyNode {
-
-    public NilNode(RubyContext context, SourceSection sourceSection) {
-        super(context, sourceSection);
-    }
-
-    @Override
-    public NilPlaceholder executeNilPlaceholder(VirtualFrame frame) {
-        return NilPlaceholder.INSTANCE;
-    }
-
-    @Override
-    public Object execute(VirtualFrame frame) {
-        return executeNilPlaceholder(frame);
-    }
-
-    @Override
-    public void executeVoid(VirtualFrame frame) {
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/literal/ObjectLiteralNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.literal;
-
-import java.math.*;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-
-@NodeInfo(shortName = "object")
-public class ObjectLiteralNode extends RubyNode {
-
-    private final Object object;
-
-    public ObjectLiteralNode(RubyContext context, SourceSection sourceSection, Object object) {
-        super(context, sourceSection);
-
-        assert RubyContext.shouldObjectBeVisible(object);
-        assert !(object instanceof Integer);
-        assert !(object instanceof Double);
-        assert !(object instanceof BigInteger);
-        assert !(object instanceof String);
-        assert !(object instanceof RubyString);
-
-        this.object = object;
-    }
-
-    @Override
-    public Object execute(VirtualFrame frame) {
-        return object;
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/literal/RangeLiteralNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,50 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.literal;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.dsl.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.range.*;
-
-@NodeInfo(shortName = "range")
-@NodeChildren({@NodeChild("begin"), @NodeChild("end")})
-public abstract class RangeLiteralNode extends RubyNode {
-
-    private final boolean excludeEnd;
-
-    public RangeLiteralNode(RubyContext context, SourceSection sourceSection, boolean excludeEnd) {
-        super(context, sourceSection);
-        this.excludeEnd = excludeEnd;
-    }
-
-    public RangeLiteralNode(RangeLiteralNode prev) {
-        this(prev.getContext(), prev.getSourceSection(), prev.excludeEnd);
-    }
-
-    @Specialization
-    public FixnumRange doFixnum(int begin, int end) {
-        return new FixnumRange(getContext().getCoreLibrary().getRangeClass(), begin, end, excludeEnd);
-    }
-
-    @Generic
-    public Object doGeneric(Object begin, Object end) {
-        final RubyContext context = getContext();
-
-        if ((begin instanceof Integer) && (end instanceof Integer)) {
-            return doFixnum((int) begin, (int) end);
-        } else {
-            return new ObjectRange(context.getCoreLibrary().getRangeClass(), begin, end, excludeEnd);
-        }
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/literal/StringLiteralNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /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. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.literal;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-
-@NodeInfo(shortName = "string")
-public class StringLiteralNode extends RubyNode {
-
-    private final String string;
-
-    public StringLiteralNode(RubyContext context, SourceSection sourceSection, String string) {
-        super(context, sourceSection);
-
-        assert string != null;
-
-        this.string = string;
-    }
-
-    @Override
-    public Object execute(VirtualFrame frame) {
-        return getContext().makeString(string);
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/literal/array/ArrayLiteralNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,55 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.literal.array;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.array.*;
-
-public abstract class ArrayLiteralNode extends RubyNode {
-
-    @Children protected final RubyNode[] values;
-
-    public ArrayLiteralNode(RubyContext context, SourceSection sourceSection, RubyNode[] values) {
-        super(context, sourceSection);
-        this.values = adoptChildren(values);
-    }
-
-    protected RubyArray makeGeneric(VirtualFrame frame, Object[] alreadyExecuted) {
-        CompilerAsserts.neverPartOfCompilation();
-
-        replace(new ObjectArrayLiteralNode(getContext(), getSourceSection(), values));
-
-        final Object[] executedValues = new Object[values.length];
-
-        for (int n = 0; n < values.length; n++) {
-            if (n < alreadyExecuted.length) {
-                executedValues[n] = alreadyExecuted[n];
-            } else {
-                executedValues[n] = values[n].execute(frame);
-            }
-        }
-
-        return RubyArray.specializedFromObjects(getContext().getCoreLibrary().getArrayClass(), executedValues);
-    }
-
-    @Override
-    public Object isDefined(VirtualFrame frame) {
-        return getContext().makeString("expression");
-    }
-
-    // TODO(CS): remove this - shouldn't be fiddling with nodes from the outside
-    public RubyNode[] getValues() {
-        return values;
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/literal/array/FixnumArrayLiteralNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,61 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.literal.array;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.array.*;
-
-@NodeInfo(shortName = "fixnum-array-literal")
-public class FixnumArrayLiteralNode extends ArrayLiteralNode {
-
-    public FixnumArrayLiteralNode(RubyContext context, SourceSection sourceSection, RubyNode[] values) {
-        super(context, sourceSection, values);
-    }
-
-    @ExplodeLoop
-    @Override
-    public RubyArray executeArray(VirtualFrame frame) {
-        final int[] executedValues = new int[values.length];
-
-        for (int n = 0; n < values.length; n++) {
-            try {
-                executedValues[n] = values[n].executeFixnum(frame);
-            } catch (UnexpectedResultException e) {
-                final Object[] executedObjects = new Object[n];
-
-                for (int i = 0; i < n; i++) {
-                    executedObjects[i] = executedValues[i];
-                }
-
-                return makeGeneric(frame, executedObjects);
-            }
-        }
-
-        return new RubyArray(getContext().getCoreLibrary().getArrayClass(), new FixnumArrayStore(executedValues));
-    }
-
-    @ExplodeLoop
-    @Override
-    public void executeVoid(VirtualFrame frame) {
-        for (int n = 0; n < values.length; n++) {
-            values[n].executeVoid(frame);
-        }
-    }
-
-    @Override
-    public Object execute(VirtualFrame frame) {
-        return executeArray(frame);
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/literal/array/ObjectArrayLiteralNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /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. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.literal.array;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.array.*;
-
-@NodeInfo(shortName = "object-array-literal")
-public class ObjectArrayLiteralNode extends ArrayLiteralNode {
-
-    public ObjectArrayLiteralNode(RubyContext context, SourceSection sourceSection, RubyNode[] values) {
-        super(context, sourceSection, values);
-    }
-
-    @ExplodeLoop
-    @Override
-    public RubyArray executeArray(VirtualFrame frame) {
-        final Object[] executedValues = new Object[values.length];
-
-        for (int n = 0; n < values.length; n++) {
-            executedValues[n] = values[n].execute(frame);
-        }
-
-        return new RubyArray(getContext().getCoreLibrary().getArrayClass(), new ObjectArrayStore(executedValues));
-    }
-
-    @ExplodeLoop
-    @Override
-    public void executeVoid(VirtualFrame frame) {
-        for (int n = 0; n < values.length; n++) {
-            values[n].executeVoid(frame);
-        }
-    }
-
-    @Override
-    public Object execute(VirtualFrame frame) {
-        return executeArray(frame);
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/literal/array/UninitialisedArrayLiteralNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,49 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.literal.array;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.array.*;
-
-@NodeInfo(shortName = "uninit-array-literal")
-public class UninitialisedArrayLiteralNode extends ArrayLiteralNode {
-
-    public UninitialisedArrayLiteralNode(RubyContext context, SourceSection sourceSection, RubyNode[] values) {
-        super(context, sourceSection, values);
-    }
-
-    @ExplodeLoop
-    @Override
-    public Object execute(VirtualFrame frame) {
-        CompilerDirectives.transferToInterpreter();
-
-        final Object[] executedValues = new Object[values.length];
-
-        for (int n = 0; n < values.length; n++) {
-            executedValues[n] = values[n].execute(frame);
-        }
-
-        final RubyArray array = RubyArray.specializedFromObjects(getContext().getCoreLibrary().getArrayClass(), executedValues);
-        final ArrayStore store = array.getArrayStore();
-
-        if (store instanceof FixnumArrayStore) {
-            replace(new FixnumArrayLiteralNode(getContext(), getSourceSection(), values));
-        } else {
-            replace(new ObjectArrayLiteralNode(getContext(), getSourceSection(), values));
-        }
-
-        return array;
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/AddMethodNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,72 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.methods;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-import com.oracle.truffle.ruby.runtime.methods.*;
-
-@NodeInfo(shortName = "add-method")
-public class AddMethodNode extends RubyNode {
-
-    @Child protected RubyNode receiver;
-    @Child protected MethodDefinitionNode method;
-
-    public AddMethodNode(RubyContext context, SourceSection section, RubyNode receiver, MethodDefinitionNode method) {
-        super(context, section);
-        this.receiver = adoptChild(receiver);
-        this.method = adoptChild(method);
-    }
-
-    @Override
-    public Object execute(VirtualFrame frame) {
-        final Object receiverObject = receiver.execute(frame);
-
-        final RubyMethod methodObject = (RubyMethod) method.execute(frame);
-
-        final FrameSlot moduleFunctionFlagSlot = frame.getFrameDescriptor().findFrameSlot(RubyModule.MODULE_FUNCTION_FLAG_FRAME_SLOT_ID);
-
-        boolean moduleFunctionFlag;
-
-        if (moduleFunctionFlagSlot == null) {
-            moduleFunctionFlag = false;
-        } else {
-            Object moduleFunctionObject;
-
-            try {
-                moduleFunctionObject = frame.getObject(moduleFunctionFlagSlot);
-            } catch (FrameSlotTypeException e) {
-                throw new RuntimeException(e);
-            }
-
-            if (moduleFunctionObject instanceof Boolean) {
-                moduleFunctionFlag = (boolean) moduleFunctionObject;
-            } else {
-                moduleFunctionFlag = false;
-            }
-        }
-
-        final RubyModule module = (RubyModule) receiverObject;
-
-        final RubyMethod methodWithDeclaringModule = methodObject.withDeclaringModule(module);
-
-        module.addMethod(methodWithDeclaringModule);
-
-        if (moduleFunctionFlag) {
-            module.getSingletonClass().addMethod(methodWithDeclaringModule);
-        }
-
-        return NilPlaceholder.INSTANCE;
-    }
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/AliasNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,45 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.methods;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-
-@NodeInfo(shortName = "alias")
-public class AliasNode extends RubyNode {
-
-    @Child protected RubyNode module;
-    final String newName;
-    final String oldName;
-
-    public AliasNode(RubyContext context, SourceSection sourceSection, RubyNode module, String newName, String oldName) {
-        super(context, sourceSection);
-        this.module = adoptChild(module);
-        this.newName = newName;
-        this.oldName = oldName;
-    }
-
-    @Override
-    public void executeVoid(VirtualFrame frame) {
-        final RubyModule moduleObject = (RubyModule) module.execute(frame);
-        moduleObject.alias(newName, oldName);
-    }
-
-    @Override
-    public Object execute(VirtualFrame frame) {
-        executeVoid(frame);
-        return NilPlaceholder.INSTANCE;
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/BlockDefinitionNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.methods;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-import com.oracle.truffle.ruby.runtime.methods.*;
-
-/**
- * Define a block. That is, store the definition of a block and when executed produce the executable
- * object that results.
- */
-@NodeInfo(shortName = "block-def")
-public class BlockDefinitionNode extends MethodDefinitionNode {
-
-    public BlockDefinitionNode(RubyContext context, SourceSection sourceSection, String name, UniqueMethodIdentifier uniqueIdentifier, FrameDescriptor frameDescriptor,
-                    boolean requiresDeclarationFrame, RubyRootNode pristineRootNode, CallTarget callTarget) {
-        super(context, sourceSection, name, uniqueIdentifier, frameDescriptor, requiresDeclarationFrame, pristineRootNode, callTarget);
-    }
-
-    @Override
-    public Object execute(VirtualFrame frame) {
-        final RubyContext context = getContext();
-
-        MaterializedFrame declarationFrame;
-
-        if (requiresDeclarationFrame) {
-            declarationFrame = frame.materialize();
-        } else {
-            declarationFrame = null;
-        }
-
-        final RubyArguments arguments = frame.getArguments(RubyArguments.class);
-
-        final InlinableMethodImplementation methodImplementation = new InlinableMethodImplementation(callTarget, declarationFrame, frameDescriptor, pristineRootNode, true, false);
-        final RubyMethod method = new RubyMethod(getSourceSection(), null, uniqueIdentifier, null, name, Visibility.PUBLIC, false, methodImplementation);
-
-        return new RubyProc(context.getCoreLibrary().getProcClass(), RubyProc.Type.PROC, arguments.getSelf(), arguments.getBlock(), method);
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/CatchNextNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,43 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.methods;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.utilities.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.control.*;
-
-/**
- * Catch a {@code next} jump at the root of a method.
- */
-public class CatchNextNode extends RubyNode {
-
-    @Child protected RubyNode body;
-
-    private final BranchProfile nextProfile = new BranchProfile();
-
-    public CatchNextNode(RubyContext context, SourceSection sourceSection, RubyNode body) {
-        super(context, sourceSection);
-        this.body = adoptChild(body);
-    }
-
-    @Override
-    public Object execute(VirtualFrame frame) {
-        try {
-            return body.execute(frame);
-        } catch (NextException e) {
-            nextProfile.enter();
-            return e.getResult();
-        }
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/CatchReturnAsErrorNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,40 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.methods;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.control.*;
-
-/**
- * Catch a {@code return} jump at the root of a method, and report it as an error.
- */
-public class CatchReturnAsErrorNode extends RubyNode {
-
-    @Child protected RubyNode body;
-
-    public CatchReturnAsErrorNode(RubyContext context, SourceSection sourceSection, RubyNode body) {
-        super(context, sourceSection);
-        this.body = adoptChild(body);
-    }
-
-    @Override
-    public Object execute(VirtualFrame frame) {
-        try {
-            return body.execute(frame);
-        } catch (ReturnException e) {
-            CompilerDirectives.transferToInterpreter();
-            throw new RaiseException(getContext().getCoreLibrary().unexpectedReturn());
-        }
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/CatchReturnNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,57 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.methods;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.utilities.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.control.*;
-
-/**
- * Catch a {@code return} jump at the root of a method.
- */
-public class CatchReturnNode extends RubyNode {
-
-    @Child protected RubyNode body;
-    private final long returnID;
-
-    private final BranchProfile returnProfile = new BranchProfile();
-    private final BranchProfile returnToOtherMethodProfile = new BranchProfile();
-
-    public CatchReturnNode(RubyContext context, SourceSection sourceSection, RubyNode body, long returnID) {
-        super(context, sourceSection);
-        this.body = adoptChild(body);
-        this.returnID = returnID;
-    }
-
-    public CatchReturnNode(CatchReturnNode prev) {
-        super(prev);
-        returnID = prev.returnID;
-    }
-
-    @Override
-    public Object execute(VirtualFrame frame) {
-        try {
-            return body.execute(frame);
-        } catch (ReturnException e) {
-            returnProfile.enter();
-
-            if (e.getReturnID() == returnID) {
-                return e.getValue();
-            } else {
-                returnToOtherMethodProfile.enter();
-                throw e;
-            }
-        }
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/MethodDefinitionNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,98 +0,0 @@
-/*
- * Copyright (c) 2013, 2014 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.methods;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-import com.oracle.truffle.ruby.runtime.methods.*;
-
-/**
- * Define a method. That is, store the definition of a method and when executed produce the
- * executable object that results.
- */
-@NodeInfo(shortName = "method-def")
-public class MethodDefinitionNode extends RubyNode {
-
-    protected final String name;
-    protected final UniqueMethodIdentifier uniqueIdentifier;
-
-    protected final FrameDescriptor frameDescriptor;
-    protected final RubyRootNode pristineRootNode;
-
-    protected final CallTarget callTarget;
-
-    protected final boolean requiresDeclarationFrame;
-
-    public MethodDefinitionNode(RubyContext context, SourceSection sourceSection, String name, UniqueMethodIdentifier uniqueIdentifier, FrameDescriptor frameDescriptor,
-                    boolean requiresDeclarationFrame, RubyRootNode pristineRootNode, CallTarget callTarget) {
-        super(context, sourceSection);
-        this.name = name;
-        this.uniqueIdentifier = uniqueIdentifier;
-        this.frameDescriptor = frameDescriptor;
-        this.requiresDeclarationFrame = requiresDeclarationFrame;
-        this.pristineRootNode = pristineRootNode;
-        this.callTarget = callTarget;
-    }
-
-    public RubyMethod executeMethod(VirtualFrame frame) {
-        CompilerDirectives.transferToInterpreter();
-
-        MaterializedFrame declarationFrame;
-
-        if (requiresDeclarationFrame) {
-            declarationFrame = frame.materialize();
-        } else {
-            declarationFrame = null;
-        }
-
-        final FrameSlot visibilitySlot = frame.getFrameDescriptor().findFrameSlot(RubyModule.VISIBILITY_FRAME_SLOT_ID);
-
-        Visibility visibility;
-
-        if (visibilitySlot == null) {
-            visibility = Visibility.PUBLIC;
-        } else {
-            Object visibilityObject;
-
-            try {
-                visibilityObject = frame.getObject(visibilitySlot);
-            } catch (FrameSlotTypeException e) {
-                throw new RuntimeException(e);
-            }
-
-            if (visibilityObject instanceof Visibility) {
-                visibility = (Visibility) visibilityObject;
-            } else {
-                visibility = Visibility.PUBLIC;
-            }
-        }
-
-        final InlinableMethodImplementation methodImplementation = new InlinableMethodImplementation(callTarget, declarationFrame, frameDescriptor, pristineRootNode, false, false);
-        return new RubyMethod(getSourceSection(), null, uniqueIdentifier, null, name, visibility, false, methodImplementation);
-    }
-
-    @Override
-    public Object execute(VirtualFrame frame) {
-        return executeMethod(frame);
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public CallTarget getCallTarget() {
-        return callTarget;
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/ShellResultNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,34 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.methods;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-
-/**
- * Produce a {@link ShellResult} object from a return value and the resulting frame.
- */
-public class ShellResultNode extends RubyNode {
-
-    @Child protected RubyNode body;
-
-    public ShellResultNode(RubyContext context, SourceSection sourceSection, RubyNode body) {
-        super(context, sourceSection);
-        this.body = adoptChild(body);
-    }
-
-    @Override
-    public Object execute(VirtualFrame frame) {
-        return new ShellResult(body.execute(frame), frame.materialize());
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/arguments/BlockDestructureSwitchNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,50 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.methods.arguments;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.array.*;
-
-/**
- * Switches between loading arguments as normal and doing a destructure. See
- * testBlockArgumentsDestructure and MethodTranslator.
- */
-@NodeInfo(shortName = "block-destructure-switch")
-public class BlockDestructureSwitchNode extends RubyNode {
-
-    @Child protected RubyNode loadIndividualArguments;
-    @Child protected RubyNode destructureArguments;
-    @Child protected RubyNode body;
-
-    public BlockDestructureSwitchNode(RubyContext context, SourceSection sourceSection, RubyNode loadIndividualArguments, RubyNode destructureArguments, RubyNode body) {
-        super(context, sourceSection);
-        this.loadIndividualArguments = adoptChild(loadIndividualArguments);
-        this.destructureArguments = adoptChild(destructureArguments);
-        this.body = adoptChild(body);
-    }
-
-    @Override
-    public Object execute(VirtualFrame frame) {
-        final RubyArguments arguments = frame.getArguments(RubyArguments.class);
-
-        if (arguments.getArguments().length == 1 && arguments.getArguments()[0] instanceof RubyArray) {
-            destructureArguments.executeVoid(frame);
-        } else {
-            loadIndividualArguments.executeVoid(frame);
-        }
-
-        return body.execute(frame);
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/arguments/CheckArityNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.methods.arguments;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.methods.*;
-
-/**
- * Check arguments meet the arity of the method.
- */
-@NodeInfo(shortName = "check-arity")
-public class CheckArityNode extends RubyNode {
-
-    private final Arity arity;
-
-    public CheckArityNode(RubyContext context, SourceSection sourceSection, Arity arity) {
-        super(context, sourceSection);
-        this.arity = arity;
-    }
-
-    @Override
-    public void executeVoid(VirtualFrame frame) {
-        final RubyArguments arguments = frame.getArguments(RubyArguments.class);
-        arity.checkArguments(getContext(), arguments.getArguments());
-    }
-
-    @Override
-    public Object execute(VirtualFrame frame) {
-        executeVoid(frame);
-        return NilPlaceholder.INSTANCE;
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/arguments/ReadAllArgumentsNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.methods.arguments;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-
-public class ReadAllArgumentsNode extends RubyNode {
-
-    public ReadAllArgumentsNode(RubyContext context, SourceSection sourceSection) {
-        super(context, sourceSection);
-    }
-
-    @Override
-    public Object[] executeObjectArray(VirtualFrame frame) {
-        return frame.getArguments(RubyArguments.class).getArguments();
-    }
-
-    @Override
-    public Object execute(VirtualFrame frame) {
-        return executeObjectArray(frame);
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/arguments/ReadBlockArgumentNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,48 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.methods.arguments;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-
-/**
- * Read the block as a {@code Proc}.
- */
-@NodeInfo(shortName = "read-block-argument")
-public class ReadBlockArgumentNode extends RubyNode {
-
-    private final boolean undefinedIfNotPresent;
-
-    public ReadBlockArgumentNode(RubyContext context, SourceSection sourceSection, boolean undefinedIfNotPresent) {
-        super(context, sourceSection);
-        this.undefinedIfNotPresent = undefinedIfNotPresent;
-    }
-
-    @Override
-    public Object execute(VirtualFrame frame) {
-        final RubyArguments arguments = frame.getArguments(RubyArguments.class);
-        final RubyProc block = arguments.getBlock();
-
-        if (block == null) {
-            if (undefinedIfNotPresent) {
-                return UndefinedPlaceholder.INSTANCE;
-            } else {
-                return NilPlaceholder.INSTANCE;
-            }
-        } else {
-            return block;
-        }
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/arguments/ReadDestructureArgumentNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.methods.arguments;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.array.*;
-
-/**
- * Assuming argument 0 is an array, read an element from that array.
- */
-@NodeInfo(shortName = "read-destructure-argument")
-public class ReadDestructureArgumentNode extends RubyNode {
-
-    private final int index;
-
-    public ReadDestructureArgumentNode(RubyContext context, SourceSection sourceSection, int index) {
-        super(context, sourceSection);
-        this.index = index;
-    }
-
-    @Override
-    public Object execute(VirtualFrame frame) {
-        final RubyArray array = (RubyArray) frame.getArguments(RubyArguments.class).getArguments()[0];
-        return array.get(index);
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/arguments/ReadOptionalArgumentNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /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. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.methods.arguments;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.api.utilities.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-
-/**
- * Read an optional argument.
- */
-@NodeInfo(shortName = "read-optional-argument")
-public class ReadOptionalArgumentNode extends RubyNode {
-
-    private final int index;
-    private final int minimum;
-    @Child protected RubyNode defaultValue;
-
-    private final BranchProfile defaultValueProfile = new BranchProfile();
-
-    public ReadOptionalArgumentNode(RubyContext context, SourceSection sourceSection, int index, int minimum, RubyNode defaultValue) {
-        super(context, sourceSection);
-        this.index = index;
-        this.minimum = minimum;
-        this.defaultValue = adoptChild(defaultValue);
-    }
-
-    @Override
-    public Object execute(VirtualFrame frame) {
-        final Object[] arguments = frame.getArguments(RubyArguments.class).getArguments();
-
-        if (arguments.length < minimum) {
-            defaultValueProfile.enter();
-            return defaultValue.execute(frame);
-        } else {
-            assert index < arguments.length;
-            return arguments[index];
-        }
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/arguments/ReadPostArgumentNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.methods.arguments;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-
-/**
- * Read a post-optional argument.
- */
-@NodeInfo(shortName = "read-post-optional-argument")
-public class ReadPostArgumentNode extends RubyNode {
-
-    private final int indexFromEnd;
-
-    public ReadPostArgumentNode(RubyContext context, SourceSection sourceSection, int indexFromEnd) {
-        super(context, sourceSection);
-        this.indexFromEnd = indexFromEnd;
-    }
-
-    @Override
-    public Object execute(VirtualFrame frame) {
-        final Object[] arguments = frame.getArguments(RubyArguments.class).getArguments();
-        final int effectiveIndex = arguments.length - 1 - indexFromEnd;
-        assert effectiveIndex < arguments.length;
-        return arguments[effectiveIndex];
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/arguments/ReadPreArgumentNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.methods.arguments;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.api.utilities.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-
-/**
- * Read pre-optional argument.
- */
-@NodeInfo(shortName = "read-pre-optional-argument")
-public class ReadPreArgumentNode extends RubyNode {
-
-    private final int index;
-    private final boolean undefinedIfNotPresent;
-
-    private final BranchProfile notPresentProfile = new BranchProfile();
-
-    public ReadPreArgumentNode(RubyContext context, SourceSection sourceSection, int index, boolean undefinedIfNotPresent) {
-        super(context, sourceSection);
-        this.index = index;
-        this.undefinedIfNotPresent = undefinedIfNotPresent;
-    }
-
-    @Override
-    public Object execute(VirtualFrame frame) {
-        final Object[] arguments = frame.getArguments(RubyArguments.class).getArguments();
-
-        if (undefinedIfNotPresent) {
-            if (index >= arguments.length) {
-                notPresentProfile.enter();
-                return UndefinedPlaceholder.INSTANCE;
-            }
-        } else {
-            assert index < arguments.length;
-        }
-
-        return arguments[index];
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/arguments/ReadRestArgumentNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /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. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.methods.arguments;
-
-import java.util.*;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-import com.oracle.truffle.ruby.runtime.core.array.*;
-
-/**
- * Read the rest of arguments after a certain point into an array.
- */
-@NodeInfo(shortName = "read-rest-of-arguments")
-public class ReadRestArgumentNode extends RubyNode {
-
-    private final int index;
-
-    public ReadRestArgumentNode(RubyContext context, SourceSection sourceSection, int index) {
-        super(context, sourceSection);
-        this.index = index;
-    }
-
-    @Override
-    public Object execute(VirtualFrame frame) {
-        final RubyArguments rubyArguments = frame.getArguments(RubyArguments.class);
-
-        final Object[] arguments = rubyArguments.getArguments();
-
-        final RubyClass arrayClass = getContext().getCoreLibrary().getArrayClass();
-
-        if (arguments.length <= index) {
-            return new RubyArray(arrayClass);
-        } else if (index == 0) {
-            return new RubyArray(arrayClass, new ObjectArrayStore(arguments));
-        } else {
-            return new RubyArray(arrayClass, new ObjectArrayStore(Arrays.copyOfRange(arguments, index, arguments.length)));
-        }
-    }
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/locals/FlipFlopStateNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,26 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.methods.locals;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-
-public abstract class FlipFlopStateNode extends Node {
-
-    public FlipFlopStateNode(SourceSection sourceSection) {
-        super(sourceSection);
-    }
-
-    public abstract boolean getState(VirtualFrame frame);
-
-    public abstract void setState(VirtualFrame frame, boolean state);
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/locals/FrameSlotNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,104 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.methods.locals;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-
-public abstract class FrameSlotNode extends RubyNode {
-
-    protected final FrameSlot frameSlot;
-
-    protected FrameSlotNode(RubyContext context, SourceSection sourceSection, FrameSlot frameSlot) {
-        super(context, sourceSection);
-        this.frameSlot = frameSlot;
-    }
-
-    public final FrameSlot getFrameSlot() {
-        return frameSlot;
-    }
-
-    @Override
-    public FrameSlotNode copy() {
-        return (FrameSlotNode) super.copy();
-    }
-
-    protected final void setBoolean(Frame frame, boolean value) {
-        frame.setBoolean(frameSlot, value);
-    }
-
-    protected final void setFixnum(Frame frame, int value) {
-        frame.setInt(frameSlot, value);
-    }
-
-    protected final void setFloat(Frame frame, double value) {
-        frame.setDouble(frameSlot, value);
-    }
-
-    protected final void setObject(Frame frame, Object value) {
-        frame.setObject(frameSlot, value);
-    }
-
-    protected final boolean getBoolean(Frame frame) throws FrameSlotTypeException {
-        return frame.getBoolean(frameSlot);
-    }
-
-    protected final int getFixnum(Frame frame) throws FrameSlotTypeException {
-        return frame.getInt(frameSlot);
-    }
-
-    protected final double getFloat(Frame frame) throws FrameSlotTypeException {
-        return frame.getDouble(frameSlot);
-    }
-
-    protected final Object getObject(Frame frame) {
-        try {
-            return frame.getObject(frameSlot);
-        } catch (FrameSlotTypeException e) {
-            throw new IllegalStateException();
-        }
-    }
-
-    protected final boolean isBooleanKind() {
-        return isKind(FrameSlotKind.Boolean);
-    }
-
-    protected final boolean isFixnumKind() {
-        return isKind(FrameSlotKind.Int);
-    }
-
-    protected final boolean isFloatKind() {
-        return isKind(FrameSlotKind.Double);
-    }
-
-    protected final boolean isObjectKind() {
-        if (frameSlot.getKind() != FrameSlotKind.Object) {
-            CompilerDirectives.transferToInterpreter();
-            frameSlot.setKind(FrameSlotKind.Object);
-        }
-        return true;
-    }
-
-    private boolean isKind(FrameSlotKind kind) {
-        return frameSlot.getKind() == kind || initialSetKind(kind);
-    }
-
-    private boolean initialSetKind(FrameSlotKind kind) {
-        if (frameSlot.getKind() == FrameSlotKind.Illegal) {
-            CompilerDirectives.transferToInterpreter();
-            frameSlot.setKind(kind);
-            return true;
-        }
-        return false;
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/locals/InitFlipFlopSlotNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.methods.locals;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-
-public class InitFlipFlopSlotNode extends RubyNode {
-
-    private final FrameSlot frameSlot;
-
-    public InitFlipFlopSlotNode(RubyContext context, SourceSection sourceSection, FrameSlot frameSlot) {
-        super(context, sourceSection);
-        this.frameSlot = frameSlot;
-    }
-
-    @Override
-    public void executeVoid(VirtualFrame frame) {
-        frame.setBoolean(frameSlot, false);
-    }
-
-    @Override
-    public Object execute(VirtualFrame frame) {
-        executeVoid(frame);
-        return null;
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/locals/LevelFlipFlopStateNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.methods.locals;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.ruby.runtime.*;
-
-public class LevelFlipFlopStateNode extends FlipFlopStateNode {
-
-    private final int level;
-    private final FrameSlot frameSlot;
-
-    public LevelFlipFlopStateNode(SourceSection sourceSection, int level, FrameSlot frameSlot) {
-        super(sourceSection);
-        this.level = level;
-        this.frameSlot = frameSlot;
-    }
-
-    @Override
-    public boolean getState(VirtualFrame frame) {
-        final MaterializedFrame levelFrame = RubyArguments.getDeclarationFrame(frame, level);
-
-        try {
-            return levelFrame.getBoolean(frameSlot);
-        } catch (FrameSlotTypeException e) {
-            throw new IllegalStateException();
-        }
-    }
-
-    @Override
-    public void setState(VirtualFrame frame, boolean state) {
-        final MaterializedFrame levelFrame = RubyArguments.getDeclarationFrame(frame, level);
-        levelFrame.setBoolean(frameSlot, state);
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/locals/LocalFlipFlopStateNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.methods.locals;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-
-public class LocalFlipFlopStateNode extends FlipFlopStateNode {
-
-    private final FrameSlot frameSlot;
-
-    public LocalFlipFlopStateNode(SourceSection sourceSection, FrameSlot frameSlot) {
-        super(sourceSection);
-        this.frameSlot = frameSlot;
-    }
-
-    @Override
-    public boolean getState(VirtualFrame frame) {
-        try {
-            return frame.getBoolean(frameSlot);
-        } catch (FrameSlotTypeException e) {
-            throw new IllegalStateException();
-        }
-    }
-
-    @Override
-    public void setState(VirtualFrame frame, boolean state) {
-        frame.setBoolean(frameSlot, state);
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/locals/ReadLevelVariableNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,64 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.methods.locals;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.dsl.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-
-public abstract class ReadLevelVariableNode extends FrameSlotNode implements ReadNode {
-
-    private final int varLevel;
-
-    public ReadLevelVariableNode(RubyContext context, SourceSection sourceSection, FrameSlot slot, int level) {
-        super(context, sourceSection, slot);
-        this.varLevel = level;
-    }
-
-    public ReadLevelVariableNode(ReadLevelVariableNode prev) {
-        this(prev.getContext(), prev.getSourceSection(), prev.frameSlot, prev.varLevel);
-    }
-
-    @Specialization(rewriteOn = {FrameSlotTypeException.class})
-    public boolean doBoolean(VirtualFrame frame) throws FrameSlotTypeException {
-        MaterializedFrame levelFrame = RubyArguments.getDeclarationFrame(frame, varLevel);
-        return getBoolean(levelFrame);
-    }
-
-    @Specialization(rewriteOn = {FrameSlotTypeException.class})
-    public int doFixnum(VirtualFrame frame) throws FrameSlotTypeException {
-        MaterializedFrame levelFrame = RubyArguments.getDeclarationFrame(frame, varLevel);
-        return getFixnum(levelFrame);
-    }
-
-    @Specialization(rewriteOn = {FrameSlotTypeException.class})
-    public double doFloat(VirtualFrame frame) throws FrameSlotTypeException {
-        MaterializedFrame levelFrame = RubyArguments.getDeclarationFrame(frame, varLevel);
-        return getFloat(levelFrame);
-    }
-
-    @Specialization
-    public Object doObject(VirtualFrame frame) {
-        MaterializedFrame levelFrame = RubyArguments.getDeclarationFrame(frame, varLevel);
-        return getObject(levelFrame);
-    }
-
-    public int getVarLevel() {
-        return varLevel;
-    }
-
-    @Override
-    public RubyNode makeWriteNode(RubyNode rhs) {
-        return WriteLevelVariableNodeFactory.create(getContext(), getSourceSection(), frameSlot, varLevel, rhs);
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/locals/ReadLocalVariableNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,53 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.methods.locals;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.dsl.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-
-public abstract class ReadLocalVariableNode extends FrameSlotNode implements ReadNode {
-
-    public ReadLocalVariableNode(RubyContext context, SourceSection sourceSection, FrameSlot slot) {
-        super(context, sourceSection, slot);
-    }
-
-    public ReadLocalVariableNode(ReadLocalVariableNode prev) {
-        this(prev.getContext(), prev.getSourceSection(), prev.frameSlot);
-    }
-
-    @Specialization(rewriteOn = {FrameSlotTypeException.class})
-    public boolean doBoolean(VirtualFrame frame) throws FrameSlotTypeException {
-        return getBoolean(frame);
-    }
-
-    @Specialization(rewriteOn = {FrameSlotTypeException.class})
-    public int doFixnum(VirtualFrame frame) throws FrameSlotTypeException {
-        return getFixnum(frame);
-    }
-
-    @Specialization(rewriteOn = {FrameSlotTypeException.class})
-    public double doFloat(VirtualFrame frame) throws FrameSlotTypeException {
-        return getFloat(frame);
-    }
-
-    @Specialization
-    public Object doObject(VirtualFrame frame) {
-        return getObject(frame);
-    }
-
-    @Override
-    public RubyNode makeWriteNode(RubyNode rhs) {
-        return WriteLocalVariableNodeFactory.create(getContext(), getSourceSection(), frameSlot, rhs);
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/locals/WriteLevelVariableNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,64 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.methods.locals;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.dsl.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-
-@NodeChild(value = "rhs", type = RubyNode.class)
-public abstract class WriteLevelVariableNode extends FrameSlotNode implements WriteNode {
-
-    private final int varLevel;
-
-    public WriteLevelVariableNode(RubyContext context, SourceSection sourceSection, FrameSlot frameSlot, int level) {
-        super(context, sourceSection, frameSlot);
-        this.varLevel = level;
-    }
-
-    protected WriteLevelVariableNode(WriteLevelVariableNode prev) {
-        this(prev.getContext(), prev.getSourceSection(), prev.frameSlot, prev.varLevel);
-    }
-
-    @Specialization(guards = "isBooleanKind")
-    public boolean doBoolean(VirtualFrame frame, boolean value) {
-        MaterializedFrame levelFrame = RubyArguments.getDeclarationFrame(frame, varLevel);
-        setBoolean(levelFrame, value);
-        return value;
-    }
-
-    @Specialization(guards = "isFixnumKind")
-    public int doFixnum(VirtualFrame frame, int value) {
-        MaterializedFrame levelFrame = RubyArguments.getDeclarationFrame(frame, varLevel);
-        setFixnum(levelFrame, value);
-        return value;
-    }
-
-    @Specialization(guards = "isFloatKind")
-    public double doFloat(VirtualFrame frame, double value) {
-        MaterializedFrame levelFrame = RubyArguments.getDeclarationFrame(frame, varLevel);
-        setFloat(levelFrame, value);
-        return value;
-    }
-
-    @Specialization(guards = "isObjectKind")
-    public Object doObject(VirtualFrame frame, Object value) {
-        MaterializedFrame levelFrame = RubyArguments.getDeclarationFrame(frame, varLevel);
-        setObject(levelFrame, value);
-        return value;
-    }
-
-    @Override
-    public RubyNode makeReadNode() {
-        return ReadLevelVariableNodeFactory.create(getContext(), getSourceSection(), frameSlot, varLevel);
-    }
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/locals/WriteLocalVariableNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,58 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.methods.locals;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.dsl.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-
-@NodeChild(value = "rhs", type = RubyNode.class)
-public abstract class WriteLocalVariableNode extends FrameSlotNode implements WriteNode {
-
-    public WriteLocalVariableNode(RubyContext context, SourceSection sourceSection, FrameSlot frameSlot) {
-        super(context, sourceSection, frameSlot);
-    }
-
-    protected WriteLocalVariableNode(WriteLocalVariableNode prev) {
-        this(prev.getContext(), prev.getSourceSection(), prev.frameSlot);
-    }
-
-    @Specialization(guards = "isBooleanKind")
-    public boolean doFixnum(VirtualFrame frame, boolean value) {
-        setBoolean(frame, value);
-        return value;
-    }
-
-    @Specialization(guards = "isFixnumKind")
-    public int doFixnum(VirtualFrame frame, int value) {
-        setFixnum(frame, value);
-        return value;
-    }
-
-    @Specialization(guards = "isFloatKind")
-    public double doFloat(VirtualFrame frame, double value) {
-        setFloat(frame, value);
-        return value;
-    }
-
-    @Specialization(guards = "isObjectKind")
-    public Object doObject(VirtualFrame frame, Object value) {
-        setObject(frame, value);
-        return value;
-    }
-
-    @Override
-    public RubyNode makeReadNode() {
-        return ReadLocalVariableNodeFactory.create(getContext(), getSourceSection(), frameSlot);
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/objects/ClassNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.objects;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.objects.*;
-
-/**
- * Reads the class of an object.
- */
-@NodeInfo(shortName = "class")
-public class ClassNode extends RubyNode {
-
-    @Child protected RubyNode child;
-
-    public ClassNode(RubyContext context, SourceSection sourceSection, RubyNode child) {
-        super(context, sourceSection);
-        this.child = adoptChild(child);
-    }
-
-    @Override
-    public Object execute(VirtualFrame frame) {
-        return ((RubyBasicObject) child.execute(frame)).getRubyClass();
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/objects/DefineOrGetClassNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,83 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.objects;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.control.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-
-/**
- * Define a new class, or get the existing one of the same name.
- */
-public class DefineOrGetClassNode extends RubyNode {
-
-    private final String name;
-    @Child protected RubyNode moduleDefinedIn;
-    @Child protected RubyNode superClass;
-
-    public DefineOrGetClassNode(RubyContext context, SourceSection sourceSection, String name, RubyNode moduleDefinedIn, RubyNode superClass) {
-        super(context, sourceSection);
-        this.name = name;
-        this.moduleDefinedIn = adoptChild(moduleDefinedIn);
-        this.superClass = adoptChild(superClass);
-    }
-
-    @Override
-    public Object execute(VirtualFrame frame) {
-        CompilerAsserts.neverPartOfCompilation();
-
-        final RubyContext context = getContext();
-
-        final RubyModule moduleDefinedInObject = (RubyModule) moduleDefinedIn.execute(frame);
-
-        // Look for a current definition of the class, or create a new one
-
-        final Object constantValue = moduleDefinedInObject.lookupConstant(name);
-
-        RubyClass definingClass;
-
-        if (constantValue == null) {
-            final Object self = frame.getArguments(RubyArguments.class).getSelf();
-
-            RubyModule parentModule;
-
-            if (self instanceof RubyModule) {
-                parentModule = (RubyModule) self;
-            } else {
-                // Because it's top level, and so self is the magic main object
-                parentModule = null;
-            }
-
-            final RubyClass superClassObject = (RubyClass) superClass.execute(frame);
-
-            if (superClassObject instanceof RubyException.RubyExceptionClass) {
-                definingClass = new RubyException.RubyExceptionClass(superClassObject, name);
-            } else {
-                definingClass = new RubyClass(parentModule, superClassObject, name);
-            }
-
-            moduleDefinedInObject.setConstant(name, definingClass);
-            moduleDefinedInObject.getSingletonClass().setConstant(name, definingClass);
-
-            definingClass.getRubyClass().include(moduleDefinedInObject);
-        } else {
-            if (constantValue instanceof RubyClass) {
-                definingClass = (RubyClass) constantValue;
-            } else {
-                throw new RaiseException(context.getCoreLibrary().typeErrorIsNotA(constantValue.toString(), "class"));
-            }
-        }
-
-        return definingClass;
-    }
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/objects/DefineOrGetModuleNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,73 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.objects;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.control.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-
-/**
- * Define a new module, or get the existing one of the same name.
- */
-public class DefineOrGetModuleNode extends RubyNode {
-
-    private final String name;
-    @Child protected RubyNode moduleDefinedIn;
-
-    public DefineOrGetModuleNode(RubyContext context, SourceSection sourceSection, String name, RubyNode moduleDefinedIn) {
-        super(context, sourceSection);
-        this.name = name;
-        this.moduleDefinedIn = adoptChild(moduleDefinedIn);
-    }
-
-    @Override
-    public Object execute(VirtualFrame frame) {
-        CompilerAsserts.neverPartOfCompilation();
-
-        final RubyContext context = getContext();
-
-        final RubyModule moduleDefinedInObject = (RubyModule) moduleDefinedIn.execute(frame);
-
-        // Look for a current definition of the module, or create a new one
-
-        final Object constantValue = moduleDefinedInObject.lookupConstant(name);
-
-        RubyModule definingModule;
-
-        if (constantValue == null) {
-            final Object self = frame.getArguments(RubyArguments.class).getSelf();
-
-            RubyModule parentModule;
-
-            if (self instanceof RubyModule) {
-                parentModule = (RubyModule) self;
-            } else {
-                // Because it's top level, and so self is the magic main object
-                parentModule = null;
-            }
-
-            definingModule = new RubyModule(context.getCoreLibrary().getModuleClass(), parentModule, name);
-            moduleDefinedInObject.setConstant(name, definingModule);
-            moduleDefinedInObject.getSingletonClass().setConstant(name, definingModule);
-        } else {
-            if (constantValue instanceof RubyModule) {
-                definingModule = (RubyModule) constantValue;
-            } else {
-                throw new RaiseException(context.getCoreLibrary().typeErrorIsNotA(constantValue.toString(), "module"));
-            }
-        }
-
-        return definingModule;
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/objects/OpenModuleNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,45 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.objects;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.nodes.methods.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-
-/**
- * Open a module and execute a method in it - probably to define new methods.
- */
-public class OpenModuleNode extends RubyNode {
-
-    @Child protected RubyNode definingModule;
-    @Child protected MethodDefinitionNode definitionMethod;
-
-    public OpenModuleNode(RubyContext context, SourceSection sourceSection, RubyNode definingModule, MethodDefinitionNode definitionMethod) {
-        super(context, sourceSection);
-        this.definingModule = adoptChild(definingModule);
-        this.definitionMethod = adoptChild(definitionMethod);
-    }
-
-    @Override
-    public Object execute(VirtualFrame frame) {
-        CompilerAsserts.neverPartOfCompilation();
-
-        // Call the definition method with the module as self - there's no return value
-
-        final RubyModule module = (RubyModule) definingModule.execute(frame);
-        definitionMethod.executeMethod(frame).call(frame.pack(), module, null);
-
-        return NilPlaceholder.INSTANCE;
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/objects/ReadClassVariableNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,78 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.objects;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-
-@NodeInfo(shortName = "read-class-variable")
-public class ReadClassVariableNode extends RubyNode {
-
-    protected final String name;
-    @Child protected RubyNode module;
-
-    public ReadClassVariableNode(RubyContext context, SourceSection sourceSection, String name, RubyNode module) {
-        super(context, sourceSection);
-        this.name = name;
-        this.module = adoptChild(module);
-    }
-
-    @Override
-    public Object execute(VirtualFrame frame) {
-        final RubyObject object = (RubyObject) module.execute(frame);
-
-        RubyModule moduleObject;
-
-        // TODO(CS): this cannot be right
-
-        if (object instanceof RubyModule) {
-            moduleObject = (RubyModule) object;
-        } else {
-            moduleObject = object.getRubyClass();
-        }
-
-        final Object value = moduleObject.lookupClassVariable(name);
-
-        if (value == null) {
-            // TODO(CS): is this right?
-            return NilPlaceholder.INSTANCE;
-        }
-
-        return value;
-    }
-
-    @Override
-    public Object isDefined(VirtualFrame frame) {
-        final RubyContext context = getContext();
-
-        final RubyObject object = (RubyObject) module.execute(frame);
-
-        RubyModule moduleObject;
-
-        if (object instanceof RubyModule) {
-            moduleObject = (RubyModule) object;
-        } else {
-            moduleObject = object.getRubyClass();
-        }
-
-        final Object value = moduleObject.lookupClassVariable(name);
-
-        if (value == null) {
-            return NilPlaceholder.INSTANCE;
-        } else {
-            return context.makeString("class variable");
-        }
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/objects/SelfNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,32 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.objects;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-
-@NodeInfo(shortName = "self")
-public class SelfNode extends RubyNode {
-
-    public SelfNode(RubyContext context, SourceSection sourceSection) {
-        super(context, sourceSection);
-    }
-
-    @Override
-    public Object execute(VirtualFrame frame) {
-        final Object self = frame.getArguments(RubyArguments.class).getSelf();
-        assert RubyContext.shouldObjectBeVisible(self);
-        return self;
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/objects/SingletonClassNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,50 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.objects;
-
-import java.math.*;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.objects.*;
-
-/**
- * Reads the singleton (meta, eigen) class of an object.
- */
-@NodeInfo(shortName = "singleton")
-public class SingletonClassNode extends RubyNode {
-
-    @Child protected RubyNode child;
-
-    public SingletonClassNode(RubyContext context, SourceSection sourceSection, RubyNode child) {
-        super(context, sourceSection);
-        this.child = adoptChild(child);
-    }
-
-    @Override
-    public Object execute(VirtualFrame frame) {
-        final Object childResult = child.execute(frame);
-
-        final RubyContext context = getContext();
-
-        if (childResult instanceof NilPlaceholder) {
-            return context.getCoreLibrary().getNilClass();
-        } else if (childResult instanceof BigInteger) {
-            // TODO(CS): this is problematic - do Bignums have singletons or not?
-            return context.getCoreLibrary().box(childResult).getSingletonClass();
-        } else {
-            return ((RubyBasicObject) childResult).getSingletonClass();
-        }
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/objects/WriteClassVariableNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,46 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.objects;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-
-@NodeInfo(shortName = "write-class-variable")
-public class WriteClassVariableNode extends RubyNode {
-
-    private final String name;
-    @Child protected RubyNode module;
-    @Child protected RubyNode rhs;
-
-    public WriteClassVariableNode(RubyContext context, SourceSection sourceSection, String name, RubyNode module, RubyNode rhs) {
-        super(context, sourceSection);
-        this.name = name;
-        this.module = adoptChild(module);
-        this.rhs = adoptChild(rhs);
-    }
-
-    @Override
-    public Object execute(VirtualFrame frame) {
-        // TODO(CS): can module ever not evaluate to a RubyModule?
-
-        final RubyModule moduleObject = (RubyModule) module.execute(frame);
-
-        final Object rhsValue = rhs.execute(frame);
-
-        moduleObject.setClassVariable(name, rhsValue);
-
-        return rhsValue;
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/objects/instancevariables/ReadFixnumInstanceVariableNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,56 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.objects.instancevariables;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.objects.*;
-
-@NodeInfo(shortName = "@Fixnum")
-public class ReadFixnumInstanceVariableNode extends ReadSpecializedInstanceVariableNode {
-
-    private final FixnumStorageLocation storageLocation;
-
-    public ReadFixnumInstanceVariableNode(RubyContext context, SourceSection sourceSection, String name, RubyNode receiver, ObjectLayout objectLayout, FixnumStorageLocation storageLocation) {
-        super(context, sourceSection, name, receiver, objectLayout);
-        this.storageLocation = storageLocation;
-    }
-
-    @Override
-    public int executeFixnum(VirtualFrame frame) throws UnexpectedResultException {
-        final RubyBasicObject receiverObject = (RubyBasicObject) receiver.execute(frame);
-
-        final ObjectLayout receiverLayout = receiverObject.getObjectLayout();
-
-        final boolean condition = receiverLayout == objectLayout;
-
-        if (condition) {
-            assert receiverLayout != null;
-            return storageLocation.readFixnum(receiverObject, condition);
-        } else {
-            CompilerDirectives.transferToInterpreter();
-            replace(respecialize(receiverObject));
-            throw new UnexpectedResultException(receiverObject.getInstanceVariable(name));
-        }
-    }
-
-    @Override
-    public Object execute(VirtualFrame frame) {
-        try {
-            return executeFixnum(frame);
-        } catch (UnexpectedResultException e) {
-            return e.getResult();
-        }
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/objects/instancevariables/ReadFloatInstanceVariableNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,56 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.objects.instancevariables;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.objects.*;
-
-@NodeInfo(shortName = "@Float")
-public class ReadFloatInstanceVariableNode extends ReadSpecializedInstanceVariableNode {
-
-    private final FloatStorageLocation storageLocation;
-
-    public ReadFloatInstanceVariableNode(RubyContext context, SourceSection sourceSection, String name, RubyNode receiver, ObjectLayout objectLayout, FloatStorageLocation storageLocation) {
-        super(context, sourceSection, name, receiver, objectLayout);
-        this.storageLocation = storageLocation;
-    }
-
-    @Override
-    public double executeFloat(VirtualFrame frame) throws UnexpectedResultException {
-        final RubyBasicObject receiverObject = (RubyBasicObject) receiver.execute(frame);
-
-        final ObjectLayout receiverLayout = receiverObject.getObjectLayout();
-
-        final boolean condition = receiverLayout == objectLayout;
-
-        if (condition) {
-            assert receiverLayout != null;
-            return storageLocation.readFloat(receiverObject, condition);
-        } else {
-            CompilerDirectives.transferToInterpreter();
-            replace(respecialize(receiverObject));
-            throw new UnexpectedResultException(receiverObject.getInstanceVariable(name));
-        }
-    }
-
-    @Override
-    public Object execute(VirtualFrame frame) {
-        try {
-            return executeFloat(frame);
-        } catch (UnexpectedResultException e) {
-            return e.getResult();
-        }
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/objects/instancevariables/ReadInstanceVariableNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,77 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.objects.instancevariables;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.objects.*;
-
-public abstract class ReadInstanceVariableNode extends RubyNode implements ReadNode {
-
-    protected final String name;
-    @Child protected RubyNode receiver;
-
-    public ReadInstanceVariableNode(RubyContext context, SourceSection sourceSection, String name, RubyNode receiver) {
-        super(context, sourceSection);
-        this.name = name;
-        this.receiver = adoptChild(receiver);
-    }
-
-    public ReadInstanceVariableNode respecialize(RubyBasicObject receiverObject) {
-        final StorageLocation storageLocation = receiverObject.getUpdatedObjectLayout().findStorageLocation(name);
-
-        if (storageLocation == null) {
-            return new ReadMissingInstanceVariableNode(getSourceSection(), name, receiver, receiverObject.getObjectLayout(), getContext());
-        }
-
-        if (storageLocation instanceof FixnumStorageLocation) {
-            return new ReadFixnumInstanceVariableNode(getContext(), getSourceSection(), name, receiver, storageLocation.getObjectLayout(), (FixnumStorageLocation) storageLocation);
-        } else if (storageLocation instanceof FloatStorageLocation) {
-            return new ReadFloatInstanceVariableNode(getContext(), getSourceSection(), name, receiver, storageLocation.getObjectLayout(), (FloatStorageLocation) storageLocation);
-        } else {
-            return new ReadObjectInstanceVariableNode(getContext(), getSourceSection(), name, receiver, storageLocation.getObjectLayout(), (ObjectStorageLocation) storageLocation);
-        }
-    }
-
-    public WriteInstanceVariableNode makeWriteNode(RubyNode rhs) {
-        return new UninitializedWriteInstanceVariableNode(getContext(), getEncapsulatingSourceSection(), name, (RubyNode) receiver.copy(), rhs);
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public RubyNode getReceiver() {
-        return receiver;
-    }
-
-    @Override
-    public Object isDefined(VirtualFrame frame) {
-        final RubyContext context = getContext();
-
-        try {
-            final Object receiverObject = receiver.execute(frame);
-            final RubyBasicObject receiverRubyObject = context.getCoreLibrary().box(receiverObject);
-
-            final ObjectLayout layout = receiverRubyObject.getObjectLayout();
-            final StorageLocation storageLocation = layout.findStorageLocation(name);
-
-            if (storageLocation.isSet(receiverRubyObject)) {
-                return context.makeString("instance-variable");
-            } else {
-                return NilPlaceholder.INSTANCE;
-            }
-        } catch (Exception e) {
-            return NilPlaceholder.INSTANCE;
-        }
-    }
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/objects/instancevariables/ReadMissingInstanceVariableNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.objects.instancevariables;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.objects.*;
-
-@NodeInfo(shortName = "@missing")
-public class ReadMissingInstanceVariableNode extends ReadSpecializedInstanceVariableNode {
-
-    public ReadMissingInstanceVariableNode(SourceSection sourceSection, String name, RubyNode receiver, ObjectLayout objectLayout, RubyContext context) {
-        super(context, sourceSection, name, receiver, objectLayout);
-    }
-
-    @Override
-    public Object execute(VirtualFrame frame) {
-        final RubyBasicObject receiverObject = (RubyBasicObject) receiver.execute(frame);
-
-        if (!receiverObject.getObjectLayout().contains(objectLayout)) {
-            CompilerDirectives.transferToInterpreter();
-            replace(respecialize(receiverObject));
-            return receiverObject.getInstanceVariable(name);
-        }
-
-        return NilPlaceholder.INSTANCE;
-    }
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/objects/instancevariables/ReadObjectInstanceVariableNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,47 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.objects.instancevariables;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.objects.*;
-
-@NodeInfo(shortName = "@Object")
-public class ReadObjectInstanceVariableNode extends ReadSpecializedInstanceVariableNode {
-
-    private final ObjectStorageLocation storageLocation;
-
-    public ReadObjectInstanceVariableNode(RubyContext context, SourceSection sourceSection, String name, RubyNode receiver, ObjectLayout objectLayout, ObjectStorageLocation storageLocation) {
-        super(context, sourceSection, name, receiver, objectLayout);
-        this.storageLocation = storageLocation;
-    }
-
-    @Override
-    public Object execute(VirtualFrame frame) {
-        final RubyBasicObject receiverObject = (RubyBasicObject) receiver.execute(frame);
-
-        final ObjectLayout receiverLayout = receiverObject.getObjectLayout();
-
-        final boolean condition = receiverLayout == objectLayout;
-
-        if (condition) {
-            assert receiverLayout != null;
-            return storageLocation.read(receiverObject, condition);
-        } else {
-            CompilerDirectives.transferToInterpreter();
-            replace(respecialize(receiverObject));
-            return receiverObject.getInstanceVariable(name);
-        }
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/objects/instancevariables/ReadSpecializedInstanceVariableNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,29 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.objects.instancevariables;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.objects.*;
-
-public abstract class ReadSpecializedInstanceVariableNode extends ReadInstanceVariableNode {
-
-    protected final ObjectLayout objectLayout;
-
-    public ReadSpecializedInstanceVariableNode(RubyContext context, SourceSection sourceSection, String name, RubyNode receiver, ObjectLayout objectLayout) {
-        super(context, sourceSection, name, receiver);
-        this.objectLayout = objectLayout;
-    }
-
-    protected void respecialize() {
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/objects/instancevariables/UninitializedReadInstanceVariableNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,34 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.objects.instancevariables;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.objects.*;
-
-@NodeInfo(shortName = "@uninit")
-public class UninitializedReadInstanceVariableNode extends ReadInstanceVariableNode {
-
-    public UninitializedReadInstanceVariableNode(RubyContext context, SourceSection sourceSection, String name, RubyNode receiver) {
-        super(context, sourceSection, name, receiver);
-    }
-
-    @Override
-    public Object execute(VirtualFrame frame) {
-        CompilerDirectives.transferToInterpreter();
-        final RubyBasicObject receiverObject = (RubyBasicObject) receiver.execute(frame);
-        replace(respecialize(receiverObject));
-        return receiverObject.getInstanceVariable(name);
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/objects/instancevariables/UninitializedWriteInstanceVariableNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /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. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.objects.instancevariables;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.objects.*;
-
-@NodeInfo(shortName = "@uninit=")
-public class UninitializedWriteInstanceVariableNode extends WriteInstanceVariableNode {
-
-    public UninitializedWriteInstanceVariableNode(RubyContext context, SourceSection sourceSection, String name, RubyNode receiver, RubyNode rhs) {
-        super(context, sourceSection, name, receiver, rhs);
-    }
-
-    @Override
-    public Object execute(VirtualFrame frame) {
-        CompilerDirectives.transferToInterpreter();
-        final RubyBasicObject receiverObject = (RubyBasicObject) receiver.execute(frame);
-        final Object value = rhs.execute(frame);
-        receiverObject.setInstanceVariable(name, value);
-        replace(respecialize(receiverObject));
-        return value;
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/objects/instancevariables/WriteFixnumInstanceVariableNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,68 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.objects.instancevariables;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.objects.*;
-
-@NodeInfo(shortName = "@Fixnum=")
-public class WriteFixnumInstanceVariableNode extends WriteSpecializedInstanceVariableNode {
-
-    private final FixnumStorageLocation storageLocation;
-
-    public WriteFixnumInstanceVariableNode(RubyContext context, SourceSection sourceSection, String name, RubyNode receiver, RubyNode rhs, ObjectLayout objectLayout,
-                    FixnumStorageLocation storageLocation) {
-        super(context, sourceSection, name, receiver, rhs, objectLayout);
-        this.storageLocation = storageLocation;
-    }
-
-    @Override
-    public int executeFixnum(VirtualFrame frame) throws UnexpectedResultException {
-        final RubyBasicObject receiverObject = (RubyBasicObject) receiver.execute(frame);
-
-        int value;
-
-        try {
-            value = rhs.executeFixnum(frame);
-        } catch (UnexpectedResultException e) {
-            receiverObject.setInstanceVariable(name, e.getResult());
-            replace(respecialize(receiverObject));
-            throw e;
-        }
-
-        final ObjectLayout receiverLayout = receiverObject.getObjectLayout();
-
-        if (receiverLayout != objectLayout) {
-            CompilerDirectives.transferToInterpreter();
-            receiverObject.setInstanceVariable(name, value);
-            replace(respecialize(receiverObject));
-            return value;
-        }
-
-        assert receiverLayout != null;
-
-        storageLocation.writeFixnum(receiverObject, value);
-        return value;
-    }
-
-    @Override
-    public Object execute(VirtualFrame frame) {
-        try {
-            return executeFixnum(frame);
-        } catch (UnexpectedResultException e) {
-            return e.getResult();
-        }
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/objects/instancevariables/WriteFloatInstanceVariableNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,68 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.objects.instancevariables;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.objects.*;
-
-@NodeInfo(shortName = "@Float=")
-public class WriteFloatInstanceVariableNode extends WriteSpecializedInstanceVariableNode {
-
-    private final FloatStorageLocation storageLocation;
-
-    public WriteFloatInstanceVariableNode(RubyContext context, SourceSection sourceSection, String name, RubyNode receiver, RubyNode rhs, ObjectLayout objectLayout,
-                    FloatStorageLocation storageLocation) {
-        super(context, sourceSection, name, receiver, rhs, objectLayout);
-        this.storageLocation = storageLocation;
-    }
-
-    @Override
-    public double executeFloat(VirtualFrame frame) throws UnexpectedResultException {
-        final RubyBasicObject receiverObject = (RubyBasicObject) receiver.execute(frame);
-
-        double value;
-
-        try {
-            value = rhs.executeFloat(frame);
-        } catch (UnexpectedResultException e) {
-            receiverObject.setInstanceVariable(name, e.getResult());
-            replace(respecialize(receiverObject));
-            throw e;
-        }
-
-        final ObjectLayout receiverLayout = receiverObject.getObjectLayout();
-
-        if (receiverLayout != objectLayout) {
-            CompilerDirectives.transferToInterpreter();
-            receiverObject.setInstanceVariable(name, value);
-            replace(respecialize(receiverObject));
-            return value;
-        }
-
-        assert receiverLayout != null;
-
-        storageLocation.writeFloat(receiverObject, value);
-        return value;
-    }
-
-    @Override
-    public Object execute(VirtualFrame frame) {
-        try {
-            return executeFloat(frame);
-        } catch (UnexpectedResultException e) {
-            return e.getResult();
-        }
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/objects/instancevariables/WriteInstanceVariableNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,63 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.objects.instancevariables;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.objects.*;
-
-public abstract class WriteInstanceVariableNode extends RubyNode implements WriteNode {
-
-    protected final String name;
-    @Child protected RubyNode receiver;
-    @Child protected RubyNode rhs;
-
-    public WriteInstanceVariableNode(RubyContext context, SourceSection sourceSection, String name, RubyNode receiver, RubyNode rhs) {
-        super(context, sourceSection);
-        this.name = name;
-        this.receiver = adoptChild(receiver);
-        this.rhs = adoptChild(rhs);
-    }
-
-    public WriteInstanceVariableNode respecialize(RubyBasicObject receiverObject) {
-        StorageLocation storageLocation = receiverObject.getObjectLayout().findStorageLocation(name);
-
-        if (storageLocation == null) {
-            throw new RuntimeException("Storage location should be found at this point");
-        }
-
-        if (storageLocation instanceof FixnumStorageLocation) {
-            return new WriteFixnumInstanceVariableNode(getContext(), getSourceSection(), name, receiver, rhs, storageLocation.getObjectLayout(), (FixnumStorageLocation) storageLocation);
-        } else if (storageLocation instanceof FloatStorageLocation) {
-            return new WriteFloatInstanceVariableNode(getContext(), getSourceSection(), name, receiver, rhs, storageLocation.getObjectLayout(), (FloatStorageLocation) storageLocation);
-        } else {
-            return new WriteObjectInstanceVariableNode(getContext(), getSourceSection(), name, receiver, rhs, storageLocation.getObjectLayout(), (ObjectStorageLocation) storageLocation);
-        }
-    }
-
-    @Override
-    public ReadInstanceVariableNode makeReadNode() {
-        return new UninitializedReadInstanceVariableNode(getContext(), getEncapsulatingSourceSection(), name, (RubyNode) receiver.copy());
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public RubyNode getReceiver() {
-        return receiver;
-    }
-
-    public RubyNode getRHS() {
-        return rhs;
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/objects/instancevariables/WriteObjectInstanceVariableNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,50 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.objects.instancevariables;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.objects.*;
-
-@NodeInfo(shortName = "@Object=")
-public class WriteObjectInstanceVariableNode extends WriteSpecializedInstanceVariableNode {
-
-    private final ObjectStorageLocation storageLocation;
-
-    public WriteObjectInstanceVariableNode(RubyContext context, SourceSection sourceSection, String name, RubyNode receiver, RubyNode rhs, ObjectLayout objectLayout,
-                    ObjectStorageLocation storageLocation) {
-        super(context, sourceSection, name, receiver, rhs, objectLayout);
-        this.storageLocation = storageLocation;
-    }
-
-    @Override
-    public Object execute(VirtualFrame frame) {
-        final RubyBasicObject receiverObject = (RubyBasicObject) receiver.execute(frame);
-        final Object value = rhs.execute(frame);
-
-        final ObjectLayout receiverLayout = receiverObject.getObjectLayout();
-
-        if (receiverLayout != objectLayout) {
-            CompilerDirectives.transferToInterpreter();
-            receiverObject.setInstanceVariable(name, value);
-            replace(respecialize(receiverObject));
-            return value;
-        }
-
-        assert receiverLayout != null;
-
-        storageLocation.write(receiverObject, value);
-        return value;
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/objects/instancevariables/WriteSpecializedInstanceVariableNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,26 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.objects.instancevariables;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.objects.*;
-
-public abstract class WriteSpecializedInstanceVariableNode extends WriteInstanceVariableNode {
-
-    protected final ObjectLayout objectLayout;
-
-    public WriteSpecializedInstanceVariableNode(RubyContext context, SourceSection sourceSection, String name, RubyNode receiver, RubyNode rhs, ObjectLayout objectLayout) {
-        super(context, sourceSection, name, receiver, rhs);
-        this.objectLayout = objectLayout;
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/yield/GeneralYieldDispatchNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /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. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.yield;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-
-/**
- * A yield dispatch node that just calls {@link RubyProc#call} as normal.
- */
-public class GeneralYieldDispatchNode extends YieldDispatchNode {
-
-    public GeneralYieldDispatchNode(RubyContext context, SourceSection sourceSection) {
-        super(context, sourceSection);
-    }
-
-    @Override
-    public Object dispatch(VirtualFrame frame, RubyProc block, Object[] argumentsObjects) {
-        return block.call(frame.pack(), argumentsObjects);
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/yield/InlinedYieldDispatchNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,60 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.yield;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-
-/**
- * Dispatch to a known method which has been inlined.
- */
-public class InlinedYieldDispatchNode extends YieldDispatchNode {
-
-    private final RubyRootNode pristineRootNode;
-
-    private final FrameDescriptor frameDescriptor;
-    private final RubyRootNode rootNode;
-
-    public InlinedYieldDispatchNode(RubyContext context, SourceSection sourceSection, InlinableMethodImplementation method) {
-        super(context, sourceSection);
-        pristineRootNode = method.getPristineRootNode();
-        frameDescriptor = method.getFrameDescriptor();
-        rootNode = method.getCloneOfPristineRootNode();
-    }
-
-    @Override
-    public Object dispatch(VirtualFrame frame, RubyProc block, Object[] argumentsObjects) {
-        /*
-         * We're inlining based on the root node used, checking that root node still matches, and
-         * then taking the materialized frame from the block we actually got. We can't look for
-         * RubyMethod or RubyProc, because they're allocated for each call passing a block.
-         */
-
-        if (!(block.getMethod().getImplementation() instanceof InlinableMethodImplementation) ||
-                        ((InlinableMethodImplementation) block.getMethod().getImplementation()).getPristineRootNode() != pristineRootNode) {
-            CompilerDirectives.transferToInterpreter();
-
-            // TODO(CS): at the moment we just go back to uninit, which may cause loops
-
-            final UninitializedYieldDispatchNode dispatch = new UninitializedYieldDispatchNode(getContext(), getSourceSection());
-            replace(dispatch);
-            return dispatch.dispatch(frame, block, argumentsObjects);
-        }
-
-        final InlinableMethodImplementation implementation = (InlinableMethodImplementation) block.getMethod().getImplementation();
-
-        final RubyArguments arguments = new RubyArguments(implementation.getDeclarationFrame(), block.getSelf(), block.getBlock(), argumentsObjects);
-        final VirtualFrame inlinedFrame = Truffle.getRuntime().createVirtualFrame(frame.pack(), arguments, frameDescriptor);
-        return rootNode.execute(inlinedFrame);
-    }
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/yield/UninitializedYieldDispatchNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,46 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.yield;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.nodes.call.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-import com.oracle.truffle.ruby.runtime.methods.*;
-
-/**
- * An uninitialized node in the yield dispatch chain.
- */
-public class UninitializedYieldDispatchNode extends YieldDispatchNode {
-
-    public UninitializedYieldDispatchNode(RubyContext context, SourceSection sourceSection) {
-        super(context, sourceSection);
-    }
-
-    @Override
-    public Object dispatch(VirtualFrame frame, RubyProc block, Object[] argumentsObjects) {
-        CompilerDirectives.transferToInterpreter();
-
-        final MethodImplementation implementation = block.getMethod().getImplementation();
-
-        if (implementation instanceof InlinableMethodImplementation && InlineHeuristic.shouldInlineYield((InlinableMethodImplementation) implementation)) {
-            final InlinedYieldDispatchNode dispatch = new InlinedYieldDispatchNode(getContext(), getSourceSection(), (InlinableMethodImplementation) implementation);
-            replace(dispatch);
-            return dispatch.dispatch(frame, block, argumentsObjects);
-        } else {
-            final GeneralYieldDispatchNode dispatch = new GeneralYieldDispatchNode(getContext(), getSourceSection());
-            replace(dispatch);
-            return dispatch.dispatch(frame, block, argumentsObjects);
-        }
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/yield/YieldDispatchNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,40 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.yield;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-
-/**
- * A node in the yield dispatch chain.
- */
-public abstract class YieldDispatchNode extends Node {
-
-    private final RubyContext context;
-
-    public YieldDispatchNode(RubyContext context, SourceSection sourceSection) {
-        super(sourceSection);
-
-        assert context != null;
-        assert sourceSection != null;
-
-        this.context = context;
-    }
-
-    public abstract Object dispatch(VirtualFrame frame, RubyProc block, Object[] argumentsObjects);
-
-    public RubyContext getContext() {
-        return context;
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/yield/YieldNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,65 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.nodes.yield;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-
-/**
- * Yield to the current block.
- */
-@NodeInfo(shortName = "yield")
-public class YieldNode extends RubyNode {
-
-    @Children protected final RubyNode[] arguments;
-    @Child protected YieldDispatchNode dispatch;
-
-    public YieldNode(RubyContext context, SourceSection sourceSection, RubyNode[] arguments) {
-        super(context, sourceSection);
-        this.arguments = adoptChildren(arguments);
-        dispatch = adoptChild(new UninitializedYieldDispatchNode(getContext(), getSourceSection()));
-    }
-
-    @ExplodeLoop
-    @Override
-    public final Object execute(VirtualFrame frame) {
-        final Object[] argumentsObjects = new Object[arguments.length];
-
-        for (int i = 0; i < arguments.length; i++) {
-            argumentsObjects[i] = arguments[i].execute(frame);
-        }
-
-        final RubyProc block = frame.getArguments(RubyArguments.class).getBlock();
-
-        if (block == null) {
-            CompilerDirectives.transferToInterpreter();
-            // TODO(CS): convert to the proper Ruby exception
-            throw new RuntimeException("No block to yield to");
-        }
-
-        return dispatch.dispatch(frame, block, argumentsObjects);
-    }
-
-    @Override
-    public Object isDefined(VirtualFrame frame) {
-        final RubyArguments args = frame.getArguments(RubyArguments.class);
-
-        if (args.getBlock() == null) {
-            return NilPlaceholder.INSTANCE;
-        } else {
-            return getContext().makeString("yield");
-        }
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.parser/src/com/oracle/truffle/ruby/parser/DeadNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /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. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.parser;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-
-/**
- * Dead nodes are removed wherever they are found during translation. They fill in for some missing
- * nodes when we're processing the AST.
- */
-public class DeadNode extends RubyNode {
-
-    public DeadNode(RubyContext context, SourceSection sourceSection) {
-        super(context, sourceSection);
-    }
-
-    @Override
-    public Object execute(VirtualFrame frame) {
-        throw new UnsupportedOperationException("Dead nodes should have been pruned before execution starts");
-    }
-}
--- a/graal/com.oracle.truffle.ruby.parser/src/com/oracle/truffle/ruby/parser/JRubyParser.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,181 +0,0 @@
-/*
- * Copyright (c) 2013, 2014 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.parser;
-
-import java.io.*;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.nodes.control.*;
-import com.oracle.truffle.ruby.nodes.literal.*;
-import com.oracle.truffle.ruby.nodes.methods.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.control.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-import com.oracle.truffle.ruby.runtime.methods.*;
-
-public class JRubyParser implements RubyParser {
-
-    private long nextReturnID = 0;
-
-    public JRubyParser() {
-    }
-
-    @Override
-    public RubyParserResult parse(RubyContext context, Source source, ParserContext parserContext, MaterializedFrame parentFrame) {
-
-        // Set up the JRuby parser
-
-        final org.jrubyparser.Parser parser = new org.jrubyparser.Parser();
-
-        // TODO(cs) should this get a new unique method identifier or not?
-        final TranslatorEnvironment environment = new TranslatorEnvironment(context, environmentForFrame(context, parentFrame), this, allocateReturnID(), true, true, new UniqueMethodIdentifier());
-
-        // All parsing contexts have a visibility slot at their top level
-
-        environment.addMethodDeclarationSlots();
-
-        final org.jrubyparser.LocalStaticScope staticScope = new org.jrubyparser.LocalStaticScope(null);
-
-        if (parentFrame != null) {
-            /*
-             * Note that jruby-parser will be mistaken about how deep the existing variables are,
-             * but that doesn't matter as we look them up ourselves after being told their in some
-             * parent scope.
-             */
-
-            MaterializedFrame frame = parentFrame;
-
-            while (frame != null) {
-                for (FrameSlot slot : frame.getFrameDescriptor().getSlots()) {
-                    if (slot.getIdentifier() instanceof String) {
-                        final String name = (String) slot.getIdentifier();
-                        if (staticScope.exists(name) == -1) {
-                            staticScope.assign(null, name, null);
-                        }
-                    }
-                }
-
-                frame = frame.getArguments(RubyArguments.class).getDeclarationFrame();
-            }
-        }
-
-        final org.jrubyparser.parser.ParserConfiguration parserConfiguration = new org.jrubyparser.parser.ParserConfiguration(0, org.jrubyparser.CompatVersion.RUBY2_0, staticScope);
-
-        // Parse to the JRuby AST
-
-        org.jrubyparser.ast.RootNode node;
-
-        try {
-            node = (org.jrubyparser.ast.RootNode) parser.parse(source.getName(), new StringReader(source.getCode()), parserConfiguration);
-        } catch (UnsupportedOperationException | org.jrubyparser.lexer.SyntaxException e) {
-            String message = e.getMessage();
-
-            if (message == null) {
-                message = "(no message)";
-            }
-
-            throw new RaiseException(new RubyException(context.getCoreLibrary().getSyntaxErrorClass(), message));
-        }
-
-        if (context.getConfiguration().getPrintParseTree()) {
-            System.err.println(node);
-        }
-
-        // Translate to Ruby Truffle nodes
-
-        final Translator translator;
-
-        if (parserContext == RubyParser.ParserContext.MODULE) {
-            translator = new ModuleTranslator(context, null, environment, source);
-        } else {
-            translator = new Translator(context, null, environment, source);
-        }
-
-        RubyNode truffleNode;
-
-        try {
-            context.getDebugContext().getDebugManager().notifyStartLoading(source);
-
-            if (node.getBody() == null) {
-                truffleNode = new NilNode(context, null);
-            } else {
-                truffleNode = (RubyNode) node.getBody().accept(translator);
-            }
-
-            // Load flip-flop states
-
-            if (environment.getFlipFlopStates().size() > 0) {
-                truffleNode = new SequenceNode(context, truffleNode.getSourceSection(), translator.initFlipFlopStates(truffleNode.getSourceSection()), truffleNode);
-            }
-
-            // Catch next
-
-            truffleNode = new CatchNextNode(context, truffleNode.getSourceSection(), truffleNode);
-
-            // Catch return
-
-            truffleNode = new CatchReturnAsErrorNode(context, truffleNode.getSourceSection(), truffleNode);
-
-            // Shell result
-
-            if (parserContext == RubyParser.ParserContext.SHELL) {
-                truffleNode = new ShellResultNode(context, truffleNode.getSourceSection(), truffleNode);
-            }
-
-            // Root Node
-
-            String indicativeName;
-
-            switch (parserContext) {
-                case TOP_LEVEL:
-                    indicativeName = "(main)";
-                    break;
-                case SHELL:
-                    indicativeName = "(shell)";
-                    break;
-                case MODULE:
-                    indicativeName = "(module)";
-                    break;
-                default:
-                    throw new UnsupportedOperationException();
-            }
-
-            final RootNode root = new RubyRootNode(truffleNode.getSourceSection(), environment.getFrameDescriptor(), indicativeName, truffleNode);
-
-            // Return the root and the frame descriptor
-            return new RubyParserResult(root);
-        } finally {
-            context.getDebugContext().getDebugManager().notifyFinishedLoading(source);
-        }
-    }
-
-    public long allocateReturnID() {
-        if (nextReturnID == Long.MAX_VALUE) {
-            throw new RuntimeException("Return IDs exhausted");
-        }
-
-        final long allocated = nextReturnID;
-        nextReturnID++;
-        return allocated;
-    }
-
-    private TranslatorEnvironment environmentForFrame(RubyContext context, MaterializedFrame frame) {
-        if (frame == null) {
-            return null;
-        } else {
-            final MaterializedFrame parent = frame.getArguments(RubyArguments.class).getDeclarationFrame();
-            return new TranslatorEnvironment(context, environmentForFrame(context, parent), frame.getFrameDescriptor(), this, allocateReturnID(), true, true, new UniqueMethodIdentifier());
-        }
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.parser/src/com/oracle/truffle/ruby/parser/MethodTranslator.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,338 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.parser;
-
-import java.util.*;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.nodes.call.*;
-import com.oracle.truffle.ruby.nodes.control.*;
-import com.oracle.truffle.ruby.nodes.literal.*;
-import com.oracle.truffle.ruby.nodes.methods.*;
-import com.oracle.truffle.ruby.nodes.methods.arguments.*;
-import com.oracle.truffle.ruby.nodes.methods.locals.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.methods.*;
-
-class MethodTranslator extends Translator {
-
-    private boolean isBlock;
-
-    public MethodTranslator(RubyContext context, Translator parent, TranslatorEnvironment environment, boolean isBlock, Source source) {
-        super(context, parent, environment, source);
-        this.isBlock = isBlock;
-    }
-
-    public MethodDefinitionNode compileFunctionNode(SourceSection sourceSection, String methodName, org.jrubyparser.ast.ArgsNode argsNode, org.jrubyparser.ast.Node bodyNode) {
-        environment.setMethodName(methodName);
-
-        final Arity arity = findParameters(argsNode);
-
-        RubyNode body;
-
-        if (bodyNode != null) {
-            body = (RubyNode) bodyNode.accept(this);
-        } else {
-            body = new NilNode(context, sourceSection);
-        }
-
-        body = loadArgumentsIntoLocals(arity, body);
-
-        if (environment.getFlipFlopStates().size() > 0) {
-            body = new SequenceNode(context, sourceSection, initFlipFlopStates(sourceSection), body);
-        }
-
-        if (isBlock) {
-            body = new CatchNextNode(context, sourceSection, body);
-        } else {
-            body = new CatchReturnNode(context, sourceSection, body, environment.getReturnID());
-            body = new CatchNextNode(context, sourceSection, body);
-        }
-
-        final RubyRootNode pristineRootNode = new RubyRootNode(sourceSection, environment.getFrameDescriptor(), methodName, body);
-
-        final CallTarget callTarget = Truffle.getRuntime().createCallTarget(NodeUtil.cloneNode(pristineRootNode));
-
-        if (isBlock) {
-            return new BlockDefinitionNode(context, sourceSection, methodName, environment.getUniqueMethodIdentifier(), environment.getFrameDescriptor(), environment.needsDeclarationFrame(),
-                            pristineRootNode, callTarget);
-        } else {
-            return new MethodDefinitionNode(context, sourceSection, methodName, environment.getUniqueMethodIdentifier(), environment.getFrameDescriptor(), environment.needsDeclarationFrame(),
-                            pristineRootNode, callTarget);
-        }
-    }
-
-    private RubyNode loadArgumentsIntoLocals(Arity arity, RubyNode body) {
-        final SourceSection sourceSection = body.getEncapsulatingSourceSection();
-
-        final List<RubyNode> loadIndividualArgumentsNodes = new ArrayList<>();
-
-        if (!isBlock) {
-            loadIndividualArgumentsNodes.add(new CheckArityNode(context, sourceSection, arity));
-        }
-
-        final int preCount = environment.getPreParameters().size();
-        final int postCount = environment.getPostParameters().size();
-
-        for (int n = 0; n < environment.getPreParameters().size(); n++) {
-            final FrameSlot param = environment.getPreParameters().get(n);
-
-            // ReadPre reads from the start of the arguments array
-
-            final ReadPreArgumentNode readArgumentNode = new ReadPreArgumentNode(context, sourceSection, n, false);
-
-            final WriteLocalVariableNode writeLocal = WriteLocalVariableNodeFactory.create(context, sourceSection, param, readArgumentNode);
-
-            loadIndividualArgumentsNodes.add(writeLocal);
-        }
-
-        for (int n = 0; n < environment.getOptionalParameters().size(); n++) {
-            final FrameSlot param = environment.getOptionalParameters().get(n);
-            final RubyNode defaultValue = environment.getOptionalParametersDefaultValues().get(param);
-
-            /*
-             * ReadOptional reads from the start of the arguments array, as long as it is long
-             * enough, else uses the default value (which may use locals with arguments just loaded,
-             * either from pre or preceding optionals).
-             */
-
-            final ReadOptionalArgumentNode readArgumentNode = new ReadOptionalArgumentNode(context, body.getEncapsulatingSourceSection(), preCount + n, preCount + postCount + n + 1,
-                            (RubyNode) defaultValue.copy());
-
-            final WriteLocalVariableNode writeLocal = WriteLocalVariableNodeFactory.create(context, sourceSection, param, readArgumentNode);
-
-            loadIndividualArgumentsNodes.add(writeLocal);
-        }
-
-        for (int n = 0; n < environment.getPostParameters().size(); n++) {
-            final FrameSlot param = environment.getPostParameters().get(n);
-
-            // ReadPost reads from the end of the arguments array
-
-            final ReadPostArgumentNode readArgumentNode = new ReadPostArgumentNode(context, sourceSection, postCount - n - 1);
-
-            final WriteLocalVariableNode writeLocal = WriteLocalVariableNodeFactory.create(context, sourceSection, param, readArgumentNode);
-
-            loadIndividualArgumentsNodes.add(writeLocal);
-        }
-
-        if (environment.getRestParameter() != null) {
-            /*
-             * TODO(cs): this assumes there are no optionals and therefore also no posts, which may
-             * not be a valid assumption.
-             */
-
-            if (postCount != 0) {
-                context.implementationMessage("post arguments as well as a rest argument - they will conflict");
-            }
-
-            final ReadRestArgumentNode readArgumentNode = new ReadRestArgumentNode(context, sourceSection, preCount);
-
-            final WriteLocalVariableNode writeLocal = WriteLocalVariableNodeFactory.create(context, sourceSection, environment.getRestParameter(), readArgumentNode);
-
-            loadIndividualArgumentsNodes.add(writeLocal);
-        }
-
-        if (environment.getBlockParameter() != null) {
-            final FrameSlot param = environment.getBlockParameter();
-
-            final ReadBlockArgumentNode readArgumentNode = new ReadBlockArgumentNode(context, sourceSection, false);
-
-            final WriteLocalVariableNode writeLocal = WriteLocalVariableNodeFactory.create(context, sourceSection, param, readArgumentNode);
-
-            loadIndividualArgumentsNodes.add(writeLocal);
-        }
-
-        final RubyNode loadIndividualArguments = new SequenceNode(context, sourceSection, loadIndividualArgumentsNodes.toArray(new RubyNode[loadIndividualArgumentsNodes.size()]));
-
-        final RubyNode noSwitch = new SequenceNode(context, body.getSourceSection(), loadIndividualArguments, body);
-
-        if (!isBlock) {
-            return noSwitch;
-        }
-
-        /*
-         * See the test testBlockArgumentsDestructure for a motivation for this. See
-         * BlockDestructureSwitchNode for how it works.
-         */
-
-        if (preCount + postCount == 1 && environment.getOptionalParameters().size() == 0) {
-            return noSwitch;
-        }
-
-        final List<RubyNode> destructureLoadArgumentsNodes = new ArrayList<>();
-
-        for (int n = 0; n < environment.getPreParameters().size(); n++) {
-            final FrameSlot param = environment.getPreParameters().get(n);
-
-            final ReadDestructureArgumentNode readArgumentNode = new ReadDestructureArgumentNode(context, sourceSection, n);
-
-            final WriteLocalVariableNode writeLocal = WriteLocalVariableNodeFactory.create(context, sourceSection, param, readArgumentNode);
-
-            destructureLoadArgumentsNodes.add(writeLocal);
-        }
-
-        final RubyNode destructureLoadArguments = new SequenceNode(context, body.getSourceSection(), destructureLoadArgumentsNodes.toArray(new RubyNode[destructureLoadArgumentsNodes.size()]));
-
-        return new BlockDestructureSwitchNode(context, body.getEncapsulatingSourceSection(), loadIndividualArguments, destructureLoadArguments, body);
-
-    }
-
-    private Arity findParameters(org.jrubyparser.ast.ArgsNode args) {
-        if (args == null) {
-            return Arity.NO_ARGS;
-        }
-
-        final SourceSection sourceSection = translate(args.getPosition());
-
-        if (args.getPre() != null) {
-            for (org.jrubyparser.ast.Node arg : args.getPre().childNodes()) {
-                if (arg instanceof org.jrubyparser.ast.ArgumentNode) {
-                    final org.jrubyparser.ast.ArgumentNode argNode = (org.jrubyparser.ast.ArgumentNode) arg;
-                    environment.getPreParameters().add(environment.declareVar(argNode.getName()));
-                } else if (arg instanceof org.jrubyparser.ast.MultipleAsgnNode) {
-                    /*
-                     * TODO(cs): I don't know how to handle this yet, so I just do my best to get
-                     * the names out and define them so the rest of the parser succeeds.
-                     */
-
-                    context.implementationMessage("only extracting names from multiple assignment in arguments");
-
-                    final org.jrubyparser.ast.MultipleAsgnNode multAsgn = (org.jrubyparser.ast.MultipleAsgnNode) arg;
-
-                    final List<String> names = new ArrayList<>();
-                    getNamesFromMultipleAssignment(multAsgn, names);
-
-                    for (String name : names) {
-                        environment.getPreParameters().add(environment.declareVar(name));
-                    }
-                }
-            }
-        }
-
-        // The JRuby parser expresses optional arguments as a block of local assignments
-
-        /*
-         * Note that default values for optional params can refer to the actual value of previous
-         * args, so be careful with the order of args here and in loadArgumentsIntoLocals.
-         */
-
-        if (args.getOptional() != null) {
-            for (org.jrubyparser.ast.Node arg : args.getOptional().childNodes()) {
-                final org.jrubyparser.ast.OptArgNode optArgNode = (org.jrubyparser.ast.OptArgNode) arg;
-
-                String name;
-                org.jrubyparser.ast.Node valueNode;
-
-                if (optArgNode.getValue() instanceof org.jrubyparser.ast.LocalAsgnNode) {
-                    final org.jrubyparser.ast.LocalAsgnNode optLocalAsgn = (org.jrubyparser.ast.LocalAsgnNode) optArgNode.getValue();
-                    name = optLocalAsgn.getName();
-                    valueNode = optLocalAsgn.getValue();
-                } else if (optArgNode.getValue() instanceof org.jrubyparser.ast.DAsgnNode) {
-                    final org.jrubyparser.ast.DAsgnNode optLocalAsgn = (org.jrubyparser.ast.DAsgnNode) optArgNode.getValue();
-                    name = optLocalAsgn.getName();
-                    valueNode = optLocalAsgn.getValue();
-                } else {
-                    throw new UnsupportedOperationException(optArgNode.getValue().getClass().getName());
-                }
-
-                RubyNode paramDefaultValue;
-
-                if (valueNode == null) {
-                    paramDefaultValue = new NilNode(context, sourceSection);
-                } else {
-                    paramDefaultValue = (RubyNode) valueNode.accept(this);
-                }
-
-                final FrameSlot frameSlot = environment.declareVar(name);
-                environment.getOptionalParameters().add(frameSlot);
-                environment.getOptionalParametersDefaultValues().put(frameSlot, paramDefaultValue);
-            }
-        }
-
-        if (args.getPost() != null) {
-            for (org.jrubyparser.ast.Node arg : args.getPost().childNodes()) {
-                final org.jrubyparser.ast.ArgumentNode argNode = (org.jrubyparser.ast.ArgumentNode) arg;
-                environment.getPostParameters().add(environment.declareVar(argNode.getName()));
-            }
-        }
-
-        if (args.getRest() != null) {
-            final org.jrubyparser.ast.RestArgNode rest = (org.jrubyparser.ast.RestArgNode) args.getRest();
-            environment.setRestParameter(environment.declareVar(rest.getName()));
-        }
-
-        if (args.getBlock() != null) {
-            final org.jrubyparser.ast.BlockArgNode blockArgNode = args.getBlock();
-            final FrameSlot frameSlot = environment.declareVar(blockArgNode.getName());
-            environment.setBlockParameter(frameSlot);
-        }
-
-        final int minimum = environment.getPreParameters().size() + environment.getPostParameters().size();
-
-        int maximum = minimum + environment.getOptionalParameters().size();
-
-        if (args.getRest() != null) {
-            maximum = Arity.NO_MAXIMUM;
-        }
-
-        return new Arity(minimum, maximum);
-    }
-
-    private void getNamesFromMultipleAssignment(org.jrubyparser.ast.MultipleAsgnNode multAsgn, List<String> names) {
-        for (org.jrubyparser.ast.Node a : multAsgn.getPre().childNodes()) {
-            if (a instanceof org.jrubyparser.ast.DAsgnNode) {
-                names.add(((org.jrubyparser.ast.DAsgnNode) a).getName());
-            } else if (a instanceof org.jrubyparser.ast.MultipleAsgnNode) {
-                getNamesFromMultipleAssignment((org.jrubyparser.ast.MultipleAsgnNode) a, names);
-            } else if (a instanceof org.jrubyparser.ast.LocalAsgnNode) {
-                names.add(((org.jrubyparser.ast.LocalAsgnNode) a).getName());
-            } else {
-                throw new RuntimeException(a.getClass().getName());
-            }
-        }
-    }
-
-    @Override
-    public Object visitSuperNode(org.jrubyparser.ast.SuperNode node) {
-        final SourceSection sourceSection = translate(node.getPosition());
-
-        final ArgumentsAndBlockTranslation argumentsAndBlock = translateArgumentsAndBlock(sourceSection, node.getIter(), node.getArgs(), null);
-
-        final String name = environment.getMethodName();
-
-        return new GeneralSuperCallNode(context, sourceSection, name, argumentsAndBlock.getBlock(), argumentsAndBlock.getArguments(), argumentsAndBlock.isSplatted());
-    }
-
-    @Override
-    public Object visitZSuperNode(org.jrubyparser.ast.ZSuperNode node) {
-        final SourceSection sourceSection = translate(node.getPosition());
-
-        final ArgumentsAndBlockTranslation argumentsAndBlock = translateArgumentsAndBlock(sourceSection, node.getIter(), null, null);
-
-        final String name = environment.getMethodName();
-
-        return new GeneralSuperCallNode(context, sourceSection, name, argumentsAndBlock.getBlock(), argumentsAndBlock.getArguments(), argumentsAndBlock.isSplatted());
-    }
-
-    @Override
-    protected FlipFlopStateNode createFlipFlopState(SourceSection sourceSection, int depth) {
-        if (isBlock) {
-            environment.setNeedsDeclarationFrame();
-            return parent.createFlipFlopState(sourceSection, depth + 1);
-        } else {
-            return super.createFlipFlopState(sourceSection, depth);
-        }
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.parser/src/com/oracle/truffle/ruby/parser/ModuleTranslator.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,134 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.parser;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.nodes.constants.*;
-import com.oracle.truffle.ruby.nodes.control.*;
-import com.oracle.truffle.ruby.nodes.literal.*;
-import com.oracle.truffle.ruby.nodes.methods.*;
-import com.oracle.truffle.ruby.nodes.objects.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.methods.*;
-
-/**
- * Translates module and class nodes.
- * <p>
- * In Ruby, a module or class definition is somewhat like a method. It has a local scope and a value
- * for self, which is the module or class object that is being defined. Therefore for a module or
- * class definition we translate into a special method. We run that method with self set to be the
- * newly allocated module or class. We then have to treat at least method and constant definitions
- * differently.
- */
-class ModuleTranslator extends Translator {
-
-    public ModuleTranslator(RubyContext context, Translator parent, TranslatorEnvironment environment, Source source) {
-        super(context, parent, environment, source);
-    }
-
-    public MethodDefinitionNode compileClassNode(org.jrubyparser.SourcePosition sourcePosition, String name, org.jrubyparser.ast.Node bodyNode) {
-        final SourceSection sourceSection = translate(sourcePosition);
-
-        environment.addMethodDeclarationSlots();
-
-        final String methodName = "(" + name + "-def" + ")";
-        environment.setMethodName(methodName);
-
-        RubyNode body;
-
-        if (bodyNode != null) {
-            body = (RubyNode) bodyNode.accept(this);
-        } else {
-            body = new NilNode(context, sourceSection);
-        }
-
-        if (environment.getFlipFlopStates().size() > 0) {
-            body = new SequenceNode(context, sourceSection, initFlipFlopStates(sourceSection), body);
-        }
-
-        body = new CatchReturnNode(context, sourceSection, body, environment.getReturnID());
-
-        final RubyRootNode pristineRootNode = new RubyRootNode(sourceSection, environment.getFrameDescriptor(), methodName, body);
-
-        final CallTarget callTarget = Truffle.getRuntime().createCallTarget(NodeUtil.cloneNode(pristineRootNode));
-
-        return new MethodDefinitionNode(context, sourceSection, methodName, environment.getUniqueMethodIdentifier(), environment.getFrameDescriptor(), environment.needsDeclarationFrame(),
-                        pristineRootNode, callTarget);
-    }
-
-    @Override
-    public Object visitConstDeclNode(org.jrubyparser.ast.ConstDeclNode node) {
-        final SourceSection sourceSection = translate(node.getPosition());
-
-        final SelfNode selfNode = new SelfNode(context, sourceSection);
-
-        return new WriteConstantNode(context, sourceSection, node.getName(), selfNode, (RubyNode) node.getValue().accept(this));
-    }
-
-    @Override
-    public Object visitConstNode(org.jrubyparser.ast.ConstNode node) {
-        final SourceSection sourceSection = translate(node.getPosition());
-
-        final SelfNode selfNode = new SelfNode(context, sourceSection);
-
-        return new UninitializedReadConstantNode(context, sourceSection, node.getName(), selfNode);
-    }
-
-    @Override
-    public Object visitDefnNode(org.jrubyparser.ast.DefnNode node) {
-        /*
-         * The top-level translator puts methods into Object. We put ours into the self, which is
-         * the class being defined.
-         */
-
-        final TranslatorEnvironment newEnvironment = new TranslatorEnvironment(context, environment, environment.getParser(), environment.getParser().allocateReturnID(), true, true,
-                        new UniqueMethodIdentifier());
-        final MethodTranslator methodCompiler = new MethodTranslator(context, this, newEnvironment, false, source);
-        final MethodDefinitionNode functionExprNode = methodCompiler.compileFunctionNode(translate(node.getPosition()), node.getName(), node.getArgs(), node.getBody());
-
-        final SourceSection sourceSection = translate(node.getPosition());
-        return new AddMethodNode(context, sourceSection, new SelfNode(context, sourceSection), functionExprNode);
-    }
-
-    @Override
-    public Object visitClassVarAsgnNode(org.jrubyparser.ast.ClassVarAsgnNode node) {
-        final SourceSection sourceSection = translate(node.getPosition());
-
-        final RubyNode receiver = new SelfNode(context, sourceSection);
-
-        final RubyNode rhs = (RubyNode) node.getValue().accept(this);
-
-        return new WriteClassVariableNode(context, sourceSection, node.getName(), receiver, rhs);
-    }
-
-    @Override
-    public Object visitClassVarNode(org.jrubyparser.ast.ClassVarNode node) {
-        final SourceSection sourceSection = translate(node.getPosition());
-        return new ReadClassVariableNode(context, sourceSection, node.getName(), new SelfNode(context, sourceSection));
-    }
-
-    @Override
-    public Object visitAliasNode(org.jrubyparser.ast.AliasNode node) {
-        final SourceSection sourceSection = translate(node.getPosition());
-
-        final org.jrubyparser.ast.LiteralNode oldName = (org.jrubyparser.ast.LiteralNode) node.getOldName();
-        final org.jrubyparser.ast.LiteralNode newName = (org.jrubyparser.ast.LiteralNode) node.getNewName();
-
-        return new AliasNode(context, sourceSection, new SelfNode(context, sourceSection), newName.getName(), oldName.getName());
-    }
-
-    @Override
-    protected RubyNode getModuleToDefineModulesIn(SourceSection sourceSection) {
-        return new SelfNode(context, sourceSection);
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.parser/src/com/oracle/truffle/ruby/parser/RubyFrameTypeConversion.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,30 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.parser;
-
-import com.oracle.truffle.api.impl.*;
-import com.oracle.truffle.ruby.runtime.*;
-
-public final class RubyFrameTypeConversion extends DefaultFrameTypeConversion {
-
-    private static final RubyFrameTypeConversion INSTANCE = new RubyFrameTypeConversion();
-
-    private RubyFrameTypeConversion() {
-    }
-
-    @Override
-    public Object getDefaultValue() {
-        return NilPlaceholder.INSTANCE;
-    }
-
-    public static RubyFrameTypeConversion getInstance() {
-        return INSTANCE;
-    }
-}
--- a/graal/com.oracle.truffle.ruby.parser/src/com/oracle/truffle/ruby/parser/Translator.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2066 +0,0 @@
-/*
- * Copyright (c) 2013, 2014 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.parser;
-
-import java.math.*;
-import java.util.*;
-import java.util.regex.*;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.impl.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.nodes.call.*;
-import com.oracle.truffle.ruby.nodes.cast.*;
-import com.oracle.truffle.ruby.nodes.constants.*;
-import com.oracle.truffle.ruby.nodes.control.*;
-import com.oracle.truffle.ruby.nodes.core.*;
-import com.oracle.truffle.ruby.nodes.instrument.*;
-import com.oracle.truffle.ruby.nodes.literal.*;
-import com.oracle.truffle.ruby.nodes.literal.array.*;
-import com.oracle.truffle.ruby.nodes.methods.*;
-import com.oracle.truffle.ruby.nodes.methods.locals.*;
-import com.oracle.truffle.ruby.nodes.objects.*;
-import com.oracle.truffle.ruby.nodes.objects.instancevariables.*;
-import com.oracle.truffle.ruby.nodes.yield.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-import com.oracle.truffle.ruby.runtime.core.range.*;
-import com.oracle.truffle.ruby.runtime.methods.*;
-
-/**
- * A JRuby parser node visitor which translates JRuby AST nodes into our Ruby nodes, implementing a
- * Ruby parser. Therefore there is some namespace contention here! We make all references to JRuby
- * explicit. This is the only place though - it doesn't leak out elsewhere.
- */
-public class Translator implements org.jrubyparser.NodeVisitor {
-
-    protected final Translator parent;
-
-    protected final RubyContext context;
-    protected final TranslatorEnvironment environment;
-    protected final Source source;
-    protected final RubyNodeInstrumenter instrumenter;
-
-    private boolean translatingForStatement = false;
-
-    private static final Map<Class, String> nodeDefinedNames = new HashMap<>();
-
-    static {
-        nodeDefinedNames.put(org.jrubyparser.ast.SelfNode.class, "self");
-        nodeDefinedNames.put(org.jrubyparser.ast.NilNode.class, "nil");
-        nodeDefinedNames.put(org.jrubyparser.ast.TrueNode.class, "true");
-        nodeDefinedNames.put(org.jrubyparser.ast.FalseNode.class, "false");
-        nodeDefinedNames.put(org.jrubyparser.ast.LocalAsgnNode.class, "assignment");
-        nodeDefinedNames.put(org.jrubyparser.ast.DAsgnNode.class, "assignment");
-        nodeDefinedNames.put(org.jrubyparser.ast.GlobalAsgnNode.class, "assignment");
-        nodeDefinedNames.put(org.jrubyparser.ast.InstAsgnNode.class, "assignment");
-        nodeDefinedNames.put(org.jrubyparser.ast.ClassVarAsgnNode.class, "assignment");
-        nodeDefinedNames.put(org.jrubyparser.ast.OpAsgnAndNode.class, "assignment");
-        nodeDefinedNames.put(org.jrubyparser.ast.OpAsgnOrNode.class, "assignment");
-        nodeDefinedNames.put(org.jrubyparser.ast.OpAsgnNode.class, "assignment");
-        nodeDefinedNames.put(org.jrubyparser.ast.OpElementAsgnNode.class, "assignment");
-        nodeDefinedNames.put(org.jrubyparser.ast.MultipleAsgnNode.class, "assignment");
-        nodeDefinedNames.put(org.jrubyparser.ast.GlobalVarNode.class, "global-variable");
-        nodeDefinedNames.put(org.jrubyparser.ast.StrNode.class, "expression");
-        nodeDefinedNames.put(org.jrubyparser.ast.DStrNode.class, "expression");
-        nodeDefinedNames.put(org.jrubyparser.ast.FixnumNode.class, "expression");
-        nodeDefinedNames.put(org.jrubyparser.ast.BignumNode.class, "expression");
-        nodeDefinedNames.put(org.jrubyparser.ast.FloatNode.class, "expression");
-        nodeDefinedNames.put(org.jrubyparser.ast.RegexpNode.class, "expression");
-        nodeDefinedNames.put(org.jrubyparser.ast.DRegexpNode.class, "expression");
-        nodeDefinedNames.put(org.jrubyparser.ast.ArrayNode.class, "expression");
-        nodeDefinedNames.put(org.jrubyparser.ast.HashNode.class, "expression");
-        nodeDefinedNames.put(org.jrubyparser.ast.SymbolNode.class, "expression");
-        nodeDefinedNames.put(org.jrubyparser.ast.DotNode.class, "expression");
-        nodeDefinedNames.put(org.jrubyparser.ast.NotNode.class, "expression");
-        nodeDefinedNames.put(org.jrubyparser.ast.AndNode.class, "expression");
-        nodeDefinedNames.put(org.jrubyparser.ast.OrNode.class, "expression");
-        nodeDefinedNames.put(org.jrubyparser.ast.LocalVarNode.class, "local-variable");
-        nodeDefinedNames.put(org.jrubyparser.ast.DVarNode.class, "local-variable");
-    }
-
-    /**
-     * Global variables which in common usage have frame local semantics.
-     */
-    public static final Set<String> FRAME_LOCAL_GLOBAL_VARIABLES = new HashSet<>(Arrays.asList("$_"));
-
-    public Translator(RubyContext context, Translator parent, TranslatorEnvironment environment, Source source) {
-        this.context = context;
-        this.parent = parent;
-        this.environment = environment;
-        this.source = source;
-        this.instrumenter = environment.getNodeInstrumenter();
-    }
-
-    @Override
-    public Object visitAliasNode(org.jrubyparser.ast.AliasNode node) {
-        final SourceSection sourceSection = translate(node.getPosition());
-
-        final org.jrubyparser.ast.LiteralNode oldName = (org.jrubyparser.ast.LiteralNode) node.getOldName();
-        final org.jrubyparser.ast.LiteralNode newName = (org.jrubyparser.ast.LiteralNode) node.getNewName();
-
-        final ClassNode classNode = new ClassNode(context, sourceSection, new SelfNode(context, sourceSection));
-
-        return new AliasNode(context, sourceSection, classNode, newName.getName(), oldName.getName());
-    }
-
-    @Override
-    public Object visitAndNode(org.jrubyparser.ast.AndNode node) {
-        final SourceSection sourceSection = translate(node.getPosition());
-
-        RubyNode x;
-
-        if (node.getFirst() == null) {
-            x = new NilNode(context, sourceSection);
-        } else {
-            x = (RubyNode) node.getFirst().accept(this);
-        }
-
-        RubyNode y;
-
-        if (node.getSecond() == null) {
-            y = new NilNode(context, sourceSection);
-        } else {
-            y = (RubyNode) node.getSecond().accept(this);
-        }
-
-        return AndNodeFactory.create(context, sourceSection, x, y);
-    }
-
-    @Override
-    public Object visitArgsCatNode(org.jrubyparser.ast.ArgsCatNode node) {
-        final List<org.jrubyparser.ast.Node> nodes = new ArrayList<>();
-        collectArgsCatNodes(nodes, node);
-
-        final List<RubyNode> translatedNodes = new ArrayList<>();
-
-        for (org.jrubyparser.ast.Node catNode : nodes) {
-            translatedNodes.add((RubyNode) catNode.accept(this));
-        }
-
-        return new ArrayConcatNode(context, translate(node.getPosition()), translatedNodes.toArray(new RubyNode[translatedNodes.size()]));
-    }
-
-    // ArgsCatNodes can be nested - this collects them into a flat list of children
-    private void collectArgsCatNodes(List<org.jrubyparser.ast.Node> nodes, org.jrubyparser.ast.ArgsCatNode node) {
-        if (node.getFirst() instanceof org.jrubyparser.ast.ArgsCatNode) {
-            collectArgsCatNodes(nodes, (org.jrubyparser.ast.ArgsCatNode) node.getFirst());
-        } else {
-            nodes.add(node.getFirst());
-        }
-
-        if (node.getSecond() instanceof org.jrubyparser.ast.ArgsCatNode) {
-            collectArgsCatNodes(nodes, (org.jrubyparser.ast.ArgsCatNode) node.getSecond());
-        } else {
-            nodes.add(node.getSecond());
-        }
-    }
-
-    @Override
-    public Object visitArgsNode(org.jrubyparser.ast.ArgsNode node) {
-        return unimplemented(node);
-    }
-
-    @Override
-    public Object visitArgsPushNode(org.jrubyparser.ast.ArgsPushNode node) {
-        return new ArrayPushNode(context, translate(node.getPosition()), (RubyNode) node.getFirstNode().accept(this), (RubyNode) node.getSecondNode().accept(this));
-    }
-
-    @Override
-    public Object visitArrayNode(org.jrubyparser.ast.ArrayNode node) {
-        final List<org.jrubyparser.ast.Node> values = node.childNodes();
-
-        final RubyNode[] translatedValues = new RubyNode[values.size()];
-
-        for (int n = 0; n < values.size(); n++) {
-            translatedValues[n] = (RubyNode) values.get(n).accept(this);
-        }
-
-        return new UninitialisedArrayLiteralNode(context, translate(node.getPosition()), translatedValues);
-    }
-
-    @Override
-    public Object visitAttrAssignNode(org.jrubyparser.ast.AttrAssignNode node) {
-        return visitAttrAssignNodeExtraArgument(node, null);
-    }
-
-    /**
-     * See translateDummyAssignment to understand what this is for.
-     */
-    public RubyNode visitAttrAssignNodeExtraArgument(org.jrubyparser.ast.AttrAssignNode node, RubyNode extraArgument) {
-        final org.jrubyparser.ast.CallNode callNode = new org.jrubyparser.ast.CallNode(node.getPosition(), node.getReceiver(), node.getName(), node.getArgs());
-        return visitCallNodeExtraArgument(callNode, extraArgument);
-    }
-
-    @Override
-    public Object visitBackRefNode(org.jrubyparser.ast.BackRefNode node) {
-        return unimplemented(node);
-    }
-
-    @Override
-    public Object visitBeginNode(org.jrubyparser.ast.BeginNode node) {
-        return node.getBody().accept(this);
-    }
-
-    @Override
-    public Object visitBignumNode(org.jrubyparser.ast.BignumNode node) {
-        return new BignumLiteralNode(context, translate(node.getPosition()), node.getValue());
-    }
-
-    @Override
-    public Object visitBlockArg18Node(org.jrubyparser.ast.BlockArg18Node node) {
-        return unimplemented(node);
-    }
-
-    @Override
-    public Object visitBlockArgNode(org.jrubyparser.ast.BlockArgNode node) {
-        return unimplemented(node);
-    }
-
-    @Override
-    public Object visitBlockNode(org.jrubyparser.ast.BlockNode node) {
-        final List<org.jrubyparser.ast.Node> children = node.childNodes();
-
-        final List<RubyNode> translatedChildren = new ArrayList<>();
-
-        for (int n = 0; n < children.size(); n++) {
-            final RubyNode translatedChild = (RubyNode) children.get(n).accept(this);
-
-            if (!(translatedChild instanceof DeadNode)) {
-                translatedChildren.add(translatedChild);
-            }
-        }
-
-        if (translatedChildren.size() == 1) {
-            return translatedChildren.get(0);
-        } else {
-            return new SequenceNode(context, translate(node.getPosition()), translatedChildren.toArray(new RubyNode[translatedChildren.size()]));
-        }
-    }
-
-    @Override
-    public Object visitBlockPassNode(org.jrubyparser.ast.BlockPassNode node) {
-        return unimplemented(node);
-    }
-
-    @Override
-    public Object visitBreakNode(org.jrubyparser.ast.BreakNode node) {
-        final SourceSection sourceSection = translate(node.getPosition());
-
-        RubyNode resultNode;
-
-        if (node.getValueNode() == null) {
-            resultNode = new NilNode(context, sourceSection);
-        } else {
-            resultNode = (RubyNode) node.getValueNode().accept(this);
-        }
-
-        return new BreakNode(context, sourceSection, resultNode);
-    }
-
-    @Override
-    public Object visitCallNode(org.jrubyparser.ast.CallNode node) {
-        return visitCallNodeExtraArgument(node, null);
-    }
-
-    /**
-     * See translateDummyAssignment to understand what this is for.
-     */
-    public RubyNode visitCallNodeExtraArgument(org.jrubyparser.ast.CallNode node, RubyNode extraArgument) {
-        final SourceSection sourceSection = translate(node.getPosition());
-
-        final RubyNode receiverTranslated = (RubyNode) node.getReceiver().accept(this);
-
-        org.jrubyparser.ast.Node args = node.getArgs();
-        org.jrubyparser.ast.Node block = node.getIter();
-
-        if (block == null && args instanceof org.jrubyparser.ast.IterNode) {
-            final org.jrubyparser.ast.Node temp = args;
-            args = block;
-            block = temp;
-        }
-
-        final ArgumentsAndBlockTranslation argumentsAndBlock = translateArgumentsAndBlock(sourceSection, block, args, extraArgument);
-
-        RubyNode translated = new CallNode(context, sourceSection, node.getName(), receiverTranslated, argumentsAndBlock.getBlock(), argumentsAndBlock.isSplatted(), argumentsAndBlock.getArguments());
-
-        return instrumenter.instrumentAsCall(translated, node.getName());
-    }
-
-    protected class ArgumentsAndBlockTranslation {
-
-        private final RubyNode block;
-        private final RubyNode[] arguments;
-        private final boolean isSplatted;
-
-        public ArgumentsAndBlockTranslation(RubyNode block, RubyNode[] arguments, boolean isSplatted) {
-            super();
-            this.block = block;
-            this.arguments = arguments;
-            this.isSplatted = isSplatted;
-        }
-
-        public RubyNode getBlock() {
-            return block;
-        }
-
-        public RubyNode[] getArguments() {
-            return arguments;
-        }
-
-        public boolean isSplatted() {
-            return isSplatted;
-        }
-
-    }
-
-    protected ArgumentsAndBlockTranslation translateArgumentsAndBlock(SourceSection sourceSection, org.jrubyparser.ast.Node iterNode, org.jrubyparser.ast.Node argsNode, RubyNode extraArgument) {
-        assert !(argsNode instanceof org.jrubyparser.ast.IterNode);
-
-        final List<org.jrubyparser.ast.Node> arguments = new ArrayList<>();
-        org.jrubyparser.ast.Node blockPassNode = null;
-
-        boolean isSplatted = false;
-
-        if (argsNode instanceof org.jrubyparser.ast.ListNode) {
-            arguments.addAll(((org.jrubyparser.ast.ListNode) argsNode).childNodes());
-        } else if (argsNode instanceof org.jrubyparser.ast.BlockPassNode) {
-            final org.jrubyparser.ast.BlockPassNode blockPass = (org.jrubyparser.ast.BlockPassNode) argsNode;
-
-            final org.jrubyparser.ast.Node blockPassArgs = blockPass.getArgs();
-
-            if (blockPassArgs instanceof org.jrubyparser.ast.ListNode) {
-                arguments.addAll(((org.jrubyparser.ast.ListNode) blockPassArgs).childNodes());
-            } else if (blockPassArgs instanceof org.jrubyparser.ast.ArgsCatNode) {
-                arguments.add(blockPassArgs);
-            } else if (blockPassArgs != null) {
-                throw new UnsupportedOperationException("Don't know how to block pass " + blockPassArgs);
-            }
-
-            blockPassNode = blockPass.getBody();
-        } else if (argsNode instanceof org.jrubyparser.ast.SplatNode) {
-            isSplatted = true;
-            arguments.add(argsNode);
-        } else if (argsNode instanceof org.jrubyparser.ast.ArgsCatNode) {
-            isSplatted = true;
-            arguments.add(argsNode);
-        } else if (argsNode != null) {
-            isSplatted = true;
-            arguments.add(argsNode);
-        }
-
-        RubyNode blockTranslated;
-
-        if (blockPassNode != null && iterNode != null) {
-            throw new UnsupportedOperationException("Don't know how to pass both an block and a block-pass argument");
-        } else if (iterNode != null) {
-            blockTranslated = (BlockDefinitionNode) iterNode.accept(this);
-        } else if (blockPassNode != null) {
-            blockTranslated = ProcCastNodeFactory.create(context, sourceSection, (RubyNode) blockPassNode.accept(this));
-        } else {
-            blockTranslated = null;
-        }
-
-        final List<RubyNode> argumentsTranslated = new ArrayList<>();
-
-        for (org.jrubyparser.ast.Node argument : arguments) {
-            argumentsTranslated.add((RubyNode) argument.accept(this));
-        }
-
-        if (extraArgument != null) {
-            argumentsTranslated.add(extraArgument);
-        }
-
-        final RubyNode[] argumentsTranslatedArray = argumentsTranslated.toArray(new RubyNode[argumentsTranslated.size()]);
-
-        return new ArgumentsAndBlockTranslation(blockTranslated, argumentsTranslatedArray, isSplatted);
-    }
-
-    @Override
-    public Object visitCaseNode(org.jrubyparser.ast.CaseNode node) {
-        final SourceSection sourceSection = translate(node.getPosition());
-
-        RubyNode elseNode;
-
-        if (node.getElse() != null) {
-            elseNode = (RubyNode) node.getElse().accept(this);
-        } else {
-            elseNode = new NilNode(context, sourceSection);
-        }
-
-        /*
-         * There are two sorts of case - one compares a list of expressions against a value, the
-         * other just checks a list of expressions for truth.
-         */
-
-        if (node.getCase() != null) {
-            // Evaluate the case expression and store it in a local
-
-            final String tempName = environment.allocateLocalTemp();
-
-            final RubyNode readTemp = environment.findLocalVarNode(tempName, sourceSection);
-
-            final RubyNode assignTemp = ((ReadNode) readTemp).makeWriteNode((RubyNode) node.getCase().accept(this));
-
-            /*
-             * Build an if expression from the whens and else. Work backwards because the first if
-             * contains all the others in its else clause.
-             */
-
-            for (int n = node.getCases().size() - 1; n >= 0; n--) {
-                final org.jrubyparser.ast.WhenNode when = (org.jrubyparser.ast.WhenNode) node.getCases().get(n);
-
-                // Make a condition from the one or more expressions combined in an or expression
-
-                final List<org.jrubyparser.ast.Node> expressions;
-
-                if (when.getExpression() instanceof org.jrubyparser.ast.ListNode) {
-                    expressions = ((org.jrubyparser.ast.ListNode) when.getExpression()).childNodes();
-                } else {
-                    expressions = Arrays.asList(when.getExpression());
-                }
-
-                final List<RubyNode> comparisons = new ArrayList<>();
-
-                for (org.jrubyparser.ast.Node expressionNode : expressions) {
-                    final RubyNode rubyExpression = (RubyNode) expressionNode.accept(this);
-
-                    final CallNode comparison = new CallNode(context, sourceSection, "===", rubyExpression, null, false, new RubyNode[]{environment.findLocalVarNode(tempName, sourceSection)});
-
-                    comparisons.add(comparison);
-                }
-
-                RubyNode conditionNode = comparisons.get(comparisons.size() - 1);
-
-                // As with the if nodes, we work backwards to make it left associative
-
-                for (int i = comparisons.size() - 2; i >= 0; i--) {
-                    conditionNode = OrNodeFactory.create(context, sourceSection, comparisons.get(i), conditionNode);
-                }
-
-                // Create the if node
-
-                final BooleanCastNode conditionCastNode = BooleanCastNodeFactory.create(context, sourceSection, conditionNode);
-
-                RubyNode thenNode;
-
-                if (when.getBody() == null) {
-                    thenNode = new NilNode(context, sourceSection);
-                } else {
-                    thenNode = (RubyNode) when.getBody().accept(this);
-                }
-
-                final IfNode ifNode = new IfNode(context, sourceSection, conditionCastNode, thenNode, elseNode);
-
-                // This if becomes the else for the next if
-
-                elseNode = ifNode;
-            }
-
-            final RubyNode ifNode = elseNode;
-
-            // A top-level block assigns the temp then runs the if
-
-            return new SequenceNode(context, sourceSection, assignTemp, ifNode);
-        } else {
-            for (int n = node.getCases().size() - 1; n >= 0; n--) {
-                final org.jrubyparser.ast.WhenNode when = (org.jrubyparser.ast.WhenNode) node.getCases().get(n);
-
-                // Make a condition from the one or more expressions combined in an or expression
-
-                final List<org.jrubyparser.ast.Node> expressions;
-
-                if (when.getExpression() instanceof org.jrubyparser.ast.ListNode) {
-                    expressions = ((org.jrubyparser.ast.ListNode) when.getExpression()).childNodes();
-                } else {
-                    expressions = Arrays.asList(when.getExpression());
-                }
-
-                final List<RubyNode> tests = new ArrayList<>();
-
-                for (org.jrubyparser.ast.Node expressionNode : expressions) {
-                    final RubyNode rubyExpression = (RubyNode) expressionNode.accept(this);
-                    tests.add(rubyExpression);
-                }
-
-                RubyNode conditionNode = tests.get(tests.size() - 1);
-
-                // As with the if nodes, we work backwards to make it left associative
-
-                for (int i = tests.size() - 2; i >= 0; i--) {
-                    conditionNode = OrNodeFactory.create(context, sourceSection, tests.get(i), conditionNode);
-                }
-
-                // Create the if node
-
-                final BooleanCastNode conditionCastNode = BooleanCastNodeFactory.create(context, sourceSection, conditionNode);
-
-                final RubyNode thenNode = (RubyNode) when.getBody().accept(this);
-
-                final IfNode ifNode = new IfNode(context, sourceSection, conditionCastNode, thenNode, elseNode);
-
-                // This if becomes the else for the next if
-
-                elseNode = ifNode;
-            }
-
-            return elseNode;
-        }
-    }
-
-    @Override
-    public Object visitClassNode(org.jrubyparser.ast.ClassNode node) {
-        final SourceSection sourceSection = translate(node.getPosition());
-
-        final String name = node.getCPath().getName();
-
-        final TranslatorEnvironment newEnvironment = new TranslatorEnvironment(context, environment, environment.getParser(), environment.getParser().allocateReturnID(), true, true,
-                        new UniqueMethodIdentifier());
-        final ModuleTranslator classTranslator = new ModuleTranslator(context, this, newEnvironment, source);
-
-        final MethodDefinitionNode definitionMethod = classTranslator.compileClassNode(node.getPosition(), node.getCPath().getName(), node.getBody());
-
-        /*
-         * See my note in visitDefnNode about where the class gets defined - the same applies here.
-         */
-
-        RubyNode superClass;
-
-        if (node.getSuper() != null) {
-            superClass = (RubyNode) node.getSuper().accept(this);
-        } else {
-            superClass = new ObjectLiteralNode(context, sourceSection, context.getCoreLibrary().getObjectClass());
-        }
-
-        final DefineOrGetClassNode defineOrGetClass = new DefineOrGetClassNode(context, sourceSection, name, getModuleToDefineModulesIn(sourceSection), superClass);
-
-        return new OpenModuleNode(context, sourceSection, defineOrGetClass, definitionMethod);
-    }
-
-    protected RubyNode getModuleToDefineModulesIn(SourceSection sourceSection) {
-        return new ClassNode(context, sourceSection, new SelfNode(context, sourceSection));
-    }
-
-    @Override
-    public Object visitClassVarAsgnNode(org.jrubyparser.ast.ClassVarAsgnNode node) {
-        final SourceSection sourceSection = translate(node.getPosition());
-
-        final RubyNode receiver = new ClassNode(context, sourceSection, new SelfNode(context, sourceSection));
-
-        final RubyNode rhs = (RubyNode) node.getValue().accept(this);
-
-        return new WriteClassVariableNode(context, sourceSection, node.getName(), receiver, rhs);
-    }
-
-    @Override
-    public Object visitClassVarDeclNode(org.jrubyparser.ast.ClassVarDeclNode node) {
-        return unimplemented(node);
-    }
-
-    @Override
-    public Object visitClassVarNode(org.jrubyparser.ast.ClassVarNode node) {
-        final SourceSection sourceSection = translate(node.getPosition());
-        return new ReadClassVariableNode(context, sourceSection, node.getName(), new SelfNode(context, sourceSection));
-    }
-
-    @Override
-    public Object visitColon2Node(org.jrubyparser.ast.Colon2Node node) {
-        final RubyNode lhs = (RubyNode) node.getLeftNode().accept(this);
-
-        return new UninitializedReadConstantNode(context, translate(node.getPosition()), node.getName(), lhs);
-    }
-
-    @Override
-    public Object visitColon3Node(org.jrubyparser.ast.Colon3Node node) {
-        // Colon3 means the root namespace, as in ::Foo
-
-        final SourceSection sourceSection = translate(node.getPosition());
-
-        final ObjectLiteralNode root = new ObjectLiteralNode(context, sourceSection, context.getCoreLibrary().getMainObject());
-
-        return new UninitializedReadConstantNode(context, sourceSection, node.getName(), root);
-    }
-
-    @Override
-    public Object visitConstDeclNode(org.jrubyparser.ast.ConstDeclNode node) {
-        final SourceSection sourceSection = translate(node.getPosition());
-
-        final ClassNode classNode = new ClassNode(context, sourceSection, new SelfNode(context, sourceSection));
-
-        return new WriteConstantNode(context, sourceSection, node.getName(), classNode, (RubyNode) node.getValue().accept(this));
-    }
-
-    @Override
-    public Object visitConstNode(org.jrubyparser.ast.ConstNode node) {
-        final SourceSection sourceSection = translate(node.getPosition());
-
-        return new UninitializedReadConstantNode(context, sourceSection, node.getName(), new SelfNode(context, sourceSection));
-    }
-
-    @Override
-    public Object visitDAsgnNode(org.jrubyparser.ast.DAsgnNode node) {
-        return new org.jrubyparser.ast.LocalAsgnNode(node.getPosition(), node.getName(), node.getDepth(), node.getValue()).accept(this);
-    }
-
-    @Override
-    public Object visitDRegxNode(org.jrubyparser.ast.DRegexpNode node) {
-        SourceSection sourceSection = translate(node.getPosition());
-
-        final RubyNode stringNode = translateInterpolatedString(sourceSection, node.childNodes());
-
-        return StringToRegexpNodeFactory.create(context, sourceSection, stringNode);
-    }
-
-    @Override
-    public Object visitDStrNode(org.jrubyparser.ast.DStrNode node) {
-        return translateInterpolatedString(translate(node.getPosition()), node.childNodes());
-    }
-
-    @Override
-    public Object visitDSymbolNode(org.jrubyparser.ast.DSymbolNode node) {
-        SourceSection sourceSection = translate(node.getPosition());
-
-        final RubyNode stringNode = translateInterpolatedString(sourceSection, node.childNodes());
-
-        return StringToSymbolNodeFactory.create(context, sourceSection, stringNode);
-    }
-
-    private RubyNode translateInterpolatedString(SourceSection sourceSection, List<org.jrubyparser.ast.Node> childNodes) {
-        final List<RubyNode> children = new ArrayList<>();
-
-        for (org.jrubyparser.ast.Node child : childNodes) {
-            children.add((RubyNode) child.accept(this));
-        }
-
-        return new InterpolatedStringNode(context, sourceSection, children.toArray(new RubyNode[children.size()]));
-    }
-
-    @Override
-    public Object visitDVarNode(org.jrubyparser.ast.DVarNode node) {
-        RubyNode readNode = environment.findLocalVarNode(node.getName(), translate(node.getPosition()));
-
-        if (readNode == null) {
-            context.implementationMessage("can't find variable %s at %s, using noop", node.getName(), node.getPosition());
-            readNode = new NilNode(context, translate(node.getPosition()));
-        }
-
-        return readNode;
-    }
-
-    @Override
-    public Object visitDXStrNode(org.jrubyparser.ast.DXStrNode node) {
-        SourceSection sourceSection = translate(node.getPosition());
-
-        final RubyNode string = translateInterpolatedString(sourceSection, node.childNodes());
-
-        return new SystemNode(context, sourceSection, string);
-    }
-
-    @Override
-    public Object visitDefinedNode(org.jrubyparser.ast.DefinedNode node) {
-        final SourceSection sourceSection = translate(node.getPosition());
-
-        org.jrubyparser.ast.Node expressionNode = node.getExpression();
-
-        while (expressionNode instanceof org.jrubyparser.ast.NewlineNode) {
-            expressionNode = ((org.jrubyparser.ast.NewlineNode) expressionNode).getNextNode();
-        }
-
-        final String name = nodeDefinedNames.get(expressionNode.getClass());
-
-        if (name != null) {
-            final StringLiteralNode literal = new StringLiteralNode(context, sourceSection, name);
-            return literal;
-        }
-
-        return new DefinedNode(context, sourceSection, (RubyNode) node.getExpression().accept(this));
-    }
-
-    @Override
-    public Object visitDefnNode(org.jrubyparser.ast.DefnNode node) {
-        final SourceSection sourceSection = translate(node.getPosition());
-        final ClassNode classNode = new ClassNode(context, sourceSection, new SelfNode(context, sourceSection));
-        return translateMethodDefinition(sourceSection, classNode, node.getName(), node.getArgs(), node.getBody());
-    }
-
-    @Override
-    public Object visitDefsNode(org.jrubyparser.ast.DefsNode node) {
-        final SourceSection sourceSection = translate(node.getPosition());
-
-        final RubyNode objectNode = (RubyNode) node.getReceiver().accept(this);
-
-        final SingletonClassNode singletonClassNode = new SingletonClassNode(context, sourceSection, objectNode);
-
-        return translateMethodDefinition(sourceSection, singletonClassNode, node.getName(), node.getArgs(), node.getBody());
-    }
-
-    private RubyNode translateMethodDefinition(SourceSection sourceSection, RubyNode classNode, String methodName, org.jrubyparser.ast.ArgsNode argsNode, org.jrubyparser.ast.Node bodyNode) {
-        final TranslatorEnvironment newEnvironment = new TranslatorEnvironment(context, environment, environment.getParser(), environment.getParser().allocateReturnID(), true, true,
-                        new UniqueMethodIdentifier());
-
-        // ownScopeForAssignments is the same for the defined method as the current one.
-
-        final MethodTranslator methodCompiler = new MethodTranslator(context, this, newEnvironment, false, source);
-
-        final MethodDefinitionNode functionExprNode = methodCompiler.compileFunctionNode(sourceSection, methodName, argsNode, bodyNode);
-
-        /*
-         * In the top-level, methods are defined in the class of the main object. This is
-         * counter-intuitive - I would have expected them to be defined in the singleton class.
-         * Apparently this is a design decision to make top-level methods sort of global.
-         * 
-         * http://stackoverflow.com/questions/1761148/where-are-methods-defined-at-the-ruby-top-level
-         */
-
-        return new AddMethodNode(context, sourceSection, classNode, functionExprNode);
-    }
-
-    @Override
-    public Object visitDotNode(org.jrubyparser.ast.DotNode node) {
-        final RubyNode begin = (RubyNode) node.getBegin().accept(this);
-        final RubyNode end = (RubyNode) node.getEnd().accept(this);
-        SourceSection sourceSection = translate(node.getPosition());
-
-        if (begin instanceof FixnumLiteralNode && end instanceof FixnumLiteralNode) {
-            final int beginValue = ((FixnumLiteralNode) begin).getValue();
-            final int endValue = ((FixnumLiteralNode) end).getValue();
-
-            return new ObjectLiteralNode(context, sourceSection, new FixnumRange(context.getCoreLibrary().getRangeClass(), beginValue, endValue, node.isExclusive()));
-        }
-        // See RangeNode for why there is a node specifically for creating this one type
-        return RangeLiteralNodeFactory.create(context, sourceSection, node.isExclusive(), begin, end);
-    }
-
-    @Override
-    public Object visitEncodingNode(org.jrubyparser.ast.EncodingNode node) {
-        return unimplemented(node);
-    }
-
-    @Override
-    public Object visitEnsureNode(org.jrubyparser.ast.EnsureNode node) {
-        final RubyNode tryPart = (RubyNode) node.getBody().accept(this);
-        final RubyNode ensurePart = (RubyNode) node.getEnsure().accept(this);
-        return new EnsureNode(context, translate(node.getPosition()), tryPart, ensurePart);
-    }
-
-    @Override
-    public Object visitEvStrNode(org.jrubyparser.ast.EvStrNode node) {
-        return node.getBody().accept(this);
-    }
-
-    @Override
-    public Object visitFCallNode(org.jrubyparser.ast.FCallNode node) {
-        final org.jrubyparser.ast.Node receiver = new org.jrubyparser.ast.SelfNode(node.getPosition());
-        final org.jrubyparser.ast.Node callNode = new org.jrubyparser.ast.CallNode(node.getPosition(), receiver, node.getName(), node.getArgs(), node.getIter());
-
-        return callNode.accept(this);
-    }
-
-    @Override
-    public Object visitFalseNode(org.jrubyparser.ast.FalseNode node) {
-        return new BooleanLiteralNode(context, translate(node.getPosition()), false);
-    }
-
-    @Override
-    public Object visitFixnumNode(org.jrubyparser.ast.FixnumNode node) {
-        final long value = node.getValue();
-
-        if (value >= RubyFixnum.MIN_VALUE && value <= RubyFixnum.MAX_VALUE) {
-            return new FixnumLiteralNode(context, translate(node.getPosition()), (int) value);
-        }
-        return new BignumLiteralNode(context, translate(node.getPosition()), BigInteger.valueOf(value));
-    }
-
-    @Override
-    public Object visitFlipNode(org.jrubyparser.ast.FlipNode node) {
-        final SourceSection sourceSection = translate(node.getPosition());
-
-        final RubyNode begin = (RubyNode) node.getBegin().accept(this);
-        final RubyNode end = (RubyNode) node.getEnd().accept(this);
-
-        final BooleanCastNode beginCast = BooleanCastNodeFactory.create(context, sourceSection, begin);
-        final BooleanCastNode endCast = BooleanCastNodeFactory.create(context, sourceSection, end);
-        final FlipFlopStateNode stateNode = createFlipFlopState(sourceSection, 0);
-
-        return new FlipFlopNode(context, sourceSection, beginCast, endCast, stateNode, node.isExclusive());
-    }
-
-    protected FlipFlopStateNode createFlipFlopState(SourceSection sourceSection, int depth) {
-        final FrameSlot frameSlot = environment.declareVar(environment.allocateLocalTemp());
-        environment.getFlipFlopStates().add(frameSlot);
-
-        if (depth == 0) {
-            return new LocalFlipFlopStateNode(sourceSection, frameSlot);
-        } else {
-            return new LevelFlipFlopStateNode(sourceSection, depth, frameSlot);
-        }
-    }
-
-    @Override
-    public Object visitFloatNode(org.jrubyparser.ast.FloatNode node) {
-        return new FloatLiteralNode(context, translate(node.getPosition()), node.getValue());
-    }
-
-    @Override
-    public Object visitForNode(org.jrubyparser.ast.ForNode node) {
-        /**
-         * A Ruby for-loop, such as:
-         * 
-         * <pre>
-         * for x in y
-         *     z = x
-         *     puts z
-         * end
-         * </pre>
-         * 
-         * naively desugars to:
-         * 
-         * <pre>
-         * y.each do |x|
-         *     z = x
-         *     puts z
-         * end
-         * </pre>
-         * 
-         * The main difference is that z is always going to be local to the scope outside the block,
-         * so it's a bit more like:
-         * 
-         * <pre>
-         * z = nil unless z is already defined
-         * y.each do |x|
-         *    z = x
-         *    puts x
-         * end
-         * </pre>
-         * 
-         * Which forces z to be defined in the correct scope. The parser already correctly calls z a
-         * local, but then that causes us a problem as if we're going to translate to a block we
-         * need a formal parameter - not a local variable. My solution to this is to add a
-         * temporary:
-         * 
-         * <pre>
-         * z = nil unless z is already defined
-         * y.each do |temp|
-         *    x = temp
-         *    z = x
-         *    puts x
-         * end
-         * </pre>
-         * 
-         * We also need that temp because the expression assigned in the for could be index
-         * assignment, multiple assignment, or whatever:
-         * 
-         * <pre>
-         * for x[0] in y
-         *     z = x[0]
-         *     puts z
-         * end
-         * </pre>
-         * 
-         * http://blog.grayproductions.net/articles/the_evils_of_the_for_loop
-         * http://stackoverflow.com/questions/3294509/for-vs-each-in-ruby
-         * 
-         * The other complication is that normal locals should be defined in the enclosing scope,
-         * unlike a normal block. We do that by setting a flag on this translator object when we
-         * visit the new iter, translatingForStatement, which we recognise when visiting an iter
-         * node.
-         * 
-         * Finally, note that JRuby's terminology is strange here. Normally 'iter' is a different
-         * term for a block. Here, JRuby calls the object being iterated over the 'iter'.
-         */
-
-        final String temp = environment.allocateLocalTemp();
-
-        final org.jrubyparser.ast.Node receiver = node.getIter();
-
-        /*
-         * The x in for x in ... is like the nodes in multiple assignment - it has a dummy RHS which
-         * we need to replace with our temp. Just like in multiple assignment this is really awkward
-         * with the JRuby AST.
-         */
-
-        final org.jrubyparser.ast.LocalVarNode readTemp = new org.jrubyparser.ast.LocalVarNode(node.getPosition(), 0, temp);
-        final org.jrubyparser.ast.Node forVar = node.getVar();
-        final org.jrubyparser.ast.Node assignTemp = setRHS(forVar, readTemp);
-
-        final org.jrubyparser.ast.BlockNode bodyWithTempAssign = new org.jrubyparser.ast.BlockNode(node.getPosition());
-        bodyWithTempAssign.add(assignTemp);
-        bodyWithTempAssign.add(node.getBody());
-
-        final org.jrubyparser.ast.ArgumentNode blockVar = new org.jrubyparser.ast.ArgumentNode(node.getPosition(), temp);
-        final org.jrubyparser.ast.ListNode blockArgsPre = new org.jrubyparser.ast.ListNode(node.getPosition(), blockVar);
-        final org.jrubyparser.ast.ArgsNode blockArgs = new org.jrubyparser.ast.ArgsNode(node.getPosition(), blockArgsPre, null, null, null, null, null, null);
-        final org.jrubyparser.ast.IterNode block = new org.jrubyparser.ast.IterNode(node.getPosition(), blockArgs, node.getScope(), bodyWithTempAssign);
-
-        final org.jrubyparser.ast.CallNode callNode = new org.jrubyparser.ast.CallNode(node.getPosition(), receiver, "each", null, block);
-
-        translatingForStatement = true;
-        final RubyNode translated = (RubyNode) callNode.accept(this);
-        translatingForStatement = false;
-
-        return translated;
-    }
-
-    private static org.jrubyparser.ast.Node setRHS(org.jrubyparser.ast.Node node, org.jrubyparser.ast.Node rhs) {
-        if (node instanceof org.jrubyparser.ast.LocalAsgnNode) {
-            final org.jrubyparser.ast.LocalAsgnNode localAsgnNode = (org.jrubyparser.ast.LocalAsgnNode) node;
-            return new org.jrubyparser.ast.LocalAsgnNode(node.getPosition(), localAsgnNode.getName(), 0, rhs);
-        } else if (node instanceof org.jrubyparser.ast.DAsgnNode) {
-            final org.jrubyparser.ast.DAsgnNode dAsgnNode = (org.jrubyparser.ast.DAsgnNode) node;
-            return new org.jrubyparser.ast.DAsgnNode(node.getPosition(), dAsgnNode.getName(), 0, rhs);
-        } else if (node instanceof org.jrubyparser.ast.MultipleAsgnNode) {
-            final org.jrubyparser.ast.MultipleAsgnNode multAsgnNode = (org.jrubyparser.ast.MultipleAsgnNode) node;
-            return new org.jrubyparser.ast.MultipleAsgnNode(node.getPosition(), multAsgnNode.getPre(), multAsgnNode.getRest(), multAsgnNode.getPost());
-        } else if (node instanceof org.jrubyparser.ast.InstAsgnNode) {
-            final org.jrubyparser.ast.InstAsgnNode instAsgnNode = (org.jrubyparser.ast.InstAsgnNode) node;
-            return new org.jrubyparser.ast.InstAsgnNode(node.getPosition(), instAsgnNode.getName(), rhs);
-        } else if (node instanceof org.jrubyparser.ast.ClassVarAsgnNode) {
-            final org.jrubyparser.ast.ClassVarAsgnNode instAsgnNode = (org.jrubyparser.ast.ClassVarAsgnNode) node;
-            return new org.jrubyparser.ast.ClassVarAsgnNode(node.getPosition(), instAsgnNode.getName(), rhs);
-        } else if (node instanceof org.jrubyparser.ast.ConstDeclNode) {
-            final org.jrubyparser.ast.ConstDeclNode constDeclNode = (org.jrubyparser.ast.ConstDeclNode) node;
-            return new org.jrubyparser.ast.ConstDeclNode(node.getPosition(), constDeclNode.getName(), (org.jrubyparser.ast.INameNode) constDeclNode.getConstNode(), rhs);
-        } else {
-            throw new UnsupportedOperationException("Don't know how to set the RHS of a " + node.getClass().getName());
-        }
-    }
-
-    @Override
-    public Object visitGlobalAsgnNode(org.jrubyparser.ast.GlobalAsgnNode node) {
-        final SourceSection sourceSection = translate(node.getPosition());
-
-        final String name = "$" + node.getName();
-        final RubyNode rhs = (RubyNode) node.getValue().accept(this);
-
-        if (FRAME_LOCAL_GLOBAL_VARIABLES.contains(name)) {
-            context.implementationMessage("Assigning to frame local global variables not implemented at %s", node.getPosition());
-
-            return rhs;
-        } else {
-            final ObjectLiteralNode globalVariablesObjectNode = new ObjectLiteralNode(context, sourceSection, context.getCoreLibrary().getGlobalVariablesObject());
-
-            return new UninitializedWriteInstanceVariableNode(context, sourceSection, name, globalVariablesObjectNode, rhs);
-        }
-    }
-
-    @Override
-    public Object visitGlobalVarNode(org.jrubyparser.ast.GlobalVarNode node) {
-        final String name = "$" + node.getName();
-        final SourceSection sourceSection = translate(node.getPosition());
-
-        if (FRAME_LOCAL_GLOBAL_VARIABLES.contains(name)) {
-            // Assignment is implicit for many of these, so we need to declare when we use
-
-            environment.declareVar(name);
-
-            final RubyNode readNode = environment.findLocalVarNode(name, sourceSection);
-
-            return readNode;
-        } else {
-            final ObjectLiteralNode globalVariablesObjectNode = new ObjectLiteralNode(context, sourceSection, context.getCoreLibrary().getGlobalVariablesObject());
-
-            return new UninitializedReadInstanceVariableNode(context, sourceSection, name, globalVariablesObjectNode);
-        }
-    }
-
-    @Override
-    public Object visitHashNode(org.jrubyparser.ast.HashNode node) {
-        final SourceSection sourceSection = translate(node.getPosition());
-
-        final List<RubyNode> keys = new ArrayList<>();
-        final List<RubyNode> values = new ArrayList<>();
-
-        final org.jrubyparser.ast.ListNode entries = node.getListNode();
-
-        assert entries.size() % 2 == 0;
-
-        for (int n = 0; n < entries.size(); n += 2) {
-            if (entries.get(n) == null) {
-                final NilNode nilNode = new NilNode(context, sourceSection);
-                keys.add(nilNode);
-            } else {
-                keys.add((RubyNode) entries.get(n).accept(this));
-            }
-
-            if (entries.get(n + 1) == null) {
-                final NilNode nilNode = new NilNode(context, sourceSection);
-                values.add(nilNode);
-            } else {
-                values.add((RubyNode) entries.get(n + 1).accept(this));
-            }
-        }
-
-        return new HashLiteralNode(translate(node.getPosition()), keys.toArray(new RubyNode[keys.size()]), values.toArray(new RubyNode[values.size()]), context);
-    }
-
-    @Override
-    public Object visitIfNode(org.jrubyparser.ast.IfNode node) {
-        final SourceSection sourceSection = translate(node.getPosition());
-
-        org.jrubyparser.ast.Node thenBody = node.getThenBody();
-
-        if (thenBody == null) {
-            thenBody = new org.jrubyparser.ast.NilNode(node.getPosition());
-        }
-
-        org.jrubyparser.ast.Node elseBody = node.getElseBody();
-
-        if (elseBody == null) {
-            elseBody = new org.jrubyparser.ast.NilNode(node.getPosition());
-        }
-
-        RubyNode condition;
-
-        if (node.getCondition() == null) {
-            condition = new NilNode(context, sourceSection);
-        } else {
-            condition = (RubyNode) node.getCondition().accept(this);
-        }
-
-        final BooleanCastNode conditionCast = BooleanCastNodeFactory.create(context, sourceSection, condition);
-
-        final RubyNode thenBodyTranslated = (RubyNode) thenBody.accept(this);
-        final RubyNode elseBodyTranslated = (RubyNode) elseBody.accept(this);
-
-        return new IfNode(context, sourceSection, conditionCast, thenBodyTranslated, elseBodyTranslated);
-    }
-
-    @Override
-    public Object visitInstAsgnNode(org.jrubyparser.ast.InstAsgnNode node) {
-        final SourceSection sourceSection = translate(node.getPosition());
-        final String nameWithoutSigil = node.getName();
-
-        final RubyNode receiver = new SelfNode(context, sourceSection);
-
-        RubyNode rhs;
-
-        if (node.getValue() == null) {
-            rhs = new DeadNode(context, sourceSection);
-        } else {
-            rhs = (RubyNode) node.getValue().accept(this);
-        }
-
-        return new UninitializedWriteInstanceVariableNode(context, sourceSection, nameWithoutSigil, receiver, rhs);
-    }
-
-    @Override
-    public Object visitInstVarNode(org.jrubyparser.ast.InstVarNode node) {
-        final SourceSection sourceSection = translate(node.getPosition());
-        final String nameWithoutSigil = node.getName();
-
-        final RubyNode receiver = new SelfNode(context, sourceSection);
-
-        return new UninitializedReadInstanceVariableNode(context, sourceSection, nameWithoutSigil, receiver);
-    }
-
-    @Override
-    public Object visitIterNode(org.jrubyparser.ast.IterNode node) {
-        /*
-         * In a block we do NOT allocate a new return ID - returns will return from the method, not
-         * the block (in the general case, see Proc and the difference between Proc and Lambda for
-         * specifics).
-         */
-
-        final boolean hasOwnScope = !translatingForStatement;
-
-        // Unset this flag for any for any blocks within the for statement's body
-
-        translatingForStatement = false;
-
-        final TranslatorEnvironment newEnvironment = new TranslatorEnvironment(context, environment, environment.getParser(), environment.getReturnID(), hasOwnScope, false,
-                        new UniqueMethodIdentifier());
-        final MethodTranslator methodCompiler = new MethodTranslator(context, this, newEnvironment, true, source);
-
-        org.jrubyparser.ast.ArgsNode argsNode;
-
-        if (node.getVar() instanceof org.jrubyparser.ast.ArgsNode) {
-            argsNode = (org.jrubyparser.ast.ArgsNode) node.getVar();
-        } else if (node.getVar() instanceof org.jrubyparser.ast.DAsgnNode) {
-            final org.jrubyparser.ast.ArgumentNode arg = new org.jrubyparser.ast.ArgumentNode(node.getPosition(), ((org.jrubyparser.ast.DAsgnNode) node.getVar()).getName());
-            final org.jrubyparser.ast.ListNode preArgs = new org.jrubyparser.ast.ArrayNode(node.getPosition(), arg);
-            argsNode = new org.jrubyparser.ast.ArgsNode(node.getPosition(), preArgs, null, null, null, null, null, null);
-        } else if (node.getVar() == null) {
-            argsNode = null;
-        } else {
-            throw new UnsupportedOperationException();
-        }
-
-        return methodCompiler.compileFunctionNode(translate(node.getPosition()), "(block)", argsNode, node.getBody());
-    }
-
-    @Override
-    public Object visitLiteralNode(org.jrubyparser.ast.LiteralNode node) {
-        return unimplemented(node);
-    }
-
-    @Override
-    public Object visitLocalAsgnNode(org.jrubyparser.ast.LocalAsgnNode node) {
-
-        final SourceSection sourceSection = translate(node.getPosition());
-
-        if (environment.getNeverAssignInParentScope()) {
-            environment.declareVar(node.getName());
-        }
-
-        RubyNode lhs = environment.findLocalVarNode(node.getName(), sourceSection);
-
-        if (lhs == null) {
-            if (environment.hasOwnScopeForAssignments()) {
-                environment.declareVar(node.getName());
-            }
-
-            TranslatorEnvironment environmentToDeclareIn = environment;
-
-            while (!environmentToDeclareIn.hasOwnScopeForAssignments()) {
-                environmentToDeclareIn = environmentToDeclareIn.getParent();
-            }
-
-            environmentToDeclareIn.declareVar(node.getName());
-            lhs = environment.findLocalVarNode(node.getName(), sourceSection);
-
-            if (lhs == null) {
-                throw new RuntimeException("shoudln't be here");
-            }
-        }
-
-        RubyNode rhs;
-
-        if (node.getValue() == null) {
-            rhs = new DeadNode(context, sourceSection);
-        } else {
-            rhs = (RubyNode) node.getValue().accept(this);
-        }
-
-        RubyNode translated = ((ReadNode) lhs).makeWriteNode(rhs);
-
-        final UniqueMethodIdentifier methodIdentifier = environment.findMethodForLocalVar(node.getName());
-
-        return instrumenter.instrumentAsLocalAssignment(translated, methodIdentifier, node.getName());
-    }
-
-    @Override
-    public Object visitLocalVarNode(org.jrubyparser.ast.LocalVarNode node) {
-        final SourceSection sourceSection = translate(node.getPosition());
-
-        final String name = node.getName();
-
-        RubyNode readNode = environment.findLocalVarNode(name, sourceSection);
-
-        if (readNode == null) {
-            context.implementationMessage("Local variable found by parser but not by translator - " + name + " at " + node.getPosition());
-            readNode = environment.findLocalVarNode(environment.allocateLocalTemp(), sourceSection);
-        }
-
-        return readNode;
-    }
-
-    @Override
-    public Object visitMatch2Node(org.jrubyparser.ast.Match2Node node) {
-        final org.jrubyparser.ast.Node argsNode = buildArrayNode(node.getPosition(), node.getValue());
-        final org.jrubyparser.ast.Node callNode = new org.jrubyparser.ast.CallNode(node.getPosition(), node.getReceiver(), "=~", argsNode, null);
-        return callNode.accept(this);
-    }
-
-    @Override
-    public Object visitMatch3Node(org.jrubyparser.ast.Match3Node node) {
-        final org.jrubyparser.ast.Node argsNode = buildArrayNode(node.getPosition(), node.getValue());
-        final org.jrubyparser.ast.Node callNode = new org.jrubyparser.ast.CallNode(node.getPosition(), node.getReceiver(), "=~", argsNode, null);
-        return callNode.accept(this);
-    }
-
-    @Override
-    public Object visitMatchNode(org.jrubyparser.ast.MatchNode node) {
-        return unimplemented(node);
-    }
-
-    @Override
-    public Object visitModuleNode(org.jrubyparser.ast.ModuleNode node) {
-        // See visitClassNode
-
-        final SourceSection sourceSection = translate(node.getPosition());
-
-        final String name = node.getCPath().getName();
-
-        final TranslatorEnvironment newEnvironment = new TranslatorEnvironment(context, environment, environment.getParser(), environment.getParser().allocateReturnID(), true, true,
-                        new UniqueMethodIdentifier());
-        final ModuleTranslator classTranslator = new ModuleTranslator(context, this, newEnvironment, source);
-
-        final MethodDefinitionNode definitionMethod = classTranslator.compileClassNode(node.getPosition(), node.getCPath().getName(), node.getBody());
-
-        final DefineOrGetModuleNode defineModuleNode = new DefineOrGetModuleNode(context, sourceSection, name, getModuleToDefineModulesIn(sourceSection));
-
-        return new OpenModuleNode(context, sourceSection, defineModuleNode, definitionMethod);
-    }
-
-    @Override
-    public Object visitMultipleAsgnNode(org.jrubyparser.ast.MultipleAsgnNode node) {
-        final SourceSection sourceSection = translate(node.getPosition());
-
-        final org.jrubyparser.ast.ArrayNode preArray = (org.jrubyparser.ast.ArrayNode) node.getPre();
-        final org.jrubyparser.ast.Node rhs = node.getValue();
-
-        RubyNode rhsTranslated;
-
-        if (rhs == null) {
-            context.implementationMessage("warning: no RHS for multiple assignment - using noop");
-            rhsTranslated = new NilNode(context, sourceSection);
-        } else {
-            rhsTranslated = (RubyNode) rhs.accept(this);
-        }
-
-        /*
-         * One very common case is to do
-         * 
-         * a, b = c, d
-         */
-
-        if (preArray != null && node.getPost() == null && node.getRest() == null && rhsTranslated instanceof UninitialisedArrayLiteralNode &&
-                        ((UninitialisedArrayLiteralNode) rhsTranslated).getValues().length == preArray.size()) {
-            /*
-             * We can deal with this common case be rewriting as
-             * 
-             * temp1 = c; temp2 = d; a = temp1; b = temp2
-             * 
-             * We can't just do
-             * 
-             * a = c; b = d
-             * 
-             * As we don't know if d depends on the original value of a.
-             * 
-             * We also need to return an array [c, d], but we make that result elidable so it isn't
-             * executed if it isn't actually demanded.
-             */
-
-            final RubyNode[] rhsValues = ((UninitialisedArrayLiteralNode) rhsTranslated).getValues();
-            final int assignedValuesCount = preArray.size();
-
-            final RubyNode[] sequence = new RubyNode[assignedValuesCount * 2];
-
-            final RubyNode[] tempValues = new RubyNode[assignedValuesCount];
-
-            for (int n = 0; n < assignedValuesCount; n++) {
-                final String tempName = environment.allocateLocalTemp();
-                final RubyNode readTemp = environment.findLocalVarNode(tempName, sourceSection);
-                final RubyNode assignTemp = ((ReadNode) readTemp).makeWriteNode(rhsValues[n]);
-                final RubyNode assignFinalValue = translateDummyAssignment(preArray.get(n), readTemp);
-
-                sequence[n] = assignTemp;
-                sequence[assignedValuesCount + n] = assignFinalValue;
-
-                tempValues[n] = readTemp;
-            }
-
-            final RubyNode blockNode = new SequenceNode(context, sourceSection, sequence);
-
-            final UninitialisedArrayLiteralNode arrayNode = new UninitialisedArrayLiteralNode(context, sourceSection, tempValues);
-
-            final ElidableResultNode elidableResult = new ElidableResultNode(context, sourceSection, blockNode, arrayNode);
-
-            return elidableResult;
-        } else if (preArray != null) {
-            /*
-             * The other simple case is
-             * 
-             * a, b, c = x
-             * 
-             * If x is an array, then it's
-             * 
-             * a[0] = x[0] etc
-             * 
-             * If x isn't an array then it's
-             * 
-             * a, b, c = [x, nil, nil]
-             * 
-             * Which I believe is the same effect as
-             * 
-             * a, b, c, = *x
-             * 
-             * So we insert the splat cast node, even though it isn't there.
-             */
-
-            /*
-             * Create a temp for the array.
-             */
-
-            final String tempName = environment.allocateLocalTemp();
-
-            /*
-             * Create a sequence of instructions, with the first being the literal array assigned to
-             * the temp.
-             */
-
-            final List<RubyNode> sequence = new ArrayList<>();
-
-            final RubyNode splatCastNode = SplatCastNodeFactory.create(context, sourceSection, rhsTranslated);
-
-            final RubyNode writeTemp = ((ReadNode) environment.findLocalVarNode(tempName, sourceSection)).makeWriteNode(splatCastNode);
-
-            sequence.add(writeTemp);
-
-            /*
-             * Then index the temp array for each assignment on the LHS.
-             */
-
-            for (int n = 0; n < preArray.size(); n++) {
-                final ArrayIndexNode assignedValue = ArrayIndexNodeFactory.create(context, sourceSection, n, environment.findLocalVarNode(tempName, sourceSection));
-
-                sequence.add(translateDummyAssignment(preArray.get(n), assignedValue));
-            }
-
-            if (node.getRest() != null) {
-                final ArrayRestNode assignedValue = new ArrayRestNode(context, sourceSection, preArray.size(), environment.findLocalVarNode(tempName, sourceSection));
-
-                sequence.add(translateDummyAssignment(node.getRest(), assignedValue));
-            }
-
-            return new SequenceNode(context, sourceSection, sequence.toArray(new RubyNode[sequence.size()]));
-        } else if (node.getPre() == null && node.getPost() == null && node.getRest() instanceof org.jrubyparser.ast.StarNode) {
-            return rhsTranslated;
-        } else if (node.getPre() == null && node.getPost() == null && node.getRest() != null && rhs != null && !(rhs instanceof org.jrubyparser.ast.ArrayNode)) {
-            /*
-             * *a = b
-             * 
-             * >= 1.8, this seems to be the same as:
-             * 
-             * a = *b
-             */
-
-            final RubyNode restTranslated = ((RubyNode) node.getRest().accept(this)).getNonProxyNode();
-
-            /*
-             * Sometimes rest is a corrupt write with no RHS, like in other multiple assignments,
-             * and sometimes it is already a read.
-             */
-
-            ReadNode restRead;
-
-            if (restTranslated instanceof ReadNode) {
-                restRead = (ReadNode) restTranslated;
-            } else if (restTranslated instanceof WriteNode) {
-                restRead = (ReadNode) ((WriteNode) restTranslated).makeReadNode();
-            } else {
-                throw new RuntimeException("Unknown form of multiple assignment " + node + " at " + node.getPosition());
-            }
-
-            final SplatCastNode rhsSplatCast = SplatCastNodeFactory.create(context, sourceSection, rhsTranslated);
-
-            return restRead.makeWriteNode(rhsSplatCast);
-        } else if (node.getPre() == null && node.getPost() == null && node.getRest() != null && rhs != null && rhs instanceof org.jrubyparser.ast.ArrayNode) {
-            /*
-             * *a = [b, c]
-             * 
-             * This seems to be the same as:
-             * 
-             * a = [b, c]
-             */
-
-            final RubyNode restTranslated = ((RubyNode) node.getRest().accept(this)).getNonProxyNode();
-
-            /*
-             * Sometimes rest is a corrupt write with no RHS, like in other multiple assignments,
-             * and sometimes it is already a read.
-             */
-
-            ReadNode restRead;
-
-            if (restTranslated instanceof ReadNode) {
-                restRead = (ReadNode) restTranslated;
-            } else if (restTranslated instanceof WriteNode) {
-                restRead = (ReadNode) ((WriteNode) restTranslated).makeReadNode();
-            } else {
-                throw new RuntimeException("Unknown form of multiple assignment " + node + " at " + node.getPosition());
-            }
-
-            return restRead.makeWriteNode(rhsTranslated);
-        } else {
-            throw new RuntimeException("Unknown form of multiple assignment " + node + " at " + node.getPosition());
-        }
-    }
-
-    private RubyNode translateDummyAssignment(org.jrubyparser.ast.Node dummyAssignment, RubyNode rhs) {
-        final SourceSection sourceSection = translate(dummyAssignment.getPosition());
-
-        /*
-         * This is tricky. To represent the RHS of a multiple assignment they use corrupt assignment
-         * values, in some cases with no value to be assigned, and in other cases with a dummy
-         * value. We can't visit them normally, as they're corrupt. We can't just modify them to
-         * have our RHS, as that's a node in our AST, not theirs. We can't use a dummy value in
-         * their AST because I can't add new visitors to this interface.
-         */
-
-        RubyNode translated;
-
-        if (dummyAssignment instanceof org.jrubyparser.ast.LocalAsgnNode) {
-            /*
-             * They have a dummy NilImplicitNode as the RHS. Translate, convert to read, convert to
-             * write which allows us to set the RHS.
-             */
-
-            final WriteNode dummyTranslated = (WriteNode) ((RubyNode) dummyAssignment.accept(this)).getNonProxyNode();
-            translated = ((ReadNode) dummyTranslated.makeReadNode()).makeWriteNode(rhs);
-        } else if (dummyAssignment instanceof org.jrubyparser.ast.InstAsgnNode) {
-            /*
-             * Same as before, just a different type of assignment.
-             */
-
-            final WriteInstanceVariableNode dummyTranslated = (WriteInstanceVariableNode) dummyAssignment.accept(this);
-            translated = dummyTranslated.makeReadNode().makeWriteNode(rhs);
-        } else if (dummyAssignment instanceof org.jrubyparser.ast.AttrAssignNode) {
-            /*
-             * They've given us an AttrAssignNode with the final argument, the assigned value,
-             * missing. If we translate that we'll get foo.[]=(index), so missing the value. To
-             * solve we have a special version of the visitCallNode that allows us to pass another
-             * already translated argument, visitCallNodeExtraArgument. However, we initially have
-             * an AttrAssignNode, so we also need a special version of that.
-             */
-
-            final org.jrubyparser.ast.AttrAssignNode dummyAttrAssignment = (org.jrubyparser.ast.AttrAssignNode) dummyAssignment;
-            translated = visitAttrAssignNodeExtraArgument(dummyAttrAssignment, rhs);
-        } else if (dummyAssignment instanceof org.jrubyparser.ast.DAsgnNode) {
-            final RubyNode dummyTranslated = (RubyNode) dummyAssignment.accept(this);
-
-            if (dummyTranslated.getNonProxyNode() instanceof WriteLevelVariableNode) {
-                translated = ((ReadNode) ((WriteLevelVariableNode) dummyTranslated.getNonProxyNode()).makeReadNode()).makeWriteNode(rhs);
-            } else {
-                translated = ((ReadNode) ((WriteLocalVariableNode) dummyTranslated.getNonProxyNode()).makeReadNode()).makeWriteNode(rhs);
-            }
-        } else {
-            translated = ((ReadNode) environment.findLocalVarNode(environment.allocateLocalTemp(), sourceSection)).makeWriteNode(rhs);
-        }
-
-        return translated;
-    }
-
-    @Override
-    public Object visitNewlineNode(org.jrubyparser.ast.NewlineNode node) {
-        RubyNode translated = (RubyNode) node.getNextNode().accept(this);
-        return instrumenter.instrumentAsStatement(translated);
-    }
-
-    @Override
-    public Object visitNextNode(org.jrubyparser.ast.NextNode node) {
-        final SourceSection sourceSection = translate(node.getPosition());
-
-        RubyNode resultNode;
-
-        if (node.getValueNode() == null) {
-            resultNode = new NilNode(context, sourceSection);
-        } else {
-            resultNode = (RubyNode) node.getValueNode().accept(this);
-        }
-
-        return new NextNode(context, sourceSection, resultNode);
-    }
-
-    @Override
-    public Object visitNilNode(org.jrubyparser.ast.NilNode node) {
-        return new NilNode(context, translate(node.getPosition()));
-    }
-
-    @Override
-    public Object visitNotNode(org.jrubyparser.ast.NotNode node) {
-        final SourceSection sourceSection = translate(node.getPosition());
-
-        final BooleanCastNode booleanCastNode = BooleanCastNodeFactory.create(context, sourceSection, (RubyNode) node.getCondition().accept(this));
-
-        return new NotNode(context, sourceSection, booleanCastNode);
-    }
-
-    @Override
-    public Object visitNthRefNode(org.jrubyparser.ast.NthRefNode node) {
-        final SourceSection sourceSection = translate(node.getPosition());
-
-        final String name = "$" + node.getMatchNumber();
-
-        RubyNode readLocal = environment.findLocalVarNode(name, sourceSection);
-
-        if (readLocal == null) {
-            environment.declareVar(name);
-            readLocal = environment.findLocalVarNode(name, sourceSection);
-        }
-
-        return readLocal;
-    }
-
-    @Override
-    public Object visitOpAsgnAndNode(org.jrubyparser.ast.OpAsgnAndNode node) {
-        final org.jrubyparser.ast.Node lhs = node.getFirst();
-        final org.jrubyparser.ast.Node rhs = node.getSecond();
-
-        return AndNodeFactory.create(context, translate(node.getPosition()), (RubyNode) lhs.accept(this), (RubyNode) rhs.accept(this));
-    }
-
-    @Override
-    public Object visitOpAsgnNode(org.jrubyparser.ast.OpAsgnNode node) {
-        /*
-         * We're going to de-sugar a.foo += c into a.foo = a.foo + c. Note that we can't evaluate a
-         * more than once, so we put it into a temporary, and we're doing something more like:
-         * 
-         * temp = a; temp.foo = temp.foo + c
-         */
-
-        final String temp = environment.allocateLocalTemp();
-        final org.jrubyparser.ast.Node writeReceiverToTemp = new org.jrubyparser.ast.LocalAsgnNode(node.getPosition(), temp, 0, node.getReceiver());
-        final org.jrubyparser.ast.Node readReceiverFromTemp = new org.jrubyparser.ast.LocalVarNode(node.getPosition(), 0, temp);
-
-        final org.jrubyparser.ast.Node readMethod = new org.jrubyparser.ast.CallNode(node.getPosition(), readReceiverFromTemp, node.getVariableName(), null);
-        final org.jrubyparser.ast.Node operation = new org.jrubyparser.ast.CallNode(node.getPosition(), readMethod, node.getOperatorName(), buildArrayNode(node.getPosition(), node.getValue()));
-        final org.jrubyparser.ast.Node writeMethod = new org.jrubyparser.ast.CallNode(node.getPosition(), readReceiverFromTemp, node.getVariableName() + "=", buildArrayNode(node.getPosition(),
-                        operation));
-
-        final org.jrubyparser.ast.BlockNode block = new org.jrubyparser.ast.BlockNode(node.getPosition());
-        block.add(writeReceiverToTemp);
-        block.add(writeMethod);
-
-        return block.accept(this);
-    }
-
-    @Override
-    public Object visitOpAsgnOrNode(org.jrubyparser.ast.OpAsgnOrNode node) {
-        /*
-         * De-sugar x ||= y into x || x = y. No repeated evaluations there so it's easy. It's also
-         * basically how jruby-parser represents it already. We'll do it directly, rather than via
-         * another JRuby AST node.
-         */
-
-        final org.jrubyparser.ast.Node lhs = node.getFirst();
-        final org.jrubyparser.ast.Node rhs = node.getSecond();
-
-        return OrNodeFactory.create(context, translate(node.getPosition()), (RubyNode) lhs.accept(this), (RubyNode) rhs.accept(this));
-    }
-
-    @Override
-    public Object visitOpElementAsgnNode(org.jrubyparser.ast.OpElementAsgnNode node) {
-        /*
-         * We're going to de-sugar a[b] += c into a[b] = a[b] + c. See discussion in
-         * visitOpAsgnNode.
-         */
-
-        org.jrubyparser.ast.Node index;
-
-        if (node.getArgs() == null) {
-            index = null;
-        } else {
-            index = node.getArgs().childNodes().get(0);
-        }
-
-        final org.jrubyparser.ast.Node operand = node.getValue();
-
-        final String temp = environment.allocateLocalTemp();
-        final org.jrubyparser.ast.Node writeArrayToTemp = new org.jrubyparser.ast.LocalAsgnNode(node.getPosition(), temp, 0, node.getReceiver());
-        final org.jrubyparser.ast.Node readArrayFromTemp = new org.jrubyparser.ast.LocalVarNode(node.getPosition(), 0, temp);
-
-        final org.jrubyparser.ast.Node arrayRead = new org.jrubyparser.ast.CallNode(node.getPosition(), readArrayFromTemp, "[]", buildArrayNode(node.getPosition(), index));
-
-        final String op = node.getOperatorName();
-
-        org.jrubyparser.ast.Node operation = null;
-
-        if (op.equals("||")) {
-            operation = new org.jrubyparser.ast.OrNode(node.getPosition(), arrayRead, operand);
-        } else if (op.equals("&&")) {
-            operation = new org.jrubyparser.ast.AndNode(node.getPosition(), arrayRead, operand);
-        } else {
-            operation = new org.jrubyparser.ast.CallNode(node.getPosition(), arrayRead, node.getOperatorName(), buildArrayNode(node.getPosition(), operand));
-        }
-
-        final org.jrubyparser.ast.Node arrayWrite = new org.jrubyparser.ast.CallNode(node.getPosition(), readArrayFromTemp, "[]=", buildArrayNode(node.getPosition(), index, operation));
-
-        final org.jrubyparser.ast.BlockNode block = new org.jrubyparser.ast.BlockNode(node.getPosition());
-        block.add(writeArrayToTemp);
-        block.add(arrayWrite);
-
-        return block.accept(this);
-    }
-
-    private static org.jrubyparser.ast.ArrayNode buildArrayNode(org.jrubyparser.SourcePosition sourcePosition, org.jrubyparser.ast.Node first, org.jrubyparser.ast.Node... rest) {
-        if (first == null) {
-            return new org.jrubyparser.ast.ArrayNode(sourcePosition);
-        }
-
-        final org.jrubyparser.ast.ArrayNode array = new org.jrubyparser.ast.ArrayNode(sourcePosition, first);
-
-        for (org.jrubyparser.ast.Node node : rest) {
-            array.add(node);
-        }
-
-        return array;
-    }
-
-    @Override
-    public Object visitOrNode(org.jrubyparser.ast.OrNode node) {
-        final SourceSection sourceSection = translate(node.getPosition());
-
-        RubyNode x;
-
-        if (node.getFirst() == null) {
-            x = new NilNode(context, sourceSection);
-        } else {
-            x = (RubyNode) node.getFirst().accept(this);
-        }
-
-        RubyNode y;
-
-        if (node.getSecond() == null) {
-            y = new NilNode(context, sourceSection);
-        } else {
-            y = (RubyNode) node.getSecond().accept(this);
-        }
-
-        return OrNodeFactory.create(context, sourceSection, x, y);
-    }
-
-    @Override
-    public Object visitPostExeNode(org.jrubyparser.ast.PostExeNode node) {
-        return unimplemented(node);
-    }
-
-    @Override
-    public Object visitPreExeNode(org.jrubyparser.ast.PreExeNode node) {
-        return unimplemented(node);
-    }
-
-    @Override
-    public Object visitRedoNode(org.jrubyparser.ast.RedoNode node) {
-        return new RedoNode(context, translate(node.getPosition()));
-    }
-
-    @Override
-    public Object visitRegexpNode(org.jrubyparser.ast.RegexpNode node) {
-        RubyRegexp regexp;
-
-        try {
-            final String patternText = node.getValue();
-
-            int flags = Pattern.MULTILINE | Pattern.UNIX_LINES;
-
-            final org.jrubyparser.RegexpOptions options = node.getOptions();
-
-            if (options.isIgnorecase()) {
-                flags |= Pattern.CASE_INSENSITIVE;
-            }
-
-            if (options.isMultiline()) {
-                // TODO(cs): isn't this the default?
-                flags |= Pattern.MULTILINE;
-            }
-
-            final Pattern pattern = Pattern.compile(patternText, flags);
-
-            regexp = new RubyRegexp(context.getCoreLibrary().getRegexpClass(), pattern);
-        } catch (PatternSyntaxException e) {
-            context.implementationMessage("failed to parse Ruby regexp " + node.getValue() + " as Java regexp - replacing with .");
-            regexp = new RubyRegexp(context.getCoreLibrary().getRegexpClass(), ".");
-        }
-
-        final ObjectLiteralNode literalNode = new ObjectLiteralNode(context, translate(node.getPosition()), regexp);
-        return literalNode;
-    }
-
-    @Override
-    public Object visitRescueBodyNode(org.jrubyparser.ast.RescueBodyNode node) {
-        return unimplemented(node);
-    }
-
-    @Override
-    public Object visitRescueNode(org.jrubyparser.ast.RescueNode node) {
-        final SourceSection sourceSection = translate(node.getPosition());
-
-        RubyNode tryPart;
-
-        if (node.getBody() != null) {
-            tryPart = (RubyNode) node.getBody().accept(this);
-        } else {
-            tryPart = new NilNode(context, sourceSection);
-        }
-
-        final List<RescueNode> rescueNodes = new ArrayList<>();
-
-        org.jrubyparser.ast.RescueBodyNode rescueBody = node.getRescue();
-
-        while (rescueBody != null) {
-            if (rescueBody.getExceptions() != null) {
-                if (rescueBody.getExceptions() instanceof org.jrubyparser.ast.ArrayNode) {
-                    final List<org.jrubyparser.ast.Node> exceptionNodes = ((org.jrubyparser.ast.ArrayNode) rescueBody.getExceptions()).childNodes();
-
-                    final RubyNode[] handlingClasses = new RubyNode[exceptionNodes.size()];
-
-                    for (int n = 0; n < handlingClasses.length; n++) {
-                        handlingClasses[n] = (RubyNode) exceptionNodes.get(n).accept(this);
-                    }
-
-                    RubyNode translatedBody;
-
-                    if (rescueBody.getBody() == null) {
-                        translatedBody = new NilNode(context, sourceSection);
-                    } else {
-                        translatedBody = (RubyNode) rescueBody.getBody().accept(this);
-                    }
-
-                    final RescueClassesNode rescueNode = new RescueClassesNode(context, sourceSection, handlingClasses, translatedBody);
-                    rescueNodes.add(rescueNode);
-                } else if (rescueBody.getExceptions() instanceof org.jrubyparser.ast.SplatNode) {
-                    final org.jrubyparser.ast.SplatNode splat = (org.jrubyparser.ast.SplatNode) rescueBody.getExceptions();
-
-                    RubyNode splatTranslated;
-
-                    if (splat.getValue() == null) {
-                        splatTranslated = new NilNode(context, sourceSection);
-                    } else {
-                        splatTranslated = (RubyNode) splat.getValue().accept(this);
-                    }
-
-                    RubyNode bodyTranslated;
-
-                    if (rescueBody.getBody() == null) {
-                        bodyTranslated = new NilNode(context, sourceSection);
-                    } else {
-                        bodyTranslated = (RubyNode) rescueBody.getBody().accept(this);
-                    }
-
-                    final RescueSplatNode rescueNode = new RescueSplatNode(context, sourceSection, splatTranslated, bodyTranslated);
-                    rescueNodes.add(rescueNode);
-                } else {
-                    unimplemented(node);
-                }
-            } else {
-                RubyNode bodyNode;
-
-                if (rescueBody.getBody() == null) {
-                    bodyNode = new NilNode(context, sourceSection);
-                } else {
-                    bodyNode = (RubyNode) rescueBody.getBody().accept(this);
-                }
-
-                final RescueAnyNode rescueNode = new RescueAnyNode(context, sourceSection, bodyNode);
-                rescueNodes.add(rescueNode);
-            }
-
-            rescueBody = rescueBody.getOptRescue();
-        }
-
-        RubyNode elsePart;
-
-        if (node.getElse() != null) {
-            elsePart = (RubyNode) node.getElse().accept(this);
-        } else {
-            elsePart = new NilNode(context, sourceSection);
-        }
-
-        return new TryNode(context, sourceSection, tryPart, rescueNodes.toArray(new RescueNode[rescueNodes.size()]), elsePart);
-    }
-
-    @Override
-    public Object visitRestArgNode(org.jrubyparser.ast.RestArgNode node) {
-        return unimplemented(node);
-    }
-
-    @Override
-    public Object visitRetryNode(org.jrubyparser.ast.RetryNode node) {
-        return new RetryNode(context, translate(node.getPosition()));
-    }
-
-    @Override
-    public Object visitReturnNode(org.jrubyparser.ast.ReturnNode node) {
-        final SourceSection sourceSection = translate(node.getPosition());
-
-        RubyNode translatedChild;
-
-        if (node.getValue() == null) {
-            translatedChild = new NilNode(context, sourceSection);
-        } else {
-            translatedChild = (RubyNode) node.getValue().accept(this);
-        }
-
-        return new ReturnNode(context, sourceSection, environment.getReturnID(), translatedChild);
-    }
-
-    @Override
-    public Object visitRootNode(org.jrubyparser.ast.RootNode node) {
-        return unimplemented(node);
-    }
-
-    @Override
-    public Object visitSClassNode(org.jrubyparser.ast.SClassNode node) {
-        final SourceSection sourceSection = translate(node.getPosition());
-
-        final TranslatorEnvironment newEnvironment = new TranslatorEnvironment(context, environment, environment.getParser(), environment.getParser().allocateReturnID(), true, true,
-                        new UniqueMethodIdentifier());
-        final ModuleTranslator classTranslator = new ModuleTranslator(context, this, newEnvironment, source);
-
-        final MethodDefinitionNode definitionMethod = classTranslator.compileClassNode(node.getPosition(), "singleton", node.getBody());
-
-        final RubyNode receiverNode = (RubyNode) node.getReceiver().accept(this);
-
-        final SingletonClassNode singletonClassNode = new SingletonClassNode(context, sourceSection, receiverNode);
-
-        return new OpenModuleNode(context, sourceSection, singletonClassNode, definitionMethod);
-    }
-
-    @Override
-    public Object visitSValueNode(org.jrubyparser.ast.SValueNode node) {
-        return node.getValue().accept(this);
-    }
-
-    @Override
-    public Object visitSelfNode(org.jrubyparser.ast.SelfNode node) {
-        return new SelfNode(context, translate(node.getPosition()));
-    }
-
-    @Override
-    public Object visitSplatNode(org.jrubyparser.ast.SplatNode node) {
-        final SourceSection sourceSection = translate(node.getPosition());
-
-        RubyNode value;
-
-        if (node.getValue() == null) {
-            value = new NilNode(context, sourceSection);
-        } else {
-            value = (RubyNode) node.getValue().accept(this);
-        }
-
-        return SplatCastNodeFactory.create(context, sourceSection, value);
-    }
-
-    @Override
-    public Object visitStrNode(org.jrubyparser.ast.StrNode node) {
-        return new StringLiteralNode(context, translate(node.getPosition()), node.getValue());
-    }
-
-    @Override
-    public Object visitSuperNode(org.jrubyparser.ast.SuperNode node) {
-        return unimplemented(node);
-    }
-
-    @Override
-    public Object visitSymbolNode(org.jrubyparser.ast.SymbolNode node) {
-        return new ObjectLiteralNode(context, translate(node.getPosition()), new RubySymbol(context.getCoreLibrary().getSymbolClass(), node.getName()));
-    }
-
-    @Override
-    public Object visitToAryNode(org.jrubyparser.ast.ToAryNode node) {
-        return unimplemented(node);
-    }
-
-    @Override
-    public Object visitTrueNode(org.jrubyparser.ast.TrueNode node) {
-        return new BooleanLiteralNode(context, translate(node.getPosition()), true);
-    }
-
-    @Override
-    public Object visitUndefNode(org.jrubyparser.ast.UndefNode node) {
-        return unimplemented(node);
-    }
-
-    @Override
-    public Object visitUntilNode(org.jrubyparser.ast.UntilNode node) {
-        final SourceSection sourceSection = translate(node.getPosition());
-
-        RubyNode condition;
-
-        if (node.getCondition() == null) {
-            condition = new NilNode(context, sourceSection);
-        } else {
-            condition = (RubyNode) node.getCondition().accept(this);
-        }
-
-        final BooleanCastNode conditionCast = BooleanCastNodeFactory.create(context, sourceSection, condition);
-        final NotNode conditionCastNot = new NotNode(context, sourceSection, conditionCast);
-        final BooleanCastNode conditionCastNotCast = BooleanCastNodeFactory.create(context, sourceSection, conditionCastNot);
-
-        final RubyNode body = (RubyNode) node.getBody().accept(this);
-
-        return new WhileNode(context, sourceSection, conditionCastNotCast, body);
-    }
-
-    @Override
-    public Object visitVAliasNode(org.jrubyparser.ast.VAliasNode node) {
-        return unimplemented(node);
-    }
-
-    @Override
-    public Object visitVCallNode(org.jrubyparser.ast.VCallNode node) {
-        final org.jrubyparser.ast.Node receiver = new org.jrubyparser.ast.SelfNode(node.getPosition());
-        final org.jrubyparser.ast.Node args = null;
-        final org.jrubyparser.ast.Node callNode = new org.jrubyparser.ast.CallNode(node.getPosition(), receiver, node.getName(), args);
-
-        return callNode.accept(this);
-    }
-
-    @Override
-    public Object visitWhenNode(org.jrubyparser.ast.WhenNode node) {
-        return unimplemented(node);
-    }
-
-    @Override
-    public Object visitWhileNode(org.jrubyparser.ast.WhileNode node) {
-        final SourceSection sourceSection = translate(node.getPosition());
-
-        RubyNode condition;
-
-        if (node.getCondition() == null) {
-            condition = new NilNode(context, sourceSection);
-        } else {
-            condition = (RubyNode) node.getCondition().accept(this);
-        }
-
-        final BooleanCastNode conditionCast = BooleanCastNodeFactory.create(context, sourceSection, condition);
-
-        final RubyNode body = (RubyNode) node.getBody().accept(this);
-
-        return new WhileNode(context, sourceSection, conditionCast, body);
-    }
-
-    @Override
-    public Object visitXStrNode(org.jrubyparser.ast.XStrNode node) {
-        SourceSection sourceSection = translate(node.getPosition());
-
-        final StringLiteralNode literal = new StringLiteralNode(context, sourceSection, node.getValue());
-
-        return new SystemNode(context, sourceSection, literal);
-    }
-
-    @Override
-    public Object visitYieldNode(org.jrubyparser.ast.YieldNode node) {
-        final List<org.jrubyparser.ast.Node> arguments = new ArrayList<>();
-
-        final org.jrubyparser.ast.Node argsNode = node.getArgs();
-
-        if (argsNode != null) {
-            if (argsNode instanceof org.jrubyparser.ast.ListNode) {
-                arguments.addAll(((org.jrubyparser.ast.ListNode) node.getArgs()).childNodes());
-            } else {
-                arguments.add(node.getArgs());
-            }
-        }
-
-        final List<RubyNode> argumentsTranslated = new ArrayList<>();
-
-        for (org.jrubyparser.ast.Node argument : arguments) {
-            argumentsTranslated.add((RubyNode) argument.accept(this));
-        }
-
-        final RubyNode[] argumentsTranslatedArray = argumentsTranslated.toArray(new RubyNode[argumentsTranslated.size()]);
-
-        return new YieldNode(context, translate(node.getPosition()), argumentsTranslatedArray);
-    }
-
-    @Override
-    public Object visitZArrayNode(org.jrubyparser.ast.ZArrayNode node) {
-        final RubyNode[] values = new RubyNode[0];
-
-        return new UninitialisedArrayLiteralNode(context, translate(node.getPosition()), values);
-    }
-
-    @Override
-    public Object visitZSuperNode(org.jrubyparser.ast.ZSuperNode node) {
-        return unimplemented(node);
-    }
-
-    public Object visitArgumentNode(org.jrubyparser.ast.ArgumentNode node) {
-        return unimplemented(node);
-    }
-
-    public Object visitCommentNode(org.jrubyparser.ast.CommentNode node) {
-        return unimplemented(node);
-    }
-
-    public Object visitKeywordArgNode(org.jrubyparser.ast.KeywordArgNode node) {
-        return unimplemented(node);
-    }
-
-    public Object visitKeywordRestArgNode(org.jrubyparser.ast.KeywordRestArgNode node) {
-        return unimplemented(node);
-    }
-
-    public Object visitListNode(org.jrubyparser.ast.ListNode node) {
-        return unimplemented(node);
-    }
-
-    public Object visitMethodNameNode(org.jrubyparser.ast.MethodNameNode node) {
-        return unimplemented(node);
-    }
-
-    public Object visitOptArgNode(org.jrubyparser.ast.OptArgNode node) {
-        return unimplemented(node);
-    }
-
-    public Object visitSyntaxNode(org.jrubyparser.ast.SyntaxNode node) {
-        return unimplemented(node);
-    }
-
-    public Object visitImplicitNilNode(org.jrubyparser.ast.ImplicitNilNode node) {
-        return new NilNode(context, translate(node.getPosition()));
-    }
-
-    public Object visitLambdaNode(org.jrubyparser.ast.LambdaNode node) {
-        // TODO(cs): code copied and modified from visitIterNode - extract common
-
-        final TranslatorEnvironment newEnvironment = new TranslatorEnvironment(context, environment, environment.getParser(), environment.getReturnID(), false, false, new UniqueMethodIdentifier());
-        final MethodTranslator methodCompiler = new MethodTranslator(context, this, newEnvironment, false, source);
-
-        org.jrubyparser.ast.ArgsNode argsNode;
-
-        if (node.getVar() instanceof org.jrubyparser.ast.ArgsNode) {
-            argsNode = (org.jrubyparser.ast.ArgsNode) node.getVar();
-        } else if (node.getVar() instanceof org.jrubyparser.ast.DAsgnNode) {
-            final org.jrubyparser.ast.ArgumentNode arg = new org.jrubyparser.ast.ArgumentNode(node.getPosition(), ((org.jrubyparser.ast.DAsgnNode) node.getVar()).getName());
-            final org.jrubyparser.ast.ListNode preArgs = new org.jrubyparser.ast.ArrayNode(node.getPosition(), arg);
-            argsNode = new org.jrubyparser.ast.ArgsNode(node.getPosition(), preArgs, null, null, null, null, null, null);
-        } else if (node.getVar() == null) {
-            argsNode = null;
-        } else {
-            throw new UnsupportedOperationException();
-        }
-
-        final MethodDefinitionNode definitionNode = methodCompiler.compileFunctionNode(translate(node.getPosition()), "(lambda)", argsNode, node.getBody());
-
-        return new LambdaNode(context, translate(node.getPosition()), definitionNode);
-    }
-
-    public Object visitUnaryCallNode(org.jrubyparser.ast.UnaryCallNode node) {
-        final org.jrubyparser.ast.Node callNode = new org.jrubyparser.ast.CallNode(node.getPosition(), node.getReceiver(), node.getName(), null, null);
-        return callNode.accept(this);
-    }
-
-    protected Object unimplemented(org.jrubyparser.ast.Node node) {
-        context.implementationMessage("warning: %s at %s does nothing", node, node.getPosition());
-        return new NilNode(context, translate(node.getPosition()));
-    }
-
-    protected SourceSection translate(final org.jrubyparser.SourcePosition sourcePosition) {
-        try {
-            // TODO(cs): get an identifier
-            final String identifier = "(identifier)";
-
-            // TODO(cs): work out the start column
-            final int startColumn = -1;
-
-            final int charLength = sourcePosition.getEndOffset() - sourcePosition.getStartOffset();
-
-            return new DefaultSourceSection(source, identifier, sourcePosition.getStartLine() + 1, startColumn, sourcePosition.getStartOffset(), charLength);
-        } catch (UnsupportedOperationException e) {
-            // In some circumstances JRuby can't tell you what the position is
-            return translate(new org.jrubyparser.SourcePosition("(unknown)", 0, 0));
-        }
-    }
-
-    protected SequenceNode initFlipFlopStates(SourceSection sourceSection) {
-        final RubyNode[] initNodes = new RubyNode[environment.getFlipFlopStates().size()];
-
-        for (int n = 0; n < initNodes.length; n++) {
-            initNodes[n] = new InitFlipFlopSlotNode(context, sourceSection, environment.getFlipFlopStates().get(n));
-        }
-
-        return new SequenceNode(context, sourceSection, initNodes);
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.parser/src/com/oracle/truffle/ruby/parser/TranslatorEnvironment.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,232 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.parser;
-
-import java.util.*;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.ruby.nodes.*;
-import com.oracle.truffle.ruby.nodes.instrument.*;
-import com.oracle.truffle.ruby.nodes.methods.locals.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-import com.oracle.truffle.ruby.runtime.methods.*;
-
-public class TranslatorEnvironment {
-
-    private final RubyContext context;
-
-    private final FrameDescriptor frameDescriptor;
-
-    private final List<FrameSlot> preParameters = new ArrayList<>();
-
-    private final List<FrameSlot> optionalParameters = new ArrayList<>();
-    private final Map<FrameSlot, RubyNode> optionalParametersDefaultValues = new HashMap<>();
-
-    private final List<FrameSlot> postParameters = new ArrayList<>();
-
-    private final List<FrameSlot> flipFlopStates = new ArrayList<>();
-
-    private FrameSlot restParameter = null;
-
-    private FrameSlot blockParameter = null;
-
-    private JRubyParser parser;
-    private final long returnID;
-
-    private final boolean ownScopeForAssignments;
-    private final boolean neverAssignInParentScope;
-
-    protected final TranslatorEnvironment parent;
-    private String methodName = "";
-    private boolean needsDeclarationFrame = false;
-    private UniqueMethodIdentifier methodIdentifier;
-
-    private int tempIndex;
-
-    public TranslatorEnvironment(RubyContext context, TranslatorEnvironment parent, FrameDescriptor frameDescriptor, JRubyParser parser, long returnID, boolean ownScopeForAssignments,
-                    boolean neverAssignInParentScope, UniqueMethodIdentifier methodIdentifier) {
-        this.context = context;
-        this.parent = parent;
-        this.frameDescriptor = frameDescriptor;
-        this.parser = parser;
-        this.returnID = returnID;
-        this.ownScopeForAssignments = ownScopeForAssignments;
-        this.neverAssignInParentScope = neverAssignInParentScope;
-        this.methodIdentifier = methodIdentifier;
-    }
-
-    public TranslatorEnvironment(RubyContext context, TranslatorEnvironment parent, JRubyParser parser, long returnID, boolean ownScopeForAssignments, boolean neverAssignInParentScope,
-                    UniqueMethodIdentifier methodIdentifier) {
-        this(context, parent, new FrameDescriptor(RubyFrameTypeConversion.getInstance()), parser, returnID, ownScopeForAssignments, neverAssignInParentScope, methodIdentifier);
-    }
-
-    public int getLocalVarCount() {
-        return getFrameDescriptor().getSize();
-    }
-
-    public TranslatorEnvironment getParent() {
-        return parent;
-    }
-
-    public List<FrameSlot> getPreParameters() {
-        return preParameters;
-    }
-
-    public List<FrameSlot> getOptionalParameters() {
-        return optionalParameters;
-    }
-
-    public Map<FrameSlot, RubyNode> getOptionalParametersDefaultValues() {
-        return optionalParametersDefaultValues;
-    }
-
-    public List<FrameSlot> getPostParameters() {
-        return postParameters;
-    }
-
-    public TranslatorEnvironment getParent(int level) {
-        assert level >= 0;
-        if (level == 0) {
-            return this;
-        } else {
-            return parent.getParent(level - 1);
-        }
-    }
-
-    public FrameSlot declareVar(String name) {
-        return getFrameDescriptor().findOrAddFrameSlot(name);
-    }
-
-    public UniqueMethodIdentifier findMethodForLocalVar(String name) {
-        TranslatorEnvironment current = this;
-        do {
-            FrameSlot slot = current.getFrameDescriptor().findFrameSlot(name);
-            if (slot != null) {
-                return current.methodIdentifier;
-            }
-
-            current = current.parent;
-        } while (current != null);
-
-        return null;
-    }
-
-    public RubyNode findLocalVarNode(String name, SourceSection sourceSection) {
-        TranslatorEnvironment current = this;
-        int level = -1;
-        try {
-            do {
-                level++;
-                FrameSlot slot = current.getFrameDescriptor().findFrameSlot(name);
-                if (slot != null) {
-                    if (level == 0) {
-                        return ReadLocalVariableNodeFactory.create(context, sourceSection, slot);
-                    } else {
-                        return ReadLevelVariableNodeFactory.create(context, sourceSection, slot, level);
-                    }
-                }
-
-                current = current.parent;
-            } while (current != null);
-        } finally {
-            if (current != null) {
-                current = this;
-                while (level-- > 0) {
-                    current.needsDeclarationFrame = true;
-                    current = current.parent;
-                }
-            }
-        }
-
-        return null;
-    }
-
-    public void setRestParameter(FrameSlot restParameter) {
-        this.restParameter = restParameter;
-    }
-
-    public FrameSlot getRestParameter() {
-        return restParameter;
-    }
-
-    public void setBlockParameter(FrameSlot blockParameter) {
-        this.blockParameter = blockParameter;
-    }
-
-    public FrameSlot getBlockParameter() {
-        return blockParameter;
-    }
-
-    public void declareFunction(String name) {
-        declareVar(name);
-    }
-
-    public String getMethodName() {
-        return methodName;
-    }
-
-    public void setMethodName(String methodName) {
-        this.methodName = methodName;
-    }
-
-    public void setNeedsDeclarationFrame() {
-        needsDeclarationFrame = true;
-    }
-
-    public boolean needsDeclarationFrame() {
-        return needsDeclarationFrame;
-    }
-
-    public FrameDescriptor getFrameDescriptor() {
-        return frameDescriptor;
-    }
-
-    public String allocateLocalTemp() {
-        final String name = "rubytruffle_temp" + tempIndex;
-        tempIndex++;
-        declareVar(name);
-        return name;
-    }
-
-    public long getReturnID() {
-        return returnID;
-    }
-
-    public JRubyParser getParser() {
-        return parser;
-    }
-
-    public boolean hasOwnScopeForAssignments() {
-        return ownScopeForAssignments;
-    }
-
-    public boolean getNeverAssignInParentScope() {
-        return neverAssignInParentScope;
-    }
-
-    public void addMethodDeclarationSlots() {
-        frameDescriptor.addFrameSlot(RubyModule.VISIBILITY_FRAME_SLOT_ID);
-        frameDescriptor.addFrameSlot(RubyModule.MODULE_FUNCTION_FLAG_FRAME_SLOT_ID);
-    }
-
-    public UniqueMethodIdentifier getUniqueMethodIdentifier() {
-        return methodIdentifier;
-    }
-
-    public List<FrameSlot> getFlipFlopStates() {
-        return flipFlopStates;
-    }
-
-    public RubyNodeInstrumenter getNodeInstrumenter() {
-        return (RubyNodeInstrumenter) context.getDebugContext().getNodeInstrumenter();
-    }
-}
--- a/graal/com.oracle.truffle.ruby.runtime/.checkstyle_checks.xml	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,206 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE module PUBLIC "-//Puppy Crawl//DTD Check Configuration 1.3//EN" "http://www.puppycrawl.com/dtds/configuration_1_3.dtd">
-
-<!--
-    This configuration file was written by the eclipse-cs plugin configuration editor
--->
-<!--
-    Checkstyle-Configuration: Maxine Checks
-    Description: none
--->
-<module name="Checker">
-  <property name="severity" value="warning"/>
-  <module name="TreeWalker">
-    <property name="tabWidth" value="4"/>
-    <module name="FileContentsHolder"/>
-    <module name="JavadocStyle">
-      <property name="checkHtml" value="false"/>
-    </module>
-    <module name="LocalFinalVariableName"/>
-    <module name="LocalVariableName"/>
-    <module name="MemberName">
-      <property name="format" value="^(([a-z][a-zA-Z0-9]*$)|(_[A-Z][a-zA-Z0-9]*_[a-z][a-zA-Z0-9]*$))"/>
-    </module>
-    <module name="MethodName">
-      <property name="format" value="^[a-z][a-z_A-Z0-9]*$"/>
-    </module>
-    <module name="PackageName"/>
-    <module name="ParameterName"/>
-    <module name="TypeName">
-      <property name="format" value="^[A-Z][_a-zA-Z0-9]*$"/>
-    </module>
-    <module name="RedundantImport"/>
-    <module name="LineLength">
-      <property name="max" value="250"/>
-    </module>
-    <module name="MethodParamPad"/>
-    <module name="NoWhitespaceAfter">
-      <property name="tokens" value="ARRAY_INIT,BNOT,DEC,DOT,INC,LNOT,UNARY_MINUS,UNARY_PLUS"/>
-    </module>
-    <module name="NoWhitespaceBefore">
-      <property name="tokens" value="SEMI,DOT,POST_DEC,POST_INC"/>
-    </module>
-    <module name="ParenPad"/>
-    <module name="TypecastParenPad">
-      <property name="tokens" value="RPAREN,TYPECAST"/>
-    </module>
-    <module name="WhitespaceAfter"/>
-    <module name="WhitespaceAround">
-      <property name="tokens" value="ASSIGN,BAND,BAND_ASSIGN,BOR,BOR_ASSIGN,BSR,BSR_ASSIGN,BXOR,BXOR_ASSIGN,COLON,DIV,DIV_ASSIGN,EQUAL,GE,GT,LAND,LE,LITERAL_ASSERT,LITERAL_CATCH,LITERAL_DO,LITERAL_ELSE,LITERAL_FINALLY,LITERAL_FOR,LITERAL_IF,LITERAL_RETURN,LITERAL_SYNCHRONIZED,LITERAL_TRY,LITERAL_WHILE,LOR,LT,MINUS,MINUS_ASSIGN,MOD,MOD_ASSIGN,NOT_EQUAL,PLUS,PLUS_ASSIGN,QUESTION,SL,SLIST,SL_ASSIGN,SR,SR_ASSIGN,STAR,STAR_ASSIGN,LITERAL_ASSERT,TYPE_EXTENSION_AND"/>
-    </module>
-    <module name="RedundantModifier"/>
-    <module name="AvoidNestedBlocks">
-      <property name="allowInSwitchCase" value="true"/>
-    </module>
-    <module name="EmptyBlock">
-      <property name="option" value="text"/>
-      <property name="tokens" value="LITERAL_DO,LITERAL_ELSE,LITERAL_FINALLY,LITERAL_IF,LITERAL_TRY,LITERAL_WHILE,STATIC_INIT"/>
-    </module>
-    <module name="LeftCurly"/>
-    <module name="NeedBraces"/>
-    <module name="RightCurly"/>
-    <module name="EmptyStatement"/>
-    <module name="HiddenField">
-      <property name="severity" value="ignore"/>
-      <property name="ignoreConstructorParameter" value="true"/>
-      <metadata name="net.sf.eclipsecs.core.lastEnabledSeverity" value="inherit"/>
-    </module>
-    <module name="FinalClass"/>
-    <module name="HideUtilityClassConstructor">
-      <property name="severity" value="ignore"/>
-      <metadata name="net.sf.eclipsecs.core.lastEnabledSeverity" value="inherit"/>
-    </module>
-    <module name="ArrayTypeStyle"/>
-    <module name="UpperEll"/>
-    <module name="FallThrough"/>
-    <module name="FinalLocalVariable">
-      <property name="severity" value="ignore"/>
-      <metadata name="net.sf.eclipsecs.core.lastEnabledSeverity" value="inherit"/>
-    </module>
-    <module name="MultipleVariableDeclarations"/>
-    <module name="StringLiteralEquality">
-      <property name="severity" value="error"/>
-    </module>
-    <module name="SuperFinalize"/>
-    <module name="UnnecessaryParentheses">
-      <property name="severity" value="ignore"/>
-      <metadata name="net.sf.eclipsecs.core.lastEnabledSeverity" value="inherit"/>
-    </module>
-    <module name="Indentation">
-      <property name="severity" value="ignore"/>
-      <metadata name="net.sf.eclipsecs.core.lastEnabledSeverity" value="inherit"/>
-    </module>
-    <module name="StaticVariableName">
-      <property name="format" value="^[A-Za-z][a-zA-Z0-9]*$"/>
-    </module>
-    <module name="EmptyForInitializerPad"/>
-    <module name="EmptyForIteratorPad"/>
-    <module name="ModifierOrder"/>
-    <module name="DefaultComesLast"/>
-    <module name="InnerAssignment">
-      <property name="severity" value="ignore"/>
-      <metadata name="net.sf.eclipsecs.core.lastEnabledSeverity" value="inherit"/>
-    </module>
-    <module name="JUnitTestCase"/>
-    <module name="ModifiedControlVariable"/>
-    <module name="MutableException">
-      <property name="severity" value="ignore"/>
-      <metadata name="net.sf.eclipsecs.core.lastEnabledSeverity" value="inherit"/>
-    </module>
-    <module name="ParameterAssignment">
-      <property name="severity" value="ignore"/>
-      <metadata name="net.sf.eclipsecs.core.lastEnabledSeverity" value="inherit"/>
-    </module>
-    <module name="RegexpSinglelineJava">
-      <metadata name="net.sf.eclipsecs.core.comment" value="Illegal trailing whitespace(s) at the end of the line."/>
-      <property name="format" value="\s$"/>
-      <property name="message" value="Illegal trailing whitespace(s) at the end of the line."/>
-      <property name="ignoreComments" value="true"/>
-      <metadata name="com.atlassw.tools.eclipse.checkstyle.comment" value="Checks for trailing spaces at the end of a line"/>
-    </module>
-    <module name="RegexpSinglelineJava">
-      <metadata name="net.sf.eclipsecs.core.comment" value="illegal space before a comma"/>
-      <property name="format" value=" ,"/>
-      <property name="message" value="illegal space before a comma"/>
-      <property name="ignoreComments" value="true"/>
-      <metadata name="com.atlassw.tools.eclipse.checkstyle.customMessage" value="Illegal whitespace before a comma."/>
-      <metadata name="com.atlassw.tools.eclipse.checkstyle.comment" value="Checks for whitespace before a comma."/>
-    </module>
-  </module>
-  <!--<module name="RegexpHeader">
-    <property name="header" value="/\*\n \* Copyright \(c\) 2013 Oracle and/or its affiliates. All rights reserved. This\n \* code is released under a tri EPL/GPL/LGPL license. You can use it,\n \* redistribute it and/or modify it under the terms of the:\n \*\n \* Eclipse Public License version 1.0\n \* GNU General Public License version 2\n \* GNU Lesser General Public License version 2.1\n \*/\n"/>
-    <property name="fileExtensions" value="java"/>
-  </module>-->
-  <module name="FileTabCharacter">
-    <property name="severity" value="error"/>
-  </module>
-  <module name="NewlineAtEndOfFile">
-    <property name="lineSeparator" value="lf"/>
-  </module>
-  <module name="Translation"/>
-  <module name="SuppressionCommentFilter">
-    <property name="offCommentFormat" value="Checkstyle: stop constant name check"/>
-    <property name="onCommentFormat" value="Checkstyle: resume constant name check"/>
-    <property name="checkFormat" value="ConstantNameCheck"/>
-    <metadata name="com.atlassw.tools.eclipse.checkstyle.comment" value="Allow non-conforming constant names"/>
-  </module>
-  <module name="SuppressionCommentFilter">
-    <property name="offCommentFormat" value="Checkstyle: stop method name check"/>
-    <property name="onCommentFormat" value="Checkstyle: resume method name check"/>
-    <property name="checkFormat" value="MethodName"/>
-    <property name="checkC" value="false"/>
-    <metadata name="com.atlassw.tools.eclipse.checkstyle.comment" value="Disable method name checks"/>
-  </module>
-  <module name="SuppressionCommentFilter">
-    <property name="offCommentFormat" value="CheckStyle: stop parameter assignment check"/>
-    <property name="onCommentFormat" value="CheckStyle: resume parameter assignment check"/>
-    <property name="checkFormat" value="ParameterAssignment"/>
-    <property name="checkC" value="false"/>
-    <metadata name="com.atlassw.tools.eclipse.checkstyle.comment" value="Disable Parameter Assignment"/>
-  </module>
-  <module name="SuppressionCommentFilter">
-    <property name="offCommentFormat" value="Checkstyle: stop final variable check"/>
-    <property name="onCommentFormat" value="Checkstyle: resume final variable check"/>
-    <property name="checkFormat" value="FinalLocalVariable"/>
-    <metadata name="com.atlassw.tools.eclipse.checkstyle.comment" value="Disable final variable checks"/>
-  </module>
-  <module name="SuppressionCommentFilter">
-    <property name="offCommentFormat" value="Checkstyle: stop"/>
-    <property name="onCommentFormat" value="Checkstyle: resume"/>
-    <metadata name="com.atlassw.tools.eclipse.checkstyle.comment" value="Disable all checks"/>
-  </module>
-  <module name="SuppressionCommentFilter">
-    <property name="offCommentFormat" value="// START GENERATED RAW ASSEMBLER METHODS"/>
-    <property name="onCommentFormat" value="// END GENERATED RAW ASSEMBLER METHODS"/>
-    <metadata name="com.atlassw.tools.eclipse.checkstyle.comment" value="Disable all checks for generated raw assembler methods"/>
-  </module>
-  <module name="SuppressionCommentFilter">
-    <property name="offCommentFormat" value="// START GENERATED LABEL ASSEMBLER METHODS"/>
-    <property name="onCommentFormat" value="// END GENERATED LABEL ASSEMBLER METHODS"/>
-    <metadata name="com.atlassw.tools.eclipse.checkstyle.comment" value="Disable all checks for generated label assembler methods"/>
-  </module>
-  <module name="SuppressionCommentFilter">
-    <property name="offCommentFormat" value="CheckStyle: stop inner assignment check"/>
-    <property name="onCommentFormat" value="CheckStyle: resume inner assignment check"/>
-    <property name="checkFormat" value="InnerAssignment"/>
-    <metadata name="com.atlassw.tools.eclipse.checkstyle.comment" value="Disable inner assignment checks"/>
-  </module>
-  <module name="SuppressionCommentFilter">
-    <property name="offCommentFormat" value="Checkstyle: stop field name check"/>
-    <property name="onCommentFormat" value="Checkstyle: resume field name check"/>
-    <property name="checkFormat" value="MemberName"/>
-    <property name="checkC" value="false"/>
-    <metadata name="com.atlassw.tools.eclipse.checkstyle.comment" value="Disable field name checks"/>
-  </module>
-  <module name="RegexpMultiline">
-    <metadata name="net.sf.eclipsecs.core.comment" value="illegal Windows line ending"/>
-    <property name="format" value="\r\n"/>
-    <property name="message" value="illegal Windows line ending"/>
-  </module>
-  <module name="SuppressionCommentFilter">
-    <property name="offCommentFormat" value="CheckStyle: stop header check"/>
-    <property name="onCommentFormat" value="CheckStyle: resume header check"/>
-    <property name="checkFormat" value=".*Header"/>
-    <metadata name="com.atlassw.tools.eclipse.checkstyle.comment" value="Disable header checks"/>
-  </module>
-</module>
--- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/InputReader.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,25 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.runtime;
-
-import java.io.*;
-
-/**
- * Interface allowing Ruby {@code Kernel#gets} to be configured to use the standard Java readLine,
- * some library like JLine, or to be mocked for testing.
- */
-public interface InputReader {
-
-    /**
-     * Show a prompt and read one line of input.
-     */
-    String readLine(String prompt) throws IOException;
-
-}
--- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/NilPlaceholder.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,29 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.runtime;
-
-/**
- * Represents the Ruby {@code Nil} object, but without being a full Ruby object. This allows us to
- * have a simple values that is {@code nil}, but more readily available than the particular instance
- * for a context.
- */
-public final class NilPlaceholder {
-
-    public static final NilPlaceholder INSTANCE = new NilPlaceholder();
-
-    private NilPlaceholder() {
-    }
-
-    @Override
-    public String toString() {
-        return "";
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/RubyArguments.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,84 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.runtime;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-
-/**
- * Arguments and other context passed to a Ruby method. Includes the central Ruby context object,
- * optionally the scope at the point of declaration (forming a closure), the value of self, a passed
- * block, and the formal arguments.
- */
-public final class RubyArguments extends Arguments {
-
-    private final MaterializedFrame declarationFrame;
-    private final Object self;
-    private final RubyProc block;
-    private final Object[] arguments;
-
-    public RubyArguments(MaterializedFrame declarationFrame, Object self, RubyProc block, Object... arguments) {
-        assert self != null;
-        assert arguments != null;
-
-        this.declarationFrame = declarationFrame;
-        this.self = self;
-        this.block = block;
-        this.arguments = arguments;
-    }
-
-    public MaterializedFrame getDeclarationFrame() {
-        return declarationFrame;
-    }
-
-    /**
-     * Get the declaration frame a certain number of levels up from the current frame, where the
-     * current frame is 0.
-     */
-    public static MaterializedFrame getDeclarationFrame(VirtualFrame frame, int level) {
-        assert level > 0;
-
-        MaterializedFrame parentFrame = frame.getArguments(RubyArguments.class).getDeclarationFrame();
-        return getDeclarationFrame(parentFrame, level - 1);
-    }
-
-    /**
-     * Get the declaration frame a certain number of levels up from the current frame, where the
-     * current frame is 0.
-     */
-    @ExplodeLoop
-    private static MaterializedFrame getDeclarationFrame(MaterializedFrame frame, int level) {
-        assert frame != null;
-        assert level >= 0;
-
-        MaterializedFrame parentFrame = frame;
-
-        for (int n = 0; n < level; n++) {
-            parentFrame = parentFrame.getArguments(RubyArguments.class).getDeclarationFrame();
-        }
-
-        return parentFrame;
-    }
-
-    public Object getSelf() {
-        return self;
-    }
-
-    public RubyProc getBlock() {
-        return block;
-    }
-
-    public Object[] getArguments() {
-        return arguments;
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/RubyContext.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,294 +0,0 @@
-/*
- * Copyright (c) 2013, 2014 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.runtime;
-
-import java.math.*;
-import java.util.concurrent.atomic.*;
-
-import jnr.posix.*;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.debug.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.api.source.*;
-import com.oracle.truffle.ruby.runtime.configuration.*;
-import com.oracle.truffle.ruby.runtime.control.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-import com.oracle.truffle.ruby.runtime.methods.*;
-import com.oracle.truffle.ruby.runtime.objects.*;
-import com.oracle.truffle.ruby.runtime.subsystems.*;
-
-/**
- * The global state of a running Ruby system.
- */
-public class RubyContext implements ExecutionContext {
-
-    private final Configuration configuration;
-    private final RubyParser parser;
-    private final CoreLibrary coreLibrary;
-    private final FeatureManager featureManager;
-    private final ObjectSpaceManager objectSpaceManager;
-    private final TraceManager traceManager;
-    private final ThreadManager threadManager;
-    private final FiberManager fiberManager;
-    private final AtExitManager atExitManager;
-    private final SourceManager sourceManager;
-    private DebugContext debugContext = null;
-
-    private AtomicLong nextObjectID = new AtomicLong(0);
-
-    private String currentDirectory = System.getProperty("user.dir");
-
-    private POSIX posix = POSIXFactory.getPOSIX();
-
-    public RubyContext(RubyParser parser) {
-        this(new Configuration(new ConfigurationBuilder()), parser);
-    }
-
-    public RubyContext(Configuration configuration, RubyParser parser) {
-        assert configuration != null;
-
-        this.configuration = configuration;
-        this.parser = parser;
-        objectSpaceManager = new ObjectSpaceManager(this);
-        traceManager = new TraceManager(this);
-
-        // See note in CoreLibrary#initialize to see why we need to break this into two statements
-        coreLibrary = new CoreLibrary(this);
-        coreLibrary.initialize();
-
-        featureManager = new FeatureManager(this);
-        atExitManager = new AtExitManager();
-        sourceManager = new SourceManager();
-
-        // Must initialize threads before fibers
-
-        threadManager = new ThreadManager(this);
-        fiberManager = new FiberManager(this);
-    }
-
-    public final String getLanguageShortName() {
-        return "Ruby " + CoreLibrary.RUBY_VERSION;
-    }
-
-    public SourceManager getSourceManager() {
-        return sourceManager;
-    }
-
-    public DebugContext getDebugContext() {
-        return debugContext;
-    }
-
-    public void setDebugContext(DebugContext debugContext) {
-        this.debugContext = debugContext;
-    }
-
-    public void implementationMessage(String format, Object... arguments) {
-        System.err.println("rubytruffle: " + String.format(format, arguments));
-    }
-
-    public void load(Source source) {
-        execute(this, source, RubyParser.ParserContext.TOP_LEVEL, coreLibrary.getMainObject(), null);
-    }
-
-    public void loadFile(String fileName) {
-        final Source source = sourceManager.get(fileName);
-        final String code = source.getCode();
-        if (code == null) {
-            throw new RuntimeException("Can't read file " + fileName);
-        }
-        execute(this, source, RubyParser.ParserContext.TOP_LEVEL, coreLibrary.getMainObject(), null);
-    }
-
-    /**
-     * Receives runtime notification that execution has halted.
-     */
-    public void haltedAt(Node node, MaterializedFrame frame) {
-        runShell(node, frame);
-    }
-
-    public Object eval(String code) {
-        final Source source = sourceManager.get("(eval)", code);
-        return execute(this, source, RubyParser.ParserContext.TOP_LEVEL, coreLibrary.getMainObject(), null);
-    }
-
-    public Object eval(String code, RubyModule module) {
-        final Source source = sourceManager.get("(eval)", code);
-        return execute(this, source, RubyParser.ParserContext.MODULE, module, null);
-    }
-
-    public Object eval(String code, RubyBinding binding) {
-        final Source source = sourceManager.get("(eval)", code);
-        return execute(this, source, RubyParser.ParserContext.TOP_LEVEL, binding.getSelf(), binding.getFrame());
-    }
-
-    public void runShell(Node node, MaterializedFrame frame) {
-        MaterializedFrame existingLocals = frame;
-
-        String prompt = "Ruby> ";
-        if (node != null) {
-            final SourceSection src = node.getSourceSection();
-            if (src != null) {
-                prompt = (src.getSource().getName() + ":" + src.getStartLine() + "> ");
-            }
-        }
-
-        while (true) {
-            try {
-                final String line = configuration.getInputReader().readLine(prompt);
-
-                final ShellResult result = evalShell(line, existingLocals);
-
-                configuration.getStandardOut().println("=> " + result.getResult());
-
-                existingLocals = result.getFrame();
-            } catch (KillException e) {
-                return;
-            } catch (Exception e) {
-                e.printStackTrace();
-            }
-        }
-    }
-
-    public ShellResult evalShell(String code, MaterializedFrame existingLocals) {
-        final Source source = sourceManager.get("(shell)", code);
-        return (ShellResult) execute(this, source, RubyParser.ParserContext.SHELL, coreLibrary.getMainObject(), existingLocals);
-    }
-
-    public Object execute(RubyContext context, Source source, RubyParser.ParserContext parserContext, Object self, MaterializedFrame parentFrame) {
-        try {
-            final RubyParserResult parseResult = parser.parse(context, source, parserContext, parentFrame);
-            final RubyArguments arguments = new RubyArguments(parentFrame, self, null);
-            final CallTarget callTarget = Truffle.getRuntime().createCallTarget(parseResult.getRootNode());
-
-            return callTarget.call(null, arguments);
-        } catch (RaiseException e) {
-            throw e;
-        } catch (ThrowException e) {
-            throw new RaiseException(context.getCoreLibrary().argumentErrorUncaughtThrow(e.getTag()));
-        } catch (KillException | QuitException e) {
-            throw e;
-        } catch (Throwable e) {
-            throw new RaiseException(ExceptionTranslator.translateException(this, e));
-        }
-    }
-
-    public long getNextObjectID() {
-        // TODO(CS): We can theoretically run out of long values
-
-        final long id = nextObjectID.getAndIncrement();
-
-        if (id < 0) {
-            nextObjectID.set(Long.MIN_VALUE);
-            throw new RuntimeException("Object IDs exhausted");
-        }
-
-        return id;
-    }
-
-    public void shutdown() {
-        atExitManager.run();
-
-        threadManager.leaveGlobalLock();
-
-        objectSpaceManager.shutdown();
-
-        if (fiberManager != null) {
-            fiberManager.shutdown();
-        }
-    }
-
-    public RubyString makeString(String string) {
-        return new RubyString(coreLibrary.getStringClass(), string);
-    }
-
-    public RubyString makeString(char string) {
-        return makeString(Character.toString(string));
-    }
-
-    public Configuration getConfiguration() {
-        return configuration;
-    }
-
-    public CoreLibrary getCoreLibrary() {
-        return coreLibrary;
-    }
-
-    public FeatureManager getFeatureManager() {
-        return featureManager;
-    }
-
-    public ObjectSpaceManager getObjectSpaceManager() {
-        return objectSpaceManager;
-    }
-
-    public TraceManager getTraceManager() {
-        return traceManager;
-    }
-
-    public FiberManager getFiberManager() {
-        return fiberManager;
-    }
-
-    public ThreadManager getThreadManager() {
-        return threadManager;
-    }
-
-    public RubyParser getParser() {
-        return parser;
-    }
-
-    /**
-     * Utility method to check if an object should be visible in a Ruby program. Used in assertions
-     * at method boundaries to check that only values we want to be visible to the programmer become
-     * so.
-     */
-    public static boolean shouldObjectBeVisible(Object object) {
-        // TODO(cs): RubyMethod should never be visible
-
-        return object instanceof UndefinedPlaceholder || //
-                        object instanceof Boolean || //
-                        object instanceof Integer || //
-                        object instanceof BigInteger || //
-                        object instanceof Double || //
-                        object instanceof RubyBasicObject || //
-                        object instanceof RubyMethod || //
-                        object instanceof NilPlaceholder || //
-                        object instanceof RubyMethod;
-    }
-
-    public static boolean shouldObjectsBeVisible(Object... objects) {
-        for (Object object : objects) {
-            if (!shouldObjectBeVisible(object)) {
-                return false;
-            }
-        }
-
-        return true;
-    }
-
-    public void setCurrentDirectory(String currentDirectory) {
-        this.currentDirectory = currentDirectory;
-    }
-
-    public String getCurrentDirectory() {
-        return currentDirectory;
-    }
-
-    public POSIX getPOSIX() {
-        return posix;
-    }
-
-    public AtExitManager getAtExitManager() {
-        return atExitManager;
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/RubyParser.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,26 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.runtime;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-
-/**
- * Interface to a Ruby parser.
- */
-public interface RubyParser {
-
-    public static enum ParserContext {
-        TOP_LEVEL, SHELL, MODULE
-    }
-
-    RubyParserResult parse(RubyContext context, Source source, ParserContext parserContext, MaterializedFrame parentFrame);
-
-}
--- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/RubyParserResult.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,32 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.runtime;
-
-import com.oracle.truffle.api.nodes.*;
-
-/**
- * The result of parsing Ruby code is a root node and a frame descriptor for the method in that
- * root. The root node will always be a {@code RubyRootNode}, but this package is below the nodes
- * package so currently cannot refer to it.
- */
-public class RubyParserResult {
-
-    private final RootNode rootNode;
-
-    public RubyParserResult(RootNode rootNode) {
-        assert rootNode != null;
-        this.rootNode = rootNode;
-    }
-
-    public RootNode getRootNode() {
-        return rootNode;
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/ShellResult.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.runtime;
-
-import com.oracle.truffle.api.frame.*;
-
-/**
- * The result of executing a line in a shell is a result value and the final frame containing any
- * local variables set.
- */
-public class ShellResult {
-
-    private final Object result;
-    private final MaterializedFrame frame;
-
-    public ShellResult(Object result, MaterializedFrame frame) {
-        assert RubyContext.shouldObjectBeVisible(result);
-        assert frame != null;
-
-        this.result = result;
-        this.frame = frame;
-    }
-
-    public Object getResult() {
-        return result;
-    }
-
-    public MaterializedFrame getFrame() {
-        return frame;
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/UndefinedPlaceholder.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,24 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.runtime;
-
-/**
- * The {@link UndefinedPlaceholder} is a value that represents an undefined value in Ruby. This is
- * used to differentiate between nil and the true absence of a value, such as an argument that has
- * not been passed.
- */
-public final class UndefinedPlaceholder {
-
-    public static final UndefinedPlaceholder INSTANCE = new UndefinedPlaceholder();
-
-    private UndefinedPlaceholder() {
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/configuration/Configuration.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,121 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.runtime.configuration;
-
-import java.io.*;
-
-import com.oracle.truffle.ruby.runtime.*;
-
-/**
- * Configurable, immutable global parameters for Ruby.
- */
-public class Configuration {
-
-    private final String standardLibrary;
-
-    private final boolean verbose;
-    private final int warningLevel;
-    private final int taintCheckLevel;
-
-    private final String defaultExternalEncoding;
-    private final String defaultInternalEncoding;
-
-    private final boolean debug;
-    private final boolean trace;
-    private final boolean fullObjectSpace;
-
-    private final boolean printParseTree;
-    private final boolean printUninitializedCalls;
-    private final boolean printJavaExceptions;
-
-    private final PrintStream standardOut;
-    private final InputReader inputReader;
-
-    public Configuration(ConfigurationBuilder builder) {
-        assert builder != null;
-
-        standardLibrary = builder.getStandardLibrary();
-
-        verbose = builder.getVerbose();
-        warningLevel = builder.getWarningLevel();
-        taintCheckLevel = builder.getTaintCheckLevel();
-
-        defaultExternalEncoding = builder.getDefaultExternalEncoding();
-        defaultInternalEncoding = builder.getDefaultInternalEncoding();
-
-        debug = builder.getDebug();
-        trace = builder.getTrace();
-        fullObjectSpace = builder.getFullObjectSpace();
-
-        printParseTree = builder.getPrintParseTree();
-        printUninitializedCalls = builder.getPrintUninitializedCalls();
-        printJavaExceptions = builder.getPrintJavaExceptions();
-
-        standardOut = builder.getStandardOut();
-        inputReader = builder.getInputReader();
-    }
-
-    public String getStandardLibrary() {
-        return standardLibrary;
-    }
-
-    public boolean getDebug() {
-        return debug;
-    }
-
-    public boolean getVerbose() {
-        return verbose;
-    }
-
-    public int getWarningLevel() {
-        return warningLevel;
-    }
-
-    public int getTaintCheckLevel() {
-        return taintCheckLevel;
-    }
-
-    public String getDefaultExternalEncoding() {
-        return defaultExternalEncoding;
-    }
-
-    public String getDefaultInternalEncoding() {
-        return defaultInternalEncoding;
-    }
-
-    public boolean getTrace() {
-        return trace;
-    }
-
-    public boolean getFullObjectSpace() {
-        return fullObjectSpace;
-    }
-
-    public boolean getPrintParseTree() {
-        return printParseTree;
-    }
-
-    public boolean getPrintUninitializedCalls() {
-        return printUninitializedCalls;
-    }
-
-    public boolean getPrintJavaExceptions() {
-        return printJavaExceptions;
-    }
-
-    public PrintStream getStandardOut() {
-        return standardOut;
-    }
-
-    public InputReader getInputReader() {
-        return inputReader;
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/configuration/ConfigurationBuilder.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,200 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.runtime.configuration;
-
-import java.io.*;
-
-import com.oracle.truffle.ruby.runtime.*;
-
-/**
- * The mutable counterpart to {@link Configuration}.
- */
-public class ConfigurationBuilder {
-
-    /**
-     * The path of the JRuby packaging of the Ruby standard library within our source tree.
-     */
-    public static final String JRUBY_STDLIB_JAR = "lib/jruby-stdlib-1.7.4.jar";
-
-    private String standardLibrary = JRUBY_STDLIB_JAR;
-
-    private boolean debug = false;
-    private boolean verbose = false;
-    private int warningLevel = 0;
-    private int taintCheckLevel = 0;
-
-    private String defaultExternalEncoding = null;
-    private String defaultInternalEncoding = null;
-
-    private boolean trace = false;
-    private boolean fullObjectSpace = false;
-
-    private boolean printParseTree = false;
-    private boolean printUninitializedCalls = false;
-    private boolean printJavaExceptions = false;
-
-    private PrintStream standardOut = System.out;
-
-    private InputReader inputReader = new InputReader() {
-
-        private final BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
-
-        @Override
-        public String readLine(String prompt) throws IOException {
-            System.err.print(prompt);
-            return reader.readLine();
-        }
-
-    };
-
-    public ConfigurationBuilder() {
-    }
-
-    public ConfigurationBuilder(Configuration configuration) {
-        assert configuration != null;
-
-        standardLibrary = configuration.getStandardLibrary();
-
-        debug = configuration.getDebug();
-        verbose = configuration.getVerbose();
-        warningLevel = configuration.getWarningLevel();
-        taintCheckLevel = configuration.getTaintCheckLevel();
-
-        defaultExternalEncoding = configuration.getDefaultExternalEncoding();
-        defaultInternalEncoding = configuration.getDefaultInternalEncoding();
-
-        trace = configuration.getTrace();
-        fullObjectSpace = configuration.getFullObjectSpace();
-
-        printParseTree = configuration.getPrintParseTree();
-        printUninitializedCalls = configuration.getPrintUninitializedCalls();
-        printJavaExceptions = configuration.getPrintJavaExceptions();
-
-        standardOut = configuration.getStandardOut();
-    }
-
-    public String getStandardLibrary() {
-        return standardLibrary;
-    }
-
-    public void setStandardLibrary(String standardLibrary) {
-        assert standardLibrary != null;
-        this.standardLibrary = standardLibrary;
-    }
-
-    public boolean getDebug() {
-        return debug;
-    }
-
-    public void setDebug(boolean debug) {
-        this.debug = debug;
-    }
-
-    public boolean getVerbose() {
-        return verbose;
-    }
-
-    public void setVerbose(boolean verbose) {
-        this.verbose = verbose;
-    }
-
-    public int getWarningLevel() {
-        return warningLevel;
-    }
-
-    public void setWarningLevel(int warningLevel) {
-        this.warningLevel = warningLevel;
-    }
-
-    public int getTaintCheckLevel() {
-        return taintCheckLevel;
-    }
-
-    public void setTaintCheckLevel(int taintCheckLevel) {
-        this.taintCheckLevel = taintCheckLevel;
-    }
-
-    public String getDefaultExternalEncoding() {
-        return defaultExternalEncoding;
-    }
-
-    public void setDefaultExternalEncoding(String defaultExternalEncoding) {
-        assert defaultExternalEncoding != null;
-        this.defaultExternalEncoding = defaultExternalEncoding;
-    }
-
-    public String getDefaultInternalEncoding() {
-        return defaultInternalEncoding;
-    }
-
-    public void setDefaultInternalEncoding(String defaultInternalEncoding) {
-        assert defaultInternalEncoding != null;
-        this.defaultInternalEncoding = defaultInternalEncoding;
-    }
-
-    public boolean getTrace() {
-        return trace;
-    }
-
-    public void setTrace(boolean trace) {
-        this.trace = trace;
-    }
-
-    public boolean getFullObjectSpace() {
-        return fullObjectSpace;
-    }
-
-    public void setFullObjectSpace(boolean fullObjectSpace) {
-        this.fullObjectSpace = fullObjectSpace;
-    }
-
-    public boolean getPrintParseTree() {
-        return printParseTree;
-    }
-
-    public void setPrintParseTree(boolean printParseTree) {
-        this.printParseTree = printParseTree;
-    }
-
-    public boolean getPrintUninitializedCalls() {
-        return printUninitializedCalls;
-    }
-
-    public void setPrintUninitializedCalls(boolean printUninitializedCalls) {
-        this.printUninitializedCalls = printUninitializedCalls;
-    }
-
-    public boolean getPrintJavaExceptions() {
-        return printJavaExceptions;
-    }
-
-    public void setPrintJavaExceptions(boolean printJavaExceptions) {
-        this.printJavaExceptions = printJavaExceptions;
-    }
-
-    public PrintStream getStandardOut() {
-        return standardOut;
-    }
-
-    public void setStandardOut(PrintStream standardOut) {
-        assert standardOut != null;
-        this.standardOut = standardOut;
-    }
-
-    public InputReader getInputReader() {
-        return inputReader;
-    }
-
-    public void setInputReader(InputReader lineReader) {
-        assert lineReader != null;
-        this.inputReader = lineReader;
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/control/BreakException.java	Sun Feb 23 17:00:35 2014 -0800
+++ /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. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.runtime.control;
-
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-
-/**
- * Controls a break from a control structure or method.
- */
-public final class BreakException extends ControlFlowException {
-
-    public static final BreakException NIL = new BreakException(NilPlaceholder.INSTANCE);
-
-    private final Object result;
-
-    public BreakException(Object result) {
-        assert RubyContext.shouldObjectBeVisible(result);
-
-        this.result = result;
-    }
-
-    public Object getResult() {
-        return result;
-    }
-
-    private static final long serialVersionUID = -8650123232850256133L;
-
-}
--- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/control/ContinuationReturnException.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,48 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.runtime.control;
-
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-
-/**
- * Controls return from a continuation.
- */
-public final class ContinuationReturnException extends ControlFlowException {
-
-    private final RubyContinuation continuation;
-    private final Object value;
-
-    public ContinuationReturnException(RubyContinuation continuation, Object value) {
-        assert continuation != null;
-        assert RubyContext.shouldObjectBeVisible(value);
-
-        this.continuation = continuation;
-        this.value = value;
-    }
-
-    /**
-     * Get the continuation that caused this.
-     */
-    public RubyContinuation getContinuation() {
-        return continuation;
-    }
-
-    /**
-     * Get the value that has been returned.
-     */
-    public Object getValue() {
-        return value;
-    }
-
-    private static final long serialVersionUID = 6215834704293311504L;
-
-}
--- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/control/ExceptionTranslator.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,61 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.runtime.control;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-import com.oracle.truffle.ruby.runtime.objects.*;
-
-public final class ExceptionTranslator {
-
-    /**
-     * Translate a Java exception into a Ruby exception.
-     */
-    public static RubyBasicObject translateException(RubyContext context, Throwable exception) {
-        assert context != null;
-        assert exception != null;
-
-        CompilerAsserts.neverPartOfCompilation();
-
-        // RaiseException already includes the Ruby exception
-
-        if (exception instanceof RaiseException) {
-            return ((RaiseException) exception).getRubyException();
-        }
-
-        // Translate divide by zero into ZeroDivisionError
-
-        if (exception instanceof ArithmeticException && (exception.getMessage().endsWith("divide by zero") || exception.getMessage().endsWith("/ by zero"))) {
-            return new RubyException(context.getCoreLibrary().getZeroDivisionErrorClass(), "divided by 0");
-        }
-
-        /*
-         * If we can't translate the exception into a Ruby exception, then the error is ours and we
-         * report it as as RubyTruffleError. If a programmer sees this then it's a bug in our
-         * implementation.
-         */
-
-        if (context.getConfiguration().getPrintJavaExceptions()) {
-            exception.printStackTrace();
-        }
-
-        String message;
-
-        if (exception.getMessage() == null) {
-            message = exception.getClass().getSimpleName();
-        } else {
-            message = exception.getMessage();
-        }
-
-        return new RubyException(context.getCoreLibrary().getRubyTruffleErrorClass(), message);
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/control/NextException.java	Sun Feb 23 17:00:35 2014 -0800
+++ /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. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.runtime.control;
-
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-
-/**
- * Controls moving to the next iteration in a control structure or method.
- */
-public final class NextException extends ControlFlowException {
-
-    public static final NextException NIL = new NextException(NilPlaceholder.INSTANCE);
-
-    private final Object result;
-
-    public NextException(Object result) {
-        assert RubyContext.shouldObjectBeVisible(result);
-
-        this.result = result;
-    }
-
-    public Object getResult() {
-        return result;
-    }
-
-    private static final long serialVersionUID = -302759969186731457L;
-
-}
--- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/control/RaiseException.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.runtime.control;
-
-import com.oracle.truffle.ruby.runtime.objects.*;
-
-/**
- * Ruby exceptions are just Ruby objects, so they cannot also be exceptions unless we made all Ruby
- * objects exceptions. A simpler approach is to wrap Ruby exceptions in Java exceptions when we want
- * to throw them. The error messages match MRI. Note that throwing is different to raising in Ruby,
- * which is the reason we have both {@link ThrowException} and {@link RaiseException}.
- */
-public class RaiseException extends RuntimeException {
-
-    private final RubyBasicObject rubyException;
-
-    public RaiseException(RubyBasicObject rubyException) {
-        this.rubyException = rubyException;
-    }
-
-    @Override
-    public String toString() {
-        return rubyException.toString();
-    }
-
-    @Override
-    public String getMessage() {
-        return rubyException.toString();
-    }
-
-    public RubyBasicObject getRubyException() {
-        return rubyException;
-    }
-
-    private static final long serialVersionUID = 7501185855599094740L;
-
-}
--- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/control/RedoException.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,21 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.runtime.control;
-
-import com.oracle.truffle.api.nodes.*;
-
-/**
- * Controls re-doing an iteration in a control structure or method.
- */
-public final class RedoException extends ControlFlowException {
-
-    private static final long serialVersionUID = -4717868827111714052L;
-
-}
--- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/control/RetryException.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,21 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.runtime.control;
-
-import com.oracle.truffle.api.nodes.*;
-
-/**
- * Controls re-trying an iteration in a control structure or method.
- */
-public final class RetryException extends ControlFlowException {
-
-    private static final long serialVersionUID = -1675586631300635765L;
-
-}
--- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/control/ReturnException.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,46 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.runtime.control;
-
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-
-/**
- * Controls an explicit return from a method.
- */
-public final class ReturnException extends ControlFlowException {
-
-    private final long returnID;
-    private final Object value;
-
-    public ReturnException(long returnID, Object value) {
-        assert RubyContext.shouldObjectBeVisible(value);
-
-        this.returnID = returnID;
-        this.value = value;
-    }
-
-    /**
-     * Return the return ID of this return that identifies where it intends to return to.
-     */
-    public long getReturnID() {
-        return returnID;
-    }
-
-    /**
-     * Get the value that has been returned.
-     */
-    public Object getValue() {
-        return value;
-    }
-
-    private static final long serialVersionUID = -9177536212065610691L;
-
-}
--- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/control/ThrowException.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,42 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.runtime.control;
-
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-
-/**
- * Controls throwing a value. Note that throwing is different to raising in Ruby, which is the
- * reason we have both {@link ThrowException} and {@link RaiseException}.
- */
-public class ThrowException extends ControlFlowException {
-
-    private final Object tag;
-    private final Object value;
-
-    public ThrowException(Object tag, Object value) {
-        assert tag != null;
-        assert RubyContext.shouldObjectBeVisible(value);
-
-        this.tag = tag;
-        this.value = value;
-    }
-
-    public Object getTag() {
-        return tag;
-    }
-
-    public Object getValue() {
-        return value;
-    }
-
-    private static final long serialVersionUID = 8693305627979840677L;
-
-}
--- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/CoreLibrary.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,651 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.runtime.core;
-
-import java.io.*;
-import java.math.*;
-import java.util.*;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.array.*;
-import com.oracle.truffle.ruby.runtime.objects.*;
-
-public class CoreLibrary {
-
-    public static final String RUBY_VERSION = "2.1.0";
-
-    private final RubyContext context;
-
-    private RubyClass argumentErrorClass;
-    private RubyClass arrayClass;
-    private RubyClass basicObjectClass;
-    private RubyClass bignumClass;
-    private RubyClass bindingClass;
-    private RubyClass classClass;
-    private RubyClass continuationClass;
-    private RubyClass dirClass;
-    private RubyClass exceptionClass;
-    private RubyClass falseClass;
-    private RubyClass fiberClass;
-    private RubyClass fileClass;
-    private RubyClass fixnumClass;
-    private RubyClass floatClass;
-    private RubyClass hashClass;
-    private RubyClass integerClass;
-    private RubyClass ioClass;
-    private RubyClass loadErrorClass;
-    private RubyClass localJumpErrorClass;
-    private RubyClass matchDataClass;
-    private RubyClass moduleClass;
-    private RubyClass nameErrorClass;
-    private RubyClass nilClass;
-    private RubyClass noMethodErrorClass;
-    private RubyClass numericClass;
-    private RubyClass objectClass;
-    private RubyClass procClass;
-    private RubyClass processClass;
-    private RubyClass rangeClass;
-    private RubyClass rangeErrorClass;
-    private RubyClass regexpClass;
-    private RubyClass rubyTruffleErrorClass;
-    private RubyClass runtimeErrorClass;
-    private RubyClass standardErrorClass;
-    private RubyClass stringClass;
-    private RubyClass structClass;
-    private RubyClass symbolClass;
-    private RubyClass syntaxErrorClass;
-    private RubyClass systemCallErrorClass;
-    private RubyClass systemExitClass;
-    private RubyClass threadClass;
-    private RubyClass timeClass;
-    private RubyClass trueClass;
-    private RubyClass typeErrorClass;
-    private RubyClass zeroDivisionErrorClass;
-
-    private RubyModule comparableModule;
-    private RubyModule configModule;
-    private RubyModule errnoModule;
-    private RubyModule kernelModule;
-    private RubyModule mathModule;
-    private RubyModule objectSpaceModule;
-    private RubyModule signalModule;
-
-    private RubyModule debugModule;
-    private RubyArray argv;
-    private RubyBasicObject globalVariablesObject;
-    private RubyBasicObject mainObject;
-    private RubyFalseClass falseObject;
-    private RubyNilClass nilObject;
-    private RubyTrueClass trueObject;
-
-    public CoreLibrary(RubyContext context) {
-        this.context = context;
-    }
-
-    public void initialize() {
-        // Create the cyclic classes and modules
-
-        classClass = new RubyClass.RubyClassClass(context);
-        basicObjectClass = new RubyClass(context, classClass, null, null, "BasicObject");
-        objectClass = new RubyClass(null, basicObjectClass, "Object");
-        moduleClass = new RubyModule.RubyModuleClass(context);
-
-        // Close the cycles
-
-        moduleClass.unsafeSetRubyClass(classClass);
-        classClass.unsafeSetSuperclass(moduleClass);
-        moduleClass.unsafeSetSuperclass(objectClass);
-        classClass.unsafeSetRubyClass(classClass);
-
-        // Create all other classes and modules
-
-        numericClass = new RubyClass(null, objectClass, "Numeric");
-        integerClass = new RubyClass(null, numericClass, "Integer");
-
-        exceptionClass = new RubyException.RubyExceptionClass(objectClass, "Exception");
-        standardErrorClass = new RubyException.RubyExceptionClass(exceptionClass, "StandardError");
-
-        ioClass = new RubyClass(null, objectClass, "IO");
-
-        argumentErrorClass = new RubyException.RubyExceptionClass(standardErrorClass, "ArgumentError");
-        arrayClass = new RubyArray.RubyArrayClass(objectClass);
-        bignumClass = new RubyClass(null, integerClass, "Bignum");
-        bindingClass = new RubyClass(null, objectClass, "Binding");
-        continuationClass = new RubyClass(null, objectClass, "Continuation");
-        comparableModule = new RubyModule(moduleClass, null, "Comparable");
-        configModule = new RubyModule(moduleClass, null, "Config");
-        debugModule = new RubyModule(moduleClass, null, "Debug");
-        dirClass = new RubyClass(null, objectClass, "Dir");
-        errnoModule = new RubyModule(moduleClass, null, "Errno");
-        falseClass = new RubyClass(null, objectClass, "FalseClass");
-        fiberClass = new RubyFiber.RubyFiberClass(objectClass);
-        fileClass = new RubyClass(null, ioClass, "File");
-        fixnumClass = new RubyClass(null, integerClass, "Fixnum");
-        floatClass = new RubyClass(null, objectClass, "Float");
-        hashClass = new RubyHash.RubyHashClass(objectClass);
-        kernelModule = new RubyModule(moduleClass, null, "Kernel");
-        loadErrorClass = new RubyException.RubyExceptionClass(standardErrorClass, "LoadError");
-        localJumpErrorClass = new RubyException.RubyExceptionClass(standardErrorClass, "LocalJumpError");
-        matchDataClass = new RubyClass(null, objectClass, "MatchData");
-        mathModule = new RubyModule(moduleClass, null, "Math");
-        nameErrorClass = new RubyClass(null, standardErrorClass, "NameError");
-        nilClass = new RubyClass(null, objectClass, "NilClass");
-        noMethodErrorClass = new RubyException.RubyExceptionClass(standardErrorClass, "NoMethodError");
-        objectSpaceModule = new RubyModule(moduleClass, null, "ObjectSpace");
-        procClass = new RubyProc.RubyProcClass(objectClass);
-        processClass = new RubyClass(null, objectClass, "Process");
-        rangeClass = new RubyClass(null, objectClass, "Range");
-        rangeErrorClass = new RubyException.RubyExceptionClass(standardErrorClass, "RangeError");
-        regexpClass = new RubyRegexp.RubyRegexpClass(objectClass);
-        rubyTruffleErrorClass = new RubyException.RubyExceptionClass(standardErrorClass, "RubyTruffleError");
-        runtimeErrorClass = new RubyException.RubyExceptionClass(standardErrorClass, "RuntimeError");
-        stringClass = new RubyString.RubyStringClass(objectClass);
-        structClass = new RubyClass(null, ioClass, "Struct");
-        signalModule = new RubyModule(moduleClass, null, "Signal");
-        symbolClass = new RubyClass(null, objectClass, "Symbol");
-        syntaxErrorClass = new RubyException.RubyExceptionClass(standardErrorClass, "SyntaxError");
-        systemCallErrorClass = new RubyException.RubyExceptionClass(standardErrorClass, "SystemCallError");
-        systemExitClass = new RubyException.RubyExceptionClass(exceptionClass, "SystemExit");
-        threadClass = new RubyThread.RubyThreadClass(objectClass);
-        timeClass = new RubyTime.RubyTimeClass(objectClass);
-        trueClass = new RubyClass(null, objectClass, "TrueClass");
-        typeErrorClass = new RubyException.RubyExceptionClass(standardErrorClass, "TypeError");
-        zeroDivisionErrorClass = new RubyException.RubyExceptionClass(standardErrorClass, "ZeroDivisionError");
-
-        // Includes
-
-        objectClass.include(kernelModule);
-
-        // Set constants
-
-        objectClass.setConstant("RUBY_VERSION", new RubyString(stringClass, RUBY_VERSION));
-        objectClass.setConstant("RUBY_PATCHLEVEL", 0);
-        objectClass.setConstant("RUBY_ENGINE", new RubyString(stringClass, "rubytruffle"));
-        objectClass.setConstant("RUBY_PLATFORM", new RubyString(stringClass, "jvm"));
-
-        argv = new RubyArray(arrayClass, new ObjectArrayStore());
-        objectClass.setConstant("ARGV", argv);
-        objectClass.setConstant("ENV", getEnv());
-
-        final RubyHash configHash = new RubyHash(hashClass);
-        configHash.put(new RubyString(stringClass, "ruby_install_name"), new RubyString(stringClass, "rubytruffle"));
-        configHash.put(new RubyString(stringClass, "RUBY_INSTALL_NAME"), new RubyString(stringClass, "rubytruffle"));
-        configHash.put(new RubyString(stringClass, "host_os"), new RubyString(stringClass, "unknown"));
-        configHash.put(new RubyString(stringClass, "exeext"), new RubyString(stringClass, ""));
-        configHash.put(new RubyString(stringClass, "EXEEXT"), new RubyString(stringClass, "rubytruffle"));
-        configModule.setConstant("CONFIG", configHash);
-        objectClass.setConstant("RbConfig", configModule);
-
-        mathModule.setConstant("PI", Math.PI);
-
-        fileClass.setConstant("SEPARATOR", new RubyString(stringClass, File.separator));
-        fileClass.setConstant("Separator", new RubyString(stringClass, File.separator));
-        fileClass.setConstant("ALT_SEPARATOR", NilPlaceholder.INSTANCE);
-        fileClass.setConstant("PATH_SEPARATOR", new RubyString(stringClass, File.pathSeparator));
-        fileClass.setConstant("FNM_SYSCASE", 0);
-
-        errnoModule.setConstant("ENOENT", new RubyClass(null, systemCallErrorClass, "ENOENT"));
-        errnoModule.setConstant("EPERM", new RubyClass(null, systemCallErrorClass, "EPERM"));
-        errnoModule.setConstant("ENOTEMPTY", new RubyClass(null, systemCallErrorClass, "ENOTEMPTY"));
-        errnoModule.setConstant("EEXIST", new RubyClass(null, systemCallErrorClass, "EEXIST"));
-        errnoModule.setConstant("EXDEV", new RubyClass(null, systemCallErrorClass, "EXDEV"));
-        errnoModule.setConstant("EACCES", new RubyClass(null, systemCallErrorClass, "EACCES"));
-
-        // Add all classes and modules as constants in Object
-
-        final RubyModule[] modules = {argumentErrorClass, //
-                        arrayClass, //
-                        basicObjectClass, //
-                        bignumClass, //
-                        bindingClass, //
-                        classClass, //
-                        continuationClass, //
-                        comparableModule, //
-                        configModule, //
-                        debugModule, //
-                        dirClass, //
-                        errnoModule, //
-                        exceptionClass, //
-                        falseClass, //
-                        fiberClass, //
-                        fileClass, //
-                        fixnumClass, //
-                        floatClass, //
-                        hashClass, //
-                        integerClass, //
-                        ioClass, //
-                        kernelModule, //
-                        loadErrorClass, //
-                        localJumpErrorClass, //
-                        matchDataClass, //
-                        mathModule, //
-                        moduleClass, //
-                        nameErrorClass, //
-                        nilClass, //
-                        noMethodErrorClass, //
-                        numericClass, //
-                        objectClass, //
-                        objectSpaceModule, //
-                        procClass, //
-                        processClass, //
-                        rangeClass, //
-                        rangeErrorClass, //
-                        regexpClass, //
-                        rubyTruffleErrorClass, //
-                        runtimeErrorClass, //
-                        signalModule, //
-                        standardErrorClass, //
-                        stringClass, //
-                        structClass, //
-                        symbolClass, //
-                        syntaxErrorClass, //
-                        systemCallErrorClass, //
-                        systemExitClass, //
-                        threadClass, //
-                        timeClass, //
-                        trueClass, //
-                        typeErrorClass, //
-                        zeroDivisionErrorClass};
-
-        for (RubyModule module : modules) {
-            objectClass.setConstant(module.getName(), module);
-        }
-
-        // Create some key objects
-
-        mainObject = new RubyObject(objectClass);
-        nilObject = new RubyNilClass(nilClass);
-        trueObject = new RubyTrueClass(trueClass);
-        falseObject = new RubyFalseClass(falseClass);
-
-        // Create the globals object
-
-        globalVariablesObject = new RubyBasicObject(objectClass);
-        globalVariablesObject.switchToPrivateLayout();
-        globalVariablesObject.setInstanceVariable("$:", new RubyArray(arrayClass, new ObjectArrayStore()));
-    }
-
-    public void initializeAfterMethodsAdded() {
-        bignumClass.getSingletonClass().undefMethod("new");
-        falseClass.getSingletonClass().undefMethod("new");
-        fixnumClass.getSingletonClass().undefMethod("new");
-        floatClass.getSingletonClass().undefMethod("new");
-        integerClass.getSingletonClass().undefMethod("new");
-        nilClass.getSingletonClass().undefMethod("new");
-        numericClass.getSingletonClass().undefMethod("new");
-        trueClass.getSingletonClass().undefMethod("new");
-    }
-
-    public RubyBasicObject box(Object object) {
-        assert RubyContext.shouldObjectBeVisible(object);
-
-        // TODO(cs): pool common object instances like small Fixnums?
-
-        if (object instanceof RubyBasicObject) {
-            return (RubyBasicObject) object;
-        }
-
-        if (object instanceof Boolean) {
-            if ((boolean) object) {
-                return trueObject;
-            } else {
-                return falseObject;
-            }
-        }
-
-        if (object instanceof Integer) {
-            return new RubyFixnum(fixnumClass, (int) object);
-        }
-
-        if (object instanceof BigInteger) {
-            return new RubyBignum(bignumClass, (BigInteger) object);
-        }
-
-        if (object instanceof Double) {
-            return new RubyFloat(floatClass, (double) object);
-        }
-
-        if (object instanceof NilPlaceholder) {
-            return nilObject;
-        }
-
-        CompilerDirectives.transferToInterpreter();
-
-        throw new UnsupportedOperationException("Don't know how to box " + object.getClass().getName());
-    }
-
-    public RubyException runtimeError(String message) {
-        return new RubyException(runtimeErrorClass, message);
-    }
-
-    public RubyException frozenError(String className) {
-        return runtimeError(String.format("can't modify frozen %s", className));
-    }
-
-    public RubyException argumentError(String message) {
-        return new RubyException(argumentErrorClass, message);
-    }
-
-    public RubyException argumentError(int passed, int required) {
-        return argumentError(String.format("wrong number of arguments (%d for %d)", passed, required));
-    }
-
-    public RubyException argumentErrorUncaughtThrow(Object tag) {
-        return argumentError(String.format("uncaught throw `%s'", tag));
-    }
-
-    public RubyException localJumpError(String message) {
-        return new RubyException(localJumpErrorClass, message);
-    }
-
-    public RubyException unexpectedReturn() {
-        return localJumpError("unexpected return");
-    }
-
-    public RubyException typeError(String message) {
-        return new RubyException(typeErrorClass, message);
-    }
-
-    public RubyException typeError(String from, String to) {
-        return typeError(String.format("can't convert %s to %s", from, to));
-    }
-
-    public RubyException typeErrorIsNotA(String value, String expectedType) {
-        return typeError(String.format("%s is not a %s", value, expectedType));
-    }
-
-    public RubyException typeErrorNeedsToBe(String name, String expectedType) {
-        return typeError(String.format("%s needs to be %s", name, expectedType));
-    }
-
-    public RubyException rangeError(String message) {
-        return new RubyException(rangeErrorClass, message);
-    }
-
-    public RubyException nameError(String message) {
-        return new RubyException(nameErrorClass, message);
-    }
-
-    public RubyException nameErrorUninitializedConstant(String name) {
-        return nameError(String.format("uninitialized constant %s", name));
-    }
-
-    public RubyException nameErrorNoMethod(String name, String object) {
-        return nameError(String.format("undefined local variable or method `%s' for %s", name, object));
-    }
-
-    public RubyException nameErrorInstanceNameNotAllowable(String name) {
-        return nameError(String.format("`%s' is not allowable as an instance variable name", name));
-    }
-
-    public RubyException nameErrorUncaughtThrow(Object tag) {
-        return nameError(String.format("uncaught throw `%s'", tag));
-    }
-
-    public RubyException noMethodError(String message) {
-        return new RubyException(context.getCoreLibrary().getNoMethodErrorClass(), message);
-    }
-
-    public RubyException noMethodError(String name, String object) {
-        return noMethodError(String.format("undefined method `%s' for %s", name, object));
-    }
-
-    public RubyException loadError(String message) {
-        return new RubyException(context.getCoreLibrary().getLoadErrorClass(), message);
-    }
-
-    public RubyException loadErrorCannotLoad(String name) {
-        return loadError(String.format("cannot load such file -- %s", name));
-    }
-
-    public RubyException zeroDivisionError() {
-        return new RubyException(context.getCoreLibrary().getZeroDivisionErrorClass(), "divided by 0");
-    }
-
-    public RubyContext getContext() {
-        return context;
-    }
-
-    public RubyClass getArgumentErrorClass() {
-        return argumentErrorClass;
-    }
-
-    public RubyClass getArrayClass() {
-        return arrayClass;
-    }
-
-    public RubyClass getBasicObjectClass() {
-        return basicObjectClass;
-    }
-
-    public RubyClass getBignumClass() {
-        return bignumClass;
-    }
-
-    public RubyClass getBindingClass() {
-        return bindingClass;
-    }
-
-    public RubyClass getClassClass() {
-        return classClass;
-    }
-
-    public RubyModule getComparableClass() {
-        return comparableModule;
-    }
-
-    public RubyClass getContinuationClass() {
-        return continuationClass;
-    }
-
-    public RubyClass getDirClass() {
-        return dirClass;
-    }
-
-    public RubyClass getExceptionClass() {
-        return exceptionClass;
-    }
-
-    public RubyClass getFalseClass() {
-        return falseClass;
-    }
-
-    public RubyClass getFiberClass() {
-        return fiberClass;
-    }
-
-    public RubyClass getFileClass() {
-        return fileClass;
-    }
-
-    public RubyClass getFixnumClass() {
-        return fixnumClass;
-    }
-
-    public RubyClass getFloatClass() {
-        return floatClass;
-    }
-
-    public RubyClass getHashClass() {
-        return hashClass;
-    }
-
-    public RubyClass getIntegerClass() {
-        return integerClass;
-    }
-
-    public RubyClass getIoClass() {
-        return ioClass;
-    }
-
-    public RubyClass getLoadErrorClass() {
-        return loadErrorClass;
-    }
-
-    public RubyClass getLocalJumpErrorClass() {
-        return localJumpErrorClass;
-    }
-
-    public RubyClass getMatchDataClass() {
-        return matchDataClass;
-    }
-
-    public RubyClass getModuleClass() {
-        return moduleClass;
-    }
-
-    public RubyClass getNameErrorClass() {
-        return nameErrorClass;
-    }
-
-    public RubyClass getNilClass() {
-        return nilClass;
-    }
-
-    public RubyClass getNoMethodErrorClass() {
-        return noMethodErrorClass;
-    }
-
-    public RubyClass getNumericClass() {
-        return numericClass;
-    }
-
-    public RubyClass getObjectClass() {
-        return objectClass;
-    }
-
-    public RubyClass getProcClass() {
-        return procClass;
-    }
-
-    public RubyClass getProcessClass() {
-        return processClass;
-    }
-
-    public RubyClass getRangeClass() {
-        return rangeClass;
-    }
-
-    public RubyClass getRangeErrorClass() {
-        return rangeErrorClass;
-    }
-
-    public RubyClass getRegexpClass() {
-        return regexpClass;
-    }
-
-    public RubyClass getRubyTruffleErrorClass() {
-        return rubyTruffleErrorClass;
-    }
-
-    public RubyClass getRuntimeErrorClass() {
-        return runtimeErrorClass;
-    }
-
-    public RubyModule getSignalModule() {
-        return signalModule;
-    }
-
-    public RubyClass getStandardErrorClass() {
-        return standardErrorClass;
-    }
-
-    public RubyClass getStringClass() {
-        return stringClass;
-    }
-
-    public RubyClass getStructClass() {
-        return structClass;
-    }
-
-    public RubyClass getSymbolClass() {
-        return symbolClass;
-    }
-
-    public RubyClass getSyntaxErrorClass() {
-        return syntaxErrorClass;
-    }
-
-    public RubyClass getSystemCallErrorClass() {
-        return systemCallErrorClass;
-    }
-
-    public RubyClass getThreadClass() {
-        return threadClass;
-    }
-
-    public RubyClass getTimeClass() {
-        return timeClass;
-    }
-
-    public RubyClass getTrueClass() {
-        return trueClass;
-    }
-
-    public RubyClass getTypeErrorClass() {
-        return typeErrorClass;
-    }
-
-    public RubyClass getZeroDivisionErrorClass() {
-        return zeroDivisionErrorClass;
-    }
-
-    public RubyModule getKernelModule() {
-        return kernelModule;
-    }
-
-    public RubyModule getMathModule() {
-        return mathModule;
-    }
-
-    public RubyModule getObjectSpaceModule() {
-        return objectSpaceModule;
-    }
-
-    public RubyModule getDebugModule() {
-        return debugModule;
-    }
-
-    public RubyArray getArgv() {
-        return argv;
-    }
-
-    public RubyBasicObject getGlobalVariablesObject() {
-        return globalVariablesObject;
-    }
-
-    public RubyBasicObject getMainObject() {
-        return mainObject;
-    }
-
-    public RubyFalseClass getFalseObject() {
-        return falseObject;
-    }
-
-    public RubyNilClass getNilObject() {
-        return nilObject;
-    }
-
-    public RubyTrueClass getTrueObject() {
-        return trueObject;
-    }
-
-    public RubyHash getEnv() {
-        final RubyHash hash = new RubyHash(context.getCoreLibrary().getHashClass());
-
-        for (Map.Entry<String, String> variable : System.getenv().entrySet()) {
-            hash.put(context.makeString(variable.getKey()), context.makeString(variable.getValue()));
-        }
-
-        return hash;
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/GeneralConversions.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,157 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.runtime.core;
-
-import java.math.*;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.ruby.runtime.*;
-
-public class GeneralConversions {
-
-    /**
-     * Convert a value to a boolean, without doing any lookup.
-     */
-    public static boolean toBoolean(Object value) {
-        assert value != null;
-
-        if (value instanceof NilPlaceholder) {
-            return false;
-        }
-
-        if (value instanceof Boolean) {
-            return (boolean) value;
-        }
-
-        if (value instanceof RubyTrueClass) {
-            return true;
-        }
-
-        if (value instanceof RubyFalseClass) {
-            return false;
-        }
-
-        return true;
-    }
-
-    /**
-     * Convert a value to a {@code Fixnum}, without doing any lookup.
-     */
-    public static int toFixnum(Object value) {
-        assert value != null;
-
-        if (value instanceof NilPlaceholder || value instanceof RubyNilClass) {
-            return 0;
-        }
-
-        if (value instanceof Integer) {
-            return (int) value;
-        }
-
-        if (value instanceof RubyFixnum) {
-            return ((RubyFixnum) value).getValue();
-        }
-
-        if (value instanceof BigInteger) {
-            throw new UnsupportedOperationException();
-        }
-
-        if (value instanceof RubyBignum) {
-            throw new UnsupportedOperationException();
-        }
-
-        if (value instanceof Double) {
-            return (int) (double) value;
-        }
-
-        if (value instanceof RubyFloat) {
-            return (int) ((RubyFloat) value).getValue();
-        }
-
-        CompilerDirectives.transferToInterpreter();
-
-        throw new UnsupportedOperationException(value.getClass().toString());
-    }
-
-    /**
-     * Convert a value to a {@code Float}, without doing any lookup.
-     */
-    public static double toFloat(Object value) {
-        assert value != null;
-
-        if (value instanceof NilPlaceholder || value instanceof RubyNilClass) {
-            return 0;
-        }
-
-        if (value instanceof Integer) {
-            return (int) value;
-        }
-
-        if (value instanceof RubyFixnum) {
-            return ((RubyFixnum) value).getValue();
-        }
-
-        if (value instanceof BigInteger) {
-            return ((BigInteger) value).doubleValue();
-        }
-
-        if (value instanceof RubyBignum) {
-            return ((RubyBignum) value).getValue().doubleValue();
-        }
-
-        if (value instanceof Double) {
-            return (double) value;
-        }
-
-        if (value instanceof RubyFloat) {
-            return ((RubyFloat) value).getValue();
-        }
-
-        CompilerDirectives.transferToInterpreter();
-
-        throw new UnsupportedOperationException();
-    }
-
-    /**
-     * Given a {@link BigInteger} value, produce either a {@code Fixnum} or {@code Bignum} .
-     */
-    public static Object fixnumOrBignum(BigInteger value) {
-        assert value != null;
-
-        if (value.compareTo(RubyFixnum.MIN_VALUE_BIG) >= 0 && value.compareTo(RubyFixnum.MAX_VALUE_BIG) <= 0) {
-            return value.intValue();
-        } else {
-            return value;
-        }
-    }
-
-    /**
-     * Given a {@code long} value, produce either a {@code Fixnum} or {@code Bignum} .
-     */
-    public static Object fixnumOrBignum(long value) {
-        if (value >= RubyFixnum.MIN_VALUE && value <= RubyFixnum.MAX_VALUE) {
-            return (int) value;
-        } else {
-            return BigInteger.valueOf(value);
-        }
-    }
-
-    /**
-     * Given a reference, produce either {@code nil} or the object. .
-     */
-    public static Object instanceOrNil(Object object) {
-        if (object == null) {
-            return NilPlaceholder.INSTANCE;
-        } else {
-            return object;
-        }
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/RubyBignum.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,83 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.runtime.core;
-
-import java.math.*;
-
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.array.*;
-import com.oracle.truffle.ruby.runtime.objects.*;
-
-/**
- * Represents the Ruby {@code Bignum} class.
- */
-public class RubyBignum extends RubyObject implements Unboxable {
-
-    private final BigInteger value;
-
-    public RubyBignum(RubyClass bignumClass, BigInteger value) {
-        super(bignumClass);
-
-        assert value != null;
-
-        this.value = value;
-    }
-
-    public BigInteger getValue() {
-        return value;
-    }
-
-    public Object unbox() {
-        return value;
-    }
-
-    public static RubyArray divMod(RubyContext context, BigInteger a, BigInteger b) {
-        final BigInteger[] quotientRemainder = a.divideAndRemainder(b);
-
-        final Object quotient = GeneralConversions.fixnumOrBignum(quotientRemainder[0]);
-        final Object remainder = GeneralConversions.fixnumOrBignum(quotientRemainder[1]);
-
-        final ObjectImmutablePairArrayStore store = new ObjectImmutablePairArrayStore(quotient, remainder);
-        return new RubyArray(context.getCoreLibrary().getArrayClass(), store);
-    }
-
-    @Override
-    public int hashCode() {
-        return value.hashCode();
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj == null) {
-            return false;
-        }
-        if (!(obj instanceof RubyBignum)) {
-            return false;
-        }
-        RubyBignum other = (RubyBignum) obj;
-        if (value == null) {
-            if (other.value != null) {
-                return false;
-            }
-        } else if (!value.equals(other.value)) {
-            return false;
-        }
-        return true;
-    }
-
-    @Override
-    public String toString() {
-        return value.toString();
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/RubyBinding.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,40 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.runtime.core;
-
-import com.oracle.truffle.api.frame.*;
-
-/**
- * Represents the Ruby {@code Binding} class.
- */
-public class RubyBinding extends RubyObject {
-
-    private final Object self;
-    private final MaterializedFrame frame;
-
-    public RubyBinding(RubyClass bindingClass, Object self, MaterializedFrame frame) {
-        super(bindingClass);
-
-        assert self != null;
-        assert frame != null;
-
-        this.self = self;
-        this.frame = frame;
-    }
-
-    public Object getSelf() {
-        return self;
-    }
-
-    public MaterializedFrame getFrame() {
-        return frame;
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/RubyClass.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,167 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.runtime.core;
-
-import java.util.*;
-
-import com.oracle.truffle.api.CompilerDirectives.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.lookup.*;
-import com.oracle.truffle.ruby.runtime.objects.*;
-
-/**
- * Represents the Ruby {@code Class} class. Note that most of the functionality you might associate
- * with {@code Class} is actually in {@code Module}, implemented by {@link RubyModule}.
- */
-public class RubyClass extends RubyModule {
-
-    /**
-     * The class from which we create the object that is {@code Class}. A subclass of
-     * {@link RubyClass} so that we can override {@link #newInstance} and allocate a
-     * {@link RubyClass} rather than a normal {@link RubyBasicObject}.
-     */
-    public static class RubyClassClass extends RubyClass {
-
-        public RubyClassClass(RubyContext context) {
-            super(context, null, null, null, "Class");
-        }
-
-        @Override
-        public RubyBasicObject newInstance() {
-            return new RubyClass(null, getContext().getCoreLibrary().getObjectClass(), "(unnamed class)");
-        }
-
-    }
-
-    @CompilationFinal private RubyClass superclass;
-
-    // We maintain a list of subclasses so we can notify them when they need to update their layout.
-    private final Set<RubyClass> subClasses = Collections.newSetFromMap(new WeakHashMap<RubyClass, Boolean>());
-
-    /*
-     * The layout to use for instances of this class - do not confuse with objectLayout, which is
-     * the layout for this object - the class.
-     */
-    private ObjectLayout objectLayoutForInstances = null;
-
-    public RubyClass(RubyModule parentModule, RubyClass rubySuperclass, String name) {
-        this(parentModule, rubySuperclass, name, false);
-    }
-
-    public RubyClass(RubyModule parentModule, RubyClass rubySuperclass, String name, boolean isSingleton) {
-        this(rubySuperclass.getContext(), rubySuperclass.getContext().getCoreLibrary().getClassClass(), parentModule, rubySuperclass, name);
-
-        if (!isSingleton) {
-            getSingletonClass();
-        }
-    }
-
-    /**
-     * This constructor supports initialization and solves boot-order problems and should not
-     * normally be used from outside this class.
-     */
-    public RubyClass(RubyContext context, RubyClass classClass, RubyModule parentModule, RubyClass superclass, String name) {
-        super(context, classClass, parentModule, name);
-
-        if (superclass == null) {
-            objectLayoutForInstances = ObjectLayout.EMPTY;
-        } else {
-            unsafeSetSuperclass(superclass);
-        }
-    }
-
-    public RubyClass getSuperclass() {
-        assert superclass != null;
-        return superclass;
-    }
-
-    @Override
-    public RubyClass getSingletonClass() {
-        if (rubySingletonClass == null) {
-            RubyClass singletonSuperclass;
-
-            if (superclass == null) {
-                singletonSuperclass = getRubyClass();
-            } else {
-                singletonSuperclass = superclass.getSingletonClass();
-            }
-
-            rubySingletonClass = new RubyClass(getParentModule(), singletonSuperclass, String.format("#<Class:%s>", getName()), true);
-
-            lookupNode = new LookupFork(rubySingletonClass, lookupNode);
-        }
-
-        return rubySingletonClass;
-    }
-
-    /**
-     * This method supports initialization and solves boot-order problems and should not normally be
-     * used.
-     */
-    public void unsafeSetSuperclass(RubyClass newSuperclass) {
-        assert superclass == null;
-
-        superclass = newSuperclass;
-        superclass.addDependent(this);
-        superclass.subClasses.add(this);
-
-        include(superclass);
-
-        objectLayoutForInstances = new ObjectLayout(getName(), superclass.objectLayoutForInstances);
-    }
-
-    public RubyBasicObject newInstance() {
-        return new RubyObject(this);
-    }
-
-    /**
-     * Is an instance of this class assignable to some location expecting some other class?
-     */
-    public boolean assignableTo(RubyClass otherClass) {
-        if (this == otherClass) {
-            return true;
-        }
-
-        if (superclass == null) {
-            return false;
-        }
-
-        return superclass.assignableTo(otherClass);
-    }
-
-    /**
-     * Returns the object layout that objects of this class should use. Do not confuse with
-     * {@link #getObjectLayout}, which for {@link RubyClass} will return the layout of the class
-     * object itself.
-     */
-    public ObjectLayout getObjectLayoutForInstances() {
-        return objectLayoutForInstances;
-    }
-
-    /**
-     * Change the layout to be used for instances of this object.
-     */
-    public void setObjectLayoutForInstances(ObjectLayout newObjectLayoutForInstances) {
-        objectLayoutForInstances = newObjectLayoutForInstances;
-
-        for (RubyClass subClass : subClasses) {
-            subClass.renewObjectLayoutForInstances();
-        }
-    }
-
-    private void renewObjectLayoutForInstances() {
-        objectLayoutForInstances = objectLayoutForInstances.renew(superclass.objectLayoutForInstances);
-
-        for (RubyClass subClass : subClasses) {
-            subClass.renewObjectLayoutForInstances();
-        }
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/RubyContinuation.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,79 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.runtime.core;
-
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.control.*;
-import com.oracle.truffle.ruby.runtime.core.array.*;
-
-/**
- * Represents the Ruby {@code Continuation} class. We only support continuations that just move up
- * the stack and are one-shot.
- */
-public class RubyContinuation extends RubyObject {
-
-    /*
-     * A continuation is dead if we have already resumed it once. We will not be able to resume it
-     * again due to the current implementation being an exception thrown to go back up the stack.
-     */
-    private boolean dead = false;
-
-    public RubyContinuation(RubyClass rubyClass) {
-        super(rubyClass);
-    }
-
-    /**
-     * To enter a continuation means to remember the execution state at this point, reify that into
-     * an object, and then call the passed block. For our implementation, the continuation will be
-     * dead when this method resumes.
-     */
-    public Object enter(RubyProc block) {
-        try {
-            return block.call(null, this);
-        } catch (ContinuationReturnException e) {
-            // Thrown in call
-
-            // Check the exception is for this continuation
-
-            if (e.getContinuation() == this) {
-                return e.getValue();
-            } else {
-                throw e;
-            }
-        } finally {
-            dead = true;
-        }
-    }
-
-    /**
-     * To call a continuation means to go back to the execution state when it was created. For our
-     * implementation we can only do this once, and only if that means jumping back up the stack.
-     */
-    public void call(Object... args) {
-        if (dead) {
-            throw new UnsupportedOperationException("Only continuations that just move up the stack and are one-shot are supported");
-        }
-
-        Object returnValue;
-
-        if (args.length == 0) {
-            returnValue = NilPlaceholder.INSTANCE;
-        } else if (args.length == 1) {
-            returnValue = args[0];
-        } else {
-            returnValue = RubyArray.specializedFromObjects(getRubyClass().getContext().getCoreLibrary().getArrayClass(), args);
-        }
-
-        // Caught in enter
-
-        throw new ContinuationReturnException(this, returnValue);
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/RubyException.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,67 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.runtime.core;
-
-import com.oracle.truffle.ruby.runtime.objects.*;
-
-/**
- * Represents the Ruby {@code Exception} class.
- */
-public class RubyException extends RubyObject {
-
-    /**
-     * The class from which we create the object that is {@code Exception}. A subclass of
-     * {@link RubyClass} so that we can override {@link #newInstance} and allocate a
-     * {@link RubyException} rather than a normal {@link RubyBasicObject}.
-     */
-    public static class RubyExceptionClass extends RubyClass {
-
-        public RubyExceptionClass(RubyClass superClass, String name) {
-            super(null, superClass, name);
-        }
-
-        @Override
-        public RubyBasicObject newInstance() {
-            return new RubyException(this);
-        }
-
-    }
-
-    private RubyString message;
-
-    public RubyException(RubyClass rubyClass) {
-        super(rubyClass);
-        message = rubyClass.getContext().makeString("(object uninitialized)");
-    }
-
-    public RubyException(RubyClass rubyClass, String message) {
-        this(rubyClass, rubyClass.getContext().makeString(message));
-    }
-
-    public RubyException(RubyClass rubyClass, RubyString message) {
-        this(rubyClass);
-        initialize(message);
-    }
-
-    public void initialize(RubyString setMessage) {
-        assert setMessage != null;
-        message = setMessage;
-    }
-
-    public RubyString getMessage() {
-        return message;
-    }
-
-    @Override
-    public String toString() {
-        return message.toString();
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/RubyFalseClass.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,42 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.runtime.core;
-
-import com.oracle.truffle.ruby.runtime.objects.*;
-
-/**
- * Represents the Ruby {@code FalseClass} class.
- */
-public class RubyFalseClass extends RubyObject implements Unboxable {
-
-    public RubyFalseClass(RubyClass objectClass) {
-        super(objectClass);
-    }
-
-    public Object unbox() {
-        return false;
-    }
-
-    @Override
-    public String toString() {
-        return "false";
-    }
-
-    @Override
-    public boolean equals(Object other) {
-        return other instanceof RubyFalseClass || (other instanceof Boolean && !((boolean) other));
-    }
-
-    @Override
-    public int hashCode() {
-        return Boolean.FALSE.hashCode();
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/RubyFiber.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,173 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.runtime.core;
-
-import java.util.concurrent.*;
-
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.array.*;
-import com.oracle.truffle.ruby.runtime.objects.*;
-import com.oracle.truffle.ruby.runtime.subsystems.*;
-
-/**
- * Represents the Ruby {@code Fiber} class. The current implementation uses Java threads and message
- * passing. Note that the relationship between Java threads, Ruby threads and Ruby fibers is
- * complex. A Java thread might be running a fiber that on difference resumptions is representing
- * different Ruby threads. Take note of the lock contracts on {@link #waitForResume} and
- * {@link #resume}.
- */
-public class RubyFiber extends RubyObject {
-
-    public static class RubyFiberClass extends RubyClass {
-
-        public RubyFiberClass(RubyClass objectClass) {
-            super(null, objectClass, "Fiber");
-        }
-
-        @Override
-        public RubyBasicObject newInstance() {
-            return new RubyFiber(this, getContext().getFiberManager(), getContext().getThreadManager());
-        }
-
-    }
-
-    private interface FiberMessage {
-    }
-
-    private class FiberResumeMessage implements FiberMessage {
-
-        private final RubyThread thread;
-        private final RubyFiber sendingFiber;
-        private final Object arg;
-
-        public FiberResumeMessage(RubyThread thread, RubyFiber sendingFiber, Object arg) {
-            this.thread = thread;
-            this.sendingFiber = sendingFiber;
-            this.arg = arg;
-        }
-
-        public RubyThread getThread() {
-            return thread;
-        }
-
-        public RubyFiber getSendingFiber() {
-            return sendingFiber;
-        }
-
-        public Object getArg() {
-            return arg;
-        }
-
-    }
-
-    private class FiberExitMessage implements FiberMessage {
-    }
-
-    public class FiberExitException extends ControlFlowException {
-
-        private static final long serialVersionUID = 1522270454305076317L;
-
-    }
-
-    private final FiberManager fiberManager;
-    private final ThreadManager threadManager;
-
-    private BlockingQueue<FiberMessage> messageQueue = new ArrayBlockingQueue<>(1);
-    public RubyFiber lastResumedByFiber = null;
-
-    public RubyFiber(RubyClass rubyClass, FiberManager fiberManager, ThreadManager threadManager) {
-        super(rubyClass);
-        this.fiberManager = fiberManager;
-        this.threadManager = threadManager;
-    }
-
-    public void initialize(RubyProc block) {
-        final RubyFiber finalFiber = this;
-        final RubyProc finalBlock = block;
-
-        new Thread(new Runnable() {
-
-            @Override
-            public void run() {
-                fiberManager.registerFiber(finalFiber);
-
-                try {
-                    try {
-                        final Object arg = finalFiber.waitForResume();
-                        final Object result = finalBlock.call(null, arg);
-                        finalFiber.lastResumedByFiber.resume(finalFiber, result);
-                    } catch (FiberExitException e) {
-                        // Naturally exit the thread on catching this
-                    }
-                } finally {
-                    fiberManager.unregisterFiber(finalFiber);
-                }
-            }
-
-        }).start();
-    }
-
-    /**
-     * Send the Java thread that represents this fiber to sleep until it recieves a resume or exit
-     * message. On entry, assumes that the GIL is not held. On exit, holding the GIL.
-     */
-    public Object waitForResume() {
-        FiberMessage message = null;
-
-        do {
-            try {
-                // TODO(cs) what is a suitable timeout?
-                message = messageQueue.poll(1, TimeUnit.SECONDS);
-            } catch (InterruptedException e) {
-                // Poll again
-            }
-        } while (message == null);
-
-        if (message instanceof FiberExitMessage) {
-            throw new FiberExitException();
-        }
-
-        final FiberResumeMessage resumeMessage = (FiberResumeMessage) message;
-
-        threadManager.enterGlobalLock(resumeMessage.getThread());
-
-        fiberManager.setCurrentFiber(this);
-
-        lastResumedByFiber = resumeMessage.getSendingFiber();
-        return resumeMessage.getArg();
-    }
-
-    /**
-     * Send a message to a fiber by posting into a message queue. Doesn't explicitly notify the Java
-     * thread (although the queue implementation may) and doesn't wait for the message to be
-     * received. On entry, assumes the the GIL is held. On exit, not holding the GIL.
-     */
-    public void resume(RubyFiber sendingFiber, Object... args) {
-        Object arg;
-
-        if (args.length == 0) {
-            arg = NilPlaceholder.INSTANCE;
-        } else if (args.length == 1) {
-            arg = args[0];
-        } else {
-            arg = RubyArray.specializedFromObjects(getRubyClass().getContext().getCoreLibrary().getArrayClass(), args);
-        }
-
-        final RubyThread runningThread = threadManager.leaveGlobalLock();
-
-        messageQueue.add(new FiberResumeMessage(runningThread, sendingFiber, arg));
-    }
-
-    public void shutdown() {
-        messageQueue.add(new FiberExitMessage());
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/RubyFile.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,109 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.runtime.core;
-
-import java.io.*;
-
-import com.oracle.truffle.ruby.runtime.*;
-
-/**
- * Represents the Ruby {@code File} class.
- */
-public class RubyFile extends RubyObject {
-
-    private final Reader reader;
-    private final Writer writer;
-
-    public RubyFile(RubyClass rubyClass, Reader reader, Writer writer) {
-        super(rubyClass);
-        this.reader = reader;
-        this.writer = writer;
-    }
-
-    public void close() {
-        if (reader != null) {
-            try {
-                reader.close();
-            } catch (IOException e) {
-                throw new RuntimeException(e);
-            }
-        }
-
-        if (writer != null) {
-            try {
-                writer.close();
-            } catch (IOException e) {
-                throw new RuntimeException(e);
-            }
-        }
-    }
-
-    public static String expandPath(String fileName) {
-        // TODO(cs): see the other expandPath
-
-        try {
-            return new File(fileName).getCanonicalPath();
-        } catch (IOException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    public static String expandPath(String fileName, String dir) {
-        /*
-         * TODO(cs): this isn't quite correct - I think we want to collapse .., but we don't want to
-         * resolve symlinks etc. This might be where we want to start borrowing JRuby's
-         * implementation, but it looks quite tied to their data structures.
-         */
-
-        try {
-            return new File(dir, fileName).getCanonicalPath();
-        } catch (IOException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    public static RubyFile open(RubyContext context, String fileName, String mode) {
-        Reader reader;
-        Writer writer;
-
-        if (mode.equals("rb")) {
-            try {
-                reader = new InputStreamReader(new FileInputStream(fileName));
-            } catch (FileNotFoundException e) {
-                throw new RuntimeException(e);
-            }
-
-            writer = null;
-        } else if (mode.equals("w")) {
-            reader = null;
-
-            try {
-                writer = new OutputStreamWriter(new FileOutputStream(fileName));
-            } catch (FileNotFoundException e) {
-                throw new RuntimeException(e);
-            }
-        } else {
-            throw new UnsupportedOperationException();
-        }
-
-        final RubyFile file = new RubyFile(context.getCoreLibrary().getFileClass(), reader, writer);
-
-        return file;
-    }
-
-    public Reader getReader() {
-        return reader;
-    }
-
-    public Writer getWriter() {
-        return writer;
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/RubyFixnum.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,73 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.runtime.core;
-
-import java.math.*;
-
-import com.oracle.truffle.ruby.runtime.objects.*;
-
-/**
- * Represents the Ruby {@code Fixnum} class.
- */
-public class RubyFixnum extends RubyObject implements Unboxable {
-
-    public static final int MIN_VALUE = Integer.MIN_VALUE;
-    public static final int MAX_VALUE = Integer.MAX_VALUE;
-
-    public static final BigInteger MIN_VALUE_BIG = BigInteger.valueOf(MIN_VALUE);
-    public static final BigInteger MAX_VALUE_BIG = BigInteger.valueOf(MAX_VALUE);
-
-    public static final int SIZE = Integer.SIZE;
-
-    private final int value;
-
-    public RubyFixnum(RubyClass fixnumClass, int value) {
-        super(fixnumClass);
-        this.value = value;
-    }
-
-    public int getValue() {
-        return value;
-    }
-
-    @Override
-    public String toString() {
-        return Integer.toString(value);
-    }
-
-    @Override
-    public boolean equals(Object other) {
-        if (other instanceof Integer) {
-            return value == (int) other;
-        } else if (other instanceof RubyFixnum) {
-            return value == ((RubyFixnum) other).value;
-        } else if (other instanceof BigInteger) {
-            return ((BigInteger) other).equals(value);
-        } else if (other instanceof RubyBignum) {
-            return ((RubyBignum) other).getValue().equals(value);
-        } else if (other instanceof Double) {
-            return value == (double) other;
-        } else if (other instanceof RubyFloat) {
-            return value == ((RubyFloat) other).getValue();
-        } else {
-            return super.equals(other);
-        }
-    }
-
-    @Override
-    public int hashCode() {
-        throw new UnsupportedOperationException();
-    }
-
-    public Object unbox() {
-        return value;
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/RubyFloat.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,59 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.runtime.core;
-
-import com.oracle.truffle.ruby.runtime.objects.*;
-
-/**
- * Represents the Ruby {@code Float} class.
- */
-public class RubyFloat extends RubyObject implements Unboxable {
-
-    private final double value;
-
-    public RubyFloat(RubyClass floatClass, double value) {
-        super(floatClass);
-        this.value = value;
-    }
-
-    public double getValue() {
-        return value;
-    }
-
-    @Override
-    public String toString() {
-        return Double.toString(value);
-    }
-
-    @Override
-    public boolean equals(Object other) {
-        if (other instanceof Integer) {
-            return value == (int) other;
-        } else if (other instanceof RubyFixnum) {
-            return value == ((RubyFixnum) other).getValue();
-        } else if (other instanceof Double) {
-            return value == (double) other;
-        } else if (other instanceof RubyFloat) {
-            return value == ((RubyFloat) other).value;
-        } else {
-            return super.equals(other);
-        }
-    }
-
-    @Override
-    public int hashCode() {
-        throw new UnsupportedOperationException();
-    }
-
-    public Object unbox() {
-        return value;
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/RubyHash.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,127 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.runtime.core;
-
-import java.util.*;
-
-import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
-import com.oracle.truffle.ruby.runtime.objects.*;
-
-/**
- * Represents the Ruby {@code Hash} class.
- */
-public class RubyHash extends RubyObject {
-
-    /**
-     * The class from which we create the object that is {@code Hash}. A subclass of
-     * {@link RubyClass} so that we can override {@link #newInstance} and allocate a
-     * {@link RubyHash} rather than a normal {@link RubyBasicObject}.
-     */
-    public static class RubyHashClass extends RubyClass {
-
-        public RubyHashClass(RubyClass objectClass) {
-            super(null, objectClass, "Hash");
-        }
-
-        @Override
-        public RubyBasicObject newInstance() {
-            return new RubyHash(this);
-        }
-
-    }
-
-    public final Map<Object, Object> storage = new LinkedHashMap<>();
-    @CompilationFinal public RubyProc defaultBlock = null;
-
-    public RubyHash(RubyClass rubyClass, RubyProc defaultBlock) {
-        super(rubyClass);
-        initialize(defaultBlock);
-    }
-
-    public RubyHash(RubyClass rubyClass) {
-        super(rubyClass);
-    }
-
-    public void initialize(RubyProc setDefaultBlock) {
-        defaultBlock = setDefaultBlock;
-    }
-
-    @Override
-    public Object dup() {
-        final RubyHash newHash = new RubyHash(rubyClass);
-        newHash.setInstanceVariables(getInstanceVariables());
-        newHash.storage.putAll(storage);
-        return newHash;
-    }
-
-    public void put(Object key, Object value) {
-        checkFrozen();
-
-        storage.put(key, value);
-    }
-
-    public Object get(Object key) {
-        return storage.get(key);
-    }
-
-    public Map<Object, Object> getMap() {
-        return storage;
-    }
-
-    @Override
-    public String toString() {
-        final StringBuilder builder = new StringBuilder();
-        builder.append("{");
-
-        for (Map.Entry<Object, Object> entry : storage.entrySet()) {
-            if (builder.length() > 1) {
-                builder.append(", ");
-            }
-
-            builder.append(entry.getKey().toString());
-            builder.append("=>");
-            builder.append(entry.getValue().toString());
-        }
-
-        builder.append("}");
-        return builder.toString();
-    }
-
-    @Override
-    public int hashCode() {
-        final int prime = 31;
-        int result = 1;
-        result = prime * result + ((storage == null) ? 0 : storage.hashCode());
-        return result;
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj == null) {
-            return false;
-        }
-        if (!(obj instanceof RubyHash)) {
-            return false;
-        }
-        RubyHash other = (RubyHash) obj;
-        if (storage == null) {
-            if (other.storage != null) {
-                return false;
-            }
-        } else if (!storage.equals(other.storage)) {
-            return false;
-        }
-        return true;
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/RubyMatchData.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.runtime.core;
-
-/**
- * Represents the Ruby {@code MatchData} class.
- */
-public class RubyMatchData extends RubyObject {
-
-    private final Object[] values;
-
-    public RubyMatchData(RubyClass rubyClass, Object[] values) {
-        super(rubyClass);
-        this.values = values;
-    }
-
-    public Object[] valuesAt(int... indices) {
-        final Object[] result = new Object[indices.length];
-
-        for (int n = 0; n < indices.length; n++) {
-            result[n] = values[indices[n]];
-        }
-
-        return result;
-    }
-
-    public Object[] getValues() {
-        return values;
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/RubyModule.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,381 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.runtime.core;
-
-import java.util.*;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.utilities.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.lookup.*;
-import com.oracle.truffle.ruby.runtime.methods.*;
-import com.oracle.truffle.ruby.runtime.objects.*;
-
-/**
- * Represents the Ruby {@code Module} class.
- */
-public class RubyModule extends RubyObject implements LookupNode {
-
-    /**
-     * The class from which we create the object that is {@code Module}. A subclass of
-     * {@link RubyClass} so that we can override {@link #newInstance} and allocate a
-     * {@link RubyModule} rather than a normal {@link RubyBasicObject}.
-     */
-    public static class RubyModuleClass extends RubyClass {
-
-        public RubyModuleClass(RubyContext context) {
-            super(context, null, null, null, "Module");
-        }
-
-        @Override
-        public RubyBasicObject newInstance() {
-            return new RubyModule(this, null, "(unnamed module)");
-        }
-
-    }
-
-    /**
-     * The slot within a module definition method frame where we store the implicit state that is
-     * the current visibility for new methods.
-     */
-    public static final Object VISIBILITY_FRAME_SLOT_ID = new Object();
-
-    /**
-     * The slot within a module definition method frame where we store the implicit state that is
-     * the flag for whether or not new methods will be module methods (functions is the term).
-     */
-    public static final Object MODULE_FUNCTION_FLAG_FRAME_SLOT_ID = new Object();
-
-    // The context is stored here - objects can obtain it via their class (which is a module)
-    private final RubyContext context;
-
-    /*
-     * The module in which this module was defined. By analogy, if superclass is the dynamic scope,
-     * the parent module is the lexical scope.
-     */
-    private final RubyModule parentModule;
-
-    /*
-     * The first thing to lookup names in. Not always the class, as we also have singleton classes,
-     * included modules etc.
-     */
-    private LookupNode lookupParent = LookupTerminal.INSTANCE;
-
-    private final String name;
-    private final Map<String, RubyMethod> methods = new HashMap<>();
-    private final Map<String, Object> constants = new HashMap<>();
-    private final Map<String, Object> classVariables = new HashMap<>();
-
-    private final CyclicAssumption unmodifiedAssumption;
-
-    /**
-     * Keep track of other modules that depend on the configuration of this module in some way. The
-     * include subclasses and modules that include this module.
-     */
-    private final Set<RubyModule> dependents = Collections.newSetFromMap(new WeakHashMap<RubyModule, Boolean>());
-
-    public RubyModule(RubyClass rubyClass, RubyModule parentModule, String name) {
-        this(rubyClass.getContext(), rubyClass, parentModule, name);
-    }
-
-    public RubyModule(RubyContext context, RubyClass rubyClass, RubyModule parentModule, String name) {
-        super(rubyClass);
-
-        this.context = context;
-        this.parentModule = parentModule;
-        this.name = name;
-
-        unmodifiedAssumption = new CyclicAssumption(name + " is unmodified");
-
-        /*
-         * Modules always go into the object space manager. Manually allocate an objectID, because
-         * the lazy mechanism uses the Ruby class of the object, which may not be set yet during
-         * bootstrap.
-         */
-
-        objectID = context.getNextObjectID();
-        context.getObjectSpaceManager().add(this);
-    }
-
-    public RubyModule getParentModule() {
-        return parentModule;
-    }
-
-    public void include(RubyModule module) {
-        checkFrozen();
-
-        lookupParent = new LookupFork(module, lookupParent);
-        newVersion();
-        module.addDependent(this);
-    }
-
-    /**
-     * Set the value of a constant, possibly redefining it.
-     */
-    public void setConstant(String constantName, Object value) {
-        assert RubyContext.shouldObjectBeVisible(value);
-
-        checkFrozen();
-
-        getConstants().put(constantName, value);
-        newVersion();
-        // TODO(CS): warn when redefining a constant
-    }
-
-    public void setClassVariable(String variableName, Object value) {
-        assert RubyContext.shouldObjectBeVisible(value);
-
-        checkFrozen();
-
-        if (!setClassVariableIfAlreadySet(variableName, value)) {
-            classVariables.put(variableName, value);
-        }
-    }
-
-    public boolean setClassVariableIfAlreadySet(String variableName, Object value) {
-        assert RubyContext.shouldObjectBeVisible(value);
-
-        checkFrozen();
-
-        if (lookupParent.setClassVariableIfAlreadySet(variableName, value)) {
-            return true;
-        }
-
-        if (classVariables.containsKey(variableName)) {
-            classVariables.put(variableName, value);
-            return true;
-        }
-
-        return false;
-    }
-
-    public void removeClassVariable(String variableName) {
-        checkFrozen();
-
-        classVariables.remove(variableName);
-    }
-
-    public void setModuleConstant(String constantName, Object value) {
-        checkFrozen();
-
-        setConstant(constantName, value);
-        getSingletonClass().setConstant(constantName, value);
-    }
-
-    public void addMethod(RubyMethod method) {
-        checkFrozen();
-        getMethods().put(method.getName(), method);
-        newVersion();
-    }
-
-    /**
-     * Remove a method from this module.
-     */
-    public void removeMethod(String methodName) {
-        checkFrozen();
-
-        getMethods().remove(methodName);
-        newVersion();
-    }
-
-    public void undefMethod(String methodName) {
-        undefMethod(lookupMethod(methodName));
-    }
-
-    public void undefMethod(RubyMethod method) {
-        addMethod(method.undefined());
-    }
-
-    /**
-     * Alias a method.
-     */
-    public void alias(String newName, String oldName) {
-        final RubyMethod method = lookupMethod(oldName);
-
-        if (method == null) {
-            CompilerDirectives.transferToInterpreter();
-            throw new RuntimeException("Couldn't alias as coudln't find " + oldName);
-        }
-
-        addMethod(method.withNewName(newName));
-    }
-
-    @Override
-    public Object lookupConstant(String constantName) {
-        Object value;
-
-        // Look in this module
-
-        value = getConstants().get(constantName);
-
-        if (value != null) {
-            return value;
-        }
-
-        // Look in the parent module
-
-        if (parentModule != null) {
-            value = parentModule.lookupConstant(constantName);
-
-            if (value != null) {
-                return value;
-            }
-        }
-
-        // Look in the lookup parent
-
-        return lookupParent.lookupConstant(constantName);
-    }
-
-    @Override
-    public Object lookupClassVariable(String variableName) {
-        // Look in this module
-
-        final Object value = classVariables.get(variableName);
-
-        if (value != null) {
-            return value;
-        }
-
-        // Look in the parent
-
-        return lookupParent.lookupClassVariable(variableName);
-    }
-
-    public Set<String> getClassVariables() {
-        final Set<String> classVariablesSet = new HashSet<>();
-
-        classVariablesSet.addAll(classVariables.keySet());
-        classVariablesSet.addAll(lookupParent.getClassVariables());
-
-        return classVariablesSet;
-    }
-
-    @Override
-    public RubyMethod lookupMethod(String methodName) {
-        // Look in this module
-
-        final RubyMethod method = getMethods().get(methodName);
-
-        if (method != null) {
-            return method;
-        }
-
-        // Look in the parent
-
-        return lookupParent.lookupMethod(methodName);
-    }
-
-    public void appendFeatures(RubyModule other) {
-        // TODO(CS): check only run once
-
-        for (Map.Entry<String, Object> constantEntry : getConstants().entrySet()) {
-            final String constantName = constantEntry.getKey();
-            final Object constantValue = constantEntry.getValue();
-            other.setModuleConstant(constantName, constantValue);
-        }
-
-        for (Map.Entry<String, RubyMethod> methodEntry : getMethods().entrySet()) {
-            final String methodName = methodEntry.getKey();
-            final RubyMethod method = methodEntry.getValue();
-            other.addMethod(method.withNewName(methodName));
-        }
-    }
-
-    public RubyContext getContext() {
-        return context;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    @Override
-    public int hashCode() {
-        return name.hashCode();
-    }
-
-    @Override
-    public String toString() {
-        return name;
-    }
-
-    public void newVersion() {
-        unmodifiedAssumption.invalidate();
-
-        // Make dependents new versions
-
-        for (RubyModule dependent : dependents) {
-            dependent.newVersion();
-        }
-    }
-
-    public void addDependent(RubyModule dependent) {
-        dependents.add(dependent);
-    }
-
-    public Assumption getUnmodifiedAssumption() {
-        return unmodifiedAssumption.getAssumption();
-    }
-
-    public void getMethods(Map<String, RubyMethod> foundMethods) {
-        lookupParent.getMethods(foundMethods);
-
-        for (RubyMethod method : methods.values()) {
-            foundMethods.put(method.getName(), method);
-        }
-    }
-
-    public static void setCurrentVisibility(Frame frame, Visibility visibility) {
-        final FrameSlot slot = frame.getFrameDescriptor().findFrameSlot(VISIBILITY_FRAME_SLOT_ID);
-
-        frame.setObject(slot, visibility);
-    }
-
-    public void visibilityMethod(PackedFrame frame, Object[] arguments, Visibility visibility) {
-        if (arguments.length == 0) {
-            setCurrentVisibility(frame.unpack(), visibility);
-        } else {
-            for (Object arg : arguments) {
-                final RubyMethod method = lookupMethod(arg.toString());
-
-                if (method == null) {
-                    throw new RuntimeException("Couldn't find method " + arg.toString());
-                }
-
-                /*
-                 * If the method was already defined in this class, that's fine {@link addMethod}
-                 * will overwrite it, otherwise we do actually want to add a copy of the method with
-                 * a different visibility to this module.
-                 */
-
-                addMethod(method.withNewVisibility(visibility));
-            }
-        }
-    }
-
-    public List<RubyMethod> getDeclaredMethods() {
-        return new ArrayList<>(getMethods().values());
-    }
-
-    public void moduleEval(String source) {
-        getRubyClass().getContext().eval(source, this);
-    }
-
-    public Map<String, Object> getConstants() {
-        return constants;
-    }
-
-    public Map<String, RubyMethod> getMethods() {
-        return methods;
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/RubyNilClass.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,42 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.runtime.core;
-
-import com.oracle.truffle.ruby.runtime.*;
-
-/**
- * Represents the Ruby {@code NilClass} class.
- */
-public class RubyNilClass extends RubyObject {
-
-    public RubyNilClass(RubyClass rubyClass) {
-        super(rubyClass);
-    }
-
-    @Override
-    public boolean equals(Object other) {
-        return other instanceof RubyNilClass || other instanceof NilPlaceholder;
-    }
-
-    @Override
-    public int hashCode() {
-        return 0;
-    }
-
-    public static boolean isNil(Object block) {
-        return block instanceof NilPlaceholder || block instanceof RubyNilClass;
-    }
-
-    @Override
-    public String toString() {
-        return "";
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/RubyObject.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,49 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.runtime.core;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.control.*;
-import com.oracle.truffle.ruby.runtime.objects.*;
-
-/**
- * Represents the Ruby {@code Object} class.
- */
-public class RubyObject extends RubyBasicObject {
-
-    public boolean frozen = false;
-
-    public RubyObject(RubyClass rubyClass) {
-        super(rubyClass);
-    }
-
-    public void checkFrozen() {
-        if (frozen) {
-            CompilerDirectives.transferToInterpreter();
-            throw new RaiseException(getRubyClass().getContext().getCoreLibrary().frozenError(getRubyClass().getName().toLowerCase()));
-        }
-    }
-
-    public Object dup() {
-        final RubyObject newObject = new RubyObject(rubyClass);
-        newObject.setInstanceVariables(getInstanceVariables());
-        return newObject;
-    }
-
-    public static String checkInstanceVariableName(RubyContext context, String name) {
-        if (!name.startsWith("@")) {
-            throw new RaiseException(context.getCoreLibrary().nameErrorInstanceNameNotAllowable(name));
-        }
-
-        return name.substring(1);
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/RubyProc.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,108 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.runtime.core;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.control.*;
-import com.oracle.truffle.ruby.runtime.methods.*;
-import com.oracle.truffle.ruby.runtime.objects.*;
-
-/**
- * Represents the Ruby {@code Proc} class.
- */
-public class RubyProc extends RubyObject {
-
-    /**
-     * The class from which we create the object that is {@code Proc}. A subclass of
-     * {@link RubyClass} so that we can override {@link #newInstance} and allocate a
-     * {@link RubyProc} rather than a normal {@link RubyBasicObject}.
-     */
-    public static class RubyProcClass extends RubyClass {
-
-        public RubyProcClass(RubyClass objectClass) {
-            super(null, objectClass, "Proc");
-        }
-
-        @Override
-        public RubyBasicObject newInstance() {
-            return new RubyProc(this);
-        }
-
-    }
-
-    public static enum Type {
-        PROC, LAMBDA
-    }
-
-    @CompilationFinal private Type type;
-    @CompilationFinal private Object self;
-    @CompilationFinal private RubyProc block;
-    @CompilationFinal private RubyMethod method;
-
-    public RubyProc(RubyClass procClass) {
-        super(procClass);
-    }
-
-    public RubyProc(RubyClass procClass, Type type, Object self, RubyProc block, RubyMethod method) {
-        super(procClass);
-        initialize(type, self, block, method);
-    }
-
-    public void initialize(Type setType, Object setSelf, RubyProc setBlock, RubyMethod setMethod) {
-        assert setSelf != null;
-        assert RubyContext.shouldObjectBeVisible(setSelf);
-        type = setType;
-        self = setSelf;
-        block = setBlock;
-        method = setMethod;
-    }
-
-    public Object getSelf() {
-        return self;
-    }
-
-    @CompilerDirectives.SlowPath
-    public Object call(PackedFrame caller, Object... args) {
-        return callWithModifiedSelf(caller, self, args);
-    }
-
-    public Object callWithModifiedSelf(PackedFrame caller, Object modifiedSelf, Object... args) {
-        assert modifiedSelf != null;
-
-        try {
-            return method.call(caller, modifiedSelf, block, args);
-        } catch (ReturnException e) {
-            switch (type) {
-                case PROC:
-                    throw e;
-                case LAMBDA:
-                    return e.getValue();
-                default:
-                    throw new IllegalStateException();
-            }
-        }
-    }
-
-    public RubyMethod getMethod() {
-        return method;
-    }
-
-    public Type getType() {
-        return type;
-    }
-
-    public RubyProc getBlock() {
-        return block;
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/RubyRegexp.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,144 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.runtime.core;
-
-import java.util.regex.*;
-
-import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.objects.*;
-
-/**
- * Represents the Ruby {@code Regexp} class.
- */
-public class RubyRegexp extends RubyObject {
-
-    /**
-     * The class from which we create the object that is {@code Regexp}. A subclass of
-     * {@link RubyClass} so that we can override {@link #newInstance} and allocate a
-     * {@link RubyRegexp} rather than a normal {@link RubyBasicObject}.
-     */
-    public static class RubyRegexpClass extends RubyClass {
-
-        public RubyRegexpClass(RubyClass objectClass) {
-            super(null, objectClass, "Regexp");
-        }
-
-        @Override
-        public RubyBasicObject newInstance() {
-            return new RubyRegexp(getContext().getCoreLibrary().getRegexpClass());
-        }
-
-    }
-
-    @CompilationFinal private Pattern pattern;
-
-    public RubyRegexp(RubyClass regexpClass) {
-        super(regexpClass);
-    }
-
-    public RubyRegexp(RubyClass regexpClass, String pattern) {
-        this(regexpClass);
-        initialize(compile(pattern));
-    }
-
-    public RubyRegexp(RubyClass regexpClass, Pattern pattern) {
-        this(regexpClass);
-        initialize(pattern);
-    }
-
-    public void initialize(String setPattern) {
-        pattern = compile(setPattern);
-    }
-
-    public void initialize(Pattern setPattern) {
-        pattern = setPattern;
-    }
-
-    public Object matchOperator(Frame frame, String string) {
-        final RubyContext context = getRubyClass().getContext();
-
-        final Matcher matcher = pattern.matcher(string);
-
-        if (matcher.find()) {
-            for (int n = 1; n < matcher.groupCount() + 1; n++) {
-                final FrameSlot slot = frame.getFrameDescriptor().findFrameSlot("$" + n);
-
-                if (slot != null) {
-                    frame.setObject(slot, context.makeString(matcher.group(n)));
-                }
-            }
-
-            return matcher.start();
-        } else {
-            return NilPlaceholder.INSTANCE;
-        }
-    }
-
-    public Pattern getPattern() {
-        return pattern;
-    }
-
-    public Object match(String string) {
-        final RubyContext context = getRubyClass().getContext();
-
-        final Matcher matcher = pattern.matcher(string);
-
-        if (!matcher.find()) {
-            return NilPlaceholder.INSTANCE;
-        }
-
-        final Object[] values = new Object[matcher.groupCount() + 1];
-
-        for (int n = 0; n < matcher.groupCount() + 1; n++) {
-            final String group = matcher.group(n);
-
-            if (group == null) {
-                values[n] = NilPlaceholder.INSTANCE;
-            } else {
-                values[n] = context.makeString(group);
-            }
-        }
-
-        return new RubyMatchData(context.getCoreLibrary().getMatchDataClass(), values);
-    }
-
-    @Override
-    public int hashCode() {
-        return pattern.pattern().hashCode();
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj == null) {
-            return false;
-        }
-        if (!(obj instanceof RubyRegexp)) {
-            return false;
-        }
-        RubyRegexp other = (RubyRegexp) obj;
-        if (pattern == null) {
-            if (other.pattern != null) {
-                return false;
-            }
-        } else if (!pattern.pattern().equals(other.pattern.pattern())) {
-            return false;
-        }
-        return true;
-    }
-
-    public static Pattern compile(String pattern) {
-        return Pattern.compile(pattern, Pattern.MULTILINE | Pattern.UNIX_LINES);
-    }
-}
--- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/RubyString.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,291 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.runtime.core;
-
-import java.math.*;
-import java.nio.*;
-import java.nio.charset.*;
-import java.util.*;
-import java.util.regex.*;
-
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.array.*;
-import com.oracle.truffle.ruby.runtime.core.range.*;
-import com.oracle.truffle.ruby.runtime.objects.*;
-
-/**
- * Represents the Ruby {@code String} class.
- */
-public class RubyString extends RubyObject {
-
-    /**
-     * The class from which we create the object that is {@code String}. A subclass of
-     * {@link RubyClass} so that we can override {@link #newInstance} and allocate a
-     * {@link RubyString} rather than a normal {@link RubyBasicObject}.
-     */
-    public static class RubyStringClass extends RubyClass {
-
-        public RubyStringClass(RubyClass objectClass) {
-            super(null, objectClass, "String");
-        }
-
-        @Override
-        public RubyBasicObject newInstance() {
-            return new RubyString(getContext().getCoreLibrary().getStringClass(), "");
-        }
-
-    }
-
-    private boolean fromJavaString;
-
-    private Charset encoding;
-    private byte[] bytes;
-
-    private String cachedStringValue;
-
-    /**
-     * Construct a string from a Java {@link String}, lazily converting to bytes as needed.
-     */
-    public RubyString(RubyClass stringClass, String value) {
-        super(stringClass);
-        fromJavaString = true;
-        encoding = null;
-        bytes = null;
-        cachedStringValue = value;
-    }
-
-    /**
-     * Construct a string from bytes representing characters in an encoding, lazily converting to a
-     * Java {@link String} as needed.
-     */
-    public RubyString(RubyClass stringClass, Charset encoding, byte[] bytes) {
-        super(stringClass);
-        fromJavaString = false;
-        this.encoding = encoding;
-        this.bytes = bytes;
-        cachedStringValue = null;
-    }
-
-    public RubyString(RubyString copyOf) {
-        super(copyOf.getRubyClass().getContext().getCoreLibrary().getStringClass());
-        fromJavaString = copyOf.fromJavaString;
-        encoding = copyOf.encoding;
-
-        if (copyOf.bytes != null) {
-            bytes = Arrays.copyOf(copyOf.bytes, copyOf.bytes.length);
-        } else {
-            bytes = null;
-        }
-
-        cachedStringValue = copyOf.cachedStringValue;
-    }
-
-    public boolean isFromJavaString() {
-        return fromJavaString;
-    }
-
-    public byte[] getBytes() {
-        return bytes;
-    }
-
-    public void replace(String value) {
-        fromJavaString = true;
-        encoding = null;
-        bytes = null;
-        cachedStringValue = value;
-    }
-
-    @Override
-    public String toString() {
-        if (cachedStringValue == null) {
-            cachedStringValue = encoding.decode(ByteBuffer.wrap(bytes)).toString();
-        }
-
-        return cachedStringValue;
-    }
-
-    @Override
-    public boolean equals(Object other) {
-        if (other == null) {
-            return false;
-        }
-
-        // If the other value is a Java string, use our Java string representation to compare
-
-        if (other instanceof String) {
-            return toString().equals(other);
-        }
-
-        if (other instanceof RubyString) {
-            final RubyString otherString = (RubyString) other;
-
-            // If we both came from Java strings, use them to compare
-
-            if (fromJavaString && otherString.fromJavaString) {
-                return toString().equals(other.toString());
-            }
-
-            // If we both have the same encoding, compare bytes
-
-            if (encoding == otherString.encoding) {
-                return Arrays.equals(bytes, otherString.bytes);
-            }
-
-            // If we don't have the same encoding, we need some more advanced logic
-
-            throw new UnsupportedOperationException("Can't compare strings in different encodings yet");
-        }
-
-        return false;
-    }
-
-    @Override
-    public int hashCode() {
-        return toString().hashCode();
-    }
-
-    public static Object getIndex(RubyContext context, String string, Object[] args) {
-        if (args.length == 1) {
-            final Object index = args[0];
-
-            if (index instanceof Integer) {
-                final int stringLength = string.length();
-                final int normalisedIndex = ArrayUtilities.normaliseIndex(stringLength, (int) index);
-
-                return context.makeString(string.charAt(normalisedIndex));
-            } else if (index instanceof FixnumRange) {
-                final FixnumRange range = (FixnumRange) index;
-
-                final int stringLength = string.length();
-
-                if (range.doesExcludeEnd()) {
-                    final int begin = ArrayUtilities.normaliseIndex(stringLength, range.getBegin());
-                    final int exclusiveEnd = ArrayUtilities.normaliseExclusiveIndex(stringLength, range.getExclusiveEnd());
-                    return context.makeString(string.substring(begin, exclusiveEnd));
-                } else {
-                    final int begin = ArrayUtilities.normaliseIndex(stringLength, range.getBegin());
-                    final int inclusiveEnd = ArrayUtilities.normaliseIndex(stringLength, range.getInclusiveEnd());
-                    return context.makeString(string.substring(begin, inclusiveEnd + 1));
-                }
-            } else {
-                throw new UnsupportedOperationException("Don't know how to index a string with " + index.getClass());
-            }
-        } else {
-            final int rangeStart = (int) args[0];
-            int rangeLength = (int) args[1];
-
-            if (rangeLength > string.length() - rangeStart) {
-                rangeLength = string.length() - rangeStart;
-            }
-
-            if (rangeStart > string.length()) {
-                return NilPlaceholder.INSTANCE;
-            }
-
-            return context.makeString(string.substring(rangeStart, rangeStart + rangeLength));
-        }
-    }
-
-    @Override
-    public Object dup() {
-        return new RubyString(this);
-    }
-
-    public void concat(RubyString other) {
-        if (fromJavaString && other.fromJavaString) {
-            cachedStringValue += other.cachedStringValue;
-            encoding = null;
-            bytes = null;
-        } else {
-            throw new UnsupportedOperationException("Don't know how to append strings with encodings");
-        }
-    }
-
-    public static String ljust(String string, int length, String padding) {
-        final StringBuilder builder = new StringBuilder();
-
-        builder.append(string);
-
-        int n = 0;
-
-        while (builder.length() < length) {
-            builder.append(padding.charAt(n));
-
-            n++;
-
-            if (n == padding.length()) {
-                n = 0;
-            }
-        }
-
-        return builder.toString();
-    }
-
-    public static String rjust(String string, int length, String padding) {
-        final StringBuilder builder = new StringBuilder();
-
-        int n = 0;
-
-        while (builder.length() + string.length() < length) {
-            builder.append(padding.charAt(n));
-
-            n++;
-
-            if (n == padding.length()) {
-                n = 0;
-            }
-        }
-
-        builder.append(string);
-
-        return builder.toString();
-    }
-
-    public static RubyArray scan(RubyContext context, String string, Pattern pattern) {
-        final Matcher matcher = pattern.matcher(string);
-
-        final RubyArray results = new RubyArray(context.getCoreLibrary().getArrayClass());
-
-        while (matcher.find()) {
-            if (matcher.groupCount() == 0) {
-                results.push(context.makeString(matcher.group(0)));
-            } else {
-                final RubyArray subResults = new RubyArray(context.getCoreLibrary().getArrayClass());
-
-                for (int n = 1; n < matcher.groupCount() + 1; n++) {
-                    subResults.push(context.makeString(matcher.group(n)));
-                }
-
-                results.push(subResults);
-            }
-        }
-
-        return results;
-    }
-
-    public Object toInteger() {
-        if (toString().length() == 0) {
-            return 0;
-        }
-
-        try {
-            final int value = Integer.parseInt(toString());
-
-            if (value >= RubyFixnum.MIN_VALUE && value <= RubyFixnum.MAX_VALUE) {
-                return value;
-            } else {
-                return BigInteger.valueOf(value);
-            }
-        } catch (NumberFormatException e) {
-            return new BigInteger(toString());
-        }
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/RubySymbol.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,82 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.runtime.core;
-
-import java.util.*;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.methods.*;
-import com.oracle.truffle.ruby.runtime.objects.*;
-
-/**
- * Represents the Ruby {@code Symbol} class.
- */
-public class RubySymbol extends RubyObject {
-
-    private final String symbol;
-
-    public RubySymbol(RubyClass symbolClass, String symbol) {
-        super(symbolClass);
-        this.symbol = symbol.intern();
-    }
-
-    public RubyProc toProc() {
-        final RubyContext context = getRubyClass().getContext();
-
-        final CallTarget callTarget = new CallTarget() {
-
-            @Override
-            public Object call(PackedFrame frame, Arguments args) {
-                final RubyArguments rubyArgs = (RubyArguments) args;
-                final Object receiver = rubyArgs.getArguments()[0];
-                final Object[] sendArgs = Arrays.copyOfRange(rubyArgs.getArguments(), 1, rubyArgs.getArguments().length);
-                final RubyBasicObject receiverObject = context.getCoreLibrary().box(receiver);
-                return receiverObject.send(symbol, rubyArgs.getBlock(), sendArgs);
-            }
-
-        };
-
-        final CallTargetMethodImplementation methodImplementation = new CallTargetMethodImplementation(callTarget, null);
-        final RubyMethod method = new RubyMethod(null, null, new UniqueMethodIdentifier(), symbol, null, Visibility.PUBLIC, false, methodImplementation);
-
-        return new RubyProc(context.getCoreLibrary().getProcClass(), RubyProc.Type.PROC, NilPlaceholder.INSTANCE, null, method);
-    }
-
-    @Override
-    public String toString() {
-        return symbol;
-    }
-
-    @Override
-    public String inspect() {
-        return ":" + symbol;
-    }
-
-    @Override
-    public int hashCode() {
-        return symbol.hashCode();
-    }
-
-    @Override
-    public boolean equals(Object other) {
-        if (other == this) {
-            return true;
-        } else if (other instanceof RubySymbol) {
-            return symbol == ((RubySymbol) other).symbol;
-        } else if (other instanceof RubyString) {
-            return other.equals(symbol);
-        } else {
-            return super.equals(other);
-        }
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/RubyThread.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,115 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.runtime.core;
-
-import java.util.*;
-import java.util.concurrent.*;
-
-import com.oracle.truffle.ruby.runtime.objects.*;
-import com.oracle.truffle.ruby.runtime.subsystems.*;
-
-/**
- * Represents the Ruby {@code Thread} class. Implemented using Java threads, but note that there is
- * not a one-to-one mapping between Ruby threads and Java threads - specifically in combination with
- * fibers as they are currently implemented as their own Java threads.
- */
-public class RubyThread extends RubyObject {
-
-    /**
-     * The class from which we create the object that is {@code Thread}. A subclass of
-     * {@link RubyClass} so that we can override {@link #newInstance} and allocate a
-     * {@link RubyThread} rather than a normal {@link RubyBasicObject}.
-     */
-    public static class RubyThreadClass extends RubyClass {
-
-        public RubyThreadClass(RubyClass objectClass) {
-            super(null, objectClass, "Thread");
-        }
-
-        @Override
-        public RubyBasicObject newInstance() {
-            return new RubyThread(this, getContext().getThreadManager());
-        }
-
-    }
-
-    private final ThreadManager manager;
-
-    private final CountDownLatch finished = new CountDownLatch(1);
-
-    private final int hashCode = new Random().nextInt();
-
-    public RubyThread(RubyClass rubyClass, ThreadManager manager) {
-        super(rubyClass);
-        this.manager = manager;
-    }
-
-    public void initialize(RubyProc block) {
-        final RubyProc finalBlock = block;
-
-        initialize(new Runnable() {
-
-            @Override
-            public void run() {
-                finalBlock.call(null);
-            }
-
-        });
-    }
-
-    public void initialize(Runnable runnable) {
-        final RubyThread finalThread = this;
-        final Runnable finalRunnable = runnable;
-
-        new Thread(new Runnable() {
-
-            @Override
-            public void run() {
-                finalThread.manager.registerThread(finalThread);
-                finalThread.manager.enterGlobalLock(finalThread);
-
-                try {
-                    finalRunnable.run();
-                } finally {
-                    finalThread.manager.leaveGlobalLock();
-                    finalThread.manager.unregisterThread(finalThread);
-                    finalThread.finished.countDown();
-                }
-            }
-
-        }).start();
-    }
-
-    @Override
-    public int hashCode() {
-        return hashCode;
-    }
-
-    public void shutdown() {
-    }
-
-    public void join() {
-        final RubyThread runningThread = getRubyClass().getContext().getThreadManager().leaveGlobalLock();
-
-        try {
-            while (true) {
-                try {
-                    finished.await();
-                    break;
-                } catch (InterruptedException e) {
-                    // Await again
-                }
-            }
-        } finally {
-            runningThread.manager.enterGlobalLock(runningThread);
-        }
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/RubyTime.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,85 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.runtime.core;
-
-import java.text.*;
-import java.util.*;
-
-import com.oracle.truffle.ruby.runtime.objects.*;
-
-/**
- * Represents the Ruby {@code Time} class. This is a very rough implementation and is only really
- * enough to run benchmark harnesses.
- */
-public class RubyTime extends RubyObject {
-
-    /**
-     * The class from which we create the object that is {@code Time}. A subclass of
-     * {@link RubyClass} so that we can override {@link #newInstance} and allocate a
-     * {@link RubyTime} rather than a normal {@link RubyBasicObject}.
-     */
-    public static class RubyTimeClass extends RubyClass {
-
-        public RubyTimeClass(RubyClass objectClass) {
-            super(null, objectClass, "Time");
-        }
-
-        @Override
-        public RubyBasicObject newInstance() {
-            return new RubyTime(this, milisecondsToNanoseconds(System.currentTimeMillis()));
-        }
-
-    }
-
-    private final long nanoseconds;
-
-    public RubyTime(RubyClass timeClass, long nanoseconds) {
-        super(timeClass);
-        this.nanoseconds = nanoseconds;
-    }
-
-    /**
-     * Subtract one time from another, producing duration in seconds.
-     */
-    public double subtract(RubyTime other) {
-        return nanosecondsToSecond(nanoseconds - other.nanoseconds);
-    }
-
-    @Override
-    public String toString() {
-        /*
-         * I think this is ISO 8601 with a custom time part. Note that Ruby's time formatting syntax
-         * is different to Java's.
-         */
-
-        return new SimpleDateFormat("Y-MM-d H:m:ss Z").format(toDate());
-    }
-
-    private Date toDate() {
-        return new Date(nanosecondsToMiliseconds(nanoseconds));
-    }
-
-    public static RubyTime fromDate(RubyClass timeClass, long timeMiliseconds) {
-        return new RubyTime(timeClass, milisecondsToNanoseconds(timeMiliseconds));
-    }
-
-    private static long milisecondsToNanoseconds(long miliseconds) {
-        return miliseconds * 1000000;
-    }
-
-    private static long nanosecondsToMiliseconds(long nanoseconds) {
-        return nanoseconds / 1000000;
-    }
-
-    private static double nanosecondsToSecond(long nanoseconds) {
-        return nanoseconds / 1e9;
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/RubyTrueClass.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,42 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.runtime.core;
-
-import com.oracle.truffle.ruby.runtime.objects.*;
-
-/**
- * Represents the Ruby {@code TrueClass} class.
- */
-public class RubyTrueClass extends RubyObject implements Unboxable {
-
-    public RubyTrueClass(RubyClass objectClass) {
-        super(objectClass);
-    }
-
-    public Object unbox() {
-        return true;
-    }
-
-    @Override
-    public String toString() {
-        return "true";
-    }
-
-    @Override
-    public boolean equals(Object other) {
-        return other instanceof RubyTrueClass || (other instanceof Boolean && (boolean) other);
-    }
-
-    @Override
-    public int hashCode() {
-        return Boolean.TRUE.hashCode();
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/StringFormatter.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,157 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.runtime.core;
-
-import java.io.*;
-import java.util.*;
-
-import com.oracle.truffle.ruby.runtime.core.array.*;
-
-public class StringFormatter {
-
-    public static String format(String format, List<Object> values) {
-        final ByteArrayOutputStream byteArray = new ByteArrayOutputStream();
-        final PrintStream printStream = new PrintStream(byteArray);
-
-        format(printStream, format, values);
-
-        return byteArray.toString();
-    }
-
-    public static void format(PrintStream stream, String format, List<Object> values) {
-        /*
-         * See http://www.ruby-doc.org/core-1.9.3/Kernel.html#method-i-sprintf.
-         * 
-         * At the moment we just do the basics that we need. We will need a proper lexer later on.
-         * Or better than that we could compile to Truffle nodes if the format string is constant! I
-         * don't think we can easily translate to Java's format syntax, otherwise JRuby would do
-         * that and they don't.
-         */
-
-        // I'm not using a for loop, because Checkstyle won't let me modify the control variable
-
-        int n = 0;
-        int v = 0;
-
-        while (n < format.length()) {
-            final char c = format.charAt(n);
-            n++;
-
-            if (c == '%') {
-                // %[flags][width][.precision]type
-
-                final String flagChars = "0";
-
-                boolean zeroPad = false;
-
-                while (n < format.length() && flagChars.indexOf(format.charAt(n)) != -1) {
-                    switch (format.charAt(n)) {
-                        case '0':
-                            zeroPad = true;
-                            break;
-                    }
-
-                    n++;
-                }
-
-                int width;
-
-                if (n < format.length() && Character.isDigit(format.charAt(n))) {
-                    final int widthStart = n;
-
-                    while (Character.isDigit(format.charAt(n))) {
-                        n++;
-                    }
-
-                    width = Integer.parseInt(format.substring(widthStart, n));
-                } else {
-                    width = 0;
-                }
-
-                int precision;
-
-                if (format.charAt(n) == '.') {
-                    n++;
-
-                    final int precisionStart = n;
-
-                    while (Character.isDigit(format.charAt(n))) {
-                        n++;
-                    }
-
-                    precision = Integer.parseInt(format.substring(precisionStart, n));
-                } else {
-                    precision = 5;
-                }
-
-                final char type = format.charAt(n);
-                n++;
-
-                final StringBuilder formatBuilder = new StringBuilder();
-
-                formatBuilder.append("%");
-
-                if (width > 0) {
-                    if (zeroPad) {
-                        formatBuilder.append("0");
-                    }
-
-                    formatBuilder.append(width);
-                }
-
-                switch (type) {
-                    case 'd': {
-                        formatBuilder.append("d");
-                        final int value = GeneralConversions.toFixnum(values.get(v));
-                        stream.printf(formatBuilder.toString(), value);
-                        break;
-                    }
-
-                    case 'f': {
-                        formatBuilder.append(".");
-                        formatBuilder.append(precision);
-                        formatBuilder.append("f");
-                        final double value = GeneralConversions.toFloat(values.get(v));
-                        stream.printf(formatBuilder.toString(), value);
-                        break;
-                    }
-
-                    default:
-                        throw new RuntimeException("Kernel#sprintf error");
-                }
-
-                v++;
-            } else {
-                stream.print(c);
-            }
-        }
-    }
-
-    public static void formatPuts(PrintStream stream, List<Object> args) {
-        if (args.size() > 0) {
-            formatPutsInner(stream, args);
-        } else {
-            stream.println();
-        }
-    }
-
-    public static void formatPutsInner(PrintStream stream, List<Object> args) {
-        if (args.size() > 0) {
-            for (Object arg : args) {
-                if (arg instanceof RubyArray) {
-                    final RubyArray array = (RubyArray) arg;
-                    formatPutsInner(stream, array.asList());
-                } else {
-                    stream.println(arg);
-                }
-            }
-        }
-    }
-}
--- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/array/ArrayStore.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,97 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.runtime.core.array;
-
-/**
- * Interface to various ways to store values in arrays.
- */
-public interface ArrayStore {
-
-    /**
-     * Get the size of the store.
-     */
-    int size();
-
-    /**
-     * Get a value from the array using a normalized index.
-     */
-    Object get(int normalisedIndex);
-
-    /**
-     * Get a range of values from an array store.
-     */
-    ArrayStore getRange(int normalisedBegin, int truncatedNormalisedExclusiveEnd);
-
-    /**
-     * Set a value at an index, or throw {@link GeneraliseArrayStoreException} if that's not
-     * possible.
-     */
-    void set(int normalisedIndex, Object value) throws GeneraliseArrayStoreException;
-
-    /**
-     * Set a range to be a single value, or throw {@link GeneraliseArrayStoreException} if that's
-     * not possible.
-     */
-    void setRangeSingle(int normalisedBegin, int truncatedNormalisedExclusiveEnd, Object value) throws GeneraliseArrayStoreException;
-
-    /**
-     * Set a range to be a copied from another array, or throw {@link GeneraliseArrayStoreException}
-     * if that's not possible.
-     */
-    void setRangeArray(int normalisedBegin, int normalisedExclusiveEnd, ArrayStore other) throws GeneraliseArrayStoreException;
-
-    /**
-     * Insert a value at an index, or throw {@link GeneraliseArrayStoreException} if that's not
-     * possible.
-     */
-    void insert(int normalisedIndex, Object value) throws GeneraliseArrayStoreException;
-
-    /**
-     * Push a value onto the end, or throw {@link GeneraliseArrayStoreException} if that's not
-     * possible.
-     */
-    void push(Object value) throws GeneraliseArrayStoreException;
-
-    /**
-     * Delete a value at an index, returning the value.
-     */
-    Object deleteAt(int normalisedIndex);
-
-    /**
-     * Does a store contain a value?
-     */
-    boolean contains(Object value);
-
-    /**
-     * Duplicate the store.
-     */
-    ArrayStore dup();
-
-    /**
-     * Duplicate the store, in a format which can store an object.
-     */
-    ArrayStore generalizeFor(Object type);
-
-    /**
-     * Get the type of value stored.
-     */
-    Object getIndicativeValue();
-
-    /**
-     * Get the contents of the store as a new array.
-     */
-    Object[] toObjectArray();
-
-    /**
-     * Does one store equal another.
-     */
-    boolean equals(ArrayStore other);
-
-}
--- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/array/ArrayUtilities.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,53 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.runtime.core.array;
-
-/**
- * Simple array utilities, not tied to any particular implementation.
- */
-public abstract class ArrayUtilities {
-
-    /**
-     * Apply Ruby's wrap-around index semantics.
-     */
-    public static int normaliseIndex(int length, int index) {
-        if (index < 0) {
-            return length + index;
-        } else {
-            return index;
-        }
-    }
-
-    /**
-     * Apply Ruby's wrap-around index semantics.
-     */
-    public static int normaliseExclusiveIndex(int length, int exclusiveIndex) {
-        if (exclusiveIndex < 0) {
-            return length + exclusiveIndex + 1;
-        } else {
-            return exclusiveIndex;
-        }
-    }
-
-    /**
-     * If an exclusive index is beyond the end of the array, truncate it to be length of the array.
-     */
-    public static int truncateNormalisedExclusiveIndex(int length, int normalisedExclusiveEnd) {
-        return Math.min(length, normalisedExclusiveEnd);
-    }
-
-    /**
-     * What capacity should we allocate for a given requested length?
-     */
-    public static int capacityFor(int length) {
-        return Math.max(16, length * 2);
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/array/BaseArrayStore.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,149 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.runtime.core.array;
-
-/**
- * Contains implementations of as much of the array stores that we could easily share. Much of the
- * rest depends on static types in method signatures, so is lexically almost the same, but isn't the
- * same in type, and as the whole point is to avoid boxing, we can't use Java's generics.
- */
-public abstract class BaseArrayStore implements ArrayStore {
-
-    protected int capacity;
-    protected int size;
-
-    @Override
-    public int size() {
-        return size;
-    }
-
-    /**
-     * Set a range in the array to be another range. You must ensure that the otherValues array is
-     * of the same type as your values array.
-     */
-    protected void setRangeArrayMatchingTypes(int normalisedBegin, int normalisedExclusiveEnd, Object otherValues, int otherSize) {
-        // Is the range the whole array?
-
-        if (normalisedBegin == 0 && normalisedExclusiveEnd == size) {
-            // Do we already have enough space?
-
-            if (otherSize <= capacity) {
-                // Copy to our existing array.
-                final Object values = getValuesArrayObject();
-                System.arraycopy(otherValues, 0, values, 0, otherSize);
-            } else {
-                // Create a new copy of their array.
-                setCapacityWithNewArray(otherSize);
-                final Object values = getValuesArrayObject();
-                System.arraycopy(otherValues, 0, values, 0, otherSize);
-            }
-
-            size = otherSize;
-        } else {
-            final int rangeLength = normalisedExclusiveEnd - normalisedBegin;
-
-            // Create extra space - might be negative if the new range is shorter, or zero.
-
-            final int extraSpaceNeeded = otherSize - rangeLength;
-
-            if (extraSpaceNeeded > 0) {
-                createSpace(normalisedBegin, extraSpaceNeeded);
-            } else if (extraSpaceNeeded < 0) {
-                deleteSpace(normalisedBegin, -extraSpaceNeeded);
-            }
-
-            // Copy across the new values.
-            final Object values = getValuesArrayObject();
-            System.arraycopy(otherValues, 0, values, normalisedBegin, otherSize);
-        }
-    }
-
-    protected void createSpace(int normalisedBegin, int count) {
-        /*
-         * Is this space at the end or in the middle?
-         */
-
-        if (normalisedBegin == size) {
-            createSpaceAtEnd(count);
-        } else {
-            /*
-             * Create space in the middle - is the array already big enough?
-             */
-
-            final int elementsToMove = size - normalisedBegin;
-
-            if (size + count > capacity) {
-                /*
-                 * The array isn't big enough. We don't want to use Arrays.copyOf because that will
-                 * do wasted copying of the elements we are about to move. However - is
-                 * Arrays.copyOf clever enough to see that only one instance of Array is using the
-                 * block and use realloc, potentially avoiding a malloc and winning?
-                 */
-
-                final Object values = getValuesArrayObject();
-                setCapacityWithNewArray(ArrayUtilities.capacityFor(size + count));
-                final Object newValues = getValuesArrayObject();
-                System.arraycopy(values, 0, newValues, 0, normalisedBegin);
-                System.arraycopy(values, normalisedBegin, newValues, normalisedBegin + count, elementsToMove);
-            } else {
-                /*
-                 * The array is already big enough - we can copy elements already in the array to
-                 * make space.
-                 */
-
-                final Object values = getValuesArrayObject();
-                System.arraycopy(values, normalisedBegin, values, normalisedBegin + count, elementsToMove);
-            }
-
-            size += count;
-        }
-    }
-
-    protected void createSpaceAtEnd(int count) {
-        /*
-         * Create space at the end - we can do this by creating a copy of the array if needed.
-         */
-
-        if (size + count > capacity) {
-            setCapacityByCopying(ArrayUtilities.capacityFor(size + count));
-        }
-
-        size += count;
-    }
-
-    protected void deleteSpace(int normalisedBegin, int count) {
-        final Object values = getValuesArrayObject();
-        final int elementsToMove = size - normalisedBegin - count;
-
-        if (elementsToMove > 0) {
-            System.arraycopy(values, normalisedBegin + count, values, normalisedBegin, elementsToMove);
-        }
-
-        size -= count;
-    }
-
-    protected abstract void setCapacityByCopying(int newCapacity);
-
-    protected abstract void setCapacityWithNewArray(int newCapacity);
-
-    protected abstract Object getValuesArrayObject();
-
-    @Override
-    public boolean equals(ArrayStore other) {
-        for (int n = 0; n < size; n++) {
-            if (!other.get(n).equals(get(n))) {
-                return false;
-            }
-        }
-
-        return true;
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/array/EmptyArrayStore.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,109 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.runtime.core.array;
-
-import com.oracle.truffle.ruby.runtime.*;
-
-/**
- * An array store that can only be empty.
- */
-public final class EmptyArrayStore implements ArrayStore {
-
-    public static final EmptyArrayStore INSTANCE = new EmptyArrayStore();
-
-    private EmptyArrayStore() {
-    }
-
-    @Override
-    public int size() {
-        return 0;
-    }
-
-    @Override
-    public Object get(int normalisedIndex) {
-        return NilPlaceholder.INSTANCE;
-    }
-
-    @Override
-    public ArrayStore getRange(int normalisedBegin, int truncatedNormalisedExclusiveEnd) {
-        return null; // Represents Nil
-    }
-
-    @Override
-    public void set(int normalisedIndex, Object value) throws GeneraliseArrayStoreException {
-        throw new GeneraliseArrayStoreException();
-    }
-
-    @Override
-    public void setRangeSingle(int normalisedBegin, int truncatedNormalisedExclusiveEnd, Object value) throws GeneraliseArrayStoreException {
-        throw new GeneraliseArrayStoreException();
-    }
-
-    @Override
-    public void setRangeArray(int normalisedBegin, int normalisedExclusiveEnd, ArrayStore other) throws GeneraliseArrayStoreException {
-        throw new GeneraliseArrayStoreException();
-    }
-
-    @Override
-    public void insert(int normalisedIndex, Object value) throws GeneraliseArrayStoreException {
-        throw new GeneraliseArrayStoreException();
-    }
-
-    @Override
-    public void push(Object value) throws GeneraliseArrayStoreException {
-        throw new GeneraliseArrayStoreException();
-    }
-
-    @Override
-    public Object deleteAt(int normalisedIndex) {
-        throw new UnsupportedOperationException("Cannot delete from an empty array");
-    }
-
-    @Override
-    public ArrayStore dup() {
-        return this;
-    }
-
-    @Override
-    public boolean contains(Object value) {
-        return false;
-    }
-
-    @Override
-    public ArrayStore generalizeFor(Object type) {
-        if (type instanceof Integer) {
-            return new FixnumArrayStore();
-        } else {
-            return new ObjectArrayStore();
-        }
-    }
-
-    @Override
-    public Object getIndicativeValue() {
-        return null;
-    }
-
-    @Override
-    public Object[] toObjectArray() {
-        return new Object[]{};
-    }
-
-    @Override
-    public boolean equals(ArrayStore other) {
-        if (other == null) {
-            return false;
-        } else if (other == this) {
-            return true;
-        } else {
-            return other.size() == 0;
-        }
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/array/FixnumArrayStore.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,264 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.runtime.core.array;
-
-import java.util.*;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-
-/**
- * A store for an array of Fixnums.
- */
-public final class FixnumArrayStore extends BaseArrayStore {
-
-    private int[] values;
-
-    public FixnumArrayStore() {
-        this(new int[]{});
-    }
-
-    public FixnumArrayStore(int[] values) {
-        this.values = values;
-        size = values.length;
-        capacity = values.length;
-    }
-
-    @Override
-    public Object get(int normalisedIndex) {
-        try {
-            return getFixnum(normalisedIndex);
-        } catch (UnexpectedResultException e) {
-            return e.getResult();
-        }
-    }
-
-    public int getFixnum(int normalisedIndex) throws UnexpectedResultException {
-        if (normalisedIndex >= size) {
-            throw new UnexpectedResultException(NilPlaceholder.INSTANCE);
-        }
-
-        return values[normalisedIndex];
-    }
-
-    @Override
-    public ArrayStore getRange(int normalisedBegin, int truncatedNormalisedExclusiveEnd) {
-        if (normalisedBegin >= size) {
-            return null; // Represents Nil
-        }
-
-        return new FixnumArrayStore(Arrays.copyOfRange(values, normalisedBegin, truncatedNormalisedExclusiveEnd));
-    }
-
-    @Override
-    public void set(int normalisedIndex, Object value) throws GeneraliseArrayStoreException {
-        if (value instanceof Integer) {
-            setFixnum(normalisedIndex, (int) value);
-        } else {
-            throw new GeneraliseArrayStoreException();
-        }
-    }
-
-    public void setFixnum(int normalisedIndex, int value) throws GeneraliseArrayStoreException {
-        if (normalisedIndex > size) {
-            throw new GeneraliseArrayStoreException();
-        }
-
-        if (normalisedIndex == size) {
-            push(value);
-        } else {
-            values[normalisedIndex] = value;
-        }
-    }
-
-    @Override
-    public void setRangeSingle(int normalisedBegin, int truncatedNormalisedExclusiveEnd, Object value) throws GeneraliseArrayStoreException {
-        if (value instanceof Integer) {
-            setRangeSingleFixnum(normalisedBegin, truncatedNormalisedExclusiveEnd, (int) value);
-        } else {
-            throw new GeneraliseArrayStoreException();
-        }
-    }
-
-    public void setRangeSingleFixnum(int normalisedBegin, int truncatedNormalisedExclusiveEnd, int value) {
-        // Is the range the whole array?
-
-        if (normalisedBegin == 0 && truncatedNormalisedExclusiveEnd == size) {
-            // Reset length and set the value.
-            size = 1;
-            values[0] = value;
-        } else {
-            // Delete the range, except for the first value.
-            deleteSpace(normalisedBegin + 1, truncatedNormalisedExclusiveEnd - normalisedBegin - 1);
-
-            // Set the value we left in.
-            values[normalisedBegin] = value;
-        }
-    }
-
-    @Override
-    public void setRangeArray(int normalisedBegin, int normalisedExclusiveEnd, ArrayStore other) throws GeneraliseArrayStoreException {
-        if (other instanceof FixnumArrayStore) {
-            setRangeArrayFixnum(normalisedBegin, normalisedExclusiveEnd, (FixnumArrayStore) other);
-        } else {
-            throw new GeneraliseArrayStoreException();
-        }
-    }
-
-    public void setRangeArrayFixnum(int normalisedBegin, int normalisedExclusiveEnd, FixnumArrayStore other) {
-        setRangeArrayMatchingTypes(normalisedBegin, normalisedExclusiveEnd, other.values, other.size);
-    }
-
-    @Override
-    public void insert(int normalisedIndex, Object value) throws GeneraliseArrayStoreException {
-        if (value instanceof Integer) {
-            insertFixnum(normalisedIndex, (int) value);
-        } else {
-            throw new GeneraliseArrayStoreException();
-        }
-    }
-
-    public void insertFixnum(int normalisedIndex, int value) throws GeneraliseArrayStoreException {
-        if (normalisedIndex > size) {
-            throw new GeneraliseArrayStoreException();
-        }
-
-        createSpace(normalisedIndex, 1);
-        values[normalisedIndex] = value;
-    }
-
-    @Override
-    public void push(Object value) throws GeneraliseArrayStoreException {
-        if (value instanceof Integer) {
-            pushFixnum((int) value);
-        } else {
-            throw new GeneraliseArrayStoreException();
-        }
-    }
-
-    public void pushFixnum(int value) {
-        createSpaceAtEnd(1);
-        values[size - 1] = value;
-    }
-
-    @Override
-    public Object deleteAt(int normalisedIndex) {
-        try {
-            return deleteAtFixnum(normalisedIndex);
-        } catch (UnexpectedResultException e) {
-            return e.getResult();
-        }
-    }
-
-    public int deleteAtFixnum(int normalisedIndex) throws UnexpectedResultException {
-        if (normalisedIndex >= size) {
-            CompilerDirectives.transferToInterpreter();
-            throw new UnexpectedResultException(NilPlaceholder.INSTANCE);
-        }
-
-        final int value = values[normalisedIndex];
-
-        deleteSpace(normalisedIndex, 1);
-
-        return value;
-    }
-
-    @Override
-    public ArrayStore dup() {
-        return new FixnumArrayStore(Arrays.copyOf(values, size));
-    }
-
-    @Override
-    public boolean contains(Object value) {
-        if (!(value instanceof Integer)) {
-            return false;
-        }
-
-        final int intValue = (int) value;
-
-        for (int n = 0; n < size; n++) {
-            if (values[n] == intValue) {
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    @Override
-    public ArrayStore generalizeFor(Object type) {
-        return new ObjectArrayStore(toObjectArray());
-    }
-
-    @Override
-    public Object getIndicativeValue() {
-        return 0;
-    }
-
-    @Override
-    protected void setCapacityByCopying(int newCapacity) {
-        values = Arrays.copyOf(values, newCapacity);
-        capacity = values.length;
-    }
-
-    @Override
-    protected void setCapacityWithNewArray(int newCapacity) {
-        values = new int[newCapacity];
-        capacity = values.length;
-    }
-
-    @Override
-    protected Object getValuesArrayObject() {
-        return values;
-    }
-
-    @Override
-    public Object[] toObjectArray() {
-        final Object[] objectValues = new Object[size];
-
-        // System.arraycopy will not box.
-
-        for (int n = 0; n < size; n++) {
-            objectValues[n] = values[n];
-        }
-
-        return objectValues;
-    }
-
-    @Override
-    public boolean equals(ArrayStore other) {
-        if (other instanceof FixnumArrayStore) {
-            return equals((FixnumArrayStore) other);
-        } else {
-            return super.equals(other);
-        }
-    }
-
-    public boolean equals(FixnumArrayStore other) {
-        if (other == null) {
-            return false;
-        } else if (other == this) {
-            return true;
-        } else if (other.size != size) {
-            return false;
-        } else if (other.capacity == capacity) {
-            return Arrays.equals(other.values, values);
-        } else {
-            for (int n = 0; n < size; n++) {
-                if (other.values[n] != values[n]) {
-                    return false;
-                }
-            }
-
-            return true;
-        }
-    }
-}
--- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/array/FixnumImmutablePairArrayStore.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,169 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.runtime.core.array;
-
-import java.util.*;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-
-/**
- * A store for a pair of Fixnums.
- */
-public final class FixnumImmutablePairArrayStore extends BaseArrayStore {
-
-    private final int first;
-    private final int second;
-
-    public FixnumImmutablePairArrayStore(int first, int second) {
-        size = 2;
-        capacity = 2;
-        this.first = first;
-        this.second = second;
-    }
-
-    @Override
-    public int size() {
-        return 2;
-    }
-
-    @Override
-    public Object get(int normalisedIndex) {
-        switch (normalisedIndex) {
-            case 0:
-                return first;
-            case 1:
-                return second;
-            default:
-                return NilPlaceholder.INSTANCE;
-        }
-    }
-
-    public int getFixnum(int normalisedIndex) throws UnexpectedResultException {
-        switch (normalisedIndex) {
-            case 0:
-                return first;
-            case 1:
-                return second;
-            default:
-                CompilerDirectives.transferToInterpreter();
-                throw new UnexpectedResultException(NilPlaceholder.INSTANCE);
-        }
-    }
-
-    @Override
-    public ArrayStore getRange(int normalisedBegin, int truncatedNormalisedExclusiveEnd) {
-        if (normalisedBegin >= size) {
-            return null; // Represents Nil
-        }
-
-        return new FixnumArrayStore(Arrays.copyOfRange(new int[]{first, second}, normalisedBegin, truncatedNormalisedExclusiveEnd));
-    }
-
-    @Override
-    public void set(int normalisedIndex, Object value) throws GeneraliseArrayStoreException {
-        CompilerDirectives.transferToInterpreter();
-        throw new GeneraliseArrayStoreException();
-    }
-
-    @Override
-    public void setRangeSingle(int normalisedBegin, int truncatedNormalisedExclusiveEnd, Object value) throws GeneraliseArrayStoreException {
-        CompilerDirectives.transferToInterpreter();
-        throw new GeneraliseArrayStoreException();
-    }
-
-    @Override
-    public void setRangeArray(int normalisedBegin, int normalisedExclusiveEnd, ArrayStore other) throws GeneraliseArrayStoreException {
-        CompilerDirectives.transferToInterpreter();
-        throw new GeneraliseArrayStoreException();
-    }
-
-    @Override
-    public void insert(int normalisedIndex, Object value) throws GeneraliseArrayStoreException {
-        CompilerDirectives.transferToInterpreter();
-        throw new GeneraliseArrayStoreException();
-    }
-
-    @Override
-    public void push(Object value) throws GeneraliseArrayStoreException {
-        CompilerDirectives.transferToInterpreter();
-        throw new GeneraliseArrayStoreException();
-    }
-
-    @Override
-    public Object deleteAt(int normalisedIndex) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public ArrayStore dup() {
-        return this;
-    }
-
-    @Override
-    public boolean contains(Object value) {
-        if (value instanceof Integer) {
-            final int intValue = (int) value;
-            return first == intValue || second == intValue;
-        } else {
-            return false;
-        }
-    }
-
-    @Override
-    public ArrayStore generalizeFor(Object type) {
-        return new ObjectArrayStore(toObjectArray());
-    }
-
-    @Override
-    public Object getIndicativeValue() {
-        return 0;
-    }
-
-    @Override
-    protected void setCapacityByCopying(int newCapacity) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    protected void setCapacityWithNewArray(int newCapacity) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    protected Object getValuesArrayObject() {
-        return new int[]{first, second};
-    }
-
-    @Override
-    public Object[] toObjectArray() {
-        return new Object[]{first, second};
-    }
-
-    @Override
-    public boolean equals(ArrayStore other) {
-        if (other instanceof FixnumImmutablePairArrayStore) {
-            return equals((FixnumImmutablePairArrayStore) other);
-        } else {
-            return super.equals(other);
-        }
-    }
-
-    public boolean equals(FixnumImmutablePairArrayStore other) {
-        if (other == null) {
-            return false;
-        } else if (other == this) {
-            return true;
-        } else {
-            return other.first == first && other.second == second;
-        }
-    }
-}
--- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/array/GeneraliseArrayStoreException.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,22 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.runtime.core.array;
-
-import com.oracle.truffle.api.nodes.*;
-
-/**
- * An exception that signals that an ArrayStore cannot store a given object because of its type, and
- * that the store must be generalized to accommodate it.
- */
-public class GeneraliseArrayStoreException extends SlowPathException {
-
-    private static final long serialVersionUID = -7648655548414168177L;
-
-}
--- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/array/ObjectArrayStore.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,208 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.runtime.core.array;
-
-import java.util.*;
-
-import com.oracle.truffle.ruby.runtime.*;
-
-/**
- * A store for an array of any objects.
- */
-public final class ObjectArrayStore extends BaseArrayStore {
-
-    private Object[] values;
-
-    public ObjectArrayStore() {
-        this(new Object[]{});
-    }
-
-    public ObjectArrayStore(Object[] values) {
-        this.values = values;
-        size = values.length;
-        capacity = values.length;
-    }
-
-    @Override
-    public Object get(int normalisedIndex) {
-        if (normalisedIndex >= size) {
-            return NilPlaceholder.INSTANCE;
-        }
-
-        return values[normalisedIndex];
-    }
-
-    @Override
-    public ArrayStore getRange(int normalisedBegin, int normalisedExclusiveEnd) {
-        if (normalisedBegin >= size) {
-            return null; // Represents Nil
-        }
-
-        return new ObjectArrayStore(Arrays.copyOfRange(values, normalisedBegin, normalisedExclusiveEnd));
-    }
-
-    @Override
-    public void set(int normalisedIndex, Object value) throws GeneraliseArrayStoreException {
-        if (normalisedIndex > size) {
-            final int originalLength = size;
-            createSpace(size, normalisedIndex - size + 1);
-            Arrays.fill(values, originalLength, normalisedIndex, NilPlaceholder.INSTANCE);
-            values[normalisedIndex] = value;
-        } else if (normalisedIndex == size) {
-            push(value);
-        } else {
-            values[normalisedIndex] = value;
-        }
-    }
-
-    @Override
-    public void setRangeSingle(int normalisedBegin, int normalisedExclusiveEnd, Object value) throws GeneraliseArrayStoreException {
-        // Is the range the whole array?
-
-        if (normalisedBegin == 0 && normalisedExclusiveEnd == size) {
-            // Reset length and set the value.
-            size = 1;
-            values[0] = value;
-        } else {
-            // Delete the range, except for the first value.
-            deleteSpace(normalisedBegin + 1, normalisedExclusiveEnd - normalisedBegin - 1);
-
-            // Set the value we left in.
-            System.err.println(normalisedBegin + " in " + size + " with " + values.length);
-            values[normalisedBegin] = value;
-        }
-    }
-
-    @Override
-    public void setRangeArray(int normalisedBegin, int normalisedExclusiveEnd, ArrayStore other) throws GeneraliseArrayStoreException {
-        setRangeArray(normalisedBegin, normalisedExclusiveEnd, (ObjectArrayStore) other.generalizeFor(null));
-    }
-
-    public void setRangeArray(int normalisedBegin, int normalisedExclusiveEnd, ObjectArrayStore other) {
-        setRangeArrayMatchingTypes(normalisedBegin, normalisedExclusiveEnd, other.values, other.size);
-    }
-
-    @Override
-    public void insert(int normalisedIndex, Object value) throws GeneraliseArrayStoreException {
-        if (normalisedIndex > size) {
-            final int originalLength = size;
-            createSpaceAtEnd(normalisedIndex - size + 1);
-            Arrays.fill(values, originalLength, normalisedIndex, NilPlaceholder.INSTANCE);
-            values[normalisedIndex] = value;
-        } else {
-            createSpace(normalisedIndex, 1);
-            values[normalisedIndex] = value;
-        }
-    }
-
-    @Override
-    public void push(Object value) throws GeneraliseArrayStoreException {
-        createSpaceAtEnd(1);
-        values[size - 1] = value;
-    }
-
-    @Override
-    public Object deleteAt(int normalisedIndex) {
-        if (normalisedIndex >= size) {
-            return NilPlaceholder.INSTANCE;
-        }
-
-        final Object value = values[normalisedIndex];
-
-        deleteSpace(normalisedIndex, 1);
-
-        return value;
-    }
-
-    @Override
-    public ArrayStore dup() {
-        return new ObjectArrayStore(Arrays.copyOf(values, size));
-    }
-
-    @Override
-    public boolean contains(Object value) {
-        for (int n = 0; n < size; n++) {
-            if (values[n].equals(value)) {
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    @Override
-    public ObjectArrayStore generalizeFor(Object type) {
-        return this;
-    }
-
-    @Override
-    public Object getIndicativeValue() {
-        return null;
-    }
-
-    @Override
-    protected void setCapacityByCopying(int newCapacity) {
-        values = Arrays.copyOf(values, newCapacity);
-        capacity = values.length;
-    }
-
-    @Override
-    protected void setCapacityWithNewArray(int newCapacity) {
-        values = new Object[newCapacity];
-        capacity = values.length;
-    }
-
-    @Override
-    protected Object getValuesArrayObject() {
-        return values;
-    }
-
-    public Object[] getValues() {
-        return values;
-    }
-
-    @Override
-    public Object[] toObjectArray() {
-        if (values.length == size) {
-            return values;
-        } else {
-            return Arrays.copyOf(values, size);
-        }
-    }
-
-    @Override
-    public boolean equals(ArrayStore other) {
-        if (other instanceof ObjectArrayStore) {
-            return equals((ObjectArrayStore) other);
-        } else {
-            return super.equals(other);
-        }
-    }
-
-    public boolean equals(ObjectArrayStore other) {
-        if (other == null) {
-            return false;
-        } else if (other == this) {
-            return true;
-        } else if (other.size != size) {
-            return false;
-        } else if (other.capacity == capacity) {
-            return Arrays.equals(other.values, values);
-        } else {
-            for (int n = 0; n < size; n++) {
-                if (!other.values[n].equals(values[n])) {
-                    return false;
-                }
-            }
-
-            return true;
-        }
-    }
-}
--- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/array/ObjectImmutablePairArrayStore.java	Sun Feb 23 17:00:35 2014 -0800
+++ /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. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.runtime.core.array;
-
-import java.util.*;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.ruby.runtime.*;
-
-/**
- * A store for a pair of objects.
- */
-public final class ObjectImmutablePairArrayStore extends BaseArrayStore {
-
-    private final Object first;
-    private final Object second;
-
-    public ObjectImmutablePairArrayStore(Object first, Object second) {
-        size = 2;
-        capacity = 2;
-        this.first = first;
-        this.second = second;
-    }
-
-    @Override
-    public int size() {
-        return 2;
-    }
-
-    @Override
-    public Object get(int normalisedIndex) {
-        switch (normalisedIndex) {
-            case 0:
-                return first;
-            case 1:
-                return second;
-            default:
-                return NilPlaceholder.INSTANCE;
-        }
-    }
-
-    @Override
-    public ArrayStore getRange(int normalisedBegin, int truncatedNormalisedExclusiveEnd) {
-        if (normalisedBegin >= size) {
-            return null; // Represents Nil
-        }
-
-        return new ObjectArrayStore(Arrays.copyOfRange(new Object[]{first, second}, normalisedBegin, truncatedNormalisedExclusiveEnd));
-    }
-
-    @Override
-    public void set(int normalisedIndex, Object value) throws GeneraliseArrayStoreException {
-        CompilerDirectives.transferToInterpreter();
-        throw new GeneraliseArrayStoreException();
-    }
-
-    @Override
-    public void setRangeSingle(int normalisedBegin, int truncatedNormalisedExclusiveEnd, Object value) throws GeneraliseArrayStoreException {
-        CompilerDirectives.transferToInterpreter();
-        throw new GeneraliseArrayStoreException();
-    }
-
-    @Override
-    public void setRangeArray(int normalisedBegin, int normalisedExclusiveEnd, ArrayStore other) throws GeneraliseArrayStoreException {
-        CompilerDirectives.transferToInterpreter();
-        throw new GeneraliseArrayStoreException();
-    }
-
-    @Override
-    public void insert(int normalisedIndex, Object value) throws GeneraliseArrayStoreException {
-        CompilerDirectives.transferToInterpreter();
-        throw new GeneraliseArrayStoreException();
-    }
-
-    @Override
-    public void push(Object value) throws GeneraliseArrayStoreException {
-        CompilerDirectives.transferToInterpreter();
-        throw new GeneraliseArrayStoreException();
-    }
-
-    @Override
-    public Object deleteAt(int normalisedIndex) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public ArrayStore dup() {
-        return this;
-    }
-
-    @Override
-    public boolean contains(Object value) {
-        return first.equals(value) || second.equals(value);
-    }
-
-    @Override
-    public ArrayStore generalizeFor(Object type) {
-        return new ObjectArrayStore(toObjectArray());
-    }
-
-    @Override
-    public Object getIndicativeValue() {
-        return 0;
-    }
-
-    @Override
-    protected void setCapacityByCopying(int newCapacity) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    protected void setCapacityWithNewArray(int newCapacity) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    protected Object getValuesArrayObject() {
-        return new Object[]{first, second};
-    }
-
-    @Override
-    public Object[] toObjectArray() {
-        return new Object[]{first, second};
-    }
-
-    @Override
-    public boolean equals(ArrayStore other) {
-        if (other instanceof ObjectImmutablePairArrayStore) {
-            return equals((ObjectImmutablePairArrayStore) other);
-        } else {
-            return super.equals(other);
-        }
-    }
-
-    public boolean equals(ObjectImmutablePairArrayStore other) {
-        if (other == null) {
-            return false;
-        } else if (other == this) {
-            return true;
-        } else {
-            return other.first == first && other.second == second;
-        }
-    }
-}
--- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/array/RubyArray.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,428 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.runtime.core.array;
-
-import java.util.*;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
-import com.oracle.truffle.api.CompilerDirectives.SlowPath;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.control.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-import com.oracle.truffle.ruby.runtime.methods.*;
-import com.oracle.truffle.ruby.runtime.objects.*;
-
-/**
- * Implements the Ruby {@code Array} class.
- */
-@SuppressWarnings("unused")
-public final class RubyArray extends RubyObject {
-
-    public static class RubyArrayClass extends RubyClass {
-
-        public RubyArrayClass(RubyClass objectClass) {
-            super(null, objectClass, "Array");
-        }
-
-        @Override
-        public RubyBasicObject newInstance() {
-            return new RubyArray(this);
-        }
-
-    }
-
-    @CompilationFinal private ArrayStore store;
-
-    public RubyArray(RubyClass arrayClass) {
-        this(arrayClass, EmptyArrayStore.INSTANCE);
-    }
-
-    public RubyArray(RubyClass arrayClass, ArrayStore store) {
-        super(arrayClass);
-        this.store = store;
-    }
-
-    private static RubyArray selfAsArray(Object self) {
-        if (self instanceof RubyArray) {
-            return (RubyArray) self;
-        } else {
-            throw new IllegalStateException();
-        }
-    }
-
-    @CompilerDirectives.SlowPath
-    public static RubyArray specializedFromObject(RubyClass arrayClass, Object object) {
-        ArrayStore store;
-
-        if (object instanceof Integer || object instanceof RubyFixnum) {
-            store = new FixnumArrayStore(new int[]{GeneralConversions.toFixnum(object)});
-        } else {
-            store = new ObjectArrayStore(new Object[]{object});
-        }
-
-        return new RubyArray(arrayClass, store);
-    }
-
-    /**
-     * Create a Ruby array from a Java array of objects, choosing the best store.
-     */
-    @CompilerDirectives.SlowPath
-    public static RubyArray specializedFromObjects(RubyClass arrayClass, Object... objects) {
-        if (objects.length == 0) {
-            return new RubyArray(arrayClass);
-        }
-
-        boolean canUseFixnum = true;
-
-        for (Object object : objects) {
-            if (!(object instanceof Integer || object instanceof RubyFixnum)) {
-                canUseFixnum = false;
-            }
-        }
-
-        ArrayStore store;
-
-        if (canUseFixnum) {
-            final int[] values = new int[objects.length];
-
-            for (int n = 0; n < objects.length; n++) {
-                values[n] = GeneralConversions.toFixnum(objects[n]);
-            }
-
-            store = new FixnumArrayStore(values);
-        } else {
-            store = new ObjectArrayStore(objects);
-        }
-
-        return new RubyArray(arrayClass, store);
-    }
-
-    public Object get(int index) {
-        return store.get(ArrayUtilities.normaliseIndex(store.size(), index));
-    }
-
-    public Object getRangeInclusive(int begin, int inclusiveEnd) {
-        final int l = store.size();
-        final int normalisedInclusiveEnd = ArrayUtilities.normaliseIndex(l, inclusiveEnd);
-        return getRangeExclusive(begin, normalisedInclusiveEnd + 1);
-    }
-
-    public Object getRangeExclusive(int begin, int exclusiveEnd) {
-        final int l = store.size();
-        final int normalisedBegin = ArrayUtilities.normaliseIndex(l, begin);
-        final int truncatedNormalisedExclusiveEnd = ArrayUtilities.truncateNormalisedExclusiveIndex(l, ArrayUtilities.normaliseExclusiveIndex(l, exclusiveEnd));
-
-        final Object range = store.getRange(normalisedBegin, truncatedNormalisedExclusiveEnd);
-
-        if (range == null) {
-            return new RubyArray(getRubyClass());
-        } else {
-            return new RubyArray(getRubyClass(), (ArrayStore) range);
-        }
-    }
-
-    public void set(int index, Object value) {
-        checkFrozen();
-
-        final int l = store.size();
-        final int normalisedIndex = ArrayUtilities.normaliseIndex(l, index);
-
-        try {
-            store.set(normalisedIndex, value);
-        } catch (GeneraliseArrayStoreException e) {
-            store = store.generalizeFor(value);
-
-            try {
-                store.set(normalisedIndex, value);
-            } catch (GeneraliseArrayStoreException ex) {
-                throwSecondGeneraliseException();
-            }
-        }
-    }
-
-    public void setRangeSingleInclusive(int begin, int inclusiveEnd, Object value) {
-        final int l = store.size();
-        final int normalisedInclusiveEnd = ArrayUtilities.normaliseIndex(l, inclusiveEnd);
-        setRangeSingleExclusive(begin, normalisedInclusiveEnd + 1, value);
-    }
-
-    public void setRangeSingleExclusive(int begin, int exclusiveEnd, Object value) {
-        checkFrozen();
-
-        final int l = store.size();
-        final int normalisedBegin = ArrayUtilities.normaliseIndex(l, begin);
-        final int truncatedNormalisedExclusiveEnd = ArrayUtilities.truncateNormalisedExclusiveIndex(l, ArrayUtilities.normaliseExclusiveIndex(l, exclusiveEnd));
-
-        try {
-            store.setRangeSingle(normalisedBegin, truncatedNormalisedExclusiveEnd, value);
-        } catch (GeneraliseArrayStoreException e) {
-            store = store.generalizeFor(value);
-
-            try {
-                store.setRangeSingle(normalisedBegin, truncatedNormalisedExclusiveEnd, value);
-            } catch (GeneraliseArrayStoreException ex) {
-                throwSecondGeneraliseException();
-            }
-        }
-    }
-
-    public void setRangeArrayInclusive(int begin, int inclusiveEnd, RubyArray other) {
-        final int l = store.size();
-        final int normalisedInclusiveEnd = ArrayUtilities.normaliseIndex(l, inclusiveEnd);
-        setRangeArrayExclusive(begin, normalisedInclusiveEnd + 1, other);
-    }
-
-    public void setRangeArrayExclusive(int begin, int exclusiveEnd, RubyArray other) {
-        checkFrozen();
-
-        final int l = store.size();
-        final int normalisedBegin = ArrayUtilities.normaliseIndex(l, begin);
-        final int normalisedExclusiveEnd = ArrayUtilities.normaliseExclusiveIndex(l, exclusiveEnd);
-
-        try {
-            store.setRangeArray(normalisedBegin, normalisedExclusiveEnd, other.store);
-        } catch (GeneraliseArrayStoreException e) {
-            store = store.generalizeFor(other.store.getIndicativeValue());
-
-            try {
-                store.setRangeArray(normalisedBegin, normalisedExclusiveEnd, other.store);
-            } catch (GeneraliseArrayStoreException ex) {
-                throwSecondGeneraliseException();
-            }
-        }
-    }
-
-    public void insert(int index, Object value) {
-        checkFrozen();
-
-        final int l = store.size();
-        final int normalisedIndex = ArrayUtilities.normaliseIndex(l, index);
-
-        try {
-            store.insert(normalisedIndex, value);
-        } catch (GeneraliseArrayStoreException e) {
-            store = store.generalizeFor(value);
-
-            try {
-                store.insert(normalisedIndex, value);
-            } catch (GeneraliseArrayStoreException ex) {
-                throwSecondGeneraliseException();
-            }
-        }
-    }
-
-    public void push(Object value) {
-        checkFrozen();
-
-        if (store instanceof EmptyArrayStore) {
-            /*
-             * Normally we want to transfer to interpreter to generalize an array store, but the
-             * special case of an empty array is common, will never cause rewrites and has a simple
-             * implementation, so treat it as a special case.
-             */
-            store = ((EmptyArrayStore) store).generalizeFor(value);
-        }
-
-        try {
-            store.push(value);
-        } catch (GeneraliseArrayStoreException e) {
-            store = store.generalizeFor(value);
-
-            try {
-                store.push(value);
-            } catch (GeneraliseArrayStoreException ex) {
-                throw new IllegalStateException("Generalised to support a specific value, but value still rejected by store");
-            }
-        }
-    }
-
-    public void unshift(Object value) {
-        insert(0, value);
-    }
-
-    public Object deleteAt(int index) {
-        checkFrozen();
-
-        final int l = store.size();
-        final int normalisedIndex = ArrayUtilities.normaliseIndex(l, index);
-
-        return store.deleteAt(normalisedIndex);
-    }
-
-    @Override
-    @CompilerDirectives.SlowPath
-    public Object dup() {
-        return new RubyArray(getRubyClass(), store.dup());
-    }
-
-    public ArrayStore getArrayStore() {
-        return store;
-    }
-
-    public List<Object> asList() {
-        final RubyArray array = this;
-
-        return new AbstractList<Object>() {
-
-            @Override
-            public Object get(int n) {
-                return array.get(n);
-            }
-
-            @Override
-            public int size() {
-                return array.size();
-            }
-
-        };
-    }
-
-    public Object[] toObjectArray() {
-        return store.toObjectArray();
-    }
-
-    private static void throwSecondGeneraliseException() {
-        CompilerAsserts.neverPartOfCompilation();
-        throw new RuntimeException("Generalised based on a value, but the new store also rejected that value.");
-    }
-
-    public int size() {
-        return store.size();
-    }
-
-    public boolean contains(Object value) {
-        return store.contains(value);
-    }
-
-    /**
-     * Recursive Cartesian product.
-     * <p>
-     * The Array#product method is supposed to be able to take a block, to which it yields tuples as
-     * they are produced, so it might be worth abstracting this method into sending tuples to some
-     * interface, which either adds them to an array, or yields them to the block.
-     */
-    @SlowPath
-    public static RubyArray product(RubyClass arrayClass, RubyArray[] arrays, int l) {
-        if (arrays.length - l == 1) {
-            final RubyArray firstArray = arrays[0];
-
-            final RubyArray tuples = new RubyArray(arrayClass);
-
-            for (int i = 0; i < firstArray.size(); i++) {
-                final RubyArray tuple = new RubyArray(arrayClass);
-                tuple.push(firstArray.get(i));
-                tuples.push(tuple);
-            }
-
-            return tuples;
-        } else {
-            final RubyArray intermediateTuples = product(arrayClass, arrays, l - 1);
-            final RubyArray lastArray = arrays[l - 1];
-
-            final RubyArray tuples = new RubyArray(arrayClass);
-
-            for (int n = 0; n < intermediateTuples.size(); n++) {
-                for (int i = 0; i < lastArray.size(); i++) {
-                    final RubyArray tuple = (RubyArray) ((RubyArray) intermediateTuples.get(n)).dup();
-                    tuple.push(lastArray.get(i));
-                    tuples.push(tuple);
-                }
-            }
-
-            return tuples;
-        }
-    }
-
-    public boolean equals(RubyArray other) {
-        if (other == null) {
-            return false;
-        } else if (other == this) {
-            return true;
-        } else {
-            return store.equals(other.store);
-        }
-    }
-
-    @Override
-    public boolean equals(Object other) {
-        if (other instanceof RubyArray) {
-            return equals((RubyArray) other);
-        } else {
-            return false;
-        }
-    }
-
-    @Override
-    public int hashCode() {
-        getRubyClass().getContext().implementationMessage("Array#hash returns nonsense");
-        return 0;
-    }
-
-    public RubyArray relativeComplement(RubyArray other) {
-        // TODO(cs): specialize for different stores
-
-        final RubyArray result = new RubyArray(getRubyClass().getContext().getCoreLibrary().getArrayClass());
-
-        for (Object value : asList()) {
-            if (!other.contains(value)) {
-                result.push(value);
-            }
-        }
-
-        return result;
-    }
-
-    public String join(String separator) {
-        final StringBuilder builder = new StringBuilder();
-
-        for (int n = 0; n < size(); n++) {
-            if (n > 0) {
-                builder.append(separator);
-            }
-
-            builder.append(get(n).toString());
-        }
-
-        return builder.toString();
-    }
-
-    public static String join(Object[] parts, String separator) {
-        final StringBuilder builder = new StringBuilder();
-
-        for (int n = 0; n < parts.length; n++) {
-            if (n > 0) {
-                builder.append(separator);
-            }
-
-            builder.append(parts[n].toString());
-        }
-
-        return builder.toString();
-    }
-
-    public void flattenTo(RubyArray result) {
-        for (int n = 0; n < size(); n++) {
-            final Object value = get(n);
-
-            if (value instanceof RubyArray) {
-                ((RubyArray) value).flattenTo(result);
-            } else {
-                result.push(value);
-            }
-        }
-    }
-
-    public boolean isEmpty() {
-        return store.size() == 0;
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/range/FixnumRange.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,128 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.runtime.core.range;
-
-import com.oracle.truffle.ruby.runtime.core.*;
-import com.oracle.truffle.ruby.runtime.core.array.*;
-
-/**
- * A range that has {@code Fixnum} begin and end.
- */
-public class FixnumRange extends RubyRange {
-
-    private final int begin;
-    private final int end;
-    private final boolean excludeEnd;
-
-    public FixnumRange(RubyClass rangeClass, int begin, int end, boolean excludeEnd) {
-        super(rangeClass);
-        this.begin = begin;
-        this.end = end;
-        this.excludeEnd = excludeEnd;
-    }
-
-    @Override
-    public String toString() {
-        if (excludeEnd) {
-            return begin + "..." + end;
-        } else {
-            return begin + ".." + end;
-        }
-    }
-
-    @Override
-    public RubyArray toArray() {
-        final int length = getLength();
-
-        if (length < 0) {
-            return new RubyArray(getRubyClass().getContext().getCoreLibrary().getArrayClass());
-        } else {
-            final int[] values = new int[length];
-
-            for (int n = 0; n < length; n++) {
-                values[n] = begin + n;
-            }
-
-            return new RubyArray(getRubyClass().getContext().getCoreLibrary().getArrayClass(), new FixnumArrayStore(values));
-        }
-    }
-
-    private int getLength() {
-        if (excludeEnd) {
-            return end - begin;
-        } else {
-            return end - begin + 1;
-        }
-    }
-
-    public final int getBegin() {
-        return begin;
-    }
-
-    public final int getEnd() {
-        return end;
-    }
-
-    public final int getInclusiveEnd() {
-        if (excludeEnd) {
-            return end - 1;
-        } else {
-            return end;
-        }
-    }
-
-    public final int getExclusiveEnd() {
-        if (excludeEnd) {
-            return end;
-        } else {
-            return end + 1;
-        }
-    }
-
-    @Override
-    public boolean doesExcludeEnd() {
-        return excludeEnd;
-    }
-
-    @Override
-    public int hashCode() {
-        final int prime = 31;
-        int result = 1;
-        result = prime * result + begin;
-        result = prime * result + end;
-        result = prime * result + (excludeEnd ? 1231 : 1237);
-        return result;
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj == null) {
-            return false;
-        }
-        if (!(obj instanceof FixnumRange)) {
-            return false;
-        }
-        FixnumRange other = (FixnumRange) obj;
-        if (begin != other.begin) {
-            return false;
-        }
-        if (end != other.end) {
-            return false;
-        }
-        if (excludeEnd != other.excludeEnd) {
-            return false;
-        }
-        return true;
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/range/ObjectRange.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,89 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.runtime.core.range;
-
-import com.oracle.truffle.ruby.runtime.core.*;
-import com.oracle.truffle.ruby.runtime.core.array.*;
-
-public class ObjectRange extends RubyRange {
-
-    private final Object begin;
-    private final Object end;
-    private final boolean excludeEnd;
-
-    public ObjectRange(RubyClass rangeClass, Object begin, Object end, boolean excludeEnd) {
-        super(rangeClass);
-        this.begin = begin;
-        this.end = end;
-        this.excludeEnd = excludeEnd;
-    }
-
-    @Override
-    public RubyArray toArray() {
-        throw new UnsupportedOperationException();
-    }
-
-    public Object getBegin() {
-        return begin;
-    }
-
-    public Object getEnd() {
-        return end;
-    }
-
-    @Override
-    public int hashCode() {
-        final int prime = 31;
-        int result = 1;
-        result = prime * result + ((begin == null) ? 0 : begin.hashCode());
-        result = prime * result + ((end == null) ? 0 : end.hashCode());
-        result = prime * result + (excludeEnd ? 1231 : 1237);
-        return result;
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj == null) {
-            return false;
-        }
-        if (!(obj instanceof ObjectRange)) {
-            return false;
-        }
-        ObjectRange other = (ObjectRange) obj;
-        if (begin == null) {
-            if (other.begin != null) {
-                return false;
-            }
-        } else if (!begin.equals(other.begin)) {
-            return false;
-        }
-        if (end == null) {
-            if (other.end != null) {
-                return false;
-            }
-        } else if (!end.equals(other.end)) {
-            return false;
-        }
-        if (excludeEnd != other.excludeEnd) {
-            return false;
-        }
-        return true;
-    }
-
-    @Override
-    public boolean doesExcludeEnd() {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/range/RubyRange.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,25 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.runtime.core.range;
-
-import com.oracle.truffle.ruby.runtime.core.*;
-import com.oracle.truffle.ruby.runtime.core.array.*;
-
-public abstract class RubyRange extends RubyObject {
-
-    public RubyRange(RubyClass rangeClass) {
-        super(rangeClass);
-    }
-
-    public abstract RubyArray toArray();
-
-    public abstract boolean doesExcludeEnd();
-
-}
--- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/debug/RubyProbe.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,41 +0,0 @@
-/*
- * Copyright (c) 2013, 2014 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.runtime.debug;
-
-import com.oracle.truffle.api.nodes.instrument.*;
-import com.oracle.truffle.ruby.runtime.*;
-
-/**
- * A "probe node" implemented specifically for the Ruby implementation; subclasses need only
- * override those members of {@link InstrumentationProbeEvents} for which some action is needed.
- */
-public abstract class RubyProbe extends InstrumentationProbeNode.DefaultProbeNode {
-
-    protected final boolean oneShot;
-
-    protected final RubyContext context;
-
-    /**
-     * OneShot is this a one-shot (self-removing) probe?
-     */
-    public RubyProbe(RubyContext context, boolean oneShot) {
-        super(context);
-        this.oneShot = oneShot;
-        this.context = context;
-    }
-
-    /**
-     * Is this a one-shot (self-removing) probe? If so, it will remove itself the first time
-     * activated.
-     */
-    public boolean isOneShot() {
-        return oneShot;
-    }
-}
--- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/debug/RubyTraceProbe.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,48 +0,0 @@
-/*
- * Copyright (c) 2013, 2014 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.runtime.debug;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.subsystems.*;
-
-/**
- * A "trace" probe that has no runtime cost until activated, at which time it invokes a trace
- * message.
- */
-public final class RubyTraceProbe extends RubyProbe {
-
-    private final Assumption notTracingAssumption;
-
-    @CompilerDirectives.CompilationFinal private boolean tracingEverEnabled = false;
-
-    public RubyTraceProbe(RubyContext context) {
-        super(context, false);
-        this.notTracingAssumption = context.getTraceManager().getNotTracingAssumption();
-    }
-
-    @Override
-    public void enter(Node astNode, VirtualFrame frame) {
-        if (!tracingEverEnabled) {
-            try {
-                notTracingAssumption.check();
-            } catch (InvalidAssumptionException e) {
-                tracingEverEnabled = true;
-            }
-        }
-        final TraceManager traceManager = context.getTraceManager();
-        if (tracingEverEnabled && traceManager.hasTraceProc()) {
-            final SourceSection sourceSection = astNode.getEncapsulatingSourceSection();
-            traceManager.trace("line", sourceSection.getSource().getName(), sourceSection.getStartLine(), 0, null, null);
-        }
-    }
-}
--- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/lookup/LookupFork.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,97 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.runtime.lookup;
-
-import java.util.*;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.utilities.*;
-import com.oracle.truffle.ruby.runtime.methods.*;
-
-/**
- * A fork in the lookup graph. Look at first and then look at second.
- */
-public class LookupFork implements LookupNode {
-
-    private LookupNode first;
-    private LookupNode second;
-
-    public LookupFork(LookupNode first, LookupNode second) {
-        this.first = first;
-        this.second = second;
-    }
-
-    public boolean setClassVariableIfAlreadySet(String variableName, Object value) {
-        if (first.setClassVariableIfAlreadySet(variableName, value)) {
-            return true;
-        }
-
-        return second.setClassVariableIfAlreadySet(variableName, value);
-    }
-
-    @Override
-    public Object lookupConstant(String constantName) {
-        final Object firstResult = first.lookupConstant(constantName);
-
-        if (firstResult != null) {
-            return firstResult;
-        }
-
-        return second.lookupConstant(constantName);
-    }
-
-    @Override
-    public Object lookupClassVariable(String classVariable) {
-        final Object firstResult = first.lookupClassVariable(classVariable);
-
-        if (firstResult != null) {
-            return firstResult;
-        }
-
-        return second.lookupClassVariable(classVariable);
-    }
-
-    @Override
-    public RubyMethod lookupMethod(String methodName) {
-        final RubyMethod firstResult = first.lookupMethod(methodName);
-
-        if (firstResult != null) {
-            return firstResult;
-        }
-
-        return second.lookupMethod(methodName);
-    }
-
-    @Override
-    public Assumption getUnmodifiedAssumption() {
-        return new UnionAssumption(first.getUnmodifiedAssumption(), second.getUnmodifiedAssumption());
-    }
-
-    public LookupNode getFirst() {
-        return first;
-    }
-
-    public LookupNode getSecond() {
-        return second;
-    }
-
-    public Set<String> getClassVariables() {
-        final Set<String> classVariables = new HashSet<>();
-        classVariables.addAll(first.getClassVariables());
-        classVariables.addAll(second.getClassVariables());
-        return classVariables;
-    }
-
-    public void getMethods(Map<String, RubyMethod> methods) {
-        second.getMethods(methods);
-        first.getMethods(methods);
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/lookup/LookupNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.runtime.lookup;
-
-import java.util.*;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.ruby.runtime.methods.*;
-
-/**
- * A node in the lookup graph. We abstract from modules and classes because with includes and
- * singletons and so on there are more nodes in the graph than there are classes and modules.
- */
-public interface LookupNode {
-
-    boolean setClassVariableIfAlreadySet(String variableName, Object value);
-
-    Object lookupConstant(String constantName);
-
-    Object lookupClassVariable(String variableName);
-
-    RubyMethod lookupMethod(String methodName);
-
-    Assumption getUnmodifiedAssumption();
-
-    Set<String> getClassVariables();
-
-    void getMethods(Map<String, RubyMethod> methods);
-
-}
--- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/lookup/LookupTerminal.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,56 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.runtime.lookup;
-
-import java.util.*;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.utilities.*;
-import com.oracle.truffle.ruby.runtime.methods.*;
-
-/**
- * A terminal in the lookup graph.
- */
-public class LookupTerminal implements LookupNode {
-
-    public static final LookupTerminal INSTANCE = new LookupTerminal();
-
-    public boolean setClassVariableIfAlreadySet(String variableName, Object value) {
-        return false;
-    }
-
-    @Override
-    public Object lookupConstant(String constantName) {
-        return null;
-    }
-
-    @Override
-    public Object lookupClassVariable(String constantName) {
-        return null;
-    }
-
-    @Override
-    public RubyMethod lookupMethod(String methodName) {
-        return null;
-    }
-
-    @Override
-    public Assumption getUnmodifiedAssumption() {
-        return AlwaysValidAssumption.INSTANCE;
-    }
-
-    public Set<String> getClassVariables() {
-        return Collections.emptySet();
-    }
-
-    public void getMethods(Map<String, RubyMethod> methods) {
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/methods/Arity.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,55 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.runtime.methods;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.control.*;
-
-/**
- * Represents the arity, or parameter contract, of a method.
- */
-public class Arity {
-
-    private final int minimum;
-    public static final int NO_MINIMUM = 0;
-
-    private final int maximum;
-    public static final int NO_MAXIMUM = Integer.MAX_VALUE;
-
-    public static final Arity NO_ARGS = new Arity(0, 0);
-    public static final Arity ONE_ARG = new Arity(1, 1);
-
-    public Arity(int minimum, int maximum) {
-        this.minimum = minimum;
-        this.maximum = maximum;
-    }
-
-    public void checkArguments(RubyContext context, Object[] arguments) {
-        if (arguments.length < minimum || arguments.length > maximum) {
-            CompilerDirectives.transferToInterpreter();
-            throw new RaiseException(context.getCoreLibrary().argumentError(arguments.length, minimum));
-        }
-    }
-
-    public int getMinimum() {
-        return minimum;
-    }
-
-    public int getMaximum() {
-        return maximum;
-    }
-
-    @Override
-    public String toString() {
-        return String.format("Arity(%d, %d)", minimum, maximum);
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/methods/CallTargetMethodImplementation.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,46 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.runtime.methods;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-
-public class CallTargetMethodImplementation implements MethodImplementation {
-
-    private final CallTarget callTarget;
-    private final MaterializedFrame declarationFrame;
-
-    public CallTargetMethodImplementation(CallTarget callTarget, MaterializedFrame declarationFrame) {
-        assert callTarget != null;
-
-        this.callTarget = callTarget;
-        this.declarationFrame = declarationFrame;
-    }
-
-    public Object call(PackedFrame caller, Object self, RubyProc block, Object... args) {
-        assert RubyContext.shouldObjectBeVisible(self);
-        assert RubyContext.shouldObjectsBeVisible(args);
-
-        RubyArguments arguments = new RubyArguments(declarationFrame, self, block, args);
-
-        final Object result = callTarget.call(caller, arguments);
-
-        assert RubyContext.shouldObjectBeVisible(result);
-
-        return result;
-    }
-
-    public MaterializedFrame getDeclarationFrame() {
-        return declarationFrame;
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/methods/MethodImplementation.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,19 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.runtime.methods;
-
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-
-public interface MethodImplementation {
-
-    Object call(PackedFrame caller, Object self, RubyProc block, Object... args);
-
-}
--- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/methods/RubyMethod.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,168 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.runtime.methods;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-import com.oracle.truffle.ruby.runtime.objects.*;
-
-/**
- * Any kind of Ruby method - so normal methods in classes and modules, but also blocks, procs,
- * lambdas and native methods written in Java.
- */
-public class RubyMethod {
-
-    private final SourceSection sourceSection;
-    private final RubyModule declaringModule;
-    private final UniqueMethodIdentifier uniqueIdentifier;
-    private final String intrinsicName;
-    private final String name;
-    private final Visibility visibility;
-    private final boolean undefined;
-
-    private final MethodImplementation implementation;
-
-    public RubyMethod(SourceSection sourceSection, RubyModule declaringModule, UniqueMethodIdentifier uniqueIdentifier, String intrinsicName, String name, Visibility visibility, boolean undefined,
-                    MethodImplementation implementation) {
-        this.sourceSection = sourceSection;
-        this.declaringModule = declaringModule;
-        this.uniqueIdentifier = uniqueIdentifier;
-        this.intrinsicName = intrinsicName;
-        this.name = name;
-        this.visibility = visibility;
-        this.undefined = undefined;
-        this.implementation = implementation;
-    }
-
-    public Object call(PackedFrame caller, Object self, RubyProc block, Object... args) {
-        assert RubyContext.shouldObjectBeVisible(self);
-        assert RubyContext.shouldObjectsBeVisible(args);
-
-        final Object result = implementation.call(caller, self, block, args);
-
-        assert RubyContext.shouldObjectBeVisible(result);
-
-        return result;
-    }
-
-    public SourceSection getSourceSection() {
-        return sourceSection;
-    }
-
-    public UniqueMethodIdentifier getUniqueIdentifier() {
-        return uniqueIdentifier;
-    }
-
-    public String getIntrinsicName() {
-        return intrinsicName;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public Visibility getVisibility() {
-        return visibility;
-    }
-
-    public boolean isUndefined() {
-        return undefined;
-    }
-
-    public MethodImplementation getImplementation() {
-        return implementation;
-    }
-
-    public RubyMethod withNewName(String newName) {
-        if (newName.equals(name)) {
-            return this;
-        }
-
-        return new RubyMethod(sourceSection, declaringModule, uniqueIdentifier, intrinsicName, newName, visibility, undefined, implementation);
-    }
-
-    public RubyMethod withNewVisibility(Visibility newVisibility) {
-        if (newVisibility == visibility) {
-            return this;
-        }
-
-        return new RubyMethod(sourceSection, declaringModule, uniqueIdentifier, intrinsicName, name, newVisibility, undefined, implementation);
-    }
-
-    public RubyMethod withDeclaringModule(RubyModule newDeclaringModule) {
-        if (newDeclaringModule == declaringModule) {
-            return this;
-        }
-
-        return new RubyMethod(sourceSection, newDeclaringModule, uniqueIdentifier, intrinsicName, name, visibility, undefined, implementation);
-    }
-
-    public RubyMethod undefined() {
-        if (undefined) {
-            return this;
-        }
-
-        return new RubyMethod(sourceSection, declaringModule, uniqueIdentifier, intrinsicName, name, visibility, true, implementation);
-    }
-
-    public boolean isVisibleTo(RubyBasicObject caller) {
-        if (caller instanceof RubyModule) {
-            if (isVisibleTo((RubyModule) caller)) {
-                return true;
-            }
-        }
-
-        if (isVisibleTo(caller.getRubyClass())) {
-            return true;
-        }
-
-        if (isVisibleTo(caller.getSingletonClass())) {
-            return true;
-        }
-
-        return false;
-    }
-
-    private boolean isVisibleTo(RubyModule module) {
-        switch (visibility) {
-            case PUBLIC:
-                return true;
-
-            case PROTECTED:
-                return true;
-
-            case PRIVATE:
-                if (module == declaringModule) {
-                    return true;
-                }
-
-                if (module.getSingletonClass() == declaringModule) {
-                    return true;
-                }
-
-                if (module.getParentModule() != null && isVisibleTo(module.getParentModule())) {
-                    return true;
-                }
-
-                return false;
-
-            default:
-                return false;
-        }
-    }
-
-    @Override
-    public String toString() {
-        return implementation.toString();
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/methods/UniqueMethodIdentifier.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,18 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.runtime.methods;
-
-/**
- * An object that uniquely identifies a method as it appears in the source code, and that follows
- * the method as a normal method, when it becomes a proc, when it changes access or is aliased etc.
- */
-public class UniqueMethodIdentifier {
-
-}
--- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/methods/Visibility.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,17 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.runtime.methods;
-
-/**
- * Represents the visibility of a method.
- */
-public enum Visibility {
-    PUBLIC, PROTECTED, PRIVATE
-}
--- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/objects/FixnumStorageLocation.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,63 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.runtime.objects;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-
-/**
- * A storage location for Fixnums.
- */
-public class FixnumStorageLocation extends PrimitiveStorageLocation {
-
-    public FixnumStorageLocation(ObjectLayout objectLayout, long offset, int mask) {
-        super(objectLayout, offset, mask);
-    }
-
-    @Override
-    public Object read(RubyBasicObject object, boolean condition) {
-        try {
-            return readFixnum(object, condition);
-        } catch (UnexpectedResultException e) {
-            return e.getResult();
-        }
-    }
-
-    public int readFixnum(RubyBasicObject object, boolean condition) throws UnexpectedResultException {
-        if (isSet(object)) {
-            return CompilerDirectives.unsafeGetInt(object, offset, condition, this);
-        } else {
-            throw new UnexpectedResultException(NilPlaceholder.INSTANCE);
-        }
-    }
-
-    @Override
-    public void write(RubyBasicObject object, Object value) throws GeneralizeStorageLocationException {
-        if (value instanceof Integer) {
-            writeFixnum(object, (int) value);
-        } else if (value instanceof NilPlaceholder) {
-            markAsUnset(object);
-        } else {
-            throw new GeneralizeStorageLocationException();
-        }
-    }
-
-    public void writeFixnum(RubyBasicObject object, int value) {
-        CompilerDirectives.unsafePutInt(object, offset, value, null);
-        markAsSet(object);
-    }
-
-    @Override
-    public Class getStoredClass() {
-        return Integer.class;
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/objects/FloatStorageLocation.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,63 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.runtime.objects;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.ruby.runtime.*;
-
-/**
- * A storage location for Floats.
- */
-public class FloatStorageLocation extends PrimitiveStorageLocation {
-
-    public FloatStorageLocation(ObjectLayout objectLayout, long offset, int mask) {
-        super(objectLayout, offset, mask);
-    }
-
-    @Override
-    public Object read(RubyBasicObject object, boolean condition) {
-        try {
-            return readFloat(object, condition);
-        } catch (UnexpectedResultException e) {
-            return e.getResult();
-        }
-    }
-
-    public double readFloat(RubyBasicObject object, boolean condition) throws UnexpectedResultException {
-        if (isSet(object)) {
-            return CompilerDirectives.unsafeGetDouble(object, offset, condition, this);
-        } else {
-            throw new UnexpectedResultException(NilPlaceholder.INSTANCE);
-        }
-    }
-
-    @Override
-    public void write(RubyBasicObject object, Object value) throws GeneralizeStorageLocationException {
-        if (value instanceof Double) {
-            writeFloat(object, (double) value);
-        } else if (value instanceof NilPlaceholder) {
-            markAsUnset(object);
-        } else {
-            throw new GeneralizeStorageLocationException();
-        }
-    }
-
-    public void writeFloat(RubyBasicObject object, Double value) {
-        CompilerDirectives.unsafePutDouble(object, offset, value, null);
-        markAsSet(object);
-    }
-
-    @Override
-    public Class getStoredClass() {
-        return Double.class;
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/objects/GeneralizeStorageLocationException.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,19 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.runtime.objects;
-
-/**
- * Indicates that a storage location cannot store the type of value that you asked it to.
- */
-public class GeneralizeStorageLocationException extends Exception {
-
-    private static final long serialVersionUID = -5136358171098229961L;
-
-}
--- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/objects/ObjectLayout.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,235 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.runtime.objects;
-
-import java.lang.reflect.*;
-import java.util.*;
-import java.util.Map.Entry;
-
-import sun.misc.*;
-
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.api.nodes.NodeUtil.*;
-
-/**
- * Maps names of instance variables to storage locations, which are either the offset of a primitive
- * field in {@code RubyBasicObject}, or an index into an object array in {@code RubyBasicObject}.
- * Object layouts are chained, with each having zero or one parents.
- * <p>
- * Object layouts are immutable, with the methods for adding new instance variables of generalizing
- * the type of existing instance variables returning new object layouts.
- */
-public class ObjectLayout {
-
-    public static final ObjectLayout EMPTY = new ObjectLayout("(empty)");
-
-    private final String originHint;
-
-    private final ObjectLayout parent;
-
-    private final Map<String, StorageLocation> storageLocations = new HashMap<>();
-
-    private final int primitiveStorageLocationsUsed;
-    private final int objectStorageLocationsUsed;
-
-    public static final long FIRST_OFFSET = getFirstOffset();
-
-    private ObjectLayout(String originHint) {
-        this.originHint = originHint;
-        this.parent = null;
-        primitiveStorageLocationsUsed = 0;
-        objectStorageLocationsUsed = 0;
-    }
-
-    public ObjectLayout(String originHint, ObjectLayout parent) {
-        this(originHint, parent, new HashMap<String, Class>());
-    }
-
-    public ObjectLayout(String originHint, ObjectLayout parent, Map<String, Class> storageTypes) {
-        this.originHint = originHint;
-        this.parent = parent;
-
-        // Start our offsets from where the parent ends
-
-        int primitiveStorageLocationIndex;
-        int objectStorageLocationIndex;
-
-        if (parent == null) {
-            primitiveStorageLocationIndex = 0;
-            objectStorageLocationIndex = 0;
-        } else {
-            primitiveStorageLocationIndex = parent.primitiveStorageLocationsUsed;
-            objectStorageLocationIndex = parent.objectStorageLocationsUsed;
-        }
-
-        // Go through the variables we've been asked to store
-
-        for (Entry<String, Class> entry : storageTypes.entrySet()) {
-            // TODO(cs): what if parent has it, but we need a more general type?
-
-            final String name = entry.getKey();
-            final Class type = entry.getValue();
-
-            if (parent == null || parent.findStorageLocation(name) == null) {
-                boolean canStoreInPrimitive = false;
-                int primitivesNeeded = 0;
-
-                if (type == Integer.class) {
-                    canStoreInPrimitive = true;
-                    primitivesNeeded = 1;
-                } else if (type == Double.class) {
-                    canStoreInPrimitive = true;
-                    primitivesNeeded = 2;
-                }
-
-                if (canStoreInPrimitive && primitiveStorageLocationIndex + primitivesNeeded <= RubyBasicObject.PRIMITIVE_STORAGE_LOCATIONS_COUNT) {
-                    final long offset = FIRST_OFFSET + Unsafe.ARRAY_INT_INDEX_SCALE * primitiveStorageLocationIndex;
-                    final int mask = 1 << primitiveStorageLocationIndex;
-
-                    StorageLocation newStorageLocation = null;
-
-                    if (type == Integer.class) {
-                        newStorageLocation = new FixnumStorageLocation(this, offset, mask);
-                    } else if (type == Double.class) {
-                        newStorageLocation = new FloatStorageLocation(this, offset, mask);
-                    }
-
-                    storageLocations.put(entry.getKey(), newStorageLocation);
-                    primitiveStorageLocationIndex += primitivesNeeded;
-                } else {
-                    final ObjectStorageLocation newStorageLocation = new ObjectStorageLocation(this, objectStorageLocationIndex);
-                    storageLocations.put(entry.getKey(), newStorageLocation);
-                    objectStorageLocationIndex++;
-                }
-            }
-        }
-
-        primitiveStorageLocationsUsed = primitiveStorageLocationIndex;
-        objectStorageLocationsUsed = objectStorageLocationIndex;
-    }
-
-    /**
-     * Create a new version of this layout, but with a different parent. The new parent probably
-     * comes from the same Ruby class as it did, but it's a new layout because layouts are
-     * immutable, so modifications to the superclass yields a new layout.
-     */
-    public ObjectLayout renew(ObjectLayout newParent) {
-        return new ObjectLayout(originHint + ".renewed", newParent, getStorageTypes());
-    }
-
-    /**
-     * Create a new version of this layout but with a new variable.
-     */
-    public ObjectLayout withNewVariable(String name, Class type) {
-        final Map<String, Class> storageTypes = getStorageTypes();
-        storageTypes.put(name, type);
-        return new ObjectLayout(originHint + ".withnew", parent, storageTypes);
-    }
-
-    /**
-     * Create a new version of this layout but with an existing variable generalized to support any
-     * type.
-     */
-    public ObjectLayout withGeneralisedVariable(String name) {
-        return withNewVariable(name, Object.class);
-    }
-
-    /**
-     * Get a map of instance variable names to the type that they store.
-     */
-    public Map<String, Class> getStorageTypes() {
-        Map<String, Class> storageTypes = new HashMap<>();
-
-        for (Entry<String, StorageLocation> entry : storageLocations.entrySet()) {
-            final String name = entry.getKey();
-            final StorageLocation storageLocation = entry.getValue();
-
-            if (storageLocation.getStoredClass() != null) {
-                storageTypes.put(name, storageLocation.getStoredClass());
-            }
-        }
-
-        return storageTypes;
-    }
-
-    /**
-     * Get a map of instance variable names to the type that they store, but including both this
-     * layout and all parent layouts.
-     */
-    public Map<String, StorageLocation> getAllStorageLocations() {
-        final Map<String, StorageLocation> allStorageLocations = new HashMap<>();
-
-        allStorageLocations.putAll(storageLocations);
-
-        if (parent != null) {
-            allStorageLocations.putAll(parent.getAllStorageLocations());
-        }
-
-        return allStorageLocations;
-    }
-
-    /**
-     * Find a storage location from a name, including in parents.
-     */
-    public StorageLocation findStorageLocation(String name) {
-        final StorageLocation storageLocation = storageLocations.get(name);
-
-        if (storageLocation != null) {
-            return storageLocation;
-        }
-
-        if (parent == null) {
-            return null;
-        }
-
-        return parent.findStorageLocation(name);
-    }
-
-    public int getObjectStorageLocationsUsed() {
-        return objectStorageLocationsUsed;
-    }
-
-    /**
-     * Does this layout include another layout? That is, is that other layout somewhere in the chain
-     * of parents? We say 'include' because all of the variables in a parent layout are available in
-     * your layout as well.
-     */
-    public boolean contains(ObjectLayout other) {
-        ObjectLayout layout = this;
-
-        do {
-            if (other == layout) {
-                return true;
-            }
-
-            layout = layout.parent;
-        } while (layout != null);
-
-        return false;
-    }
-
-    public String getOriginHint() {
-        return originHint;
-    }
-
-    private static long getFirstOffset() {
-        try {
-            final Field fieldOffsetProviderField = NodeUtil.class.getDeclaredField("unsafeFieldOffsetProvider");
-            fieldOffsetProviderField.setAccessible(true);
-            final FieldOffsetProvider fieldOffsetProvider = (FieldOffsetProvider) fieldOffsetProviderField.get(null);
-
-            final Field firstPrimitiveField = RubyBasicObject.class.getDeclaredField("primitiveStorageLocation01");
-            return fieldOffsetProvider.objectFieldOffset(firstPrimitiveField);
-        } catch (NoSuchFieldException | IllegalAccessException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/objects/ObjectStorageLocation.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.runtime.objects;
-
-import com.oracle.truffle.ruby.runtime.*;
-
-/**
- * A storage location for any object.
- */
-public class ObjectStorageLocation extends StorageLocation {
-
-    private final int index;
-
-    public ObjectStorageLocation(ObjectLayout objectLayout, int index) {
-        super(objectLayout);
-        this.index = index;
-    }
-
-    @Override
-    public boolean isSet(RubyBasicObject object) {
-        return object.objectStorageLocations[index] != null;
-    }
-
-    @Override
-    public Object read(RubyBasicObject object, boolean condition) {
-        final Object result = object.objectStorageLocations[index];
-
-        if (result == null) {
-            return NilPlaceholder.INSTANCE;
-        } else {
-            return result;
-        }
-    }
-
-    @Override
-    public void write(RubyBasicObject object, Object value) {
-        object.objectStorageLocations[index] = value;
-    }
-
-    @Override
-    public Class getStoredClass() {
-        return Object.class;
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/objects/PrimitiveStorageLocation.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.runtime.objects;
-
-/**
- * A storage location that uses one of the primitive fields in {@code RubyBasObject}.
- */
-public abstract class PrimitiveStorageLocation extends StorageLocation {
-
-    protected final long offset;
-    protected final int mask;
-
-    protected PrimitiveStorageLocation(ObjectLayout objectLayout, long offset, int mask) {
-        super(objectLayout);
-        this.offset = offset;
-        this.mask = mask;
-    }
-
-    @Override
-    public boolean isSet(RubyBasicObject object) {
-        return (object.primitiveSetMap & mask) != 0;
-    }
-
-    protected void markAsSet(RubyBasicObject object) {
-        object.primitiveSetMap |= mask;
-    }
-
-    protected void markAsUnset(RubyBasicObject object) {
-        object.primitiveSetMap &= ~mask;
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/objects/RubyBasicObject.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,360 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.runtime.objects;
-
-import java.util.*;
-import java.util.Map.Entry;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.control.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-import com.oracle.truffle.ruby.runtime.lookup.*;
-import com.oracle.truffle.ruby.runtime.methods.*;
-
-/**
- * Represents the Ruby {@code BasicObject} class - the root of the Ruby class hierarchy.
- */
-public class RubyBasicObject {
-
-    @CompilationFinal protected RubyClass rubyClass;
-    protected RubyClass rubySingletonClass;
-
-    protected LookupNode lookupNode;
-
-    protected long objectID = -1;
-
-    public boolean hasPrivateLayout = false;
-    private ObjectLayout objectLayout;
-
-    public static final int PRIMITIVE_STORAGE_LOCATIONS_COUNT = 14;
-    protected int primitiveStorageLocation01;
-    protected int primitiveStorageLocation02;
-    protected int primitiveStorageLocation03;
-    protected int primitiveStorageLocation04;
-    protected int primitiveStorageLocation05;
-    protected int primitiveStorageLocation06;
-    protected int primitiveStorageLocation07;
-    protected int primitiveStorageLocation08;
-    protected int primitiveStorageLocation09;
-    protected int primitiveStorageLocation10;
-    protected int primitiveStorageLocation11;
-    protected int primitiveStorageLocation12;
-    protected int primitiveStorageLocation13;
-    protected int primitiveStorageLocation14;
-
-    // A bit map to indicate which primitives are set, so that they can be Nil
-    protected int primitiveSetMap;
-
-    protected Object[] objectStorageLocations;
-
-    public RubyBasicObject(RubyClass rubyClass) {
-        if (rubyClass != null) {
-            unsafeSetRubyClass(rubyClass);
-
-            if (rubyClass.getContext().getConfiguration().getFullObjectSpace()) {
-                rubyClass.getContext().getObjectSpaceManager().add(this);
-            }
-        }
-    }
-
-    public void initialize() {
-    }
-
-    public LookupNode getLookupNode() {
-        return lookupNode;
-    }
-
-    public RubyClass getRubyClass() {
-        assert rubyClass != null;
-        return rubyClass;
-    }
-
-    public boolean hasPrivateLayout() {
-        return hasPrivateLayout;
-    }
-
-    public ObjectLayout getObjectLayout() {
-        return objectLayout;
-    }
-
-    public ObjectLayout getUpdatedObjectLayout() {
-        updateLayout();
-        return objectLayout;
-    }
-
-    /**
-     * Does this object have an instance variable defined?
-     */
-    public boolean isInstanceVariableDefined(String name) {
-        if (!hasPrivateLayout && objectLayout != rubyClass.getObjectLayoutForInstances()) {
-            updateLayout();
-        }
-
-        return objectLayout.findStorageLocation(name) != null;
-    }
-
-    /**
-     * Set an instance variable to be a value. Slow path.
-     */
-    public void setInstanceVariable(String name, Object value) {
-        CompilerAsserts.neverPartOfCompilation();
-
-        // If the object's layout doesn't match the class, update
-
-        if (!hasPrivateLayout && objectLayout != rubyClass.getObjectLayoutForInstances()) {
-            updateLayout();
-        }
-
-        // Find the storage location
-
-        StorageLocation storageLocation = objectLayout.findStorageLocation(name);
-
-        if (storageLocation == null) {
-            /*
-             * It doesn't exist, so create a new layout for the class that includes it and update
-             * the layout of this object.
-             */
-
-            rubyClass.setObjectLayoutForInstances(rubyClass.getObjectLayoutForInstances().withNewVariable(name, value.getClass()));
-            updateLayout();
-
-            storageLocation = objectLayout.findStorageLocation(name);
-        }
-
-        // Try to write to that storage location
-
-        try {
-            storageLocation.write(this, value);
-        } catch (GeneralizeStorageLocationException e) {
-            /*
-             * It might not be able to store the type that we passed, if not generalize the class's
-             * layout and update the layout of this object.
-             */
-
-            rubyClass.setObjectLayoutForInstances(rubyClass.getObjectLayoutForInstances().withGeneralisedVariable(name));
-            updateLayout();
-
-            storageLocation = objectLayout.findStorageLocation(name);
-
-            // Try to write to the generalized storage location
-
-            try {
-                storageLocation.write(this, value);
-            } catch (GeneralizeStorageLocationException e1) {
-                // We know that we just generalized it, so this should not happen
-                throw new RuntimeException("Generalised an instance variable, but it still rejected the value");
-            }
-        }
-    }
-
-    /**
-     * Get the value of an instance variable, or Nil if it isn't defined. Slow path.
-     */
-    public Object getInstanceVariable(String name) {
-        CompilerAsserts.neverPartOfCompilation();
-
-        // If the object's layout doesn't match the class, update
-
-        if (!hasPrivateLayout && objectLayout != rubyClass.getObjectLayoutForInstances()) {
-            updateLayout();
-        }
-
-        // Find the storage location
-
-        final StorageLocation storageLocation = objectLayout.findStorageLocation(name);
-
-        // Get the value
-
-        if (storageLocation == null) {
-            return NilPlaceholder.INSTANCE;
-        }
-
-        return storageLocation.read(this, true);
-    }
-
-    public String[] getInstanceVariableNames() {
-        final Set<String> instanceVariableNames = getInstanceVariables().keySet();
-        return instanceVariableNames.toArray(new String[instanceVariableNames.size()]);
-    }
-
-    public RubyClass getSingletonClass() {
-        if (rubySingletonClass == null) {
-            /*
-             * The object a of class A has a singleton class a' of class Class, with name
-             * #<Class:#<A:objectid>>, and with superclass that is A.
-             * 
-             * irb(main):001:0> class A; end
-             * 
-             * => nil
-             * 
-             * irb(main):002:0> a = A.new
-             * 
-             * => #<A:0x007ff612a631e0>
-             * 
-             * irb(main):003:0> a.singleton_class
-             * 
-             * => #<Class:#<A:0x007ff612a631e0>>
-             * 
-             * irb(main):004:0> a.singleton_class.class
-             * 
-             * => Class
-             * 
-             * irb(main):005:0> a.singleton_class.superclass
-             * 
-             * => A
-             */
-
-            rubySingletonClass = new RubyClass(rubyClass.getParentModule(), rubyClass, String.format("#<Class:#<%s:%d>>", rubyClass.getName(), getObjectID()), true);
-
-            lookupNode = new LookupFork(rubySingletonClass, rubyClass);
-        }
-
-        return rubySingletonClass;
-    }
-
-    public long getObjectID() {
-        if (objectID == -1) {
-            objectID = rubyClass.getContext().getNextObjectID();
-        }
-
-        return objectID;
-    }
-
-    public String inspect() {
-        return toString();
-    }
-
-    /**
-     * Get a map of all instance variables.
-     */
-    protected Map<String, Object> getInstanceVariables() {
-        if (objectLayout == null) {
-            return Collections.emptyMap();
-        }
-
-        final Map<String, Object> instanceVariableMap = new HashMap<>();
-
-        for (Entry<String, StorageLocation> entry : objectLayout.getAllStorageLocations().entrySet()) {
-            final String name = entry.getKey();
-            final StorageLocation storageLocation = entry.getValue();
-
-            if (storageLocation.isSet(this)) {
-                instanceVariableMap.put(name, storageLocation.read(this, true));
-            }
-        }
-
-        return instanceVariableMap;
-    }
-
-    /**
-     * Set instance variables from a map.
-     */
-    protected void setInstanceVariables(Map<String, Object> instanceVariables) {
-        assert instanceVariables != null;
-
-        if (objectLayout == null) {
-            updateLayout();
-        }
-
-        for (Entry<String, Object> entry : instanceVariables.entrySet()) {
-            final StorageLocation storageLocation = objectLayout.findStorageLocation(entry.getKey());
-            assert storageLocation != null;
-
-            try {
-                storageLocation.write(this, entry.getValue());
-            } catch (GeneralizeStorageLocationException e) {
-                throw new RuntimeException("Should not have to be generalising when setting instance variables - " + entry.getValue().getClass().getName() + ", " +
-                                storageLocation.getStoredClass().getName());
-            }
-        }
-    }
-
-    /**
-     * Update the layout of this object to match that of its class.
-     */
-    @CompilerDirectives.SlowPath
-    public void updateLayout() {
-        // Get the current values of instance variables
-
-        final Map<String, Object> instanceVariableMap = getInstanceVariables();
-
-        // Use the layout of the class
-
-        objectLayout = rubyClass.getObjectLayoutForInstances();
-
-        // Make all primitives as unset
-
-        primitiveSetMap = 0;
-
-        // Create a new array for objects
-
-        allocateObjectStorageLocations();
-
-        // Restore values
-
-        setInstanceVariables(instanceVariableMap);
-    }
-
-    private void allocateObjectStorageLocations() {
-        final int objectStorageLocationsUsed = objectLayout.getObjectStorageLocationsUsed();
-
-        if (objectStorageLocationsUsed == 0) {
-            objectStorageLocations = null;
-        } else {
-            objectStorageLocations = new Object[objectStorageLocationsUsed];
-        }
-    }
-
-    public void switchToPrivateLayout() {
-        final Map<String, Object> instanceVariables = getInstanceVariables();
-
-        hasPrivateLayout = true;
-        objectLayout = ObjectLayout.EMPTY;
-
-        for (Entry<String, Object> entry : instanceVariables.entrySet()) {
-            objectLayout = objectLayout.withNewVariable(entry.getKey(), entry.getValue().getClass());
-        }
-
-        setInstanceVariables(instanceVariables);
-    }
-
-    public void extend(RubyModule module) {
-        getSingletonClass().include(module);
-    }
-
-    @Override
-    public String toString() {
-        return "#<" + rubyClass.getName() + ":0x" + Long.toHexString(getObjectID()) + ">";
-    }
-
-    public boolean hasSingletonClass() {
-        return rubySingletonClass != null;
-    }
-
-    public Object send(String name, RubyProc block, Object... args) {
-        final RubyMethod method = getLookupNode().lookupMethod(name);
-
-        if (method == null || method.isUndefined()) {
-            throw new RaiseException(getRubyClass().getContext().getCoreLibrary().noMethodError(name, toString()));
-        }
-
-        return method.call(null, this, block, args);
-    }
-
-    public void unsafeSetRubyClass(RubyClass newRubyClass) {
-        assert rubyClass == null;
-
-        rubyClass = newRubyClass;
-        lookupNode = rubyClass;
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/objects/StorageLocation.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,35 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.runtime.objects;
-
-/**
- * A storage location that abstracts the method for reading and writing values.
- */
-public abstract class StorageLocation {
-
-    private ObjectLayout objectLayout;
-
-    protected StorageLocation(ObjectLayout objectLayout) {
-        this.objectLayout = objectLayout;
-    }
-
-    public abstract boolean isSet(RubyBasicObject object);
-
-    public abstract Object read(RubyBasicObject object, boolean condition);
-
-    public abstract void write(RubyBasicObject object, Object value) throws GeneralizeStorageLocationException;
-
-    public abstract Class getStoredClass();
-
-    public ObjectLayout getObjectLayout() {
-        return objectLayout;
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/objects/Unboxable.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,19 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.runtime.objects;
-
-/**
- * An object that can be losslessly unboxed back to a more primitive value.
- */
-public interface Unboxable {
-
-    Object unbox();
-
-}
--- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/subsystems/AtExitManager.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,34 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.runtime.subsystems;
-
-import java.util.*;
-
-import com.oracle.truffle.ruby.runtime.core.*;
-
-/**
- * Manages at_exit callbacks.
- */
-public class AtExitManager {
-
-    private final List<RubyProc> blocks = new ArrayList<>();
-
-    public void add(RubyProc block) {
-        blocks.add(block);
-    }
-
-    public void run() {
-        final ListIterator<RubyProc> iterator = blocks.listIterator(blocks.size());
-
-        while (iterator.hasPrevious()) {
-            iterator.previous().call(null);
-        }
-    }
-}
--- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/subsystems/FeatureManager.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,141 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.runtime.subsystems;
-
-import java.io.*;
-import java.net.*;
-import java.util.*;
-
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.control.*;
-import com.oracle.truffle.ruby.runtime.core.array.*;
-
-/**
- * Manages the features loaded into Ruby. This basically means which library files are loaded, but
- * Ruby often talks about requiring features, not files.
- * 
- */
-public class FeatureManager {
-
-    private RubyContext context;
-
-    private final Set<String> requiredFiles = new HashSet<>();
-
-    public FeatureManager(RubyContext context) {
-        this.context = context;
-    }
-
-    public boolean require(String feature) throws IOException {
-        // Some features are handled specially
-
-        if (feature.equals("stringio")) {
-            context.implementationMessage("stringio not yet implemented");
-            return true;
-        }
-
-        if (feature.equals("rbconfig")) {
-            // Kernel#rbconfig is always there
-            return true;
-        }
-
-        if (feature.equals("pp")) {
-            // Kernel#pretty_inspect is always there
-            return true;
-        }
-
-        // Get the load path
-
-        final Object loadPathObject = context.getCoreLibrary().getGlobalVariablesObject().getInstanceVariable("$:");
-
-        if (!(loadPathObject instanceof RubyArray)) {
-            throw new RuntimeException("$: is not an array");
-        }
-
-        final List<Object> loadPath = ((RubyArray) loadPathObject).asList();
-
-        // Try as a full path
-
-        if (requireInPath("", feature)) {
-            return true;
-        }
-
-        // Try each load path in turn
-
-        for (Object pathObject : loadPath) {
-            final String path = pathObject.toString();
-
-            if (requireInPath(path, feature)) {
-                return true;
-            }
-        }
-
-        // Didn't find the feature
-
-        throw new RaiseException(context.getCoreLibrary().loadErrorCannotLoad(feature));
-    }
-
-    public boolean requireInPath(String path, String feature) throws IOException {
-        if (requireFile(feature)) {
-            return true;
-        }
-
-        if (requireFile(feature + ".rb")) {
-            return true;
-        }
-
-        if (requireFile(path + File.separator + feature)) {
-            return true;
-        }
-
-        if (requireFile(path + File.separator + feature + ".rb")) {
-            return true;
-        }
-
-        return false;
-    }
-
-    private boolean requireFile(String fileName) throws IOException {
-        if (requiredFiles.contains(fileName)) {
-            return true;
-        }
-
-        /*
-         * There is unfortunately no way to check if a string is a file path, or a URL. file:foo.txt
-         * is a valid file name, as well as a valid URL. We try as a file path first.
-         */
-
-        if (new File(fileName).isFile()) {
-            context.loadFile(fileName);
-            requiredFiles.add(fileName);
-            return true;
-        } else {
-            URL url;
-
-            try {
-                url = new URL(fileName);
-            } catch (MalformedURLException e) {
-                return false;
-            }
-
-            InputStream inputStream;
-
-            try {
-                inputStream = url.openConnection().getInputStream();
-            } catch (IOException e) {
-                return false;
-            }
-
-            context.load(context.getSourceManager().get(url.toString(), inputStream));
-            requiredFiles.add(fileName);
-            return true;
-        }
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/subsystems/FiberManager.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,55 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.runtime.subsystems;
-
-import java.util.*;
-import java.util.concurrent.*;
-
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-
-/**
- * Manages Ruby {@code Fiber} objects.
- */
-public class FiberManager {
-
-    private final RubyFiber rootFiber;
-    private RubyFiber currentFiber;
-
-    private final Set<RubyFiber> runningFibers = Collections.newSetFromMap(new ConcurrentHashMap<RubyFiber, Boolean>());
-
-    public FiberManager(RubyContext context) {
-        rootFiber = new RubyFiber(context.getCoreLibrary().getFiberClass(), this, context.getThreadManager());
-        currentFiber = rootFiber;
-    }
-
-    public RubyFiber getCurrentFiber() {
-        return currentFiber;
-    }
-
-    public void setCurrentFiber(RubyFiber fiber) {
-        currentFiber = fiber;
-    }
-
-    public void registerFiber(RubyFiber fiber) {
-        runningFibers.add(fiber);
-    }
-
-    public void unregisterFiber(RubyFiber fiber) {
-        runningFibers.remove(fiber);
-    }
-
-    public void shutdown() {
-        for (RubyFiber fiber : runningFibers) {
-            fiber.shutdown();
-        }
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/subsystems/ObjectSpaceManager.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,193 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.runtime.subsystems;
-
-import java.lang.ref.*;
-import java.util.*;
-import java.util.concurrent.*;
-
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-import com.oracle.truffle.ruby.runtime.objects.*;
-
-/**
- * Supports the Ruby {@code ObjectSpace} module. Object IDs are lazily allocated {@code long}
- * values, mapped to objects with a weak hash map. Finalizers are implemented with weak references
- * and reference queues, and are run in a dedicated Ruby thread (but not a dedicated Java thread).
- */
-public class ObjectSpaceManager {
-
-    private class FinalizerReference extends WeakReference<RubyBasicObject> {
-
-        public List<RubyProc> finalizers = new LinkedList<>();
-
-        public FinalizerReference(RubyBasicObject object, ReferenceQueue<? super RubyBasicObject> queue) {
-            super(object, queue);
-        }
-
-        public void addFinalizer(RubyProc proc) {
-            finalizers.add(proc);
-        }
-
-        public List<RubyProc> getFinalizers() {
-            return finalizers;
-        }
-
-        public void clearFinalizers() {
-            finalizers = new LinkedList<>();
-        }
-
-    }
-
-    private final RubyContext context;
-
-    // TODO(cs): this is wrong - WeakHashMap is not weak in the value
-    private final WeakHashMap<Long, RubyBasicObject> objects = new WeakHashMap<>();
-
-    private final Map<RubyBasicObject, FinalizerReference> finalizerReferences = new WeakHashMap<>();
-    private final ReferenceQueue<RubyBasicObject> finalizerQueue = new ReferenceQueue<>();
-    private RubyThread finalizerThread;
-    private Thread finalizerJavaThread;
-    private boolean stop;
-    private CountDownLatch finished = new CountDownLatch(1);
-
-    public ObjectSpaceManager(RubyContext context) {
-        this.context = context;
-    }
-
-    public void add(RubyBasicObject object) {
-        objects.put(object.getObjectID(), object);
-    }
-
-    public RubyBasicObject lookupId(long id) {
-        return objects.get(id);
-    }
-
-    public void defineFinalizer(RubyBasicObject object, RubyProc proc) {
-        // Record the finalizer against the object
-
-        FinalizerReference finalizerReference = finalizerReferences.get(object);
-
-        if (finalizerReference == null) {
-            finalizerReference = new FinalizerReference(object, finalizerQueue);
-            finalizerReferences.put(object, finalizerReference);
-        }
-
-        finalizerReference.addFinalizer(proc);
-
-        // If there is no finalizer thread, start one
-
-        if (finalizerThread == null) {
-            finalizerThread = new RubyThread(context.getCoreLibrary().getThreadClass(), context.getThreadManager());
-
-            finalizerThread.initialize(new Runnable() {
-
-                @Override
-                public void run() {
-                    runFinalizers();
-                }
-
-            });
-        }
-    }
-
-    public void undefineFinalizer(RubyBasicObject object) {
-        final FinalizerReference finalizerReference = finalizerReferences.get(object);
-
-        if (finalizerReference != null) {
-            finalizerReference.clearFinalizers();
-        }
-    }
-
-    private void runFinalizers() {
-        // Run in a loop
-
-        while (true) {
-            // Is there a finalizer ready to immediately run?
-
-            FinalizerReference finalizerReference = (FinalizerReference) finalizerQueue.poll();
-
-            if (finalizerReference != null) {
-                runFinalizers(finalizerReference);
-                continue;
-            }
-
-            // Check if we've been asked to stop
-
-            if (stop) {
-                break;
-            }
-
-            // Leave the global lock and wait on the finalizer queue
-
-            final RubyThread runningThread = context.getThreadManager().leaveGlobalLock();
-            finalizerJavaThread = Thread.currentThread();
-
-            try {
-                finalizerReference = (FinalizerReference) finalizerQueue.remove();
-            } catch (InterruptedException e) {
-                continue;
-            } finally {
-                context.getThreadManager().enterGlobalLock(runningThread);
-            }
-
-            runFinalizers(finalizerReference);
-        }
-
-        finished.countDown();
-    }
-
-    private static void runFinalizers(FinalizerReference finalizerReference) {
-        try {
-            for (RubyProc proc : finalizerReference.getFinalizers()) {
-                proc.call(null);
-            }
-        } catch (Exception e) {
-            // MRI seems to silently ignore exceptions in finalizers
-        }
-    }
-
-    public void shutdown() {
-        context.getThreadManager().enterGlobalLock(finalizerThread);
-
-        try {
-            // Tell the finalizer thread to stop and wait for it to do so
-
-            if (finalizerThread != null) {
-                stop = true;
-
-                if (finalizerJavaThread != null) {
-                    finalizerJavaThread.interrupt();
-                }
-
-                context.getThreadManager().leaveGlobalLock();
-
-                try {
-                    finished.await();
-                } catch (InterruptedException e) {
-                } finally {
-                    context.getThreadManager().enterGlobalLock(finalizerThread);
-                }
-            }
-
-            // Run any finalizers for objects that are still live
-
-            for (FinalizerReference finalizerReference : finalizerReferences.values()) {
-                runFinalizers(finalizerReference);
-            }
-        } finally {
-            context.getThreadManager().leaveGlobalLock();
-        }
-    }
-
-    public Collection<RubyBasicObject> getObjects() {
-        return objects.values();
-    }
-}
--- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/subsystems/ThreadManager.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,82 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.runtime.subsystems;
-
-import java.util.*;
-import java.util.concurrent.*;
-import java.util.concurrent.locks.*;
-
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-
-/**
- * Manages Ruby {@code Thread} objects.
- */
-public class ThreadManager {
-
-    private final ReentrantLock globalLock = new ReentrantLock();
-
-    private final RubyThread rootThread;
-    private RubyThread currentThread;
-
-    private final Set<RubyThread> runningThreads = Collections.newSetFromMap(new ConcurrentHashMap<RubyThread, Boolean>());
-
-    public ThreadManager(RubyContext context) {
-        rootThread = new RubyThread(context.getCoreLibrary().getFiberClass(), this);
-        runningThreads.add(rootThread);
-        enterGlobalLock(rootThread);
-    }
-
-    /**
-     * Enters the global lock. Reentrant, but be aware that Ruby threads are not one-to-one with
-     * Java threads. Needs to be told which Ruby thread is becoming active as it can't work this out
-     * from the current Java thread. Remember to call {@link #leaveGlobalLock} again before
-     * blocking.
-     */
-    public void enterGlobalLock(RubyThread thread) {
-        globalLock.lock();
-        currentThread = thread;
-    }
-
-    /**
-     * Leaves the global lock, returning the Ruby thread which has just stopped being the current
-     * thread. Remember to call {@link #enterGlobalLock} again with that returned thread before
-     * executing any Ruby code. You probably want to use this with a {@code finally} statement to
-     * make sure that happens
-     */
-    public RubyThread leaveGlobalLock() {
-        if (!globalLock.isHeldByCurrentThread()) {
-            throw new RuntimeException("You don't own this lock!");
-        }
-
-        final RubyThread result = currentThread;
-        globalLock.unlock();
-        return result;
-    }
-
-    public RubyThread getCurrentThread() {
-        return currentThread;
-    }
-
-    public void registerThread(RubyThread thread) {
-        runningThreads.add(thread);
-    }
-
-    public void unregisterThread(RubyThread thread) {
-        runningThreads.remove(thread);
-    }
-
-    public void shutdown() {
-        for (RubyThread thread : runningThreads) {
-            thread.shutdown();
-        }
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/subsystems/TraceManager.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,110 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.runtime.subsystems;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.utilities.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-
-/**
- * Manages trace events and calls the user's trace method if one is set.
- * <p>
- * Once tracing has been enabled via {@link #setTraceProc(RubyProc)}, the underlying instrumentation
- * remains in effect, along with performance impact.
- */
-public final class TraceManager {
-
-    private RubyContext context;
-
-    private final AssumedValue<RubyProc> traceProc = new AssumedValue<>("trace-proc", null);
-    private boolean suspended;
-
-    private String lastFile;
-    private int lastLine;
-
-    private final Assumption notTracingAssumption = Truffle.getRuntime().createAssumption("tracing-disabled");
-
-    public TraceManager(RubyContext context) {
-        this.context = context;
-    }
-
-    /**
-     * Produce a trace; it is a runtime error if {@link #hasTraceProc()}{@code == false}.
-     */
-    @CompilerDirectives.SlowPath
-    public void trace(String event, String file, int line, long objectId, RubyBinding binding, String className) {
-        // If tracing is suspended, stop here
-
-        if (suspended) {
-            return;
-        }
-
-        // If the file and line haven't changed since the last trace, stop here
-
-        if (file.equals(lastFile) && line == lastLine) {
-            return;
-        }
-
-        final RubyClass stringClass = context.getCoreLibrary().getStringClass();
-
-        // Suspend tracing while we run the trace proc
-
-        suspended = true;
-
-        try {
-            // Exceptions from within the proc propagate normally
-
-            traceProc.get().call(null, new RubyString(stringClass, event), //
-                            new RubyString(stringClass, file), //
-                            line, //
-                            GeneralConversions.fixnumOrBignum(objectId), //
-                            GeneralConversions.instanceOrNil(binding), //
-                            GeneralConversions.instanceOrNil(className));
-        } finally {
-            // Resume tracing
-
-            suspended = false;
-        }
-
-        // Remember the last trace event file and line
-
-        lastFile = file;
-        lastLine = line;
-    }
-
-    /**
-     * Is there a "trace proc" in effect?
-     */
-    public boolean hasTraceProc() {
-        return traceProc.get() != null;
-    }
-
-    /**
-     * Gets the assumption that there has never yet been tracing enabled. Once the assumption is
-     * invalidated, tracing is presumed permanently enabled even if {@link #hasTraceProc()} returns
-     * {@code false}.
-     */
-    public Assumption getNotTracingAssumption() {
-        return notTracingAssumption;
-    }
-
-    public void setTraceProc(RubyProc newTraceProc) {
-        if (!context.getConfiguration().getTrace()) {
-            throw new RuntimeException("You need the --trace option to use tracing");
-        }
-
-        traceProc.set(newTraceProc);
-        lastFile = null;
-        lastLine = -1;
-
-        notTracingAssumption.invalidate();
-    }
-}
--- a/graal/com.oracle.truffle.ruby.shell/src/com/oracle/truffle/ruby/shell/CommandLineOptions.java	Sun Feb 23 17:00:35 2014 -0800
+++ /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. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.shell;
-
-import java.util.*;
-
-import com.oracle.truffle.ruby.runtime.configuration.*;
-
-/**
- * Options resulting from parsing a command line by {@link CommandLineParser}.
- */
-public class CommandLineOptions {
-
-    private final List<String> preRequires;
-    private final String preChangeDirectory;
-
-    private final List<String> extraLoadPath;
-
-    private final String programFile;
-    private final List<String> commandLineScripts;
-    private final List<String> programArgs;
-    private final List<String> switchArgs;
-
-    private final int recordSeparator;
-    private final boolean autosplit;
-    private final String autosplitPattern;
-    private final boolean checkSyntaxOnly;
-    private final boolean lineEndingProcessing;
-    private final boolean inPlaceEdit;
-    private final String inPlaceBackupExtension;
-    private final boolean implicitLoop;
-    private final boolean implicitSedLoop;
-    private final boolean importFromPath;
-    private final boolean stripMessage;
-    private final boolean useJLine;
-
-    private final Configuration configuration;
-
-    public CommandLineOptions(List<String> preRequires, String preChangeDirectory, List<String> extraLoadPath, String programFile, List<String> commandLineScripts, List<String> programArgs,
-                    List<String> switchArgs, int recordSeparator, boolean autosplit, String autosplitPattern, boolean checkSyntaxOnly, boolean lineEndingProcessing, boolean inPlaceEdit,
-                    String inPlaceBackupExtension, boolean implicitLoop, boolean implicitSedLoop, boolean importFromPath, boolean stripMessage, boolean useJLine, Configuration configuration) {
-        this.preRequires = preRequires;
-        this.preChangeDirectory = preChangeDirectory;
-        this.extraLoadPath = extraLoadPath;
-        this.programFile = programFile;
-        this.commandLineScripts = commandLineScripts;
-        this.programArgs = programArgs;
-        this.switchArgs = switchArgs;
-        this.recordSeparator = recordSeparator;
-        this.autosplit = autosplit;
-        this.autosplitPattern = autosplitPattern;
-        this.checkSyntaxOnly = checkSyntaxOnly;
-        this.lineEndingProcessing = lineEndingProcessing;
-        this.inPlaceEdit = inPlaceEdit;
-        this.inPlaceBackupExtension = inPlaceBackupExtension;
-        this.implicitLoop = implicitLoop;
-        this.implicitSedLoop = implicitSedLoop;
-        this.importFromPath = importFromPath;
-        this.stripMessage = stripMessage;
-        this.useJLine = useJLine;
-        this.configuration = configuration;
-    }
-
-    public List<String> getPreRequires() {
-        return preRequires;
-    }
-
-    public String getPreChangeDirectory() {
-        return preChangeDirectory;
-    }
-
-    public List<String> getExtraLoadPath() {
-        return extraLoadPath;
-    }
-
-    public String getProgramFile() {
-        return programFile;
-    }
-
-    public List<String> getCommandLineScripts() {
-        return commandLineScripts;
-    }
-
-    public List<String> getProgramArgs() {
-        return programArgs;
-    }
-
-    public List<String> getSwitchArgs() {
-        return switchArgs;
-    }
-
-    public int getRecordSeparator() {
-        return recordSeparator;
-    }
-
-    public String getAutosplitPattern() {
-        return autosplitPattern;
-    }
-
-    public boolean isAutosplit() {
-        return autosplit;
-    }
-
-    public boolean isCheckSyntaxOnly() {
-        return checkSyntaxOnly;
-    }
-
-    public boolean isLineEndingProcessing() {
-        return lineEndingProcessing;
-    }
-
-    public boolean isInPlaceEdit() {
-        return inPlaceEdit;
-    }
-
-    public String getInPlaceBackupExtension() {
-        return inPlaceBackupExtension;
-    }
-
-    public boolean isImplicitLoop() {
-        return implicitLoop;
-    }
-
-    public boolean isImplicitSedLoop() {
-        return implicitSedLoop;
-    }
-
-    public boolean isImportFromPath() {
-        return importFromPath;
-    }
-
-    public boolean isStripMessage() {
-        return stripMessage;
-    }
-
-    public boolean useJLine() {
-        return useJLine;
-    }
-
-    public Configuration getConfiguration() {
-        return configuration;
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.shell/src/com/oracle/truffle/ruby/shell/CommandLineParser.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,355 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.shell;
-
-import java.io.*;
-import java.util.*;
-
-import com.oracle.truffle.ruby.runtime.configuration.*;
-
-/**
- * MRI-compatible command line parser, producing {@link CommandLineOptions}.
- */
-public abstract class CommandLineParser {
-
-    /**
-     * Parse an MRI-compatible command line.
-     */
-    public static CommandLineOptions parse(String[] args) {
-        assert args != null;
-
-        final List<String> preRequires = new ArrayList<>();
-        String preChangeDirectory = null;
-
-        final List<String> extraLoadPath = new ArrayList<>();
-
-        String programFile = null;
-        final List<String> commandLineScripts = new ArrayList<>();
-        final List<String> programArgs = new ArrayList<>();
-        final List<String> switchArgs = new ArrayList<>();
-
-        int recordSeparator = -1;
-        boolean autosplit = false;
-        String autosplitPattern = null;
-        boolean checkSyntaxOnly = false;
-        boolean lineEndingProcessing = false;
-        boolean inPlaceEdit = false;
-        String inPlaceBackupExtension = null;
-        boolean implicitLoop = false;
-        boolean implicitSedLoop = false;
-        boolean importFromPath = false;
-        boolean messageStrip = false;
-        boolean useJLine = true;
-
-        final ConfigurationBuilder configurationBuilder = new ConfigurationBuilder();
-
-        final List<String> normalizedArgs = normalizeArgs(args);
-
-        boolean stillRubyArgs = true;
-        boolean collectingSwitchArgs = false;
-        int n = 0;
-
-        while (n < normalizedArgs.size()) {
-            final String arg = normalizedArgs.get(n);
-
-            if (stillRubyArgs && arg.startsWith("-")) {
-                if (collectingSwitchArgs) {
-                    switchArgs.add(arg);
-                } else if (arg.startsWith("-0")) {
-                    if (arg.length() == 2) {
-                        recordSeparator = 0;
-                    } else {
-                        recordSeparator = Integer.parseInt(arg.substring(2), 8);
-                    }
-                } else if (arg.startsWith("-i")) {
-                    inPlaceEdit = true;
-
-                    if (arg.length() > 2) {
-                        inPlaceBackupExtension = arg.substring(2);
-                    }
-                } else if (arg.startsWith("-W")) {
-                    if (arg.length() == 2) {
-                        configurationBuilder.setWarningLevel(2);
-                    } else if (arg.startsWith("-Wlevel=")) {
-                        configurationBuilder.setWarningLevel(Integer.parseInt(arg.substring("-Wlevel=".length())));
-                    } else {
-                        throw new IllegalArgumentException("bad flag " + arg);
-                    }
-                } else if (arg.startsWith("-T")) {
-                    if (arg.length() == 2) {
-                        configurationBuilder.setTaintCheckLevel(1);
-                    } else if (arg.startsWith("-Tlevel=")) {
-                        configurationBuilder.setTaintCheckLevel(Integer.parseInt(arg.substring("-Tlevel=".length())));
-                    } else {
-                        throw new IllegalArgumentException("bad flag " + arg);
-                    }
-                } else if (arg.startsWith("-x")) {
-                    messageStrip = true;
-
-                    if (arg.length() > 2) {
-                        preChangeDirectory = arg.substring(2);
-                    }
-                } else {
-                    switch (arg) {
-                        case "-C":
-                        case "-e":
-                        case "-E":
-                        case "-F":
-                        case "-I":
-                        case "-r":
-                        case "--home":
-                            if (n + 1 >= normalizedArgs.size()) {
-                                throw new RuntimeException("Expecting value after " + arg);
-                            }
-                    }
-
-                    switch (arg) {
-                        case "--":
-                            stillRubyArgs = false;
-                            break;
-                        case "-a":
-                            autosplit = true;
-                            break;
-                        case "-c":
-                            checkSyntaxOnly = true;
-                            break;
-                        case "-C":
-                            if (n + 1 >= normalizedArgs.size()) {
-                                throw new RuntimeException("Need a directory path after -C");
-                            }
-                            preChangeDirectory = normalizedArgs.get(n + 1);
-                            n++;
-                            break;
-                        case "-d":
-                        case "--debug":
-                            configurationBuilder.setDebug(true);
-                            break;
-                        case "--no-debug":
-                            configurationBuilder.setDebug(false);
-                            break;
-                        case "--trace":
-                            configurationBuilder.setTrace(true);
-                            break;
-                        case "--no-trace":
-                            configurationBuilder.setTrace(false);
-                            break;
-                        case "-e":
-                            commandLineScripts.add(normalizedArgs.get(n + 1));
-                            n++;
-                            break;
-                        case "-E":
-                            final String[] encodings = normalizedArgs.get(n + 1).split(":");
-                            configurationBuilder.setDefaultExternalEncoding(encodings[0]);
-
-                            if (encodings.length == 2) {
-                                configurationBuilder.setDefaultInternalEncoding(encodings[1]);
-                            } else {
-                                throw new IllegalArgumentException("bad flag " + arg);
-                            }
-
-                            n++;
-                            break;
-                        case "-F":
-                            autosplitPattern = normalizedArgs.get(n + 1);
-                            n++;
-                            break;
-                        case "-I":
-                            extraLoadPath.add(normalizedArgs.get(n + 1));
-                            n++;
-                            break;
-                        case "-l":
-                            lineEndingProcessing = true;
-                            break;
-                        case "-n":
-                            implicitLoop = true;
-                            break;
-                        case "-r":
-                            preRequires.add(normalizedArgs.get(n + 1));
-                            n++;
-                            break;
-                        case "-s":
-                            collectingSwitchArgs = true;
-                            break;
-                        case "-p":
-                            implicitSedLoop = true;
-                            break;
-                        case "-S":
-                            importFromPath = true;
-                            break;
-                        case "-w":
-                            configurationBuilder.setWarningLevel(1);
-                            break;
-                        case "-h":
-                        case "--help":
-                            help(System.out);
-                            return null;
-                        case "-v":
-                            version(System.out);
-                            configurationBuilder.setVerbose(true);
-                            break;
-                        case "--version":
-                            version(System.out);
-                            return null;
-                        case "--copyright":
-                            copyright(System.out);
-                            return null;
-                        case "--home":
-                            configurationBuilder.setStandardLibrary(normalizedArgs.get(n + 1) + "/" + ConfigurationBuilder.JRUBY_STDLIB_JAR);
-                            n++;
-                            break;
-                        case "--stdlib":
-                            configurationBuilder.setStandardLibrary(normalizedArgs.get(n + 1));
-                            n++;
-                            break;
-                        case "--full-object-space":
-                            configurationBuilder.setFullObjectSpace(true);
-                            break;
-                        case "--no-jline":
-                            useJLine = false;
-                            break;
-                        case "--print-parse-tree":
-                            configurationBuilder.setPrintParseTree(true);
-                            break;
-                        case "--print-uninitialized-calls":
-                            configurationBuilder.setPrintUninitializedCalls(true);
-                            break;
-                        case "--print-java-exceptions":
-                            configurationBuilder.setPrintJavaExceptions(true);
-                            break;
-                        default:
-                            throw new IllegalArgumentException("unknown flag " + arg);
-                    }
-                }
-            } else if (programFile == null) {
-                programFile = arg;
-                stillRubyArgs = false;
-            } else {
-                programArgs.add(arg);
-            }
-
-            n++;
-        }
-
-        return new CommandLineOptions(preRequires, preChangeDirectory, extraLoadPath, programFile, commandLineScripts, programArgs, switchArgs, recordSeparator, autosplit, autosplitPattern,
-                        checkSyntaxOnly, lineEndingProcessing, inPlaceEdit, inPlaceBackupExtension, implicitLoop, implicitSedLoop, importFromPath, messageStrip, useJLine, new Configuration(
-                                        configurationBuilder));
-    }
-
-    /**
-     * Produce a canonical set of arguments that includes {@code $RUBYOPT} and has contractions such
-     * as a {@code -rdir} replaced with separate arguments {@code -r} and {@code dir} for simpler
-     * processing.
-     */
-    private static List<String> normalizeArgs(String[] args) {
-        assert args != null;
-
-        // Arguments come from the main method arguments parameter and $RUBYOPT
-
-        final List<String> inputArgs = new ArrayList<>();
-
-        final String rubyoptVar = System.getenv("RUBYOPT");
-
-        if (rubyoptVar != null) {
-            /*
-             * TODO(cs): what we've got here is a string that we are supposed to treat as if it was
-             * an extra part of the command line, including more Ruby options. However, we just get
-             * the string and have to split it into arguments ourselves. Normally the shell does
-             * that, including lots of fancy quoting styles. Are we supposed to re-implement all of
-             * that? Otherwise arguments in RUBYOPT will be parsed differently to if they were
-             * actually on the command line. JRuby just splits like we do. I also think that's what
-             * MRI does, but is this correct?
-             */
-
-            inputArgs.addAll(Arrays.asList(rubyoptVar.split("\\s+")));
-        }
-
-        inputArgs.addAll(Arrays.asList(args));
-
-        // Replace some contractions such as -rdir with -r dir
-
-        final List<String> outputArgs = new ArrayList<>();
-
-        for (String arg : inputArgs) {
-            if (arg.startsWith("-C") || arg.startsWith("-E") || arg.startsWith("-F") || arg.startsWith("-I") || arg.startsWith("-r")) {
-                outputArgs.add(arg.substring(0, 2));
-                outputArgs.add(arg.substring(2));
-            } else {
-                outputArgs.add(arg);
-            }
-        }
-
-        return outputArgs;
-    }
-
-    /**
-     * Print help information.
-     */
-    private static void help(PrintStream out) {
-        out.println("Usage: ruby [switches] [--] [programfile] [arguments]");
-        out.println("  -0[octal]       specify record separator (\0, if no argument)");
-        out.println("  -a              autosplit mode with -n or -p (splits $_ into $F)");
-        out.println("  -c              check syntax only");
-        out.println("  -Cdirectory     cd to directory, before executing your script");
-        out.println("  -d, --debug     set debugging flags (set $DEBUG to true) and enable Debug module");
-        out.println("  -e 'command'    one line of script. Several -e's allowed. Omit [programfile]");
-        out.println("  -Eex[:in]       specify the default external and internal character encodings");
-        out.println("  -Fpattern       split() pattern for autosplit (-a)");
-        out.println("  -i[extension]   edit ARGV files in place (make backup if extension supplied)");
-        out.println("  -Idirectory     specify $LOAD_PATH directory (may be used more than once)");
-        out.println("  -l              enable line ending processing");
-        out.println("  -n              assume 'while gets(); ... end' loop around your script");
-        out.println("  -p              assume loop like -n but print line also like sed");
-        out.println("  -rlibrary       require the library, before executing your script");
-        out.println("  -s              enable some switch parsing for switches after script name");
-        out.println("  -S              look for the script using PATH environment variable");
-        out.println("  -T[level=1]     turn on tainting checks");
-        out.println("  -v              print version number, then turn on verbose mode");
-        out.println("  -w              turn warnings on for your script");
-        out.println("  -W[level=2]     set warning level; 0=silence, 1=medium, 2=verbose");
-        out.println("  -x[directory]   strip off text before #!ruby line and perhaps cd to directory");
-        out.println("  --copyright     print the copyright");
-        out.println("  --version       print the version");
-        out.println("Extra rubytruffle switches:");
-        out.println("  --home dir                        set the location of the Ruby Truffle installation (default . or $RUBY_TRUFFLE_HOME)");
-        out.println("  --stdlib dir                      use a directory for the Ruby standard library");
-        out.println("  --full-object-space               enable full ObjectSpace#each_object and similar");
-        out.println("  --no-debug                        disable debugging");
-        out.println("  --no-trace                        disable tracing");
-        out.println("Debugging rubytruffle switches:");
-        out.println("  --no-cache-constant-lookup        don't cache constant lookups");
-        out.println("  --no-cache-method-calls           don't cache method lookups");
-        out.println("  --no-intrinsic-method-calls       don't turn method calls into intrinsic nodes");
-        out.println("  --no-jline                        don't use JLine");
-        out.println("  --print-parse-tree                print the result of parsing");
-        out.println("  --print-uninitialized-calls       print each time a method call is uninitialized");
-        out.println("  --print-java-exceptions           print Java exception back traces at the point of translating them to Ruby exceptions");
-        out.println("Relevant environment variables:");
-        out.println("  RUBYHOME                          location of the Ruby Truffle installation");
-        out.println("  RUBYOPT                           extra command line arguments");
-        out.println("  RUBYLIB                           list of colon separated paths to add to $LOAD_PATH");
-        out.println("  PATH                              as RUBYLIB, if -S is used");
-    }
-
-    /**
-     * Print version information.
-     */
-    private static void version(PrintStream out) {
-        out.printf("ruby (rubytruffle) dev [JVM %s]\n", System.getProperty("java.version"));
-    }
-
-    /**
-     * Print copyright information.
-     */
-    private static void copyright(PrintStream out) {
-        out.println("Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.");
-        out.println("ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.");
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.shell/src/com/oracle/truffle/ruby/shell/Shell.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,215 +0,0 @@
-/*
- * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.shell;
-
-import java.io.*;
-
-import jline.console.*;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.ruby.nodes.core.*;
-import com.oracle.truffle.ruby.parser.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.configuration.*;
-import com.oracle.truffle.ruby.runtime.core.array.*;
-
-/**
- * The entry point class for RubyTruffle. Implements the MRI command line interface.
- */
-public class Shell {
-
-    /**
-     * Entry point method for Ruby both in batch and interactive mode.
-     */
-    public static void main(String[] args) throws IOException {
-        // Parse the command line
-
-        final CommandLineOptions options = CommandLineParser.parse(args);
-
-        if (options == null) {
-            return;
-        }
-
-        // Setup JLine
-
-        ConsoleReader console = null;
-
-        if (options.useJLine()) {
-            System.setProperty("jline.shutdownhook", "true");
-            console = new ConsoleReader();
-            console.setExpandEvents(false);
-        }
-
-        // Override the home directory if RUBYHOME is set
-
-        final ConfigurationBuilder configurationBuilder = new ConfigurationBuilder(options.getConfiguration());
-
-        if (System.getenv("RUBYHOME") != null) {
-            configurationBuilder.setStandardLibrary(System.getenv("RUBYHOME") + "/" + ConfigurationBuilder.JRUBY_STDLIB_JAR);
-        }
-
-        // Use JLine for console input
-
-        final ConsoleReader finalConsole = console;
-
-        if (options.useJLine()) {
-            configurationBuilder.setInputReader(new InputReader() {
-
-                @Override
-                public String readLine(String prompt) throws IOException {
-                    return finalConsole.readLine(prompt);
-                }
-
-            });
-        }
-
-        // Set up a context
-
-        final RubyContext context = new RubyContext(new Configuration(configurationBuilder), new JRubyParser());
-
-        // Ruby should always have a debug context.
-        context.setDebugContext(new MinimalRubyDebugContext(context));
-
-        // Bring in core method nodes
-
-        CoreMethodNodeManager.addMethods(context.getCoreLibrary().getObjectClass());
-
-        // Give the core library manager a chance to tweak some of those methods
-
-        context.getCoreLibrary().initializeAfterMethodsAdded();
-
-        // Set program arguments
-
-        for (String arg : options.getProgramArgs()) {
-            context.getCoreLibrary().getArgv().push(context.makeString(arg));
-        }
-
-        if (!options.getSwitchArgs().isEmpty()) {
-            context.implementationMessage("can't set -s switch arguments yet");
-        }
-
-        // Set the load path
-
-        final RubyArray loadPath = (RubyArray) context.getCoreLibrary().getGlobalVariablesObject().getInstanceVariable("$:");
-
-        final String pathVar = System.getenv("PATH");
-
-        if (options.isImportFromPath() && pathVar != null) {
-            for (String path : pathVar.split(File.pathSeparator)) {
-                loadPath.push(context.makeString(path));
-            }
-        }
-
-        for (String path : options.getExtraLoadPath()) {
-            loadPath.push(context.makeString(path));
-        }
-
-        final String rubylibVar = System.getenv("RUBYLIB");
-
-        if (rubylibVar != null) {
-            for (String path : rubylibVar.split(File.pathSeparator)) {
-                loadPath.push(context.makeString(path));
-            }
-        }
-
-        if (context.getConfiguration().getStandardLibrary().endsWith(".jar")) {
-            /*
-             * Use the 1.9 library, even though we're emulating 2.1, as there are some bugs running
-             * the 2.1 library at the moment.
-             */
-            loadPath.push(context.makeString("jar:file:" + context.getConfiguration().getStandardLibrary() + "!/META-INF/jruby.home/lib/ruby/1.9"));
-        } else {
-            loadPath.push(context.makeString(context.getConfiguration().getStandardLibrary()));
-        }
-
-        // Pre-required modules
-
-        for (String feature : options.getPreRequires()) {
-            context.getFeatureManager().require(feature);
-        }
-
-        // Check for other options that are not implemented yet
-
-        if (options.getRecordSeparator() != -1) {
-            context.implementationMessage("record separator not implemented");
-        }
-
-        if (options.isAutosplit()) {
-            context.implementationMessage("autosplit not implemented");
-        }
-
-        if (options.getPreChangeDirectory() != null) {
-            context.implementationMessage("not able to change directory");
-        }
-
-        if (options.isLineEndingProcessing()) {
-            context.implementationMessage("line end processing not implemented");
-        }
-
-        if (options.isInPlaceEdit()) {
-            context.implementationMessage("in place editing not implemented");
-        }
-
-        if (options.isImplicitLoop() || options.isImplicitSedLoop()) {
-            context.implementationMessage("implicit loops not implemented");
-        }
-
-        if (options.isStripMessage()) {
-            context.implementationMessage("strip message -x option not implemented");
-        }
-
-        // Run the scripts, program file, or run the temporary version of IRB
-
-        try {
-            if (!options.getCommandLineScripts().isEmpty()) {
-                final StringBuilder combinedScript = new StringBuilder();
-
-                for (String script : options.getCommandLineScripts()) {
-                    combinedScript.append(script);
-                    combinedScript.append("\n");
-                }
-
-                try {
-                    final Source source = context.getSourceManager().get("-e", combinedScript.toString());
-                    if (options.isCheckSyntaxOnly()) {
-                        context.getParser().parse(context, source, RubyParser.ParserContext.TOP_LEVEL, null);
-                        System.out.println("Syntax OK");
-                    } else {
-                        context.execute(context, source, RubyParser.ParserContext.TOP_LEVEL, context.getCoreLibrary().getMainObject(), null);
-                    }
-                } catch (Exception e) {
-                    e.printStackTrace();
-                }
-            } else if (options.getProgramFile() != null) {
-                try {
-                    if (options.isCheckSyntaxOnly()) {
-                        final Source source = context.getSourceManager().get(options.getProgramFile());
-                        context.getParser().parse(context, source, RubyParser.ParserContext.TOP_LEVEL, null);
-                        System.out.println("Syntax OK");
-                    } else {
-                        context.loadFile(options.getProgramFile());
-                    }
-                } catch (Exception e) {
-                    e.printStackTrace();
-                }
-            } else {
-                if (options.isCheckSyntaxOnly()) {
-                    System.err.println("Can't check syntax in IRB mode");
-                    return;
-                }
-
-                context.runShell(null, null);
-            }
-        } finally {
-            context.shutdown();
-        }
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.test/specs/README	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,21 +0,0 @@
-This is a configuration of the RubySpec set of specifications -
-http://rubyspec.org. RubySpec is the specifications, and MSpec is the tool to
-run them.
-
-Thanks to Brian Shirai and others who have worked on RubySpec.
-
-At the moment we have only configured the version 1.9 specs, and we only run
-language and command line specs.
-
-In the `specs` directory (everything we do here will be in the `specs`
-directory), you need to clone the MSpec and RubySpec Git repositories:
-
-    $ git clone https://github.com/rubyspec/mspec.git
-    $ git --git-dir=mspec/.git --work-tree=mspec checkout 1343524a06466b7aa0c90798b7894454c8abce0f
-    $ git clone https://github.com/rubyspec/rubyspec.git
-    $ git --git-dir=rubyspec/.git --work-tree=rubyspec checkout 926e356b268fe32c67bec43a21565d727360a89b
-
-Then you can run MSpec to run RubySpec. We can run all of the harness in our
-implementation, not just as an executable under test.
-
-    $ ./rubytruffle mspec/bin/mspec run -t ./rubytruffle --config rubytruffle.mspec --excl-tag fails
--- a/graal/com.oracle.truffle.ruby.test/specs/rubytruffle	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,20 +0,0 @@
-#!/bin/bash
-
-# The command this file executes is what mx would execute, just taken out of
-# the mx wrapper because it appears to interfere with MSpec, and we need a
-# 'executable' (a shell script will do) to run.
-#
-# If this file isn't working for you try generating one for your setup. You
-# will need to do this for example if your Java isn't 1.7.0u45. You can use
-# the command below - the -v flag gives you the Java command, then just append
-# "$@".
-#
-#     $TRUFFLE_DIR/mxtool/mx -v --vm server-nograal ruby -ea -- --home $TRUFFLE_DIR "$@"
-
-TRUFFLE_DIR=../../..
-
-$TRUFFLE_DIR/jdk1.7.0_45/product/bin/java \
-  -server-nograal -d64 -ea \
-  -cp $TRUFFLE_DIR/lib/jline-2.10.jar:$TRUFFLE_DIR/lib/jrubyparser-0.5.0.jar:$TRUFFLE_DIR/lib/jruby-stdlib-1.7.4.jar:$TRUFFLE_DIR/lib/jnr-posix-3.0.0.jar:$TRUFFLE_DIR/lib/jnr-constants-0.8.4.jar:$TRUFFLE_DIR/lib/jnr-ffi-1.0.4.jar:$TRUFFLE_DIR/lib/jffi-1.2.1.jar:$TRUFFLE_DIR/lib/jffi-1.2.1-native.jar:$TRUFFLE_DIR/lib/jnr-x86asm-1.0.2.jar:$TRUFFLE_DIR/lib/asm-4.0.jar:$TRUFFLE_DIR/lib/asm-analysis-4.0.jar:$TRUFFLE_DIR/lib/asm-commons-4.0.jar:$TRUFFLE_DIR/lib/asm-tree-4.0.jar:$TRUFFLE_DIR/lib/asm-util-4.0.jar:$TRUFFLE_DIR/graal/com.oracle.truffle.api/bin:$TRUFFLE_DIR/graal/com.oracle.truffle.ruby.runtime/bin:$TRUFFLE_DIR/graal/com.oracle.truffle.api.dsl/bin:$TRUFFLE_DIR/graal/com.oracle.truffle.ruby.nodes/bin:$TRUFFLE_DIR/graal/com.oracle.truffle.ruby.parser/bin:$TRUFFLE_DIR/graal/com.oracle.truffle.ruby.shell/bin \
-  com.oracle.truffle.ruby.shell.Shell \
-  --home $TRUFFLE_DIR "$@"
--- a/graal/com.oracle.truffle.ruby.test/specs/rubytruffle.mspec	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,26 +0,0 @@
-class MSpecScript
-
-  Rubyspec = "rubyspec"
-
-  set :command_line, [
-    "rubyspec/command_line"
-  ]
-
-  set :language, [
-    "rubyspec/language"
-  ]
-
-  set :tags_patterns, [
-      [/rubyspec/, "tags"],
-      [/_spec.rb$/, "_tags.txt"]
-  ]
-
-  MSpec.enable_feature :encoding
-  MSpec.enable_feature :continuation
-  MSpec.enable_feature :fiber
-  MSpec.enable_feature :fork
-  MSpec.enable_feature :generator
-
-  set :files, get(:command_line) + get(:language)
-
-end
--- a/graal/com.oracle.truffle.ruby.test/specs/tags/command_line/dash_a_tags.txt	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-fails:The -a command line option runs the code in loop conditional on Kernel.gets()
-fails:The -a command line option sets $-a
--- a/graal/com.oracle.truffle.ruby.test/specs/tags/command_line/dash_d_tags.txt	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-fails:The -d command line option sets $DEBUG to true
-fails:The -d command line option sets $VERBOSE to true
-fails:The -d command line option sets $-d to true
--- a/graal/com.oracle.truffle.ruby.test/specs/tags/command_line/dash_e_tags.txt	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-fails:The -e command line option with -n and a Fixnum range mimics an awk conditional by comparing an inclusive-end range with $.
-fails:The -e command line option with -n and a Fixnum range mimics a sed conditional by comparing an exclusive-end range with $.
--- a/graal/com.oracle.truffle.ruby.test/specs/tags/command_line/dash_n_tags.txt	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-fails:The -n command line option runs the code in loop conditional on Kernel.gets()
-fails:The -n command line option only evaluates BEGIN blocks once
-fails:The -n command line option only evaluates END blocks once
-fails:The -n command line option allows summing over a whole file
--- a/graal/com.oracle.truffle.ruby.test/specs/tags/command_line/dash_p_tags.txt	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-fails:The -p command line option runs the code in loop conditional on Kernel.gets() and prints $_
-fails:The -p command line option sets $-p
--- a/graal/com.oracle.truffle.ruby.test/specs/tags/command_line/dash_r_tags.txt	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-fails:The -r command line option requires the specified file
--- a/graal/com.oracle.truffle.ruby.test/specs/tags/command_line/dash_s_tags.txt	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,8 +0,0 @@
-fails:The -s command line option when using -- to stop parsing sets the value to true without an explicit value
-fails:The -s command line option when using -- to stop parsing parses single letter args into globals
-fails:The -s command line option when using -- to stop parsing parses long args into globals
-fails:The -s command line option when using -- to stop parsing converts extra dashes into underscores
-fails:The -s command line option when running a script sets the value to true without an explicit value
-fails:The -s command line option when running a script parses single letter args into globals
-fails:The -s command line option when running a script parses long args into globals
-fails:The -s command line option when running a script converts extra dashes into underscores
--- a/graal/com.oracle.truffle.ruby.test/specs/tags/command_line/dash_upper_e_tags.txt	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-fails:ruby -E raises a RuntimeError if used with -U
--- a/graal/com.oracle.truffle.ruby.test/specs/tags/command_line/dash_upper_f_tags.txt	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-fails:the -F command line option specifies the field separator pattern for -a
--- a/graal/com.oracle.truffle.ruby.test/specs/tags/command_line/dash_upper_i_tags.txt	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-fails:The -I command line option adds the path to the load path ($:)
--- a/graal/com.oracle.truffle.ruby.test/specs/tags/command_line/dash_upper_u_tags.txt	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,7 +0,0 @@
-fails:ruby -U sets Encoding.default_internal to UTF-8
-fails:ruby -U does nothing different if specified multiple times
-fails:ruby -U is overruled by Encoding.default_internal=
-fails:ruby -U does not affect the default external encoding
-fails:ruby -U does not affect the source encoding
-fails:ruby -U raises a RuntimeError if used with -Eext:int
-fails:ruby -U raises a RuntimeError if used with -E:int
--- a/graal/com.oracle.truffle.ruby.test/specs/tags/command_line/dash_upper_w_tags.txt	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-fails:The -W command line option with 0 sets $VERBOSE to nil
-fails:The -W command line option with 1 sets $VERBOSE to false
-fails:The -W command line option with 2 sets $VERBOSE to true
--- a/graal/com.oracle.truffle.ruby.test/specs/tags/command_line/dash_v_tags.txt	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-fails:The -v command line option sets $VERBOSE to true
--- a/graal/com.oracle.truffle.ruby.test/specs/tags/command_line/dash_w_tags.txt	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-fails:The -w command line option sets $VERBOSE to true
--- a/graal/com.oracle.truffle.ruby.test/specs/tags/command_line/dash_x_tags.txt	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-fails:The -x command line option runs code after the first /#!.*ruby.*/-ish line in target file
-fails:The -x command line option needs to be reviewed for spec completeness
--- a/graal/com.oracle.truffle.ruby.test/specs/tags/command_line/error_message_tags.txt	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-fails:The error message caused by an exception is not printed to stdout
--- a/graal/com.oracle.truffle.ruby.test/specs/tags/language/BEGIN_tags.txt	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-fails:The BEGIN keyword runs first in a given code unit
-fails:The BEGIN keyword runs multiple begins in FIFO order
-fails:The BEGIN keyword runs in a shared scope
-fails:The BEGIN keyword accesses variables outside the eval scope
--- a/graal/com.oracle.truffle.ruby.test/specs/tags/language/alias_tags.txt	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,11 +0,0 @@
-fails:The alias keyword creates a new name for an existing method
-fails:The alias keyword adds the new method to the list of methods
-fails:The alias keyword adds the new method to the list of public methods
-fails:The alias keyword overwrites an existing method with the target name
-fails:The alias keyword is reversible
-fails:The alias keyword operates on the object's metaclass when used in instance_eval
-fails:The alias keyword operates on methods with splat arguments
-fails:The alias keyword operates on methods with splat arguments on eigenclasses
-fails:The alias keyword operates on methods with splat arguments defined in a superclass
-fails:The alias keyword operates on methods with splat arguments defined in a superclass using text block for class eval
-fails:The alias keyword is not allowed against Fixnum or String instances
--- a/graal/com.oracle.truffle.ruby.test/specs/tags/language/array_tags.txt	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-fails:The unpacking splat operator (*) returns a new array containing the same values when applied to an array inside an empty array
-fails:The unpacking splat operator (*) unpacks the start and count arguments in an array slice assignment
-fails:Array literals [] treats splatted nil as no element
-fails:The unpacking splat operator (*) when applied to a non-Array value attempts to coerce it to Array if the object respond_to?(:to_a)
--- a/graal/com.oracle.truffle.ruby.test/specs/tags/language/block_tags.txt	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,67 +0,0 @@
-fails:A block allows to define a block variable with the same name as the enclosing block
-fails:A block taking |a| arguments assigns nil to the argument when no values are yielded
-fails:A block taking |a| arguments does not call #to_ary to convert a single yielded object to an Array
-fails:A block taking |a| arguments assigns the first value yielded to the argument
-fails:A block taking |a, b| arguments assgins nil to the arguments when no values are yielded
-fails:A block taking |a, b| arguments assigns one value yielded to the first argument
-fails:A block taking |a, b| arguments destructures a splatted Array
-fails:A block taking |a, b| arguments calls #to_ary to convert a single yielded object to an Array
-fails:A block taking |a, b| arguments does not call #to_ary if the single yielded object is an Array
-fails:A block taking |a, b| arguments does not call #to_ary if the object does not respond to #to_ary
-fails:A block taking |a, b| arguments raises an TypeError if #to_ary does not return an Array
-fails:A block taking |a, *b| arguments assigns 'nil' and '[]' to the arguments when no values are yielded
-fails:A block taking |a, *b| arguments assigns all yielded values after the first to the rest argument
-fails:A block taking |a, *b| arguments assigns 'nil' and '[]' to the arguments when a single, empty Array is yielded
-fails:A block taking |a, *b| arguments assigns the element of a single element Array to the first argument
-fails:A block taking |a, *b| arguments destructures a splatted Array
-fails:A block taking |a, *b| arguments destructures a single Array value assigning the remaining values to the rest argument
-fails:A block taking |a, *b| arguments calls #to_ary to convert a single yielded object to an Array
-fails:A block taking |a, *b| arguments does not call #to_ary if the single yielded object is an Array
-fails:A block taking |a, *b| arguments raises an TypeError if #to_ary does not return an Array
-fails:A block taking |*| arguments does not call #to_ary if the single yielded object is an Array
-fails:A block taking |*| arguments does not call #to_ary to convert a single yielded object to an Array
-fails:A block taking |*a| arguments assigns all the values passed to the argument as an Array
-fails:A block taking |*a| arguments assigns '[[]]' to the argument when passed an empty Array
-fails:A block taking |*a| arguments assigns a single Array value passed to the argument by wrapping it in an Array
-fails:A block taking |*a| arguments does not call #to_ary if the single yielded object is an Array
-fails:A block taking |*a| arguments does not call #to_ary to convert a single yielded object to an Array
-fails:A block taking |a, | arguments assigns nil to the argument when no values are yielded
-fails:A block taking |a, | arguments assigns the argument the first value yielded
-fails:A block taking |a, | arguments assigns the argument the first of several values yielded when it is an Array
-fails:A block taking |a, | arguments assigns nil to the argument when passed an empty Array
-fails:A block taking |a, | arguments assigns the argument the first element of the Array when passed a single Array
-fails:A block taking |a, | arguments calls #to_ary to convert a single yielded object to an Array
-fails:A block taking |a, | arguments does not call #to_ary if the single yielded object is an Array
-fails:A block taking |a, | arguments raises an TypeError if #to_ary does not return an Array
-fails:A block taking |(a, b)| arguments assigns nil to the arguments when yielded no values
-fails:A block taking |(a, b)| arguments calls #to_ary to convert a single yielded object to an Array
-fails:A block taking |(a, b)| arguments does not call #to_ary if the single yielded object is an Array
-fails:A block taking |(a, b)| arguments does not call #to_ary if the object does not respond to #to_ary
-fails:A block taking |(a, b)| arguments raises an TypeError if #to_ary does not return an Array
-fails:A block taking |(a, b), c| arguments assigns nil to the arguments when yielded no values
-fails:A block taking |(a, b), c| arguments destructures a single one-level Array value yielded
-fails:A block taking |(a, b), c| arguments destructures a single multi-level Array value yielded
-fails:A block taking |(a, b), c| arguments calls #to_ary to convert a single yielded object to an Array
-fails:A block taking |(a, b), c| arguments does not call #to_ary if the single yielded object is an Array
-fails:A block taking |(a, b), c| arguments does not call #to_ary if the object does not respond to #to_ary
-fails:A block taking |(a, b), c| arguments raises an TypeError if #to_ary does not return an Array
-fails:A block taking nested |a, (b, (c, d))| destructures a single multi-level Array value yielded
-fails:A block taking nested |a, (b, (c, d))| destructures a single multi-level Array value yielded
-fails:A block taking nested |a, ((b, c), d)| destructures a single multi-level Array value yielded
-fails:A block taking nested |a, ((b, c), d)| destructures a single multi-level Array value yielded
-fails:A block arguments with _ extracts arguments with _
-fails:Block-local variables override shadowed variables from the outer scope
-fails:Post-args appear after a splat
-fails:Post-args are required
-fails:Post-args with required args gathers remaining args in the splat
-fails:Post-args with required args has an empty splat when there are no remaining args
-fails:Post-args with optional args gathers remaining args in the splat
-fails:Post-args with optional args overrides the optional arg before gathering in the splat
-fails:Post-args with optional args uses the required arg before the optional and the splat
-fails:Post-args with optional args overrides the optional args from left to right before gathering the splat
-fails:A block taking |(a, b)| arguments destructures a single Array value yielded
-fails:A block taking |(a, b)| arguments destructures a single Array value yielded when shadowing an outer variable
-fails:A block taking nested |a, (b, (c, d))| assigns nil to the arguments when yielded no values
-fails:A block taking nested |a, (b, (c, d))| destructures separate yielded values
-fails:A block taking nested |a, ((b, c), d)| assigns nil to the arguments when yielded no values
-fails:A block taking nested |a, ((b, c), d)| destructures separate yielded values
--- a/graal/com.oracle.truffle.ruby.test/specs/tags/language/break_tags.txt	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-fails:The break statement in a lambda created at the toplevel returns a value when invoking from the toplevel
-fails:The break statement in a lambda created at the toplevel returns a value when invoking from a method
-fails:The break statement in a lambda created at the toplevel returns a value when invoking from a block
--- a/graal/com.oracle.truffle.ruby.test/specs/tags/language/case_tags.txt	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,12 +0,0 @@
-fails:The 'case'-construct evaluates the body of the when clause matching the case target expression
-fails:The 'case'-construct evaluates the body of the when clause whose array expression includes the case target expression
-fails:The 'case'-construct evaluates the body of the when clause in left-to-right order if it's an array expression
-fails:The 'case'-construct evaluates the body of the when clause whose range expression includes the case target expression
-fails:The 'case'-construct expands arrays to lists of values
-fails:The 'case'-construct concats arrays before expanding them
-fails:The 'case'-construct never matches when clauses with no values
-fails:The 'case'-construct works even if there's only one when statement
-fails:The 'case'-construct with no target expression evaluates true as only 'true' when true is the first clause
-fails:The 'case'-construct with no target expression evaluates false as only 'false' when false is the first clause
-fails:The 'case'-construct with no target expression treats a literal array as its own when argument, rather than a list of arguments
-fails:The 'case'-construct takes multiple expanded arrays
--- a/graal/com.oracle.truffle.ruby.test/specs/tags/language/class_tags.txt	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,18 +0,0 @@
-fails:A class definition has no class variables
-fails:A class definition raises TypeError if the constant qualifying the class is nil
-fails:A class definition raises TypeError if any constant qualifying the class is not a Module
-fails:A class definition allows using self as the superclass if self is a class
-fails:A class definition raises a TypeError if inheriting from a metaclass
-fails:A class definition allows the declaration of class variables in the body
-fails:A class definition stores instance variables defined in the class body in the class object
-fails:A class definition allows the declaration of class variables in a class method
-fails:A class definition allows the definition of class-level instance variables in a class method
-fails:A class definition allows the declaration of class variables in an instance method
-fails:A class definition returns the value of the last statement in the body
-fails:An outer class definition contains the inner classes
-fails:A class definition extending an object (sclass) raises a TypeError when trying to extend numbers
-fails:A class definition extending an object (sclass) allows accessing the block of the original scope
-fails:A class definition extending an object (sclass) can use return to cause the enclosing method to return
-fails:Reopening a class raises a TypeError when superclasses mismatch
-fails:Reopening a class adds new methods to subclasses
-fails:class provides hooks calls inherited when a class is created
--- a/graal/com.oracle.truffle.ruby.test/specs/tags/language/class_variable_tags.txt	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,10 +0,0 @@
-fails:A class variable can be accessed from a subclass
-fails:A class variable is set in the superclass
-fails:A class variable defined in a module can be accessed from classes that extend the module
-fails:A class variable defined in a module is not defined in these classes
-fails:A class variable defined in a module is only updated in the module a method defined in the module is used
-fails:A class variable defined in a module is updated in the class when a Method defined in the class is used
-fails:A class variable defined in a module can be accessed from modules that extend the module
-fails:A class variable defined in a module is defined in the extended module
-fails:A class variable defined in a module is not defined in the extending module
-fails:A class variable defined in a module can be accessed inside the class using the module methods
--- a/graal/com.oracle.truffle.ruby.test/specs/tags/language/constants_tags.txt	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,45 +0,0 @@
-fails:Literal (A::X) constant resolution sends #const_missing to the original class or module scope
-fails:Literal (A::X) constant resolution raises a TypeError if a non-class or non-module qualifier is given
-fails:Literal (A::X) constant resolution with statically assigned constants does not search the singleton class of the class or module
-fails:Literal (A::X) constant resolution with dynamically assigned constants does not search the singleton class of the class or module
-fails:Literal (A::X) constant resolution with dynamically assigned constants evaluates the right hand side before evaluating a constant path
-fails:Constant resolution within methods sends #const_missing to the original class or module scope
-fails:Constant resolution within methods with statically assigned constants searches the lexical scope of the method not the receiver's immediate class
-fails:Constant resolution within methods with statically assigned constants searches the lexical scope of a singleton method
-fails:Constant resolution within methods with statically assigned constants searches Object as a lexical scope only if Object is explicitly opened
-fails:Constant resolution within methods with dynamically assigned constants searches the immediate class or module scope first
-fails:Constant resolution within methods with dynamically assigned constants searches the superclass before a module included in the superclass
-fails:Constant resolution within methods with dynamically assigned constants searches the lexical scope of the method not the receiver's immediate class
-fails:Constant resolution within methods with dynamically assigned constants searches the lexical scope of a singleton method
-fails:Constant resolution within methods with dynamically assigned constants does not search the lexical scope of the caller
-fails:Constant resolution within methods with dynamically assigned constants searches the lexical scope of a block
-fails:Constant resolution within methods with dynamically assigned constants searches Object as a lexical scope only if Object is explicitly opened
-fails:Constant resolution within methods with ||= assignes constant if previously undefined
-fails:Module#private_constant marked constants remain private even when updated
-fails:Module#private_constant marked constants in a module cannot be accessed from outside the module
-fails:Module#private_constant marked constants in a module cannot be reopened as a module
-fails:Module#private_constant marked constants in a module cannot be reopened as a class
-fails:Module#private_constant marked constants in a module is not defined? with A::B form
-fails:Module#private_constant marked constants in a module can be accessed from lexical scope
-fails:Module#private_constant marked constants in a module is defined? from lexical scope
-fails:Module#private_constant marked constants in a class cannot be accessed from outside the class
-fails:Module#private_constant marked constants in a class cannot be reopened as a module
-fails:Module#private_constant marked constants in a class cannot be reopened as a class
-fails:Module#private_constant marked constants in a class is not defined? with A::B form
-fails:Module#private_constant marked constants in a class can be accessed from lexical scope
-fails:Module#private_constant marked constants in Object cannot be accessed using ::Const form
-fails:Module#private_constant marked constants in Object is not defined? using ::Const form
-fails:Module#public_constant marked constants in a module can be accessed from outside the module
-fails:Module#public_constant marked constants in a module is defined? with A::B form
-fails:Module#public_constant marked constants in a class can be accessed from outside the class
-fails:Module#public_constant marked constants in a class is defined? with A::B form
-fails:Module#public_constant marked constants in Object can be accessed using ::Const form
-fails:Module#public_constant marked constants in Object is defined? using ::Const form
-fails:Module#private_constant marked constants in a class is defined? from lexical scope
-fails:Literal (A::X) constant resolution with statically assigned constants searches a module included in the superclass
-fails:Constant resolution within methods with statically assigned constants searches a module included in the superclass
-fails:Constant resolution within methods with statically assigned constants searches the superclass chain
-fails:Literal (A::X) constant resolution with statically assigned constants searches Object if no class or module qualifier is given
-fails:Literal (A::X) constant resolution with statically assigned constants searches Object after searching other scopes
-fails:Constant resolution within methods with statically assigned constants searches the superclass chain
-fails:Literal (A::X) constant resolution with statically assigned constants searches the superclass chain
--- a/graal/com.oracle.truffle.ruby.test/specs/tags/language/def_tags.txt	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,28 +0,0 @@
-fails:Defining an 'initialize' method sets the method's visibility to private
-fails:Defining an 'initialize_copy' method sets the method's visibility to private
-fails:An instance method with a default argument assigns an empty Array to an unused splat argument
-fails:An instance method with a default argument prefers to assign to a default argument when there are no required arguments
-fails:An instance method with a default argument does not evaluate the default when passed a value and a * argument
-fails:A singleton method definition raises RuntimeError if frozen
-fails:Redefining a singleton method does not inherit a previously set visibility 
-fails:Redefining a singleton method does not inherit a previously set visibility 
-fails:A method defined with extreme default arguments may use an fcall as a default
-fails:A method defined with extreme default arguments may use preceding arguments as defaults
-fails:A method defined with extreme default arguments may use a lambda as a default
-fails:A singleton method defined with extreme default arguments may use an fcall as a default
-fails:A singleton method defined with extreme default arguments may use preceding arguments as defaults
-fails:A singleton method defined with extreme default arguments may use a lambda as a default
-fails:A method definition inside a metaclass scope can create a class method
-fails:A method definition inside a metaclass scope can create a singleton method
-fails:A method definition inside a metaclass scope raises RuntimeError if frozen
-fails:A nested method definition creates an instance method when evaluated in an instance method
-fails:A nested method definition creates a class method when evaluated in a class method
-fails:A nested method definition creates a singleton method when evaluated in the metaclass of an instance
-fails:A method definition inside an instance_eval creates a singleton method
-fails:A method definition inside an instance_eval creates a singleton method when evaluated inside a metaclass
-fails:A method definition inside an instance_eval creates a class method when the receiver is a class
-fails:A method definition in an eval creates an instance method
-fails:A method definition in an eval creates a class method
-fails:A method definition in an eval creates a singleton method
-fails:a method definition that sets more than one default parameter all to the same value assigns them all the same object by default
-fails:The def keyword within a closure looks outside the closure for the visibility
--- a/graal/com.oracle.truffle.ruby.test/specs/tags/language/defined_tags.txt	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,48 +0,0 @@
-fails:The defined? keyword when called with a method name having a module as receiver returns nil if the method is private
-fails:The defined? keyword when called with a method name having a module as receiver returns nil if the method is protected
-fails:The defined? keyword when called with a method name having a local variable as receiver calls #respond_to_missing?
-fails:The defined? keyword for an expression returns nil for an expression with !~ and an undefined method
-fails:The defined? keyword for an expression returns 'method' for an expression with '!~'
-fails:The defined? keyword for an expression with logical connectives returns nil for an expression with '!' and an unset class variable
-fails:The defined? keyword for an expression with logical connectives returns nil for an expression with 'not' and an unset class variable
-fails:The defined? keyword for an expression with logical connectives returns nil for an expression with '!' and an unset global variable
-fails:The defined? keyword for an expression with logical connectives returns nil for an expression with '!' and an unset instance variable
-fails:The defined? keyword for an expression with logical connectives returns nil for an expression with 'not' and an unset global variable
-fails:The defined? keyword for an expression with logical connectives returns nil for an expression with 'not' and an unset instance variable
-fails:The defined? keyword for variables returns nil for a global variable that has not been read
-fails:The defined? keyword for variables returns nil for a global variable that has been read but not assigned to
-fails:The defined? keyword for variables when a String does not match a Regexp returns nil for $&
-fails:The defined? keyword for variables when a String does not match a Regexp returns nil for $`
-fails:The defined? keyword for variables when a String does not match a Regexp returns nil for $'
-fails:The defined? keyword for variables when a String does not match a Regexp returns nil for $+
-fails:The defined? keyword for variables when a String matches a Regexp returns 'global-variable' for $&
-fails:The defined? keyword for variables when a String matches a Regexp returns 'global-variable' for $`
-fails:The defined? keyword for variables when a String matches a Regexp returns 'global-variable' for $'
-fails:The defined? keyword for variables when a String matches a Regexp returns 'global-variable' for $+
-fails:The defined? keyword for variables when a String matches a Regexp returns 'global-variable' for the capture references
-fails:The defined? keyword for variables when a Regexp does not match a String returns nil for $&
-fails:The defined? keyword for variables when a Regexp does not match a String returns nil for $`
-fails:The defined? keyword for variables when a Regexp does not match a String returns nil for $'
-fails:The defined? keyword for variables when a Regexp does not match a String returns nil for $+
-fails:The defined? keyword for variables when a Regexp matches a String returns 'global-variable' for $&
-fails:The defined? keyword for variables when a Regexp matches a String returns 'global-variable' for $`
-fails:The defined? keyword for variables when a Regexp matches a String returns 'global-variable' for $'
-fails:The defined? keyword for variables when a Regexp matches a String returns 'global-variable' for $+
-fails:The defined? keyword for variables when a Regexp matches a String returns 'global-variable' for the capture references
-fails:The defined? keyword for a scoped constant returns nil when an undefined constant is scoped to a defined constant
-fails:The defined? keyword for a top-level scoped constant returns nil when an undefined constant is scoped to a defined constant
-fails:The defined? keyword for super returns nil when a superclass undef's the method
-fails:The defined? keyword for super for a method taking no arguments returns 'super' from a block when a superclass method exists
-fails:The defined? keyword for super for a method taking no arguments returns 'super' from a #define_method when a superclass method exists
-fails:The defined? keyword for super for a method taking no arguments returns 'super' from a block in a #define_method when a superclass method exists
-fails:The defined? keyword for super for a method taking no arguments returns 'super' when the method exists in a supermodule
-fails:The defined? keyword for super for a method taking arguments returns 'super' when a superclass method exists
-fails:The defined? keyword for super for a method taking arguments returns 'super' from a block when a superclass method exists
-fails:The defined? keyword for super for a method taking arguments returns 'super' from a #define_method when a superclass method exists
-fails:The defined? keyword for super for a method taking arguments returns 'super' from a block in a #define_method when a superclass method exists
-fails:The defined? keyword for super within an included module's method returns 'super' when a superclass method exists in the including hierarchy
-fails:The defined? keyword for instance variables returns nil if not assigned
-fails:The defined? keyword for variables when a String does not match a Regexp returns nil for $1-$9
-fails:The defined? keyword for variables when a String matches a Regexp returns nil for non-captures
-fails:The defined? keyword for variables when a Regexp does not match a String returns nil for $1-$9
-fails:The defined? keyword for variables when a Regexp matches a String returns nil for non-captures
--- a/graal/com.oracle.truffle.ruby.test/specs/tags/language/encoding_tags.txt	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,14 +0,0 @@
-fails:The __ENCODING__ pseudo-variable is an instance of Encoding
-fails:The __ENCODING__ pseudo-variable is US-ASCII by default
-fails:The __ENCODING__ pseudo-variable is the evaluated strings's one inside an eval
-fails:The __ENCODING__ pseudo-variable is the encoding specified by a magic comment inside an eval
-fails:The __ENCODING__ pseudo-variable is the encoding specified by a magic comment in the file
-fails:The __ENCODING__ pseudo-variable is Encoding::ASCII_8BIT when the interpreter is invoked with -Ka
-fails:The __ENCODING__ pseudo-variable is Encoding::ASCII_8BIT when the interpreter is invoked with -KA
-fails:The __ENCODING__ pseudo-variable is Encoding::EUC_JP when the interpreter is invoked with -Ke
-fails:The __ENCODING__ pseudo-variable is Encoding::EUC_JP when the interpreter is invoked with -KE
-fails:The __ENCODING__ pseudo-variable is Encoding::UTF_8 when the interpreter is invoked with -Ku
-fails:The __ENCODING__ pseudo-variable is Encoding::UTF_8 when the interpreter is invoked with -KU
-fails:The __ENCODING__ pseudo-variable is Encoding::Windows_31J when the interpreter is invoked with -Ks
-fails:The __ENCODING__ pseudo-variable is Encoding::Windows_31J when the interpreter is invoked with -KS
-fails:The __ENCODING__ pseudo-variable raises a SyntaxError if assigned to
--- a/graal/com.oracle.truffle.ruby.test/specs/tags/language/ensure_tags.txt	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-fails:An ensure block inside a begin block is executed when an exception is raised in it's corresponding begin block
-fails:An ensure block inside a method is executed when an exception is raised in the method
--- a/graal/com.oracle.truffle.ruby.test/specs/tags/language/execution_tags.txt	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-fails:`` returns the output of the executed sub-process
-fails:%x is the same as ``
--- a/graal/com.oracle.truffle.ruby.test/specs/tags/language/file_tags.txt	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-fails:The __FILE__ pseudo-variable equals (eval) inside an eval
-fails:The __FILE__ pseudo-variable equals the absolute path of a file loaded by an absolute path
-fails:The __FILE__ pseudo-variable equals the absolute path of a file loaded by a relative path
--- a/graal/com.oracle.truffle.ruby.test/specs/tags/language/for_tags.txt	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,6 +0,0 @@
-fails:The for expression iterates over an Hash passing each key-value pair to the block
-fails:The for expression allows a class variable as an iterator name
-fails:The for expression yields only as many values as there are arguments
-fails:The for expression executes code in containing variable scope
-fails:The for expression executes code in containing variable scope with 'do'
-fails:The for expression returns expr
--- a/graal/com.oracle.truffle.ruby.test/specs/tags/language/hash_tags.txt	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-fails:Hash literal freezes string keys on initialization
--- a/graal/com.oracle.truffle.ruby.test/specs/tags/language/line_tags.txt	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-fails:The __LINE__ pseudo-variable equals the line number of the text in a loaded file
--- a/graal/com.oracle.truffle.ruby.test/specs/tags/language/literal_lambda_tags.txt	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-fails:->(){} assigns the given block to the parameter prefixed with an ampersand if such a parameter exists
-fails:->(){} sets parameters appropriately when a combination of parameter types is given between the parenthesis
-fails:->(){} uses lambda's 'rigid' argument handling
-fails:->(){} evaluates constants as normal blocks do
--- a/graal/com.oracle.truffle.ruby.test/specs/tags/language/magic_comment_tags.txt	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,8 +0,0 @@
-fails:Magic comment is optional
-fails:Magic comment determines __ENCODING__
-fails:Magic comment is case-insensitive
-fails:Magic comment must be at the first line
-fails:Magic comment must be the first token of the line
-fails:Magic comment can be after the shebang
-fails:Magic comment can take Emacs style
-fails:Magic comment can take vim style
--- a/graal/com.oracle.truffle.ruby.test/specs/tags/language/match_tags.txt	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-fails:The !~ operator evaluates as a call to !~
-fails:The =~ operator calls the =~ method
--- a/graal/com.oracle.truffle.ruby.test/specs/tags/language/metaclass_tags.txt	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,16 +0,0 @@
-fails:self in a metaclass body (class << obj) is TrueClass for true
-fails:self in a metaclass body (class << obj) is FalseClass for false
-fails:self in a metaclass body (class << obj) is NilClass for nil
-fails:self in a metaclass body (class << obj) raises a TypeError for numbers
-fails:self in a metaclass body (class << obj) raises a TypeError for symbols
-fails:self in a metaclass body (class << obj) is a singleton Class instance
-fails:A constant on a metaclass can be accessed via const_get
-fails:A constant on a metaclass cannot be accessed via object::CONST
-fails:A constant on a metaclass raises a NameError for anonymous_module::CONST
-fails:A constant on a metaclass appears in the metaclass constant list
-fails:A constant on a metaclass does not appear in the object's class constant list
-fails:A constant on a metaclass is not preserved when the object is duped
-fails:A constant on a metaclass is preserved when the object is cloned
-fails:calling methods on the metaclass calls a method on the instance's metaclass
-fails:calling methods on the metaclass calls a method in deeper chains of metaclasses
-fails:calling methods on the metaclass calls a method defined on the metaclass of the metaclass
--- a/graal/com.oracle.truffle.ruby.test/specs/tags/language/module_tags.txt	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,7 +0,0 @@
-fails:The module keyword reopens a module included in Object
-fails:The module keyword raises a TypeError if the constant is a Class
-fails:The module keyword raises a TypeError if the constant is a String
-fails:The module keyword raises a TypeError if the constant is a Fixnum
-fails:The module keyword raises a TypeError if the constant is nil
-fails:The module keyword raises a TypeError if the constant is true
-fails:The module keyword raises a TypeError if the constant is false
--- a/graal/com.oracle.truffle.ruby.test/specs/tags/language/next_tags.txt	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,9 +0,0 @@
-fails:The next statement from within the block returns the argument passed
-fails:The next statement from within the block returns to the invoking method, with the specified value
-fails:The next statement from within the block returns to the currently yielding method in case of chained calls
-fails:Assignment via next assigns objects
-fails:Assignment via next assigns splatted objects
-fails:Assignment via next assigns objects to a splatted reference
-fails:Assignment via next assigns splatted objects to a splatted reference via a splatted yield
-fails:Assignment via next assigns objects to multiple variables
-fails:Assignment via next assigns splatted objects to multiple variables
--- a/graal/com.oracle.truffle.ruby.test/specs/tags/language/precedence_tags.txt	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-fails:Operators + - have higher precedence than >> <<
-fails:Operators + - are left-associative
--- a/graal/com.oracle.truffle.ruby.test/specs/tags/language/predefined/data_tags.txt	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,6 +0,0 @@
-fails:The DATA constant exists when the main script contains __END__
-fails:The DATA constant does not exist when the main script contains no __END__
-fails:The DATA constant does not exist when an included file has a __END__
-fails:The DATA constant does not change when an included files also has a __END__
-fails:The DATA constant is included in an otherwise empty file
-fails:The DATA constant succeeds in locking the file DATA came from
--- a/graal/com.oracle.truffle.ruby.test/specs/tags/language/predefined_tags.txt	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,108 +0,0 @@
-fails:Predefined global $~ is set to contain the MatchData object of the last match if successful
-fails:Predefined global $~ is set to nil if the last match was unsuccessful
-fails:Predefined global $~ is set at the method-scoped level rather than block-scoped
-fails:Predefined global $~ raises an error if assigned an object not nil or instanceof MatchData
-fails:Predefined global $~ changes the value of derived capture globals when assigned
-fails:Predefined global $~ changes the value of the derived preceding match global
-fails:Predefined global $~ changes the value of the derived following match global
-fails:Predefined global $~ changes the value of the derived full match global
-fails:Predefined global $& is equivalent to MatchData#[0] on the last match $~
-fails:Predefined global $& sets the encoding to the encoding of the source String
-fails:Predefined global $` is equivalent to MatchData#pre_match on the last match $~
-fails:Predefined global $` sets the encoding to the encoding of the source String
-fails:Predefined global $` sets an empty result to the encoding of the source String
-fails:Predefined global $' is equivalent to MatchData#post_match on the last match $~
-fails:Predefined global $' sets the encoding to the encoding of the source String
-fails:Predefined global $' sets an empty result to the encoding of the source String
-fails:Predefined global $+ is equivalent to $~.captures.last
-fails:Predefined global $+ captures the last non nil capture
-fails:Predefined global $+ sets the encoding to the encoding of the source String
-fails:Predefined globals $1..N are equivalent to $~[N]
-fails:Predefined globals $1..N are nil unless a match group occurs
-fails:Predefined globals $1..N sets the encoding to the encoding of the source String
-fails:Predefined global $stdout is the same as $DEFAULT_OUTPUT from 'English' library
-fails:Predefined global $stdout raises TypeError error if assigned to nil
-fails:Predefined global $stdout raises TypeError error if assigned to object that doesn't respond to #write
-fails:Predefined global $! remains nil after a failed core class "checked" coercion against a class that defines method_missing
-fails:Predefined global $/ changes $-0
-fails:Predefined global $/ does not call #to_str to convert the object to a String
-fails:Predefined global $/ raises a TypeError if assigned a Fixnum
-fails:Predefined global $/ raises a TypeError if assigned a boolean
-fails:Predefined global $-0 changes $/
-fails:Predefined global $-0 does not call #to_str to convert the object to a String
-fails:Predefined global $-0 raises a TypeError if assigned a Fixnum
-fails:Predefined global $-0 raises a TypeError if assigned a boolean
-fails:Predefined global $, raises TypeError if assigned a non-String
-fails:Predefined global $_ is set to the last line read by e.g. StringIO#gets
-fails:Predefined global $_ is set at the method-scoped level rather than block-scoped
-fails:Predefined global $_ is Thread-local
-fails:Execution variable $: does not include '.' when the taint check level > 1
-fails:Execution variable $: is the same object as $LOAD_PATH and $-I
-fails:Execution variable $: is read-only
-fails:Global variable $" is read-only
-fails:Global variable $< is read-only
-fails:Global variable $FILENAME is read-only
-fails:Global variable $? is read-only
-fails:Global variable $? is thread-local
-fails:Global variable $-a is read-only
-fails:Global variable $-l is read-only
-fails:Global variable $-p is read-only
-fails:Global variable $-d is an alias of $DEBUG
-fails:Global variable $-v is an alias of $VERBOSE
-fails:Global variable $-w is an alias of $VERBOSE
-fails:Global variable $0 raises a TypeError when not given an object that can be coerced to a String
-fails:The predefined standard objects includes ARGF
-fails:The predefined global constants includes TRUE
-fails:The predefined global constants includes FALSE
-fails:The predefined global constants includes NIL
-fails:The predefined global constants includes STDIN
-fails:The predefined global constants includes STDOUT
-fails:The predefined global constants includes STDERR
-fails:The predefined global constants includes RUBY_RELEASE_DATE
-fails:The predefined global constants includes TOPLEVEL_BINDING
-fails:Processing RUBYOPT adds the -I path to $LOAD_PATH
-fails:Processing RUBYOPT sets $DEBUG to true for '-d'
-fails:Processing RUBYOPT prints the version number for '-v'
-fails:Processing RUBYOPT sets $VERBOSE to true for '-w'
-fails:Processing RUBYOPT sets $VERBOSE to true for '-W'
-fails:Processing RUBYOPT sets $VERBOSE to nil for '-W0'
-fails:Processing RUBYOPT sets $VERBOSE to false for '-W1'
-fails:Processing RUBYOPT sets $VERBOSE to true for '-W2'
-fails:Processing RUBYOPT requires the file for '-r'
-fails:Processing RUBYOPT raises a RuntimeError for '-a'
-fails:Processing RUBYOPT raises a RuntimeError for '-p'
-fails:Processing RUBYOPT raises a RuntimeError for '-n'
-fails:Processing RUBYOPT raises a RuntimeError for '-y'
-fails:Processing RUBYOPT raises a RuntimeError for '-c'
-fails:Processing RUBYOPT raises a RuntimeError for '-s'
-fails:Processing RUBYOPT raises a RuntimeError for '-h'
-fails:Processing RUBYOPT raises a RuntimeError for '--help'
-fails:Processing RUBYOPT raises a RuntimeError for '-l'
-fails:Processing RUBYOPT raises a RuntimeError for '-S'
-fails:Processing RUBYOPT raises a RuntimeError for '-e'
-fails:Processing RUBYOPT raises a RuntimeError for '-i'
-fails:Processing RUBYOPT raises a RuntimeError for '-x'
-fails:Processing RUBYOPT raises a RuntimeError for '-C'
-fails:Processing RUBYOPT raises a RuntimeError for '-X'
-fails:Processing RUBYOPT raises a RuntimeError for '-F'
-fails:Processing RUBYOPT raises a RuntimeError for '-0'
-fails:Processing RUBYOPT raises a RuntimeError for '--copyright'
-fails:Processing RUBYOPT raises a RuntimeError for '--version'
-fails:Processing RUBYOPT raises a RuntimeError for '--yydebug'
-fails:The predefined global constant STDERR has nil for the external encoding despite Encoding.default_external being changed
-fails:The predefined global constant STDERR has the encodings set by #set_encoding
-fails:The predefined global constant ARGV contains Strings encoded in locale Encoding
-fails:The predefined global constant STDERR has nil for the internal encoding despite Encoding.default_internal being changed
-fails:The predefined global constant STDERR has nil for the internal encoding
-fails:The predefined global constant STDERR has nil for the external encoding
-fails:The predefined global constant STDOUT has nil for the internal encoding despite Encoding.default_internal being changed
-fails:The predefined global constant STDOUT has nil for the internal encoding
-fails:The predefined global constant STDOUT has the encodings set by #set_encoding
-fails:The predefined global constant STDOUT has nil for the external encoding despite Encoding.default_external being changed
-fails:The predefined global constant STDOUT has nil for the external encoding
-fails:The predefined global constant STDIN has nil for the internal encoding despite Encoding.default_internal being changed
-fails:The predefined global constant STDIN has nil for the internal encoding
-fails:The predefined global constant STDIN retains the encoding set by #set_encoding when Encoding.default_external is changed
-fails:The predefined global constant STDIN has the encodings set by #set_encoding
-fails:The predefined global constant STDIN has the same external encoding as Encoding.default_external when that encoding is changed
-fails:The predefined global constant STDIN has the same external encoding as Encoding.default_external
--- a/graal/com.oracle.truffle.ruby.test/specs/tags/language/private_tags.txt	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-fails:The private keyword is overridden when a new class is opened
--- a/graal/com.oracle.truffle.ruby.test/specs/tags/language/proc_tags.txt	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,18 +0,0 @@
-fails:A Proc taking zero arguments raises an ArgumentErro if a value is passed
-fails:A Proc taking || arguments raises an ArgumentError if a value is passed
-fails:A Proc taking |a| arguments does not call #to_ary to convert a single passed object to an Array
-fails:A Proc taking |a| arguments raises an ArgumentError if no value is passed
-fails:A Proc taking |a, b| arguments raises an ArgumentError if passed no values
-fails:A Proc taking |a, b| arguments raises an ArgumentError if passed one value
-fails:A Proc taking |a, b| arguments does not call #to_ary to convert a single passed object to an Array
-fails:A Proc taking |a, *b| arguments raises an ArgumentError if passed no values
-fails:A Proc taking |a, *b| arguments does not call #to_ary to convert a single passed object to an Array
-fails:A Proc taking |*| arguments does not call #to_ary to convert a single passed object to an Array
-fails:A Proc taking |*a| arguments does not call #to_ary to convert a single passed object to an Array
-fails:A Proc taking |a, | arguments raises an ArgumentError when passed no values
-fails:A Proc taking |a, | arguments raises an ArgumentError when passed more than one value
-fails:A Proc taking |a, | arguments does not call #to_ary to convert a single passed object to an Array
-fails:A Proc taking |(a, b)| arguments raises an ArgumentError when passed no values
-fails:A Proc taking |(a, b)| arguments calls #to_ary to convert a single passed object to an Array
-fails:A Proc taking |(a, b)| arguments raises an TypeError if #to_ary does not return an Array
-fails:A Proc taking |(a, b)| arguments destructures a single Array value yielded
--- a/graal/com.oracle.truffle.ruby.test/specs/tags/language/redo_tags.txt	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-fails:The redo statement restarts block execution if used within block
-fails:The redo statement re-executes the closest loop
-fails:The redo statement re-executes the last step in enumeration
--- a/graal/com.oracle.truffle.ruby.test/specs/tags/language/regexp/anchors_tags.txt	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-fails:Regexps with anchors supports B (non-word-boundary)
--- a/graal/com.oracle.truffle.ruby.test/specs/tags/language/regexp/back-references_tags.txt	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-fails:Regexps with back-references saves match data in the $~ pseudo-global variable
-fails:Regexps with back-references saves captures in numbered $[1-9] variables
-fails:Regexps with back-references will not clobber capture variables across threads
-fails:Regexps with back-references resets nested <n> backreference before match of outer subexpression
--- a/graal/com.oracle.truffle.ruby.test/specs/tags/language/regexp/character_classes_tags.txt	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,68 +0,0 @@
-fails:Regexp with character classes supports [] (character class)
-fails:Regexp with character classes supports [[:alpha:][:digit:][:etc:]] (predefined character classes)
-fails:Regexp with character classes matches ASCII characters with [[:ascii:]]
-fails:Regexp with character classes matches Unicode letter characters with [[:alnum:]]
-fails:Regexp with character classes matches Unicode digits with [[:alnum:]]
-fails:Regexp with character classes doesn't match Unicode control characters with [[:alnum:]]
-fails:Regexp with character classes doesn't match Unicode punctuation characters with [[:alnum:]]
-fails:Regexp with character classes matches Unicode letter characters with [[:alpha:]]
-fails:Regexp with character classes doesn't match Unicode digits with [[:alpha:]]
-fails:Regexp with character classes doesn't match Unicode control characters with [[:alpha:]]
-fails:Regexp with character classes doesn't match Unicode punctuation characters with [[:alpha:]]
-fails:Regexp with character classes matches Unicode space characters with [[:blank:]]
-fails:Regexp with character classes matches Unicode control characters with [[:cntrl:]]
-fails:Regexp with character classes matches Unicode digits with [[:digit:]]
-fails:Regexp with character classes matches Unicode letter characters with [[:graph:]]
-fails:Regexp with character classes matches Unicode digits with [[:graph:]]
-fails:Regexp with character classes matches Unicode marks with [[:graph:]]
-fails:Regexp with character classes matches Unicode punctuation characters with [[:graph:]]
-fails:Regexp with character classes match Unicode format characters with [[:graph:]]
-fails:Regexp with character classes match Unicode private-use characters with [[:graph:]]
-fails:Regexp with character classes matches Unicode lowercase letter characters with [[:lower:]]
-fails:Regexp with character classes matches Unicode lowercase letter characters with [[:print:]]
-fails:Regexp with character classes matches Unicode uppercase letter characters with [[:print:]]
-fails:Regexp with character classes matches Unicode title-case characters with [[:print:]]
-fails:Regexp with character classes matches Unicode digits with [[:print:]]
-fails:Regexp with character classes matches Unicode marks with [[:print:]]
-fails:Regexp with character classes matches Unicode punctuation characters with [[:print:]]
-fails:Regexp with character classes match Unicode format characters with [[:print:]]
-fails:Regexp with character classes match Unicode private-use characters with [[:print:]]
-fails:Regexp with character classes matches Unicode Pc characters with [[:punct:]]
-fails:Regexp with character classes matches Unicode Pd characters with [[:punct:]]
-fails:Regexp with character classes matches Unicode Ps characters with [[:punct:]]
-fails:Regexp with character classes matches Unicode Pe characters with [[:punct:]]
-fails:Regexp with character classes matches Unicode Pi characters with [[:punct:]]
-fails:Regexp with character classes matches Unicode Pf characters with [[:punct:]]
-fails:Regexp with character classes matches Unicode Pf characters with [[:punct:]]
-fails:Regexp with character classes matches Unicode Po characters with [[:punct:]]
-fails:Regexp with character classes matches Unicode Zs characters with [[:space:]]
-fails:Regexp with character classes matches Unicode Zl characters with [[:space:]]
-fails:Regexp with character classes matches Unicode Zp characters with [[:space:]]
-fails:Regexp with character classes matches Unicode uppercase characters with [[:upper:]]
-fails:Regexp with character classes doesn't match Unicode letter characters [^a-fA-F] with [[:xdigit:]]
-fails:Regexp with character classes matches Unicode letter characters [a-fA-F] with [[:xdigit:]]
-fails:Regexp with character classes matches Unicode lowercase characters with [[:word:]]
-fails:Regexp with character classes matches Unicode uppercase characters with [[:word:]]
-fails:Regexp with character classes matches Unicode title-case characters with [[:word:]]
-fails:Regexp with character classes matches Unicode decimal digits with [[:word:]]
-fails:Regexp with character classes matches Unicode marks with [[:word:]]
-fails:Regexp with character classes match Unicode Nl characters with [[:word:]]
-fails:Regexps with anchors supports ^ (line start anchor)
-fails:Regexp with character classes doesn't matches Unicode marks with [[:alnum:]]
-fails:Regexp with character classes doesn't match Unicode lowercase letter characters with [[:punct:]]
-fails:Regexp with character classes doesn't match Unicode uppercase letter characters with [[:punct:]]
-fails:Regexp with character classes doesn't match Unicode title-case characters with [[:punct:]]
-fails:Regexp with character classes doesn't match Unicode digits with [[:punct:]]
-fails:Regexp with character classes doesn't match Unicode marks with [[:punct:]]
-fails:Regexp with character classes doesn't match Unicode format characters with [[:punct:]]
-fails:Regexp with character classes doesn't match Unicode private-use characters with [[:punct:]]
-fails:Regexp with character classes doesn't match Unicode lowercase characters with [[:upper:]]
-fails:Regexp with character classes doesn't match Unicode title-case characters with [[:upper:]]
-fails:Regexp with character classes doesn't match Unicode digits with [[:upper:]]
-fails:Regexp with character classes doesn't match Unicode marks with [[:upper:]]
-fails:Regexp with character classes doesn't match Unicode punctuation characters with [[:upper:]]
-fails:Regexp with character classes doesn't match Unicode control characters with [[:upper:]]
-fails:Regexp with character classes doesn't match Unicode format characters with [[:upper:]]
-fails:Regexp with character classes doesn't match Unicode private-use characters with [[:upper:]]
-fails:Regexps with escape characters support \x (hex characters)
-fails:Regexps with escape characters support \c (control characters)
--- a/graal/com.oracle.truffle.ruby.test/specs/tags/language/regexp/encoding_tags.txt	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,23 +0,0 @@
-fails:Regexps with encoding modifiers supports /e (EUC encoding)
-fails:Regexps with encoding modifiers supports /e (EUC encoding) with interpolation
-fails:Regexps with encoding modifiers supports /e (EUC encoding) with interpolation /o
-fails:Regexps with encoding modifiers uses EUC-JP as /e encoding
-fails:Regexps with encoding modifiers preserves EUC-JP as /e encoding through interpolation
-fails:Regexps with encoding modifiers supports /n (No encoding)
-fails:Regexps with encoding modifiers supports /n (No encoding) with interpolation
-fails:Regexps with encoding modifiers supports /n (No encoding) with interpolation /o
-fails:Regexps with encoding modifiers uses US-ASCII as /n encoding if all chars are 7-bit
-fails:Regexps with encoding modifiers uses ASCII-8BIT as /n encoding if not all chars are 7-bit
-fails:Regexps with encoding modifiers preserves US-ASCII as /n encoding through interpolation if all chars are 7-bit
-fails:Regexps with encoding modifiers preserves ASCII-8BIT as /n encoding through interpolation if all chars are 7-bit
-fails:Regexps with encoding modifiers supports /s (Windows_31J encoding)
-fails:Regexps with encoding modifiers supports /s (Windows_31J encoding) with interpolation
-fails:Regexps with encoding modifiers supports /s (Windows_31J encoding) with interpolation and /o
-fails:Regexps with encoding modifiers uses Windows-31J as /s encoding
-fails:Regexps with encoding modifiers preserves Windows-31J as /s encoding through interpolation
-fails:Regexps with encoding modifiers supports /u (UTF8 encoding)
-fails:Regexps with encoding modifiers supports /u (UTF8 encoding) with interpolation
-fails:Regexps with encoding modifiers supports /u (UTF8 encoding) with interpolation and /o
-fails:Regexps with encoding modifiers uses UTF-8 as /u encoding
-fails:Regexps with encoding modifiers preserves UTF-8 as /u encoding through interpolation
-fails:Regexps with encoding modifiers selects last of multiple encoding specifiers
--- a/graal/com.oracle.truffle.ruby.test/specs/tags/language/regexp/escapes_tags.txt	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-fails:Regexps with escape characters support \x (hex characters)
-fails:Regexps with escape characters support \c (control characters)
--- a/graal/com.oracle.truffle.ruby.test/specs/tags/language/regexp/grouping_tags.txt	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-fails:Regexps with grouping raise a SyntaxError when parentheses aren't balanced
--- a/graal/com.oracle.truffle.ruby.test/specs/tags/language/regexp/interpolation_tags.txt	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,7 +0,0 @@
-fails:Regexps with interpolation allows interpolation of literal regexps
-fails:Regexps with interpolation allows interpolation of any class that responds to to_s
-fails:Regexps with interpolation allows interpolation which mixes modifiers
-fails:Regexps with interpolation gives precedence to escape sequences over substitution
-fails:Regexps with interpolation throws RegexpError for malformed interpolation
-fails:Regexps with interpolation allows interpolation in extended mode
-fails:Regexps with interpolation allows escape sequences in interpolated regexps
--- a/graal/com.oracle.truffle.ruby.test/specs/tags/language/regexp/modifiers_tags.txt	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,9 +0,0 @@
-fails:Regexps with modifers supports /m (multiline)
-fails:Regexps with modifers supports /x (extended syntax)
-fails:Regexps with modifers supports /o (once)
-fails:Regexps with modifers invokes substitutions for /o only once
-fails:Regexps with modifers supports (?imx-imx) (inline modifiers)
-fails:Regexps with modifers supports (?imx-imx:expr) (scoped inline modifiers)
-fails:Regexps with modifers supports . with /m
-fails:Regexps with modifers supports ASII/Unicode modifiers
-fails:Regexps with modifers raises SyntaxError for ASII/Unicode modifiers
--- a/graal/com.oracle.truffle.ruby.test/specs/tags/language/regexp/repetition_tags.txt	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-fails:Regexps with repetition does not treat {m,n}+ as possessive
--- a/graal/com.oracle.truffle.ruby.test/specs/tags/language/regexp_tags.txt	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,16 +0,0 @@
-fails:Literal Regexps matches against $_ (last input) in a conditional if no explicit matchee provided
-fails:Literal Regexps throws SyntaxError for malformed literals
-fails:Literal Regexps supports paired delimiters with %r
-fails:Literal Regexps supports grouping constructs that are also paired delimiters
-fails:Literal Regexps allows second part of paired delimiters to be used as non-paired delimiters
-fails:Literal Regexps supports non-paired delimiters delimiters with %r
-fails:Literal Regexps allows unescaped / to be used with %r
-fails:Literal Regexps supports . (any character except line terminator)
-fails:Literal Regexps supports | (alternations)
-fails:Literal Regexps supports (?> ) (embedded subexpression)
-fails:Literal Regexps supports (?# )
-fails:Literal Regexps supports (?<= ) (positive lookbehind)
-fails:Literal Regexps supports (?<! ) (negative lookbehind)
-fails:Literal Regexps supports g (named backreference)
-fails:Literal Regexps supports character class composition
-fails:Literal Regexps supports possessive quantifiers
--- a/graal/com.oracle.truffle.ruby.test/specs/tags/language/rescue_tags.txt	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,9 +0,0 @@
-fails:The rescue keyword can be used to handle a specific exception
-fails:The rescue keyword can capture the raised exception in a local variable
-fails:The rescue keyword can rescue multiple raised exceptions with a single rescue block
-fails:The rescue keyword can rescue a splatted list of exceptions
-fails:The rescue keyword will only rescue the specified exceptions when doing a splat rescue
-fails:The rescue keyword will execute an else block only if no exceptions were raised
-fails:The rescue keyword will not execute an else block if an exception was raised
-fails:The rescue keyword will not rescue errors raised in an else block in the rescue block above it
-fails:The rescue keyword parses  'a += b rescue c' as 'a += (b rescue c)'
--- a/graal/com.oracle.truffle.ruby.test/specs/tags/language/retry_tags.txt	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-fails:The retry statement re-executes the closest block
-fails:The retry statement raises a SyntaxError when used outside of a begin statement
-fails:The retry keyword inside a begin block's rescue block causes the begin block to be executed again
--- a/graal/com.oracle.truffle.ruby.test/specs/tags/language/return_tags.txt	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-fails:The return keyword in a Thread raises a LocalJumpError if used to exit a thread
-fails:The return keyword when passed a splat calls 'to_a' on the splatted value first
-fails:The return keyword within define_method stops at the method when the return is used directly
--- a/graal/com.oracle.truffle.ruby.test/specs/tags/language/send_tags.txt	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,57 +0,0 @@
-fails:Invoking a method with a block makes it available to yield
-fails:Invoking a method with a block converts the block to a Proc
-fails:Invoking a method with an object as a block uses 'to_proc' for coercion
-fails:Invoking a method raises a SyntaxError with both a literal block and an object as block
-fails:Invoking a method with splat operator makes the object the direct arguments
-fails:Invoking a method without parentheses works
-fails:Invoking a method with a space separating method name and parenthesis treats expression in parenthesis as first argument
-fails:Invoking a method passes literal hashes without curly braces as the last parameter
-fails:Invoking a method passes a literal hash without curly braces or parens
-fails:Invoking a method allows to literal hashes without curly braces as the only parameter
-fails:Invoking a method with zero arguments requires no arguments passed
-fails:Invoking a method with zero arguments raises ArgumentError if the method has a positive arity
-fails:Invoking a method with only manditory arguments requires exactly the same number of passed values
-fails:Invoking a method with only manditory arguments raises ArgumentError if the methods arity doesn't match
-fails:Invoking a method with optional arguments uses the optional argument if none is is passed
-fails:Invoking a method with optional arguments uses the passed argument if available
-fails:Invoking a method with optional arguments raises ArgumentError if extra arguments are passed
-fails:Invoking a method with manditory and optional arguments uses the passed values in left to right order
-fails:Invoking a method with manditory and optional arguments raises an ArgumentError if there are no values for the manditory args
-fails:Invoking a method with manditory and optional arguments raises an ArgumentError if too many values are passed
-fails:Invoking a method with a rest argument is an empty array if there are no additional arguments
-fails:Invoking a method with a rest argument gathers unused arguments
-fails:Invoking a method when the method is not available invokes method_missing
-fails:Invoking a private getter method does not permit self as a receiver
-fails:Invoking a method with .() invokes #call
-fails:Invoking a method allows a vestigial trailing ',' in the arguments
-fails:Invoking a method with splat operator attempts to coerce it to an Array if the object respond_to?(:to_a)
-fails:Invoking a method with splat operator * and non-Array value uses value unchanged if it does not respond_to?(:to_ary)
-fails:Invoking a method accepts additional arguments after splat expansion
-fails:Invoking a method does not expand final array arguments after a splat expansion
-fails:Invoking a method accepts final explicit literal Hash arguments after the splat
-fails:Invoking a method accepts final implicit literal Hash arguments after the splat
-fails:Invoking a method accepts final Hash arguments after the splat
-fails:Invoking a method accepts mandatory and explicit literal Hash arguments after the splat
-fails:Invoking a method accepts mandatory and implicit literal Hash arguments after the splat
-fails:Invoking a method accepts mandatory and Hash arguments after the splat
-fails:Invoking a method converts a final splatted explicit Hash to an Array
-fails:Invoking a method calls #to_a to convert a final splatted Hash object to an Array
-fails:Invoking a method accepts multiple splat expansions in the same argument list
-fails:Invoking a method expands an array to arguments grouped in parentheses
-fails:Invoking a method expands an array to arguments grouped in parentheses and ignores any rest arguments in the array
-fails:Invoking a method expands an array to arguments grouped in parentheses and sets not specified arguments to nil
-fails:Invoking a method expands an array to arguments grouped in parentheses which in turn takes rest arguments
-fails:Invoking a method with required args after the rest arguments binds the required arguments first
-fails:Invoking a method with manditory arguments after optional arguments binds the required arguments first
-fails:Invoking a method new-style hash arguments as the only parameter passes without curly braces
-fails:Invoking a method new-style hash arguments as the only parameter passes without curly braces or parens
-fails:Invoking a method new-style hash arguments as the only parameter handles a hanging comma without curly braces
-fails:Invoking a method new-style hash arguments as the last parameter passes without curly braces
-fails:Invoking a method new-style hash arguments as the last parameter passes without curly braces or parens
-fails:Invoking a method new-style hash arguments as the last parameter handles a hanging comma without curly braces
-fails:Invoking a method mixed new- and old-style hash arguments as the only parameter passes without curly braces
-fails:Invoking a method mixed new- and old-style hash arguments as the only parameter passes without curly braces or parens
-fails:Invoking a method mixed new- and old-style hash arguments as the only parameter handles a hanging comma without curly braces
-fails:Invoking a method mixed new- and old-style hash arguments as the last parameter passes without curly braces
-fails:Invoking a method mixed new- and old-style hash arguments as the last parameter passes without curly braces or parens
-fails:Invoking a method mixed new- and old-style hash arguments as the last parameter handles a hanging comma without curly braces
--- a/graal/com.oracle.truffle.ruby.test/specs/tags/language/singleton_class_tags.txt	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,51 +0,0 @@
-fails:A singleton class doesn't have singleton class
-fails:A singleton class is TrueClass for true
-fails:A singleton class is FalseClass for false
-fails:A singleton class is NilClass for nil
-fails:A singleton class raises a TypeError for Fixnum's
-fails:A singleton class raises a TypeError for symbols
-fails:A singleton class is a singleton Class instance
-fails:A singleton class is a Class for classes
-fails:A singleton class inherits from Class for classes
-fails:A singleton class is a subclass of Class's singleton class
-fails:A singleton class is a subclass of the same level of Class's singleton class
-fails:A singleton class is a subclass of a superclass's singleton class
-fails:A singleton class is a subclass of the same level of superclass's singleton class
-fails:A singleton class for BasicObject has Class as it's superclass
-fails:A singleton class for BasicObject has the proper level of superclass for Class
-fails:A singleton class has class String as the superclass of a String instance
-fails:A singleton class has class Bignum as the superclass of a Bignum instance
-fails:A constant on a singleton class can be accessed after the singleton class body is reopened
-fails:A constant on a singleton class can be accessed via self::CONST
-fails:A constant on a singleton class can be accessed via const_get
-fails:A constant on a singleton class is not defined on the object's class
-fails:A constant on a singleton class is not defined in the singleton class opener's scope
-fails:A constant on a singleton class cannot be accessed via object::CONST
-fails:A constant on a singleton class raises a NameError for anonymous_module::CONST
-fails:A constant on a singleton class appears in the singleton class constant list
-fails:A constant on a singleton class does not appear in the object's class constant list
-fails:A constant on a singleton class is not preserved when the object is duped
-fails:A constant on a singleton class is preserved when the object is cloned
-fails:Defining instance methods on a singleton class define public methods
-fails:Instance methods of a singleton class include ones of the object's class
-fails:Instance methods of a singleton class do not include class methods of the object's class
-fails:Instance methods of a singleton class include instance methods of Object
-fails:Instance methods of a singleton class do not include class methods of Object
-fails:Instance methods of a singleton class for a class include instance methods of Class
-fails:Instance methods of a singleton class for a class do not include class methods of Class
-fails:Instance methods of a singleton class for a class do not include instance methods of the singleton class of Class
-fails:Instance methods of a singleton class for a class do not include class methods of the singleton class of Class
-fails:Instance methods of a singleton class for a singleton class includes instance methods of the singleton class of Class
-fails:Instance methods of a singleton class for a singleton class does not include class methods of the singleton class of Class
-fails:Class methods of a singleton class include ones of the object's class
-fails:Class methods of a singleton class do not include instance methods of the object's class
-fails:Class methods of a singleton class include instance methods of Class
-fails:Class methods of a singleton class do not include class methods of Class
-fails:Class methods of a singleton class for a class include instance methods of Class
-fails:Class methods of a singleton class for a class include class methods of Class
-fails:Class methods of a singleton class for a class include instance methods of the singleton class of Class
-fails:Class methods of a singleton class for a class do not include class methods of the singleton class of Class
-fails:Class methods of a singleton class for a singleton class include instance methods of the singleton class of Class
-fails:Class methods of a singleton class for a singleton class include class methods of the singleton class of Class
-fails:Instantiating a singleton class raises a TypeError when new is called
-fails:Instantiating a singleton class raises a TypeError when allocate is called
--- a/graal/com.oracle.truffle.ruby.test/specs/tags/language/splat_tags.txt	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-fails:Splat operator used to assign a splatted object to an object assigns the returned value of to_a when the splatted object responds to to_a
-fails:Splat operator used to assign a splatted object to an object assigns the object in a new array when it responds to to_a but to_a returns nil
--- a/graal/com.oracle.truffle.ruby.test/specs/tags/language/string_tags.txt	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,15 +0,0 @@
-fails:Ruby character strings taints the result of interpolation when an interpolated value is tainted
-fails:Ruby character strings untrusts the result of interpolation when an interpolated value is untrusted
-fails:Ruby character strings call #to_s when the object is not a String
-fails:Ruby character strings call #to_s as a private method
-fails:Ruby character strings uses an internal representation when #to_s doesn't return a String
-fails:Ruby character strings Unicode escaping can be done with \u and four hex digits
-fails:Ruby character strings Unicode escaping can be done with \u{} and one to six hex digits
-fails:Ruby character strings Unicode escaping with US-ASCII source encoding produces an ASCII string when escaping ASCII characters via \u
-fails:Ruby character strings Unicode escaping with US-ASCII source encoding produces an ASCII string when escaping ASCII characters via \u{}
-Ruby character strings Unicode escaping with US-ASCII source encoding produces a UTF-8-encoded string when escaping non-ASCII fails:characters via \u
-fails:Ruby character strings Unicode escaping with US-ASCII source encoding produces a UTF-8-encoded string when escaping non-ASCII characters via \u{}
-fails:Ruby String interpolation creates a String having an Encoding compatible with all components
-fails:Ruby String interpolation creates a String having the Encoding of the components when all are the same Encoding
-fails:Ruby String interpolation raises an Encoding::CompatibilityError if the Encodings are not compatible
-fails:Ruby character strings Unicode escaping with US-ASCII source encoding produces a UTF-8-encoded string when escaping non-ASCII characters via \u
--- a/graal/com.oracle.truffle.ruby.test/specs/tags/language/super_tags.txt	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,14 +0,0 @@
-fails:The super keyword searches class methods
-fails:The super keyword searches class methods including modules
-fails:The super keyword calls the correct method when the method visibility is modified
-fails:The super keyword raises an error error when super method does not exist
-fails:The super keyword calls the superclass method when in a block
-fails:The super keyword calls the superclass method when initial method is defined_method'd
-fails:The super keyword can call through a define_method multiple times (caching check)
-fails:The super keyword supers up appropriate name even if used for multiple method names
-fails:The super keyword can be used with implicit arguments from a method defined with define_method
-fails:The super keyword respects the original module a method is aliased from
-fails:The super keyword passes along modified rest args when they weren't originally empty
-fails:The super keyword passes along modified rest args when they were originally empty
-fails:The super keyword sees the included version of a module a method is alias from
-fails:The super keyword can't be used with implicit arguments from a method defined with define_method
--- a/graal/com.oracle.truffle.ruby.test/specs/tags/language/symbol_tags.txt	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,7 +0,0 @@
-fails:A Symbol literal is a ':' followed by any number of valid characters
-fails:A Symbol literal is a ':' followed by a single- or double-quoted string that may contain otherwise invalid characters
-fails:A Symbol literal is converted to a literal, unquoted representation if the symbol contains only valid characters
-fails:A Symbol literal can be created by the %s-delimited expression
-fails:A Symbol literal is the same object when created from identical strings
-fails:A Symbol literal can contain null in the string
-fails:A Symbol literal can be an empty string
--- a/graal/com.oracle.truffle.ruby.test/specs/tags/language/throw_tags.txt	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-fails:The throw keyword does not convert strings to a symbol
-fails:The throw keyword raises an ArgumentError if outside of scope of a matching catch
-fails:The throw keyword raises a ArgumentError if used to exit a thread
--- a/graal/com.oracle.truffle.ruby.test/specs/tags/language/undef_tags.txt	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-fails:The undef keyword undefines 'meth='
--- a/graal/com.oracle.truffle.ruby.test/specs/tags/language/until_tags.txt	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-fails:The until modifier with begin .. end block runs block at least once (even if the expression is true)
-fails:The until modifier with begin .. end block evaluates condition after block execution
-fails:The until modifier with begin .. end block skips to end of body with next
-fails:The until modifier with begin .. end block restart the current iteration without reevaluting condition with redo
--- a/graal/com.oracle.truffle.ruby.test/specs/tags/language/variables_tags.txt	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,29 +0,0 @@
-fails:Basic assignment calls to_a on the given argument when using a splat
-fails:Basic assignment allows assignment through lambda
-fails:Basic multiple assignment with a single RHS value does not call #to_ary on an Array subclass instance
-fails:Basic multiple assignment with a single RHS value does not call #to_a on an Array subclass instance
-fails:Basic multiple assignment with a single RHS value calls #to_ary on an object
-fails:Basic multiple assignment with a splatted single RHS value does not call #to_ary on an Array subclass instance
-fails:Basic multiple assignment with a splatted single RHS value does not call #to_a on an Array subclass instance
-fails:Basic multiple assignment with a splatted single RHS value calls #to_a on an object if #to_ary is not defined
-fails:Assigning multiple values calls #to_ary on RHS arg if the corresponding LHS var is a splat
-fails:Assigning multiple values allows complex parallel assignment
-fails:Unconditional operator assignment 'var op= expr' is equivalent to 'var = var op expr'
-fails:Unconditional operator assignment 'obj.meth op= expr' is equivalent to 'obj.meth = obj.meth op expr'
-fails:Conditional operator assignment 'obj.meth op= expr' is equivalent to 'obj.meth op obj.meth = expr'
-fails:Conditional operator assignment 'obj.meth op= expr' may not assign at all, depending on the truthiness of lhs
-fails:Operator assignment 'obj.meth op= expr' evaluates lhs one time
-fails:Unconditional operator assignment 'obj[idx] op= expr' is equivalent to 'obj[idx] = obj[idx] op expr'
-fails:Conditional operator assignment 'obj[idx] op= expr' may not assign at all, depending on the truthiness of lhs
-fails:Operator assignment 'obj[idx] op= expr' handles empty index (idx) arguments
-fails:Operator assignment 'obj[idx] op= expr' handles complex index (idx) arguments
-fails:Operator assignment 'obj[idx] op= expr' handles empty splat index (idx) arguments
-fails:Operator assignment 'obj[idx] op= expr' handles single splat index (idx) arguments
-fails:Operator assignment 'obj[idx] op= expr' handles multiple splat index (idx) arguments
-fails:Operator assignment 'obj[idx] op= expr' handles splat index (idx) arguments with normal arguments
-fails:Operator assignment 'obj[idx] op= expr' returns result of rhs not result of []=
-fails:Multiple assignments with grouping A group on the lhs is considered one position and treats its corresponding rhs position like an Array
-fails:Multiple assignments with grouping supports multiple levels of nested groupings
-fails:Multiple assignment has the proper return value
-fails:Multiple assignment, array-style returns an array of all rhs values
-fails:Multiple assignments with splats * on the LHS has to be applied to any parameter
--- a/graal/com.oracle.truffle.ruby.test/specs/tags/language/while_tags.txt	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-fails:The while modifier with begin .. end block runs block at least once (even if the expression is false)
-fails:The while modifier with begin .. end block evaluates condition after block execution
-fails:The while modifier with begin .. end block skips to end of body with next
-fails:The while modifier with begin .. end block restarts the current iteration without reevaluting condition with redo
--- a/graal/com.oracle.truffle.ruby.test/specs/tags/language/yield_tags.txt	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,21 +0,0 @@
-fails:The yield call taking no arguments raises a LocalJumpError when the method is not passed a block
-fails:The yield call taking no arguments ignores assignment to the explicit block argument and calls the passed block
-fails:The yield call taking a single argument raises a LocalJumpError when the method is not passed a block
-fails:The yield call taking a single argument passes an empty Array when the argument is an empty Array
-fails:The yield call taking a single argument passes nil as a value
-fails:The yield call taking a single argument passes a single value
-fails:The yield call taking a single argument passes a single, multi-value Array
-fails:The yield call taking multiple arguments raises a LocalJumpError when the method is not passed a block
-fails:The yield call taking multiple arguments passes the arguments to the block
-fails:The yield call taking a single splatted argument raises a LocalJumpError when the method is not passed a block
-fails:The yield call taking a single splatted argument passes a single value
-fails:The yield call taking a single splatted argument passes no arguments when the argument is an empty Array
-fails:The yield call taking a single splatted argument passes the value when the argument is an Array containing a single value
-fails:The yield call taking a single splatted argument passes the values of the Array as individual arguments
-fails:The yield call taking a single splatted argument passes the element of a single element Array
-fails:The yield call taking a single splatted argument passes no values when give nil as an argument
-fails:The yield call taking multiple arguments with a splat raises a LocalJumpError when the method is not passed a block
-fails:The yield call taking multiple arguments with a splat passes the arguments to the block
-fails:The yield call taking multiple arguments with a splat does not pass an argument value if the splatted argument is an empty Array
-fails:The yield call taking multiple arguments with a splat passes the Array elements as arguments if the splatted argument is a non-empty Array
-fails:The yield call taking multiple arguments with a splat does not pass an argument value if the splatted argument is nil
--- a/graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/RubyTests.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,99 +0,0 @@
-/*
- * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.test;
-
-import static org.junit.Assert.*;
-
-import java.io.*;
-import java.util.*;
-
-import org.junit.*;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.ruby.nodes.core.*;
-import com.oracle.truffle.ruby.parser.*;
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.configuration.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-
-/**
- * Base class for Ruby tests.
- */
-public class RubyTests {
-
-    @BeforeClass
-    public static void applyDefaultLocale() {
-        // Avoid printing comparison issues
-        Locale.setDefault(Locale.ENGLISH);
-    }
-
-    /**
-     * Executes some Ruby code and asserts that it prints an expected string. Remember to include
-     * the newline characters.
-     */
-    public static void assertPrints(String expectedOutput, String code, String... args) {
-        assertPrintsWithInput(expectedOutput, code, "", args);
-    }
-
-    /**
-     * Executes some Ruby code and asserts that it prints an expected string. Remember to include
-     * the newline characters. Allows input for {@code Kernel#gets} to be passed in.
-     */
-    public static void assertPrintsWithInput(String expectedOutput, String code, String input, String... args) {
-        assertPrints(null, expectedOutput, "(test)", code, input, args);
-    }
-
-    /**
-     * Executes some Ruby code and asserts that it prints an expected string. Remember to include
-     * the newline characters. Also takes a string to simulate input.
-     */
-    public static void assertPrints(Configuration configuration, String expectedOutput, String fileName, String code, String input, String... args) {
-        final ByteArrayOutputStream byteArray = new ByteArrayOutputStream();
-        final PrintStream printStream = new PrintStream(byteArray);
-
-        ConfigurationBuilder configurationBuilder;
-
-        if (configuration == null) {
-            configurationBuilder = new ConfigurationBuilder();
-        } else {
-            configurationBuilder = new ConfigurationBuilder(configuration);
-        }
-
-        configurationBuilder.setStandardOut(printStream);
-
-        final BufferedReader inputReader = new BufferedReader(new StringReader(input));
-
-        configurationBuilder.setInputReader(new InputReader() {
-
-            @Override
-            public String readLine(String prompt) throws IOException {
-                return inputReader.readLine();
-            }
-
-        });
-
-        final RubyContext context = new RubyContext(new Configuration(configurationBuilder), new JRubyParser());
-        context.setDebugContext(new MinimalRubyDebugContext(context));
-
-        CoreMethodNodeManager.addMethods(context.getCoreLibrary().getObjectClass());
-        context.getCoreLibrary().initializeAfterMethodsAdded();
-
-        for (String arg : args) {
-            context.getCoreLibrary().getArgv().push(new RubyString(context.getCoreLibrary().getStringClass(), arg));
-        }
-
-        final Source source = context.getSourceManager().getFakeFile(fileName, code);
-
-        context.execute(context, source, RubyParser.ParserContext.TOP_LEVEL, context.getCoreLibrary().getMainObject(), null);
-        context.shutdown();
-
-        assertEquals(expectedOutput, byteArray.toString().replaceAll("\r\n", "\n"));
-    }
-}
--- a/graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/core/ArrayTests.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,168 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.test.core;
-
-import org.junit.*;
-
-import com.oracle.truffle.ruby.test.*;
-
-/**
- * Test the {@code Array} class.
- */
-public class ArrayTests extends RubyTests {
-
-    @Test
-    public void testLiteral() {
-        assertPrints("", "puts []");
-        assertPrints("1\n", "puts [1]");
-        assertPrints("1\n2\n", "puts [1, 2]");
-        assertPrints("1\n2\n3\n", "puts [1, 2, 3]");
-        assertPrints("1\n2\n3\n", "puts [(1), 2, ((3))]");
-    }
-
-    @Test
-    public void testReadIndexSimple() {
-        assertPrints("2\n", "puts [1, 2, 3][1]");
-        assertPrints("2\n", "x = [1, 2, 3]; puts x[1]");
-        assertPrints("\n", "puts [1, 2, 3][10]");
-    }
-
-    @Test
-    public void testReadIndexRange() {
-        assertPrints("2\n3\n", "puts [1, 2, 3][1..2]");
-        assertPrints("2\n3\n", "puts [1, 2, 3][1..-1]");
-        assertPrints("1\n2\n3\n", "puts [1, 2, 3][0..-1]");
-    }
-
-    @Test
-    public void testWriteIndexSimple() {
-        assertPrints("1\n0\n3\n", "x = [1, 2, 3]; x[1] = 0; puts x");
-        assertPrints("0\n", "x = [1, 2, 3]; puts x[1] = 0");
-        assertPrints("1\n\n3\n", "x = [1]; x[2] = 3; puts x");
-    }
-
-    @Test
-    public void testWriteIndexRangeSingle() {
-        assertPrints("1\n0\n", "x = [1, 2, 3]; x[1..2] = 0; puts x");
-        assertPrints("1\n0\n", "x = [1, 2, 3]; x[1..3] = 0; puts x");
-        assertPrints("1\n0\n", "x = [1, 2, 3]; x[1..-1] = 0; puts x");
-        assertPrints("0\n", "x = [1, 2, 3]; x[0..-1] = 0; puts x");
-    }
-
-    @Test
-    public void testWriteIndexRangeArray() {
-        assertPrints("1\n4\n5\n", "x = [1, 2, 3]; x[1..2] = [4, 5]; puts x");
-        assertPrints("1\n4\n5\n", "x = [1, 2, 3]; x[1..-1] = [4, 5]; puts x");
-        assertPrints("4\n5\n6\n", "x = [1, 2, 3]; x[0..-1] = [4, 5, 6]; puts x");
-    }
-
-    @Test
-    public void testInsert() {
-        assertPrints("1\n2\n3\n", "x = [1, 2]; x.insert(2, 3); puts x");
-        assertPrints("1\n2\n3\n", "x = [1, 3]; x.insert(1, 2); puts x");
-        assertPrints("1\n\n3\n", "x = [1]; x.insert(2, 3); puts x");
-    }
-
-    @Test
-    public void testPush() {
-        assertPrints("1\n2\n3\n", "x = [1, 2]; x.push(3); puts x");
-        assertPrints("1\n2\n3\n", "x = [1, 2]; x << 3; puts x");
-        assertPrints("1\n2\n3\n4\n", "x = [1, 2]; x << 3 << 4; puts x");
-    }
-
-    @Test
-    public void testDeleteAt() {
-        assertPrints("1\n3\n", "x = [1, 2, 3]; x.delete_at(1); puts x");
-    }
-
-    @Test
-    public void testDup() {
-        assertPrints("1\n2\n3\n", "x = [1, 2, 3]; y = x.dup; x.delete_at(1); puts y;");
-    }
-
-    @Test
-    public void testOpAssign() {
-        assertPrints("1\n", "x = [0]; x[0] += 1; puts x");
-    }
-
-    @Test
-    public void testSize() {
-        assertPrints("0\n", "puts [].size");
-        assertPrints("1\n", "puts [1].size");
-        assertPrints("2\n", "puts [1, 2].size");
-    }
-
-    @Test
-    public void testEach() {
-        assertPrints("", "[].each { |n| puts n }");
-        assertPrints("1\n", "[1].each { |n| puts n }");
-        assertPrints("1\n2\n3\n", "[1, 2, 3].each { |n| puts n }");
-    }
-
-    @Test
-    public void testMap() {
-        assertPrints("2\n4\n6\n", "puts [1, 2, 3].map { |n| n*2 }");
-    }
-
-    @Test
-    public void testZip() {
-        assertPrints("1\n4\n2\n5\n3\n6\n", "puts [1, 2, 3].zip([4, 5, 6])");
-        assertPrints("1\n4\n2\n5\n", "puts [1, 2].zip([4, 5, 6])");
-        assertPrints("1\n4\n2\n5\n3\n\n", "puts [1, 2, 3].zip([4, 5])");
-        assertPrints("1\n3\n5\n2\n4\n6\n", "puts [1, 2].zip([3, 4], [5, 6])");
-    }
-
-    @Test
-    public void testProduct() {
-        assertPrints("[[1, 3], [1, 4], [2, 3], [2, 4]]\n", "puts [1, 2].product([3, 4]).to_s");
-    }
-
-    @Test
-    public void testInject() {
-        assertPrints("10\n", "puts [2, 3, 4].inject(1) { |a, n| a + n }");
-    }
-
-    @Test
-    public void testLiteralSplat() {
-        assertPrints("[1, 2, 3, 4]\n", "a = [3, 4]; puts [1, 2, *a].to_s");
-        assertPrints("[1, 2, 3, 4, 5, 6]\n", "a = [3, 4]; puts [1, 2, *a, 5, 6].to_s");
-    }
-
-    @Test
-    public void testSplatCast() {
-        assertPrints("[14]\n", "def foo; value = 14; return *value; end; puts foo.to_s");
-    }
-
-    @Test
-    public void testSelect() {
-        assertPrints("[3, 4]\n", "foo = [1, 2, 3, 4]; bar = foo.select { |x| x > 2 }; puts bar.to_s");
-    }
-
-    @Test
-    public void testInclude() {
-        assertPrints("true\nfalse\n", "foo = [1, 2, 3, 4]; puts foo.include? 2; puts foo.include? 5");
-    }
-
-    @Test
-    public void testSub() {
-        assertPrints("[1, 4]\n", "puts ([1, 2, 2, 3, 4] - [2, 3]).to_s");
-    }
-
-    @Test
-    public void testJoin() {
-        assertPrints("1.2.3\n", "puts [1, 2, 3].join('.')");
-    }
-
-    @Test
-    public void testShift() {
-        assertPrints("1\n2\n3\n", "a = [1, 2, 3]; while b = a.shift; puts b; end");
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/core/BignumTests.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,57 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.test.core;
-
-import org.junit.*;
-
-import com.oracle.truffle.ruby.test.*;
-
-/**
- * Test the {@code Bignum} class.
- */
-public class BignumTests extends RubyTests {
-
-    @Test
-    public void testImmediate() {
-        assertPrints("123456789123456789\n", "puts 123456789123456789");
-        assertPrints("574658776654483828\n", "puts 574658776654483828");
-    }
-
-    @Test
-    public void testAddImmediate() {
-        assertPrints("821572354901397406\n", "puts 123456789123456789+698115565777940617");
-        assertPrints("7675735362615108\n", "puts 867676857675 + 7674867685757433");
-        assertPrints("8792416214481\n", "puts 8785647643454 + (6768571027)");
-        assertPrints("8089240320234\n", "puts (7132953783486) + ((956286536748))");
-    }
-
-    @Test
-    public void testSubImmediate() {
-        assertPrints("574658776654483828\n", "puts 698115565777940617-123456789123456789");
-        assertPrints("7674000008899758\n", "puts 7674867685757433 - 867676857675");
-        assertPrints("8778879072427\n", "puts 8785647643454 - (6768571027)");
-        assertPrints("6176667246738\n", "puts (7132953783486) - ((956286536748))");
-    }
-
-    @Test
-    public void testLessImmediate() {
-        assertPrints("false\n", "puts 698115565777940617 < 123456789123456789");
-        assertPrints("true\n", "puts 867676857675 < 7674867685757433");
-        assertPrints("false\n", "puts 8785647643454 < (6768571027)");
-        assertPrints("true\n", "puts (956286536748) < ((7132953783486))");
-    }
-
-    @Test
-    public void testDivmod() {
-        assertPrints("100\n2342\n", "puts 1000000000000000000000002342.divmod(10000000000000000000000000)");
-        assertPrints("Fixnum\n", "puts 1000000000000000000000002342.divmod(10000000000000000000000000)[0].class");
-        assertPrints("Fixnum\n", "puts 1000000000000000000000002342.divmod(10000000000000000000000000)[1].class");
-    }
-}
--- a/graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/core/BoolTests.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,28 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.test.core;
-
-import org.junit.*;
-
-import com.oracle.truffle.ruby.test.*;
-
-/**
- * Test {@code true} and {@code false}. Note that there is no {@code Bool} class or type. There is
- * {@code TrueClass}, {@code FalseClass}, and instances of them {@code true} and {@code false}.
- */
-public class BoolTests extends RubyTests {
-
-    @Test
-    public void testImmediate() {
-        assertPrints("true\n", "puts true");
-        assertPrints("false\n", "puts false");
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/core/ContinuationTests.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,42 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.test.core;
-
-import org.junit.*;
-
-import com.oracle.truffle.ruby.test.*;
-
-/**
- * Test the {@code Continuation} class.
- */
-public class ContinuationTests extends RubyTests {
-
-    @Test
-    public void testRequired() {
-        assertPrints("", "callcc { |c| c.call }");
-    }
-
-    @Test
-    public void testOneShotGoingUpCallstack() {
-        assertPrints("1\n3\n", "callcc { |c| puts 1; c.call; puts 2 }; puts 3");
-    }
-
-    @Test
-    public void testOneShotGoingUpCallstackReturnValue() {
-        assertPrints("14\n", "puts callcc { |c| c.call 14 }");
-    }
-
-    @Test
-    public void testNestedOneShotGoingUpCallstack() {
-        assertPrints("1\n2\n4\n5\n", "callcc { |c1| puts 1; callcc { |c2| puts 2; c2.call; puts 3 }; puts 4 }; puts 5");
-        assertPrints("1\n2\n5\n", "callcc { |c1| puts 1; callcc { |c2| puts 2; c1.call; puts 3 }; puts 4 }; puts 5");
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/core/FiberTests.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,46 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.test.core;
-
-import org.junit.*;
-
-import com.oracle.truffle.ruby.test.*;
-
-/**
- * Test the {@code Fiber} class.
- */
-public class FiberTests extends RubyTests {
-
-    @Test
-    public void testResume() {
-        assertPrints("14\n", "f = Fiber.new { |x| puts x }; f.resume 14");
-    }
-
-    @Test
-    public void testYield() {
-        assertPrints("14\n", "f = Fiber.new { |x| Fiber.yield x }; puts f.resume(14)");
-    }
-
-    @Test
-    public void testCountdown() {
-        assertPrints("", "f = Fiber.new do |n|\n" + //
-                        "    loop do\n" + //
-                        "        n = Fiber.yield n - 1\n" + //
-                        "    end\n" + //
-                        "end\n" + //
-                        "\n" + //
-                        "n = 1000\n" + //
-                        "\n" + //
-                        "while n > 0\n" + //
-                        "    n = f.resume n\n" + //
-                        "end\n");
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/core/FixnumTests.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,134 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.test.core;
-
-import org.junit.*;
-
-import com.oracle.truffle.ruby.test.*;
-
-/**
- * Test the {@code Fixnum} class.
- */
-public class FixnumTests extends RubyTests {
-
-    @Test
-    public void testImmediate() {
-        assertPrints("2\n", "puts 2");
-        assertPrints("14\n", "puts 14");
-        assertPrints("-14\n", "puts -14");
-    }
-
-    @Test
-    public void testNegate() {
-        assertPrints("-1\n", "x = 1; puts -x");
-        assertPrints("1\n", "x = -1; puts -x");
-    }
-
-    @Test
-    public void testAddImmediate() {
-        assertPrints("16\n", "puts 14+2");
-        assertPrints("14\n", "puts 12 + 2");
-        assertPrints("17\n", "puts 9 + (8)");
-        assertPrints("10\n", "puts (6) + ((4))");
-    }
-
-    @Test
-    public void testSubImmediate() {
-        assertPrints("12\n", "puts 14-2");
-        assertPrints("10\n", "puts 12 - 2");
-        assertPrints("1\n", "puts 9 - (8)");
-        assertPrints("2\n", "puts (6) - ((4))");
-    }
-
-    @Test
-    public void testMulImmediate() {
-        assertPrints("28\n", "puts 14 * 2");
-        assertPrints("20\n", "puts 2 * 10");
-        assertPrints("72\n", "puts 9 * (8)");
-        assertPrints("24\n", "puts (4) * ((6))");
-    }
-
-    @Test
-    public void testDivImmediate() {
-        assertPrints("7\n", "puts 14 / 2");
-        assertPrints("0\n", "puts 2 / 10");
-        assertPrints("1\n", "puts 9 / (8)");
-        assertPrints("0\n", "puts (4) / ((6))");
-    }
-
-    @Test
-    public void testEqualImmediate() {
-        assertPrints("true\n", "puts 14 == 14");
-        assertPrints("true\n", "puts 2 == 2");
-        assertPrints("false\n", "puts 9 == (8)");
-        assertPrints("false\n", "puts (4) == ((6))");
-    }
-
-    @Test
-    public void testNotEqualImmediate() {
-        assertPrints("false\n", "puts 14 != 14");
-        assertPrints("false\n", "puts 2 != 2");
-        assertPrints("true\n", "puts 9 != (8)");
-        assertPrints("true\n", "puts (4) != ((6))");
-    }
-
-    @Test
-    public void testLessImmediate() {
-        assertPrints("false\n", "puts 14 < 2");
-        assertPrints("true\n", "puts 2 < 10");
-        assertPrints("false\n", "puts 9 < (8)");
-        assertPrints("true\n", "puts (4) < ((6))");
-    }
-
-    @Test
-    public void testGreaterEqualImmediate() {
-        assertPrints("true\n", "puts 14 >= 14");
-        assertPrints("true\n", "puts 14 >= 2");
-        assertPrints("false\n", "puts 2 >= 10");
-        assertPrints("true\n", "puts 9 >= (8)");
-        assertPrints("false\n", "puts (4) >= ((6))");
-    }
-
-    @Test
-    public void testLeftShift() {
-        assertPrints("0\n", "puts 0 << 0");
-        assertPrints("0\n", "puts 0 << 1");
-        assertPrints("1\n", "puts 1 << 0");
-        assertPrints("0\n", "puts 1 << -1");
-        assertPrints("0\n", "puts 1 << -2");
-        assertPrints("28\n", "puts 14 << 1");
-        assertPrints("7\n", "puts 14 << -1");
-        assertPrints("4294967296\n", "puts 1 << 32");
-        assertPrints("340282366920938463463374607431768211456\n", "puts 1 << 128");
-        assertPrints("0\n", "puts 1 << -32");
-        assertPrints("Fixnum\n", "puts (14 << 1).class");
-        assertPrints("Bignum\n", "puts (1 << 32).class");
-    }
-
-    @Test
-    public void testDivmod() {
-        // @formatter:off
-        final int[][] tests = new int[][]{
-                        new int[]{13,   4,  3,  1},
-                        new int[]{13,  -4, -4, -3},
-                        new int[]{-13,  4, -4,  3},
-                        new int[]{-13, -4,  3, -1}};
-        // @formatter:on
-
-        for (int[] test : tests) {
-            final int a = test[0];
-            final int b = test[1];
-            final int q = test[2];
-            final int r = test[3];
-            assertPrints(String.format("%d\n%d\n", q, r), String.format("puts %d.divmod(%d)", a, b));
-        }
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/core/FloatTests.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,71 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.test.core;
-
-import org.junit.*;
-
-import com.oracle.truffle.ruby.test.*;
-
-/**
- * Test the {@code Float} class.
- */
-public class FloatTests extends RubyTests {
-
-    @Test
-    public void testImmediate() {
-        assertPrints("2.5\n", "puts 2.5");
-        assertPrints("14.33\n", "puts 14.33");
-    }
-
-    @Test
-    public void testAddImmediate() {
-        assertPrints("16.2\n", "puts 14.1+2.1");
-        assertPrints("14.2\n", "puts 12.1 + 2.1");
-        assertPrints("17.2\n", "puts 9.1 + (8.1)");
-        assertPrints("10.2\n", "puts (6.1) + ((4.1))");
-    }
-
-    @Test
-    public void testSubImmediate() {
-        assertPrints("12.1\n", "puts 14.2-2.1");
-        assertPrints("10.1\n", "puts 12.2 - 2.1");
-        assertPrints("1.0999999999999996\n", "puts 9.2 - (8.1)");
-        assertPrints("2.1000000000000005\n", "puts (6.2) - ((4.1))");
-    }
-
-    @Test
-    public void testMulImmediate() {
-        assertPrints("29.82\n", "puts 14.2*2.1");
-        assertPrints("25.62\n", "puts 12.2 * 2.1");
-        assertPrints("74.52\n", "puts 9.2 * (8.1)");
-        assertPrints("25.419999999999998\n", "puts (6.2) * ((4.1))");
-        assertPrints("7.5\n", "puts 2.5 * 3");
-        assertPrints("7.5\n", "puts 3 * 2.5");
-    }
-
-    @Test
-    public void testDivImmediate() {
-        assertPrints("6.761904761904761\n", "puts 14.2/2.1");
-        assertPrints("5.809523809523809\n", "puts 12.2 / 2.1");
-        assertPrints("1.1358024691358024\n", "puts 9.2 / (8.1)");
-        assertPrints("1.5121951219512197\n", "puts (6.2) / ((4.1))");
-        assertPrints("0.8333333333333334\n", "puts 2.5 / 3");
-        assertPrints("1.2\n", "puts 3 / 2.5");
-    }
-
-    @Test
-    public void testLessImmediate() {
-        assertPrints("false\n", "puts 14.2<2.2");
-        assertPrints("true\n", "puts 2.2 < 10.2");
-        assertPrints("false\n", "puts 9.2 < (8.2)");
-        assertPrints("true\n", "puts (4.2) < ((6.2))");
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/core/HashTests.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,43 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.test.core;
-
-import org.junit.*;
-
-import com.oracle.truffle.ruby.test.*;
-
-/**
- * Test the {@code Hash} class.
- */
-public class HashTests extends RubyTests {
-
-    @Test
-    public void testLiteral() {
-        assertPrints("Hash\n", "puts ({}).class");
-        assertPrints("Hash\n", "puts ({1 => 2, 3 => 4}).class");
-        assertPrints("Hash\n", "puts ({key1: 2, key3: 4}).class");
-    }
-
-    @Test
-    public void testIndex() {
-        assertPrints("4\n", "foo = {1 => 2, 3 => 4}; puts foo[3]");
-    }
-
-    @Test
-    public void testIndexSet() {
-        assertPrints("6\n", "foo = {1 => 2, 3 => 4}; foo[5] = 6; puts foo[5]");
-    }
-
-    @Test
-    public void testKeys() {
-        assertPrints("[1, 3]\n", "foo = {1 => 2, 3 => 4}; puts foo.keys.to_s");
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/core/IntegerTests.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.test.core;
-
-import org.junit.*;
-
-import com.oracle.truffle.ruby.test.*;
-
-/**
- * Test the {@code Integer} class.
- */
-public class IntegerTests extends RubyTests {
-
-    @Test
-    public void testTimes() {
-        assertPrints("0\n", "1.times { |i| puts i }");
-        assertPrints("0\n1\n2\n", "3.times { |i| puts i }");
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/core/KernelTests.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,111 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.test.core;
-
-import org.junit.*;
-
-import com.oracle.truffle.ruby.runtime.configuration.*;
-import com.oracle.truffle.ruby.test.*;
-
-/**
- * Test {@code Kernel}.
- */
-public class KernelTests extends RubyTests {
-
-    @Test
-    public void testPutsEmpty() {
-        assertPrints("\n", "puts");
-    }
-
-    @Test
-    public void testPutsString() {
-        assertPrints("1\n", "puts 1");
-    }
-
-    @Test
-    public void testPrintfNoFormatting() {
-        assertPrints("", "printf");
-        assertPrints("foo", "printf \"foo\"");
-        assertPrints("foo\n", "printf \"foo\\n\"");
-    }
-
-    @Test
-    public void testPrintfDecimal() {
-        assertPrints("foo14bar", "printf \"foo%dbar\", 14");
-    }
-
-    @Test
-    public void testGets() {
-        assertPrintsWithInput("test\n", "puts gets", "test\n");
-    }
-
-    @Test
-    public void testInteger() {
-        assertPrints("14\n", "puts Integer(\"14\")");
-    }
-
-    @Test
-    public void testEval() {
-        assertPrints("16\n", "puts eval(\"14 + 2\")");
-    }
-
-    @Test
-    public void testBindingLocalVariables() {
-        // Use the current binding for eval
-        assertPrints("16\n", "x = 14; y = 2; puts eval(\"x + y\", binding)");
-
-        // Use the binding returned from a method for eval
-        assertPrints("16\n", "def foo; x = 14; y = 2; binding; end; puts eval(\"x + y\", foo)");
-    }
-
-    @Test
-    public void testBindingInstanceVariables() {
-        // Use the binding returned from a method in an object for eval
-        assertPrints("16\n", "class Foo; def foo; @x = 14; @y = 2; binding; end; end; puts eval(\"@x + @y\", Foo.new.foo)");
-    }
-
-    @Ignore
-    @Test
-    public void testSetTraceFuncLine() {
-        final ConfigurationBuilder configuration = new ConfigurationBuilder();
-        configuration.setTrace(true);
-
-        final String code = "def foo\n" + //
-                        "    a = 14\n" + //
-                        "    b = 2\n" + //
-                        "    a + b\n" + //
-                        "end\n" + //
-                        "\n" + //
-                        "set_trace_func proc { |event, file, line, id, binding, classname|\n" + //
-                        "    if event == \"line\"\n" + //
-                        "        puts file + \":\" + line.to_s\n" + //
-                        "    end\n" + //
-                        "}\n" + //
-                        "\n" + //
-                        "foo";
-        final String input = "";
-        final String expected = "(test):13\n(test):2\n(test):3\n(test):4\n";
-        assertPrints(new Configuration(configuration), expected, "(test)", code, input);
-    }
-
-    @Test
-    public void testBlockGiven() {
-        assertPrints("false\n", "def foo; puts block_given?; end; foo");
-        assertPrints("true\n", "def foo; puts block_given?; end; foo do; end");
-        assertPrints("true\n", "def foo; puts block_given?; end; foo {}");
-        assertPrints("true\n", "def foo; puts block_given?; end; foo &:+");
-    }
-
-    @Test
-    public void testLoop() {
-        assertPrints("14\n", "loop do; break; end; puts 14");
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/core/MathTests.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.test.core;
-
-import org.junit.*;
-
-import com.oracle.truffle.ruby.test.*;
-
-/**
- * Test the {@code Math} class.
- */
-public class MathTests extends RubyTests {
-
-    @Test
-    public void testPI() {
-        assertPrints("3.141592653589793\n", "puts Math::PI");
-    }
-
-    @Test
-    public void testSqrt() {
-        assertPrints("1.0\n", "puts Math.sqrt(1)");
-        assertPrints("1.0\n", "puts Math::sqrt(1)");
-        assertPrints("3.7416573867739413\n", "puts Math::sqrt(14)");
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/core/ModuleTests.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,59 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.test.core;
-
-import org.junit.*;
-
-import com.oracle.truffle.ruby.test.*;
-
-/**
- * Test the {@code Module} class.
- */
-public class ModuleTests extends RubyTests {
-
-    @Test
-    public void testAttrAccessor() {
-        assertPrints("14\n", "class Foo; attr_accessor :x end; foo=Foo.new; foo.x=14; puts foo.x");
-        assertPrints("14\n", "class Foo; attr_accessor(:x) end; foo=Foo.new; foo.x=14; puts foo.x");
-        assertPrints("16\n", "class Foo; attr_accessor(:x, :y) end; foo=Foo.new; foo.x=14; foo.y=2; puts foo.x + foo.y");
-        assertPrints("16\n", "class Foo; attr_accessor :x end; foo=Foo.new; foo.x=2; foo.x+=14; puts foo.x");
-    }
-
-    @Test
-    public void testDefineMethod() {
-        /*
-         * We use Object#send instead of calling define_method directly because that method is
-         * private.
-         */
-
-        assertPrints("14\n", "class Foo; end; Foo.send(:define_method, :foo) do; puts 14; end; Foo.new.foo");
-    }
-
-    @Test
-    public void testDefinedBeforeScopeRun() {
-        assertPrints("Module\n", "module Foo; puts Foo.class; end");
-    }
-
-    @Test
-    public void testDefinedInRootScopeBeforeScopeRun() {
-        assertPrints("Module\n", "module Foo; puts ::Foo.class; end");
-    }
-
-    @Test
-    public void testModuleEval() {
-        assertPrints("14\n", "class Foo; puts 14; end; Foo.module_eval('def foo; end'); Foo.new.foo");
-    }
-
-    @Test
-    public void testNextInBlock() {
-        assertPrints("1\n1\n1\n", "3.times do; puts 1; next; puts 2; end");
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/core/ObjectSpaceTests.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,57 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.test.core;
-
-import org.junit.*;
-
-import com.oracle.truffle.ruby.runtime.configuration.*;
-import com.oracle.truffle.ruby.test.*;
-
-/**
- * Test the {@code ObjectSpace} module.
- */
-public class ObjectSpaceTests extends RubyTests {
-
-    @Test
-    public void testEachObjectClass() {
-        assertPrints("true\n", "found_string = false; ObjectSpace.each_object(Class) { |o| if o == String; found_string = true; end  }; puts found_string");
-    }
-
-    @Test
-    public void testId2RefClass() {
-        assertPrints("true\n", "puts ObjectSpace._id2ref(String.object_id) == String");
-    }
-
-    @Test
-    public void testEachObjectString() {
-        final ConfigurationBuilder configurationBuilder = new ConfigurationBuilder();
-        configurationBuilder.setFullObjectSpace(true);
-        final String code = "foo = \"foo\"; found_foo = false; ObjectSpace.each_object(String) { |o| if o == foo; found_foo= true; end  }; puts found_foo";
-        final String input = "";
-        final String expected = "true\n";
-        assertPrints(new Configuration(configurationBuilder), expected, "(test)", code, input);
-    }
-
-    @Test
-    public void testId2RefString() {
-        final ConfigurationBuilder configurationBuilder = new ConfigurationBuilder();
-        configurationBuilder.setFullObjectSpace(true);
-        final String code = "foo = \"foo\"; puts ObjectSpace._id2ref(foo.object_id) == foo";
-        final String input = "";
-        final String expected = "true\n";
-        assertPrints(new Configuration(configurationBuilder), expected, "(test)", code, input);
-    }
-
-    @Test
-    public void testGarbageCollect() {
-        assertPrints("", "ObjectSpace.garbage_collect");
-        assertPrints("", "ObjectSpace.start");
-    }
-}
--- a/graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/core/ObjectTests.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,70 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.test.core;
-
-import org.junit.*;
-
-import com.oracle.truffle.ruby.test.*;
-
-/**
- * Test the {@code Object} class.
- */
-public class ObjectTests extends RubyTests {
-
-    @Test
-    public void testARGV() {
-        assertPrints("1\n2\n3\n", "puts ARGV", "1", "2", "3");
-    }
-
-    @Test
-    public void testInstanceVariableDefined() {
-        assertPrints("true\n", "class Foo; def initialize; @bar=14; end; end; puts Foo.new.instance_variable_defined?(:@bar)");
-        assertPrints("true\n", "class Foo; def initialize; @bar=14; end; end; puts Foo.new.instance_variable_defined?(\"@bar\")");
-        assertPrints("true\n", "class Foo; def initialize; instance_variable_set(:@bar, 14); end; end; puts Foo.new.instance_variable_defined?(\"@bar\")");
-        assertPrints("false\n", "class Foo; def initialize; @foo=14; end; end; puts Foo.new.instance_variable_defined?(:@bar)");
-        assertPrints("false\n", "class Foo; def initialize; @foo=14; end; end; puts Foo.new.instance_variable_defined?(\"@bar\")");
-        assertPrints("false\n", "class Foo; def initialize; instance_variable_set(:@foo, 14); end; end; puts Foo.new.instance_variable_defined?(\"@bar\")");
-    }
-
-    @Test
-    public void testInstanceVariableGet() {
-        assertPrints("14\n", "class Foo; def initialize; @bar=14; end; end; puts Foo.new.instance_variable_get(:@bar)");
-        assertPrints("14\n", "class Foo; def initialize; @bar=14; end; end; puts Foo.new.instance_variable_get(\"@bar\")");
-    }
-
-    @Test
-    public void testInstanceVariableSet() {
-        assertPrints("14\n", "class Foo; attr_accessor :bar; end; foo = Foo.new; foo.instance_variable_set(:@bar, 14); puts foo.bar");
-        assertPrints("14\n", "class Foo; attr_accessor :bar; end; foo = Foo.new; foo.instance_variable_set(\"@bar\", 14); puts foo.bar");
-    }
-
-    @Test
-    public void testInstanceVariables() {
-        assertPrints("a\nb\n", "class Foo; def initialize; @a=2; @b=14; end; end; puts Foo.new.instance_variables");
-        assertPrints("a\nb\n", "class Foo; def initialize; @a=2; instance_variable_set(:@b, 14); end; end; puts Foo.new.instance_variables");
-    }
-
-    @Test
-    public void testSend() {
-        assertPrints("14\n", "self.send(:puts, 14)");
-        assertPrints("14\n", "self.send(\"puts\", 14)");
-    }
-
-    @Test
-    public void testExtend() {
-        assertPrints("14\n", "class Foo; end; module Bar; def bar; puts 14; end; end; foo = Foo.new; foo.extend(Bar); foo.bar");
-    }
-
-    @Test
-    public void testSingletonMethods() {
-        assertPrints("[:baz]\n", "class Foo; def bar; end; end; foo = Foo.new; def foo.baz; end; puts foo.singleton_methods.to_s");
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/core/ProcTests.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,49 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.test.core;
-
-import org.junit.*;
-
-import com.oracle.truffle.ruby.test.*;
-
-/**
- * Test the {@code Proc} class.
- */
-public class ProcTests extends RubyTests {
-
-    @Test
-    public void testKernelProc() {
-        assertPrints("1\n", "x = proc { puts 1 }; x.call");
-        assertPrints("1\n", "x = proc { 1 }; puts x.call");
-    }
-
-    @Test
-    public void testKernelLambda() {
-        assertPrints("1\n", "x = lambda { puts 1 }; x.call");
-        assertPrints("1\n", "x = lambda { 1 }; puts x.call");
-    }
-
-    @Test
-    public void testKernelProcNew() {
-        assertPrints("1\n", "x = Proc.new { puts 1 }; x.call");
-        assertPrints("1\n", "x = Proc.new { 1 }; puts x.call");
-    }
-
-    @Test
-    public void testProcReturn() {
-        assertPrints("1\n", "def foo; x = proc { return 1 }; x.call; return 2; end; puts foo");
-    }
-
-    @Test
-    public void testLambdaReturn() {
-        assertPrints("2\n", "def foo; x = lambda { return 1 }; x.call; return 2; end; puts foo");
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/core/RangeTests.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,65 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.test.core;
-
-import org.junit.*;
-
-import com.oracle.truffle.ruby.test.*;
-
-/**
- * Test the {@code Range} class.
- */
-public class RangeTests extends RubyTests {
-
-    @Test
-    public void testImmediate() {
-        assertPrints("1..2\n", "puts 1..2");
-        assertPrints("1..2\n", "puts (1..2)");
-        assertPrints("1..2\n", "puts ((1)..2)");
-        assertPrints("1...2\n", "puts 1...2");
-    }
-
-    @Test
-    public void testVariables() {
-        assertPrints("1..2\n", "x = 1; puts x..2");
-        assertPrints("1..2\n", "y = 2; puts 1..y");
-        assertPrints("1..2\n", "x = 1; y = 2; puts x..y");
-    }
-
-    @Test
-    public void testToArray() {
-        assertPrints("0\n1\n2\n", "puts (0..2).to_a");
-        assertPrints("1\n2\n", "puts (1..2).to_a");
-        assertPrints("1\n2\n", "puts (1...3).to_a");
-        assertPrints("1\n2\n3\n", "puts (1..3).to_a");
-    }
-
-    @Test
-    public void testEach() {
-        assertPrints("", "(1...1).each { |n| puts n }");
-        assertPrints("1\n", "(1...2).each { |n| puts n }");
-        assertPrints("1\n2\n", "(1...3).each { |n| puts n }");
-        assertPrints("1\n2\n3\n", "(1...4).each { |n| puts n }");
-        assertPrints("1\n", "(1..1).each { |n| puts n }");
-        assertPrints("1\n2\n", "(1..2).each { |n| puts n }");
-        assertPrints("1\n2\n3\n", "(1..3).each { |n| puts n }");
-        assertPrints("1\n2\n3\n4\n", "(1..4).each { |n| puts n }");
-        assertPrints("0\n1\n", "(0..1).each { |n| puts n }");
-        assertPrints("", "(4..-2).each { |n| puts n }");
-        assertPrints("-4\n-3\n-2\n", "(-4..-2).each { |n| puts n }");
-        assertPrints("-1\n0\n1\n", "(-1..1).each { |n| puts n }");
-    }
-
-    @Test
-    public void testMap() {
-        assertPrints("2\n4\n6\n", "puts (1..3).map { |n| n*2 }");
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/core/RegexpTests.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,46 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.test.core;
-
-import org.junit.*;
-
-import com.oracle.truffle.ruby.test.*;
-
-/**
- * Test the {@code Regexp} class.
- */
-public class RegexpTests extends RubyTests {
-
-    @Test
-    public void testLiteral() {
-        assertPrints("Regexp\n", "puts /foo/.class");
-    }
-
-    @Test
-    public void testInterpolatedLiteral() {
-        assertPrints("Regexp\n", "puts /foo#{1}/.class");
-    }
-
-    @Test
-    public void testMatch() {
-        assertPrints("0\n", "puts(/foo/ =~ \"foo\")");
-        assertPrints("0\n", "puts(\"foo\" =~ /foo/)");
-        assertPrints("3\n", "puts(/foo/ =~ \"abcfoo\")");
-        assertPrints("3\n", "puts(\"abcfoo\" =~ /foo/)");
-        assertPrints("\n", "puts(/foo/ =~ \"abc\")");
-        assertPrints("\n", "puts(\"abc\" =~ /foo/)");
-    }
-
-    @Test
-    public void testFrameLocalVariableResults() {
-        assertPrints("foo\nbar\nbaz\n", "/(foo)(bar)(baz)/ =~ 'foobarbaz'; puts $1; puts $2; puts $3");
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/core/StringTests.java	Sun Feb 23 17:00:35 2014 -0800
+++ /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. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.test.core;
-
-import org.junit.*;
-
-import com.oracle.truffle.ruby.test.*;
-
-/**
- * Test the {@code String} class.
- */
-public class StringTests extends RubyTests {
-
-    @Test
-    public void testToI() {
-        assertPrints("2\n", "puts \"2\".to_i");
-        assertPrints("-2\n", "puts \"-2\".to_i");
-        assertPrints("123456789123456789\n", "puts \"123456789123456789\".to_i");
-    }
-
-    @Test
-    public void testFormat() {
-        assertPrints("a\n", "puts \"a\"");
-        assertPrints("1\n", "puts \"%d\" % 1");
-        assertPrints("a1b\n", "puts \"a%db\" % 1");
-        assertPrints("a1.00000b\n", "puts \"a%fb\" % 1");
-        assertPrints("a2.50000b\n", "puts \"a%fb\" % 2.5");
-        assertPrints("3.400000000\n", "puts \"%.9f\" % 3.4");
-        assertPrints("3.400000000\n", "puts \"%0.9f\" % 3.4");
-    }
-
-    @Test
-    public void testThreequal() {
-        assertPrints("false\n", "puts \"a\" === \"b\"");
-        assertPrints("true\n", "puts \"a\" === \"a\"");
-    }
-
-    @Test
-    public void testIndex() {
-        assertPrints("a\n", "puts 'a'[0]");
-        assertPrints("config\n", "puts 'foo.config'[-6..-1]");
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/core/SymbolTests.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.test.core;
-
-import org.junit.*;
-
-import com.oracle.truffle.ruby.test.*;
-
-/**
- * Test the {@code Symbol} class.
- */
-public class SymbolTests extends RubyTests {
-
-    @Test
-    public void testParses() {
-        assertPrints("", ":foo");
-        assertPrints("", ":\"foo\"");
-    }
-
-    @Test
-    public void testPuts() {
-        assertPrints("foo\n", "puts :foo");
-    }
-
-    @Test
-    public void testInterpolated() {
-        assertPrints("foo123\n", "puts :\"foo1#{2}3\"");
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/core/ThreadTests.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,26 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.test.core;
-
-import org.junit.*;
-
-import com.oracle.truffle.ruby.test.*;
-
-/**
- * Test the {@code Thread} class.
- */
-public class ThreadTests extends RubyTests {
-
-    @Test
-    public void testCreateJoin() {
-        assertPrints("1\n2\n", "t = Thread.new { puts 1 }; t.join; puts 2");
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/language/AndTests.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,46 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.test.language;
-
-import org.junit.*;
-
-import com.oracle.truffle.ruby.test.*;
-
-/**
- * Test {@code and} expressions, which unusually for Ruby are not methods. This is because with
- * Ruby's eager evaluation there would be no way to implement the short circuit semantics.
- */
-public class AndTests extends RubyTests {
-
-    @Test
-    public void testImmediate() {
-        assertPrints("false\n", "puts false && false");
-        assertPrints("false\n", "puts true && false");
-        assertPrints("false\n", "puts false && true");
-        assertPrints("true\n", "puts true && true");
-        assertPrints("false\n", "puts (false and false)");
-        assertPrints("false\n", "puts (true and false)");
-        assertPrints("false\n", "puts (false and true)");
-        assertPrints("true\n", "puts (true and true)");
-    }
-
-    @Test
-    public void testShortCircuits() {
-        assertPrints("false\nfalse\nfalse\n", "x = y = false; puts (x = false) && (y = false); puts x, y");
-        assertPrints("false\ntrue\nfalse\n", "x = y = false; puts (x = true) && (y = false); puts x, y");
-        assertPrints("false\nfalse\nfalse\n", "x = y = false; puts (x = false) && (y = true); puts x, y");
-        assertPrints("true\ntrue\ntrue\n", "x = y = false; puts (x = true) && (y = true); puts x, y");
-        assertPrints("false\nfalse\nfalse\n", "x = y = false; puts ((x = false) and (y = false)); puts x, y");
-        assertPrints("false\ntrue\nfalse\n", "x = y = false; puts ((x = true) and (y = false)); puts x, y");
-        assertPrints("false\nfalse\nfalse\n", "x = y = false; puts ((x = false) and (y = true)); puts x, y");
-        assertPrints("true\ntrue\ntrue\n", "x = y = false; puts ((x = true) and (y = true)); puts x, y");
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/language/BlockTests.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,68 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.test.language;
-
-import org.junit.*;
-
-import com.oracle.truffle.ruby.test.*;
-
-/**
- * Test blocks.
- */
-public class BlockTests extends RubyTests {
-
-    @Test
-    public void testSimpleYield() {
-        assertPrints("1\n", "def foo; yield; end; foo { puts 1 };");
-        assertPrints("1\n", "def foo; yield; end; foo do; puts 1; end;");
-    }
-
-    @Test
-    public void testYieldOneParameter() {
-        assertPrints("1\n", "def foo; yield 1; end; foo { |x| puts x };");
-        assertPrints("1\n", "def foo; yield 1; end; foo do |x|; puts x; end;");
-    }
-
-    @Test
-    public void testYieldTwoParameters() {
-        assertPrints("1\n2\n", "def foo; yield 1, 2; end; foo { |x, y| puts x; puts y; };");
-        assertPrints("1\n2\n", "def foo; yield 1, 2; end; foo do |x, y|; puts x; puts y; end;");
-    }
-
-    @Test
-    public void testSelfCapturedInBlock() {
-        assertPrints("main\n", "[1].each { |n| puts self.to_s }");
-    }
-
-    @Test
-    public void testBlockArgumentsDestructure() {
-        /*
-         * This really subtle. If you pass an array to a block with more than one parameters, it
-         * will be destructured. Any other type won't be destructured. There's no annotation to
-         * indicate that, like there would be with a method with the * operator.
-         */
-
-        assertPrints("1\n", "[1].each { |x| puts x.to_s }");
-        assertPrints("[1, 2]\n", "[[1, 2]].each { |xy| puts xy.to_s }");
-        assertPrints("1\n2\n", "[[1, 2]].each { |x, y| puts x, y }");
-    }
-
-    @Test
-    public void testBlocksHaveTheirOwnScopeForAssignment() {
-        assertPrints("\n", "1.times { x = 14 }; puts defined? x");
-        assertPrints("\n", "1.times do; x = 14; end; puts defined? x");
-    }
-
-    @Test
-    public void testImplicitForBlocksDoNotHaveTheirOwnScopeForAssignment() {
-        assertPrints("local-variable\n", "for n in [1]; x = 14; end; puts defined? x");
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/language/CaseTests.java	Sun Feb 23 17:00:35 2014 -0800
+++ /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. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.test.language;
-
-import org.junit.*;
-
-import com.oracle.truffle.ruby.test.*;
-
-/**
- * Test {@code case} expressions.
- */
-public class CaseTests extends RubyTests {
-
-    @Test
-    public void testSingle() {
-        assertPrints("1\n4\n", "case 'a'; when 'a'; puts 1; when 'b'; puts 2; else; puts 3; end; puts 4");
-        assertPrints("2\n4\n", "case 'b'; when 'a'; puts 1; when 'b'; puts 2; else; puts 3; end; puts 4");
-        assertPrints("3\n4\n", "case 'c'; when 'a'; puts 1; when 'b'; puts 2; else; puts 3; end; puts 4");
-    }
-
-    @Test
-    public void testMultiple() {
-        assertPrints("1\n4\n", "case 'a'; when 'a', 'b'; puts 1; when 'c'; puts 2; else; puts 3; end; puts 4");
-        assertPrints("1\n4\n", "case 'b'; when 'a', 'b'; puts 1; when 'c'; puts 2; else; puts 3; end; puts 4");
-        assertPrints("2\n4\n", "case 'c'; when 'a', 'b'; puts 1; when 'c'; puts 2; else; puts 3; end; puts 4");
-        assertPrints("3\n4\n", "case 'd'; when 'a', 'b'; puts 1; when 'c'; puts 2; else; puts 3; end; puts 4");
-    }
-
-    @Test
-    public void testSimpleConditions() {
-        assertPrints("1\n", "case; when true; puts 1; when false; puts 2; end");
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/language/ClassLocalTests.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,53 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.test.language;
-
-import org.junit.*;
-
-import com.oracle.truffle.ruby.test.*;
-
-/**
- * Test @@ class variables. There is a lot of counter-intuitive behavior here - they aren't instance
- * variables in class objects. The books describe them as being in a 'class hierarchy', rather than
- * in a class. Also, the object they are defined it is not consistent - sometimes it is the class of
- * self, sometimes it's just self.
- */
-public class ClassLocalTests extends RubyTests {
-
-    @Test
-    public void testBasic() {
-        assertPrints("14\n", "@@x = 14; puts @@x");
-    }
-
-    /*
-     * Test that they are defined for a hierarchy, not a class.
-     */
-
-    @Test
-    public void testHeirarchyNotClassVariable() {
-        assertPrints("2\n", "class Foo; @@value = 14; end; class Bar < Foo; @@value = 2; end; class Foo; puts @@value; end");
-    }
-
-    /*
-     * Test that they take the correct class at different times. In a method, they use the class of
-     * self. In a class definition they use that class, not the class of self, which is Class.
-     */
-
-    @Test
-    public void testCorrectClass() {
-        assertPrints("1\n", "class Foo; @@x = 1; def foo; puts @@x; end; end; Foo.new.foo");
-    }
-
-    @Test
-    public void testWithinSelfMethod() {
-        assertPrints("14\n", "class Foo; @@foo = 14; def self.foo; @@foo; end; end; puts Foo.foo");
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/language/ClassTests.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,80 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.test.language;
-
-import org.junit.*;
-
-import com.oracle.truffle.ruby.test.*;
-
-/**
- * Test {@code class} expressions.
- */
-public class ClassTests extends RubyTests {
-
-    @Test
-    public void testDefine() {
-        assertPrints("Foo\n", "class Foo; end; puts Foo");
-    }
-
-    @Test
-    public void testMethods() {
-        assertPrints("14\n", "class Foo; def test; return 14; end; end; foo=Foo.new; puts foo.test");
-        assertPrints("14\n", "class Foo; def test(x); return x; end; end; foo=Foo.new; puts foo.test(14)");
-    }
-
-    @Test
-    public void testDefineHasScope() {
-        assertPrints("14\n", "x=14; class Foo; x=0; end; puts x");
-        assertPrints("14\n", "class Foo; x=14; puts x; end");
-    }
-
-    @Test
-    public void testInitialise() {
-        assertPrints("14\n", "class Foo; def initialize; puts 14; end; end; Foo.new");
-        assertPrints("14\n", "class Foo; def initialize(x); puts x; end; end; Foo.new 14");
-        assertPrints("14\n", "class Foo; def initialize(x); puts x; end; end; Foo.new(14)");
-    }
-
-    @Test
-    public void testInstanceVariables() {
-        assertPrints("14\n", "class Foo; def a; @x=14; end; def b; @x; end; end; foo=Foo.new; foo.a; puts foo.b");
-    }
-
-    @Test
-    public void testMissingVariables() {
-        assertPrints("NilClass\n", "class Foo; def a; @x; end; end; foo=Foo.new; puts foo.a.class");
-    }
-
-    @Test
-    public void testClassConstants() {
-        assertPrints("14\n", "class Foo; X=14; def foo; puts X; end; end; foo=Foo.new; foo.foo");
-    }
-
-    @Test
-    public void testReopeningSingletonClass() {
-        assertPrints("1\n", "foo = Object.new; class << foo; def bar; puts 1; end; end; foo.bar");
-    }
-
-    @Test
-    public void testInheritance() {
-        assertPrints("14\n", "class Foo; def foo; puts 14; end; end; class Bar < Foo; end; Bar.new.foo");
-    }
-
-    @Test
-    public void testSingletonInheritance() {
-        assertPrints("14\n", "class Foo; def self.foo; puts 14; end; end; class Bar < Foo; end; Bar.foo");
-    }
-
-    @Test
-    public void testNestedClass() {
-        assertPrints("14\n", "class Foo; class Bar; def bar; 14; end; end; def foo; Bar.new; end; end; puts Foo.new.foo.bar");
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/language/ConstantTests.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.test.language;
-
-import org.junit.*;
-
-import com.oracle.truffle.ruby.test.*;
-
-public class ConstantTests extends RubyTests {
-
-    @Test
-    public void testTopLevelConstants() {
-        assertPrints("14\n", "X=14; class Foo; def foo; puts X; end; end; f=Foo.new; f.foo");
-    }
-
-    @Test
-    public void testNestedConstants() {
-        assertPrints("", "module X; class A; end; class B; class C < A; end; end; end");
-    }
-
-    @Test
-    public void testSearchInParentModules() {
-        assertPrints("14\n", "module A; C = 14; module B; def self.test; puts C; end; end; end; A::B.test");
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/language/ForTests.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,49 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.test.language;
-
-import org.junit.*;
-
-import com.oracle.truffle.ruby.test.*;
-
-/**
- * Test {@code for} expressions.
- */
-public class ForTests extends RubyTests {
-
-    @Test
-    public void testArray() {
-        assertPrints("1\n2\n3\n", "for x in [1, 2, 3]; puts x; end");
-        assertPrints("1\n2\n3\n", "y = [1, 2, 3]; for x in y; puts x; end");
-    }
-
-    @Test
-    public void testRange() {
-        assertPrints("1\n2\n3\n", "for x in 1..3; puts x; end");
-        assertPrints("1\n2\n3\n", "y = 1..3; for x in y; puts x; end");
-        assertPrints("1\n2\n", "for x in 1...3; puts x; end");
-    }
-
-    @Test
-    public void testScopeRO() {
-        assertPrints("14\n", "x=14; for n in [1]; puts x; end");
-    }
-
-    @Test
-    public void testScopeRW() {
-        assertPrints("14\n", "x=0; for n in [1]; x=x+14; puts x; end");
-    }
-
-    @Test
-    public void testNoNewScope() {
-        assertPrints("14\n", "for i in [1]; v = 14; end; puts v");
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/language/GlobalVariableTests.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,32 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.test.language;
-
-import org.junit.*;
-
-import com.oracle.truffle.ruby.test.*;
-
-/**
- * Test global variables.
- */
-public class GlobalVariableTests extends RubyTests {
-
-    @Test
-    public void testMinimal() {
-        assertPrints("14\n", "$foo = 14; puts $foo");
-    }
-
-    @Test
-    public void testScope() {
-        assertPrints("14\n", "def foo; $bar = 14; end; foo; puts $bar");
-        assertPrints("14\n", "$bar = 14; def foo; puts $bar; end; foo");
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/language/IfTests.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.test.language;
-
-import org.junit.*;
-
-import com.oracle.truffle.ruby.test.*;
-
-/**
- * Test {@code if} expressions.
- */
-public class IfTests extends RubyTests {
-
-    @Test
-    public void testImmediateIf() {
-        assertPrints("1\n", "if true; puts 1 end");
-        assertPrints("", "if false; puts 1 end");
-    }
-
-    @Test
-    public void testImmediateTrailingIf() {
-        assertPrints("1\n", "puts 1 if true");
-        assertPrints("", "puts 1 if false");
-    }
-
-    @Test
-    public void testImmediateIfElse() {
-        assertPrints("1\n", "if true; puts 1 else puts 2 end");
-        assertPrints("2\n", "if false; puts 1 else puts 2 end");
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/language/InterpolatedStringTests.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,32 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.test.language;
-
-import org.junit.*;
-
-import com.oracle.truffle.ruby.test.*;
-
-/**
- * Test interpolated strings - that is string literals with #{...} sections in them. Within those
- * you can have arbitrary Ruby expressions.
- */
-public class InterpolatedStringTests extends RubyTests {
-
-    @Test
-    public void testBasic() {
-        assertPrints("123\n", "puts \"1#{2}3\"");
-    }
-
-    @Test
-    public void testMethodCall() {
-        assertPrints("123\n", "def foo; 2; end; puts \"1#{foo}3\"");
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/language/LocalTests.java	Sun Feb 23 17:00:35 2014 -0800
+++ /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. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.test.language;
-
-import org.junit.*;
-
-import com.oracle.truffle.ruby.test.*;
-
-/**
- * Test local variables.
- */
-public class LocalTests extends RubyTests {
-
-    @Test
-    public void testAssignmentTopLevel() {
-        assertPrints("1\n", "x = 1; puts x");
-    }
-
-    @Test
-    public void testAssignmentWithinMethod() {
-        assertPrints("1\n", "def foo; x = 1; puts x; end; foo");
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/language/MethodTests.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,251 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.test.language;
-
-import org.junit.*;
-
-import com.oracle.truffle.ruby.runtime.control.*;
-import com.oracle.truffle.ruby.test.*;
-
-/**
- * Test method definitions and calls.
- */
-public class MethodTests extends RubyTests {
-
-    @Test
-    public void testDefineCallNoArguments() {
-        assertPrints("1\n", "def foo; puts 1; end; foo()");
-        assertPrints("1\n", "def foo; puts 1; end; foo");
-    }
-
-    @Test
-    public void testDefineCallOnePreArgument() {
-        assertPrints("1\n", "def foo(a); puts a; end; foo(1)");
-        assertPrints("1\n", "def foo(a); puts a; end; foo 1");
-    }
-
-    @Test
-    public void testDefineCallTwoPreArguments() {
-        assertPrints("1\n2\n", "def foo(a, b); puts a; puts b; end; foo(1, 2)");
-        assertPrints("1\n2\n", "def foo(a, b); puts a; puts b; end; foo 1, 2");
-    }
-
-    @Test
-    public void testSingleReturn() {
-        assertPrints("1\n", "def foo; return 1; end; puts foo");
-        assertPrints("1\n", "def foo(n); return n; end; puts foo(1)");
-    }
-
-    @Test
-    public void testImplicitReturn() {
-        assertPrints("1\n", "def foo; 1; end; puts foo");
-        assertPrints("3\n", "def foo; 1+2; end; puts foo");
-        assertPrints("14\n", "def foo; x=14; end; puts foo");
-    }
-
-    @Test
-    public void testNestedCall() {
-        assertPrints("1\n", "def foo(n); return n; end; def bar(n); return foo(n); end; puts bar(1)");
-        assertPrints("1\n1\n1\n", "def foo(n); puts n; return n; end; def bar(n); puts n; return foo(n); end; puts bar(1)");
-        assertPrints("1\n1\n", "def foo(a, b); puts a; puts b; end; def bar(n); foo(n, n); end; bar(1)");
-    }
-
-    @Test
-    public void testNestedOperatorCall() {
-        assertPrints("3\n", "def foo(a, b); puts a + b; end; foo(1, 2)");
-    }
-
-    /**
-     * Tests that arguments are evaluated before method dispatch takes place, by putting an action
-     * in one of the arguments that modifies the method that we should find in dispatch.
-     */
-    @Test
-    public void testArgumentsExecutedBeforeDispatch() {
-        /*
-         * We have to use Object#send instead of calling define_method directly because that method
-         * is private.
-         */
-
-        assertPrints("12\n", "def foo\n" + //
-                        "  Fixnum.send(:define_method, :+) do |other|\n" + //
-                        "    self - other\n" + //
-                        "   end \n" + //
-                        "  2\n" + //
-                        "end\n" + //
-                        "puts 14 + foo");
-    }
-
-    @Test(expected = RaiseException.class)
-    public void testTooFewArguments1() {
-        assertPrints("", "def foo(a); end; foo()");
-    }
-
-    @Test(expected = RaiseException.class)
-    public void testTooFewArguments2() {
-        assertPrints("", "def foo(a, b); end; foo(1)");
-    }
-
-    @Test(expected = RaiseException.class)
-    public void testTooFewArguments3() {
-        assertPrints("", "def foo(a, b, c); end; foo(1, 2)");
-    }
-
-    @Test(expected = RaiseException.class)
-    public void testTooManyArguments1() {
-        assertPrints("", "def foo(); end; foo(1)");
-    }
-
-    @Test(expected = RaiseException.class)
-    public void testTooManyArguments2() {
-        assertPrints("", "def foo(a); end; foo(1, 2)");
-    }
-
-    @Test(expected = RaiseException.class)
-    public void testTooManyArguments3() {
-        assertPrints("", "def foo(a, b); end; foo(1, 2, 3)");
-    }
-
-    @Test
-    public void testPolymophicMethod() {
-        assertPrints("A\nB\n", "class A\n" + //
-                        "    def foo\n" + //
-                        "        puts \"A\"\n" + //
-                        "    end\n" + //
-                        "end\n" + //
-                        "\n" + //
-                        "class B\n" + //
-                        "    def foo\n" + //
-                        "        puts \"B\"\n" + //
-                        "    end\n" + //
-                        "end\n" + //
-                        "\n" + //
-                        "def bar(x)\n" + //
-                        "    x.foo\n" + //
-                        "end\n" + //
-                        "\n" + //
-                        "a = A.new\n" + //
-                        "b = B.new\n" + //
-                        "\n" + //
-                        "bar(a)\n" + //
-                        "bar(b)\n");
-    }
-
-    @Test
-    public void testOneDefaultValue() {
-        assertPrints("1\n2\n", "def foo(a=1); puts a; end; foo; foo(2)");
-    }
-
-    @Test
-    public void testTwoDefaultValues() {
-        assertPrints("1\n2\n3\n2\n3\n4\n", "def foo(a=1,b=2); puts a; puts b; end; foo; foo(3); foo(3, 4)");
-    }
-
-    @Test
-    public void testOneDefaultValueAfterNonDefault() {
-        assertPrints("2\n1\n2\n3\n", "def foo(a, b=1); puts a; puts b; end; foo(2); foo(2, 3)");
-    }
-
-    @Test
-    public void testOneDefaultValueBeforeNonDefault() {
-        assertPrints("1\n2\n2\n3\n", "def foo(a=1, b); puts a; puts b; end; foo(2); foo(2, 3)");
-    }
-
-    @Test
-    public void testBlockArgument() {
-        assertPrints("1\n2\n3\n", "def foo(&block); block.call(14); end; puts 1; foo { |n| puts 2 }; puts 3");
-    }
-
-    @Test
-    public void testBlockArgumentWithOthers() {
-        assertPrints("1\n2\n3\n4\n5\n", "def foo(a, b, &block); puts a; block.call(14); puts b; end; puts 1; foo(2, 4) { |n| puts 3 }; puts 5");
-    }
-
-    @Test
-    public void testBlockPass() {
-        assertPrints("1\n2\n3\n", "def bar; yield; end; def foo(&block); bar(&block); end; puts 1; foo { puts 2 }; puts 3");
-    }
-
-    @Test
-    public void testBlockPassWithOthers() {
-        assertPrints("1\n2\n3\n4\n5\n", "def bar(a, b); puts a; yield; puts b; end; def foo(a, b, &block); bar(a, b, &block); end; puts 1; foo(2, 4) { puts 3 }; puts 5");
-    }
-
-    @Test
-    public void testSplatWhole() {
-        assertPrints("1\n2\n3\n", "def foo(a, b, c); puts a; puts b; puts c; end; d = [1, 2, 3]; foo(*d)");
-    }
-
-    @Test
-    public void testSplatSome() {
-        assertPrints("1\n2\n3\n", "def foo(a, b, c); puts a; puts b; puts c; end; d = [2, 3]; foo(1, *d)");
-    }
-
-    @Test
-    public void testSplatParam() {
-        assertPrints("[1, 2, 3]\n", "def foo(*bar); puts bar.to_s; end; foo(1, 2, 3)");
-    }
-
-    @Test
-    public void testSplatParamWithOther() {
-        assertPrints("1\n[2]\n", "def foo(a, *b); puts a.to_s; puts b.to_s; end; foo(1, 2)");
-    }
-
-    @Test
-    public void testSplatParamWithBlockPass() {
-        assertPrints("[1, 2, 3]\n", "def foo(*bar, &block); block.call(bar); end; foo(1, 2, 3) { |x| puts x.to_s }");
-    }
-
-    @Test
-    public void testSingletonMethod() {
-        assertPrints("1\n", "foo = Object.new; def foo.bar; puts 1; end; foo.bar");
-    }
-
-    @Test
-    public void testAlias() {
-        assertPrints("1\n", "def foo; puts 1; end; alias bar foo; bar");
-        assertPrints("1\n", "class Foo; def foo; puts 1; end; alias bar foo; end; Foo.new.bar");
-    }
-
-    @Test
-    public void testAliasMethod() {
-        assertPrints("1\n", "class Foo; def foo; puts 1; end; alias_method :bar, :foo; end; Foo.new.bar");
-    }
-
-    @Test
-    public void testSymbolAsBlock() {
-        assertPrints("6\n", "puts [1, 2, 3].inject(&:+)");
-    }
-
-    @Test
-    public void testSuper() {
-        assertPrints("1\n2\n3\n", "class Foo; def foo; puts 2; end; end; class Bar < Foo; def foo; puts 1; super; puts 3; end; end; Bar.new.foo");
-    }
-
-    @Test
-    public void testSuperWithArgs() {
-        assertPrints("1\n2\n3\n", "class Foo; def foo(n); puts n; end; end; class Bar < Foo; def foo(n); puts 1; super(n); puts 3; end; end; Bar.new.foo(2)");
-    }
-
-    @Test
-    public void testPushSplat() {
-        assertPrints("[1, 0, 4]\n", "a = [1, 2, 3, 4]; b = [1, 2]; a[*b] = 0; puts a.to_s");
-    }
-
-    @Test
-    public void testBlocksPassedIntoBlocks() {
-        assertPrints("14\n", "def foo; 1.times do; yield; end; end; foo do; puts 14; end");
-    }
-
-    @Test
-    public void testBlocksNotPassedIntoFullMethods() {
-        assertPrints("no block\n", "def foo(&block); if block; puts 'block'; else; puts 'no block'; end; end; def bar; foo; end; bar do; end");
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/language/ModuleTests.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,56 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.test.language;
-
-import org.junit.*;
-
-import com.oracle.truffle.ruby.test.*;
-
-/**
- * Test {@code module} expressions.
- */
-public class ModuleTests extends RubyTests {
-
-    @Test
-    public void testDefine() {
-        assertPrints("Foo\n", "module Foo; end; puts Foo");
-    }
-
-    @Test
-    public void testWithConstantDefinition() {
-        assertPrints("14\n", "module Foo; FOO=14; end; puts Foo::FOO");
-    }
-
-    @Test
-    public void testWithConstantDefinitionAndAccessInDeclaration() {
-        assertPrints("14\n", "module Foo; FOO=14; puts FOO; end");
-    }
-
-    @Test
-    public void testCanAccessObjectConstantsInModuleDefinition() {
-        assertPrints("", "class Foo; end; module Bar; foo = Foo.new; end");
-    }
-
-    @Test
-    public void testInclude() {
-        assertPrints("14\n", "module Foo; FOO=14; end; module Bar; include Foo; end; puts Bar::FOO");
-    }
-
-    @Test
-    public void testModuleFunction() {
-        assertPrints("1\n", "module Foo; def bar; puts 1; end; module_function :bar; end; Foo::bar");
-    }
-
-    @Test
-    public void testDistinctModule() {
-        assertPrints("true\n", "module A; module X; end; end; module B; module X; end; end; puts A::X.object_id != B::X.object_id");
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/language/MultipleAssignmentTests.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,65 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.test.language;
-
-import org.junit.*;
-
-import com.oracle.truffle.ruby.test.*;
-
-/**
- * Test multiple assignment, which is sort of like pattern matching for arrays. The arrays can be
- * implicit on the RHS.
- */
-public class MultipleAssignmentTests extends RubyTests {
-
-    @Test
-    public void testToLocal() {
-        assertPrints("1\n2\n", "x, y = [1, 2]; puts x, y");
-        assertPrints("1\n2\n", "x, y = 1, 2; puts x, y");
-        assertPrints("1\n2\n", "x = [1, 2]; y, z = x; puts y, z");
-    }
-
-    @Test
-    public void testToArrayIndex() {
-        assertPrints("1\n2\n", "x = []; x[0], x[1] = 1, 2; puts x");
-    }
-
-    @Test
-    public void testSwap() {
-        assertPrints("2\n1\n", "a = [1]; b = [2]; a[0], b[0] = b[0], a[0]; puts a, b");
-    }
-
-    @Test
-    public void testProducesArray() {
-        assertPrints("1\n2\n", "puts((a, b = 1, 2))");
-    }
-
-    @Test
-    public void testWithSplat() {
-        assertPrints("1\n[2, 3]\n", "a, *b = [1, 2, 3]; puts a; puts b.to_s");
-    }
-
-    @Test
-    public void testWithSplatEmpty() {
-        assertPrints("1\n[]\n", "a, *b = [1]; puts a.to_s; puts b.to_s");
-    }
-
-    @Test
-    public void testWithSingleValueRHS() {
-        assertPrints("14\n\n\n", "a, b, c = 14; puts a; puts b; puts c");
-        assertPrints("\n\n\n", "a, b, c = nil; puts a; puts b; puts c");
-    }
-
-    @Test
-    public void testWithSingleSplatLHSAndSingleValueRHS() {
-        assertPrints("[14]\n", "a = *14; puts a.to_s");
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/language/OrTests.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.test.language;
-
-import org.junit.*;
-
-import com.oracle.truffle.ruby.test.*;
-
-/**
- * Test {@code or} expressions, which unusually for Ruby are not methods. This is because with
- * Ruby's eager evaluation there would be no way to implement the short circuit semantics.
- */
-public class OrTests extends RubyTests {
-
-    @Test
-    public void testImmediate() {
-        assertPrints("false\n", "puts false || false");
-        assertPrints("true\n", "puts true || false");
-        assertPrints("true\n", "puts false || true");
-        assertPrints("true\n", "puts true || true");
-        assertPrints("false\n", "puts (false or false)");
-        assertPrints("true\n", "puts (true or false)");
-        assertPrints("true\n", "puts (false or true)");
-        assertPrints("true\n", "puts (true or true)");
-    }
-
-    @Test
-    public void testShortCircuits() {
-        assertPrints("false\nfalse\nfalse\n", "x = y = false; puts (x = false) || (y = false); puts x, y");
-        assertPrints("true\ntrue\nfalse\n", "x = y = false; puts (x = true) || (y = false); puts x, y");
-        assertPrints("true\nfalse\ntrue\n", "x = y = false; puts (x = false) || (y = true); puts x, y");
-        assertPrints("true\ntrue\nfalse\n", "x = y = false; puts (x = true) || (y = true); puts x, y");
-        assertPrints("false\nfalse\nfalse\n", "x = y = false; puts ((x = false) or (y = false)); puts x, y");
-        assertPrints("true\ntrue\nfalse\n", "x = y = false; puts ((x = true) or (y = false)); puts x, y");
-        assertPrints("true\nfalse\ntrue\n", "x = y = false; puts ((x = false) or (y = true)); puts x, y");
-        assertPrints("true\ntrue\nfalse\n", "x = y = false; puts ((x = true) or (y = true)); puts x, y");
-    }
-
-    @Test
-    public void testOrAssign() {
-        assertPrints("true\n", "def foo; puts 1; false; end; x = true; x ||= foo; puts x");
-        assertPrints("1\nfalse\n", "def foo; puts 1; false; end; x = false; x ||= foo; puts x");
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/language/PolymorphismTests.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,35 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.test.language;
-
-import org.junit.*;
-
-import com.oracle.truffle.ruby.test.*;
-
-/**
- * Test characteristics of polymorphism.
- */
-public class PolymorphismTests extends RubyTests {
-
-    /**
-     * Test that a polymorphic method that will specialize to double will then not treat integers as
-     * doubles.
-     */
-    @Test
-    public void testSimpleOperatorRedefinition() {
-        assertPrints("16.759999999999998\n16\n", //
-                        "def add(x, y)\n" + //
-                                        "    x + y\n" + //
-                                        "end\n" + //
-                                        "puts add(14.5, 2.26)\n" + //
-                                        "puts add(14, 2)\n");
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/language/RaiseRescueTests.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,67 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.test.language;
-
-import org.junit.*;
-
-import com.oracle.truffle.ruby.runtime.control.*;
-import com.oracle.truffle.ruby.test.*;
-
-/**
- * Test {@code raise} and {@code rescue}.
- */
-public class RaiseRescueTests extends RubyTests {
-
-    @Test(expected = RaiseException.class)
-    public void testZeroDivisionError() {
-        assertPrints("", "1/0");
-    }
-
-    @Test
-    public void testBeginRescue() {
-        assertPrints("", "begin; rescue; end");
-        assertPrints("", "begin; rescue => e; end");
-        assertPrints("", "begin; rescue ZeroDivisionError => e; end");
-        assertPrints("", "begin; rescue; ensure; end");
-        assertPrints("", "begin; rescue => e; ensure; end");
-        assertPrints("", "begin; rescue ZeroDivisionError => e; ensure; end");
-        assertPrints("", "begin; rescue; else; end");
-        assertPrints("", "begin; rescue => e; else; end");
-        assertPrints("", "begin; rescue ZeroDivisionError => e; else; end");
-        assertPrints("", "def foo; rescue; end");
-        assertPrints("", "def foo; rescue => e; end");
-        assertPrints("", "def foo; rescue ZeroDivisionError => e; end");
-        assertPrints("", "def foo; rescue; ensure; end");
-        assertPrints("", "def foo; rescue => e; ensure; end");
-        assertPrints("", "def foo; rescue ZeroDivisionError => e; ensure; end");
-        assertPrints("", "def foo; rescue; else; end");
-        assertPrints("", "def foo; rescue => e; else; end");
-        assertPrints("", "def foo; rescue ZeroDivisionError => e; else; end");
-    }
-
-    @Test
-    public void testRescueZeroDivisionError() {
-        assertPrints("divided by 0\n3\n4\n", "begin; 1/0; puts 1; rescue => e; puts e; else puts 2; ensure puts 3; end; puts 4");
-        assertPrints("divided by 0\n3\n4\n", "begin; 1/0; puts 1; rescue ZeroDivisionError => e; puts e; else puts 2; ensure puts 3; end; puts 4");
-        assertPrints("1\n2\n3\n4\n", "begin; 1/1; puts 1; rescue ZeroDivisionError => e; puts e; else puts 2; ensure puts 3; end; puts 4");
-        assertPrints("1\n2\n3\n4\n", "begin; 1/1; puts 1; rescue ZeroDivisionError => e; puts e; rescue NameError => e; puts e; else puts 2; ensure puts 3; end; puts 4");
-    }
-
-    @Test
-    public void testSplatRescue() {
-        assertPrints("2\n", "ERRORS=[ZeroDivisionError]; begin; 1/0; puts 1; rescue *ERRORS; puts 2; end");
-    }
-
-    @Test
-    public void testRetry() {
-        assertPrints("1\n3\n1\n2\n5\n", "x=0; begin; puts 1; 1/x; puts 2; rescue ZeroDivisionError; puts 3; x=1; retry; puts 4; end; puts 5");
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/language/RedefinitionTests.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,63 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.test.language;
-
-import org.junit.*;
-
-import com.oracle.truffle.ruby.test.*;
-
-/**
- * Test that methods can be redefined.
- */
-public class RedefinitionTests extends RubyTests {
-
-    /**
-     * Test that a method on Fixnum can be redefined and that we will use the new definition. The
-     * call that expects to find the redefinition needs to have already been specialized, which is
-     * why do it through a method.
-     */
-    @Test
-    public void testSimpleOperatorRedefinition() {
-        assertPrints("3\n-1\n", //
-                        "def add(x, y)\n" + //
-                                        "    x + y\n" + //
-                                        "end\n" + //
-                                        "puts add(1, 2)\n" + //
-                                        "class Fixnum\n" + //
-                                        "    def +(other)\n" + //
-                                        "        self - other\n" + //
-                                        "    end\n" + //
-                                        "end\n" + //
-                                        "puts add(1, 2)\n");
-    }
-
-    /**
-     * This is quite a subtle test. We redefine Float#+. We have a method which calls +. It is
-     * initially specialized to Fixnum, but then used with Float. The tricky bit is that Float has
-     * not been redefined since the operator has been specialized. The operator thinks it is up to
-     * date. When we emit a + node, we need to check if any class that that node could specialize to
-     * has been redefined.
-     */
-    @Test
-    public void testSpecialisationConsidersRedefinitionInOtherClasses() {
-        assertPrints("16\n12.25\n", //
-                        "def add(a, b)\n" + //
-                                        "    a + b\n" + //
-                                        "end\n" + //
-                                        "class Float\n" + //
-                                        "    def +(other)\n" + //
-                                        "        self - other\n" + //
-                                        "    end\n" + //
-                                        "end\n" + //
-                                        "puts add(14, 2)\n" + //
-                                        "puts add(14.5, 2.25)");
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/language/ShortcutTests.java	Sun Feb 23 17:00:35 2014 -0800
+++ /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. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.test.language;
-
-import org.junit.*;
-
-import com.oracle.truffle.ruby.test.*;
-
-/**
- * Test shortcut expressions (syntactic sugar) such as {@code +=} and {@code |=}.
- */
-public class ShortcutTests extends RubyTests {
-
-    @Test
-    public void testShortcutAddAssign() {
-        assertPrints("2\n", "x = 1; x += 1; puts x");
-    }
-
-    @Test
-    public void testShortcutSubAssign() {
-        assertPrints("0\n", "x = 1; x -= 1; puts x");
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/language/SpecialVariableTests.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.test.language;
-
-import org.junit.*;
-
-import com.oracle.truffle.ruby.test.*;
-
-/**
- * Test variables with special semantics, such as the 'global variables', {@code $_}, {@code $~}
- * etc.
- */
-public class SpecialVariableTests extends RubyTests {
-
-    @Test
-    public void testGetsResult() {
-        assertPrintsWithInput("test\n", "gets; puts $_", "test\n");
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/language/UntilTests.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.test.language;
-
-import org.junit.*;
-
-import com.oracle.truffle.ruby.test.*;
-
-/**
- * Test {@code until} expressions.
- */
-public class UntilTests extends RubyTests {
-
-    @Test
-    public void testSimpleWhile() {
-        assertPrints("0\n", "x = 10; until x == 0; x -= 1; end; puts x");
-        assertPrints("10\n", "x = 0; until x == 10; x += 1; end; puts x");
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/language/WhileTests.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.test.language;
-
-import org.junit.*;
-
-import com.oracle.truffle.ruby.test.*;
-
-/**
- * Test {@code while} expressions.
- */
-public class WhileTests extends RubyTests {
-
-    @Test
-    public void testSimpleWhile() {
-        assertPrints("0\n", "x = 10; while x > 0; x -= 1; end; puts x");
-        assertPrints("10\n", "x = 0; while x < 10; x += 1; end; puts x");
-    }
-
-    @Test
-    public void testBreak() {
-        assertPrints("1\n", "x = 0; while x < 10; x += 1; break; end; puts x");
-    }
-
-    @Test
-    public void testNext() {
-        assertPrints("10\n", "x = 0; while x < 10; x += 1; next; end; puts x");
-    }
-
-}
--- a/graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/runtime/ObjectLayoutTests.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,277 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
- * code is released under a tri EPL/GPL/LGPL license. You can use it,
- * redistribute it and/or modify it under the terms of the:
- *
- * Eclipse Public License version 1.0
- * GNU General Public License version 2
- * GNU Lesser General Public License version 2.1
- */
-package com.oracle.truffle.ruby.test.runtime;
-
-import org.junit.*;
-
-import com.oracle.truffle.ruby.runtime.*;
-import com.oracle.truffle.ruby.runtime.core.*;
-import com.oracle.truffle.ruby.runtime.objects.*;
-
-import static org.junit.Assert.*;
-
-/**
- * Test the object layout classes.
- */
-public class ObjectLayoutTests {
-
-    @Test
-    public void testNewInstanceVariable() {
-        final RubyContext context = new RubyContext(null);
-
-        // Create a class and an instance
-
-        final RubyClass classA = new RubyClass(context, null, null, null, "A");
-        final ObjectLayout layoutClassA = classA.getObjectLayoutForInstances();
-
-        final RubyBasicObject objectA = new RubyBasicObject(classA);
-        final ObjectLayout layoutObjectA = objectA.getObjectLayout();
-
-        // Add an instance variable to the instance
-
-        objectA.setInstanceVariable("foo", 14);
-
-        // That should have changed the layout of the class
-
-        assertNotSame(layoutClassA, classA.getObjectLayoutForInstances());
-
-        // If we notify the object, it should also change the layout of that
-
-        objectA.updateLayout();
-        assertNotSame(layoutObjectA, objectA.getObjectLayout());
-
-        // We should be able to find that instance variable as a storage location in the class
-
-        assertNotNull(classA.getObjectLayoutForInstances().findStorageLocation("foo"));
-
-        // We should be able to read that value back out
-
-        assertEquals(14, objectA.getInstanceVariable("foo"));
-    }
-
-    @Test
-    public void testOverflowPrimitives() {
-        final RubyContext context = new RubyContext(null);
-
-        // Create a class and an instance
-
-        final RubyClass classA = new RubyClass(context, null, null, null, "A");
-        final RubyBasicObject objectA = new RubyBasicObject(classA);
-
-        // Add many more Fixnums that we have space for primitives
-
-        final int count = 100;
-
-        for (int n = 0; n < count; n++) {
-            objectA.setInstanceVariable("foo" + n, n);
-        }
-
-        // We should be able to read them back out
-
-        for (int n = 0; n < count; n++) {
-            assertEquals(n, objectA.getInstanceVariable("foo" + n));
-        }
-    }
-
-    @Test
-    public void testGeneralisation() {
-        final RubyContext context = new RubyContext(null);
-
-        // Create a class and two instances
-
-        final RubyClass classA = new RubyClass(context, null, null, null, "A");
-        final RubyBasicObject object1 = new RubyBasicObject(classA);
-        final RubyBasicObject object2 = new RubyBasicObject(classA);
-
-        // Set an instance variable to be a Fixnum in object 1
-
-        object1.setInstanceVariable("foo", 14);
-
-        // We should be able to read that instance variable back, and it should still be a Fixnum
-
-        assertEquals(14, object1.getInstanceVariable("foo"));
-        assertSame(Integer.class, object1.getInstanceVariable("foo").getClass());
-
-        // The underlying instance store should be Fixnum
-
-        assertSame(FixnumStorageLocation.class, object1.getObjectLayout().findStorageLocation("foo").getClass());
-
-        /*
-         * The same instance variable in object 2 should be Nil. Note that this requires that we
-         * realise that even though the instance variable is known about in the layout of object 2,
-         * and we are using a primitive int to hold it, that it hasn't been set and is actually Nil.
-         * We don't want it to appear as 0.
-         */
-
-        assertSame(NilPlaceholder.INSTANCE, object2.getInstanceVariable("foo"));
-
-        /*
-         * We should be able to set the same instance variable in object 2 to also be a Fixnum
-         * without changing the layout.
-         */
-
-        final ObjectLayout objectLayout2 = object2.getObjectLayout();
-        object2.setInstanceVariable("foo", 2);
-        assertEquals(2, object2.getInstanceVariable("foo"));
-        assertSame(Integer.class, object2.getInstanceVariable("foo").getClass());
-        assertSame(objectLayout2, object2.getObjectLayout());
-
-        // Set the instance variable in object 2 to be a Float
-
-        object2.setInstanceVariable("foo", 2.25);
-
-        // We should be able to read that instance variable back, and it should still be a Fixnum
-
-        assertEquals(2.25, object2.getInstanceVariable("foo"));
-        assertSame(Double.class, object2.getInstanceVariable("foo").getClass());
-
-        // Object 1 should give still think the instance variable is a Fixnum
-
-        assertEquals(14, object1.getInstanceVariable("foo"));
-        assertSame(Integer.class, object1.getInstanceVariable("foo").getClass());
-
-        // The underlying instance store in both objects should now be Object
-
-        assertSame(ObjectStorageLocation.class, object1.getObjectLayout().findStorageLocation("foo").getClass());
-        assertSame(ObjectStorageLocation.class, object2.getObjectLayout().findStorageLocation("foo").getClass());
-
-    }
-
-    @Test
-    public void testSubclasses() {
-        final RubyContext context = new RubyContext(null);
-
-        // Create two classes, A, and a subclass, B, and an instance of each
-
-        final RubyClass classA = new RubyClass(context, null, null, null, "A");
-        final RubyClass classB = new RubyClass(context, null, null, classA, "B");
-
-        ObjectLayout layoutClassA = classA.getObjectLayoutForInstances();
-        ObjectLayout layoutClassB = classA.getObjectLayoutForInstances();
-
-        final RubyBasicObject objectA = new RubyBasicObject(classA);
-        final RubyBasicObject objectB = new RubyBasicObject(classB);
-
-        ObjectLayout layoutObjectA = objectA.getObjectLayout();
-        ObjectLayout layoutObjectB = objectB.getObjectLayout();
-
-        // Add an instance variable to the instance of A
-
-        objectA.setInstanceVariable("foo", 14);
-
-        // That should have changed the layout of both classes
-
-        assertNotSame(layoutClassA, classA.getObjectLayoutForInstances());
-        assertNotSame(layoutClassB, classB.getObjectLayoutForInstances());
-
-        layoutClassA = classA.getObjectLayoutForInstances();
-        layoutClassB = classA.getObjectLayoutForInstances();
-
-        // If we notify the objects, both of them should have changed layouts
-
-        objectA.updateLayout();
-        objectB.updateLayout();
-        assertNotSame(layoutObjectA, objectA.getObjectLayout());
-        assertNotSame(layoutObjectB, objectB.getObjectLayout());
-
-        layoutObjectA = objectA.getObjectLayout();
-        layoutObjectB = objectB.getObjectLayout();
-
-        // We should be able to find that instance variable as a storage location in both classes
-
-        assertNotNull(classA.getObjectLayoutForInstances().findStorageLocation("foo"));
-        assertNotNull(classB.getObjectLayoutForInstances().findStorageLocation("foo"));
-
-        // We should be able to read that value back out
-
-        assertEquals(14, objectA.getInstanceVariable("foo"));
-
-        // Add an instance variable to the instance of B
-
-        objectB.setInstanceVariable("bar", 2);
-
-        // This should not have changed the layout of A or the instance of A
-
-        assertSame(layoutClassA, classA.getObjectLayoutForInstances());
-        assertSame(layoutObjectA, objectA.getObjectLayout());
-
-        // But the layout of B and the instance of B should have changed
-
-        assertNotSame(layoutClassB, classB.getObjectLayoutForInstances());
-
-        objectB.updateLayout();
-        assertNotSame(layoutObjectB, objectB.getObjectLayout());
-
-        // We should be able to find the new instance variable in the instance of B but not A
-
-        assertNull(classA.getObjectLayoutForInstances().findStorageLocation("bar"));
-        assertNotNull(classB.getObjectLayoutForInstances().findStorageLocation("bar"));
-
-        // We should be able to read that value back out
-
-        assertEquals(2, objectB.getInstanceVariable("bar"));
-    }
-
-    @Test
-    public void testPerObjectInstanceVariables() {
-        final RubyContext context = new RubyContext(null);
-
-        // Create a class and an instance
-
-        final RubyClass classA = new RubyClass(context, context.getCoreLibrary().getClassClass(), null, null, "A");
-        final RubyBasicObject objectA = new RubyBasicObject(classA);
-
-        ObjectLayout layoutClassA = classA.getObjectLayoutForInstances();
-        ObjectLayout layoutObjectA = objectA.getObjectLayout();
-
-        // Add an instance variable to the instance of A
-
-        objectA.setInstanceVariable("foo", 2);
-
-        // That should have changed the layout of the class and the object
-
-        assertNotSame(layoutClassA, classA.getObjectLayoutForInstances());
-        assertNotSame(layoutObjectA, objectA.getObjectLayout());
-        layoutClassA = classA.getObjectLayoutForInstances();
-        layoutObjectA = classA.getObjectLayout();
-
-        // We should be able to read the value back out
-
-        assertEquals(2, objectA.getInstanceVariable("foo"));
-
-        /*
-         * Switch object A to having a private object layout, as would be done by calls such as
-         * instance_variable_set.
-         */
-
-        objectA.switchToPrivateLayout();
-
-        // Set an instance variable on object A
-
-        objectA.setInstanceVariable("bar", 14);
-
-        // The layout of object A, however, should have changed
-
-        // CS: it hasn't changed because it's still null
-        // assertNotSame(layoutObjectA, objectA.getObjectLayout());
-
-        // We should be able to read the value back out
-
-        assertEquals(14, objectA.getInstanceVariable("bar"));
-
-        /*
-         * We should also be able to read the first variable back out, even though we've switched to
-         * private layout since then.
-         */
-
-        assertEquals(2, objectA.getInstanceVariable("foo"));
-    }
-
-}
--- a/graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/AbstractTest.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,63 +0,0 @@
-/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.sl.test;
-
-import java.io.*;
-
-import org.junit.*;
-
-import com.oracle.truffle.sl.*;
-
-public class AbstractTest {
-
-    public static final int REPEATS = 10;
-    private static final String NEWLINE = System.getProperty("line.separator");
-
-    private static String concat(String[] string) {
-        StringBuilder result = new StringBuilder();
-        for (String s : string) {
-            result.append(s).append(NEWLINE);
-        }
-        return result.toString();
-    }
-
-    private static String repeat(String s, int count) {
-        StringBuilder result = new StringBuilder(s.length() * count);
-        for (int i = 0; i < count; i++) {
-            result.append(s);
-        }
-        return result.toString();
-    }
-
-    protected static void executeSL(String[] input, String[] expectedOutput, boolean useConsole) {
-        ByteArrayOutputStream out = new ByteArrayOutputStream();
-        PrintStream printer = new PrintStream(useConsole ? new SplitOutputStream(out, System.err) : out);
-        PrintStream origErr = System.err;
-        System.setErr(printer);
-
-        SimpleLanguage.run("(test)", concat(input), printer, REPEATS, false);
-
-        System.setErr(origErr);
-        Assert.assertEquals(repeat(concat(expectedOutput), REPEATS), new String(out.toByteArray()));
-    }
-}
--- a/graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/AddTest.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,56 +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.truffle.sl.test;
-
-import org.junit.*;
-
-// @formatter:off
-public class AddTest extends AbstractTest {
-
-    private static String[] INPUT = new String[] {
-        "function main {  ",
-        "  print(3 + 4);  ",
-        "  print(3 + \"4\");  ",
-        "  print(\"3\" + 4);  ",
-        "  print(\"3\" + \"4\");  ",
-        "  print(3 + 4000000000000);  ",
-        "  print(3000000000000 + 4);  ",
-        "  print(3000000000000 + 4000000000000);  ",
-        "}  ",
-    };
-
-    private static String[] OUTPUT = new String[] {
-        "7",
-        "34",
-        "34",
-        "34",
-        "4000000000003",
-        "3000000000004",
-        "7000000000000",
-    };
-
-    @Test
-    public void test() {
-        executeSL(INPUT, OUTPUT, false);
-    }
-}
--- a/graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/BuiltinsTest.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,45 +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.truffle.sl.test;
-
-import org.junit.*;
-
-// @formatter:off
-public class BuiltinsTest extends AbstractTest {
-
-    private static String[] INPUT = new String[] {
-        "function main {  ",
-        "  print(\"Hello World!\");  ",
-        "  time();  ",
-        "}  ",
-    };
-
-    private static String[] OUTPUT = new String[] {
-        "Hello World!",
-    };
-
-    @Test
-    public void test() {
-        executeSL(INPUT, OUTPUT, false);
-    }
-}
--- a/graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/CallTest.java	Sun Feb 23 17:00:35 2014 -0800
+++ /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.truffle.sl.test;
-
-import org.junit.*;
-
-// @formatter:off
-public class CallTest extends AbstractTest {
-
-    private static String[] INPUT = new String[] {
-        "function ret(a) { return a; } ",
-        "function dub(a) { return a * 2; } ",
-        "function inc(a) { return a + 1; } ",
-        "function dec(a) { return a - 1; } ",
-        "function call(f, v) { return f(v); } ",
-        "function main {  ",
-        "  print(ret(42));",
-        "  print(dub(21));",
-        "  print(inc(41));",
-        "  print(dec(43));",
-        "  print(call(ret, 42));",
-        "  print(call(dub, 21));",
-        "  print(call(inc, 41));",
-        "  print(call(dec, 43));",
-        "}  ",
-    };
-
-    private static String[] OUTPUT = new String[] {
-        "42",
-        "42",
-        "42",
-        "42",
-        "42",
-        "42",
-        "42",
-        "42",
-    };
-
-    @Test
-    public void test() {
-        executeSL(INPUT, OUTPUT, false);
-    }
-}
--- a/graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/ComparisonTest.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,56 +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.truffle.sl.test;
-
-import org.junit.*;
-
-// @formatter:off
-public class ComparisonTest extends AbstractTest {
-
-    private static String[] INPUT = new String[] {
-        "function main {  ",
-        "  print(4 < 20);  ",
-        "  print(4 < \"20\");  ",
-        "  print(\"4\" < 20);  ",
-        "  print(\"4\" < \"20\");  ",
-        "  print(4 < 20000000000000);  ",
-        "  print(4000000000000 < 20);  ",
-        "  print(4000000000000 < 20000000000000);  ",
-        "}  ",
-    };
-
-    private static String[] OUTPUT = new String[] {
-        "true",
-        "false",
-        "false",
-        "false",
-        "true",
-        "false",
-        "true",
-    };
-
-    @Test
-    public void test() {
-        executeSL(INPUT, OUTPUT, false);
-    }
-}
--- a/graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/DivTest.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,50 +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.truffle.sl.test;
-
-import org.junit.*;
-
-// @formatter:off
-public class DivTest extends AbstractTest {
-
-    private static String[] INPUT = new String[] {
-        "function main {  ",
-        "  print(4 / 2);  ",
-        "  print(4 / 4000000000000);  ",
-        "  print(3000000000000 / 3);  ",
-        "  print(3000000000000 / 3000000000000);  ",
-        "}  ",
-    };
-
-    private static String[] OUTPUT = new String[] {
-        "2",
-        "0",
-        "1000000000000",
-        "1",
-    };
-
-    @Test
-    public void test() {
-        executeSL(INPUT, OUTPUT, false);
-    }
-}
--- a/graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/FibonacciTest.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,89 +0,0 @@
-/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.sl.test;
-
-import javax.script.*;
-
-import org.junit.*;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.sl.*;
-import com.oracle.truffle.sl.runtime.*;
-
-// @formatter:off
-public class FibonacciTest extends AbstractTest{
-
-    private static String[] INPUT = new String[] {
-        "function fib(num) { ",
-        "  if (num < 1) {return 0;}",
-        "  n1 = 0;",
-        "  n2 = 1;",
-        "  i = 1;",
-        "  while (i < num) {",
-        "    next = n2 + n1;",
-        "    n1 = n2;",
-        "    n2 = next;",
-        "    i = i + 1;",
-        "  }",
-        "  return n2;",
-        "}",
-        "function main(num) {  ",
-        "  return fib(num);",
-        "}  ",
-    };
-
-    // java reference
-    private static int test(int num) {
-        if (num <= 0) {
-            return 0;
-        }
-        int n1 = 0;
-        int n2 = 1;
-        for (int i = 1; i < num; i++) {
-            final int next = n2 + n1;
-            n1 = n2;
-            n2 = next;
-        }
-        return n2;
-    }
-
-    private static final int TEST_VALUE = 42;
-    private static final int ITERATIONS = 5000;
-
-    @Test
-    public void test() throws ScriptException {
-        StringBuilder s = new StringBuilder();
-        for (String line : INPUT) {
-            s.append(line).append("\n");
-        }
-        final SLContext context = new SLContext(System.out);
-        final Source source = context.getSourceManager().get("(fib test)", s.toString());
-        SLScript script = SLScript.create(context, source);
-        Integer reference = test(TEST_VALUE);
-        for (int i = 0; i < ITERATIONS; i++) {
-            if (!reference.equals(script.run(TEST_VALUE))) {
-                throw new AssertionError();
-            }
-        }
-    }
-}
--- a/graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/LoopPrintTest.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,48 +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.truffle.sl.test;
-
-import org.junit.*;
-
-// @formatter:off
-public class LoopPrintTest extends AbstractTest {
-
-    private static String[] INPUT = new String[] {
-        "function main {  ",
-        "  i = 0;  ",
-        "  while (i < 1000) {  ",
-        "    i = i + 1;  ",
-        "  }  ",
-        "  print(i);  ",
-        "}  ",
-    };
-
-    private static String[] OUTPUT = new String[] {
-        "1000",
-    };
-
-    @Test
-    public void test() {
-        executeSL(INPUT, OUTPUT, false);
-    }
-}
--- a/graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/LoopTest.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,48 +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.truffle.sl.test;
-
-import org.junit.*;
-
-// @formatter:off
-public class LoopTest extends AbstractTest {
-
-    private static String[] INPUT = new String[] {
-        "function main {  ",
-        "  i = 0;  ",
-        "  while (i < 1000) {  ",
-        "    i = i + 1;  ",
-        "  }  ",
-        "  return i;  ",
-        "}  ",
-    };
-
-    private static String[] OUTPUT = new String[] {
-        "1000",
-    };
-
-    @Test
-    public void test() {
-        executeSL(INPUT, OUTPUT, false);
-    }
-}
--- a/graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/MulTest.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,50 +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.truffle.sl.test;
-
-import org.junit.*;
-
-// @formatter:off
-public class MulTest extends AbstractTest {
-
-    private static String[] INPUT = new String[] {
-        "function main {  ",
-        "  print(3 * 4);  ",
-        "  print(3 * 4000000000000);  ",
-        "  print(3000000000000 * 4);  ",
-        "  print(3000000000000 * 4000000000000);  ",
-        "}  ",
-    };
-
-    private static String[] OUTPUT = new String[] {
-        "12",
-        "12000000000000",
-        "12000000000000",
-        "12000000000000000000000000",
-    };
-
-    @Test
-    public void test() {
-        executeSL(INPUT, OUTPUT, false);
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/SLSimpleTestSuite.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.sl.test;
+
+import org.junit.*;
+import org.junit.runner.*;
+
+@RunWith(SLTestRunner.class)
+@SLTestSuite({"graal/com.oracle.truffle.sl.test/tests", "tests"})
+public class SLSimpleTestSuite {
+
+    public static void main(String[] args) throws Exception {
+        SLTestRunner.runInMain(SLSimpleTestSuite.class, args);
+    }
+
+    /*
+     * Our "mx unittest" command looks for methods that are annotated with @Test. By just defining
+     * an empty method, this class gets included and the test suite is properly executed.
+     */
+    @Test
+    public void unittest() {
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/SLTestRunner.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,208 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.sl.test;
+
+import java.io.*;
+import java.nio.charset.*;
+import java.nio.file.*;
+import java.nio.file.attribute.*;
+import java.util.*;
+
+import org.junit.*;
+import org.junit.internal.*;
+import org.junit.runner.*;
+import org.junit.runner.manipulation.*;
+import org.junit.runner.notification.*;
+import org.junit.runners.*;
+import org.junit.runners.model.*;
+
+import com.oracle.truffle.api.*;
+import com.oracle.truffle.api.source.*;
+import com.oracle.truffle.sl.*;
+import com.oracle.truffle.sl.runtime.*;
+import com.oracle.truffle.sl.test.SLTestRunner.TestCase;
+
+public final class SLTestRunner extends ParentRunner<TestCase> {
+
+    private static final int REPEATS = 10;
+
+    private static final String SOURCE_SUFFIX = ".sl";
+    private static final String INPUT_SUFFIX = ".input";
+    private static final String OUTPUT_SUFFIX = ".output";
+
+    private static final String LF = System.getProperty("line.separator");
+
+    static class TestCase {
+        protected final Description name;
+        protected final Source source;
+        protected final String testInput;
+        protected final String expectedOutput;
+        protected String actualOutput;
+
+        protected TestCase(Class<?> testClass, String name, Source source, String testInput, String expectedOutput) {
+            this.name = Description.createTestDescription(testClass, name);
+            this.source = source;
+            this.testInput = testInput;
+            this.expectedOutput = expectedOutput;
+        }
+    }
+
+    private final SourceManager sourceManager = new SourceManager();
+    private final List<TestCase> testCases;
+
+    public SLTestRunner(Class<?> runningClass) throws InitializationError {
+        super(runningClass);
+        try {
+            testCases = createTests(runningClass);
+        } catch (IOException e) {
+            throw new InitializationError(e);
+        }
+    }
+
+    @Override
+    protected Description describeChild(TestCase child) {
+        return child.name;
+    }
+
+    @Override
+    protected List<TestCase> getChildren() {
+        return testCases;
+    }
+
+    protected List<TestCase> createTests(final Class<?> c) throws IOException, InitializationError {
+        SLTestSuite suite = c.getAnnotation(SLTestSuite.class);
+        if (suite == null) {
+            throw new InitializationError(String.format("@%s annotation required on class '%s' to run with '%s'.", SLTestSuite.class.getSimpleName(), c.getName(), SLTestRunner.class.getSimpleName()));
+        }
+
+        String[] pathes = suite.value();
+
+        Path root = null;
+        for (String path : pathes) {
+            root = FileSystems.getDefault().getPath(path);
+            if (Files.exists(root)) {
+                break;
+            }
+        }
+        if (root == null && pathes.length > 0) {
+            throw new FileNotFoundException(pathes[0]);
+        }
+
+        final Path rootPath = root;
+
+        final List<TestCase> foundCases = new ArrayList<>();
+        Files.walkFileTree(rootPath, new SimpleFileVisitor<Path>() {
+            @Override
+            public FileVisitResult visitFile(Path sourceFile, BasicFileAttributes attrs) throws IOException {
+                String sourceName = sourceFile.getFileName().toString();
+                if (sourceName.endsWith(SOURCE_SUFFIX)) {
+                    String baseName = sourceName.substring(0, sourceName.length() - SOURCE_SUFFIX.length());
+
+                    Path inputFile = sourceFile.resolveSibling(baseName + INPUT_SUFFIX);
+                    String testInput = "";
+                    if (Files.exists(inputFile)) {
+                        testInput = readAllLines(inputFile);
+                    }
+
+                    Path outputFile = sourceFile.resolveSibling(baseName + OUTPUT_SUFFIX);
+                    String expectedOutput = "";
+                    if (Files.exists(outputFile)) {
+                        expectedOutput = readAllLines(outputFile);
+                    }
+
+                    foundCases.add(new TestCase(c, baseName, sourceManager.get(sourceName, readAllLines(sourceFile)), testInput, expectedOutput));
+                }
+                return FileVisitResult.CONTINUE;
+            }
+        });
+        return foundCases;
+    }
+
+    private static String readAllLines(Path file) throws IOException {
+        // fix line feeds for non unix os
+        StringBuilder outFile = new StringBuilder();
+        for (String line : Files.readAllLines(file, Charset.defaultCharset())) {
+            outFile.append(line).append(LF);
+        }
+        return outFile.toString();
+    }
+
+    @Override
+    protected void runChild(TestCase testCase, RunNotifier notifier) {
+        notifier.fireTestStarted(testCase.name);
+
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        PrintStream printer = new PrintStream(out);
+        try {
+            SLContext context = new SLContext(sourceManager, new BufferedReader(new StringReader(repeat(testCase.testInput, REPEATS))), printer);
+            SLMain.run(context, testCase.source, null, REPEATS);
+
+            String actualOutput = new String(out.toByteArray());
+            Assert.assertEquals(repeat(testCase.expectedOutput, REPEATS), actualOutput);
+        } catch (Throwable ex) {
+            notifier.fireTestFailure(new Failure(testCase.name, ex));
+        } finally {
+            notifier.fireTestFinished(testCase.name);
+        }
+    }
+
+    private static String repeat(String s, int count) {
+        StringBuilder result = new StringBuilder(s.length() * count);
+        for (int i = 0; i < count; i++) {
+            result.append(s);
+        }
+        return result.toString();
+    }
+
+    public static void runInMain(Class<?> testClass, String[] args) throws InitializationError, NoTestsRemainException {
+        JUnitCore core = new JUnitCore();
+        core.addListener(new TextListener(System.out));
+        SLTestRunner suite = new SLTestRunner(testClass);
+        if (args.length > 0) {
+            suite.filter(new NameFilter(args[0]));
+        }
+        Result r = core.run(suite);
+        if (!r.wasSuccessful()) {
+            System.exit(1);
+        }
+    }
+
+    private static final class NameFilter extends Filter {
+        private final String pattern;
+
+        private NameFilter(String pattern) {
+            this.pattern = pattern.toLowerCase();
+        }
+
+        @Override
+        public boolean shouldRun(Description description) {
+            return description.getMethodName().toLowerCase().contains(pattern);
+        }
+
+        @Override
+        public String describe() {
+            return "Filter contains " + pattern;
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/SLTestSuite.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.sl.test;
+
+import java.lang.annotation.*;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+public @interface SLTestSuite {
+
+    /**
+     * Defines the base path of the test suite. Multiple base pathes can be specified. However only
+     * the first base that exists is used to lookup the test cases.
+     */
+    String[] value();
+
+}
--- a/graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/SplitOutputStream.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,69 +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.truffle.sl.test;
-
-import java.io.*;
-
-public class SplitOutputStream extends OutputStream {
-
-    private final OutputStream[] outputs;
-
-    public SplitOutputStream(OutputStream... outputs) {
-        this.outputs = outputs;
-    }
-
-    @Override
-    public void write(int b) throws IOException {
-        for (OutputStream out : outputs) {
-            out.write(b);
-        }
-    }
-
-    @Override
-    public void write(byte[] b) throws IOException {
-        for (OutputStream out : outputs) {
-            out.write(b);
-        }
-    }
-
-    @Override
-    public void write(byte[] b, int off, int len) throws IOException {
-        for (OutputStream out : outputs) {
-            out.write(b, off, len);
-        }
-    }
-
-    @Override
-    public void flush() throws IOException {
-        for (OutputStream out : outputs) {
-            out.flush();
-        }
-    }
-
-    @Override
-    public void close() throws IOException {
-        for (OutputStream out : outputs) {
-            out.close();
-        }
-    }
-}
--- a/graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/SubTest.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,50 +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.truffle.sl.test;
-
-import org.junit.*;
-
-// @formatter:off
-public class SubTest extends AbstractTest {
-
-    private static String[] INPUT = new String[] {
-        "function main {  ",
-        "  print(3 - 4);  ",
-        "  print(3 - 4000000000000);  ",
-        "  print(3000000000000 - 4);  ",
-        "  print(3000000000000 - 4000000000000);  ",
-        "}  ",
-    };
-
-    private static String[] OUTPUT = new String[] {
-        "-1",
-        "-3999999999997",
-        "2999999999996",
-        "-1000000000000",
-    };
-
-    @Test
-    public void test() {
-        executeSL(INPUT, OUTPUT, false);
-    }
-}
--- a/graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/SumTest.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,50 +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.truffle.sl.test;
-
-import org.junit.*;
-
-// @formatter:off
-public class SumTest extends AbstractTest {
-
-    private static String[] INPUT = new String[] {
-        "function main {  ",
-        "  i = 0;  ",
-        "  sum = 0;  ",
-        "  while (i < 100000) {  ",
-        "    sum = sum + 1000000;  ",
-        "    i = i + 1;  ",
-        "  }  ",
-        "  return sum;  ",
-        "}  ",
-    };
-
-    private static String[] OUTPUT = new String[] {
-        "100000000000",
-    };
-
-    @Test
-    public void test() {
-        executeSL(INPUT, OUTPUT, false);
-    }
-}
--- a/graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/TernaryTest.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +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.truffle.sl.test;
-
-import org.junit.*;
-
-// @formatter:off
-public class TernaryTest extends AbstractTest {
-
-    private static String[] INPUT = new String[] {
-        "function main {  " +
-        "  print(#(1 < 2) ? 1 : 2);" +
-        "  print(#(2 < 1) ? 100000000000000 : 1);  ",
-        "  print(#(1 < 2) ? 100000000000000 : 1);  ",
-        "  print(#(2 < 1) ? \"wrong\" : \"true\");",
-        "  print(#(2 < 1) ? \"wrong\" : 1);",
-        "}  ",
-    };
-
-    private static String[] OUTPUT = new String[] {
-        "1",
-        "1",
-        "100000000000000",
-        "true",
-        "1",
-    };
-
-    @Test
-    public void test() {
-        executeSL(INPUT, OUTPUT, false);
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl.test/tests/Add.output	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,7 @@
+7
+34
+34
+34
+4000000000003
+3000000000004
+7000000000000
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl.test/tests/Add.sl	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,9 @@
+function main() {  
+  println(3 + 4);  
+  println(3 + "4");  
+  println("3" + 4);  
+  println("3" + "4");  
+  println(3 + 4000000000000);  
+  println(3000000000000 + 4);  
+  println(3000000000000 + 4000000000000);  
+}  
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl.test/tests/Arithmetic.output	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,10 @@
+5
+1
+-3
+14
+11
+5
+-3
+1
+18
+11
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl.test/tests/Arithmetic.sl	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,12 @@
+function main() {  
+  println(3 + 4 - 2);  
+  println(3 - 4 + 2);  
+  println(3 - 4 - 2);  
+  println(3 * 4 + 2);  
+  println(3 + 4 * 2);  
+  println(3 + (4 - 2));  
+  println(3 - (4 + 2));  
+  println(3 - (4 - 2));  
+  println(3 * (4 + 2));  
+  println(3 + (4 * 2));  
+}  
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl.test/tests/Break.output	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,1 @@
+942
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl.test/tests/Break.sl	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,10 @@
+function main() {  
+  i = 0;  
+  while (i < 1000) {
+    if (i >= 942) {
+      break;
+    }  
+    i = i + 1;  
+  }
+  return i;  
+}  
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl.test/tests/Builtins.output	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,1 @@
+Hello World!
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl.test/tests/Builtins.sl	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,4 @@
+function main() {  
+  println("Hello World!");  
+  nanoTime();  
+}  
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl.test/tests/CalcShell.input	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,15 @@
+i
+80
+c
+return cur + i;
+r
+c
+if (i <= 2) { return 1; } else { return prev + cur; }
+r
+i
+100
+r
+c
+if (i == 0) { return 1; } else { return cur * i; }
+r
+x
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl.test/tests/CalcShell.output	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,35 @@
+available commands:
+x: exit
+c: define the calculation function with the parameters prev, cur, and i
+   prev and cur start with 0; i is the loop variable from 0 to n
+     example: 'return cur + i;' computes the sum of 1 to n
+     example: 'if (i == 0) { return 1; } else { return cur * i; }' computes the factorial of i
+     example: 'if (i <= 2) { return 1; } else { return prev + cur; }' computes the nth Fibonacci number
+i: define the number of iterations, i.e, the number n in the examples above
+r: Run the calculation loop often, and print the first and last result
+t: Run the calculation loop a couple of time, and print timing information for each run
+h: Print this help message
+
+cmd>
+n>
+cmd>
+function>
+cmd>
+** first: 3240
+** last:  3240
+cmd>
+function>
+cmd>
+** first: 23416728348467685
+** last:  23416728348467685
+cmd>
+n>
+cmd>
+** first: 354224848179261915075
+** last:  354224848179261915075
+cmd>
+function>
+cmd>
+** first: 93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000
+** last:  93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000
+cmd>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl.test/tests/CalcShell.sl	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,89 @@
+function iterations() {
+  return 80;
+}
+
+function calcLoop(n) {
+  i = 0;
+  prev = cur = 0;
+  while (i <= n) {
+    next = calc(prev, cur, i);
+    prev = cur;
+    cur = next;  
+    i = i + 1;
+  }  
+  return cur;  
+}
+
+function timing(n) {
+  i = 0;
+  while (i < 20) {
+    start = nanoTime();
+    calcLoop(n);
+    end = nanoTime();
+    i = i + 1;
+
+    println("** run " + i + ": " + (end - start) + " ns");
+  }
+}
+
+function run(n) {
+  firstResult = calcLoop(n);
+  println("** first: " + firstResult);
+  i = 0;
+  while (i < 100) {
+    calcLoop(n);
+    i = i + 1;
+  }
+  lastResult = calcLoop(n);
+  println("** last:  " + lastResult);
+  
+  if (firstResult != lastResult) {
+    println("ERROR: result not stable");
+  }
+}  
+
+function help() {
+  println("available commands:");
+  println("x: exit");
+  println("c: define the calculation function with the parameters prev, cur, and i");
+  println("   prev and cur start with 0; i is the loop variable from 0 to n");
+  println("     example: 'return cur + i;' computes the sum of 1 to n"); 
+  println("     example: 'if (i == 0) { return 1; } else { return cur * i; }' computes the factorial of i"); 
+  println("     example: 'if (i <= 2) { return 1; } else { return prev + cur; }' computes the nth Fibonacci number");
+  println("i: define the number of iterations, i.e, the number n in the examples above");
+  println("r: Run the calculation loop often, and print the first and last result");
+  println("t: Run the calculation loop a couple of time, and print timing information for each run");
+  println("h: Print this help message");
+  println("");
+}
+
+function main() {
+  help();
+  
+  while (1 == 1) {
+    println("cmd>");
+    cmd = readln();
+    if (cmd == "x" || cmd == "") {
+      return;
+    }
+    if (cmd == "h") {
+      help();
+    }
+    if (cmd == "c") {
+      println("function>");
+      code = readln();
+      defineFunction("function calc(prev, cur, i) { " + code + "}");
+    }
+    if (cmd == "t") {
+      timing(iterations());
+    }
+    if (cmd == "r") {
+      run(iterations());
+    }
+    if (cmd == "i") {
+      println("n>");
+      n = readln();
+      defineFunction("function iterations() { return " + n + "; }");
+    }
+  }
+}  
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl.test/tests/Call.output	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,8 @@
+42
+42
+42
+42
+42
+42
+42
+42
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl.test/tests/Call.sl	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,16 @@
+function ret(a) { return a; } 
+function dub(a) { return a * 2; } 
+function inc(a) { return a + 1; } 
+function dec(a) { return a - 1; } 
+function call(f, v) { return f(v); }
+ 
+function main() {  
+  println(ret(42));
+  println(dub(21));
+  println(inc(41));
+  println(dec(43));
+  println(call(ret, 42));
+  println(call(dub, 21));
+  println(call(inc, 41));
+  println(call(dec, 43));
+}  
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl.test/tests/Comparison.output	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,54 @@
+<
+true
+false
+false
+true
+false
+true
+false
+false
+<=
+true
+false
+true
+true
+false
+true
+false
+true
+>
+false
+true
+false
+false
+true
+false
+true
+false
+>=
+false
+true
+true
+false
+true
+false
+true
+true
+==
+false
+false
+true
+false
+false
+false
+false
+true
+!=
+true
+true
+false
+true
+true
+true
+true
+false
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl.test/tests/Comparison.sl	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,61 @@
+function main() {  
+  println("<");
+  println(4 < 20);  
+  println(40 < 2);  
+  println(4 < 4);  
+  println(4 < 200000000000000000000000000);  
+  println(40000000000000000000000000 < 20);  
+  println(40000000000000000000000000 < 200000000000000000000000000);  
+  println(400000000000000000000000000 < 20000000000000000000000000);  
+  println(40000000000000000000000000 < 40000000000000000000000000);  
+
+  println("<=");
+  println(4 <= 20);  
+  println(40 <= 2);  
+  println(4 <= 4);  
+  println(4 <= 200000000000000000000000000);  
+  println(40000000000000000000000000 <= 20);  
+  println(40000000000000000000000000 <= 200000000000000000000000000);  
+  println(400000000000000000000000000 <= 20000000000000000000000000);  
+  println(40000000000000000000000000 <= 40000000000000000000000000);  
+
+  println(">");
+  println(4 > 20);  
+  println(40 > 2);  
+  println(4 > 4);  
+  println(4 > 200000000000000000000000000);  
+  println(40000000000000000000000000 > 20);  
+  println(40000000000000000000000000 > 200000000000000000000000000);  
+  println(400000000000000000000000000 > 20000000000000000000000000);  
+  println(40000000000000000000000000 > 40000000000000000000000000);  
+
+  println(">=");
+  println(4 >= 20);  
+  println(40 >= 2);  
+  println(4 >= 4);  
+  println(4 >= 200000000000000000000000000);  
+  println(40000000000000000000000000 >= 20);  
+  println(40000000000000000000000000 >= 200000000000000000000000000);  
+  println(400000000000000000000000000 >= 20000000000000000000000000);  
+  println(40000000000000000000000000 >= 40000000000000000000000000);  
+
+  println("==");
+  println(4 == 20);  
+  println(40 == 2);  
+  println(4 == 4);  
+  println(4 == 200000000000000000000000000);  
+  println(40000000000000000000000000 == 20);  
+  println(40000000000000000000000000 == 200000000000000000000000000);  
+  println(400000000000000000000000000 == 20000000000000000000000000);  
+  println(40000000000000000000000000 == 40000000000000000000000000);  
+
+  println("!=");
+  println(4 != 20);  
+  println(40 != 2);  
+  println(4 != 4);  
+  println(4 != 200000000000000000000000000);  
+  println(40000000000000000000000000 != 20);  
+  println(40000000000000000000000000 != 200000000000000000000000000);  
+  println(400000000000000000000000000 != 20000000000000000000000000);  
+  println(40000000000000000000000000 != 40000000000000000000000000);  
+}  
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl.test/tests/ControlFlow.output	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,1 @@
+1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl.test/tests/ControlFlow.sl	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,10 @@
+function foo() {}
+function bar() {}
+
+function main() {  
+  foo();
+  if (1 < 2) {
+    bar();
+    return 1;
+  }
+}  
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl.test/tests/DefineFunction.output	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,2 @@
+42
+38
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl.test/tests/DefineFunction.sl	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,11 @@
+function foo() {
+  println(test(40, 2));
+}
+
+function main() {
+  defineFunction("function test(a, b) { return a + b; }");
+  foo();
+
+  defineFunction("function test(a, b) { return a - b; }");
+  foo();
+}  
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl.test/tests/Div.output	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,4 @@
+2
+0
+1000000000000
+1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl.test/tests/Div.sl	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,6 @@
+function main() {  
+  println(4 / 2);  
+  println(4 / 4000000000000);  
+  println(3000000000000 / 3);  
+  println(3000000000000 / 3000000000000);  
+}  
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl.test/tests/Fibonacci.output	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,10 @@
+1: 1
+2: 1
+3: 2
+4: 3
+5: 5
+6: 8
+7: 13
+8: 21
+9: 34
+10: 55
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl.test/tests/Fibonacci.sl	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,21 @@
+function fib(num) { 
+  if (num < 1) {return 0;}
+  n1 = 0;
+  n2 = 1;
+  i = 1;
+  while (i < num) {
+    next = n2 + n1;
+    n1 = n2;
+    n2 = next;
+    i = i + 1;
+  }
+  return n2;
+}
+
+function main() {  
+  i = 1;
+  while (i <= 10) {
+    println(i + ": " + fib(i));
+    i = i + 1;
+  }
+}  
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl.test/tests/FunctionLiteral.output	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,2 @@
+42
+38
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl.test/tests/FunctionLiteral.sl	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,16 @@
+function add(a, b) {
+  return a + b;
+}
+
+function sub(a, b) {
+  return a - b;
+}
+
+function foo(f) {
+  println(f(40, 2));
+}
+
+function main() {
+  foo(add);
+  foo(sub);
+}  
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl.test/tests/HelloWorld.output	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,1 @@
+Hello World!
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl.test/tests/HelloWorld.sl	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,3 @@
+function main() {  
+  println("Hello World!");  
+}  
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl.test/tests/Inlining.output	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,1 @@
+1260000
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl.test/tests/Inlining.sl	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,18 @@
+
+function a() {return 42;}
+function b() {return a();}
+function c() {return b();}
+function d() {return c();}
+function e() {return c();}
+function f() {return c();}
+function g() {return d() + e() + f();}
+
+function main() {
+    i = 0;
+    result = 0;
+    while (i < 10000) {
+        result = result + g();
+        i = i + 1;
+    }
+    return result;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl.test/tests/Loop.output	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,1 @@
+1000
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl.test/tests/Loop.sl	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,7 @@
+function main() {  
+  i = 0;  
+  while (i < 1000) {  
+    i = i + 1;  
+  }  
+  return i;  
+}  
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl.test/tests/LoopCall.output	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,1 @@
+1000
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl.test/tests/LoopCall.sl	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,20 @@
+function add(a, b) {
+  return a + b;
+}
+
+function loop(n) {
+  i = 0;
+  while (i < n) {  
+    i = add(i, 1);  
+  }
+  return i;
+}
+
+function main() {
+  i = 0;
+  while (i < 20) {
+    loop(1000);
+    i = i + 1;
+  }
+  println(loop(1000));  
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl.test/tests/LoopInvalidate.output	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,1 @@
+1000
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl.test/tests/LoopInvalidate.sl	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,21 @@
+function add(a, b) {
+  return a + b;
+}
+
+function loop(n) {
+  i = 0;  
+  while (i < n) {  
+    i = add(i, 1);  
+  }  
+  return i;
+}  
+
+function main() {
+  i = 0;
+  while (i < 20) {
+    loop(1000);
+    i = i + 1;
+  }
+  add("a", "b");
+  println(loop(1000));  
+}  
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl.test/tests/LoopPolymorphic.output	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,1 @@
+1000
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl.test/tests/LoopPolymorphic.sl	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,22 @@
+function add(a, b) {
+  return a + b;
+}
+
+function loop(n) {
+  i = 0;
+  while (i < n) {
+    i = add(i, 1); 
+  }
+  return i;
+}
+
+function main() {
+  add("a", "b");
+
+  i = 0;
+  while (i < 20) {
+    loop(1000);
+    i = i + 1;
+  }
+  println(loop(1000));  
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl.test/tests/LoopPrint.output	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,1 @@
+1000
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl.test/tests/LoopPrint.sl	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,16 @@
+function loop(n) {
+  i = 0;  
+  while (i < n) {  
+    i = i + 1;  
+  }  
+  return i;
+}  
+
+function main() {
+  i = 0;
+  while (i < 20) {
+    loop(1000);
+    i = i + 1;
+  }
+  println(loop(1000));  
+}  
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl.test/tests/Mul.output	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,4 @@
+12
+12000000000000
+12000000000000
+12000000000000000000000000
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl.test/tests/Mul.sl	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,6 @@
+function main() {  
+  println(3 * 4);  
+  println(3 * 4000000000000);  
+  println(3000000000000 * 4);  
+  println(3000000000000 * 4000000000000);  
+}  
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl.test/tests/Null.output	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,7 @@
+null
+true
+false
+false
+true
+false
+true
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl.test/tests/Null.sl	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,13 @@
+/* The easiest way to generate null: a function without a return statement implicitly returns null. */
+function null() {
+}
+
+function main() {  
+  println(null());  
+  println(null() == null());  
+  println(null() != null());  
+  println(null() == 42);  
+  println(null() != 42);  
+  println(null() == "42");  
+  println(null() != "42");  
+}  
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl.test/tests/String.output	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,10 @@
+snull
+snull
+sbar
+sfoo
+nulls
+nulls
+bars
+foos
+2 < 4: true
+Type error at String.sl line 9 col 36: operation "<" not defined for Number 2, String "4"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl.test/tests/String.sl	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,25 @@
+function null() {
+}
+
+function foo() {
+  return "bar";
+}
+
+function f(a, b) {
+  return a + " < " + b + ": " + (a < b);
+}
+
+function main() {  
+  println("s" + null());  
+  println("s" + null);  
+  println("s" + foo());  
+  println("s" + foo);
+    
+  println(null() + "s");  
+  println(null() + "s");  
+  println(foo() + "s");  
+  println(foo + "s");
+
+  println(f(2, 4));
+  println(f(2, "4"));
+}  
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl.test/tests/Sub.output	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,4 @@
+-1
+-3999999999997
+2999999999996
+-1000000000000
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl.test/tests/Sub.sl	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,6 @@
+function main() {  
+  println(3 - 4);  
+  println(3 - 4000000000000);  
+  println(3000000000000 - 4);  
+  println(3000000000000 - 4000000000000);  
+}  
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl.test/tests/Sum.output	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,1 @@
+50005000
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl.test/tests/Sum.sl	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,9 @@
+function main() {  
+  i = 0;  
+  sum = 0;  
+  while (i <= 10000) {  
+    sum = sum + i;  
+    i = i + 1;  
+  }  
+  return sum;  
+}  
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl.test/tests/error/TypeError01.output	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,1 @@
+Type error at TypeError01.sl line 2 col 5: operation "-" not defined for Number 3, String "4"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl.test/tests/error/TypeError01.sl	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,3 @@
+function main() {  
+  3 - "4";  
+}  
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl.test/tests/error/TypeError02.output	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,1 @@
+Type error at TypeError02.sl line 2 col 6: operation "if" not defined for String "4"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl.test/tests/error/TypeError02.sl	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,3 @@
+function main() {  
+  if ("4") { }  
+}  
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl.test/tests/error/TypeError03.output	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,1 @@
+Type error at TypeError03.sl line 2 col 7: operation "&&" not defined for String "4", ANY
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl.test/tests/error/TypeError03.sl	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,3 @@
+function main() {  
+  "4" && 4;  
+}  
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl.test/tests/error/TypeError04.output	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,1 @@
+Type error at TypeError04.sl line 2 col 11: operation "||" not defined for Boolean false, Number 4
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl.test/tests/error/TypeError04.sl	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,3 @@
+function main() {  
+  (1 > 2) || 4;  
+}  
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl.test/tests/error/TypeError05.output	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,1 @@
+Type error at TypeError05.sl line 3 col 3: operation "invoke" not defined for Boolean true
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl.test/tests/error/TypeError05.sl	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,4 @@
+function main() {
+  f = 1 < 2;
+  f();  
+}  
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl.test/tests/error/TypeError06.output	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,1 @@
+Type error: operation "defineFunction" not defined for Number 3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl.test/tests/error/TypeError06.sl	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,3 @@
+function main() {
+  defineFunction(3);
+}  
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl.test/tests/error/TypeError07.output	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,1 @@
+Type error: operation "defineFunction" not defined for NULL
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl.test/tests/error/TypeError07.sl	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,3 @@
+function main() {
+  defineFunction();
+}  
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/SLException.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,36 @@
+/*
+ * 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.truffle.sl;
+
+/**
+ * SL does not need a sophisticated error checking and reporting mechanism, so all unexpected
+ * conditions just abort execution. This exception class is used when we abort from within the SL
+ * implementation.
+ */
+public class SLException extends RuntimeException {
+    private static final long serialVersionUID = -6799734410727348507L;
+
+    public SLException(String message) {
+        super(message);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/SLMain.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,263 @@
+/*
+ * 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;
+
+import java.io.*;
+import java.math.*;
+
+import com.oracle.truffle.api.*;
+import com.oracle.truffle.api.dsl.*;
+import com.oracle.truffle.api.nodes.*;
+import com.oracle.truffle.api.source.*;
+import com.oracle.truffle.sl.builtins.*;
+import com.oracle.truffle.sl.nodes.*;
+import com.oracle.truffle.sl.nodes.call.*;
+import com.oracle.truffle.sl.nodes.controlflow.*;
+import com.oracle.truffle.sl.nodes.expression.*;
+import com.oracle.truffle.sl.nodes.local.*;
+import com.oracle.truffle.sl.parser.*;
+import com.oracle.truffle.sl.runtime.*;
+
+/**
+ * SL is a simple language to demonstrate and showcase features of Truffle. The implementation is as
+ * simple and clean as possible in order to help understanding the ideas and concepts of Truffle.
+ * The language has first class functions, but no object model.
+ * <p>
+ * SL is dynamically typed, i.e., there are no type names specified by the programmer. SL is
+ * strongly typed, i.e., there is no automatic conversion between types. If an operation is not
+ * available for the types encountered at run time, a type error is reported and execution is
+ * stopped. For example, {@code 4 - "2"} results in a type error because subtraction is only defined
+ * for numbers.
+ * 
+ * <p>
+ * <b>Types:</b>
+ * <ul>
+ * <li>Number: arbitrary precision integer numbers. The implementation uses the Java primitive type
+ * {@code long} to represent numbers that fit into the 64 bit range, and {@link BigInteger} for
+ * numbers that exceed the range. Using a primitive type such as {@code long} is crucial for
+ * performance.
+ * <li>Boolean: implemented as the Java primitive type {@code boolean}.
+ * <li>String: implemented as the Java standard type {@link String}.
+ * <li>Function: implementation type {@link SLFunction}.
+ * <li>Null (with only one value {@code null}): implemented as the singleton
+ * {@link SLNull#SINGLETON}.
+ * </ul>
+ * The class {@link SLTypes} lists these types for the Truffle DSL, i.e., for type-specialized
+ * operations that are specified using Truffle DSL annotations.
+ * 
+ * <p>
+ * <b>Language concepts:</b>
+ * <ul>
+ * <li>Literals for {@link SLBigIntegerLiteralNode numbers} , {@link SLStringLiteralNode strings},
+ * and {@link SLFunctionLiteralNode functions}.
+ * <li>Basic arithmetic, logical, and comparison operations: {@link SLAddNode +}, {@link SLSubNode
+ * -}, {@link SLMulNode *}, {@link SLDivNode /}, {@link SLLogicalAndNode logical and},
+ * {@link SLLogicalOrNode logical or}, {@link SLEqualNode ==}, !=, {@link SLLessThanNode <},
+ * {@link SLLessOrEqualNode <=}, >, >=.
+ * <li>Local variables: local variables must be defined (via a {@link SLWriteLocalVariableNode
+ * write}) before they can be used (by a {@link SLReadLocalVariableNode read}). Local variables are
+ * not visible outside of the block where they were first defined.
+ * <li>Basic control flow statements: {@link SLBlockNode blocks}, {@link SLIfNode if},
+ * {@link SLWhileNode while} with {@link SLBreakNode break} and {@link SLContinueNode continue},
+ * {@link SLReturnNode return}.
+ * <li>Function calls: {@link SLInvokeNode invocations} are efficiently implemented with
+ * {@link SLAbstractDispatchNode polymorphic inline caches}.
+ * </ul>
+ * 
+ * <p>
+ * <b>Syntax and parsing:</b><br>
+ * The syntax is described as an attributed grammar. The {@link Parser} and {@link Scanner} are
+ * automatically generated by the parser generator Coco/R (available from <a
+ * href="http://ssw.jku.at/coco/">http://ssw.jku.at/coco/</a>). The grammar contains semantic
+ * actions that build the AST for a method. To keep these semantic actions short, they are mostly
+ * calls to the {@link SLNodeFactory} that performs the actual node creation. All functions found in
+ * the SL source are added to the {@link SLFunctionRegistry}, which is accessible from the
+ * {@link SLContext}.
+ * 
+ * <p>
+ * <b>Builtin functions:</b><br>
+ * Library functions that are available to every SL source without prior definition are called
+ * builtin functions. They are added to the {@link SLFunctionRegistry} when the {@link SLContext} is
+ * created. There current builtin functions are
+ * <ul>
+ * <li>{@link SLReadlnBuiltin readln}: Read a String from the {@link SLContext#getInput() standard
+ * input}.
+ * <li>{@link SLPrintlnBuiltin println}: Write a value to the {@link SLContext#getOutput() standard
+ * output}.
+ * <li>{@link SLNanoTimeBuiltin nanoTime}: Returns the value of a high-resolution time, in
+ * nanoseconds.
+ * <li>{@link SLDefineFunctionBuiltin defineFunction}: Parses the functions provided as a String
+ * argument and adds them to the function registry. Functions that are already defined are replaced
+ * with the new version.
+ * </ul>
+ */
+public class SLMain {
+
+    /**
+     * The main entry point. Use the mx command "mx sl" to run it with the correct class path setup.
+     */
+    public static void main(String[] args) throws IOException {
+        SourceManager sourceManager = new SourceManager();
+
+        Source source;
+        if (args.length == 0) {
+            source = sourceManager.get("stdin", System.in);
+        } else {
+            source = sourceManager.get(args[0]);
+        }
+
+        int repeats = 1;
+        if (args.length >= 2) {
+            repeats = Integer.parseInt(args[1]);
+        }
+
+        SLContext context = new SLContext(sourceManager, new BufferedReader(new InputStreamReader(System.in)), System.out);
+        run(context, source, System.out, repeats);
+    }
+
+    /**
+     * Parse and run the specified SL source. Factored out in a separate method so that it can also
+     * be used by the unit test harness.
+     */
+    public static void run(SLContext context, Source source, PrintStream logOutput, int repeats) {
+        if (logOutput != null) {
+            logOutput.println("== running on " + Truffle.getRuntime().getName());
+        }
+
+        /* Parse the SL source file. */
+        Parser.parseSL(context, source);
+        /* Lookup our main entry point, which is per definition always named "main". */
+        SLFunction main = context.getFunctionRegistry().lookup("main");
+        if (main.getCallTarget() == null) {
+            throw new SLException("No function main() defined in SL source file.");
+        }
+
+        /* Change to true if you want to see the AST on the console. */
+        boolean printASTToLog = false;
+        /* Change to dump the AST to IGV over the network. */
+        boolean dumpASTToIGV = false;
+
+        printScript("before execution", context, logOutput, printASTToLog, dumpASTToIGV);
+        try {
+            for (int i = 0; i < repeats; i++) {
+                long start = System.nanoTime();
+                /* Call the main entry point, without any arguments. */
+                try {
+                    Object result = main.getCallTarget().call(null, new SLArguments(new Object[0]));
+                    if (result != SLNull.SINGLETON) {
+                        context.getOutput().println(result);
+                    }
+                } catch (UnsupportedSpecializationException ex) {
+                    context.getOutput().println(formatTypeError(ex));
+                }
+                long end = System.nanoTime();
+
+                if (logOutput != null && repeats > 1) {
+                    logOutput.println("== iteration " + (i + 1) + ": " + ((end - start) / 1000000) + " ms");
+                }
+            }
+
+        } finally {
+            printScript("after execution", context, logOutput, printASTToLog, dumpASTToIGV);
+        }
+    }
+
+    /**
+     * When dumpASTToIGV is true: dumps the AST of all functions to the IGV visualizer, via a socket
+     * connection. IGV can be started with the mx command "mx igv".
+     * <p>
+     * When printASTToLog is true: prints the ASTs to the console.
+     */
+    private static void printScript(String groupName, SLContext context, PrintStream logOutput, boolean printASTToLog, boolean dumpASTToIGV) {
+        if (dumpASTToIGV) {
+            GraphPrintVisitor graphPrinter = new GraphPrintVisitor();
+            graphPrinter.beginGroup(groupName);
+            for (SLFunction function : context.getFunctionRegistry().getFunctions()) {
+                RootCallTarget callTarget = function.getCallTarget();
+                if (callTarget != null) {
+                    graphPrinter.beginGraph(function.toString()).visit(callTarget.getRootNode());
+                }
+            }
+            graphPrinter.printToNetwork(true);
+        }
+        if (printASTToLog && logOutput != null) {
+            for (SLFunction function : context.getFunctionRegistry().getFunctions()) {
+                RootCallTarget callTarget = function.getCallTarget();
+                if (callTarget != null) {
+                    logOutput.println("=== " + function);
+                    NodeUtil.printTree(logOutput, callTarget.getRootNode());
+                }
+            }
+        }
+    }
+
+    /**
+     * Provides a user-readable message for run-time type errors. SL is strongly typed, i.e., there
+     * are no automatic type conversions of values. Therefore, Truffle does the type checking for
+     * us: if no matching node specialization for the actual values is found, then we have a type
+     * error. Specialized nodes use the {@link UnsupportedSpecializationException} to report that no
+     * specialization was found. We therefore just have to convert the information encapsulated in
+     * this exception in a user-readable form.
+     */
+    private static String formatTypeError(UnsupportedSpecializationException ex) {
+        StringBuilder result = new StringBuilder();
+        result.append("Type error");
+        if (ex.getNode() != null && ex.getNode().getSourceSection() != null) {
+            SourceSection ss = ex.getNode().getSourceSection();
+            result.append(" at ").append(ss.getSource().getName()).append(" line ").append(ss.getStartLine()).append(" col ").append(ss.getStartColumn());
+        }
+        result.append(": operation");
+        if (ex.getNode() != null && ex.getNode().getClass().getAnnotation(NodeInfo.class) != null) {
+            result.append(" \"").append(ex.getNode().getClass().getAnnotation(NodeInfo.class).shortName()).append("\"");
+        }
+        result.append(" not defined for");
+
+        String sep = " ";
+        for (int i = 0; i < ex.getSuppliedValues().length; i++) {
+            Object value = ex.getSuppliedValues()[i];
+            Node node = ex.getSuppliedNodes()[i];
+            if (node != null) {
+                result.append(sep);
+                sep = ", ";
+
+                if (value instanceof Long || value instanceof BigInteger) {
+                    result.append("Number ").append(value);
+                } else if (value instanceof Boolean) {
+                    result.append("Boolean ").append(value);
+                } else if (value instanceof String) {
+                    result.append("String \"").append(value).append("\"");
+                } else if (value instanceof SLFunction) {
+                    result.append("Function ").append(value);
+                } else if (value == SLNull.SINGLETON) {
+                    result.append("NULL");
+                } else if (value == null) {
+                    // value is not evaluated because of short circuit evaluation
+                    result.append("ANY");
+                } else {
+                    result.append(value);
+                }
+            }
+        }
+        return result.toString();
+    }
+}
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/SLNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,41 +0,0 @@
-/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.sl;
-
-import com.oracle.truffle.api.dsl.*;
-import com.oracle.truffle.api.nodes.*;
-
-@TypeSystemReference(SLTypes.class)
-public class SLNode extends Node {
-
-    public SLNode() {
-        // No source attribution
-        super(null);
-    }
-
-    @Override
-    public String toString() {
-        return getEncapsulatingSourceSection() != null ? getEncapsulatingSourceSection().toString() : super.toString();
-    }
-
-}
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/SLNodeFactory.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,154 +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.truffle.sl;
-
-import java.math.*;
-import java.util.*;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.sl.nodes.ArithmeticNodeFactory.AddNodeFactory;
-import com.oracle.truffle.sl.nodes.ArithmeticNodeFactory.DivNodeFactory;
-import com.oracle.truffle.sl.nodes.ArithmeticNodeFactory.MulNodeFactory;
-import com.oracle.truffle.sl.nodes.ArithmeticNodeFactory.SubNodeFactory;
-import com.oracle.truffle.sl.nodes.*;
-import com.oracle.truffle.sl.parser.*;
-import com.oracle.truffle.sl.runtime.*;
-
-public class SLNodeFactory {
-
-    private final SLContext context;
-
-    private Parser parser;
-    private FrameDescriptor frameDescriptor;
-    private TypedNode returnValue;
-
-    private Source source;
-    private String currentFunctionName;
-
-    public SLNodeFactory(SLContext context) {
-        this.context = context;
-    }
-
-    public void setSource(Source source) {
-        this.source = source;
-    }
-
-    public void setParser(Parser parser) {
-        this.parser = parser;
-    }
-
-    public void startFunction() {
-        frameDescriptor = new FrameDescriptor();
-    }
-
-    public void createFunction(StatementNode body, String name, String[] parameterNames) {
-        context.getFunctionRegistry().register(name, FunctionRootNode.createFunction(body, frameDescriptor, name, returnValue, parameterNames));
-        this.currentFunctionName = name;
-        this.returnValue = null;
-    }
-
-    private <T extends Node> T assignSource(T node) {
-        node.assignSourceSection(ParserUtils.createSourceSection(source, currentFunctionName, parser));
-        return node;
-    }
-
-    public TypedNode createLocal(String name) {
-        return assignSource(new ReadUninitializedNode(context, frameDescriptor.findOrAddFrameSlot(name, FrameSlotKind.Int)));
-    }
-
-    public TypedNode createStringLiteral(String value) {
-        return assignSource(new StringLiteralNode(value));
-    }
-
-    public TypedNode createAssignment(TypedNode read, TypedNode assignment) {
-        FrameSlot slot = ((ReadUninitializedNode) read).getSlot();
-        return assignSource(WriteLocalNodeFactory.create(slot, assignment));
-    }
-
-    public StatementNode createWhile(ConditionNode condition, StatementNode body) {
-        return assignSource(new WhileNode(condition, body));
-    }
-
-    public StatementNode createBlock(List<StatementNode> statements) {
-        return assignSource(new BlockNode(statements.toArray(new StatementNode[statements.size()])));
-    }
-
-    public TypedNode createCall(TypedNode function, TypedNode[] parameters) {
-        return assignSource(CallNode.create(function, parameters));
-    }
-
-    public TypedNode createBinary(String operation, TypedNode left, TypedNode right) {
-        TypedNode binary;
-        switch (operation) {
-            case "+":
-                binary = AddNodeFactory.create(left, right);
-                break;
-            case "*":
-                binary = MulNodeFactory.create(left, right);
-                break;
-            case "/":
-                binary = DivNodeFactory.create(left, right);
-                break;
-            case "-":
-                binary = SubNodeFactory.create(left, right);
-                break;
-            case "<":
-                binary = LessThanNodeFactory.create(left, right);
-                break;
-            case "&&":
-                binary = LogicalAndNodeFactory.create(left, right);
-                break;
-            default:
-                throw new RuntimeException("unexpected operation: " + operation);
-        }
-        return assignSource(binary);
-    }
-
-    public TypedNode createNumericLiteral(String value) {
-        try {
-            return assignSource(new IntegerLiteralNode(Integer.parseInt(value)));
-        } catch (NumberFormatException ex) {
-            return assignSource(new BigIntegerLiteralNode(new BigInteger(value)));
-        }
-    }
-
-    public StatementNode createReturn(TypedNode value) {
-        FrameSlot slot = frameDescriptor.findOrAddFrameSlot("<retval>", FrameSlotKind.Int);
-        if (returnValue == null) {
-            returnValue = ReadLocalNodeFactory.create(slot);
-        }
-        StatementNode write = WriteLocalNodeFactory.create(slot, value);
-        return assignSource(new ReturnNode(write));
-    }
-
-    public TypedNode createTernary(TypedNode condition, TypedNode thenPart, TypedNode elsePart) {
-        return assignSource(TernaryNodeFactory.create(condition, thenPart, elsePart));
-    }
-
-    public StatementNode createIf(ConditionNode condition, StatementNode then, StatementNode elseNode) {
-        return assignSource(IfNodeFactory.create(then, elseNode, condition));
-    }
-
-}
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/SLScript.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,149 +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.truffle.sl;
-
-import java.io.*;
-
-import javax.script.*;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.sl.parser.*;
-import com.oracle.truffle.sl.runtime.*;
-
-public final class SLScript {
-
-    private final SLContext context;
-    private final CallTarget main;
-
-    private SLScript(SLContext context, CallTarget mainFunction) {
-        this.context = context;
-        this.main = mainFunction;
-    }
-
-    public SLContext getContext() {
-        return context;
-    }
-
-    public CallTarget getMain() {
-        return main;
-    }
-
-    public Object run(Object... arguments) {
-        return main.call(null, new SLArguments(arguments));
-    }
-
-    @Override
-    public String toString() {
-        return main.toString();
-    }
-
-    public static SLScript create(SLContext context, Source source) throws ScriptException {
-        SLNodeFactory factory = new SLNodeFactory(context);
-        Parser parser = new Parser(new Scanner(source.getInputStream()), factory);
-        factory.setParser(parser);
-        factory.setSource(source);
-        String error = parser.ParseErrors();
-        if (!error.isEmpty()) {
-            throw new ScriptException(String.format("Error(s) parsing script: %s", error));
-        }
-
-        CallTarget main = context.getFunctionRegistry().lookup("main");
-        if (main == null) {
-            throw new ScriptException("No main function found.");
-        }
-        return new SLScript(context, main);
-    }
-
-    public static SLScript create(SLContext context, InputStream input) throws ScriptException {
-        SLNodeFactory factory = new SLNodeFactory(context);
-        Parser parser = new Parser(new Scanner(input), factory);
-        factory.setParser(parser);
-        factory.setSource(new Source() {
-            public String getName() {
-                return "Unknown";
-            }
-
-            public String getCode() {
-                return null;
-            }
-
-            @Override
-            public String getPath() {
-                // TODO Auto-generated method stub
-                return null;
-            }
-
-            @Override
-            public Reader getReader() {
-                // TODO Auto-generated method stub
-                return null;
-            }
-
-            @Override
-            public InputStream getInputStream() {
-                // TODO Auto-generated method stub
-                return null;
-            }
-
-            @Override
-            public String getCode(int lineNumber) {
-                // TODO Auto-generated method stub
-                return null;
-            }
-
-            @Override
-            public int getLineCount() {
-                // TODO Auto-generated method stub
-                return 0;
-            }
-
-            @Override
-            public int getLineNumber(int offset) {
-                // TODO Auto-generated method stub
-                return 0;
-            }
-
-            @Override
-            public int getLineStartOffset(int lineNumber) {
-                // TODO Auto-generated method stub
-                return 0;
-            }
-
-            @Override
-            public int getLineLength(int lineNumber) {
-                // TODO Auto-generated method stub
-                return 0;
-            }
-        });
-        String error = parser.ParseErrors();
-        if (!error.isEmpty()) {
-            throw new ScriptException(String.format("Error(s) parsing script: %s", error));
-        }
-
-        CallTarget main = context.getFunctionRegistry().lookup("main");
-        if (main == null) {
-            throw new ScriptException("No main function found.");
-        }
-        return new SLScript(context, main);
-    }
-}
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/SLTypes.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,50 +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.truffle.sl;
-
-import java.math.*;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.dsl.*;
-import com.oracle.truffle.sl.runtime.*;
-
-@TypeSystem({int.class, BigInteger.class, boolean.class, String.class, CallTarget.class, SLNull.class, Object[].class})
-public class SLTypes {
-
-    @TypeCheck
-    public boolean isSLNull(Object value) {
-        return SLNull.INSTANCE == value;
-    }
-
-    @TypeCast
-    public SLNull asSLNull(Object value) {
-        assert isSLNull(value);
-        return SLNull.INSTANCE;
-    }
-
-    @ImplicitCast
-    public BigInteger castBigInteger(int integer) {
-        return BigInteger.valueOf(integer);
-    }
-
-}
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/SimpleLanguage.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,107 +0,0 @@
-/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.sl;
-
-import java.io.*;
-
-import javax.script.*;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.impl.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.sl.runtime.*;
-
-public class SimpleLanguage {
-
-    private static final Object[] NO_ARGUMENTS = new Object[0];
-
-    public static void main(String[] args) {
-        run(args[0], System.out, 10, true);
-    }
-
-    public static void run(String name, String input, PrintStream printOutput, int repeats, boolean log) {
-        if (log) {
-            // CheckStyle: stop system..print check
-            System.out.printf("== running on %s\n", Truffle.getRuntime().getName());
-            // CheckStyle: resume system..print check
-        }
-
-        final SLContext context = new SLContext(printOutput);
-        final Source source = context.getSourceManager().get(name, input);
-
-        run(context, source, printOutput, repeats, log);
-    }
-
-    public static void run(String fileName, PrintStream printOutput, int repeats, boolean log) {
-        if (log) {
-            // CheckStyle: stop system..print check
-            System.out.printf("== running on %s\n", Truffle.getRuntime().getName());
-            // CheckStyle: resume system..print check
-        }
-
-        final SLContext context = new SLContext(printOutput);
-        final Source source = context.getSourceManager().get(fileName);
-
-        run(context, source, printOutput, repeats, log);
-    }
-
-    public static void run(SLContext context, Source source, PrintStream printOutput, int repeats, boolean log) {
-
-        SLScript script;
-        try {
-            script = SLScript.create(context, source);
-        } catch (ScriptException e) {
-            // TODO temporary hack
-            throw new RuntimeException(e);
-        }
-
-        if (log) {
-            printScript(script);
-        }
-        try {
-            for (int i = 0; i < repeats; i++) {
-                long start = System.nanoTime();
-                Object result = script.run(NO_ARGUMENTS);
-                long end = System.nanoTime();
-
-                if (result != null) {
-                    printOutput.println(result);
-                }
-                if (log) {
-                    // CheckStyle: stop system..print check
-                    System.out.printf("== iteration %d: %.3f ms\n", (i + 1), (end - start) / 1000000.0);
-                    // CheckStyle: resume system..print check
-                }
-            }
-
-        } finally {
-            if (log) {
-                printScript(script);
-            }
-        }
-    }
-
-    private static void printScript(SLScript script) {
-        NodeUtil.printTree(System.out, ((DefaultCallTarget) script.getMain()).getRootNode());
-    }
-}
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/BuiltinNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +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.truffle.sl.builtins;
-
-import com.oracle.truffle.api.dsl.*;
-import com.oracle.truffle.sl.nodes.*;
-import com.oracle.truffle.sl.runtime.*;
-
-@NodeField(name = "context", type = SLContext.class)
-@NodeChild(value = "arguments", type = TypedNode[].class)
-public abstract class BuiltinNode extends TypedNode {
-
-    public abstract SLContext getContext();
-
-    public abstract TypedNode[] getArguments();
-
-}
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/DefaultBuiltins.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +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.truffle.sl.builtins;
-
-import com.oracle.truffle.api.dsl.*;
-import com.oracle.truffle.sl.nodes.*;
-import com.oracle.truffle.sl.runtime.*;
-
-public abstract class DefaultBuiltins {
-
-    public static void install(SLContext c) {
-        installBuiltin(c, PrintBuiltinFactory.getInstance(), "print");
-        installBuiltin(c, TimeBuiltinFactory.getInstance(), "time");
-    }
-
-    private static void installBuiltin(SLContext context, NodeFactory<? extends BuiltinNode> factory, String name) {
-        context.getFunctionRegistry().register(name, FunctionRootNode.createBuiltin(context, factory, name));
-    }
-}
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/PrintBuiltin.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +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.truffle.sl.builtins;
-
-import com.oracle.truffle.api.dsl.*;
-
-public abstract class PrintBuiltin extends BuiltinNode {
-
-    @Specialization
-    public int doInt(int value) {
-        getContext().getPrintOutput().println(value);
-        return value;
-    }
-
-    @Specialization
-    public boolean doBoolean(boolean value) {
-        getContext().getPrintOutput().println(value);
-        return value;
-    }
-
-    @Specialization
-    public String doString(String value) {
-        getContext().getPrintOutput().println(value);
-        return value;
-    }
-
-    @Specialization
-    public Object doGeneric(Object value) {
-        getContext().getPrintOutput().println(value.toString());
-        return value;
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLBuiltinNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,50 @@
+/*
+ * 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.dsl.*;
+import com.oracle.truffle.sl.nodes.*;
+import com.oracle.truffle.sl.runtime.*;
+
+/**
+ * Base class for all builtin functions. It contains the Truffle DSL annotation {@link NodeChild}
+ * that defines the function arguments.<br>
+ * Builtin functions need access to the {@link SLContext}. Instead of defining a Java field manually
+ * and setting it in a constructor, we use the Truffle DSL annotation {@link NodeField} that
+ * generates the field and constructor automatically.
+ * <p>
+ * The builtin functions are registered in {@link SLContext#installBuiltins}. Every builtin node
+ * subclass is instantiated there, wrapped into a function, and added to the
+ * {@link SLFunctionRegistry}. This ensures that builtin functions can be called like user-defined
+ * functions; there is no special function lookup or call node for builtin functions.
+ */
+@NodeChild(value = "arguments", type = SLExpressionNode[].class)
+@NodeField(name = "context", type = SLContext.class)
+public abstract class SLBuiltinNode extends SLExpressionNode {
+
+    /**
+     * Accessor for the {@link SLContext}. The implementation of this method is generated
+     * automatically based on the {@link NodeField} annotation on the class.
+     */
+    public abstract SLContext getContext();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLDefineFunctionBuiltin.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,51 @@
+/*
+ * 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.CompilerDirectives.SlowPath;
+import com.oracle.truffle.api.*;
+import com.oracle.truffle.api.dsl.*;
+import com.oracle.truffle.api.nodes.*;
+import com.oracle.truffle.sl.parser.*;
+import com.oracle.truffle.sl.runtime.*;
+
+/**
+ * Builtin function to define (or redefine) functions. The provided source code is parsed the same
+ * way as the initial source of the script, so the same syntax applies.
+ */
+@NodeInfo(shortName = "defineFunction")
+public abstract class SLDefineFunctionBuiltin extends SLBuiltinNode {
+
+    @Specialization
+    public String defineFunction(String code) {
+        doDefineFunction(getContext(), code);
+        return code;
+    }
+
+    @SlowPath
+    private static void doDefineFunction(SLContext context, String code) {
+        Source source = context.getSourceManager().get("[defineFunction]", code);
+        /* The same parsing code as for parsing the initial source. */
+        Parser.parseSL(context, source);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLNanoTimeBuiltin.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,38 @@
+/*
+ * 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.dsl.*;
+import com.oracle.truffle.api.nodes.*;
+
+/**
+ * Builtin function that returns the value of a high-resolution time, in nanoseconds.
+ */
+@NodeInfo(shortName = "nanoTime")
+public abstract class SLNanoTimeBuiltin extends SLBuiltinNode {
+
+    @Specialization
+    public long nanoTime() {
+        return System.nanoTime();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLPrintlnBuiltin.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,87 @@
+/*
+ * 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 java.io.*;
+
+import com.oracle.truffle.api.CompilerDirectives.SlowPath;
+import com.oracle.truffle.api.dsl.*;
+import com.oracle.truffle.api.nodes.*;
+import com.oracle.truffle.sl.runtime.*;
+
+/**
+ * Builtin function to write a value to the {@link SLContext#getOutput() standard output}. The
+ * different specialization leverage the typed {@code println} methods available in Java, i.e.,
+ * primitive values are printed without converting them to a {@link String} first.
+ * <p>
+ * Printing involves a lot of Java code, so we need to tell the optimizing system that it should not
+ * unconditionally inline everything reachable from the println() method. This is done via the
+ * {@link SlowPath} annotations.
+ */
+@NodeInfo(shortName = "println")
+public abstract class SLPrintlnBuiltin extends SLBuiltinNode {
+
+    @Specialization
+    public long println(long value) {
+        doPrint(getContext().getOutput(), value);
+        return value;
+    }
+
+    @SlowPath
+    private static void doPrint(PrintStream out, long value) {
+        out.println(value);
+    }
+
+    @Specialization
+    public boolean println(boolean value) {
+        doPrint(getContext().getOutput(), value);
+        return value;
+    }
+
+    @SlowPath
+    private static void doPrint(PrintStream out, boolean value) {
+        out.println(value);
+    }
+
+    @Specialization
+    public String println(String value) {
+        doPrint(getContext().getOutput(), value);
+        return value;
+    }
+
+    @SlowPath
+    private static void doPrint(PrintStream out, String value) {
+        out.println(value);
+    }
+
+    @Specialization
+    public Object println(Object value) {
+        doPrint(getContext().getOutput(), value);
+        return value;
+    }
+
+    @SlowPath
+    private static void doPrint(PrintStream out, Object value) {
+        out.println(value);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLReadlnBuiltin.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,61 @@
+/*
+ * 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.truffle.sl.builtins;
+
+import java.io.*;
+
+import com.oracle.truffle.api.CompilerDirectives.SlowPath;
+import com.oracle.truffle.api.dsl.*;
+import com.oracle.truffle.api.nodes.*;
+import com.oracle.truffle.sl.*;
+import com.oracle.truffle.sl.runtime.*;
+
+/**
+ * Builtin function that reads a String from the {@link SLContext#getInput() standard input}.
+ */
+@NodeInfo(shortName = "readln")
+public abstract class SLReadlnBuiltin extends SLBuiltinNode {
+
+    @Specialization
+    public String readln() {
+        String result = doRead(getContext().getInput());
+        if (result == null) {
+            /*
+             * We do not have a sophisticated end of file handling, so returning an empty string is
+             * a reasonable alternative. Note that the Java null value should never be used, since
+             * it can interfere with the specialization logic in generated source code.
+             */
+            result = "";
+        }
+        return result;
+    }
+
+    @SlowPath
+    private static String doRead(BufferedReader in) {
+        try {
+            return in.readLine();
+        } catch (IOException ex) {
+            throw new SLException(ex.getMessage());
+        }
+    }
+}
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/TimeBuiltin.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,36 +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.truffle.sl.builtins;
-
-import com.oracle.truffle.api.dsl.*;
-
-public abstract class TimeBuiltin extends BuiltinNode {
-
-    public static final long START_TIME = System.currentTimeMillis();
-
-    @Specialization
-    public int doInt() {
-        return (int) (System.currentTimeMillis() - START_TIME);
-    }
-
-}
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/ArgumentsNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,54 +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.truffle.sl.nodes;
-
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-
-public final class ArgumentsNode extends TypedNode {
-
-    @Children private final TypedNode[] arguments;
-
-    public ArgumentsNode(TypedNode[] arguments) {
-        this.arguments = adoptChildren(arguments);
-    }
-
-    public TypedNode[] getArguments() {
-        return arguments;
-    }
-
-    @Override
-    public Object[] executeGeneric(VirtualFrame frame) {
-        return executeArray(frame);
-    }
-
-    @Override
-    @ExplodeLoop
-    public Object[] executeArray(VirtualFrame frame) {
-        Object[] argumentValues = new Object[arguments.length];
-        for (int i = 0; i < arguments.length; i++) {
-            argumentValues[i] = arguments[i].executeGeneric(frame);
-        }
-        return argumentValues;
-    }
-}
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/ArithmeticNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,96 +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.truffle.sl.nodes;
-
-import java.math.*;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.dsl.*;
-
-public abstract class ArithmeticNode extends BinaryNode {
-
-    public abstract static class AddNode extends ArithmeticNode {
-
-        @Specialization(rewriteOn = ArithmeticException.class)
-        int doInt(int left, int right) {
-            return ExactMath.addExact(left, right);
-        }
-
-        @Specialization
-        BigInteger doBigInteger(BigInteger left, BigInteger right) {
-            return left.add(right);
-        }
-
-        @Specialization
-        String doString(String left, String right) {
-            return left + right;
-        }
-
-        @Specialization(guards = "isString")
-        String add(Object left, Object right) {
-            return left.toString() + right.toString();
-        }
-    }
-
-    public abstract static class SubNode extends ArithmeticNode {
-
-        @Specialization(rewriteOn = ArithmeticException.class)
-        int sub(int left, int right) {
-            return ExactMath.subtractExact(left, right);
-        }
-
-        @Specialization
-        BigInteger sub(BigInteger left, BigInteger right) {
-            return left.subtract(right);
-        }
-
-    }
-
-    public abstract static class DivNode extends ArithmeticNode {
-
-        @Specialization(rewriteOn = ArithmeticException.class)
-        int div(int left, int right) {
-            return left / right;
-        }
-
-        @Specialization
-        BigInteger div(BigInteger left, BigInteger right) {
-            return left.divide(right);
-        }
-    }
-
-    public abstract static class MulNode extends ArithmeticNode {
-
-        @Specialization(rewriteOn = ArithmeticException.class)
-        int mul(int left, int right) {
-            return ExactMath.multiplyExact(left, right);
-        }
-
-        @Specialization
-        BigInteger mul(BigInteger left, BigInteger right) {
-            return left.multiply(right);
-        }
-
-    }
-
-}
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/BigIntegerLiteralNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,48 +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.truffle.sl.nodes;
-
-import java.math.*;
-
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-
-public final class BigIntegerLiteralNode extends TypedNode {
-
-    private final BigInteger value;
-
-    public BigIntegerLiteralNode(BigInteger value) {
-        this.value = value;
-    }
-
-    @Override
-    public BigInteger executeBigInteger(VirtualFrame frame) throws UnexpectedResultException {
-        return value;
-    }
-
-    @Override
-    public Object executeGeneric(VirtualFrame frame) {
-        return value;
-    }
-
-}
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/BinaryNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,30 +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.truffle.sl.nodes;
-
-import com.oracle.truffle.api.dsl.*;
-
-@NodeChildren({@NodeChild("leftNode"), @NodeChild("rightNode")})
-public abstract class BinaryNode extends TypedNode {
-
-}
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/BlockNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,43 +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.truffle.sl.nodes;
-
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-
-public class BlockNode extends StatementNode {
-
-    @Children private final StatementNode[] statements;
-
-    public BlockNode(StatementNode[] statements) {
-        this.statements = adoptChildren(statements);
-    }
-
-    @Override
-    @ExplodeLoop
-    public void executeVoid(VirtualFrame frame) {
-        for (StatementNode statement : statements) {
-            statement.executeVoid(frame);
-        }
-    }
-}
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/BreakException.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,30 +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.truffle.sl.nodes;
-
-import com.oracle.truffle.api.nodes.*;
-
-public final class BreakException extends ControlFlowException {
-
-    private static final long serialVersionUID = -91013036379258890L;
-}
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/BreakNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +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.truffle.sl.nodes;
-
-import com.oracle.truffle.api.frame.*;
-
-public final class BreakNode extends StatementNode {
-
-    private final BreakException target;
-
-    public BreakNode(BreakException target) {
-        this.target = target;
-    }
-
-    @Override
-    public void executeVoid(VirtualFrame frame) {
-        throw target;
-    }
-}
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/CallNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,222 +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.truffle.sl.nodes;
-
-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.*;
-import com.oracle.truffle.sl.runtime.*;
-
-public abstract class CallNode extends TypedNode {
-
-    private static final int INLINE_CACHE_SIZE = 2;
-
-    @Child protected TypedNode functionNode;
-    @Child protected ArgumentsNode argumentsNode;
-
-    public CallNode(TypedNode functionNode, ArgumentsNode argumentsNode) {
-        this.functionNode = adoptChild(functionNode);
-        this.argumentsNode = adoptChild(argumentsNode);
-    }
-
-    @Override
-    public final Object executeGeneric(VirtualFrame frame) {
-        CallTarget function;
-        try {
-            function = functionNode.executeCallTarget(frame);
-        } catch (UnexpectedResultException e) {
-            throw new UnsupportedOperationException("Call to " + e.getMessage() + " not supported.");
-        }
-        Object[] arguments = argumentsNode.executeArray(frame);
-        return executeCall(frame, function, arguments);
-    }
-
-    public abstract Object executeCall(VirtualFrame frame, CallTarget function, Object[] arguments);
-
-    public static CallNode create(TypedNode function, TypedNode[] arguments) {
-        return new UninitializedCallNode(function, new ArgumentsNode(arguments), 0);
-    }
-
-    private static final class UninitializedCallNode extends CallNode {
-
-        protected final int depth;
-
-        UninitializedCallNode(TypedNode function, ArgumentsNode args, int depth) {
-            super(function, args);
-            this.depth = depth;
-        }
-
-        UninitializedCallNode(UninitializedCallNode copy) {
-            super(null, null);
-            this.depth = copy.depth + 1;
-        }
-
-        @Override
-        public Object executeCall(VirtualFrame frame, CallTarget function, Object[] arguments) {
-            CompilerDirectives.transferToInterpreter();
-            return specialize(function).executeCall(frame, function, arguments);
-        }
-
-        private CallNode specialize(CallTarget function) {
-            CompilerAsserts.neverPartOfCompilation();
-
-            if (depth < INLINE_CACHE_SIZE) {
-                DefaultCallTarget callTarget = (DefaultCallTarget) function;
-                FunctionRootNode root = (FunctionRootNode) callTarget.getRootNode();
-                CallNode next = new UninitializedCallNode(this);
-                InlinableDirectCallNode directCall = new InlinableDirectCallNode(functionNode, argumentsNode, next, callTarget);
-                replace(directCall);
-                if (root.isInlineImmediatly()) {
-                    return directCall.inlineImpl();
-                } else {
-                    return directCall;
-                }
-            } else {
-                CallNode topMost = (CallNode) NodeUtil.getNthParent(this, depth);
-                return topMost.replace(new GenericCallNode(topMost.functionNode, topMost.argumentsNode));
-            }
-        }
-
-    }
-
-    private abstract static class DirectCallNode extends CallNode {
-
-        protected final DefaultCallTarget cachedFunction;
-
-        @Child protected CallNode nextNode;
-
-        public DirectCallNode(TypedNode function, ArgumentsNode arguments, DefaultCallTarget cachedFunction, CallNode next) {
-            super(function, arguments);
-            this.cachedFunction = cachedFunction;
-            this.nextNode = adoptChild(next);
-        }
-
-        @Override
-        public Object executeCall(VirtualFrame frame, CallTarget function, Object[] arguments) {
-            if (this.cachedFunction == function) {
-                return executeCurrent(frame, arguments);
-            }
-            return nextNode.executeCall(frame, function, arguments);
-        }
-
-        protected abstract Object executeCurrent(VirtualFrame frame, Object[] arguments);
-
-    }
-
-    private static final class InlinableDirectCallNode extends DirectCallNode implements InlinableCallSite {
-
-        @CompilationFinal private int callCount;
-
-        InlinableDirectCallNode(TypedNode function, ArgumentsNode arguments, CallNode next, DefaultCallTarget cachedFunction) {
-            super(function, arguments, cachedFunction, next);
-        }
-
-        @Override
-        public Object executeCurrent(VirtualFrame frame, Object[] arguments) {
-            if (CompilerDirectives.inInterpreter()) {
-                callCount++;
-            }
-            return cachedFunction.call(frame.pack(), new SLArguments(arguments));
-        }
-
-        InlinedDirectCallNode inlineImpl() {
-            CompilerAsserts.neverPartOfCompilation();
-            RootNode root = cachedFunction.getRootNode();
-            TypedNode inlinedNode = ((FunctionRootNode) root).inline();
-            assert inlinedNode != null;
-            return replace(new InlinedDirectCallNode(this, inlinedNode), "Inlined " + root);
-        }
-
-        @Override
-        public boolean inline(FrameFactory factory) {
-            inlineImpl();
-            /* SL is always able to inline if required. */
-            return true;
-        }
-
-        @Override
-        public int getCallCount() {
-            return callCount;
-        }
-
-        @Override
-        public void resetCallCount() {
-            callCount = 0;
-        }
-
-        @Override
-        public Node getInlineTree() {
-            RootNode root = cachedFunction.getRootNode();
-            if (root instanceof FunctionRootNode) {
-                return ((FunctionRootNode) root).getUninitializedBody();
-            }
-            return null;
-        }
-
-        @Override
-        public CallTarget getCallTarget() {
-            return cachedFunction;
-        }
-
-    }
-
-    private static class InlinedDirectCallNode extends DirectCallNode implements InlinedCallSite {
-
-        private final FrameDescriptor descriptor;
-        @Child private TypedNode inlinedBody;
-
-        InlinedDirectCallNode(InlinableDirectCallNode prev, TypedNode inlinedBody) {
-            super(prev.functionNode, prev.argumentsNode, prev.cachedFunction, prev.nextNode);
-            this.descriptor = cachedFunction.getRootNode().getFrameDescriptor();
-            this.inlinedBody = adoptChild(inlinedBody);
-        }
-
-        @Override
-        public Object executeCurrent(VirtualFrame frame, Object[] arguments) {
-            SLArguments slArguments = new SLArguments(arguments);
-            VirtualFrame newFrame = Truffle.getRuntime().createVirtualFrame(frame.pack(), slArguments, descriptor);
-            return inlinedBody.executeGeneric(newFrame);
-        }
-
-        @Override
-        public CallTarget getCallTarget() {
-            return cachedFunction;
-        }
-
-    }
-
-    private static final class GenericCallNode extends CallNode {
-
-        GenericCallNode(TypedNode functionNode, ArgumentsNode arguments) {
-            super(functionNode, arguments);
-        }
-
-        @Override
-        public Object executeCall(VirtualFrame frame, CallTarget function, Object[] arguments) {
-            return function.call(frame.pack(), new SLArguments(arguments));
-        }
-    }
-
-}
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/ConditionNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,36 +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.truffle.sl.nodes;
-
-import com.oracle.truffle.api.frame.*;
-
-public abstract class ConditionNode extends StatementNode {
-
-    public abstract boolean executeCondition(VirtualFrame frame);
-
-    @Override
-    public void executeVoid(VirtualFrame frame) {
-        executeCondition(frame);
-    }
-
-}
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/ContinueException.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,30 +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.truffle.sl.nodes;
-
-import com.oracle.truffle.api.nodes.*;
-
-public final class ContinueException extends ControlFlowException {
-
-    private static final long serialVersionUID = 5329687983726237188L;
-}
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/ContinueNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +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.truffle.sl.nodes;
-
-import com.oracle.truffle.api.frame.*;
-
-public final class ContinueNode extends StatementNode {
-
-    private final ContinueException target;
-
-    public ContinueNode(ContinueException target) {
-        this.target = target;
-    }
-
-    @Override
-    public void executeVoid(VirtualFrame frame) {
-        throw target;
-    }
-}
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/FrameSlotNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,35 +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.truffle.sl.nodes;
-
-import com.oracle.truffle.api.frame.*;
-
-public abstract class FrameSlotNode extends TypedNode {
-
-    protected final FrameSlot slot;
-
-    public FrameSlotNode(FrameSlot slot) {
-        this.slot = slot;
-    }
-
-}
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/FunctionBodyNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,78 +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.truffle.sl.nodes;
-
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-
-public class FunctionBodyNode extends TypedNode {
-
-    @Child private StatementNode body;
-    @Child private TypedNode returnValue;
-    @Child private StatementNode writeArguments;
-
-    private FrameDescriptor frameDescriptor;
-
-    public FunctionBodyNode(FrameDescriptor frameDescriptor, StatementNode body, TypedNode returnValue, String[] parameterNames) {
-        this.frameDescriptor = frameDescriptor;
-        this.body = adoptChild(body);
-        this.returnValue = adoptChild(returnValue);
-        this.writeArguments = adoptChild(new BlockNode(createWriteArguments(parameterNames)));
-    }
-
-    @Override
-    public Object executeGeneric(VirtualFrame frame) {
-        writeArguments.executeVoid(frame);
-        try {
-            body.executeVoid(frame);
-        } catch (ReturnException ex) {
-            // Nothing to do, we just need to return.
-        }
-        if (returnValue != null) {
-            return returnValue.executeGeneric(frame);
-        } else {
-            return null;
-        }
-    }
-
-    @Override
-    public Node copy() {
-        FunctionBodyNode copy = (FunctionBodyNode) super.copy();
-        copy.frameDescriptor = frameDescriptor.shallowCopy();
-        return copy;
-    }
-
-    private StatementNode[] createWriteArguments(String[] parameterNames) {
-        StatementNode[] writeNodes = new StatementNode[parameterNames.length];
-        for (int i = 0; i < parameterNames.length; i++) {
-            FrameSlot frameSlot = frameDescriptor.findOrAddFrameSlot(parameterNames[i]);
-            writeNodes[i] = WriteLocalNodeFactory.create(frameSlot, new ReadArgumentNode(i));
-        }
-        return writeNodes;
-    }
-
-    public FrameDescriptor getFrameDescriptor() {
-        return frameDescriptor;
-    }
-
-}
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/FunctionRootNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,91 +0,0 @@
-/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.sl.nodes;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.dsl.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.sl.builtins.*;
-import com.oracle.truffle.sl.runtime.*;
-
-public final class FunctionRootNode extends RootNode {
-
-    @Child private TypedNode body;
-
-    private final TypedNode uninitializedBody;
-    private final String name;
-    private final boolean inlineImmediatly;
-
-    private FunctionRootNode(FrameDescriptor frameDescriptor, TypedNode body, String name, boolean inlineImmediatly) {
-        super(null, frameDescriptor);
-        this.uninitializedBody = NodeUtil.cloneNode(body);
-        this.body = adoptChild(body);
-        this.name = name;
-        this.inlineImmediatly = inlineImmediatly;
-    }
-
-    public static CallTarget createBuiltin(SLContext context, NodeFactory<? extends BuiltinNode> factory, String name) {
-        int argumentCount = factory.getExecutionSignature().size();
-        TypedNode[] arguments = new TypedNode[argumentCount];
-        for (int i = 0; i < arguments.length; i++) {
-            arguments[i] = new ReadArgumentNode(i);
-        }
-        BuiltinNode buitinBody = factory.createNode(arguments, context);
-        FunctionRootNode root = new FunctionRootNode(new FrameDescriptor(), buitinBody, name, true);
-        return Truffle.getRuntime().createCallTarget(root);
-    }
-
-    public static CallTarget createFunction(StatementNode body, FrameDescriptor frameDescriptor, String name, TypedNode returnValue, String[] parameterNames) {
-        FunctionBodyNode bodyContainer = new FunctionBodyNode(frameDescriptor, body, returnValue, parameterNames);
-        FunctionRootNode root = new FunctionRootNode(frameDescriptor, bodyContainer, name, false);
-        return Truffle.getRuntime().createCallTarget(root);
-    }
-
-    @Override
-    public Object execute(VirtualFrame frame) {
-        return body.executeGeneric(frame);
-    }
-
-    public boolean isInlineImmediatly() {
-        return inlineImmediatly;
-    }
-
-    public TypedNode inline() {
-        return NodeUtil.cloneNode(uninitializedBody);
-    }
-
-    public Node getUninitializedBody() {
-        return uninitializedBody;
-    }
-
-    @Override
-    public String toString() {
-        return "function " + name;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-}
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/IfNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,60 +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.truffle.sl.nodes;
-
-import com.oracle.truffle.api.dsl.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.utilities.*;
-
-@NodeChild(value = "conditionNode", type = ConditionNode.class)
-public abstract class IfNode extends StatementNode {
-
-    @Child private StatementNode thenPartNode;
-    @Child private StatementNode elsePartNode;
-
-    private final BranchProfile ifBranch = new BranchProfile();
-    private final BranchProfile elseBranch = new BranchProfile();
-
-    public IfNode(StatementNode thenPart, StatementNode elsePart) {
-        this.thenPartNode = adoptChild(thenPart);
-        this.elsePartNode = adoptChild(elsePart);
-    }
-
-    protected IfNode(IfNode node) {
-        this(node.thenPartNode, node.elsePartNode);
-    }
-
-    @Specialization
-    public void doVoid(VirtualFrame frame, boolean condition) {
-        if (condition) {
-            ifBranch.enter();
-            thenPartNode.executeVoid(frame);
-        } else {
-            if (elsePartNode != null) {
-                elseBranch.enter();
-                elsePartNode.executeVoid(frame);
-            }
-        }
-    }
-
-}
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/IntegerLiteralNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,45 +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.truffle.sl.nodes;
-
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-
-public final class IntegerLiteralNode extends TypedNode {
-
-    private final int value;
-
-    public IntegerLiteralNode(int value) {
-        this.value = value;
-    }
-
-    @Override
-    public int executeInteger(VirtualFrame frame) throws UnexpectedResultException {
-        return value;
-    }
-
-    @Override
-    public Object executeGeneric(VirtualFrame frame) {
-        return value;
-    }
-}
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/LessThanNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,45 +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.truffle.sl.nodes;
-
-import java.math.*;
-
-import com.oracle.truffle.api.dsl.*;
-
-public abstract class LessThanNode extends BinaryNode {
-
-    @Specialization
-    public boolean doInteger(int left, int right) {
-        return left < right;
-    }
-
-    @Specialization
-    public boolean doBigInteger(BigInteger left, BigInteger right) {
-        return left.compareTo(right) < 0;
-    }
-
-    @Specialization(guards = "isString")
-    public boolean doString(Object left, Object right) {
-        return left.toString().compareTo(right.toString()) < 0;
-    }
-}
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/LogicalAndNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,49 +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.truffle.sl.nodes;
-
-import com.oracle.truffle.api.dsl.*;
-
-@SuppressWarnings("unused")
-public abstract class LogicalAndNode extends BinaryNode {
-
-    @ShortCircuit("rightNode")
-    public boolean needsRightNode(boolean left) {
-        return left;
-    }
-
-    @ShortCircuit("rightNode")
-    public boolean needsRightNode(Object left) {
-        return left instanceof Boolean && (Boolean) left;
-    }
-
-    @Specialization
-    public boolean doBoolean(boolean left, boolean hasRight, boolean right) {
-        return hasRight && right;
-    }
-
-    @Generic
-    public Object doGeneric(Object left, boolean hasRight, Object right) {
-        throw new RuntimeException("operation not defined for type " + left.getClass().getSimpleName());
-    }
-}
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/NullLiteralNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,40 +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.truffle.sl.nodes;
-
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.sl.runtime.*;
-
-public final class NullLiteralNode extends TypedNode {
-
-    @Override
-    public Object executeGeneric(VirtualFrame frame) {
-        return executeNull(frame);
-    }
-
-    @Override
-    public SLNull executeNull(VirtualFrame frame) {
-        return SLNull.INSTANCE;
-    }
-
-}
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/ReadArgumentNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +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.truffle.sl.nodes;
-
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.utilities.*;
-import com.oracle.truffle.sl.runtime.*;
-
-public class ReadArgumentNode extends TypedNode {
-
-    private final int index;
-
-    private final BranchProfile outOfBounds = new BranchProfile();
-    private final BranchProfile inBounds = new BranchProfile();
-
-    public ReadArgumentNode(int index) {
-        this.index = index;
-    }
-
-    @Override
-    public Object executeGeneric(VirtualFrame frame) {
-        Object[] args = SLArguments.get(frame).arguments;
-        if (index < args.length) {
-            inBounds.enter();
-            return args[index];
-        } else {
-            outOfBounds.enter();
-            return SLNull.INSTANCE;
-        }
-    }
-
-}
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/ReadFunctionNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,56 +0,0 @@
-/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.sl.nodes;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.utilities.*;
-import com.oracle.truffle.sl.runtime.*;
-
-public final class ReadFunctionNode extends TypedNode {
-
-    private final SLFunctionRegistry registry;
-    private final String name;
-    private final BranchProfile invalidFunction = new BranchProfile();
-
-    public ReadFunctionNode(SLFunctionRegistry registry, String name) {
-        this.registry = registry;
-        this.name = name;
-    }
-
-    @Override
-    public Object executeGeneric(VirtualFrame frame) {
-        return executeCallTarget(frame);
-    }
-
-    @Override
-    public CallTarget executeCallTarget(VirtualFrame frame) {
-        CallTarget target = registry.lookup(name);
-        if (target != null) {
-            return target;
-        }
-        invalidFunction.enter();
-        throw new RuntimeException("Function with name '" + name + "' not found.");
-    }
-
-}
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/ReadLocalNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,59 +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.truffle.sl.nodes;
-
-import com.oracle.truffle.api.dsl.*;
-import com.oracle.truffle.api.frame.*;
-
-@PolymorphicLimit(1)
-public abstract class ReadLocalNode extends FrameSlotNode {
-
-    public ReadLocalNode(FrameSlot slot) {
-        super(slot);
-    }
-
-    public ReadLocalNode(ReadLocalNode specialized) {
-        this(specialized.slot);
-    }
-
-    @Specialization(rewriteOn = {FrameSlotTypeException.class})
-    public int doInteger(VirtualFrame frame) throws FrameSlotTypeException {
-        return frame.getInt(slot);
-    }
-
-    @Specialization(rewriteOn = {FrameSlotTypeException.class})
-    public boolean doBoolean(VirtualFrame frame) throws FrameSlotTypeException {
-        return frame.getBoolean(slot);
-    }
-
-    @Specialization(rewriteOn = {FrameSlotTypeException.class})
-    public Object doObject(VirtualFrame frame) throws FrameSlotTypeException {
-        return frame.getObject(slot);
-    }
-
-    @Generic
-    public Object doGeneric(VirtualFrame frame) {
-        return frame.getValue(slot);
-    }
-
-}
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/ReadUninitializedNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,56 +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.truffle.sl.nodes;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.sl.runtime.*;
-
-public class ReadUninitializedNode extends TypedNode {
-
-    private final SLContext context;
-    private final FrameSlot slot;
-
-    public ReadUninitializedNode(SLContext context, FrameSlot slot) {
-        this.context = context;
-        this.slot = slot;
-    }
-
-    public FrameSlot getSlot() {
-        return slot;
-    }
-
-    @Override
-    public Object executeGeneric(VirtualFrame frame) {
-        CompilerDirectives.transferToInterpreter();
-        Object result = frame.getValue(slot);
-        String identifier = (String) slot.getIdentifier();
-        if (result == null) {
-            // function access
-            return replace(new ReadFunctionNode(context.getFunctionRegistry(), identifier)).executeGeneric(frame);
-        } else {
-            // local variable access
-            return replace(ReadLocalNodeFactory.create(slot)).executeGeneric(frame);
-        }
-    }
-}
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/ReturnException.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,30 +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.truffle.sl.nodes;
-
-import com.oracle.truffle.api.nodes.*;
-
-public final class ReturnException extends ControlFlowException {
-
-    private static final long serialVersionUID = 4073191346281369231L;
-}
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/ReturnNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,42 +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.truffle.sl.nodes;
-
-import com.oracle.truffle.api.frame.*;
-
-public class ReturnNode extends StatementNode {
-
-    private static final ReturnException EXCEPTION = new ReturnException();
-
-    @Child private StatementNode expr;
-
-    public ReturnNode(StatementNode expr) {
-        this.expr = adoptChild(expr);
-    }
-
-    @Override
-    public void executeVoid(VirtualFrame frame) {
-        expr.executeVoid(frame);
-        throw EXCEPTION;
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/SLBinaryNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,34 @@
+/*
+ * 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.nodes;
+
+import com.oracle.truffle.api.dsl.*;
+
+/**
+ * Utility base class for operations that take two arguments (per convention called "left" and
+ * "right"). For concrete subclasses of this class, the Truffle DSL creates two child fields, and
+ * the necessary constructors and logic to set them.
+ */
+@NodeChildren({@NodeChild("leftNode"), @NodeChild("rightNode")})
+public abstract class SLBinaryNode extends SLExpressionNode {
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/SLExpressionNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,84 @@
+/*
+ * 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.nodes;
+
+import java.math.*;
+
+import com.oracle.truffle.api.dsl.*;
+import com.oracle.truffle.api.frame.*;
+import com.oracle.truffle.api.nodes.*;
+import com.oracle.truffle.sl.runtime.*;
+
+/**
+ * Base class for all SL nodes that produce a value and therefore benefit from type specialization.
+ * The annotation {@Link TypeSystemReference} specifies the SL types. Specifying it here
+ * defines the type system for all subclasses.
+ */
+@TypeSystemReference(SLTypes.class)
+public abstract class SLExpressionNode extends SLStatementNode {
+
+    /**
+     * The execute method when no specialization is possible. This is the most general case,
+     * therefore it must be provided by all subclasses.
+     */
+    public abstract Object executeGeneric(VirtualFrame frame);
+
+    /**
+     * When we use an expression at places where a {@SLStatmentNode statement} is
+     * already sufficient, the return value is just discarded.
+     */
+    @Override
+    public void executeVoid(VirtualFrame frame) {
+        executeGeneric(frame);
+    }
+
+    /*
+     * Execute methods for specialized types. They all follow the same pattern: they call the
+     * generic execution method and then expect a result of their return type. Type-specialized
+     * subclasses overwrite the appropriate methods.
+     */
+
+    public long executeLong(VirtualFrame frame) throws UnexpectedResultException {
+        return SLTypesGen.SLTYPES.expectLong(executeGeneric(frame));
+    }
+
+    public BigInteger executeBigInteger(VirtualFrame frame) throws UnexpectedResultException {
+        return SLTypesGen.SLTYPES.expectBigInteger(executeGeneric(frame));
+    }
+
+    public boolean executeBoolean(VirtualFrame frame) throws UnexpectedResultException {
+        return SLTypesGen.SLTYPES.expectBoolean(executeGeneric(frame));
+    }
+
+    public String executeString(VirtualFrame frame) throws UnexpectedResultException {
+        return SLTypesGen.SLTYPES.expectString(executeGeneric(frame));
+    }
+
+    public SLFunction executeFunction(VirtualFrame frame) throws UnexpectedResultException {
+        return SLTypesGen.SLTYPES.expectSLFunction(executeGeneric(frame));
+    }
+
+    public SLNull executeNull(VirtualFrame frame) throws UnexpectedResultException {
+        return SLTypesGen.SLTYPES.expectSLNull(executeGeneric(frame));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/SLRootNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,78 @@
+/*
+ * 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.nodes;
+
+import com.oracle.truffle.api.frame.*;
+import com.oracle.truffle.api.nodes.*;
+import com.oracle.truffle.sl.builtins.*;
+import com.oracle.truffle.sl.nodes.controlflow.*;
+
+/**
+ * The root of all SL execution trees. It is a Truffle requirement that the tree root extends the
+ * class {@link RootNode}. This class is used for both builtin and user-defined functions. For
+ * builtin functions, the {@link #bodyNode} is a subclass of {@link SLBuiltinNode}. For user-defined
+ * functions, the {@link #bodyNode} is a {@link SLFunctionBodyNode}.
+ */
+public final class SLRootNode extends RootNode {
+
+    /** The function body that is executed, and specialized during execution. */
+    @Child private SLExpressionNode bodyNode;
+
+    /**
+     * A copy of the uninitialized body. When performing method inlining, it is beneficial to inline
+     * the unspecialized function body, so that it is specialized in the context of the caller. This
+     * makes the specializations of the inlined function more precise.
+     */
+    private final SLExpressionNode uninitializedBodyNode;
+
+    /** The name of the function, for printing purposes only. */
+    private final String name;
+
+    public SLRootNode(FrameDescriptor frameDescriptor, SLExpressionNode bodyNode, String name) {
+        super(null, frameDescriptor);
+        /* Deep copy the body before any specialization occurs during execution. */
+        this.uninitializedBodyNode = NodeUtil.cloneNode(bodyNode);
+        this.bodyNode = adoptChild(bodyNode);
+        this.name = name;
+    }
+
+    @Override
+    public Object execute(VirtualFrame frame) {
+        return bodyNode.executeGeneric(frame);
+    }
+
+    @Override
+    public boolean isSplittable() {
+        return true;
+    }
+
+    @Override
+    public RootNode split() {
+        return new SLRootNode(getFrameDescriptor().shallowCopy(), NodeUtil.cloneNode(uninitializedBodyNode), name);
+    }
+
+    @Override
+    public String toString() {
+        return "root " + name;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/SLStatementNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,39 @@
+/*
+ * 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.nodes;
+
+import com.oracle.truffle.api.frame.*;
+import com.oracle.truffle.api.nodes.*;
+
+/**
+ * The base class of all Truffle nodes for SL. All nodes (even expressions) can be used as
+ * statements, i.e., without returning a value. The {@link VirtualFrame} provides access to the
+ * local variables.
+ */
+public abstract class SLStatementNode extends Node {
+
+    /**
+     * Execute this node as as statement, where no return value is necessary.
+     */
+    public abstract void executeVoid(VirtualFrame frame);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/SLTypes.java	Wed Mar 05 19:40:15 2014 -0800
@@ -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.truffle.sl.nodes;
+
+import java.math.*;
+
+import com.oracle.truffle.api.dsl.*;
+import com.oracle.truffle.sl.*;
+import com.oracle.truffle.sl.runtime.*;
+
+/**
+ * The type system of SL, as explained in {@link SLMain}. Based on the {@link TypeSystem}
+ * annotation, the Truffle DSL generates the subclass {@link SLTypesGen} with type test and type
+ * conversion methods for all types. In this class, we only cover types where the automatically
+ * generated ones would not be sufficient.
+ */
+@TypeSystem({long.class, BigInteger.class, boolean.class, String.class, SLFunction.class, SLNull.class})
+public abstract class SLTypes {
+
+    /**
+     * Example of a manually specified type check that replaces the automatically generated type
+     * check that the Truffle DSL would generate. For {@link SLNull}, we do not need an
+     * {@code instanceof} check, because we know that there is only a {@link SLNull#SINGLETON
+     * singleton} instance.
+     */
+    @TypeCheck
+    public boolean isSLNull(Object value) {
+        return value == SLNull.SINGLETON;
+    }
+
+    /**
+     * Example of a manually specified type cast that replaces the automatically generated type cast
+     * that the Truffle DSL would generate. For {@link SLNull}, we do not need an actual cast,
+     * because we know that there is only a {@link SLNull#SINGLETON singleton} instance.
+     */
+    @TypeCast
+    public SLNull asSLNull(Object value) {
+        assert isSLNull(value);
+        return SLNull.SINGLETON;
+    }
+
+    /**
+     * Informs the Truffle DSL that a primitive {@code long} value can be used in all
+     * specializations where a {@link BigInteger} is expected. This models the semantic of SL: It
+     * only has an arbitrary precision Number type (implemented as {@link BigInteger}, and
+     * {@code long} is only used as a performance optimization to avoid the costly
+     * {@link BigInteger} arithmetic for values that fit into a 64-bit primitive value.
+     */
+    @ImplicitCast
+    public BigInteger castBigInteger(long value) {
+        return BigInteger.valueOf(value);
+    }
+}
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/StatementNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,32 +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.truffle.sl.nodes;
-
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.sl.*;
-
-public abstract class StatementNode extends SLNode {
-
-    public abstract void executeVoid(VirtualFrame frame);
-
-}
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/StringLiteralNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,45 +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.truffle.sl.nodes;
-
-import com.oracle.truffle.api.frame.*;
-
-public final class StringLiteralNode extends TypedNode {
-
-    private final String value;
-
-    public StringLiteralNode(String value) {
-        this.value = value;
-    }
-
-    @Override
-    public String executeString(VirtualFrame frame) {
-        return value;
-    }
-
-    @Override
-    public Object executeGeneric(VirtualFrame frame) {
-        return value;
-    }
-
-}
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/TernaryNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,57 +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.truffle.sl.nodes;
-
-import java.math.*;
-
-import com.oracle.truffle.api.dsl.*;
-
-@SuppressWarnings("unused")
-@NodeChildren({@NodeChild(value = "conditionNode", type = ConditionNode.class), @NodeChild("ifPartNode"), @NodeChild("elsePartNode")})
-public abstract class TernaryNode extends TypedNode {
-
-    @ShortCircuit("ifPartNode")
-    public boolean needsIfPart(boolean condition) {
-        return condition;
-    }
-
-    @ShortCircuit("elsePartNode")
-    public boolean needsElsePart(boolean condition, boolean hasIfPart, Object ifPart) {
-        return !hasIfPart;
-    }
-
-    @Specialization
-    public int doInteger(boolean condition, boolean hasIfPart, int ifPart, boolean hasElsePart, int elsePart) {
-        return hasIfPart ? ifPart : elsePart;
-    }
-
-    @Specialization
-    public BigInteger doBigInteger(boolean condition, boolean hasIfPart, BigInteger ifPart, boolean hasElsePart, BigInteger elsePart) {
-        return hasIfPart ? ifPart : elsePart;
-    }
-
-    @Specialization
-    public Object doObject(boolean condition, boolean hasIfPart, Object ifPart, boolean hasElsePart, Object elsePart) {
-        return hasIfPart ? ifPart : elsePart;
-    }
-}
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/TypedNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,83 +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.truffle.sl.nodes;
-
-import java.math.*;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.sl.*;
-import com.oracle.truffle.sl.runtime.*;
-
-public abstract class TypedNode extends ConditionNode {
-
-    @Override
-    public final boolean executeCondition(VirtualFrame frame) {
-        try {
-            return executeBoolean(frame);
-        } catch (UnexpectedResultException ex) {
-            throw new RuntimeException("Illegal type for condition: " + ex.getResult().getClass().getSimpleName());
-        }
-    }
-
-    public abstract Object executeGeneric(VirtualFrame frame);
-
-    public boolean executeBoolean(VirtualFrame frame) throws UnexpectedResultException {
-        return SLTypesGen.SLTYPES.expectBoolean(executeGeneric(frame));
-    }
-
-    public int executeInteger(VirtualFrame frame) throws UnexpectedResultException {
-        return SLTypesGen.SLTYPES.expectInteger(executeGeneric(frame));
-    }
-
-    public BigInteger executeBigInteger(VirtualFrame frame) throws UnexpectedResultException {
-        return SLTypesGen.SLTYPES.expectBigInteger(executeGeneric(frame));
-    }
-
-    public String executeString(VirtualFrame frame) throws UnexpectedResultException {
-        return SLTypesGen.SLTYPES.expectString(executeGeneric(frame));
-    }
-
-    public CallTarget executeCallTarget(VirtualFrame frame) throws UnexpectedResultException {
-        return SLTypesGen.SLTYPES.expectCallTarget(executeGeneric(frame));
-    }
-
-    public Object[] executeArray(VirtualFrame frame) throws UnexpectedResultException {
-        return SLTypesGen.SLTYPES.expectObjectArray(executeGeneric(frame));
-    }
-
-    public SLNull executeNull(VirtualFrame frame) throws UnexpectedResultException {
-        return SLTypesGen.SLTYPES.expectSLNull(executeGeneric(frame));
-    }
-
-    @Override
-    public final void executeVoid(VirtualFrame frame) {
-        executeGeneric(frame);
-    }
-
-    public boolean isString(Object a, Object b) {
-        return a instanceof String || b instanceof String;
-    }
-
-}
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/WhileNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,74 +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.truffle.sl.nodes;
-
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.utilities.*;
-
-public class WhileNode extends StatementNode {
-
-    @Child private ConditionNode condition;
-
-    @Child private StatementNode body;
-
-    private final BreakException breakTarget;
-    private final ContinueException continueTarget;
-
-    private final BranchProfile continueMismatch = new BranchProfile();
-    private final BranchProfile continueMatch = new BranchProfile();
-    private final BranchProfile breakMismatch = new BranchProfile();
-    private final BranchProfile breakMatch = new BranchProfile();
-
-    public WhileNode(ConditionNode condition, StatementNode body) {
-        this.condition = adoptChild(condition);
-        this.body = adoptChild(body);
-
-        this.breakTarget = new BreakException();
-        this.continueTarget = new ContinueException();
-    }
-
-    @Override
-    public void executeVoid(VirtualFrame frame) {
-        try {
-            while (condition.executeCondition(frame)) {
-                try {
-                    body.executeVoid(frame);
-                } catch (ContinueException ex) {
-                    if (ex != continueTarget) {
-                        continueMismatch.enter();
-                        throw ex;
-                    }
-                    continueMatch.enter();
-                    // Fall through to next loop iteration.
-                }
-            }
-        } catch (BreakException ex) {
-            if (ex != breakTarget) {
-                breakMismatch.enter();
-                throw ex;
-            }
-            breakMatch.enter();
-            // Done executing this loop, exit method to execute statement following the loop.
-        }
-    }
-}
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/WriteLocalNode.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,87 +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.truffle.sl.nodes;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.dsl.*;
-import com.oracle.truffle.api.frame.*;
-
-@NodeChild(value = "rightNode", type = TypedNode.class)
-public abstract class WriteLocalNode extends FrameSlotNode {
-
-    public WriteLocalNode(FrameSlot slot) {
-        super(slot);
-    }
-
-    public WriteLocalNode(WriteLocalNode node) {
-        this(node.slot);
-    }
-
-    @Specialization(guards = "isIntKind")
-    public int write(VirtualFrame frame, int right) {
-        frame.setInt(slot, right);
-        return right;
-    }
-
-    @Specialization(guards = "isBooleanKind")
-    public boolean write(VirtualFrame frame, boolean right) {
-        frame.setBoolean(slot, right);
-        return right;
-    }
-
-    @Specialization(guards = "isObjectKind")
-    public Object writeGeneric(VirtualFrame frame, Object right) {
-        frame.setObject(slot, right);
-        return right;
-    }
-
-    protected final boolean isIntKind() {
-        return isKind(FrameSlotKind.Int);
-    }
-
-    protected final boolean isBooleanKind() {
-        return isKind(FrameSlotKind.Boolean);
-    }
-
-    protected final boolean isObjectKind() {
-        if (slot.getKind() != FrameSlotKind.Object) {
-            CompilerDirectives.transferToInterpreter();
-            slot.setKind(FrameSlotKind.Object);
-        }
-        return true;
-    }
-
-    private boolean isKind(FrameSlotKind kind) {
-        return slot.getKind() == kind || initialSetKind(kind);
-    }
-
-    private boolean initialSetKind(FrameSlotKind kind) {
-        if (slot.getKind() == FrameSlotKind.Illegal) {
-            CompilerDirectives.transferToInterpreter();
-            slot.setKind(kind);
-            return true;
-        }
-        return false;
-    }
-
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/call/SLAbstractDispatchNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,53 @@
+/*
+ * 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.truffle.sl.nodes.call;
+
+import com.oracle.truffle.api.frame.*;
+import com.oracle.truffle.api.nodes.*;
+import com.oracle.truffle.sl.runtime.*;
+
+/**
+ * Before a call is executed the first time, the dispatch node is a
+ * {@link SLUninitializedDispatchNode}. During execution, the call is optimized using a polymorphic
+ * inline cache, i.e., a chain of {@link SLDirectDispatchNode}s. The chain is terminated by a
+ * {@link SLUninitializedDispatchNode}. If the chain gets too long (longer than
+ * {@link #INLINE_CACHE_SIZE}), i.e., if the call is too polymorphic, the whole chain is replaced by
+ * a single {@link SLGenericDispatchNode}. All this rewriting happens on runtime, based on profiling
+ * feedback of the actual execution.
+ * <p>
+ * Example of the chain of nodes ({@code I}: {@link SLInvokeNode}; {@code U}:
+ * {@link SLUninitializedDispatchNode}; {@code D}: {@link SLDirectDispatchNode}; {@code G}:
+ * {@link SLGenericDispatchNode}):
+ * <ol>
+ * <li>After parsing: {@code I->U}
+ * <li>After execution of function {@code f1}: {@code I->D(f1)->U}
+ * <li>After execution of function {@code f2}: {@code I->D(f1)->D(f2)->U}
+ * <li>After execution of function {@code f3}: {@code I->G}
+ * </ol>
+ * */
+public abstract class SLAbstractDispatchNode extends Node {
+
+    protected static final int INLINE_CACHE_SIZE = 2;
+
+    protected abstract Object executeDispatch(VirtualFrame frame, SLFunction function, SLArguments arguments);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/call/SLDirectDispatchNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,112 @@
+/*
+ * 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.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.*;
+
+/**
+ * An entry in the polymorphic inline cache.
+ */
+final class SLDirectDispatchNode extends SLAbstractDispatchNode {
+
+    /** The cached function. */
+    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
+     * inlined, i.e., the call node is replaced with a copy of the callee's AST.
+     */
+    @Child private CallNode callCachedTargetNode;
+
+    /** Assumption that the {@link #callCachedTargetNode} is still valid. */
+    private final Assumption cachedTargetStable;
+
+    /**
+     * The next entry of the polymorphic inline cache, either another {@link SLDirectDispatchNode}
+     * or a {@link SLUninitializedDispatchNode}.
+     */
+    @Child private SLAbstractDispatchNode nextNode;
+
+    protected SLDirectDispatchNode(SLAbstractDispatchNode next, SLFunction cachedFunction) {
+        this.cachedFunction = cachedFunction;
+        this.callCachedTargetNode = adoptChild(Truffle.getRuntime().createCallNode(cachedFunction.getCallTarget()));
+        this.cachedTargetStable = cachedFunction.getCallTargetStable();
+        this.nextNode = adoptChild(next);
+    }
+
+    /**
+     * Perform the inline cache check. If it succeeds, execute the cached
+     * {@link #cachedTargetStable call target}; if it fails, defer to the next element in the chain.
+     * <p>
+     * Since SL is a quite simple language, the benefit of the inline cache is quite small: after
+     * checking that the actual function to be executed is the same as the
+     * {@link SLDirectDispatchNode#cachedFunction}, we can safely execute the cached call target.
+     * You can reasonably argue that caching the call target is overkill, since we could just
+     * retrieve it via {@code function.getCallTarget()}. However, in a more complex language the
+     * lookup of the call target is usually much more complicated than in SL. In addition, caching
+     * the call target allows method inlining.
+     */
+    @Override
+    protected Object executeDispatch(VirtualFrame frame, SLFunction function, SLArguments arguments) {
+        /*
+         * The inline cache check. Note that cachedFunction must be a final field so that the
+         * compiler can optimize the check.
+         */
+        if (this.cachedFunction == function) {
+            /* Inline cache hit, we are safe to execute the cached call target. */
+            try {
+                /*
+                 * Support for function redefinition: When a function is redefined, the call target
+                 * maintained by the SLFunction object is change. To avoid a check for that, we use
+                 * an Assumption that is invalidated by the SLFunction when the change is performed.
+                 * Since checking an assumption is a no-op in compiled code, the line below does not
+                 * add any overhead during optimized execution.
+                 */
+                cachedTargetStable.check();
+
+                /*
+                 * 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(frame.pack(), arguments);
+
+            } catch (InvalidAssumptionException ex) {
+                /*
+                 * The function has been redefined. Remove ourself from the polymorphic inline
+                 * cache, so that we fail the check only once. Note that this replacement has subtle
+                 * semantics: we are changing a node in the tree that is currently executed. This is
+                 * only safe because we know that after the call to replace(), there is no more code
+                 * that requires that this node is part of the tree.
+                 */
+                replace(nextNode);
+                /* Execute the next node in the chain by falling out of the if block. */
+            }
+        }
+        /* Inline cache miss, defer to the next element in the chain. */
+        return nextNode.executeDispatch(frame, function, arguments);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/call/SLGenericDispatchNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -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.truffle.sl.nodes.call;
+
+import com.oracle.truffle.api.frame.*;
+import com.oracle.truffle.sl.runtime.*;
+
+/**
+ * Slow-path code for a call, used when the polymorphic inline cache exceeded its maximum size. Such
+ * calls are not optimized any further, e.g., no method inlining is performed.
+ */
+final class SLGenericDispatchNode extends SLAbstractDispatchNode {
+
+    @Override
+    protected Object executeDispatch(VirtualFrame frame, SLFunction function, SLArguments arguments) {
+        /*
+         * SL has a quite simple call lookup: just ask the function for the current call target, and
+         * call it.
+         */
+        return function.getCallTarget().call(frame.pack(), arguments);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/call/SLInvokeNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,94 @@
+/*
+ * 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.truffle.sl.nodes.call;
+
+import com.oracle.truffle.api.*;
+import com.oracle.truffle.api.dsl.*;
+import com.oracle.truffle.api.frame.*;
+import com.oracle.truffle.api.nodes.*;
+import com.oracle.truffle.sl.nodes.*;
+import com.oracle.truffle.sl.runtime.*;
+
+/**
+ * The node for function invocation in SL. Since SL has first class functions, the
+ * {@link SLFunction target function} can be computed by an {@link #functionNode arbitrary
+ * expression}. This node is responsible for evaluating this expression, as well as evaluating the
+ * {@link #argumentNodes arguments}. The actual dispatch is then delegated to a chain of
+ * {@link SLAbstractDispatchNode}s that form a polymorphic inline cache.
+ */
+@NodeInfo(shortName = "invoke")
+public final class SLInvokeNode extends SLExpressionNode {
+
+    public static SLInvokeNode create(SLExpressionNode function, SLExpressionNode[] arguments) {
+        return new SLInvokeNode(function, arguments, new SLUninitializedDispatchNode());
+    }
+
+    @Child protected SLExpressionNode functionNode;
+    @Children protected final SLExpressionNode[] argumentNodes;
+    @Child protected SLAbstractDispatchNode dispatchNode;
+
+    private SLInvokeNode(SLExpressionNode functionNode, SLExpressionNode[] argumentNodes, SLAbstractDispatchNode dispatchNode) {
+        this.functionNode = adoptChild(functionNode);
+        this.argumentNodes = adoptChildren(argumentNodes);
+        this.dispatchNode = adoptChild(dispatchNode);
+    }
+
+    @Override
+    @ExplodeLoop
+    public Object executeGeneric(VirtualFrame frame) {
+        SLFunction function = evaluateFunction(frame);
+
+        /*
+         * The number of arguments is constant for one invoke node. During compilation, the loop is
+         * unrolled and the execute methods of all arguments are inlined. This is triggered by the
+         * ExplodeLoop annotation on the method. The compiler assertion below illustrates that the
+         * array length is really constant.
+         */
+        CompilerAsserts.compilationConstant(argumentNodes.length);
+
+        Object[] argumentValues = new Object[argumentNodes.length];
+        for (int i = 0; i < argumentNodes.length; i++) {
+            argumentValues[i] = argumentNodes[i].executeGeneric(frame);
+        }
+        SLArguments arguments = new SLArguments(argumentValues);
+
+        return dispatchNode.executeDispatch(frame, function, arguments);
+    }
+
+    private SLFunction evaluateFunction(VirtualFrame frame) {
+        try {
+            /*
+             * The function node must evaluate to a SLFunction value, so we call
+             * function-specialized method.
+             */
+            return functionNode.executeFunction(frame);
+        } catch (UnexpectedResultException ex) {
+            /*
+             * The function node evaluated to a non-function result. This is a type error in the SL
+             * program. We report it with the same exception that Truffle DSL generated nodes use to
+             * report type errors.
+             */
+            throw new UnsupportedSpecializationException(this, new Node[]{functionNode}, ex.getResult());
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/call/SLUninitializedDispatchNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -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.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 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.nodes.call;
+
+import com.oracle.truffle.api.*;
+import com.oracle.truffle.api.frame.*;
+import com.oracle.truffle.api.nodes.*;
+import com.oracle.truffle.sl.*;
+import com.oracle.truffle.sl.runtime.*;
+
+/**
+ * The last entry of a polymorphic inline cache.
+ */
+final class SLUninitializedDispatchNode extends SLAbstractDispatchNode {
+
+    /**
+     * When we reach this method, all the previous cache entries did not match the function. If the
+     * cache is still small enough, we extend it by adding another {@link SLDirectDispatchNode}. If
+     * the cache reached its maximum size, we replace the whole dispatch chain with a
+     * {@link SLGenericDispatchNode}.
+     */
+    @Override
+    protected Object executeDispatch(VirtualFrame frame, SLFunction function, SLArguments arguments) {
+        /* The following code modifies the AST, so compiled code must be invalidated. */
+        CompilerDirectives.transferToInterpreterAndInvalidate();
+
+        /*
+         * Count the number of SLDirectDispatchNodes we already have in the cache. We walk the chain
+         * of parent nodes until we hit the SLCallNode. We know that a SLCallNode is always present.
+         */
+        Node cur = this;
+        int depth = 0;
+        while (cur.getParent() instanceof SLAbstractDispatchNode) {
+            cur = cur.getParent();
+            depth++;
+        }
+        SLInvokeNode invokeNode = (SLInvokeNode) cur.getParent();
+
+        SLAbstractDispatchNode replacement;
+        if (function.getCallTarget() == null) {
+            /* Corner case: the function is not defined, so report an error to the user. */
+            throw new SLException("Call of undefined function: " + function.getName());
+
+        } else if (depth < INLINE_CACHE_SIZE) {
+            /* Extend the inline cache. Allocate the new cache entry, and the new end of the cache. */
+            SLAbstractDispatchNode next = new SLUninitializedDispatchNode();
+            replacement = new SLDirectDispatchNode(next, function);
+            /* Replace ourself with the new cache entry. */
+            replace(replacement);
+
+        } else {
+            /* Cache size exceeded, fall back to a single generic dispatch node. */
+            replacement = new SLGenericDispatchNode();
+            /* Replace the whole chain, not just ourself, with the new generic node. */
+            invokeNode.dispatchNode.replace(replacement);
+        }
+
+        /*
+         * Execute the newly created node perform the actual dispatch. That saves us from
+         * duplicating the actual call logic here.
+         */
+        return replacement.executeDispatch(frame, function, arguments);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLBlockNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,69 @@
+/*
+ * 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.nodes.controlflow;
+
+import com.oracle.truffle.api.*;
+import com.oracle.truffle.api.frame.*;
+import com.oracle.truffle.api.nodes.*;
+import com.oracle.truffle.sl.nodes.*;
+
+/**
+ * A statement node that just executes a list of other statements.
+ */
+@NodeInfo(shortName = "block")
+public final class SLBlockNode extends SLStatementNode {
+
+    /**
+     * The array of child nodes. The annotation {@link com.oracle.truffle.api.nodes.Node.Children
+     * Children} informs Truffle that the field contains multiple children. It is a Truffle
+     * requirement that the field is {@code final} and an array of nodes.
+     */
+    @Children private final SLStatementNode[] bodyNodes;
+
+    public SLBlockNode(SLStatementNode[] bodyNodes) {
+        /*
+         * It is a Truffle requirement to call adoptChildren(), which performs all the necessary
+         * steps to add the new children to the node tree.
+         */
+        this.bodyNodes = adoptChildren(bodyNodes);
+    }
+
+    /**
+     * Execute all child statements. The annotation {@link ExplodeLoop} triggers full unrolling of
+     * the loop during compilation. This allows the {@link SLStatementNode#executeVoid} method of
+     * all children to be inlined.
+     */
+    @Override
+    @ExplodeLoop
+    public void executeVoid(VirtualFrame frame) {
+        /*
+         * This assertion illustrates that the arryay length is really a constant during
+         * compilation.
+         */
+        CompilerAsserts.compilationConstant(bodyNodes.length);
+
+        for (SLStatementNode statement : bodyNodes) {
+            statement.executeVoid(frame);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLBreakException.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,41 @@
+/*
+ * 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.nodes.controlflow;
+
+import com.oracle.truffle.api.nodes.*;
+
+/**
+ * Exception thrown by the {@link SLBreakNode break statement} and caught by the {@link SLWhileNode
+ * loop statement}. Since the exception is stateless, i.e., has no instance fields, we can use a
+ * {@link #SINGLETON} to avoid memory allocation during interpretation.
+ */
+public final class SLBreakException extends ControlFlowException {
+
+    public static final SLBreakException SINGLETON = new SLBreakException();
+
+    private static final long serialVersionUID = -91013036379258890L;
+
+    /* Prevent instantiation from outside. */
+    private SLBreakException() {
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLBreakNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,42 @@
+/*
+ * 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.nodes.controlflow;
+
+import com.oracle.truffle.api.frame.*;
+import com.oracle.truffle.api.nodes.*;
+import com.oracle.truffle.sl.nodes.*;
+
+/**
+ * Implementation of the SL break statement. We need to unwind an unknown number of interpreter
+ * frames that are between this {@link SLBreakNode} and the {@link SLWhileNode} of the loop we are
+ * breaking out. This is done by throwing an {@link SLBreakException exception} that is caught by
+ * the {@link SLWhileNode#executeVoid loop node}.
+ */
+@NodeInfo(shortName = "break")
+public final class SLBreakNode extends SLStatementNode {
+
+    @Override
+    public void executeVoid(VirtualFrame frame) {
+        throw SLBreakException.SINGLETON;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLContinueException.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,41 @@
+/*
+ * 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.nodes.controlflow;
+
+import com.oracle.truffle.api.nodes.*;
+
+/**
+ * Exception thrown by the {@link SLContinueNode continue statement} and caught by the
+ * {@link SLWhileNode loop statement}. Since the exception is stateless, i.e., has no instance
+ * fields, we can use a {@link #SINGLETON} to avoid memory allocation during interpretation.
+ */
+public final class SLContinueException extends ControlFlowException {
+
+    public static final SLContinueException SINGLETON = new SLContinueException();
+
+    private static final long serialVersionUID = 5329687983726237188L;
+
+    /* Prevent instantiation from outside. */
+    private SLContinueException() {
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLContinueNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,42 @@
+/*
+ * 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.nodes.controlflow;
+
+import com.oracle.truffle.api.frame.*;
+import com.oracle.truffle.api.nodes.*;
+import com.oracle.truffle.sl.nodes.*;
+
+/**
+ * Implementation of the SL continue statement. We need to unwind an unknown number of interpreter
+ * frames that are between this {@link SLContinueNode} and the {@link SLWhileNode} of the loop we
+ * are continuing. This is done by throwing an {@link SLContinueException exception} that is caught
+ * by the {@link SLWhileNode#executeVoid loop node}.
+ */
+@NodeInfo(shortName = "continue")
+public final class SLContinueNode extends SLStatementNode {
+
+    @Override
+    public void executeVoid(VirtualFrame frame) {
+        throw SLContinueException.SINGLETON;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLFunctionBodyNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,84 @@
+/*
+ * 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.nodes.controlflow;
+
+import com.oracle.truffle.api.frame.*;
+import com.oracle.truffle.api.nodes.*;
+import com.oracle.truffle.api.utilities.*;
+import com.oracle.truffle.sl.nodes.*;
+import com.oracle.truffle.sl.runtime.*;
+
+/**
+ * The body of a user-defined SL function. This is the node references by a {@link SLRootNode} for
+ * user-defined functions. It handles the return value of a function: the {@link SLReturnNode return
+ * statement} throws an {@link SLReturnException exception} with the return value. This node catches
+ * the exception. If the method ends without an explicit {@code return}, return the
+ * {@link SLNull#SINGLETON default null value}.
+ */
+@NodeInfo(shortName = "body")
+public final class SLFunctionBodyNode extends SLExpressionNode {
+
+    /** The body of the function. */
+    @Child private SLStatementNode bodyNode;
+
+    /**
+     * Profiling information, collected by the interpreter, capturing whether the function had an
+     * {@link SLReturnNode explicit return statement}. This allows the compiler to generate better
+     * code.
+     */
+    private final BranchProfile exceptionTaken = new BranchProfile();
+    private final BranchProfile nullTaken = new BranchProfile();
+
+    public SLFunctionBodyNode(SLStatementNode bodyNode) {
+        /*
+         * It is a Truffle requirement to call adoptChild(), which performs all the necessary steps
+         * to add the new child to the node tree.
+         */
+        this.bodyNode = adoptChild(bodyNode);
+    }
+
+    @Override
+    public Object executeGeneric(VirtualFrame frame) {
+        try {
+            /* Execute the function body. */
+            bodyNode.executeVoid(frame);
+
+        } catch (SLReturnException ex) {
+            /*
+             * In the interpreter, record profiling information that the function has an explicit
+             * return.
+             */
+            exceptionTaken.enter();
+            /* The exception transports the actual return value. */
+            return ex.getResult();
+        }
+
+        /*
+         * In the interpreter, record profiling information that the function ends without an
+         * explicit return.
+         */
+        nullTaken.enter();
+        /* Return the default null value. */
+        return SLNull.SINGLETON;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLIfNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,98 @@
+/*
+ * 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.nodes.controlflow;
+
+import com.oracle.truffle.api.dsl.*;
+import com.oracle.truffle.api.frame.*;
+import com.oracle.truffle.api.nodes.*;
+import com.oracle.truffle.api.utilities.*;
+import com.oracle.truffle.sl.nodes.*;
+
+@NodeInfo(shortName = "if")
+public final class SLIfNode extends SLStatementNode {
+
+    /**
+     * The condition of the {@code if}. This in a {@link SLExpressionNode} because we require a
+     * result value. We do not have a node type that can only return a {@code boolean} value, so
+     * {@link #evaluateCondition executing the condition} can lead to a type error.
+     */
+    @Child private SLExpressionNode conditionNode;
+
+    /** Statement (or {@SLBlockNode block}) executed when the condition is true. */
+    @Child private SLStatementNode thenPartNode;
+
+    /** Statement (or {@SLBlockNode block}) executed when the condition is false. */
+    @Child private SLStatementNode elsePartNode;
+
+    /**
+     * Profiling information, collected by the interpreter, capturing whether the then-branch was
+     * used (analogously for the {@link #elseTaken else-branch}). This allows the compiler to
+     * generate better code for conditions that are always true or always false.
+     */
+    private final BranchProfile thenTaken = new BranchProfile();
+    private final BranchProfile elseTaken = new BranchProfile();
+
+    public SLIfNode(SLExpressionNode conditionNode, SLStatementNode thenPartNode, SLStatementNode elsePartNode) {
+        /*
+         * It is a Truffle requirement to call adoptChild(), which performs all the necessary steps
+         * to add the new child to the node tree.
+         */
+        this.conditionNode = adoptChild(conditionNode);
+        this.thenPartNode = adoptChild(thenPartNode);
+        this.elsePartNode = adoptChild(elsePartNode);
+    }
+
+    @Override
+    public void executeVoid(VirtualFrame frame) {
+        if (evaluateCondition(frame)) {
+            /* In the interpreter, record profiling information that the then-branch was used. */
+            thenTaken.enter();
+            /* Execute the then-branch. */
+            thenPartNode.executeVoid(frame);
+        } else {
+            /* In the interpreter, record profiling information that the else-branch was used. */
+            elseTaken.enter();
+            /* Execute the else-branch (which is optional according to the SL syntax). */
+            if (elsePartNode != null) {
+                elsePartNode.executeVoid(frame);
+            }
+        }
+    }
+
+    private boolean evaluateCondition(VirtualFrame frame) {
+        try {
+            /*
+             * The condition must evaluate to a boolean value, so we call the boolean-specialized
+             * execute method.
+             */
+            return conditionNode.executeBoolean(frame);
+        } catch (UnexpectedResultException ex) {
+            /*
+             * The condition evaluated to a non-boolean result. This is a type error in the SL
+             * program. We report it with the same exception that Truffle DSL generated nodes use to
+             * report type errors.
+             */
+            throw new UnsupportedSpecializationException(this, new Node[]{conditionNode}, ex.getResult());
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLReturnException.java	Wed Mar 05 19:40:15 2014 -0800
@@ -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.nodes.controlflow;
+
+import com.oracle.truffle.api.nodes.*;
+
+/**
+ * Exception thrown by the {@link SLReturnNode return statement} and caught by the
+ * {@link SLFunctionBodyNode function body}. The exception transports the return value in its
+ * {@link #result} field.
+ */
+public final class SLReturnException extends ControlFlowException {
+
+    private static final long serialVersionUID = 4073191346281369231L;
+
+    private final Object result;
+
+    public SLReturnException(Object result) {
+        this.result = result;
+    }
+
+    public Object getResult() {
+        return result;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLReturnNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,57 @@
+/*
+ * 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.nodes.controlflow;
+
+import com.oracle.truffle.api.frame.*;
+import com.oracle.truffle.api.nodes.*;
+import com.oracle.truffle.sl.nodes.*;
+import com.oracle.truffle.sl.runtime.*;
+
+/**
+ * Implementation of the SL return statement. We need to unwind an unknown number of interpreter
+ * frames that are between this {@link SLReturnNode} and the {@link SLFunctionBodyNode} of the
+ * method we are exiting. This is done by throwing an {@link SLReturnException exception} that is
+ * caught by the {@link SLFunctionBodyNode#executeGeneric function body}. The exception transports
+ * the return value.
+ */
+@NodeInfo(shortName = "return")
+public final class SLReturnNode extends SLStatementNode {
+
+    @Child private SLExpressionNode valueNode;
+
+    public SLReturnNode(SLExpressionNode valueNode) {
+        this.valueNode = adoptChild(valueNode);
+    }
+
+    @Override
+    public void executeVoid(VirtualFrame frame) {
+        Object result;
+        if (valueNode != null) {
+            result = valueNode.executeGeneric(frame);
+        } else {
+            /* Return statement that was not followed by an expression, so return the SL null value. */
+            result = SLNull.SINGLETON;
+        }
+        throw new SLReturnException(result);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLWhileNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,113 @@
+/*
+ * 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.nodes.controlflow;
+
+import com.oracle.truffle.api.*;
+import com.oracle.truffle.api.dsl.*;
+import com.oracle.truffle.api.frame.*;
+import com.oracle.truffle.api.nodes.*;
+import com.oracle.truffle.api.utilities.*;
+import com.oracle.truffle.sl.nodes.*;
+
+@NodeInfo(shortName = "while")
+public final class SLWhileNode extends SLStatementNode {
+
+    /**
+     * The condition of the loop. This in a {@link SLExpressionNode} because we require a result
+     * value. We do not have a node type that can only return a {@code boolean} value, so
+     * {@link #evaluateCondition executing the condition} can lead to a type error.
+     */
+    @Child private SLExpressionNode conditionNode;
+
+    /** Statement (or {@SLBlockNode block}) executed as long as the condition is true. */
+    @Child private SLStatementNode bodyNode;
+
+    /**
+     * Profiling information, collected by the interpreter, capturing whether a {@code continue}
+     * statement was used in this loop. This allows the compiler to generate better code for loops
+     * without a {@code continue}.
+     */
+    private final BranchProfile continueTaken = new BranchProfile();
+    private final BranchProfile breakTaken = new BranchProfile();
+
+    public SLWhileNode(SLExpressionNode conditionNode, SLStatementNode bodyNode) {
+        /*
+         * It is a Truffle requirement to call adoptChild(), which performs all the necessary steps
+         * to add the new child to the node tree.
+         */
+        this.conditionNode = adoptChild(conditionNode);
+        this.bodyNode = adoptChild(bodyNode);
+    }
+
+    @Override
+    public void executeVoid(VirtualFrame frame) {
+        int count = 0;
+        try {
+            while (evaluateCondition(frame)) {
+                try {
+                    /* Execute the loop body. */
+                    bodyNode.executeVoid(frame);
+
+                    if (CompilerDirectives.inInterpreter()) {
+                        /* In the interpreter, profile the the number of loop iteration. */
+                        count++;
+                    }
+                } catch (SLContinueException ex) {
+                    /* In the interpreter, record profiling information that the loop uses continue. */
+                    continueTaken.enter();
+                    /* Fall through to next loop iteration. */
+                }
+            }
+        } catch (SLBreakException ex) {
+            /* In the interpreter, record profiling information that the loop uses break. */
+            breakTaken.enter();
+            /* Done executing this loop, exit method to execute statement following the loop. */
+
+        } finally {
+            if (CompilerDirectives.inInterpreter()) {
+                /*
+                 * In the interpreter, report the loop count to the Truffle system. It is used for
+                 * compilation and inlining decisions.
+                 */
+                getRootNode().reportLoopCount(count);
+            }
+        }
+    }
+
+    private boolean evaluateCondition(VirtualFrame frame) {
+        try {
+            /*
+             * The condition must evaluate to a boolean value, so we call the boolean-specialized
+             * execute method.
+             */
+            return conditionNode.executeBoolean(frame);
+        } catch (UnexpectedResultException ex) {
+            /*
+             * The condition evaluated to a non-boolean result. This is a type error in the SL
+             * program. We report it with the same exception that Truffle DSL generated nodes use to
+             * report type errors.
+             */
+            throw new UnsupportedSpecializationException(this, new Node[]{conditionNode}, ex.getResult());
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLAddNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,102 @@
+/*
+ * 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.nodes.expression;
+
+import java.math.*;
+
+import com.oracle.truffle.api.*;
+import com.oracle.truffle.api.dsl.*;
+import com.oracle.truffle.api.nodes.*;
+import com.oracle.truffle.sl.nodes.*;
+
+/**
+ * SL node that performs the "+" operation, which performs addition on arbitrary precision numbers,
+ * as well as String concatenation if one of the operands is a String.
+ * <p>
+ * Type specialization on the input values is essential for the performance. This is achieved via
+ * node rewriting: specialized subclasses handle just a single type, so that the generic node that
+ * can handle all types is used only in cases where different types were encountered. The subclasses
+ * are automatically generated by the Truffle DSL. In addition, a {@link SLAddNodeFactory factory
+ * class} is generated that provides, e.g., {@link SLAddNodeFactory#create node creation}.
+ */
+@NodeInfo(shortName = "+")
+public abstract class SLAddNode extends SLBinaryNode {
+
+    /**
+     * Specialization for primitive {@code long} values. This is the fast path of the
+     * arbitrary-precision arithmetic. We need to check for overflows of the addition, and switch to
+     * the {@link #add(BigInteger, BigInteger) slow path}. Therefore, we use an
+     * {@link ExactMath#addExact(long, long) addition method that throws an exception on overflow}.
+     * The {@code rewriteOn} attribute on the {@link Specialization} annotation automatically
+     * triggers the node rewriting on the exception.
+     * <p>
+     * In compiled code, {@link ExactMath#addExact(long, long) addExact} is compiled to efficient
+     * machine code that uses the processor's overflow flag. Therefore, this method is compiled to
+     * only two machine code instructions on the fast path.
+     * <p>
+     * This specialization is automatically selected by the Truffle DSL if both the left and right
+     * operand are {@code long} values.
+     */
+    @Specialization(rewriteOn = ArithmeticException.class)
+    protected long add(long left, long right) {
+        return ExactMath.addExact(left, right);
+    }
+
+    /**
+     * This is the slow path of the arbitrary-precision arithmetic. The {@link BigInteger} type of
+     * Java is doing everything we need.
+     * <p>
+     * This specialization is automatically selected by the Truffle DSL if both the left and right
+     * operand are {@link BigInteger} values. Because the type system defines an
+     * {@link ImplicitCast implicit conversion} from {@code long} to {@link BigInteger} in
+     * {@link SLTypes#castBigInteger(long)}, this specialization is also taken if the left or the
+     * right operand is a {@code long} value. Because the {@link #add(long, long) long}
+     * specialization} has the {@code rewriteOn} attribute, this specialization is also taken if
+     * both input values are {@code long} values but the primitive addition overflows.
+     */
+    @Specialization
+    protected BigInteger add(BigInteger left, BigInteger right) {
+        return left.add(right);
+    }
+
+    /**
+     * Specialization for String concatenation. The SL specification says that String concatenation
+     * works if either the left or the right operand is a String. The non-string operand is
+     * converted then automatically converted to a String.
+     * <p>
+     * To implement these semantics, we tell the Truffle DSL to use a custom guard. The guard
+     * function is defined in {@link #isString this class}, but could also be in any superclass.
+     */
+    @Specialization(guards = "isString")
+    protected String add(Object left, Object right) {
+        return left.toString() + right.toString();
+    }
+
+    /**
+     * Guard for String concatenation: returns true if either the left or the right operand is a
+     * {@link String}.
+     */
+    protected boolean isString(Object a, Object b) {
+        return a instanceof String || b instanceof String;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLBigIntegerLiteralNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,53 @@
+/*
+ * 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.nodes.expression;
+
+import java.math.*;
+
+import com.oracle.truffle.api.frame.*;
+import com.oracle.truffle.api.nodes.*;
+import com.oracle.truffle.sl.nodes.*;
+
+/**
+ * Constant literal for a arbitrary-precision number that exceeds the range of
+ * {@link SLLongLiteralNode}.
+ */
+@NodeInfo(shortName = "const")
+public final class SLBigIntegerLiteralNode extends SLExpressionNode {
+
+    private final BigInteger value;
+
+    public SLBigIntegerLiteralNode(BigInteger value) {
+        this.value = value;
+    }
+
+    @Override
+    public BigInteger executeBigInteger(VirtualFrame frame) {
+        return value;
+    }
+
+    @Override
+    public Object executeGeneric(VirtualFrame frame) {
+        return value;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLDivNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,49 @@
+/*
+ * 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.nodes.expression;
+
+import java.math.*;
+
+import com.oracle.truffle.api.dsl.*;
+import com.oracle.truffle.api.nodes.*;
+import com.oracle.truffle.sl.nodes.*;
+
+/**
+ * This class is similar to the extensively documented {@link SLAddNode}. Divisions by 0 throw the
+ * same {@link ArithmeticException exception} as in Java, SL has no special handling for it to keep
+ * the code simple.
+ */
+@NodeInfo(shortName = "/")
+public abstract class SLDivNode extends SLBinaryNode {
+
+    @Specialization
+    protected long div(long left, long right) {
+        /* No overflow is possible on a division. */
+        return left / right;
+    }
+
+    @Specialization
+    protected BigInteger div(BigInteger left, BigInteger right) {
+        return left.divide(right);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLEqualNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,94 @@
+/*
+ * 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.nodes.expression;
+
+import java.math.*;
+
+import com.oracle.truffle.api.dsl.*;
+import com.oracle.truffle.api.nodes.*;
+import com.oracle.truffle.sl.nodes.*;
+import com.oracle.truffle.sl.runtime.*;
+
+/**
+ * The {@code ==} operator of SL is defined on all types. Therefore, we need a
+ * {@link #equal(Object, Object) generic implementation} that can handle all possible types. But
+ * since {@code ==} can only return {@code true} when the type of the left and right operand are the
+ * same, the specializations already cover all possible cases that can return {@code true} and the
+ * generic case is trivial.
+ * <p>
+ * Note that we do not need the analogous {@code =!} operator, because we can just
+ * {@link SLLogicalNotNode negate} the {@code ==} operator.
+ */
+@NodeInfo(shortName = "==")
+public abstract class SLEqualNode extends SLBinaryNode {
+
+    @Specialization
+    protected boolean equal(long left, long right) {
+        return left == right;
+    }
+
+    @Specialization
+    protected boolean equal(BigInteger left, BigInteger right) {
+        return left.equals(right);
+    }
+
+    @Specialization
+    protected boolean equal(boolean left, boolean right) {
+        return left == right;
+    }
+
+    @Specialization
+    protected boolean equal(String left, String right) {
+        return left.equals(right);
+    }
+
+    @Specialization
+    protected boolean equal(SLFunction left, SLFunction right) {
+        /*
+         * Our function registry maintains one canonical SLFunction object per function name, so we
+         * do not need equals().
+         */
+        return left == right;
+    }
+
+    @Specialization
+    protected boolean equal(SLNull left, SLNull right) {
+        /* There is only the singleton instance of SLNull, so we do not need equals(). */
+        return left == right;
+    }
+
+    /**
+     * The {@link Generic} annotation informs the Truffle DSL that this method should be executed
+     * when no {@link Specialization specialized method} matches. The operand types must be
+     * {@link Object}.
+     */
+    @Generic
+    protected boolean equal(Object left, Object right) {
+        /*
+         * We covered all the cases that can return true in specializations. If we compare two
+         * values with different types, no specialization matches and we end up here.
+         */
+        assert !left.equals(right);
+        return false;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLFunctionLiteralNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,55 @@
+/*
+ * 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.nodes.expression;
+
+import com.oracle.truffle.api.*;
+import com.oracle.truffle.api.frame.*;
+import com.oracle.truffle.api.nodes.*;
+import com.oracle.truffle.sl.nodes.*;
+import com.oracle.truffle.sl.runtime.*;
+
+/**
+ * Constant literal for a {@link SLFunction function} value, created when a function name occurs as
+ * a literal in SL source code. Note that function redefinition can change the {@link CallTarget
+ * call target} that is executed when calling the function, but the {@link SLFunction} for a name
+ * never changes. This is guaranteed by the {@link SLFunctionRegistry}.
+ */
+@NodeInfo(shortName = "func")
+public final class SLFunctionLiteralNode extends SLExpressionNode {
+
+    private final SLFunction value;
+
+    public SLFunctionLiteralNode(SLFunction value) {
+        this.value = value;
+    }
+
+    @Override
+    public SLFunction executeFunction(VirtualFrame frame) {
+        return value;
+    }
+
+    @Override
+    public Object executeGeneric(VirtualFrame frame) {
+        return value;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLLessOrEqualNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,46 @@
+/*
+ * 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.nodes.expression;
+
+import java.math.*;
+
+import com.oracle.truffle.api.dsl.*;
+import com.oracle.truffle.api.nodes.*;
+import com.oracle.truffle.sl.nodes.*;
+
+/**
+ * This class is similar to the {@link SLLessThanNode}.
+ */
+@NodeInfo(shortName = "<=")
+public abstract class SLLessOrEqualNode extends SLBinaryNode {
+
+    @Specialization
+    protected boolean lessOrEqual(long left, long right) {
+        return left <= right;
+    }
+
+    @Specialization
+    protected boolean lessOrEqual(BigInteger left, BigInteger right) {
+        return left.compareTo(right) <= 0;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLLessThanNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,47 @@
+/*
+ * 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.nodes.expression;
+
+import java.math.*;
+
+import com.oracle.truffle.api.dsl.*;
+import com.oracle.truffle.api.nodes.*;
+import com.oracle.truffle.sl.nodes.*;
+
+/**
+ * This class is similar to the extensively documented {@link SLAddNode}. The only difference: the
+ * specialized methods return {@code boolean} instead of the input types.
+ */
+@NodeInfo(shortName = "<")
+public abstract class SLLessThanNode extends SLBinaryNode {
+
+    @Specialization
+    protected boolean lessThan(long left, long right) {
+        return left < right;
+    }
+
+    @Specialization
+    protected boolean lessThan(BigInteger left, BigInteger right) {
+        return left.compareTo(right) < 0;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLLogicalAndNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,64 @@
+/*
+ * 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.nodes.expression;
+
+import com.oracle.truffle.api.dsl.*;
+import com.oracle.truffle.api.nodes.*;
+import com.oracle.truffle.sl.nodes.*;
+
+/**
+ * This class declares specializations similar to the extensively documented {@link SLAddNode}. It
+ * uses one additional feature of the Truffle DSL: {@link ShortCircuit}.
+ * <p>
+ * Logical operations in SL use short circuit evaluation: if the evaluation of the left operand
+ * already decides the result of the operation, the right operand must not be executed. This is
+ * expressed in the Truffle DSL via a method annotated with {@link ShortCircuit}, which returns
+ * whether a child needs to be executed based on the result of already executed children.
+ */
+@NodeInfo(shortName = "&&")
+@SuppressWarnings("unused")
+public abstract class SLLogicalAndNode extends SLBinaryNode {
+
+    /**
+     * This method is called after the left child was evaluated, but before the right child is
+     * evaluated. The right child is only evaluated when the return value is {code true}.
+     */
+    @ShortCircuit("rightNode")
+    protected boolean needsRightNode(boolean left) {
+        return left;
+    }
+
+    /**
+     * Similar to {@link #needsRightNode(boolean)}, but for generic cases where the type of the left
+     * child is not known.
+     */
+    @ShortCircuit("rightNode")
+    protected boolean needsRightNode(Object left) {
+        return left instanceof Boolean && needsRightNode(((Boolean) left).booleanValue());
+    }
+
+    @Specialization
+    protected boolean doBoolean(boolean left, boolean hasRight, boolean right) {
+        return left && right;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLLogicalNotNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -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.truffle.sl.nodes.expression;
+
+import com.oracle.truffle.api.dsl.*;
+import com.oracle.truffle.api.nodes.*;
+import com.oracle.truffle.sl.nodes.*;
+
+/**
+ * Example of a simple unary node that uses type specialization. See {@link SLAddNode} for
+ * information on specializations.
+ */
+@NodeChild("valueNode")
+@NodeInfo(shortName = "!")
+public abstract class SLLogicalNotNode extends SLExpressionNode {
+
+    @Specialization
+    protected boolean doBoolean(boolean value) {
+        return !value;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLLogicalOrNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,50 @@
+/*
+ * 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.nodes.expression;
+
+import com.oracle.truffle.api.dsl.*;
+import com.oracle.truffle.api.nodes.*;
+import com.oracle.truffle.sl.nodes.*;
+
+/**
+ * This class is similar to the {@link SLLogicalAndNode}.
+ */
+@NodeInfo(shortName = "||")
+@SuppressWarnings("unused")
+public abstract class SLLogicalOrNode extends SLBinaryNode {
+
+    @ShortCircuit("rightNode")
+    protected boolean needsRightNode(boolean left) {
+        return !left;
+    }
+
+    @ShortCircuit("rightNode")
+    protected boolean needsRightNode(Object left) {
+        return left instanceof Boolean && needsRightNode(((Boolean) left).booleanValue());
+    }
+
+    @Specialization
+    protected boolean doBoolean(boolean left, boolean hasRight, boolean right) {
+        return left || right;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLLongLiteralNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,52 @@
+/*
+ * 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.nodes.expression;
+
+import com.oracle.truffle.api.frame.*;
+import com.oracle.truffle.api.nodes.*;
+import com.oracle.truffle.sl.nodes.*;
+
+/**
+ * Constant literal for a primitive {@code long} value. The unboxed value can be returned when the
+ * parent expects a long value and calls {@link SLLongLiteralNode#executeLong}. In the generic case,
+ * the primitive value is automatically boxed by Java.
+ */
+@NodeInfo(shortName = "const")
+public final class SLLongLiteralNode extends SLExpressionNode {
+
+    private final long value;
+
+    public SLLongLiteralNode(long value) {
+        this.value = value;
+    }
+
+    @Override
+    public long executeLong(VirtualFrame frame) throws UnexpectedResultException {
+        return value;
+    }
+
+    @Override
+    public Object executeGeneric(VirtualFrame frame) {
+        return value;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLMulNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,47 @@
+/*
+ * 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.nodes.expression;
+
+import java.math.*;
+
+import com.oracle.truffle.api.*;
+import com.oracle.truffle.api.dsl.*;
+import com.oracle.truffle.api.nodes.*;
+import com.oracle.truffle.sl.nodes.*;
+
+/**
+ * This class is similar to the extensively documented {@link SLAddNode}.
+ */
+@NodeInfo(shortName = "*")
+public abstract class SLMulNode extends SLBinaryNode {
+
+    @Specialization(rewriteOn = ArithmeticException.class)
+    protected long mul(long left, long right) {
+        return ExactMath.multiplyExact(left, right);
+    }
+
+    @Specialization
+    protected BigInteger mul(BigInteger left, BigInteger right) {
+        return left.multiply(right);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLStringLiteralNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,50 @@
+/*
+ * 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.nodes.expression;
+
+import com.oracle.truffle.api.frame.*;
+import com.oracle.truffle.api.nodes.*;
+import com.oracle.truffle.sl.nodes.*;
+
+/**
+ * Constant literal for a String value.
+ */
+@NodeInfo(shortName = "const")
+public final class SLStringLiteralNode extends SLExpressionNode {
+
+    private final String value;
+
+    public SLStringLiteralNode(String value) {
+        this.value = value;
+    }
+
+    @Override
+    public String executeString(VirtualFrame frame) {
+        return value;
+    }
+
+    @Override
+    public Object executeGeneric(VirtualFrame frame) {
+        return value;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLSubNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,47 @@
+/*
+ * 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.nodes.expression;
+
+import java.math.*;
+
+import com.oracle.truffle.api.*;
+import com.oracle.truffle.api.dsl.*;
+import com.oracle.truffle.api.nodes.*;
+import com.oracle.truffle.sl.nodes.*;
+
+/**
+ * This class is similar to the extensively documented {@link SLAddNode}.
+ */
+@NodeInfo(shortName = "-")
+public abstract class SLSubNode extends SLBinaryNode {
+
+    @Specialization(rewriteOn = ArithmeticException.class)
+    protected long sub(long left, long right) {
+        return ExactMath.subtractExact(left, right);
+    }
+
+    @Specialization
+    protected BigInteger sub(BigInteger left, BigInteger right) {
+        return left.subtract(right);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/demo/SLAddWithoutSpecializationNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,84 @@
+/*
+ * 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.truffle.sl.nodes.expression.demo;
+
+import java.math.*;
+
+import com.oracle.truffle.api.*;
+import com.oracle.truffle.api.dsl.*;
+import com.oracle.truffle.api.frame.*;
+import com.oracle.truffle.api.nodes.*;
+import com.oracle.truffle.sl.nodes.*;
+import com.oracle.truffle.sl.nodes.expression.*;
+
+/**
+ * This is an example how the add operation would be implemented without specializations and without
+ * the Truffle DSL. Do not write such code in your language! See {@link SLAddNode} how the add
+ * operation is implemented correctly.
+ */
+public class SLAddWithoutSpecializationNode extends SLExpressionNode {
+
+    @Child private SLExpressionNode leftNode;
+    @Child private SLExpressionNode rightNode;
+
+    public SLAddWithoutSpecializationNode(SLExpressionNode leftNode, SLExpressionNode rightNode) {
+        this.leftNode = adoptChild(leftNode);
+        this.rightNode = adoptChild(rightNode);
+    }
+
+    @Override
+    public Object executeGeneric(VirtualFrame frame) {
+        /* Evaluate the child nodes. */
+        Object left = leftNode.executeGeneric(frame);
+        Object right = rightNode.executeGeneric(frame);
+
+        if (left instanceof Long && right instanceof Long) {
+            /* Fast path of the arbitrary-precision arithmetic. We need to check for overflows */
+            try {
+                return ExactMath.addExact((Long) left, (Long) right);
+            } catch (ArithmeticException ex) {
+                /* Fall through to BigInteger case. */
+            }
+        }
+
+        /* Implicit type conversions. */
+        if (left instanceof Long) {
+            left = BigInteger.valueOf((Long) left);
+        }
+        if (right instanceof Long) {
+            right = BigInteger.valueOf((Long) right);
+        }
+        if (left instanceof BigInteger && right instanceof BigInteger) {
+            /* Slow path of the arbitrary-precision arithmetic. */
+            return ((BigInteger) left).add((BigInteger) right);
+        }
+
+        /* String concatenation if either the left or the right operand is a String. */
+        if (left instanceof String || right instanceof String) {
+            return left.toString() + right.toString();
+        }
+
+        /* Type error. */
+        throw new UnsupportedSpecializationException(this, new Node[]{leftNode, rightNode}, new Object[]{left, right});
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/local/SLReadArgumentNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -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.nodes.local;
+
+import com.oracle.truffle.api.*;
+import com.oracle.truffle.api.frame.*;
+import com.oracle.truffle.api.utilities.*;
+import com.oracle.truffle.sl.nodes.*;
+import com.oracle.truffle.sl.parser.*;
+import com.oracle.truffle.sl.runtime.*;
+
+/**
+ * Reads a function argument. Arguments are passed in as a {@link SLArguments} object, which
+ * encapsulates an {@link SLArguments#getFromFrame Object[] array}. Language-defined subclasses of
+ * {@link Arguments} are the standard Truffle way to pass values between functions.
+ * <p>
+ * Arguments are not type-specialized. To ensure that repeated accesses within a method are
+ * specialized and can, e.g., be accessed without unboxing, all arguments are loaded into local
+ * variables {@link SLNodeFactory#addFormalParameter in the method prologue}.
+ */
+public class SLReadArgumentNode extends SLExpressionNode {
+
+    /** The argument number, i.e., the index into the array of arguments. */
+    private final int index;
+
+    /**
+     * Profiling information, collected by the interpreter, capturing whether the function was
+     * called with fewer actual arguments than formal arguments.
+     */
+    private final BranchProfile outOfBoundsTaken = new BranchProfile();
+
+    public SLReadArgumentNode(int index) {
+        this.index = index;
+    }
+
+    @Override
+    public Object executeGeneric(VirtualFrame frame) {
+        Object[] args = SLArguments.getFromFrame(frame);
+        if (index < args.length) {
+            return args[index];
+        } else {
+            /* In the interpreter, record profiling information that the branch was used. */
+            outOfBoundsTaken.enter();
+            /* Use the default null value. */
+            return SLNull.SINGLETON;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/local/SLReadLocalVariableNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -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.nodes.local;
+
+import com.oracle.truffle.api.dsl.*;
+import com.oracle.truffle.api.frame.*;
+import com.oracle.truffle.sl.nodes.*;
+
+/**
+ * Node to read a local variable from a function's {@link VirtualFrame frame}. The Truffle frame API
+ * allows to store primitive values of all Java primitive types, and Object values. This means that
+ * all SL types that are objects are handled by the {@link #readObject} method. When a local
+ * variable changes its type, the frame access method throws an {@link FrameSlotTypeException},
+ * which causes not rewriting. The rewriting code is generated by the Truffle DSL.
+ */
+@NodeField(name = "slot", type = FrameSlot.class)
+public abstract class SLReadLocalVariableNode extends SLExpressionNode {
+
+    /**
+     * Returns the descriptor of the accessed local variable. The implementation of this method is
+     * created by the Truffle DSL based on the {@link NodeField} annotation on the class.
+     */
+    protected abstract FrameSlot getSlot();
+
+    @Specialization(rewriteOn = FrameSlotTypeException.class)
+    protected long readLong(VirtualFrame frame) throws FrameSlotTypeException {
+        return frame.getLong(getSlot());
+    }
+
+    @Specialization(rewriteOn = FrameSlotTypeException.class)
+    protected boolean readBoolean(VirtualFrame frame) throws FrameSlotTypeException {
+        return frame.getBoolean(getSlot());
+    }
+
+    @Specialization(order = 1, rewriteOn = FrameSlotTypeException.class)
+    protected Object readObject(VirtualFrame frame) throws FrameSlotTypeException {
+        return frame.getObject(getSlot());
+    }
+
+    /**
+     * This is the generic case that always succeeds. Since we already have another specialization
+     * with the same signature above, we need to order them explicitly with the order attribute.
+     */
+    @Specialization(order = 2)
+    protected Object read(VirtualFrame frame) {
+        return frame.getValue(getSlot());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/local/SLWriteLocalVariableNode.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,118 @@
+/*
+ * 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.nodes.local;
+
+import com.oracle.truffle.api.*;
+import com.oracle.truffle.api.dsl.*;
+import com.oracle.truffle.api.frame.*;
+import com.oracle.truffle.sl.nodes.*;
+
+/**
+ * Node to write a local variable to a function's {@link VirtualFrame frame}. The Truffle frame API
+ * allows to store primitive values of all Java primitive types, and Object values.
+ */
+@NodeChild("valueNode")
+@NodeField(name = "slot", type = FrameSlot.class)
+public abstract class SLWriteLocalVariableNode extends SLExpressionNode {
+
+    /**
+     * Returns the descriptor of the accessed local variable. The implementation of this method is
+     * created by the Truffle DSL based on the {@link NodeField} annotation on the class.
+     */
+    protected abstract FrameSlot getSlot();
+
+    /**
+     * Specialized method to write a primitive {@code long} value. This is only possible if the
+     * local variable also has currently the type {@code long}, therefore a Truffle DSL
+     * {@link #isLongKind() custom guard} is specified.
+     */
+    @Specialization(guards = "isLongKind")
+    protected long write(VirtualFrame frame, long value) {
+        frame.setLong(getSlot(), value);
+        return value;
+    }
+
+    @Specialization(guards = "isBooleanKind")
+    protected boolean write(VirtualFrame frame, boolean value) {
+        frame.setBoolean(getSlot(), value);
+        return value;
+    }
+
+    /**
+     * Generic write method that works for all possible types.
+     * <p>
+     * Why is this method annotated with {@link Specialization} and not {@link Generic}? For a
+     * {@link Generic} method, the Truffle DSL generated code would try all other specializations
+     * first before calling this method. We know that all these specializations would fail their
+     * guards, so there is no point in calling them. Since this method takes a value of type
+     * {@link Object}, it is guaranteed to never fail, i.e., once we are in this specialization the
+     * node will never be re-specialized.
+     */
+    @Specialization
+    protected Object write(VirtualFrame frame, Object value) {
+        if (getSlot().getKind() != FrameSlotKind.Object) {
+            /*
+             * The local variable has still a primitive type, we need to change it to Object. Since
+             * the variable type is important when the compiler optimizes a method, we also discard
+             * compiled code.
+             */
+            CompilerDirectives.transferToInterpreterAndInvalidate();
+            getSlot().setKind(FrameSlotKind.Object);
+        }
+        frame.setObject(getSlot(), value);
+        return value;
+    }
+
+    /**
+     * Guard function that the local variable has the type {@code long}.
+     */
+    protected boolean isLongKind() {
+        return isKind(FrameSlotKind.Long);
+    }
+
+    protected boolean isBooleanKind() {
+        return isKind(FrameSlotKind.Boolean);
+    }
+
+    private boolean isKind(FrameSlotKind kind) {
+        if (getSlot().getKind() == kind) {
+            /* Success: the frame slot has the expected kind. */
+            return true;
+        } else if (getSlot().getKind() == FrameSlotKind.Illegal) {
+            /*
+             * This is the first write to this local variable. We can set the type to the one we
+             * expect. Since the variable type is important when the compiler optimizes a method, we
+             * also discard compiled code.
+             */
+            CompilerDirectives.transferToInterpreterAndInvalidate();
+            getSlot().setKind(kind);
+            return true;
+        } else {
+            /*
+             * Failure: the frame slot has the wrong kind, the Truffle DSL generated code will
+             * choose a different specialization.
+             */
+            return false;
+        }
+    }
+}
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/Copyright.frame	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/Copyright.frame	Wed Mar 05 19:40:15 2014 -0800
@@ -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
@@ -21,5 +21,4 @@
  * questions.
  */
 
- // The content of this file is automatically generated. DO NOT EDIT.
-
+// The content of this file is automatically generated. DO NOT EDIT.
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/Parser.frame	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/Parser.frame	Wed Mar 05 19:40:15 2014 -0800
@@ -30,8 +30,10 @@
 
 import java.util.*;
 
+import com.oracle.truffle.api.*;
 import com.oracle.truffle.sl.*;
 import com.oracle.truffle.sl.nodes.*;
+import com.oracle.truffle.sl.runtime.*;
 
 // Checkstyle: stop
 // @formatter:off
@@ -49,9 +51,9 @@
     public final Errors errors;
     private final SLNodeFactory factory;
     -->declarations
-    public Parser(Scanner scanner, SLNodeFactory factory) {
-        this.scanner = scanner;
-        this.factory = factory;
+    public Parser(SLContext context, Source source) {
+        this.scanner = new Scanner(source.getInputStream());
+        this.factory = new SLNodeFactory(context, source);
         errors = new Errors();
     }
 
@@ -132,28 +134,22 @@
 -->initialization
     };
 
-    public String ParseErrors() {
-        java.io.PrintStream oldStream = System.out;
-
-        java.io.OutputStream out = new java.io.ByteArrayOutputStream();
-        java.io.PrintStream newStream = new java.io.PrintStream(out);
-
-        errors.errorStream = newStream;
-
-        Parse();
-
-        String errorStream = out.toString();
-        errors.errorStream = oldStream;
-
-        return errorStream;
-
+    public static void parseSL(SLContext context, Source source) {
+        Parser parser = new Parser(context, source);
+        parser.Parse();
+        if (parser.errors.errors.size() > 0) {
+            StringBuilder msg = new StringBuilder("Error(s) parsing script:\n");
+            for (String error : parser.errors.errors) {
+                msg.append(error).append("\n");
+            }
+            throw new SLException(msg.toString());
+        }
     }
 } // end Parser
 
 class Errors {
 
-    public int count = 0; // number of errors detected
-    public java.io.PrintStream errorStream = System.out; // error messages go to this stream
+    protected final List<String> errors = new ArrayList<>();
     public String errMsgFormat = "-- line {0} col {1}: {2}"; // 0=line, 1=column, 2=text
 
     protected void printMsg(int line, int column, String msg) {
@@ -171,7 +167,7 @@
         pos = b.indexOf("{2}");
         if (pos >= 0)
             b.replace(pos, pos + 3, msg);
-        errorStream.println(b.toString());
+        errors.add(b.toString());
     }
 
     public void SynErr(int line, int col, int n) {
@@ -182,17 +178,14 @@
                 break;
         }
         printMsg(line, col, s);
-        count++;
     }
 
     public void SemErr(int line, int col, String s) {
         printMsg(line, col, s);
-        count++;
     }
 
     public void SemErr(String s) {
-        errorStream.println(s);
-        count++;
+        errors.add(s);
     }
 
     public void Warning(int line, int col, String s) {
@@ -200,7 +193,7 @@
     }
 
     public void Warning(String s) {
-        errorStream.println(s);
+        errors.add(s);
     }
 } // Errors
 
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/Parser.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/Parser.java	Wed Mar 05 19:40:15 2014 -0800
@@ -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
@@ -27,8 +27,10 @@
 
 import java.util.*;
 
+import com.oracle.truffle.api.*;
 import com.oracle.truffle.sl.*;
 import com.oracle.truffle.sl.nodes.*;
+import com.oracle.truffle.sl.runtime.*;
 
 // Checkstyle: stop
 // @formatter:off
@@ -37,7 +39,7 @@
 	public static final int _identifier = 1;
 	public static final int _stringLiteral = 2;
 	public static final int _numericLiteral = 3;
-	public static final int maxT = 29;
+	public static final int maxT = 30;
 
     static final boolean T = true;
     static final boolean x = false;
@@ -51,9 +53,9 @@
     public final Errors errors;
     private final SLNodeFactory factory;
     
-    public Parser(Scanner scanner, SLNodeFactory factory) {
-        this.scanner = scanner;
-        this.factory = factory;
+    public Parser(SLContext context, Source source) {
+        this.scanner = new Scanner(source.getInputStream());
+        this.factory = new SLNodeFactory(context, source);
         errors = new Errors();
     }
 
@@ -130,113 +132,146 @@
 
 	void Function() {
 		Expect(4);
-		factory.startFunction(); 
 		Expect(1);
-		String name = t.val; 
-		List<String> parameterNames = new ArrayList<>(); 
-		if (la.kind == 5) {
+		factory.startFunction(t); 
+		Expect(5);
+		if (la.kind == 1) {
 			Get();
-			if (la.kind == 1) {
-				Get();
-				parameterNames.add(t.val); 
-			}
+			factory.addFormalParameter(t); 
 			while (la.kind == 6) {
 				Get();
 				Expect(1);
-				parameterNames.add(t.val); 
+				factory.addFormalParameter(t); 
 			}
-			Expect(7);
 		}
-		StatementNode body = Block();
-		factory.createFunction(body, name, parameterNames.toArray(new String[parameterNames.size()])); 
+		Expect(7);
+		SLStatementNode body = Block(false);
+		factory.finishFunction(body); 
 	}
 
-	StatementNode  Block() {
-		StatementNode  result;
-		List<StatementNode> statements = new ArrayList<>(); 
+	SLStatementNode  Block(boolean inLoop) {
+		SLStatementNode  result;
+		factory.startBlock();
+		List<SLStatementNode> body = new ArrayList<>(); 
 		Expect(8);
 		while (StartOf(1)) {
-			StatementNode statement = Statement();
-			statements.add(statement); 
+			SLStatementNode s = Statement(inLoop);
+			body.add(s); 
 		}
 		Expect(9);
-		result = factory.createBlock(statements); 
+		result = factory.finishBlock(body); 
 		return result;
 	}
 
-	StatementNode  Statement() {
-		StatementNode  result;
+	SLStatementNode  Statement(boolean inLoop) {
+		SLStatementNode  result;
 		result = null; 
-		if (la.kind == 13) {
+		switch (la.kind) {
+		case 13: {
 			result = WhileStatement();
-		} else if (la.kind == 11) {
-			result = IfStatement();
-		} else if (la.kind == 14) {
+			break;
+		}
+		case 10: {
+			Get();
+			if (inLoop) { result = factory.createBreak(t); } else { SemErr("break used outside of loop"); } 
+			Expect(11);
+			break;
+		}
+		case 12: {
+			Get();
+			if (inLoop) { result = factory.createContinue(t); } else { SemErr("continue used outside of loop"); } 
+			Expect(11);
+			break;
+		}
+		case 14: {
+			result = IfStatement(inLoop);
+			break;
+		}
+		case 16: {
 			result = ReturnStatement();
-		} else if (StartOf(2)) {
+			break;
+		}
+		case 1: case 2: case 3: case 5: {
 			result = Expression();
-			Expect(10);
-		} else SynErr(30);
+			Expect(11);
+			break;
+		}
+		default: SynErr(31); break;
+		}
 		return result;
 	}
 
-	StatementNode  WhileStatement() {
-		StatementNode  result;
+	SLStatementNode  WhileStatement() {
+		SLStatementNode  result;
 		Expect(13);
 		Expect(5);
-		ConditionNode condition = Expression();
+		Token whileToken = t; 
+		SLExpressionNode condition = Expression();
 		Expect(7);
-		StatementNode body = Block();
-		result = factory.createWhile(condition, body); 
+		SLStatementNode body = Block(true);
+		result = factory.createWhile(whileToken, condition, body); 
 		return result;
 	}
 
-	StatementNode  IfStatement() {
-		StatementNode  result;
-		Expect(11);
+	SLStatementNode  IfStatement(boolean inLoop) {
+		SLStatementNode  result;
+		Expect(14);
 		Expect(5);
-		ConditionNode condition = Expression();
+		Token ifToken = t; 
+		SLExpressionNode condition = Expression();
 		Expect(7);
-		StatementNode thenNode = null; StatementNode elseNode = null; 
-		thenNode = Block();
-		if (la.kind == 12) {
+		SLStatementNode thenPart = Block(inLoop);
+		SLStatementNode elsePart = null; 
+		if (la.kind == 15) {
 			Get();
-			elseNode = Block();
+			elsePart = Block(inLoop);
 		}
-		result = factory.createIf(condition, thenNode, elseNode); 
+		result = factory.createIf(ifToken, condition, thenPart, elsePart); 
 		return result;
 	}
 
-	StatementNode  ReturnStatement() {
-		StatementNode  result;
-		Expect(14);
-		TypedNode value = Expression();
-		Expect(10);
-		result = factory.createReturn(value); 
+	SLStatementNode  ReturnStatement() {
+		SLStatementNode  result;
+		Expect(16);
+		Token returnToken = t;
+		SLExpressionNode value = null; 
+		if (StartOf(2)) {
+			value = Expression();
+		}
+		result = factory.createReturn(returnToken, value); 
+		Expect(11);
 		return result;
 	}
 
-	TypedNode  Expression() {
-		TypedNode  result;
-		result = ValueExpression();
+	SLExpressionNode  Expression() {
+		SLExpressionNode  result;
+		result = LogicTerm();
+		while (la.kind == 17) {
+			Get();
+			Token op = t; 
+			SLExpressionNode right = LogicTerm();
+			result = factory.createBinary(op, result, right); 
+		}
+		return result;
+	}
+
+	SLExpressionNode  LogicTerm() {
+		SLExpressionNode  result;
+		result = LogicFactor();
+		while (la.kind == 18) {
+			Get();
+			Token op = t; 
+			SLExpressionNode right = LogicFactor();
+			result = factory.createBinary(op, result, right); 
+		}
+		return result;
+	}
+
+	SLExpressionNode  LogicFactor() {
+		SLExpressionNode  result;
+		result = Arithmetic();
 		if (StartOf(3)) {
 			switch (la.kind) {
-			case 15: {
-				Get();
-				break;
-			}
-			case 16: {
-				Get();
-				break;
-			}
-			case 17: {
-				Get();
-				break;
-			}
-			case 18: {
-				Get();
-				break;
-			}
 			case 19: {
 				Get();
 				break;
@@ -245,130 +280,101 @@
 				Get();
 				break;
 			}
+			case 21: {
+				Get();
+				break;
 			}
-			String op = t.val; 
-			TypedNode right = ValueExpression();
+			case 22: {
+				Get();
+				break;
+			}
+			case 23: {
+				Get();
+				break;
+			}
+			case 24: {
+				Get();
+				break;
+			}
+			}
+			Token op = t; 
+			SLExpressionNode right = Arithmetic();
 			result = factory.createBinary(op, result, right); 
 		}
 		return result;
 	}
 
-	TypedNode  ValueExpression() {
-		TypedNode  result;
+	SLExpressionNode  Arithmetic() {
+		SLExpressionNode  result;
 		result = Term();
-		while (la.kind == 21 || la.kind == 22) {
-			if (la.kind == 21) {
+		while (la.kind == 25 || la.kind == 26) {
+			if (la.kind == 25) {
 				Get();
 			} else {
 				Get();
 			}
-			String op = t.val; 
-			TypedNode right = Term();
-			result = factory.createBinary(op, result, right); 
-		}
-		return result;
-	}
-
-	TypedNode  Term() {
-		TypedNode  result;
-		result = Factor();
-		while (la.kind == 23 || la.kind == 24) {
-			if (la.kind == 23) {
-				Get();
-			} else {
-				Get();
-			}
-			String op = t.val; 
-			TypedNode right = Factor();
+			Token op = t; 
+			SLExpressionNode right = Term();
 			result = factory.createBinary(op, result, right); 
 		}
 		return result;
 	}
 
-	TypedNode  Factor() {
-		TypedNode  result;
-		result = null; 
-		if (la.kind == 1) {
-			result = VariableRefOrCall();
-		} else if (la.kind == 2) {
-			result = StringLiteral();
-		} else if (la.kind == 3) {
-			result = NumericLiteral();
-		} else if (la.kind == 25) {
-			result = Ternary();
-		} else if (la.kind == 5) {
-			Get();
-			result = Expression();
-			Expect(7);
-		} else SynErr(31);
-		return result;
-	}
-
-	TypedNode  VariableRefOrCall() {
-		TypedNode  result;
-		result = VariableRef();
-		if (la.kind == 5 || la.kind == 28) {
-			if (la.kind == 5) {
-				TypedNode[] parameters = Parameters();
-				result = factory.createCall(result, parameters); 
+	SLExpressionNode  Term() {
+		SLExpressionNode  result;
+		result = Factor();
+		while (la.kind == 27 || la.kind == 28) {
+			if (la.kind == 27) {
+				Get();
 			} else {
 				Get();
-				TypedNode assignment = Expression();
-				result = factory.createAssignment(result, assignment); 
 			}
+			Token op = t; 
+			SLExpressionNode right = Factor();
+			result = factory.createBinary(op, result, right); 
 		}
 		return result;
 	}
 
-	TypedNode  StringLiteral() {
-		TypedNode  result;
-		Expect(2);
-		result = factory.createStringLiteral(t.val.substring(1, t.val.length() - 1)); 
-		return result;
-	}
-
-	TypedNode  NumericLiteral() {
-		TypedNode  result;
-		Expect(3);
-		result = factory.createNumericLiteral(t.val); 
-		return result;
-	}
-
-	TypedNode  Ternary() {
-		TypedNode  result;
-		TypedNode condition, thenPart, elsePart; 
-		Expect(25);
-		condition = Expression();
-		Expect(26);
-		thenPart = Expression();
-		Expect(27);
-		elsePart = Expression();
-		result = factory.createTernary(condition, thenPart, elsePart); 
-		return result;
-	}
-
-	TypedNode  VariableRef() {
-		TypedNode  result;
-		Expect(1);
-		result = factory.createLocal(t.val); 
-		return result;
-	}
-
-	TypedNode[]  Parameters() {
-		TypedNode[]  result;
-		Expect(5);
-		List<TypedNode> parameters = new ArrayList<>(); 
-		if (StartOf(2)) {
-			TypedNode e1 = Expression();
-			parameters.add(e1); 
-			while (la.kind == 6) {
+	SLExpressionNode  Factor() {
+		SLExpressionNode  result;
+		result = null; 
+		if (la.kind == 1) {
+			Get();
+			Token nameToken = t; 
+			if (la.kind == 5) {
 				Get();
-				TypedNode e2 = Expression();
-				parameters.add(e2); 
-			}
-		}
-		result = parameters.toArray(new TypedNode[parameters.size()]); 
-		Expect(7);
+				List<SLExpressionNode> parameters = new ArrayList<>();
+				SLExpressionNode parameter; 
+				if (StartOf(2)) {
+					parameter = Expression();
+					parameters.add(parameter); 
+					while (la.kind == 6) {
+						Get();
+						parameter = Expression();
+						parameters.add(parameter); 
+					}
+				}
+				result = factory.createCall(nameToken, parameters); 
+				Expect(7);
+			} else if (la.kind == 29) {
+				Get();
+				SLExpressionNode value = Expression();
+				result = factory.createAssignment(nameToken, value); 
+			} else if (StartOf(4)) {
+				result = factory.createRead(nameToken); 
+			} else SynErr(32);
+		} else if (la.kind == 2) {
+			Get();
+			result = factory.createStringLiteral(t); 
+		} else if (la.kind == 3) {
+			Get();
+			result = factory.createNumericLiteral(t); 
+		} else if (la.kind == 5) {
+			Get();
+			result = Expression();
+			Expect(7);
+		} else SynErr(33);
 		return result;
 	}
 
@@ -384,35 +390,30 @@
     }
 
     private static final boolean[][] set = {
-		{T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x},
-		{x,T,T,T, x,T,x,x, x,x,x,T, x,T,T,x, x,x,x,x, x,x,x,x, x,T,x,x, x,x,x},
-		{x,T,T,T, x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,T,x,x, x,x,x},
-		{x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,T, T,T,T,T, T,x,x,x, x,x,x,x, x,x,x}
+		{T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x},
+		{x,T,T,T, x,T,x,x, x,x,T,x, T,T,T,x, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x},
+		{x,T,T,T, x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x},
+		{x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,T, T,T,T,T, T,x,x,x, x,x,x,x},
+		{x,x,x,x, x,x,T,T, x,x,x,T, x,x,x,x, x,T,T,T, T,T,T,T, T,T,T,T, T,x,x,x}
 
     };
 
-    public String ParseErrors() {
-        java.io.PrintStream oldStream = System.out;
-
-        java.io.OutputStream out = new java.io.ByteArrayOutputStream();
-        java.io.PrintStream newStream = new java.io.PrintStream(out);
-
-        errors.errorStream = newStream;
-
-        Parse();
-
-        String errorStream = out.toString();
-        errors.errorStream = oldStream;
-
-        return errorStream;
-
+    public static void parseSL(SLContext context, Source source) {
+        Parser parser = new Parser(context, source);
+        parser.Parse();
+        if (parser.errors.errors.size() > 0) {
+            StringBuilder msg = new StringBuilder("Error(s) parsing script:\n");
+            for (String error : parser.errors.errors) {
+                msg.append(error).append("\n");
+            }
+            throw new SLException(msg.toString());
+        }
     }
 } // end Parser
 
 class Errors {
 
-    public int count = 0; // number of errors detected
-    public java.io.PrintStream errorStream = System.out; // error messages go to this stream
+    protected final List<String> errors = new ArrayList<>();
     public String errMsgFormat = "-- line {0} col {1}: {2}"; // 0=line, 1=column, 2=text
 
     protected void printMsg(int line, int column, String msg) {
@@ -430,7 +431,7 @@
         pos = b.indexOf("{2}");
         if (pos >= 0)
             b.replace(pos, pos + 3, msg);
-        errorStream.println(b.toString());
+        errors.add(b.toString());
     }
 
     public void SynErr(int line, int col, int n) {
@@ -446,44 +447,43 @@
 			case 7: s = "\")\" expected"; break;
 			case 8: s = "\"{\" expected"; break;
 			case 9: s = "\"}\" expected"; break;
-			case 10: s = "\";\" expected"; break;
-			case 11: s = "\"if\" expected"; break;
-			case 12: s = "\"else\" expected"; break;
+			case 10: s = "\"break\" expected"; break;
+			case 11: s = "\";\" expected"; break;
+			case 12: s = "\"continue\" expected"; break;
 			case 13: s = "\"while\" expected"; break;
-			case 14: s = "\"return\" expected"; break;
-			case 15: s = "\"<\" expected"; break;
-			case 16: s = "\">\" expected"; break;
-			case 17: s = "\"<=\" expected"; break;
-			case 18: s = "\">=\" expected"; break;
-			case 19: s = "\"==\" expected"; break;
-			case 20: s = "\"!=\" expected"; break;
-			case 21: s = "\"+\" expected"; break;
-			case 22: s = "\"-\" expected"; break;
-			case 23: s = "\"*\" expected"; break;
-			case 24: s = "\"/\" expected"; break;
-			case 25: s = "\"#\" expected"; break;
-			case 26: s = "\"?\" expected"; break;
-			case 27: s = "\":\" expected"; break;
-			case 28: s = "\"=\" expected"; break;
-			case 29: s = "??? expected"; break;
-			case 30: s = "invalid Statement"; break;
-			case 31: s = "invalid Factor"; break;
+			case 14: s = "\"if\" expected"; break;
+			case 15: s = "\"else\" expected"; break;
+			case 16: s = "\"return\" expected"; break;
+			case 17: s = "\"||\" expected"; break;
+			case 18: s = "\"&&\" expected"; break;
+			case 19: s = "\"<\" expected"; break;
+			case 20: s = "\"<=\" expected"; break;
+			case 21: s = "\">\" expected"; break;
+			case 22: s = "\">=\" expected"; break;
+			case 23: s = "\"==\" expected"; break;
+			case 24: s = "\"!=\" expected"; break;
+			case 25: s = "\"+\" expected"; break;
+			case 26: s = "\"-\" expected"; break;
+			case 27: s = "\"*\" expected"; break;
+			case 28: s = "\"/\" expected"; break;
+			case 29: s = "\"=\" expected"; break;
+			case 30: s = "??? expected"; break;
+			case 31: s = "invalid Statement"; break;
+			case 32: s = "invalid Factor"; break;
+			case 33: s = "invalid Factor"; break;
             default:
                 s = "error " + n;
                 break;
         }
         printMsg(line, col, s);
-        count++;
     }
 
     public void SemErr(int line, int col, String s) {
         printMsg(line, col, s);
-        count++;
     }
 
     public void SemErr(String s) {
-        errorStream.println(s);
-        count++;
+        errors.add(s);
     }
 
     public void Warning(int line, int col, String s) {
@@ -491,7 +491,7 @@
     }
 
     public void Warning(String s) {
-        errorStream.println(s);
+        errors.add(s);
     }
 } // Errors
 
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/ParserUtils.java	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,46 +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.truffle.sl.parser;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.impl.*;
-
-public class ParserUtils {
-
-    public static SourceSection createSourceSection(Source source, String identifier, Parser p) {
-        Token t = p.t;
-        if (t == null) {
-            t = p.la;
-        }
-        int startLine = -1;
-        int startColumn = -1;
-        int length = 0;
-        if (t != null) {
-            startLine = t.line;
-            startColumn = t.col;
-            length = t.val.length();
-        }
-        return new DefaultSourceSection(source, identifier, startLine, startColumn, 0, length);
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/SLNodeFactory.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,251 @@
+/*
+ * 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.parser;
+
+import java.math.*;
+import java.util.*;
+
+import com.oracle.truffle.api.*;
+import com.oracle.truffle.api.frame.*;
+import com.oracle.truffle.api.impl.*;
+import com.oracle.truffle.api.nodes.*;
+import com.oracle.truffle.sl.nodes.*;
+import com.oracle.truffle.sl.nodes.call.*;
+import com.oracle.truffle.sl.nodes.controlflow.*;
+import com.oracle.truffle.sl.nodes.expression.*;
+import com.oracle.truffle.sl.nodes.local.*;
+import com.oracle.truffle.sl.runtime.*;
+
+/**
+ * Helper class used by the SL {@link Parser} to create nodes. The code is factored out of the
+ * automatically generated parser to keep the attributed grammar of SL small.
+ */
+public class SLNodeFactory {
+
+    /**
+     * Local variable names that are visible in the current block. Variables are not visible outside
+     * of their defining block, to prevent the usage of undefined variables. Because of that, we can
+     * decide during parsing if a name references a local variable or is a function name.
+     */
+    static class LexicalScope {
+        protected final LexicalScope outer;
+        protected final Map<String, FrameSlot> locals;
+
+        public LexicalScope(LexicalScope outer) {
+            this.outer = outer;
+            this.locals = new HashMap<>();
+            if (outer != null) {
+                locals.putAll(outer.locals);
+            }
+        }
+    }
+
+    /* State while parsing a source unit. */
+    private final SLContext context;
+    private final Source source;
+
+    /* State while parsing a function. */
+    private String functionName;
+    private int parameterCount;
+    private FrameDescriptor frameDescriptor;
+    private List<SLStatementNode> methodNodes;
+
+    /* State while parsing a block. */
+    private LexicalScope lexicalScope;
+
+    public SLNodeFactory(SLContext context, Source source) {
+        this.context = context;
+        this.source = source;
+    }
+
+    public void startFunction(Token nameToken) {
+        assert functionName == null;
+        assert parameterCount == 0;
+        assert frameDescriptor == null;
+        assert lexicalScope == null;
+
+        functionName = nameToken.val;
+        frameDescriptor = new FrameDescriptor();
+        methodNodes = new ArrayList<>();
+        startBlock();
+    }
+
+    public void addFormalParameter(Token nameToken) {
+        /*
+         * Method parameters are assigned to local variables at the beginning of the method. This
+         * ensures that accesses to parameters are specialized the same way as local variables are
+         * specialized.
+         */
+        SLReadArgumentNode readArg = assignSource(nameToken, new SLReadArgumentNode(parameterCount));
+        methodNodes.add(createAssignment(nameToken, readArg));
+        parameterCount++;
+    }
+
+    public void finishFunction(SLStatementNode bodyNode) {
+        methodNodes.add(bodyNode);
+        SLStatementNode methodBlock = finishBlock(methodNodes);
+        assert lexicalScope == null : "Wrong scoping of blocks in parser";
+
+        SLFunctionBodyNode functionBodyNode = new SLFunctionBodyNode(methodBlock);
+        SLRootNode rootNode = new SLRootNode(frameDescriptor, functionBodyNode, functionName);
+
+        context.getFunctionRegistry().register(functionName, rootNode);
+
+        functionName = null;
+        parameterCount = 0;
+        frameDescriptor = null;
+        lexicalScope = null;
+    }
+
+    public void startBlock() {
+        lexicalScope = new LexicalScope(lexicalScope);
+    }
+
+    public SLStatementNode finishBlock(List<SLStatementNode> bodyNodes) {
+        lexicalScope = lexicalScope.outer;
+
+        List<SLStatementNode> flattenedNodes = new ArrayList<>(bodyNodes.size());
+        flattenBlocks(bodyNodes, flattenedNodes);
+        if (flattenedNodes.size() == 1) {
+            /* A block containing one other node is unnecessary, we can just that other node. */
+            return flattenedNodes.get(0);
+        } else {
+            return new SLBlockNode(flattenedNodes.toArray(new SLStatementNode[flattenedNodes.size()]));
+        }
+    }
+
+    private void flattenBlocks(Iterable<? extends Node> bodyNodes, List<SLStatementNode> flattenedNodes) {
+        for (Node n : bodyNodes) {
+            if (n instanceof SLBlockNode) {
+                flattenBlocks(n.getChildren(), flattenedNodes);
+            } else {
+                flattenedNodes.add((SLStatementNode) n);
+            }
+        }
+    }
+
+    public SLStatementNode createBreak(Token t) {
+        return assignSource(t, new SLBreakNode());
+    }
+
+    public SLStatementNode createContinue(Token t) {
+        return assignSource(t, new SLContinueNode());
+    }
+
+    public SLStatementNode createWhile(Token t, SLExpressionNode conditionNode, SLStatementNode bodyNode) {
+        return assignSource(t, new SLWhileNode(conditionNode, bodyNode));
+    }
+
+    public SLStatementNode createIf(Token t, SLExpressionNode conditionNode, SLStatementNode thenPartNode, SLStatementNode elsePartNode) {
+        return assignSource(t, new SLIfNode(conditionNode, thenPartNode, elsePartNode));
+    }
+
+    public SLStatementNode createReturn(Token t, SLExpressionNode valueNode) {
+        return assignSource(t, new SLReturnNode(valueNode));
+    }
+
+    public SLExpressionNode createBinary(Token opToken, SLExpressionNode leftNode, SLExpressionNode rightNode) {
+        switch (opToken.val) {
+            case "+":
+                return assignSource(opToken, SLAddNodeFactory.create(leftNode, rightNode));
+            case "*":
+                return assignSource(opToken, SLMulNodeFactory.create(leftNode, rightNode));
+            case "/":
+                return assignSource(opToken, SLDivNodeFactory.create(leftNode, rightNode));
+            case "-":
+                return assignSource(opToken, SLSubNodeFactory.create(leftNode, rightNode));
+            case "<":
+                return assignSource(opToken, SLLessThanNodeFactory.create(leftNode, rightNode));
+            case "<=":
+                return assignSource(opToken, SLLessOrEqualNodeFactory.create(leftNode, rightNode));
+            case ">":
+                return assignSource(opToken, SLLogicalNotNodeFactory.create(assignSource(opToken, SLLessOrEqualNodeFactory.create(leftNode, rightNode))));
+            case ">=":
+                return assignSource(opToken, SLLogicalNotNodeFactory.create(assignSource(opToken, SLLessThanNodeFactory.create(leftNode, rightNode))));
+            case "==":
+                return assignSource(opToken, SLEqualNodeFactory.create(leftNode, rightNode));
+            case "!=":
+                return assignSource(opToken, SLLogicalNotNodeFactory.create(assignSource(opToken, SLEqualNodeFactory.create(leftNode, rightNode))));
+            case "&&":
+                return assignSource(opToken, SLLogicalAndNodeFactory.create(leftNode, rightNode));
+            case "||":
+                return assignSource(opToken, SLLogicalOrNodeFactory.create(leftNode, rightNode));
+            default:
+                throw new RuntimeException("unexpected operation: " + opToken.val);
+        }
+    }
+
+    public SLExpressionNode createCall(Token nameToken, List<SLExpressionNode> parameterNodes) {
+        SLExpressionNode functionNode = createRead(nameToken);
+        return assignSource(nameToken, SLInvokeNode.create(functionNode, parameterNodes.toArray(new SLExpressionNode[parameterNodes.size()])));
+    }
+
+    public SLExpressionNode createAssignment(Token nameToken, SLExpressionNode valueNode) {
+        FrameSlot frameSlot = frameDescriptor.findOrAddFrameSlot(nameToken.val);
+        lexicalScope.locals.put(nameToken.val, frameSlot);
+        return assignSource(nameToken, SLWriteLocalVariableNodeFactory.create(valueNode, frameSlot));
+    }
+
+    public SLExpressionNode createRead(Token nameToken) {
+        FrameSlot frameSlot = lexicalScope.locals.get(nameToken.val);
+        if (frameSlot != null) {
+            /* Read of a local variable. */
+            return assignSource(nameToken, SLReadLocalVariableNodeFactory.create(frameSlot));
+        } else {
+            /* Read of a global name. In our language, the only global names are functions. */
+            return assignSource(nameToken, new SLFunctionLiteralNode(context.getFunctionRegistry().lookup(nameToken.val)));
+        }
+    }
+
+    public SLExpressionNode createStringLiteral(Token literalToken) {
+        /* Remove the trailing and ending " */
+        String literal = literalToken.val;
+        assert literal.length() >= 2 && literal.startsWith("\"") && literal.endsWith("\"");
+        literal = literal.substring(1, literal.length() - 1);
+
+        return assignSource(literalToken, new SLStringLiteralNode(literal));
+    }
+
+    public SLExpressionNode createNumericLiteral(Token literalToken) {
+        try {
+            /* Try if the literal is small enough to fit into a long value. */
+            return assignSource(literalToken, new SLLongLiteralNode(Long.parseLong(literalToken.val)));
+        } catch (NumberFormatException ex) {
+            /* Overflow of long value, so fall back to BigInteger. */
+            return assignSource(literalToken, new SLBigIntegerLiteralNode(new BigInteger(literalToken.val)));
+        }
+    }
+
+    private <T extends Node> T assignSource(Token t, T node) {
+        assert functionName != null;
+        assert t != null;
+
+        int startLine = t.line;
+        int startColumn = t.col;
+        int charLength = t.val.length();
+        SourceSection sourceSection = new DefaultSourceSection(source, functionName, startLine, startColumn, 0, charLength);
+
+        node.assignSourceSection(sourceSection);
+        return node;
+    }
+}
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/Scanner.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/Scanner.java	Wed Mar 05 19:40:15 2014 -0800
@@ -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
@@ -311,8 +311,8 @@
 
     static final char EOL = '\n';
     static final int eofSym = 0;
-	static final int maxT = 29;
-	static final int noSym = 29;
+	static final int maxT = 30;
+	static final int noSym = 30;
 
 
     public Buffer buffer; // scanner buffer
@@ -347,23 +347,24 @@
 		start.set(123, 9); 
 		start.set(125, 10); 
 		start.set(59, 11); 
-		start.set(60, 24); 
-		start.set(62, 25); 
-		start.set(61, 26); 
-		start.set(33, 15); 
-		start.set(43, 17); 
-		start.set(45, 18); 
-		start.set(42, 19); 
-		start.set(47, 20); 
-		start.set(35, 21); 
-		start.set(63, 22); 
-		start.set(58, 23); 
+		start.set(124, 12); 
+		start.set(38, 14); 
+		start.set(60, 25); 
+		start.set(62, 26); 
+		start.set(61, 27); 
+		start.set(33, 19); 
+		start.set(43, 21); 
+		start.set(45, 22); 
+		start.set(42, 23); 
+		start.set(47, 24); 
 		start.set(Buffer.EOF, -1);
 		literals.put("function", new Integer(4));
-		literals.put("if", new Integer(11));
-		literals.put("else", new Integer(12));
+		literals.put("break", new Integer(10));
+		literals.put("continue", new Integer(12));
 		literals.put("while", new Integer(13));
-		literals.put("return", new Integer(14));
+		literals.put("if", new Integer(14));
+		literals.put("else", new Integer(15));
+		literals.put("return", new Integer(16));
 
     }
 
@@ -519,69 +520,73 @@
                 } // NextCh already done
 				case 1:
 					recEnd = pos; recKind = 1;
-					if (ch >= '0' && ch <= '9' || ch >= 'A' && ch <= 'Z' || ch >= 'a' && ch <= 'z') {AddCh(); state = 1; break;}
+					if (ch >= '0' && ch <= '9' || ch >= 'A' && ch <= 'Z' || ch >= 'a' && ch <= 'z') {AddCh(); state = 1; break;}
 					else {t.kind = 1; t.val = new String(tval, 0, tlen); CheckLiteral(); return t;}
 				case 2:
-					if (ch <= 9 || ch >= 11 && ch <= 12 || ch >= 14 && ch <= '!' || ch >= '#' && ch <= '[' || ch >= ']' && ch <= 65535) {AddCh(); state = 2; break;}
-					else if (ch == '"') {AddCh(); state = 3; break;}
+					if (ch <= 9 || ch >= 11 && ch <= 12 || ch >= 14 && ch <= '!' || ch >= '#' && ch <= '[' || ch >= ']' && ch <= 65535) {AddCh(); state = 2; break;}
+					else if (ch == '"') {AddCh(); state = 3; break;}
 					else {state = 0; break;}
-				case 3:
+				case 3:
 					{t.kind = 2; break loop;}
 				case 4:
 					recEnd = pos; recKind = 3;
-					if (ch >= '0' && ch <= '9') {AddCh(); state = 4; break;}
+					if (ch >= '0' && ch <= '9') {AddCh(); state = 4; break;}
 					else {t.kind = 3; break loop;}
-				case 5:
+				case 5:
 					{t.kind = 3; break loop;}
-				case 6:
+				case 6:
 					{t.kind = 5; break loop;}
-				case 7:
+				case 7:
 					{t.kind = 6; break loop;}
-				case 8:
+				case 8:
 					{t.kind = 7; break loop;}
-				case 9:
+				case 9:
 					{t.kind = 8; break loop;}
-				case 10:
+				case 10:
 					{t.kind = 9; break loop;}
-				case 11:
-					{t.kind = 10; break loop;}
-				case 12:
+				case 11:
+					{t.kind = 11; break loop;}
+				case 12:
+					if (ch == '|') {AddCh(); state = 13; break;}
+					else {state = 0; break;}
+				case 13:
 					{t.kind = 17; break loop;}
-				case 13:
+				case 14:
+					if (ch == '&') {AddCh(); state = 15; break;}
+					else {state = 0; break;}
+				case 15:
 					{t.kind = 18; break loop;}
-				case 14:
-					{t.kind = 19; break loop;}
-				case 15:
-					if (ch == '=') {AddCh(); state = 16; break;}
-					else {state = 0; break;}
-				case 16:
+				case 16:
 					{t.kind = 20; break loop;}
-				case 17:
-					{t.kind = 21; break loop;}
-				case 18:
+				case 17:
 					{t.kind = 22; break loop;}
-				case 19:
+				case 18:
 					{t.kind = 23; break loop;}
-				case 20:
+				case 19:
+					if (ch == '=') {AddCh(); state = 20; break;}
+					else {state = 0; break;}
+				case 20:
 					{t.kind = 24; break loop;}
-				case 21:
+				case 21:
 					{t.kind = 25; break loop;}
-				case 22:
+				case 22:
 					{t.kind = 26; break loop;}
-				case 23:
+				case 23:
 					{t.kind = 27; break loop;}
 				case 24:
-					recEnd = pos; recKind = 15;
-					if (ch == '=') {AddCh(); state = 12; break;}
-					else {t.kind = 15; break loop;}
+					{t.kind = 28; break loop;}
 				case 25:
-					recEnd = pos; recKind = 16;
-					if (ch == '=') {AddCh(); state = 13; break;}
-					else {t.kind = 16; break loop;}
+					recEnd = pos; recKind = 19;
+					if (ch == '=') {AddCh(); state = 16; break;}
+					else {t.kind = 19; break loop;}
 				case 26:
-					recEnd = pos; recKind = 28;
-					if (ch == '=') {AddCh(); state = 14; break;}
-					else {t.kind = 28; break loop;}
+					recEnd = pos; recKind = 21;
+					if (ch == '=') {AddCh(); state = 17; break;}
+					else {t.kind = 21; break loop;}
+				case 27:
+					recEnd = pos; recKind = 29;
+					if (ch == '=') {AddCh(); state = 18; break;}
+					else {t.kind = 29; break loop;}
 
             }
         }
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/SimpleLanguage.atg	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/SimpleLanguage.atg	Wed Mar 05 19:40:15 2014 -0800
@@ -1,3 +1,32 @@
+/*
+ * 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.
+ */
+
+/*
+ * This is the grammar of SL that is used to automatically generate the Parser.java and Scanner.java
+ * files. You can download the parser generator Coco/R from http://ssw.jku.at/coco/. Then run
+ * "java -jar Coco.jar SimpleLanguage.atg"
+ */
+
 COMPILER SimpleLanguage
 
 CHARACTERS
@@ -24,6 +53,7 @@
 
 PRODUCTIONS
 
+
 SimpleLanguage
 =
 Function 
@@ -32,32 +62,48 @@
 }
 .
 
+
 Function
 =
-"function"                                      (. factory.startFunction(); .)
-identifier                                      (. String name = t.val; 
-                                                   List<String> parameterNames = new ArrayList<>(); .)
-["(" [identifier                                (. parameterNames.add(t.val); .)
-] {"," identifier                               (. parameterNames.add(t.val); .)
-} ")"]
-Block<out StatementNode body>                   (. factory.createFunction(body, name, parameterNames.toArray(new String[parameterNames.size()])); .)
+"function"                                      
+identifier                                      (. factory.startFunction(t); .)
+"("
+[
+    identifier                                  (. factory.addFormalParameter(t); .)
+    {
+        "," 
+        identifier                              (. factory.addFormalParameter(t); .)
+    }    
+]
+")"
+Block<out SLStatementNode body, false>          (. factory.finishFunction(body); .)
 .
 
-Block<out StatementNode result>
-=                                               (. List<StatementNode> statements = new ArrayList<>(); .)
+
+
+Block<out SLStatementNode result, boolean inLoop>
+=                                               (. factory.startBlock();
+                                                   List<SLStatementNode> body = new ArrayList<>(); .)
 "{" 
 {
-    Statement<out StatementNode statement>      (. statements.add(statement); .)
+    Statement<out SLStatementNode s, inLoop>    (. body.add(s); .)
 }
-"}"                                             (. result = factory.createBlock(statements); .)
+"}"                                             (. result = factory.finishBlock(body); .)
 .
 
-Statement<out StatementNode result>
+
+Statement<out SLStatementNode result, boolean inLoop>
 =                                               (. result = null; .)
 (
     WhileStatement<out result>
+|
+    "break"                                     (. if (inLoop) { result = factory.createBreak(t); } else { SemErr("break used outside of loop"); } .)
+    ";"
+|
+    "continue"                                  (. if (inLoop) { result = factory.createContinue(t); } else { SemErr("continue used outside of loop"); } .)
+    ";"
 |   
-    IfStatement<out result>
+    IfStatement<out result, inLoop>
 |
     ReturnStatement<out result>
 |
@@ -65,109 +111,121 @@
 )
 .
 
-IfStatement<out StatementNode result>
+
+WhileStatement<out SLStatementNode result>
 =
-"if" "(" Expression<out ConditionNode condition> ")"  (. StatementNode thenNode = null; StatementNode elseNode = null; .)
-Block<out thenNode>                             
-["else" Block<out elseNode>]                    (. result = factory.createIf(condition, thenNode, elseNode); .)
+"while"
+"("                                             (. Token whileToken = t; .)
+Expression<out SLExpressionNode condition>
+")" 
+Block<out SLStatementNode body, true>           (. result = factory.createWhile(whileToken, condition, body); .)
+.
+
+
+IfStatement<out SLStatementNode result, boolean inLoop>
+=
+"if" 
+"("                                             (. Token ifToken = t; .)
+Expression<out SLExpressionNode condition> 
+")"
+Block<out SLStatementNode thenPart, inLoop>     (. SLStatementNode elsePart = null; .)                             
+[
+    "else" 
+    Block<out elsePart, inLoop>
+]                                               (. result = factory.createIf(ifToken, condition, thenPart, elsePart); .)
 .
 
-WhileStatement<out StatementNode result>
+
+ReturnStatement<out SLStatementNode result>
+=
+"return"                                        (. Token returnToken = t;
+                                                   SLExpressionNode value = null; .)
+[
+    Expression<out value>
+]                                               (. result = factory.createReturn(returnToken, value); .)
+";"
+.
+
+
+Expression<out SLExpressionNode result>
 =
-"while"
-"("
-Expression<out ConditionNode condition>
-")" 
-Block<out StatementNode body>                   (. result = factory.createWhile(condition, body); .)
+LogicTerm<out result>
+{
+    "||"                                        (. Token op = t; .)
+    LogicTerm<out SLExpressionNode right>       (. result = factory.createBinary(op, result, right); .)
+}
+.
+
+
+LogicTerm<out SLExpressionNode result>
+=
+LogicFactor<out result>
+{
+    "&&"                                        (. Token op = t; .)
+    LogicFactor<out SLExpressionNode right>     (. result = factory.createBinary(op, result, right); .)
+}
 .
 
 
-ReturnStatement<out StatementNode result>
+LogicFactor<out SLExpressionNode result>
 =
-"return"
-Expression<out TypedNode value> ";"             (. result = factory.createReturn(value); .)
-.
-
-Expression<out TypedNode result>
-=
-ValueExpression<out result>
+Arithmetic<out result>
 [
-    ("<" | ">" | "<=" | ">=" | "==" | "!=" )    (.  String op = t.val; .)
-    ValueExpression<out TypedNode right>        (.  result = factory.createBinary(op, result, right); .)
+    ("<" | "<=" | ">" | ">=" | "==" | "!=" )    (. Token op = t; .)
+    Arithmetic<out SLExpressionNode right>      (.  result = factory.createBinary(op, result, right); .)
 ]
 .
 
-ValueExpression<out TypedNode result>
+
+Arithmetic<out SLExpressionNode result>
 =
 Term<out result>
 {
-    ("+" | "-")                                 (. String op = t.val; .)
-    Term<out TypedNode right>                   (. result = factory.createBinary(op, result, right); .)
+    ("+" | "-")                                 (. Token op = t; .)
+    Term<out SLExpressionNode right>            (. result = factory.createBinary(op, result, right); .)
 }
 .
 
-Term<out TypedNode result>
+
+Term<out SLExpressionNode result>
 =
 Factor<out result>
 {
-    ("*" | "/")                                 (. String op = t.val; .)
-    Factor<out TypedNode right>                 (. result = factory.createBinary(op, result, right); .)
+    ("*" | "/")                                 (. Token op = t; .)
+    Factor<out SLExpressionNode right>          (. result = factory.createBinary(op, result, right); .)
 }
 .
 
-Factor<out TypedNode result>
+
+Factor<out SLExpressionNode result>
 =                                               (. result = null; .)
 (
-    VariableRefOrCall<out result>
-|
-    StringLiteral<out result>
+    identifier                                  (. Token nameToken = t; .)
+    (
+        "("                                     (. List<SLExpressionNode> parameters = new ArrayList<>();
+                                                   SLExpressionNode parameter; .)
+        [
+            Expression<out parameter>           (. parameters.add(parameter); .)
+            {
+                "," 
+                Expression<out parameter>       (. parameters.add(parameter); .)
+            }                                               
+        ]                                       (. result = factory.createCall(nameToken, parameters); .) 
+        ")"
+    |
+        "=" 
+        Expression<out SLExpressionNode value>  (. result = factory.createAssignment(nameToken, value); .)
+    |
+                                                (. result = factory.createRead(nameToken); .)
+    )
 |
-    NumericLiteral<out result>
+    stringLiteral                               (. result = factory.createStringLiteral(t); .)
 |
-    Ternary<out result>
+    numericLiteral                              (. result = factory.createNumericLiteral(t); .)
 |
     "(" Expression<out result> ")"
 ) 
 .
 
-Ternary<out TypedNode result>                   (. TypedNode condition, thenPart, elsePart; .)
-=
-"#" Expression<out condition> "?" Expression<out thenPart> ":" Expression<out elsePart>
-                                                (. result = factory.createTernary(condition, thenPart, elsePart); .)
-.
-
-VariableRefOrCall<out TypedNode result> 
-=
-VariableRef<out result>                  
-[
-  (Parameters<out TypedNode[] parameters>)      (. result = factory.createCall(result, parameters); .)
-| ("=" Expression<out TypedNode assignment>)    (. result = factory.createAssignment(result, assignment); .)
-]
-.
-
-Parameters<out TypedNode[] result> 
-=      
-"("                                         (. List<TypedNode> parameters = new ArrayList<>(); .)
-[Expression<out TypedNode e1>                   (. parameters.add(e1); .)
-{"," Expression<out TypedNode e2>               (. parameters.add(e2); .)
-}                                               
-]                                           (. result = parameters.toArray(new TypedNode[parameters.size()]); .) 
-")"
-.
-
-VariableRef<out TypedNode result>
-=
-identifier                                      (. result = factory.createLocal(t.val); .)
-.
-
-StringLiteral<out TypedNode result>
-=
-stringLiteral                                   (. result = factory.createStringLiteral(t.val.substring(1, t.val.length() - 1)); .)
-.
-
-NumericLiteral<out TypedNode result>
-=
-numericLiteral                                  (. result = factory.createNumericLiteral(t.val); .)
-.
 
 END SimpleLanguage.
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/runtime/SLArguments.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/runtime/SLArguments.java	Wed Mar 05 19:40:15 2014 -0800
@@ -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
@@ -24,16 +24,28 @@
 
 import com.oracle.truffle.api.*;
 import com.oracle.truffle.api.frame.*;
+import com.oracle.truffle.sl.nodes.call.*;
+import com.oracle.truffle.sl.nodes.local.*;
 
+/**
+ * Encapsulation of SL function arguments, as required by the Truffle API. An instance of this class
+ * is allocated by the caller, and read by the callee.
+ */
 public final class SLArguments extends Arguments {
 
-    public final Object[] arguments;
+    private final Object[] argumentValues;
 
+    /**
+     * Used by the caller, i.e., the {@link SLInvokeNode node that performs a function call}.
+     */
     public SLArguments(Object[] arguments) {
-        this.arguments = arguments;
+        this.argumentValues = arguments;
     }
 
-    public static SLArguments get(VirtualFrame frame) {
-        return frame.getArguments(SLArguments.class);
+    /**
+     * Used by the callee, i.e., the {@link SLReadArgumentNode note that reads a function argument}.
+     */
+    public static Object[] getFromFrame(VirtualFrame frame) {
+        return frame.getArguments(SLArguments.class).argumentValues;
     }
 }
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/runtime/SLContext.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/runtime/SLContext.java	Wed Mar 05 19:40:15 2014 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2013, 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
@@ -24,32 +24,105 @@
 
 import java.io.*;
 
+import com.oracle.truffle.api.dsl.*;
+import com.oracle.truffle.api.frame.*;
+import com.oracle.truffle.api.nodes.*;
 import com.oracle.truffle.api.source.*;
 import com.oracle.truffle.sl.builtins.*;
-
-public final class SLContext {
+import com.oracle.truffle.sl.nodes.*;
+import com.oracle.truffle.sl.nodes.local.*;
+import com.oracle.truffle.sl.parser.*;
 
-    private final PrintStream printOutput;
-    private final SLFunctionRegistry functionRegistry;
+/**
+ * The run-time state of SL during execution. One context is instantiated before any source code is
+ * parsed, and this context is passed around to all methods that need access to it. For example, the
+ * context is used during {@link SLNodeFactory parsing} and by {@link SLBuiltinNode#getContext()
+ * builtin functions}.
+ * <p>
+ * It would be an error to have two different context instances during the execution of one script.
+ * However, if two separate scripts run in one Java VM at the same time, they have a different
+ * context. Therefore, the context is not a singleton.
+ */
+public final class SLContext {
     private final SourceManager sourceManager;
+    private final BufferedReader input;
+    private final PrintStream output;
+    private final SLFunctionRegistry functionRegistry;
 
-    public SLContext(PrintStream print) {
-        this.printOutput = print;
+    public SLContext(SourceManager sourceManager, BufferedReader input, PrintStream output) {
+        this.sourceManager = sourceManager;
+        this.input = input;
+        this.output = output;
         this.functionRegistry = new SLFunctionRegistry();
-        DefaultBuiltins.install(this);
-        this.sourceManager = new SourceManager();
+
+        installBuiltins();
     }
 
-    public PrintStream getPrintOutput() {
-        return printOutput;
+    /**
+     * Returns the source manger that controls all SL source code that is executed.
+     */
+    public SourceManager getSourceManager() {
+        return sourceManager;
     }
 
+    /**
+     * Returns the default input, i.e., the source for the {@link SLReadlnBuiltin}. To allow unit
+     * testing, we do not use {@link System#in} directly.
+     */
+    public BufferedReader getInput() {
+        return input;
+    }
+
+    /**
+     * The default default, i.e., the output for the {@link SLPrintlnBuiltin}. To allow unit
+     * testing, we do not use {@link System#out} directly.
+     */
+    public PrintStream getOutput() {
+        return output;
+    }
+
+    /**
+     * Returns the registry of all functions that are currently defined.
+     */
     public SLFunctionRegistry getFunctionRegistry() {
         return functionRegistry;
     }
 
-    public SourceManager getSourceManager() {
-        return sourceManager;
+    /**
+     * Adds all builtin functions to the {@link SLFunctionRegistry}. This method lists all
+     * {@link SLBuiltinNode builtin implementation classes}.
+     */
+    private void installBuiltins() {
+        installBuiltin(SLReadlnBuiltinFactory.getInstance());
+        installBuiltin(SLPrintlnBuiltinFactory.getInstance());
+        installBuiltin(SLNanoTimeBuiltinFactory.getInstance());
+        installBuiltin(SLDefineFunctionBuiltinFactory.getInstance());
     }
 
+    private void installBuiltin(NodeFactory<? extends SLBuiltinNode> factory) {
+        /*
+         * The builtin node factory is a class that is automatically generated by the Truffle DSL.
+         * The signature returned by the factory reflects the signature of the @Specialization
+         * methods in the builtin classes.
+         */
+        int argumentCount = factory.getExecutionSignature().size();
+        SLExpressionNode[] argumentNodes = new SLExpressionNode[argumentCount];
+        /*
+         * Builtin functions are like normal functions, i.e., the arguments are passed in as an
+         * Object[] array encapsulated in SLArguments. A SLReadArgumentNode extracts a parameter
+         * from this array.
+         */
+        for (int i = 0; i < argumentCount; i++) {
+            argumentNodes[i] = new SLReadArgumentNode(i);
+        }
+        /* Instantiate the builtin node. This node performs the actual functionality. */
+        SLBuiltinNode builtinBodyNode = factory.createNode(argumentNodes, this);
+        /* The name of the builtin function is specified via an annotation on the node class. */
+        String name = builtinBodyNode.getClass().getAnnotation(NodeInfo.class).shortName();
+        /* Wrap the builtin in a RootNode. Truffle requires all AST to start with a RootNode. */
+        SLRootNode rootNode = new SLRootNode(new FrameDescriptor(), builtinBodyNode, name);
+
+        /* Register the builtin function in our function registry. */
+        getFunctionRegistry().register(name, rootNode);
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/runtime/SLFunction.java	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,93 @@
+/*
+ * 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.truffle.sl.runtime;
+
+import com.oracle.truffle.api.*;
+import com.oracle.truffle.api.utilities.*;
+
+/**
+ * Represents a SL function. On the Truffle level, a callable element is represented by a
+ * {@link RootCallTarget call target}. This class encapsulates a call target, and adds version
+ * support: functions in SL can be redefined, i.e. changed at run time. When a function is
+ * redefined, the call target managed by this function object is changed (and {@link #callTarget} is
+ * therefore not a final field).
+ * <p>
+ * Function redefinition is expected to be rare, therefore optimized call nodes want to speculate
+ * that the call target is stable. This is possible with the help of a Truffle {@link Assumption}: a
+ * call node can keep the call target returned by {@link #getCallTarget()} cached until the
+ * assumption returned by {@link #getCallTargetStable()} is valid.
+ * <p>
+ * The {@link #callTarget} can be {@code null}. To ensure that only one {@link SLFunction} instance
+ * per name exists, the {@link SLFunctionRegistry} creates an instance also when performing name
+ * lookup. A function that has been looked up, i.e., used, but not defined, has no call target.
+ */
+public final class SLFunction {
+
+    /** The name of the function. */
+    private final String name;
+
+    /** The current implementation of this function. */
+    private RootCallTarget callTarget;
+
+    /**
+     * Manages the assumption that the {@link #callTarget} is stable. We use the utility class
+     * {@link CyclicAssumption}, which automatically creates a new {@link Assumption} when the old
+     * one gets invalidated.
+     */
+    private final CyclicAssumption callTargetStable;
+
+    protected SLFunction(String name) {
+        this.name = name;
+        this.callTargetStable = new CyclicAssumption(name);
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    protected void setCallTarget(RootCallTarget callTarget) {
+        this.callTarget = callTarget;
+        /*
+         * We have a new call target. Invalidate all code that speculated that the old call target
+         * was stable.
+         */
+        callTargetStable.invalidate();
+    }
+
+    public RootCallTarget getCallTarget() {
+        return callTarget;
+    }
+
+    public Assumption getCallTargetStable() {
+        return callTargetStable.getAssumption();
+    }
+
+    /**
+     * This method is, e.g., called when using a function literal in a string concatenation. So
+     * changing it has an effect on SL programs.
+     */
+    @Override
+    public String toString() {
+        return name;
+    }
+}
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/runtime/SLFunctionRegistry.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/runtime/SLFunctionRegistry.java	Wed Mar 05 19:40:15 2014 -0800
@@ -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
@@ -25,20 +25,49 @@
 import java.util.*;
 
 import com.oracle.truffle.api.*;
+import com.oracle.truffle.sl.nodes.*;
 
+/**
+ * Manages the mapping from function names to {@link SLFunction function objects}.
+ */
 public final class SLFunctionRegistry {
 
-    private Map<String, CallTarget> map = new HashMap<>();
+    private final Map<String, SLFunction> functions = new HashMap<>();
 
-    public void register(String name, CallTarget target) {
-        if (map.containsKey(name)) {
-            throw new IllegalArgumentException(String.format("Function with name '%s' already exists.", name));
+    /**
+     * Returns the canonical {@link SLFunction} object for the given name. If it does not exist yet,
+     * it is created.
+     */
+    public SLFunction lookup(String name) {
+        SLFunction result = functions.get(name);
+        if (result == null) {
+            result = new SLFunction(name);
+            functions.put(name, result);
         }
-        map.put(name, target);
+        return result;
     }
 
-    public CallTarget lookup(String name) {
-        return map.get(name);
+    /**
+     * Associates the {@link SLFunction} with the given name with the given implementation root
+     * node. If the function did not exist before, it defines the function. If the function existed
+     * before, it redefines the function and the old implementation is discarded.
+     */
+    public void register(String name, SLRootNode rootNode) {
+        SLFunction function = lookup(name);
+        RootCallTarget callTarget = Truffle.getRuntime().createCallTarget(rootNode);
+        function.setCallTarget(callTarget);
     }
 
+    /**
+     * Returns the sorted list of all functions, for printing purposes only.
+     */
+    public List<SLFunction> getFunctions() {
+        List<SLFunction> result = new ArrayList<>(functions.values());
+        Collections.sort(result, new Comparator<SLFunction>() {
+            public int compare(SLFunction f1, SLFunction f2) {
+                return f1.toString().compareTo(f2.toString());
+            }
+        });
+        return result;
+    }
 }
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/runtime/SLNull.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/runtime/SLNull.java	Wed Mar 05 19:40:15 2014 -0800
@@ -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
@@ -22,11 +22,34 @@
  */
 package com.oracle.truffle.sl.runtime;
 
+/**
+ * The SL type for a {@code null} (i.e., undefined) value. In Truffle, it is generally discouraged
+ * to use the Java {@code null} value to represent the guest language {@code null} value. It is not
+ * possible to specialize on Java {@code null} (since you cannot ask it for the Java class), and
+ * there is always the danger of a spurious {@link NullPointerException}. Representing the guest
+ * language {@code null} as a singleton, as in {@link #SINGLETON this class}, is the recommended
+ * practice.
+ * */
 public final class SLNull {
 
-    public static final SLNull INSTANCE = new SLNull();
+    /**
+     * The canonical value to represent {@code null} in SL.
+     */
+    public static final SLNull SINGLETON = new SLNull();
 
+    /**
+     * Disallow instantiation from outside to ensure that the {@link #SINGLETON} is the only
+     * instance.
+     */
     private SLNull() {
     }
 
+    /**
+     * This method is, e.g., called when using the {@code null} value in a string concatenation. So
+     * changing it has an effect on SL programs.
+     */
+    @Override
+    public String toString() {
+        return "null";
+    }
 }
--- a/hotspot/.project	Sun Feb 23 17:00:35 2014 -0800
+++ b/hotspot/.project	Wed Mar 05 19:40:15 2014 -0800
@@ -86,41 +86,6 @@
 	</natures>
 	<linkedResources>
 		<link>
-			<name>ptx</name>
-			<type>2</type>
-			<locationURI>PARENT-1-PROJECT_LOC/src/gpu/ptx</locationURI>
-		</link>
-		<link>
-			<name>x86</name>
-			<type>2</type>
-			<locationURI>PARENT-1-PROJECT_LOC/src/cpu/x86/vm</locationURI>
-		</link>
-		<link>
-			<name>ptx</name>
-			<type>2</type>
-			<locationURI>PARENT-1-PROJECT_LOC/src/gpu/ptx/vm</locationURI>
-		</link>
-		<link>
-			<name>hsail</name>
-			<type>2</type>
-			<locationURI>PARENT-1-PROJECT_LOC/src/gpu/hsail/vm</locationURI>
-		</link>
-		<link>
-			<name>sparc</name>
-			<type>2</type>
-			<locationURI>PARENT-1-PROJECT_LOC/src/cpu/sparc/vm</locationURI>
-		</link>
-		<link>
-			<name>generated</name>
-			<type>2</type>
-			<locationURI>PARENT-1-PROJECT_LOC/build/linux/linux_amd64_graal/generated</locationURI>
-		</link>
-		<link>
-			<name>make</name>
-			<type>2</type>
-			<locationURI>WORKSPACE_LOC/make</locationURI>
-		</link>
-		<link>
 			<name>bsd</name>
 			<type>2</type>
 			<locationURI>PARENT-1-PROJECT_LOC/src/os/bsd/vm</locationURI>
@@ -131,9 +96,49 @@
 			<locationURI>PARENT-1-PROJECT_LOC/src/os_cpu/bsd_x86/vm</locationURI>
 		</link>
 		<link>
-			<name>bsd_ptx</name>
+			<name>generated</name>
+			<type>2</type>
+			<locationURI>PARENT-1-PROJECT_LOC/build/linux/linux_amd64_graal/generated</locationURI>
+		</link>
+		<link>
+			<name>hsail</name>
+			<type>2</type>
+			<locationURI>PARENT-1-PROJECT_LOC/src/gpu/hsail/vm</locationURI>
+		</link>
+		<link>
+			<name>linux</name>
+			<type>2</type>
+			<locationURI>PARENT-1-PROJECT_LOC/src/os/linux/vm</locationURI>
+		</link>
+		<link>
+			<name>linux_sparc</name>
+			<type>2</type>
+			<locationURI>PARENT-1-PROJECT_LOC/src/os_cpu/linux_sparc/vm</locationURI>
+		</link>
+		<link>
+			<name>linux_x86</name>
 			<type>2</type>
-			<locationURI>PARENT-1-PROJECT_LOC/src/os_gpu/bsd_ptx/vm</locationURI>
+			<locationURI>PARENT-1-PROJECT_LOC/src/os_cpu/linux_x86/vm</locationURI>
+		</link>
+		<link>
+			<name>make</name>
+			<type>2</type>
+			<locationURI>WORKSPACE_LOC/make</locationURI>
+		</link>
+		<link>
+			<name>ptx</name>
+			<type>2</type>
+			<locationURI>PARENT-1-PROJECT_LOC/src/gpu/ptx/vm</locationURI>
+		</link>
+		<link>
+			<name>sparc</name>
+			<type>2</type>
+			<locationURI>PARENT-1-PROJECT_LOC/src/cpu/sparc/vm</locationURI>
+		</link>
+		<link>
+			<name>vm</name>
+			<type>2</type>
+			<locationURI>PARENT-1-PROJECT_LOC/src/share/vm</locationURI>
 		</link>
 		<link>
 			<name>windows</name>
@@ -146,34 +151,9 @@
 			<locationURI>PARENT-1-PROJECT_LOC/src/os_cpu/windows_x86/vm</locationURI>
 		</link>
 		<link>
-			<name>linux</name>
-			<type>2</type>
-			<locationURI>PARENT-1-PROJECT_LOC/src/os/linux/vm</locationURI>
-		</link>
-		<link>
-			<name>linux_x86</name>
-			<type>2</type>
-			<locationURI>PARENT-1-PROJECT_LOC/src/os_cpu/linux_x86/vm</locationURI>
-		</link>
-		<link>
-			<name>windows_hsail</name>
+			<name>x86</name>
 			<type>2</type>
-			<locationURI>PARENT-1-PROJECT_LOC/src/os_gpu/windows_hsail/vm</locationURI>
-		</link>
-		<link>
-			<name>linux_ptx</name>
-			<type>2</type>
-			<locationURI>PARENT-1-PROJECT_LOC/src/os_gpu/linux_ptx/vm</locationURI>
-		</link>
-		<link>
-			<name>linux_sparc</name>
-			<type>2</type>
-			<locationURI>PARENT-1-PROJECT_LOC/src/os_cpu/linux_sparc/vm</locationURI>
-		</link>
-		<link>
-			<name>vm</name>
-			<type>2</type>
-			<locationURI>PARENT-1-PROJECT_LOC/src/share/vm</locationURI>
+			<locationURI>PARENT-1-PROJECT_LOC/src/cpu/x86/vm</locationURI>
 		</link>
 	</linkedResources>
 </projectDescription>
--- a/make/bsd/makefiles/buildtree.make	Sun Feb 23 17:00:35 2014 -0800
+++ b/make/bsd/makefiles/buildtree.make	Wed Mar 05 19:40:15 2014 -0800
@@ -239,8 +239,6 @@
 	echo "$(call gamma-path,commonsrc,cpu/$(SRCARCH)/vm) \\"; \
 	echo "$(call gamma-path,altsrc,os_cpu/$(OS_FAMILY)_$(SRCARCH)/vm) \\"; \
 	echo "$(call gamma-path,commonsrc,os_cpu/$(OS_FAMILY)_$(SRCARCH)/vm) \\"; \
-	echo "$(call gamma-path,altsrc,os_gpu/$(OS_FAMILY)_ptx/vm) \\"; \
-	echo "$(call gamma-path,commonsrc,os_gpu/$(OS_FAMILY)_ptx/vm) \\"; \
 	echo "$(call gamma-path,altsrc,os/$(OS_FAMILY)/vm) \\"; \
 	echo "$(call gamma-path,commonsrc,os/$(OS_FAMILY)/vm) \\"; \
 	echo "$(call gamma-path,altsrc,os/posix/vm) \\"; \
@@ -261,8 +259,6 @@
 	echo "$(call gamma-path,commonsrc,cpu/$(SRCARCH)/vm) \\"; \
 	echo "$(call gamma-path,altsrc,os_cpu/$(OS_FAMILY)_$(SRCARCH)/vm) \\"; \
 	echo "$(call gamma-path,commonsrc,os_cpu/$(OS_FAMILY)_$(SRCARCH)/vm) \\"; \
-	echo "$(call gamma-path,altsrc,os_gpu/$(OS_FAMILY)_ptx/vm) \\"; \
-	echo "$(call gamma-path,commonsrc,os_gpu/$(OS_FAMILY)_ptx/vm) \\"; \
 	echo "$(call gamma-path,altsrc,os/$(OS_FAMILY)/vm) \\"; \
 	echo "$(call gamma-path,commonsrc,os/$(OS_FAMILY)/vm) \\"; \
 	echo "$(call gamma-path,altsrc,os/posix/vm) \\"; \
--- a/make/bsd/makefiles/vm.make	Sun Feb 23 17:00:35 2014 -0800
+++ b/make/bsd/makefiles/vm.make	Wed Mar 05 19:40:15 2014 -0800
@@ -178,7 +178,6 @@
 SOURCE_PATHS+=$(HS_COMMON_SRC)/os_cpu/$(Platform_os_arch)/vm
 SOURCE_PATHS+=$(HS_COMMON_SRC)/gpu/ptx/vm
 SOURCE_PATHS+=$(HS_COMMON_SRC)/gpu/hsail/vm
-SOURCE_PATHS+=$(HS_COMMON_SRC)/os_gpu/bsd_ptx/vm
 
 CORE_PATHS=$(foreach path,$(SOURCE_PATHS),$(call altsrc,$(path)) $(path))
 CORE_PATHS+=$(GENERATED)/jvmtifiles $(GENERATED)/tracefiles
--- a/make/linux/makefiles/buildtree.make	Sun Feb 23 17:00:35 2014 -0800
+++ b/make/linux/makefiles/buildtree.make	Wed Mar 05 19:40:15 2014 -0800
@@ -235,8 +235,6 @@
 	echo "$(call gamma-path,commonsrc,cpu/$(SRCARCH)/vm) \\"; \
 	echo "$(call gamma-path,altsrc,os_cpu/$(OS_FAMILY)_$(SRCARCH)/vm) \\"; \
 	echo "$(call gamma-path,commonsrc,os_cpu/$(OS_FAMILY)_$(SRCARCH)/vm) \\"; \
-	echo "$(call gamma-path,altsrc,os_gpu/$(OS_FAMILY)_ptx/vm) \\"; \
-	echo "$(call gamma-path,commonsrc,os_gpu/$(OS_FAMILY)_ptx/vm) \\"; \
 	echo "$(call gamma-path,altsrc,os/$(OS_FAMILY)/vm) \\"; \
 	echo "$(call gamma-path,commonsrc,os/$(OS_FAMILY)/vm) \\"; \
 	echo "$(call gamma-path,altsrc,os/posix/vm) \\"; \
@@ -257,8 +255,6 @@
 	echo "$(call gamma-path,commonsrc,cpu/$(SRCARCH)/vm) \\"; \
 	echo "$(call gamma-path,altsrc,os_cpu/$(OS_FAMILY)_$(SRCARCH)/vm) \\"; \
 	echo "$(call gamma-path,commonsrc,os_cpu/$(OS_FAMILY)_$(SRCARCH)/vm) \\"; \
-	echo "$(call gamma-path,altsrc,os_gpu/$(OS_FAMILY)_ptx/vm) \\"; \
-	echo "$(call gamma-path,commonsrc,os_gpu/$(OS_FAMILY)_ptx/vm) \\"; \
 	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) \\"; \
--- a/make/linux/makefiles/vm.make	Sun Feb 23 17:00:35 2014 -0800
+++ b/make/linux/makefiles/vm.make	Wed Mar 05 19:40:15 2014 -0800
@@ -158,7 +158,6 @@
 SOURCE_PATHS+=$(HS_COMMON_SRC)/os_cpu/$(Platform_os_arch)/vm
 SOURCE_PATHS+=$(HS_COMMON_SRC)/gpu/ptx/vm
 SOURCE_PATHS+=$(HS_COMMON_SRC)/gpu/hsail/vm
-SOURCE_PATHS+=$(HS_COMMON_SRC)/os_gpu/linux_ptx/vm
 
 CORE_PATHS=$(foreach path,$(SOURCE_PATHS),$(call altsrc,$(path)) $(path))
 CORE_PATHS+=$(GENERATED)/jvmtifiles $(GENERATED)/tracefiles
--- a/make/windows/makefiles/projectcreator.make	Sun Feb 23 17:00:35 2014 -0800
+++ b/make/windows/makefiles/projectcreator.make	Wed Mar 05 19:40:15 2014 -0800
@@ -56,7 +56,6 @@
         -relativeInclude src\os\windows\vm \
         -relativeInclude src\os_cpu\windows_$(Platform_arch)\vm \
         -relativeInclude src\cpu\$(Platform_arch)\vm \
-        -relativeInclude src\os_gpu\windows_hsail\vm \
         -relativeInclude src\gpu \
         -absoluteInclude $(HOTSPOTBUILDSPACE)/%f/generated \
         -relativeSrcInclude src \
--- a/make/windows/makefiles/vm.make	Sun Feb 23 17:00:35 2014 -0800
+++ b/make/windows/makefiles/vm.make	Wed Mar 05 19:40:15 2014 -0800
@@ -126,7 +126,6 @@
   /I "$(COMMONSRC)\share\vm\prims" \
   /I "$(COMMONSRC)\os\windows\vm" \
   /I "$(COMMONSRC)\os_cpu\windows_$(Platform_arch)\vm" \
-  /I "$(COMMONSRC)\os_gpu\windows_hsail\vm" \
   /I "$(COMMONSRC)\cpu\$(Platform_arch)\vm"
 
 CXX_DONT_USE_PCH=/D DONT_USE_PRECOMPILED_HEADER
@@ -171,7 +170,6 @@
 VM_PATH=$(VM_PATH);$(WorkSpace)/src/share/vm/libadt
 VM_PATH=$(VM_PATH);$(WorkSpace)/src/os/windows/vm
 VM_PATH=$(VM_PATH);$(WorkSpace)/src/os_cpu/windows_$(Platform_arch)/vm
-VM_PATH=$(VM_PATH);$(WorkSpace)/src/os_gpu/windows_hsail/vm
 VM_PATH=$(VM_PATH);$(WorkSpace)/src/cpu/$(Platform_arch)/vm
 VM_PATH=$(VM_PATH);$(WorkSpace)/src/share/vm/opto
 
--- a/mx/eclipse-settings/org.eclipse.core.resources.prefs	Sun Feb 23 17:00:35 2014 -0800
+++ b/mx/eclipse-settings/org.eclipse.core.resources.prefs	Wed Mar 05 19:40:15 2014 -0800
@@ -1,2 +1,2 @@
 eclipse.preferences.version=1
-encoding/<project>=US-ASCII
\ No newline at end of file
+encoding/<project>=UTF-8
--- a/mx/eclipse-settings/org.eclipse.jdt.core.prefs	Sun Feb 23 17:00:35 2014 -0800
+++ b/mx/eclipse-settings/org.eclipse.jdt.core.prefs	Wed Mar 05 19:40:15 2014 -0800
@@ -100,6 +100,7 @@
 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
--- a/mx/mx_graal.py	Sun Feb 23 17:00:35 2014 -0800
+++ b/mx/mx_graal.py	Wed Mar 05 19:40:15 2014 -0800
@@ -81,6 +81,8 @@
 
 _minVersion = mx.VersionSpec('1.7.0_04')
 
+JDK_UNIX_PERMISSIONS = 0755
+
 def _get_vm():
     """
     Gets the configured VM, presenting a dialogue if there is no currently configured VM.
@@ -324,7 +326,7 @@
 
             assert defaultVM is not None, 'Could not find default VM in ' + jvmCfg
             if mx.get_os() != 'windows':
-                chmodRecursive(jdk, 0755)
+                chmodRecursive(jdk, JDK_UNIX_PERMISSIONS)
             shutil.move(join(_vmLibDirInJdk(jdk), defaultVM), join(_vmLibDirInJdk(jdk), 'original'))
 
 
@@ -402,7 +404,9 @@
                 fd, tmp = tempfile.mkstemp(suffix='', prefix='graal.jar', dir=jreLibDir)
                 shutil.copyfile(graalJar, tmp)
                 os.close(fd)
-                shutil.move(tmp, join(jreLibDir, 'graal.jar'))
+                graalJar = join(jreLibDir, 'graal.jar')
+                shutil.move(tmp, graalJar)
+                os.chmod(graalJar, JDK_UNIX_PERMISSIONS)
 
 # run a command in the windows SDK Debug Shell
 def _runInDebugShell(cmd, workingDir, logFile=None, findInOutput=None, respondTo=None):
@@ -568,7 +572,7 @@
         vmDir = join(_vmLibDirInJdk(jdk), vm)
         if not exists(vmDir):
             if mx.get_os() != 'windows':
-                chmodRecursive(jdk, 0755)
+                chmodRecursive(jdk, JDK_UNIX_PERMISSIONS)
             mx.log('Creating VM directory in JDK7: ' + vmDir)
             os.makedirs(vmDir)
 
@@ -607,7 +611,7 @@
             project_config = variant + '_' + build
             _runInDebugShell('msbuild ' + _graal_home + r'\build\vs-amd64\jvm.vcproj /p:Configuration=' + project_config + ' /target:clean', _graal_home)
             winCompileCmd = r'set HotSpotMksHome=' + mksHome + r'& set OUT_DIR=' + jdk + r'& set JAVA_HOME=' + jdk + r'& set path=%JAVA_HOME%\bin;%path%;%HotSpotMksHome%& cd /D "' + _graal_home + r'\make\windows"& call create.bat ' + _graal_home
-            print(winCompileCmd)
+            print winCompileCmd
             winCompileSuccess = re.compile(r"^Writing \.vcxproj file:")
             if not _runInDebugShell(winCompileCmd, _graal_home, compilelogfile, winCompileSuccess):
                 mx.log('Error executing create command')
@@ -631,6 +635,13 @@
             env.setdefault('LANG', 'C')
             env.setdefault('HOTSPOT_BUILD_JOBS', str(cpus))
             env.setdefault('ALT_BOOTDIR', mx.java().jdk)
+
+            # extract latest release tag for graal
+            tags = [x.split(' ')[0] for x in subprocess.check_output(['hg', 'tags']).split('\n') if x.startswith("graal-")]
+            if tags:
+                # extract the most recent tag
+                tag = sorted(tags, key=lambda e: [int(x) for x in e[len("graal-"):].split('.')], reverse=True)[0]
+                env.setdefault('USER_RELEASE_SUFFIX', tag)
             if not mx._opts.verbose:
                 runCmd.append('MAKE_VERBOSE=')
             env['JAVA_HOME'] = jdk
@@ -640,10 +651,10 @@
             else:
                 env['INCLUDE_GRAAL'] = 'true'
             env.setdefault('INSTALL', 'y')
-            if mx.get_os() == 'solaris' :
+            if mx.get_os() == 'solaris':
                 # If using sparcWorks, setup flags to avoid make complaining about CC version
                 cCompilerVersion = subprocess.Popen('CC -V', stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True).stderr.readlines()[0]
-                if cCompilerVersion.startswith('CC: Sun C++') :
+                if cCompilerVersion.startswith('CC: Sun C++'):
                     compilerRev = cCompilerVersion.split(' ')[3]
                     env.setdefault('ENFORCE_COMPILER_REV', compilerRev)
                     env.setdefault('ENFORCE_CC_COMPILER_REV', compilerRev)
@@ -678,7 +689,7 @@
         if not found:
             mx.log('Appending "' + prefix + 'KNOWN" to ' + jvmCfg)
             if mx.get_os() != 'windows':
-                os.chmod(jvmCfg, 0755)
+                os.chmod(jvmCfg, JDK_UNIX_PERMISSIONS)
             with open(jvmCfg, 'w') as f:
                 for line in lines:
                     if line.startswith(prefix):
@@ -701,7 +712,7 @@
     """run the fastdebug build of VM selected by the '--vm' option"""
     return vm(args, vmbuild='fastdebug')
 
-def vm(args, vm=None, nonZeroIsFatal=True, out=None, err=None, cwd=None, timeout=None, vmbuild=None):
+def _parseVmArgs(args, vm=None, cwd=None, vmbuild=None):
     """run the VM selected by the '--vm' option"""
 
     if vm is None:
@@ -718,10 +729,6 @@
     mx.expand_project_in_args(args)
     if _make_eclipse_launch:
         mx.make_eclipse_launch(args, 'graal-' + build, name=None, deps=mx.project('com.oracle.graal.hotspot').all_deps([], True))
-    if len([a for a in args if 'PrintAssembly' in a]) != 0:
-        hsdis([], copyToDir=_vmLibDirInJdk(jdk))
-    if mx.java().debug_port is not None:
-        args = ['-Xdebug', '-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=' + str(mx.java().debug_port)] + args
     if _jacoco == 'on' or _jacoco == 'append':
         jacocoagent = mx.library("JACOCOAGENT", True)
         # Exclude all compiler tests and snippets
@@ -739,9 +746,6 @@
                         'destfile' : 'jacoco.exec'
         }
         args = ['-javaagent:' + jacocoagent.get_path(True) + '=' + ','.join([k + '=' + v for k, v in agentOptions.items()])] + args
-    if '-d64' not in args:
-        args = ['-d64'] + args
-
     exe = join(jdk, 'bin', mx.exe_suffix('java'))
     pfx = _vm_prefix.split() if _vm_prefix is not None else []
 
@@ -750,7 +754,12 @@
         if  len(ignoredArgs) > 0:
             mx.log("Warning: The following options will be ignored by the vm because they come after the '-version' argument: " + ' '.join(ignoredArgs))
 
-    return mx.run(pfx + [exe, '-' + vm] + args, nonZeroIsFatal=nonZeroIsFatal, out=out, err=err, cwd=cwd, timeout=timeout)
+    args = mx.java().processArgs(args)
+    return (pfx, exe, vm, args, cwd)
+
+def vm(args, vm=None, nonZeroIsFatal=True, out=None, err=None, cwd=None, timeout=None, vmbuild=None):
+    (pfx_, exe_, vm_, args_, cwd) = _parseVmArgs(args, vm, cwd, vmbuild)
+    return mx.run(pfx_ + [exe_, '-' + vm_] + args_, nonZeroIsFatal=nonZeroIsFatal, out=out, err=err, cwd=cwd, timeout=timeout)
 
 def _find_classes_with_annotations(p, pkgRoot, annotations, includeInnerClasses=False):
     """
@@ -759,7 +768,7 @@
     source file matched in a list.
     """
 
-    matches = lambda line : len([a for a in annotations if line == a or line.startswith(a + '(')]) != 0
+    matches = lambda line: len([a for a in annotations if line == a or line.startswith(a + '(')]) != 0
     return p.find_classes_with_matching_source_line(pkgRoot, matches, includeInnerClasses)
 
 def _extract_VM_args(args, allowClasspath=False, useDoubleDash=False):
@@ -1060,21 +1069,23 @@
         mx.pylint([])
         tasks.append(t.stop())
 
-        t = Task('Clean')
-        cleanArgs = []
-        if not args.cleanNative:
-            cleanArgs.append('--no-native')
-        if not args.cleanJava:
-            cleanArgs.append('--no-java')
-        clean(cleanArgs)
-        tasks.append(t.stop())
+        def _clean(name='Clean'):
+            t = Task(name)
+            cleanArgs = []
+            if not args.cleanNative:
+                cleanArgs.append('--no-native')
+            if not args.cleanJava:
+                cleanArgs.append('--no-java')
+            clean(cleanArgs)
+            tasks.append(t.stop())
+        _clean()
 
         t = Task('IDEConfigCheck')
         mx.ideclean([])
         mx.ideinit([])
         tasks.append(t.stop())
 
-        eclipse_exe = os.environ.get('ECLIPSE_EXE')
+        eclipse_exe = mx.get_env('ECLIPSE_EXE')
         if eclipse_exe is not None:
             t = Task('CodeFormatCheck')
             if mx.eclipseformat(['-e', eclipse_exe]) != 0:
@@ -1087,8 +1098,15 @@
             t.abort('Rerun "mx canonicalizeprojects" and check-in the modified mx/projects files.')
         tasks.append(t.stop())
 
-        t = Task('BuildJava')
-        build(['--no-native', '--jdt-warning-as-error'])
+        if mx.get_env('JDT'):
+            t = Task('BuildJavaWithEcj')
+            build(['--no-native', '--jdt-warning-as-error'])
+            tasks.append(t.stop())
+
+            _clean('CleanAfterEcjBuild')
+
+        t = Task('BuildJavaWithJavac')
+        build(['--no-native', '--force-javac'])
         tasks.append(t.stop())
 
         t = Task('Checkstyle')
@@ -1189,7 +1207,7 @@
     results = {}
     benchmarks = []
     # DaCapo
-    if ('dacapo' in args or 'all' in args):
+    if 'dacapo' in args or 'all' in args:
         benchmarks += sanitycheck.getDacapos(level=sanitycheck.SanityCheckLevel.Benchmark)
     else:
         dacapos = benchmarks_in_group('dacapo')
@@ -1197,10 +1215,10 @@
             if dacapo not in sanitycheck.dacapoSanityWarmup.keys():
                 mx.abort('Unknown DaCapo : ' + dacapo)
             iterations = sanitycheck.dacapoSanityWarmup[dacapo][sanitycheck.SanityCheckLevel.Benchmark]
-            if (iterations > 0):
+            if iterations > 0:
                 benchmarks += [sanitycheck.getDacapo(dacapo, iterations)]
 
-    if ('scaladacapo' in args or 'all' in args):
+    if 'scaladacapo' in args or 'all' in args:
         benchmarks += sanitycheck.getScalaDacapos(level=sanitycheck.SanityCheckLevel.Benchmark)
     else:
         scaladacapos = benchmarks_in_group('scaladacapo')
@@ -1208,31 +1226,31 @@
             if scaladacapo not in sanitycheck.dacapoScalaSanityWarmup.keys():
                 mx.abort('Unknown Scala DaCapo : ' + scaladacapo)
             iterations = sanitycheck.dacapoScalaSanityWarmup[scaladacapo][sanitycheck.SanityCheckLevel.Benchmark]
-            if (iterations > 0):
+            if iterations > 0:
                 benchmarks += [sanitycheck.getScalaDacapo(scaladacapo, ['-n', str(iterations)])]
 
     # Bootstrap
-    if ('bootstrap' in args or 'all' in args):
+    if 'bootstrap' in args or 'all' in args:
         benchmarks += sanitycheck.getBootstraps()
     # SPECjvm2008
-    if ('specjvm2008' in args or 'all' in args):
+    if 'specjvm2008' in args or 'all' in args:
         benchmarks += [sanitycheck.getSPECjvm2008(['-ikv', '-wt', '120', '-it', '120'])]
     else:
         specjvms = benchmarks_in_group('specjvm2008')
         for specjvm in specjvms:
             benchmarks += [sanitycheck.getSPECjvm2008(['-ikv', '-wt', '120', '-it', '120', specjvm])]
 
-    if ('specjbb2005' in args or 'all' in args):
+    if 'specjbb2005' in args or 'all' in args:
         benchmarks += [sanitycheck.getSPECjbb2005()]
 
-    if ('specjbb2013' in args):  # or 'all' in args //currently not in default set
+    if 'specjbb2013' in args:  # or 'all' in args //currently not in default set
         benchmarks += [sanitycheck.getSPECjbb2013()]
 
-    if ('ctw-full' in args):
+    if 'ctw-full' in args:
         benchmarks.append(sanitycheck.getCTW(vm, sanitycheck.CTWMode.Full))
-    if ('ctw-noinline' in args):
+    if 'ctw-noinline' in args:
         benchmarks.append(sanitycheck.getCTW(vm, sanitycheck.CTWMode.NoInline))
-    if ('ctw-nocomplex' in args):
+    if 'ctw-nocomplex' in args:
         benchmarks.append(sanitycheck.getCTW(vm, sanitycheck.CTWMode.NoComplex))
 
     for test in benchmarks:
@@ -1244,6 +1262,77 @@
         with open(resultFile, 'w') as f:
             f.write(json.dumps(results))
 
+def jmh(args):
+    """run the JMH_BENCHMARKS"""
+
+    # TODO: add option for `mvn clean package'
+    # TODO: add options to pass through arguments directly to JMH
+
+    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 definied")
+
+    def _blackhole(x):
+        mx.logv(x[:-1])
+    mx.log("Building benchmarks...")
+    mx.run(['mvn', 'package'], cwd=jmhPath, out=_blackhole)
+
+    matchedSuites = set()
+    numBench = [0]
+    for micros in os.listdir(jmhPath):
+        absoluteMicro = os.path.join(jmhPath, micros)
+        if not os.path.isdir(absoluteMicro):
+            continue
+        if not micros.startswith("micros-"):
+            mx.logv('JMH: ignored ' + absoluteMicro + " because it doesn't start with 'micros-'")
+            continue
+
+        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
+        if benchmarks:
+            def _addBenchmark(x):
+                if x.startswith("Benchmark:"):
+                    return
+                match = False
+                for b in benchmarks:
+                    match = match or (b in x)
+
+                if match:
+                    numBench[0] += 1
+                    matchedSuites.add(micros)
+
+            mx.run_java(['-jar', microJar, "-l"], cwd=jmhPath, out=_addBenchmark, addDefaultArgs=False)
+        else:
+            matchedSuites.add(micros)
+
+    mx.logv("matchedSuites: " + str(matchedSuites))
+    plural = 's' if not benchmarks or numBench[0] > 1 else ''
+    number = str(numBench[0]) if benchmarks else "all"
+    mx.log("Running " + number + " benchmark" + plural + '...')
+
+    regex = []
+    if benchmarks:
+        regex.append(r".*(" + "|".join(benchmarks) + ").*")
+
+    for suite in matchedSuites:
+        absoluteMicro = os.path.join(jmhPath, suite)
+        (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)
+
+
 def specjvm2008(args):
     """run one or more SPECjvm2008 benchmarks"""
 
@@ -1358,7 +1447,7 @@
 def sl(args):
     """run an SL program"""
     vmArgs, slArgs = _extract_VM_args(args)
-    vm(vmArgs + ['-cp', mx.classpath("com.oracle.truffle.sl"), "com.oracle.truffle.sl.SimpleLanguage"] + slArgs)
+    vm(vmArgs + ['-cp', mx.classpath("com.oracle.truffle.sl"), "com.oracle.truffle.sl.SLMain"] + slArgs)
 
 def trufflejar(args=None):
     """make truffle.jar"""
@@ -1377,17 +1466,6 @@
 def isGraalEnabled(vm):
     return vm != 'original' and not vm.endswith('nograal')
 
-def rubyShellCp():
-    return mx.classpath("com.oracle.truffle.ruby.shell")
-
-def rubyShellClass():
-    return "com.oracle.truffle.ruby.shell.Shell"
-
-def ruby(args):
-    """run a Ruby program or shell"""
-    vmArgs, rubyArgs = _extract_VM_args(args, useDoubleDash=True)
-    vm(vmArgs + ['-cp', rubyShellCp(), rubyShellClass()] + rubyArgs)
-
 def site(args):
     """create a website containing javadoc and the project dependency graph"""
 
@@ -1528,6 +1606,7 @@
         'hcfdis': [hcfdis, ''],
         'igv' : [igv, ''],
         'jdkhome': [print_jdkhome, ''],
+        'jmh': [jmh, '[VM options] [filters...]'],
         '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]'],
@@ -1546,8 +1625,7 @@
         'deoptalot' : [deoptalot, '[n]'],
         'longtests' : [longtests, ''],
         'sl' : [sl, '[SL args|@VM options]'],
-        'trufflejar' : [trufflejar, ''],
-        'ruby' : [ruby, '[Ruby args|@VM options]']
+        'trufflejar' : [trufflejar, '']
     }
 
     mx.add_argument('--jacoco', help='instruments com.oracle.* classes using JaCoCo', default='off', choices=['off', 'on', 'append'])
@@ -1556,7 +1634,7 @@
                     'The VM selected by --vm and --vmbuild options is under this directory (i.e., ' +
                     join('<path>', '<jdk-version>', '<vmbuild>', 'jre', 'lib', '<vm>', mx.add_lib_prefix(mx.add_lib_suffix('jvm'))) + ')', default=None, metavar='<path>')
 
-    if (_vmSourcesAvailable):
+    if _vmSourcesAvailable:
         mx.add_argument('--vm', action='store', dest='vm', choices=_vmChoices.keys(), help='the VM type to build/run')
         mx.add_argument('--vmbuild', action='store', dest='vmbuild', choices=_vmbuildChoices, help='the VM build to build/run (default: ' + _vmbuildChoices[0] + ')')
         mx.add_argument('--ecl', action='store_true', dest='make_eclipse_launch', help='create launch configuration for running VM execution(s) in Eclipse')
@@ -1571,10 +1649,10 @@
 
 def mx_post_parse_cmd_line(opts):  #
     # TODO _minVersion check could probably be part of a Suite in mx?
-    if (mx.java().version < _minVersion) :
+    if mx.java().version < _minVersion:
         mx.abort('Requires Java version ' + str(_minVersion) + ' or greater, got version ' + str(mx.java().version))
 
-    if (_vmSourcesAvailable):
+    if _vmSourcesAvailable:
         if hasattr(opts, 'vm') and opts.vm is not None:
             global _vm
             _vm = opts.vm
--- a/mx/projects	Sun Feb 23 17:00:35 2014 -0800
+++ b/mx/projects	Wed Mar 05 19:40:15 2014 -0800
@@ -24,51 +24,15 @@
 library@DACAPO_SCALA@path=lib/dacapo-scala-0.1.0-20120216.jar
 library@DACAPO_SCALA@urls=http://repo.scalabench.org/snapshots/org/scalabench/benchmarks/scala-benchmark-suite/0.1.0-SNAPSHOT/scala-benchmark-suite-0.1.0-20120216.103539-3.jar
 
-library@OKRA@path=lib/okra-1.2.jar
-library@OKRA@sourcePath=lib/okra-1.2.jar
-library@OKRA@urls=http://cr.openjdk.java.net/~tdeneau/okra-1.2.jar
-
-library@JRUBYPARSER@path=lib/jrubyparser-0.5.0.jar
-library@JRUBYPARSER@urls=http://repo1.maven.org/maven2/org/jruby/jrubyparser/0.5.0/jrubyparser-0.5.0.jar
-
-library@JLINE@path=lib/jline-2.10.jar
-library@JLINE@urls=http://repo1.maven.org/maven2/jline/jline/2.10/jline-2.10.jar
-
-library@JRUBYSTDLIB@path=lib/jruby-stdlib-1.7.4.jar
-library@JRUBYSTDLIB@urls=http://repo1.maven.org/maven2/org/jruby/jruby-stdlib/1.7.4/jruby-stdlib-1.7.4.jar
-
-library@JNR_POSIX@path=lib/jnr-posix-3.0.0.jar
-library@JNR_POSIX@urls=http://repo1.maven.org/maven2/com/github/jnr/jnr-posix/3.0.0/jnr-posix-3.0.0.jar
-
-library@JNR_CONSTANTS@path=lib/jnr-constants-0.8.4.jar
-library@JNR_CONSTANTS@urls=http://repo1.maven.org/maven2/com/github/jnr/jnr-constants/0.8.4/jnr-constants-0.8.4.jar
-
-library@JNR_FFI@path=lib/jnr-ffi-1.0.4.jar
-library@JNR_FFI@urls=http://repo1.maven.org/maven2/com/github/jnr/jnr-ffi/1.0.4/jnr-ffi-1.0.4.jar
+library@OKRA@path=lib/okra-1.8.jar
+library@OKRA@urls=http://cr.openjdk.java.net/~tdeneau/okra-1.8.jar
+library@OKRA@sourcePath=lib/okra-1.8-src.jar
+library@OKRA@sourceUrls=http://cr.openjdk.java.net/~tdeneau/okra-1.8-src.jar
 
-library@JFFI@path=lib/jffi-1.2.1.jar
-library@JFFI@urls=http://repo1.maven.org/maven2/com/github/jnr/jffi/1.2.1/jffi-1.2.1.jar
-
-library@JFFI_NATIVE@path=lib/jffi-1.2.1-native.jar
-library@JFFI_NATIVE@urls=http://search.maven.org/remotecontent?filepath=com/github/jnr/jffi/1.2.1/jffi-1.2.1-native.jar
-
-library@JNR_X86ASM@path=lib/jnr-x86asm-1.0.2.jar
-library@JNR_X86ASM@urls=http://repo1.maven.org/maven2/com/github/jnr/jnr-x86asm/1.0.2/jnr-x86asm-1.0.2.jar
-
-library@ASM@path=lib/asm-4.0.jar
-library@ASM@urls=http://repo1.maven.org/maven2/org/ow2/asm/asm/4.0/asm-4.0.jar
-
-library@ASM_ANALYSIS@path=lib/asm-analysis-4.0.jar
-library@ASM_ANALYSIS@urls=http://repo1.maven.org/maven2/org/ow2/asm/asm-analysis/4.0/asm-analysis-4.0.jar
-
-library@ASM_COMMONS@path=lib/asm-commons-4.0.jar
-library@ASM_COMMONS@urls=http://repo1.maven.org/maven2/org/ow2/asm/asm-commons/4.0/asm-commons-4.0.jar
-
-library@ASM_TREE@path=lib/asm-tree-4.0.jar
-library@ASM_TREE@urls=http://repo1.maven.org/maven2/org/ow2/asm/asm-tree/4.0/asm-tree-4.0.jar
-
-library@ASM_UTIL@path=lib/asm-util-4.0.jar
-library@ASM_UTIL@urls=http://repo1.maven.org/maven2/org/ow2/asm/asm-util/4.0/asm-util-4.0.jar
+library@OKRA_WITH_SIM@path=lib/okra-1.8-with-sim.jar
+library@OKRA_WITH_SIM@urls=http://cr.openjdk.java.net/~tdeneau/okra-1.8-with-sim.jar
+library@OKRA_WITH_SIM@sourcePath=lib/okra-1.8-with-sim-src.jar
+library@OKRA_WITH_SIM@sourceUrls=http://cr.openjdk.java.net/~tdeneau/okra-1.8-with-sim-src.jar
 
 distribution@GRAAL@path=graal.jar
 distribution@GRAAL@dependencies=\
@@ -178,7 +142,7 @@
 # graal.hotspot.amd64
 project@com.oracle.graal.hotspot.amd64@subDir=graal
 project@com.oracle.graal.hotspot.amd64@sourceDirs=src
-project@com.oracle.graal.hotspot.amd64@dependencies=com.oracle.graal.hotspot,com.oracle.graal.compiler.amd64,com.oracle.graal.replacements.amd64
+project@com.oracle.graal.hotspot.amd64@dependencies=com.oracle.graal.compiler.amd64,com.oracle.graal.hotspot,com.oracle.graal.replacements.amd64
 project@com.oracle.graal.hotspot.amd64@checkstyle=com.oracle.graal.graph
 project@com.oracle.graal.hotspot.amd64@annotationProcessors=com.oracle.graal.service.processor
 project@com.oracle.graal.hotspot.amd64@javaCompliance=1.7
@@ -507,6 +471,14 @@
 project@com.oracle.graal.java@javaCompliance=1.7
 project@com.oracle.graal.java@workingSets=Graal,Java
 
+# graal.baseline
+project@com.oracle.graal.baseline@subDir=graal
+project@com.oracle.graal.baseline@sourceDirs=src
+project@com.oracle.graal.baseline@dependencies=com.oracle.graal.java,com.oracle.graal.lir
+project@com.oracle.graal.baseline@checkstyle=com.oracle.graal.graph
+project@com.oracle.graal.baseline@javaCompliance=1.7
+project@com.oracle.graal.baseline@workingSets=Graal,Java
+
 # graal.java.decompiler
 project@com.oracle.graal.java.decompiler@subDir=graal
 project@com.oracle.graal.java.decompiler@sourceDirs=src
@@ -542,7 +514,7 @@
 # graal.compiler.test
 project@com.oracle.graal.compiler.test@subDir=graal
 project@com.oracle.graal.compiler.test@sourceDirs=src
-project@com.oracle.graal.compiler.test@dependencies=com.oracle.graal.test,com.oracle.graal.printer,com.oracle.graal.runtime
+project@com.oracle.graal.compiler.test@dependencies=com.oracle.graal.test,com.oracle.graal.printer,com.oracle.graal.runtime,com.oracle.graal.baseline
 project@com.oracle.graal.compiler.test@checkstyle=com.oracle.graal.graph
 project@com.oracle.graal.compiler.test@javaCompliance=1.7
 project@com.oracle.graal.compiler.test@workingSets=Graal,Test
@@ -611,7 +583,7 @@
 # graal.compiler.hsail.test.infra - HSAIL compiler test infrastructure
 project@com.oracle.graal.compiler.hsail.test.infra@subDir=graal
 project@com.oracle.graal.compiler.hsail.test.infra@sourceDirs=src
-project@com.oracle.graal.compiler.hsail.test.infra@dependencies=com.oracle.graal.hotspot.hsail,JUNIT
+project@com.oracle.graal.compiler.hsail.test.infra@dependencies=com.oracle.graal.hotspot.hsail,JUNIT,OKRA_WITH_SIM
 project@com.oracle.graal.compiler.hsail.test.infra@checkstyle=com.oracle.graal.graph
 project@com.oracle.graal.compiler.hsail.test.infra@javaCompliance=1.7
 
@@ -735,43 +707,3 @@
 project@com.oracle.graal.truffle.hotspot.amd64@javaCompliance=1.7
 project@com.oracle.graal.truffle.hotspot.amd64@annotationProcessors=com.oracle.graal.service.processor
 project@com.oracle.graal.truffle.hotspot.amd64@workingSets=Graal,Truffle
-
-# truffle.ruby.runtime
-project@com.oracle.truffle.ruby.runtime@subDir=graal
-project@com.oracle.truffle.ruby.runtime@sourceDirs=src
-project@com.oracle.truffle.ruby.runtime@dependencies=JRUBYSTDLIB,JNR_POSIX,JNR_CONSTANTS,JNR_FFI,JFFI,JFFI_NATIVE,JNR_X86ASM,ASM,ASM_ANALYSIS,ASM_COMMONS,ASM_TREE,ASM_UTIL,com.oracle.truffle.api
-project@com.oracle.truffle.ruby.runtime@javaCompliance=1.7
-project@com.oracle.truffle.ruby.runtime@workingSets=Truffle,Ruby
-
-# truffle.ruby.nodes
-project@com.oracle.truffle.ruby.nodes@subDir=graal
-project@com.oracle.truffle.ruby.nodes@sourceDirs=src
-project@com.oracle.truffle.ruby.nodes@dependencies=com.oracle.truffle.ruby.runtime,com.oracle.truffle.api.dsl
-project@com.oracle.truffle.ruby.nodes@checkstyle=com.oracle.truffle.ruby.runtime
-project@com.oracle.truffle.ruby.nodes@javaCompliance=1.7
-project@com.oracle.truffle.ruby.nodes@annotationProcessors=com.oracle.truffle.dsl.processor
-project@com.oracle.truffle.ruby.nodes@workingSets=Truffle,Ruby
-
-# truffle.ruby.parser
-project@com.oracle.truffle.ruby.parser@subDir=graal
-project@com.oracle.truffle.ruby.parser@sourceDirs=src
-project@com.oracle.truffle.ruby.parser@dependencies=JRUBYPARSER,com.oracle.truffle.ruby.nodes
-project@com.oracle.truffle.ruby.parser@checkstyle=com.oracle.truffle.ruby.runtime
-project@com.oracle.truffle.ruby.parser@javaCompliance=1.7
-project@com.oracle.truffle.ruby.parser@workingSets=Truffle,Ruby
-
-# truffle.ruby.shell
-project@com.oracle.truffle.ruby.shell@subDir=graal
-project@com.oracle.truffle.ruby.shell@sourceDirs=src
-project@com.oracle.truffle.ruby.shell@dependencies=JLINE,com.oracle.truffle.ruby.parser
-project@com.oracle.truffle.ruby.shell@checkstyle=com.oracle.truffle.ruby.runtime
-project@com.oracle.truffle.ruby.shell@javaCompliance=1.7
-project@com.oracle.truffle.ruby.shell@workingSets=Truffle,Ruby
-
-# truffle.ruby.test
-project@com.oracle.truffle.ruby.test@subDir=graal
-project@com.oracle.truffle.ruby.test@sourceDirs=src
-project@com.oracle.truffle.ruby.test@dependencies=com.oracle.truffle.ruby.parser,JUNIT
-project@com.oracle.truffle.ruby.test@checkstyle=com.oracle.truffle.ruby.runtime
-project@com.oracle.truffle.ruby.test@javaCompliance=1.7
-project@com.oracle.truffle.ruby.test@workingSets=Truffle,Ruby,Test
--- a/mx/sanitycheck.py	Sun Feb 23 17:00:35 2014 -0800
+++ b/mx/sanitycheck.py	Wed Mar 05 19:40:15 2014 -0800
@@ -68,17 +68,17 @@
     'avrora':     ['product', 'fastdebug', 'debug'],
     'batik':      ['product', 'fastdebug', 'debug'],
     'eclipse':    ['product'],
-    'fop':        [           'fastdebug', 'debug'],
+    'fop':        ['fastdebug', 'debug'],
     'h2':         ['product', 'fastdebug', 'debug'],
     'jython':     ['product', 'fastdebug', 'debug'],
     'luindex':    ['product', 'fastdebug', 'debug'],
     'lusearch':   ['product'],
     'pmd':        ['product', 'fastdebug', 'debug'],
-    'sunflow':    [           'fastdebug', 'debug'],
+    'sunflow':    ['fastdebug', 'debug'],
     'tomcat':     ['product', 'fastdebug', 'debug'],
     'tradebeans': ['product', 'fastdebug', 'debug'],
     # tradesoap is too unreliable for the gate, often crashing with "java.net.BindException: Address already in use"
-    'tradesoap':  [                               ],
+    'tradesoap':  [],
     'xalan':      ['product', 'fastdebug', 'debug'],
 }
 
@@ -323,7 +323,7 @@
         """
         Run this program as a sanity test.
         """
-        if (vm in self.ignoredVMs):
+        if vm in self.ignoredVMs:
             return True
         if cwd is None:
             cwd = self.defaultCwd
@@ -368,7 +368,7 @@
         """
         Run this program as a benchmark.
         """
-        if (vm in self.ignoredVMs):
+        if vm in self.ignoredVMs:
             return {}
         if cwd is None:
             cwd = self.defaultCwd
--- a/mxtool/mx.py	Sun Feb 23 17:00:35 2014 -0800
+++ b/mxtool/mx.py	Wed Mar 05 19:40:15 2014 -0800
@@ -28,6 +28,8 @@
 r"""
 mx is a command line tool for managing the development of Java code organized as suites of projects.
 
+Version 1.x supports a single suite of projects.
+
 Full documentation can be found at https://wiki.openjdk.java.net/display/Graal/The+mx+Tool
 """
 
@@ -36,6 +38,7 @@
 import socket
 import xml.parsers.expat
 import shutil, re, xml.dom.minidom
+import pipes
 from collections import Callable
 from threading import Thread
 from argparse import ArgumentParser, REMAINDER
@@ -48,14 +51,9 @@
 _annotationProcessors = None
 _primary_suite_path = None
 _primary_suite = None
-_src_suitemodel = None
-_dst_suitemodel = None
 _opts = None
 _java = None
-_check_global_structures = True  # can be set False to allow suites with duplicate definitions to load without aborting
 _warn = False
-_hg = None
-
 
 """
 A distribution is a jar or zip file containing the output from one or more Java projects.
@@ -382,7 +380,7 @@
             return None
         if resolve and self.mustExist and not exists(path):
             assert not len(self.urls) == 0, 'cannot find required library ' + self.name + ' ' + path
-            print('Downloading ' + self.name + ' from ' + str(self.urls))
+            print 'Downloading ' + self.name + ' from ' + str(self.urls)
             download(path, self.urls)
         return path
 
@@ -393,7 +391,7 @@
         if not isabs(path):
             path = join(self.suite.dir, path)
         if resolve and len(self.sourceUrls) != 0 and not exists(path):
-            print('Downloading sources for ' + self.name + ' from ' + str(self.sourceUrls))
+            print 'Downloading sources for ' + self.name + ' from ' + str(self.sourceUrls)
             download(path, self.sourceUrls)
         return path
 
@@ -442,229 +440,6 @@
             else:
                 return None
 
-    def can_push(self, s, strict=True):
-        try:
-            output = subprocess.check_output(['hg', '-R', s.dir, 'status'])
-            # super strict
-            return output == ''
-        except OSError:
-            warn(self.missing)
-        except subprocess.CalledProcessError:
-            return False
-
-    def default_push(self, sdir):
-        with open(join(sdir, '.hg', 'hgrc')) as f:
-            for line in f:
-                line = line.rstrip()
-                if line.startswith('default = '):
-                    return line[len('default = '):]
-        return None
-
-class SuiteModel:
-    """
-    Defines how to locate a URL/path for a suite, including imported suites.
-    Conceptually a SuiteModel is defined by a primary suite URL/path and a
-    map from suite name to URL/path for imported suites.
-    Subclasses define a specfic implementation.
-    """
-    def __init__(self):
-        self.primaryDir = None
-        self.suitenamemap = {}
-
-    def find_suite_dir(self, suitename):
-        """locates the URL/path for suitename or None if not found"""
-        abort('find_suite_dir not implemented')
-
-    def set_primary_dir(self, d):
-        """informs that d is the primary suite directory"""
-        self._primaryDir = d
-
-    def importee_dir(self, importer_dir, suitename):
-        """returns the directory path for an import of suitename, given importer_dir"""
-        abort('importee_dir not implemented')
-
-    def nestedsuites_dirname(self):
-        """Returns the dirname that contains any nested suites if the model supports that"""
-        return None
-
-    def _mxDirName(self, name):
-        # temporary workaround until mx.graal exists
-        if name == 'graal':
-            return 'mx'
-        else:
-            return 'mx.' + name
-
-    def _search_dir(self, searchDir, mxDirName):
-        for dd in os.listdir(searchDir):
-            sd = _is_suite_dir(join(searchDir, dd), mxDirName)
-            if sd is not None:
-                return sd
-
-    def _create_suitenamemap(self, optionspec, suitemap):
-        """Three ways to specify a suite name mapping, in order of precedence:
-        1. Explicitly in optionspec.
-        2. In suitemap.
-        3. in MXSUITEMAP environment variable.
-        """
-        if optionspec != '':
-            spec = optionspec
-        elif suitemap is not None:
-            spec = suitemap
-        elif get_env('MXSUITEMAP') is not None:
-            spec = get_env('MXSUITEMAP')
-        else:
-            return
-        pairs = spec.split(',')
-        for pair in pairs:
-            mappair = pair.split('=')
-            self.suitenamemap[mappair[0]] = mappair[1]
-
-    @staticmethod
-    def set_suitemodel(option, suitemap):
-        if option.startswith('sibling'):
-            return SiblingSuiteModel(os.getcwd(), option, suitemap)
-        elif option.startswith('nested'):
-            return NestedImportsSuiteModel(os.getcwd(), option, suitemap)
-        elif option.startswith('path'):
-            return PathSuiteModel(option[len('path:'):])
-        else:
-            abort('unknown suitemodel type: ' + option)
-
-    @staticmethod
-    def parse_options():
-        # suite-specific args may match the known args so there is no way at this early stage
-        # to use ArgParser to handle the suite model global arguments, so we just do it manually.
-        def _get_argvalue(arg, args, i):
-            if i < len(args):
-                return args[i]
-            else:
-                abort('value expected with ' + arg)
-
-        args = sys.argv[1:]
-        src_suitemodel_arg = dst_suitemodel_arg = 'sibling'
-        suitemap_arg = None
-
-        i = 0
-        while i < len(args):
-            arg = args[i]
-            if arg == '--src-suitemodel':
-                src_suitemodel_arg = _get_argvalue(arg, args, i + 1)
-            elif arg == '--dst-suitemodel':
-                dst_suitemodel_arg = _get_argvalue(arg, args, i + 1)
-            elif arg == '--suitemap':
-                suitemap_arg = _get_argvalue(arg, args, i + 1)
-            elif arg == '-w':
-                # to get warnings on suite loading issues before command line is parsed
-                global _warn
-                _warn = True
-            elif arg == '-p' or arg == '--primary-suite-path':
-                global _primary_suite_path
-                _primary_suite_path = os.path.abspath(_get_argvalue(arg, args, i + 1))
-            i = i + 1
-
-        global _src_suitemodel
-        _src_suitemodel = SuiteModel.set_suitemodel(src_suitemodel_arg, suitemap_arg)
-        global _dst_suitemodel
-        _dst_suitemodel = SuiteModel.set_suitemodel(dst_suitemodel_arg, suitemap_arg)
-
-
-class SiblingSuiteModel(SuiteModel):
-    """All suites are siblings in the same parent directory, recorded as _suiteRootDir"""
-    def __init__(self, suiteRootDir, option, suitemap):
-        SuiteModel.__init__(self)
-        self._suiteRootDir = suiteRootDir
-        self._create_suitenamemap(option[len('sibling:'):], suitemap)
-
-    def find_suite_dir(self, name):
-        return self._search_dir(self._suiteRootDir, self._mxDirName(name))
-
-    def set_primary_dir(self, d):
-        SuiteModel.set_primary_dir(self, d)
-        self._suiteRootDir = dirname(d)
-
-    def importee_dir(self, importer_dir, suitename):
-        if self.suitenamemap.has_key(suitename):
-            suitename = self.suitenamemap[suitename]
-        return join(dirname(importer_dir), suitename)
-
-class NestedImportsSuiteModel(SuiteModel):
-    """Imported suites are all siblings in an 'imported_suites' directory of the primary suite"""
-    def _imported_suites_dirname(self):
-        return "imported_suites"
-
-    def __init__(self, primaryDir, option, suitemap):
-        SuiteModel.__init__(self)
-        self._primaryDir = primaryDir
-        self._create_suitenamemap(option[len('nested:'):], suitemap)
-
-    def find_suite_dir(self, name):
-        return self._search_dir(join(self._primaryDir, self._imported_suites_dirname()), self._mxDirName(name))
-
-    def importee_dir(self, importer_dir, suitename):
-        if self.suitenamemap.has_key(suitename):
-            suitename = self.suitenamemap[suitename]
-        if basename(importer_dir) == basename(self._primaryDir):
-            # primary is importer
-            this_imported_suites_dirname = join(importer_dir, self._imported_suites_dirname())
-            if not exists(this_imported_suites_dirname):
-                os.mkdir(this_imported_suites_dirname)
-            return join(this_imported_suites_dirname, suitename)
-        else:
-            return join(dirname(importer_dir), suitename)
-
-    def nestedsuites_dirname(self):
-        return self._imported_suites_dirname()
-
-class PathSuiteModel(SuiteModel):
-    """The most general model. Uses a map from suitename to URL/path provided by the user"""
-    def __init__(self, path):
-        SuiteModel.__init__(self)
-        paths = path.split(',')
-        self.suit_to_url = {}
-        for path in paths:
-            pair = path.split('=')
-            if len(pair) > 1:
-                suitename = pair[0]
-                suiteurl = pair[1]
-            else:
-                suitename = basename(pair[0])
-                suiteurl = pair[0]
-            self.suit_to_url[suitename] = suiteurl
-
-    def find_suite_dir(self, suitename):
-        if self.suit_to_url.has_key(suitename):
-            return self.suit_to_url[suitename]
-        else:
-            return None
-
-    def importee_dir(self, importer_dir, suitename):
-        if suitename in self.suit_to_url:
-            return self.suit_to_url[suitename]
-        else:
-            abort('suite ' + suitename + ' not found')
-
-class SuiteImport:
-    def __init__(self, name, version):
-        self.name = name
-        self.version = version
-
-    @staticmethod
-    def parse_specification(specification):
-        pair = specification.split(',')
-        name = pair[0]
-        if len(pair) > 1:
-            version = pair[1]
-        else:
-            version = None
-        return SuiteImport(name, version)
-
-    @staticmethod
-    def tostring(name, version):
-        return name + ',' + version
-
-    def __str__(self):
-        return self.name + ',' + self.version
-
 class Suite:
     def __init__(self, mxDir, primary, load=True):
         self.dir = dirname(mxDir)
@@ -672,13 +447,12 @@
         self.projects = []
         self.libs = []
         self.dists = []
-        self.imports = []
         self.commands = None
         self.primary = primary
         self.requiredMxVersion = None
         self.name = _suitename(mxDir)  # validated in _load_projects
         if load:
-            # load suites bottom up to make sure command overriding works properly
+            # just check that there are no imports
             self._load_imports()
             self._load_env()
             self._load_commands()
@@ -687,10 +461,6 @@
     def __str__(self):
         return self.name
 
-    def version(self, abortOnError=True):
-        # we do not cache the version
-        return _hg.tip(self.dir, abortOnError)
-
     def _load_projects(self):
         libsMap = dict()
         projsMap = dict()
@@ -838,56 +608,9 @@
             mod.mx_init(self)
             self.commands = mod
 
-    def _imports_file(self):
-        return join(self.mxDir, 'imports')
-
-    def import_timestamp(self):
-        return TimeStampFile(self._imports_file())
-
-    def visit_imports(self, visitor, **extra_args):
-        """
-        Visitor support for the imports file.
-        For each line of the imports file that specifies an import, the visitor function is
-        called with this suite, a SuiteImport instance created from the line and any extra args
-        passed to this call. In addition, if extra_args contains a key 'update_versions' that is True,
-        a StringIO value is added to extra_args with key 'updated_imports', and the visitor is responsible
-        for writing a (possibly) updated import line to the file, and the file is (possibly) updated after
-        all imports are processed.
-        N.B. There is no built-in support for avoiding visiting the same suite multiple times,
-        as this function only visits the imports of a single suite. If a (recursive) visitor function
-        wishes to visit a suite exactly once, it must manage that through extra_args.
-        """
-        importsFile = self._imports_file()
-        if exists(importsFile):
-            update_versions = extra_args.has_key('update_versions') and extra_args['update_versions']
-            out = StringIO.StringIO() if update_versions else None
-            extra_args['updated_imports'] = out
-            with open(importsFile) as f:
-                for line in f:
-                    sline = line.strip()
-                    if len(sline) == 0 or sline.startswith('#'):
-                        if out is not None:
-                            out.write(sline + '\n')
-                        continue
-                    suite_import = SuiteImport.parse_specification(line.strip())
-                    visitor(self, suite_import, **extra_args)
-
-            if out is not None:
-                update_file(importsFile, out.getvalue())
-
-    @staticmethod
-    def _find_and_loadsuite(importing_suite, suite_import, **extra_args):
-        """visitor for the initial suite load"""
-        importMxDir = _src_suitemodel.find_suite_dir(suite_import.name)
-        if importMxDir is None:
-            abort('import ' + suite_import.name + ' not found')
-        importing_suite.imports.append(suite_import)
-        _loadSuite(importMxDir, False)
-        # we do not check at this stage whether the tip version of imported_suite
-        # matches that of the import, since during development, this can and will change
-
     def _load_imports(self):
-        self.visit_imports(self._find_and_loadsuite)
+        if exists(join(self.mxDir, 'imports')):
+            abort('multiple suites are not supported in this version of mx')
 
     def _load_env(self):
         e = join(self.mxDir, 'env')
@@ -908,23 +631,23 @@
         if self.requiredMxVersion is None:
             warn("This suite does not express any required mx version. Consider adding 'mxversion=<version>' to your projects file.")
         elif self.requiredMxVersion > version:
-            abort("This suite requires mx version " + str(self.requiredMxVersion) + " while your current mx verion is " + str(version) + ". Please update mx.")
+            abort("This suite requires mx version " + str(self.requiredMxVersion) + " while your current mx version is " + str(version) + ". Please update mx.")
         # set the global data structures, checking for conflicts unless _check_global_structures is False
         for p in self.projects:
             existing = _projects.get(p.name)
-            if existing is not None and _check_global_structures:
+            if existing is not None:
                 abort('cannot override project  ' + p.name + ' in ' + p.dir + " with project of the same name in  " + existing.dir)
             if not p.name in _opts.ignored_projects:
                 _projects[p.name] = p
         for l in self.libs:
             existing = _libs.get(l.name)
             # Check that suites that define same library are consistent
-            if existing is not None and existing != l and _check_global_structures:
+            if existing is not None and existing != l:
                 abort('inconsistent library redefinition of ' + l.name + ' in ' + existing.suite.dir + ' and ' + l.suite.dir)
             _libs[l.name] = l
         for d in self.dists:
             existing = _dists.get(d.name)
-            if existing is not None and _check_global_structures:
+            if existing is not None:
                 # allow redefinition, so use path from existing
                 # abort('cannot redefine distribution  ' + d.name)
                 warn('distribution ' + d.name + ' redefined')
@@ -1003,7 +726,7 @@
         assert self.current == self
         result = self.toprettyxml(indent, newl, encoding="UTF-8")
         if escape:
-            entities = { '"':  "&quot;", "'":  "&apos;", '\n': '&#10;' }
+            entities = {'"':  "&quot;", "'":  "&apos;", '\n': '&#10;'}
             result = xml.sax.saxutils.escape(result, entities)
         if standalone is not None:
             result = result.replace('encoding="UTF-8"?>', 'encoding="UTF-8" standalone="' + str(standalone) + '"?>')
@@ -1039,14 +762,7 @@
     """
     Get the list of all loaded suites.
     """
-    if opt_limit_to_suite and _opts.specific_suites:
-        result = []
-        for s in _suites.values():
-            if s.name in _opts.specific_suites:
-                result.append(s)
-        return result
-    else:
-        return _suites.values()
+    return _suites.values()
 
 def suite(name, fatalIfMissing=True):
     """
@@ -1084,15 +800,7 @@
     return projects(True)
 
 def _projects_opt_limit_to_suites(projects):
-    if not _opts.specific_suites:
-        return projects
-    else:
-        result = []
-        for p in projects:
-            s = p.suite
-            if s.name in _opts.specific_suites:
-                result.append(p)
-        return result
+    return projects
 
 def annotation_processors():
     """
@@ -1282,16 +990,12 @@
         self.add_argument('-d', action='store_const', const=8000, dest='java_dbg_port', help='alias for "-dbg 8000"')
         self.add_argument('--cp-pfx', dest='cp_prefix', help='class path prefix', metavar='<arg>')
         self.add_argument('--cp-sfx', dest='cp_suffix', help='class path suffix', metavar='<arg>')
-        self.add_argument('--J', dest='java_args', help='Java VM arguments (e.g. --J @-dsa)', metavar='@<args>', default='-ea -Xss2m -Xmx1g')
+        self.add_argument('--J', dest='java_args', help='Java VM arguments (e.g. --J @-dsa)', metavar='@<args>')
         self.add_argument('--Jp', action='append', dest='java_args_pfx', help='prefix Java VM arguments (e.g. --Jp @-dsa)', metavar='@<args>', default=[])
         self.add_argument('--Ja', action='append', dest='java_args_sfx', help='suffix Java VM arguments (e.g. --Ja @-dsa)', metavar='@<args>', default=[])
         self.add_argument('--user-home', help='users home directory', metavar='<path>', default=os.path.expanduser('~'))
         self.add_argument('--java-home', help='bootstrap JDK installation directory (must be JDK 6 or later)', metavar='<path>')
         self.add_argument('--ignore-project', action='append', dest='ignored_projects', help='name of project to ignore', metavar='<name>', default=[])
-        self.add_argument('--suite', action='append', dest='specific_suites', help='limit command to given suite', default=[])
-        self.add_argument('--src-suitemodel', help='mechanism for locating imported suites', metavar='<arg>', default='sibling')
-        self.add_argument('--dst-suitemodel', help='mechanism for placing cloned/pushed suites', metavar='<arg>', default='sibling')
-        self.add_argument('--suitemap', help='explicit remapping of suite names', metavar='<args>')
         if get_os() != 'windows':
             # Time outs are (currently) implemented with Unix specific functionality
             self.add_argument('--timeout', help='timeout (in seconds) for command', type=int, default=0, metavar='<secs>')
@@ -1349,8 +1053,8 @@
     assert _java is not None
     return _java
 
-def run_java(args, nonZeroIsFatal=True, out=None, err=None, cwd=None):
-    return run(java().format_cmd(args), nonZeroIsFatal=nonZeroIsFatal, out=out, err=err, cwd=cwd)
+def run_java(args, nonZeroIsFatal=True, out=None, err=None, cwd=None, addDefaultArgs=True):
+    return run(java().format_cmd(args, addDefaultArgs), nonZeroIsFatal=nonZeroIsFatal, out=out, err=err, cwd=cwd)
 
 def _kill_process_group(pid):
     pgid = os.getpgid(pid)
@@ -1394,7 +1098,7 @@
 
 # Makes the current subprocess accessible to the abort() function
 # This is a tuple of the Popen object and args.
-_currentSubprocess = None
+_currentSubprocess = (None, None)
 
 def waitOn(p):
     if get_os() == 'windows':
@@ -1428,7 +1132,7 @@
             log('Environment variables:')
             for key in sorted(env.keys()):
                 log('    ' + key + '=' + env[key])
-        log(' '.join(args))
+        log(' '.join(map(pipes.quote, args)))
 
     if timeout is None and _opts.ptimeout != 0:
         timeout = _opts.ptimeout
@@ -1475,7 +1179,7 @@
     except KeyboardInterrupt:
         abort(1)
     finally:
-        _currentSubprocess = None
+        _currentSubprocess = (None, None)
 
     if retcode and nonZeroIsFatal:
         if _opts.verbose:
@@ -1556,15 +1260,18 @@
         assert m is not None, 'not a recognized version string: ' + ver
         self.value = int(m.group(1))
 
-    def __str__ (self):
+    def __str__(self):
         return '1.' + str(self.value)
 
-    def __cmp__ (self, other):
+    def __cmp__(self, other):
         if isinstance(other, types.StringType):
             other = JavaCompliance(other)
 
         return cmp(self.value, other.value)
 
+    def __hash__(self):
+        return self.value.__hash__()
+
 """
 A version specification as defined in JSR-56
 """
@@ -1603,7 +1310,7 @@
         def delAtAndSplit(s):
             return shlex.split(s.lstrip('@'))
 
-        self.java_args = delAtAndSplit(_opts.java_args)
+        self.java_args = delAtAndSplit(_opts.java_args) if _opts.java_args else []
         self.java_args_pfx = sum(map(delAtAndSplit, _opts.java_args_pfx), [])
         self.java_args_sfx = sum(map(delAtAndSplit, _opts.java_args_sfx), [])
 
@@ -1626,8 +1333,14 @@
         if self.debug_port is not None:
             self.java_args += ['-Xdebug', '-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=' + str(self.debug_port)]
 
-    def format_cmd(self, args):
-        return [self.java] + self.java_args_pfx + self.java_args + self.java_args_sfx + args
+    def format_cmd(self, args, addDefaultArgs):
+        if addDefaultArgs:
+            return [self.java] + self.processArgs(args)
+        else:
+            return [self.java] + args
+
+    def processArgs(self, args):
+        return self.java_args_pfx + self.java_args + self.java_args_sfx + args
 
     def bootclasspath(self):
         if self._bootclasspath is None:
@@ -1725,9 +1438,8 @@
 
     # import traceback
     # traceback.print_stack()
-    currentSubprocess = _currentSubprocess
-    if currentSubprocess is not None:
-        p, _ = currentSubprocess
+    p, _ = _currentSubprocess
+    if p is not None:
         if get_os() == 'windows':
             p.kill()
         else:
@@ -1758,13 +1470,13 @@
 
     def url_open(url):
         userAgent = 'Mozilla/5.0 (compatible)'
-        headers = { 'User-Agent' : userAgent }
+        headers = {'User-Agent' : userAgent}
         req = urllib2.Request(url, headers=headers)
         return urllib2.urlopen(req)
 
     for url in urls:
         try:
-            if (verbose):
+            if verbose:
                 log('Downloading ' + url + ' to ' + path)
             if url.startswith('zip:') or url.startswith('jar:'):
                 i = url.find('!/')
@@ -1851,6 +1563,7 @@
     parser.add_argument('--only', action='store', help='comma separated projects to build, without checking their dependencies (omit to build all projects)')
     parser.add_argument('--no-java', action='store_false', dest='java', help='do not build Java projects')
     parser.add_argument('--no-native', action='store_false', dest='native', help='do not build native projects')
+    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='<path>')
     parser.add_argument('--jdt-warning-as-error', action='store_true', help='convert all Eclipse batch compiler warnings to errors')
 
@@ -1860,12 +1573,16 @@
     args = parser.parse_args(args)
 
     jdtJar = None
-    if args.jdt is not None:
-        if args.jdt.endswith('.jar'):
-            jdtJar = args.jdt
-            if not exists(jdtJar) and os.path.abspath(jdtJar) == os.path.abspath(defaultEcjPath) and get_env('JDT', None) is None:
-                # Silently ignore JDT if default location is used but not ecj.jar exists there
+    if not args.javac and args.jdt is not None:
+        if not args.jdt.endswith('.jar'):
+            abort('Path for Eclipse batch compiler does not look like a jar file: ' + args.jdt)
+        jdtJar = args.jdt
+        if not exists(jdtJar):
+            if os.path.abspath(jdtJar) == os.path.abspath(defaultEcjPath) and get_env('JDT', None) is None:
+                # Silently ignore JDT if default location is used but does not exist
                 jdtJar = None
+            else:
+                abort('Eclipse batch compiler jar does not exist: ' + args.jdt)
 
     built = set()
 
@@ -2047,7 +1764,7 @@
                 if java().debug_port is not None:
                     jdtArgs += ['-Xdebug', '-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=' + str(java().debug_port)]
 
-                jdtArgs += [ '-jar', jdtJar,
+                jdtArgs += ['-jar', jdtJar,
                          '-' + compliance,
                          '-cp', cp, '-g', '-enableJavadoc',
                          '-d', outputDir]
@@ -2491,7 +2208,7 @@
         dotCheckstyle = join(p.dir, '.checkstyle')
 
         if not exists(dotCheckstyle):
-            continue
+            abort('ERROR: .checkstyle for Project {0} is missing'.format(p.name))
 
         # skip checking this Java project if its Java compliance level is "higher" than the configured JDK
         if java().javaCompliance < p.javaCompliance:
@@ -2566,7 +2283,7 @@
                     size = 0
                     while i < len(javafilelist):
                         s = len(javafilelist[i]) + 1
-                        if (size + s < 30000):
+                        if size + s < 30000:
                             size += s
                             i += 1
                         else:
@@ -2742,10 +2459,7 @@
     slm.open('sourceLookupDirector')
     slm.open('sourceContainers', {'duplicates' : 'false'})
 
-    # Every Java program depends on the JRE
-    memento = XMLDoc().element('classpathContainer', {'path' : 'org.eclipse.jdt.launching.JRE_CONTAINER'}).xml(standalone='no')
-    slm.element('classpathContainer', {'memento' : memento, 'typeId':'org.eclipse.jdt.launching.sourceContainer.classpathContainer'})
-
+    javaCompliance = None
     for dep in deps:
         if dep.isLibrary():
             if hasattr(dep, 'eclipse.container'):
@@ -2757,6 +2471,15 @@
         else:
             memento = XMLDoc().element('javaProject', {'name' : dep.name}).xml(standalone='no')
             slm.element('container', {'memento' : memento, 'typeId':'org.eclipse.jdt.launching.sourceContainer.javaProject'})
+            if javaCompliance is None or dep.javaCompliance < javaCompliance:
+                javaCompliance = dep.javaCompliance
+
+    if javaCompliance:
+        memento = XMLDoc().element('classpathContainer', {'path' : 'org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-' + str(javaCompliance)}).xml(standalone='no')
+        slm.element('classpathContainer', {'memento' : memento, 'typeId':'org.eclipse.jdt.launching.sourceContainer.classpathContainer'})
+    else:
+        memento = XMLDoc().element('classpathContainer', {'path' : 'org.eclipse.jdt.launching.JRE_CONTAINER'}).xml(standalone='no')
+        slm.element('classpathContainer', {'memento' : memento, 'typeId':'org.eclipse.jdt.launching.sourceContainer.classpathContainer'})
 
     slm.close('sourceContainers')
     slm.close('sourceLookupDirector')
@@ -2870,12 +2593,10 @@
     generate_eclipse_workingsets()
 
 def _check_ide_timestamp(suite, configZip, ide):
-    """return True if and only if the projects file, imports file, eclipse-settings files, and mx itself are all older than configZip"""
+    """return True if and only if the projects file, eclipse-settings files, and mx itself are all older than configZip"""
     projectsFile = join(suite.mxDir, 'projects')
     if configZip.isOlderThan(projectsFile):
         return False
-    if configZip.isOlderThan(suite.import_timestamp()):
-        return False
     # Assume that any mx change might imply changes to the generated IDE files
     if configZip.isOlderThan(__file__):
         return False
@@ -2933,7 +2654,7 @@
             out.element('classpathentry', {'kind' : 'src', 'path' : 'src_gen'})
             files.append(genDir)
 
-        # Every Java program depends on the JRE
+        # Every Java program depends on a JRE
         out.element('classpathentry', {'kind' : 'con', 'path' : 'org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-' + str(p.javaCompliance)})
 
         if exists(join(p.dir, 'plugin.xml')):  # eclipse plugin project
@@ -3135,7 +2856,7 @@
     launchOut.open('launchConfiguration', {'type' : 'org.eclipse.ui.externaltools.ProgramBuilderLaunchConfigurationType'})
     launchOut.element('booleanAttribute', {'key' : 'org.eclipse.debug.core.capture_output', 'value': consoleOn})
     launchOut.open('mapAttribute', {'key' : 'org.eclipse.debug.core.environmentVariables'})
-    launchOut.element('mapEntry', {'key' : 'JAVA_HOME', 	'value' : java().jdk})
+    launchOut.element('mapEntry', {'key' : 'JAVA_HOME', 'value' : java().jdk})
     launchOut.close('mapAttribute')
 
     if refresh:
@@ -3258,9 +2979,6 @@
     else:
         return _find_eclipse_wsroot(split[0])
 
-def _foobar(val):
-    print(val)
-
 def _make_workingset_xml(workingSets):
     wsdoc = XMLDoc()
     wsdoc.open('workingSetManager')
@@ -3286,30 +3004,46 @@
             self.current_ws = None
             self.seen_ws = list()
             self.seen_projects = list()
+            self.aggregate_ws = False
+            self.nested_ws = False
 
     ps = ParserState()
 
     # parsing logic
     def _ws_start(name, attributes):
         if name == 'workingSet':
-            ps.current_ws_name = attributes['name']
-            if workingSets.has_key(ps.current_ws_name):
-                ps.current_ws = workingSets[ps.current_ws_name]
-                ps.seen_ws.append(ps.current_ws_name)
-                ps.seen_projects = list()
-            else:
-                ps.current_ws = None
+            if attributes.has_key('name'):
+                ps.current_ws_name = attributes['name']
+                if attributes.has_key('aggregate') and attributes['aggregate'] == 'true':
+                    ps.aggregate_ws = True
+                    ps.current_ws = None
+                elif workingSets.has_key(ps.current_ws_name):
+                    ps.current_ws = workingSets[ps.current_ws_name]
+                    ps.seen_ws.append(ps.current_ws_name)
+                    ps.seen_projects = list()
+                else:
+                    ps.current_ws = None
             target.open(name, attributes)
             parser.StartElementHandler = _ws_item
 
     def _ws_end(name):
+        closeAndResetHandler = False
         if name == 'workingSet':
-            if not ps.current_ws is None:
-                for p in ps.current_ws:
-                    if not p in ps.seen_projects:
-                        _workingset_element(target, p)
-            target.close('workingSet')
-            parser.StartElementHandler = _ws_start
+            if ps.aggregate_ws:
+                if ps.nested_ws:
+                    ps.nested_ws = False
+                else:
+                    ps.aggregate_ws = False
+                    closeAndResetHandler = True
+            else:
+                if not ps.current_ws is None:
+                    for p in ps.current_ws:
+                        if not p in ps.seen_projects:
+                            _workingset_element(target, p)
+                closeAndResetHandler = True
+            if closeAndResetHandler:
+                target.close('workingSet')
+                parser.StartElementHandler = _ws_start
         elif name == 'workingSetManager':
             # process all working sets that are new to the file
             for w in sorted(workingSets.keys()):
@@ -3323,10 +3057,17 @@
         if name == 'item':
             if ps.current_ws is None:
                 target.element(name, attributes)
+            elif not attributes.has_key('elementID') and attributes.has_key('factoryID') and attributes.has_key('path') and attributes.has_key('type'):
+                target.element(name, attributes)
+                p_name = attributes['path'][1:] # strip off the leading '/'
+                ps.seen_projects.append(p_name)
             else:
                 p_name = attributes['elementID'][1:]  # strip off the leading '='
                 _workingset_element(target, p_name)
                 ps.seen_projects.append(p_name)
+        elif name == 'workingSet':
+            ps.nested_ws = True
+            target.element(name, attributes)
 
     # process document
     parser.StartElementHandler = _ws_start
@@ -3377,7 +3118,7 @@
         out.element('description', data='Builds, tests, and runs the project ' + p.name + '.')
         out.element('import', {'file' : 'nbproject/build-impl.xml'})
         out.open('target', {'name' : '-post-compile'})
-        out.open('exec', { 'executable' : sys.executable})
+        out.open('exec', {'executable' : sys.executable})
         out.element('env', {'key' : 'JAVA_HOME', 'value' : java().jdk})
         out.element('arg', {'value' : os.path.abspath(__file__)})
         out.element('arg', {'value' : 'archive'})
@@ -3626,9 +3367,6 @@
                 # no point in traversing .hg
                 if '.hg' in dirnames:
                     dirnames.remove('.hg')
-                # if there are nested suites must not scan those now, as they are not in projectDirs
-                if _src_suitemodel.nestedsuites_dirname() in dirnames:
-                    dirnames.remove(_src_suitemodel.nestedsuites_dirname())
             elif dirpath in projectDirs:
                 # don't traverse subdirs of an existing project in this suite
                 dirnames[:] = []
@@ -4047,266 +3785,6 @@
         return kwargs.pop(0)
     return None
 
-def sclone(args):
-    """clone a suite repository, and its imported suites"""
-    _hg.check()
-    parser = ArgumentParser(prog='mx sclone')
-    parser.add_argument('--source', help='url/path of repo containing suite', metavar='<url>')
-    parser.add_argument('--dest', help='destination directory (default basename of source)', metavar='<path>')
-    parser.add_argument("--no-imports", action='store_true', help='do not clone imported suites')
-    parser.add_argument('nonKWArgs', nargs=REMAINDER, metavar='source [dest]...')
-    args = parser.parse_args(args)
-    # check for non keyword args
-    if args.source is None:
-        args.source = _kwArg(args.nonKWArgs)
-    if args.dest is None:
-        args.dest = _kwArg(args.nonKWArgs)
-    if len(args.nonKWArgs) > 0:
-        abort('unrecognized args: ' + ' '.join(args.nonKWArgs))
-
-    if args.source is None:
-        # must be primary suite and dest is required
-        if _primary_suite is None:
-            abort('--source missing and no primary suite found')
-        if args.dest is None:
-            abort('--dest required when --source is not given')
-        source = _primary_suite.dir
-    else:
-        source = args.source
-
-    if args.dest is not None:
-        dest = args.dest
-    else:
-        dest = basename(source)
-
-    dest = os.path.abspath(dest)
-    # We can now set the primary dir for the src/dst suitemodel
-    _dst_suitemodel.set_primary_dir(dest)
-    _src_suitemodel.set_primary_dir(source)
-
-    _sclone(source, dest, None, args.no_imports)
-
-def _sclone(source, dest, version, no_imports):
-    cmd = ['hg', 'clone']
-    if version is not None:
-        cmd.append('-r')
-        cmd.append(version)
-    cmd.append(source)
-    cmd.append(dest)
-
-    run(cmd)
-
-    mxDir = _is_suite_dir(dest)
-    if mxDir is None:
-        warn(source + ' is not an mx suite')
-        return None
-
-    # create a Suite (without loading) to enable imports visitor
-    s = Suite(mxDir, False, load=False)
-    if not no_imports:
-        s.visit_imports(_scloneimports_visitor, source=source)
-    return s
-
-def _scloneimports_visitor(s, suite_import, source, **extra_args):
-    """
-    cloneimports visitor for Suite.visit_imports.
-    The destination information is encapsulated by 's'
-    """
-    _scloneimports(s, suite_import, source)
-
-def _scloneimports_suitehelper(sdir):
-    mxDir = _is_suite_dir(sdir)
-    if mxDir is None:
-        abort(sdir + ' is not an mx suite')
-    else:
-        # create a Suite (without loading) to enable imports visitor
-        return Suite(mxDir, False, load=False)
-
-def _scloneimports(s, suite_import, source):
-    # clone first, then visit imports once we can locate them
-    importee_source = _src_suitemodel.importee_dir(source, suite_import.name)
-    importee_dest = _dst_suitemodel.importee_dir(s.dir, suite_import.name)
-    if exists(importee_dest):
-        # already exists in the suite model, but may be wrong version
-        importee_suite = _scloneimports_suitehelper(importee_dest)
-        if suite_import.version is not None and importee_suite.version() != suite_import.version:
-            abort("imported version of " + suite_import.name + " in " + s.name + " does not match the version in already existing suite: " + importee_suite.dir)
-        importee_suite.visit_imports(_scloneimports_visitor, source=importee_source)
-    else:
-        _sclone(importee_source, importee_dest, suite_import.version, False)
-        # _clone handles the recursive visit of the new imports
-
-def scloneimports(args):
-    """clone the imports of an existing suite"""
-    _hg.check()
-    parser = ArgumentParser(prog='mx scloneimports')
-    parser.add_argument('--source', help='url/path of repo containing suite', metavar='<url>')
-    parser.add_argument('nonKWArgs', nargs=REMAINDER, metavar='source [dest]...')
-    args = parser.parse_args(args)
-    # check for non keyword args
-    if args.source is None:
-        args.source = _kwArg(args.nonKWArgs)
-
-    if not os.path.isdir(args.source):
-        abort(args.source + ' is not a directory')
-
-    s = _scloneimports_suitehelper(args.source)
-
-    default_path = _hg.default_push(args.source)
-
-    if default_path is None:
-        abort('no default path in ' + join(args.source, '.hg', 'hgrc'))
-
-    # We can now set the primary dir for the dst suitemodel
-    # N.B. source is effectively the destination and the default_path is the (original) source
-    _dst_suitemodel.set_primary_dir(args.source)
-
-    s.visit_imports(_scloneimports_visitor, source=default_path)
-
-def _spush_import_visitor(s, suite_import, dest, checks, clonemissing, **extra_args):
-    """push visitor for Suite.visit_imports"""
-    if dest is not None:
-        dest = _dst_suitemodel.importee_dir(dest, suite_import.name)
-    _spush(suite(suite_import.name), suite_import, dest, checks, clonemissing)
-
-def _spush_check_import_visitor(s, suite_import, **extra_args):
-    """push check visitor for Suite.visit_imports"""
-    currentTip = suite(suite_import.name).version()
-    if currentTip != suite_import.version:
-        abort('imported version of ' + suite_import.name + ' in suite ' + s.name + ' does not match tip')
-
-def _spush(s, suite_import, dest, checks, clonemissing):
-    if checks:
-        if not _hg.can_push(s):
-            abort('working directory ' + s.dir + ' contains uncommitted changes, push aborted')
-
-    # check imports first
-    if checks:
-        s.visit_imports(_spush_check_import_visitor)
-
-    # ok, push imports
-    s.visit_imports(_spush_import_visitor, dest=dest, checks=checks, clonemissing=clonemissing)
-
-    dest_exists = True
-
-    if clonemissing:
-        if not os.path.exists(dest):
-            dest_exists = False
-
-    def add_version(cmd, suite_import):
-        if suite_import is not None and suite_import.version is not None:
-            cmd.append('-r')
-            cmd.append(suite_import.version)
-
-    if dest_exists:
-        cmd = ['hg', '-R', s.dir, 'push']
-        add_version(cmd, suite_import)
-        if dest is not None:
-            cmd.append(dest)
-        rc = run(cmd, nonZeroIsFatal=False)
-        if rc != 0:
-            # rc of 1 not an error,  means no changes
-            if rc != 1:
-                abort("push failed, exit code " + str(rc))
-    else:
-        cmd = ['hg', 'clone']
-        add_version(cmd, suite_import)
-        cmd.append(s.dir)
-        cmd.append(dest)
-        run(cmd)
-
-def spush(args):
-    """push primary suite and all its imports"""
-    _hg.check()
-    parser = ArgumentParser(prog='mx spush')
-    parser.add_argument('--dest', help='url/path of repo to push to (default as per hg push)', metavar='<path>')
-    parser.add_argument('--no-checks', action='store_true', help='checks on status, versions are disabled')
-    parser.add_argument('--clonemissing', action='store_true', help='clone missing imported repos at destination (forces --no-checks)')
-    parser.add_argument('nonKWArgs', nargs=REMAINDER, metavar='source [dest]...')
-    args = parser.parse_args(args)
-    if args.dest is None:
-        args.dest = _kwArg(args.nonKWArgs)
-    if len(args.nonKWArgs) > 0:
-        abort('unrecognized args: ' + ' '.join(args.nonKWArgs))
-
-    if args.dest is not None and not os.path.isdir(args.dest):
-        abort('destination must be a directory')
-
-    s = _check_primary_suite()
-
-    if args.clonemissing:
-        if args.dest is None:
-            abort('--dest required with --clonemissing')
-        args.nochecks = True
-
-    if args.dest is not None:
-        _dst_suitemodel.set_primary_dir(args.dest)
-
-    _spush(s, None, args.dest, not args.no_checks, args.clonemissing)
-
-def _supdate_import_visitor(s, suite_import, **extra_args):
-    _supdate(suite(suite_import.name), suite_import)
-
-def _supdate(s, suite_import):
-    s.visit_imports(_supdate_import_visitor)
-
-    run(['hg', '-R', s.dir, 'update'])
-
-def supdate(args):
-    """update primary suite and all its imports"""
-
-    _hg.check()
-    s = _check_primary_suite()
-
-    _supdate(s, None)
-
-def _scheck_imports_visitor(s, suite_import, update_versions, updated_imports):
-    """scheckimports visitor for Suite.visit_imports"""
-    _scheck_imports(s, suite(suite_import.name), suite_import, update_versions, updated_imports)
-
-def _scheck_imports(importing_suite, imported_suite, suite_import, update_versions, updated_imports):
-    # check imports recursively
-    imported_suite.visit_imports(_scheck_imports_visitor, update_versions=update_versions)
-
-    currentTip = imported_suite.version()
-    if currentTip != suite_import.version:
-        print('imported version of ' + imported_suite.name + ' in ' + importing_suite.name + ' does not match tip' + (': updating' if update_versions else ''))
-
-    if update_versions:
-        suite_import.version = currentTip
-        line = str(suite_import)
-        updated_imports.write(line + '\n')
-
-def scheckimports(args):
-    """check that suite import versions are up to date"""
-    parser = ArgumentParser(prog='mx scheckimports')
-    parser.add_argument('--update-versions', help='update imported version ids', action='store_true')
-    args = parser.parse_args(args)
-    _check_primary_suite().visit_imports(_scheck_imports_visitor, update_versions=args.update_versions)
-
-def _spull_import_visitor(s, suite_import, update_versions, updated_imports):
-    """pull visitor for Suite.visit_imports"""
-    _spull(suite(suite_import.name), update_versions, updated_imports)
-
-def _spull(s, update_versions, updated_imports):
-    _hg.check()
-    # pull imports first
-    s.visit_imports(_spull_import_visitor, update_versions=update_versions)
-
-    run(['hg', '-R', s.dir, 'pull', '-u'])
-    if update_versions and updated_imports is not None:
-        tip = s.version()
-        updated_imports.write(SuiteImport.tostring(s.name, tip) + '\n')
-
-def spull(args):
-    """pull primary suite and all its imports"""
-    _hg.check()
-    parser = ArgumentParser(prog='mx spull')
-    parser.add_argument('--update-versions', action='store_true', help='update version ids of imported suites')
-    args = parser.parse_args(args)
-
-    _spull(_check_primary_suite(), args.update_versions, None)
-
 def findclass(args, logToConsole=True):
     """find all classes matching a given substring"""
     matches = []
@@ -4421,7 +3899,7 @@
 
 def warn(msg):
     if _warn:
-        print('WARNING: ' + msg)
+        print 'WARNING: ' + msg
 
 # Table of commands in alphabetical order.
 # Keys are command names, value are lists: [<function>, <usage msg>, <format args to doc string of function>...]
@@ -4443,12 +3921,6 @@
     'ideinit': [ideinit, ''],
     'archive': [archive, '[options]'],
     'projectgraph': [projectgraph, ''],
-    'sclone': [sclone, '[options]'],
-    'scheckimports': [scheckimports, ''],
-    'scloneimports': [scloneimports, '[options]'],
-    'spull': [spull, '[options'],
-    'spush': [spush, '[options'],
-    'supdate': [supdate, ''],
     'pylint': [pylint, ''],
     'javap': [javap, '<class name patterns>'],
     'javadoc': [javadoc, '[options]'],
@@ -4486,12 +3958,6 @@
     else:
         return _primary_suite
 
-def _needs_primary_suite(command):
-    return not command.startswith("sclone")
-
-def _needs_primary_suite_cl():
-    return not any("sclone" in s for s in sys.argv[1:])
-
 def _findPrimarySuiteMxDirFrom(d):
     """ search for a suite directory upwards from 'd' """
     while d:
@@ -4522,34 +3988,15 @@
     return _findPrimarySuiteMxDirFrom(dirname(__file__))
 
 def main():
-    SuiteModel.parse_options()
-
-    global _hg
-    _hg = HgConfig()
-
-    primary_suite_error = 'no primary suite found'
     primarySuiteMxDir = _findPrimarySuiteMxDir()
     if primarySuiteMxDir:
-        _src_suitemodel.set_primary_dir(dirname(primarySuiteMxDir))
         global _primary_suite
         _primary_suite = _loadSuite(primarySuiteMxDir, True)
     else:
-        # in general this is an error, except for the sclone/scloneimports commands,
-        # and an extensions command will likely not parse in this case, as any extra arguments
-        # will not have been added to _argParser.
-        # If the command line does not contain a string matching one of the exceptions, we can safely abort,
-        # but not otherwise, as we can't be sure the string isn't in a value for some other option.
-        if _needs_primary_suite_cl():
-            abort(primary_suite_error)
+        abort('no primary suite found')
 
     opts, commandAndArgs = _argParser._parse_cmd_line()
 
-    if primarySuiteMxDir is None:
-        if len(commandAndArgs) > 0 and _needs_primary_suite(commandAndArgs[0]):
-            abort(primary_suite_error)
-        else:
-            warn(primary_suite_error)
-
     global _opts, _java
     _opts = opts
     _java = JavaConfig(opts)
--- a/src/cpu/sparc/vm/sharedRuntime_sparc.cpp	Sun Feb 23 17:00:35 2014 -0800
+++ b/src/cpu/sparc/vm/sharedRuntime_sparc.cpp	Wed Mar 05 19:40:15 2014 -0800
@@ -1006,6 +1006,15 @@
   __ delayed()->nop();
 }
 
+void SharedRuntime::gen_i2c_adapter(MacroAssembler *masm,
+                                    int total_args_passed,
+                                    int comp_args_on_stack,
+                                    const BasicType *sig_bt,
+                                    const VMRegPair *regs) {
+  AdapterGenerator agen(masm);
+  agen.gen_i2c_adapter(total_args_passed, comp_args_on_stack, sig_bt, regs);
+}
+
 // ---------------------------------------------------------------
 AdapterHandlerEntry* SharedRuntime::generate_i2c2i_adapters(MacroAssembler *masm,
                                                             int total_args_passed,
@@ -1016,9 +1025,7 @@
                                                             AdapterFingerPrint* fingerprint) {
   address i2c_entry = __ pc();
 
-  AdapterGenerator agen(masm);
-
-  agen.gen_i2c_adapter(total_args_passed, comp_args_on_stack, sig_bt, regs);
+  gen_i2c_adapter(masm, total_args_passed, comp_args_on_stack, sig_bt, regs);
 
 
   // -------------------------------------------------------------------------
@@ -1063,7 +1070,7 @@
   }
 
   address c2i_entry = __ pc();
-
+  AdapterGenerator agen(masm);
   agen.gen_c2i_adapter(total_args_passed, comp_args_on_stack, sig_bt, regs, L_skip_fixup);
 
   __ flush();
--- a/src/cpu/x86/vm/sharedRuntime_x86_32.cpp	Sun Feb 23 17:00:35 2014 -0800
+++ b/src/cpu/x86/vm/sharedRuntime_x86_32.cpp	Wed Mar 05 19:40:15 2014 -0800
@@ -711,7 +711,7 @@
   __ bind(L_fail);
 }
 
-static void gen_i2c_adapter(MacroAssembler *masm,
+void SharedRuntime::gen_i2c_adapter(MacroAssembler *masm,
                             int total_args_passed,
                             int comp_args_on_stack,
                             const BasicType *sig_bt,
--- a/src/cpu/x86/vm/sharedRuntime_x86_64.cpp	Sun Feb 23 17:00:35 2014 -0800
+++ b/src/cpu/x86/vm/sharedRuntime_x86_64.cpp	Wed Mar 05 19:40:15 2014 -0800
@@ -642,7 +642,7 @@
   __ bind(L_fail);
 }
 
-static void gen_i2c_adapter(MacroAssembler *masm,
+void SharedRuntime::gen_i2c_adapter(MacroAssembler *masm,
                             int total_args_passed,
                             int comp_args_on_stack,
                             const BasicType *sig_bt,
--- a/src/gpu/hsail/vm/gpu_hsail.cpp	Sun Feb 23 17:00:35 2014 -0800
+++ b/src/gpu/hsail/vm/gpu_hsail.cpp	Wed Mar 05 19:40:15 2014 -0800
@@ -25,43 +25,60 @@
 #include "precompiled.hpp"
 #include "runtime/javaCalls.hpp"
 #include "runtime/gpu.hpp"
+#include "hsail/vm/gpu_hsail.hpp"
 #include "utilities/globalDefinitions.hpp"
 #include "utilities/ostream.hpp"
 #include "memory/allocation.hpp"
 #include "memory/allocation.inline.hpp"
+#include "graal/graalEnv.hpp"
+#include "graal/graalCompiler.hpp"
+#include "graal/graalJavaAccess.hpp"
 #include "hsailKernelArguments.hpp"
 
-void * gpu::Hsail::_device_context;
+// Entry to GPU native method implementation that transitions current thread to '_thread_in_vm'.
+#define GPU_VMENTRY(result_type, name, signature) \
+  JNIEXPORT result_type JNICALL name signature { \
+  GRAAL_VM_ENTRY_MARK; \
+
+// Entry to GPU native method implementation that calls a JNI function
+// and hence cannot transition current thread to '_thread_in_vm'.
+#define GPU_ENTRY(result_type, name, signature) \
+  JNIEXPORT result_type JNICALL name signature { \
+
+#define GPU_END }
+
+#define CC (char*)  /*cast a literal from (const char*)*/
+#define FN_PTR(f) CAST_FROM_FN_PTR(void*, &(f))
+
+#define OBJECT                "Ljava/lang/Object;"
+#define STRING                "Ljava/lang/String;"
+#define HS_INSTALLED_CODE     "Lcom/oracle/graal/hotspot/meta/HotSpotInstalledCode;"
+
+//  public native void executeKernel(HotSpotNmethod kernel, int jobSize, int i, int j, Object[] args) throws InvalidInstalledCodeException;
 
-gpu::Hsail::okra_create_context_func_t  gpu::Hsail::_okra_create_context;
-gpu::Hsail::okra_create_kernel_func_t   gpu::Hsail::_okra_create_kernel;
-gpu::Hsail::okra_push_object_func_t     gpu::Hsail::_okra_push_object;
-gpu::Hsail::okra_push_boolean_func_t    gpu::Hsail::_okra_push_boolean;
-gpu::Hsail::okra_push_byte_func_t       gpu::Hsail::_okra_push_byte;
-gpu::Hsail::okra_push_double_func_t     gpu::Hsail::_okra_push_double;
-gpu::Hsail::okra_push_float_func_t      gpu::Hsail::_okra_push_float;
-gpu::Hsail::okra_push_int_func_t        gpu::Hsail::_okra_push_int;
-gpu::Hsail::okra_push_long_func_t       gpu::Hsail::_okra_push_long;
-gpu::Hsail::okra_execute_with_range_func_t    gpu::Hsail::_okra_execute_with_range;
-gpu::Hsail::okra_clearargs_func_t       gpu::Hsail::_okra_clearargs;
-gpu::Hsail::okra_register_heap_func_t   gpu::Hsail::_okra_register_heap;
+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")Z",  FN_PTR(Hsail::execute_kernel_void_1d)},
+};
+
+void * Hsail::_device_context = NULL;
+
+Hsail::okra_create_context_func_t  Hsail::_okra_create_context;
+Hsail::okra_create_kernel_func_t   Hsail::_okra_create_kernel;
+Hsail::okra_push_object_func_t     Hsail::_okra_push_object;
+Hsail::okra_push_boolean_func_t    Hsail::_okra_push_boolean;
+Hsail::okra_push_byte_func_t       Hsail::_okra_push_byte;
+Hsail::okra_push_double_func_t     Hsail::_okra_push_double;
+Hsail::okra_push_float_func_t      Hsail::_okra_push_float;
+Hsail::okra_push_int_func_t        Hsail::_okra_push_int;
+Hsail::okra_push_long_func_t       Hsail::_okra_push_long;
+Hsail::okra_execute_with_range_func_t    Hsail::_okra_execute_with_range;
+Hsail::okra_clearargs_func_t       Hsail::_okra_clearargs;
+Hsail::okra_register_heap_func_t   Hsail::_okra_register_heap;
 
 
-bool gpu::Hsail::initialize_gpu() {
-  // All the initialization is done in the okra library so
-  // nothing to do here.
-  if (TraceGPUInteraction) {
-    tty->print_cr("[HSAIL] Simulator: initialize_gpu");
-  }
-  return true;
-}
-
-unsigned int gpu::Hsail::total_cores() {
-  // This is not important with simulator
-  return 1;
-}
-
-void gpu::Hsail::register_heap() {
+void Hsail::register_heap() {
   // After the okra functions are set up and the heap is initialized, register the java heap with HSA
   guarantee(Universe::heap() != NULL, "heap should be there by now.");
   if (TraceGPUInteraction) {
@@ -71,48 +88,67 @@
   _okra_register_heap(Universe::heap()->base(), Universe::heap()->capacity());
 }
 
-bool  gpu::Hsail::execute_kernel_void_1d(address kernel, int dimX, jobject args, methodHandle& mh) {
-  objArrayOop argsArray = (objArrayOop) JNIHandles::resolve(args);
+GPU_VMENTRY(jboolean, Hsail::execute_kernel_void_1d, (JNIEnv* env, jclass, jobject kernel_handle, jint dimX, jobject args_handle))
+
+  ResourceMark rm;
+  jlong nmethodValue = HotSpotInstalledCode::codeBlob(kernel_handle);
+  if (nmethodValue == 0) {
+    SharedRuntime::throw_and_post_jvmti_exception(JavaThread::current(), vmSymbols::com_oracle_graal_api_code_InvalidInstalledCodeException(), NULL);
+  }
+  nmethod* nm = (nmethod*) (address) nmethodValue;
+  methodHandle mh = nm->method();
+  Symbol* signature = mh->signature();
+
+  void* kernel = (void*) HotSpotInstalledCode::codeStart(kernel_handle);
+  if (kernel == NULL) {
+    SharedRuntime::throw_and_post_jvmti_exception(JavaThread::current(), vmSymbols::com_oracle_graal_api_code_InvalidInstalledCodeException(), NULL);
+  }
+
+  objArrayOop args = (objArrayOop) JNIHandles::resolve(args_handle);
 
   // Reset the kernel arguments
   _okra_clearargs(kernel);
 
   // This object sets up the kernel arguments
-  HSAILKernelArguments hka(kernel, mh->signature(), argsArray, mh->is_static());
+  HSAILKernelArguments hka((address) kernel, mh->signature(), args, mh->is_static());
 
   // Run the kernel
-  bool success = _okra_execute_with_range(kernel, dimX);
-  return success;
-}
+  return _okra_execute_with_range(kernel, dimX);
+GPU_END
+
+GPU_ENTRY(jlong, Hsail::generate_kernel, (JNIEnv *env, jclass, jbyteArray code_handle, jstring name_handle))
+  guarantee(_okra_create_kernel != NULL, "[HSAIL] Okra not linked");
+  ResourceMark rm;
+  jsize name_len = env->GetStringLength(name_handle);
+  jsize code_len = env->GetArrayLength(code_handle);
 
-void *gpu::Hsail::generate_kernel(unsigned char *code, int code_len, const char *name) {
+  char* name = NEW_RESOURCE_ARRAY(char, name_len + 1);
+  unsigned char *code = NEW_RESOURCE_ARRAY(unsigned char, code_len + 1);
 
-  gpu::Hsail::register_heap();
+  code[code_len] = 0;
+  name[name_len] = 0;
+
+  env->GetByteArrayRegion(code_handle, 0, code_len, (jbyte*) code);
+  env->GetStringUTFRegion(name_handle, 0, name_len, name);
+
+  register_heap();
 
   // The kernel entrypoint is always run for the time being  
   const char* entryPointName = "&run";
 
   _device_context = _okra_create_context();
 
-  // code is not null terminated, must be a better way to do this
-  unsigned char* nullTerminatedCodeBuffer = (unsigned char*) malloc(code_len + 1);
-  memcpy(nullTerminatedCodeBuffer, code, code_len);
-  nullTerminatedCodeBuffer[code_len] = 0;
-  void* kernel = _okra_create_kernel(_device_context, nullTerminatedCodeBuffer, entryPointName);
-  free(nullTerminatedCodeBuffer);
-  return kernel;
-}
+  return (jlong) _okra_create_kernel(_device_context, code, entryPointName);
+GPU_END
 
 #if defined(LINUX)
-static const char okra_library_name[] = "libokra_x86_64.so";
-#elif defined (_WINDOWS)
-static char const okra_library_name[] = "okra_x86_64.dll";
+static const char* okra_library_name = "libokra_x86_64.so";
+#elif defined(_WINDOWS)
+static char const* okra_library_name = "okra_x86_64.dll";
 #else
-static char const okra_library_name[] = "";
+static char const* okra_library_name = NULL;
 #endif
 
-#define STD_BUFFER_SIZE 1024
-
 #define STRINGIFY(x)     #x
 
 #define LOOKUP_OKRA_FUNCTION(name, alias)  \
@@ -120,48 +156,76 @@
     CAST_TO_FN_PTR(alias##_func_t, os::dll_lookup(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 0; \
+        return false; \
   } \
 
-bool gpu::Hsail::probe_linkage() {
-  if (okra_library_name != NULL) {
-    char *buffer = (char*)malloc(STD_BUFFER_SIZE);
-    if (TraceGPUInteraction) {
-      tty->print_cr("[HSAIL] library is %s", okra_library_name);
-    }
-    void *handle = os::dll_load(okra_library_name, buffer, STD_BUFFER_SIZE);
-    free(buffer);
-    if (handle != NULL) {
-
-      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);
-      LOOKUP_OKRA_FUNCTION(okra_push_boolean, okra_push_boolean);
-      LOOKUP_OKRA_FUNCTION(okra_push_byte, okra_push_byte);
-      LOOKUP_OKRA_FUNCTION(okra_push_double, okra_push_double);
-      LOOKUP_OKRA_FUNCTION(okra_push_float, okra_push_float);
-      LOOKUP_OKRA_FUNCTION(okra_push_int, okra_push_int);
-      LOOKUP_OKRA_FUNCTION(okra_push_long, okra_push_long);
-      LOOKUP_OKRA_FUNCTION(okra_execute_with_range, okra_execute_with_range);
-      LOOKUP_OKRA_FUNCTION(okra_clearargs, okra_clearargs);
-      LOOKUP_OKRA_FUNCTION(okra_register_heap, okra_register_heap);
-
-      return true;
-    } else {
-      // Unable to dlopen okra
-      if (TraceGPUInteraction) {
-        tty->print_cr("[HSAIL] library load failed.");
-      }
-      return false;
-    }
-  } else {
+GPU_ENTRY(jboolean, Hsail::initialize, (JNIEnv *env, jclass))
+  if (okra_library_name == NULL) {
     if (TraceGPUInteraction) {
       tty->print_cr("Unsupported HSAIL platform");
     }
     return false;
   }
+
+  // here we know we have a valid okra_library_name to try to load
+  char ebuf[O_BUFLEN];
   if (TraceGPUInteraction) {
-    tty->print_cr("Failed to find HSAIL linkage");
+      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
+    if (TraceGPUInteraction) {
+      tty->print_cr("[HSAIL] library load failed.");
+    }
+    return false;
   }
-  return false;
+  
+  guarantee(_okra_create_context == NULL, "cannot repeat GPU initialization");
+
+  // at this point we know handle is valid and 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);
+  LOOKUP_OKRA_FUNCTION(okra_push_boolean, okra_push_boolean);
+  LOOKUP_OKRA_FUNCTION(okra_push_byte, okra_push_byte);
+  LOOKUP_OKRA_FUNCTION(okra_push_double, okra_push_double);
+  LOOKUP_OKRA_FUNCTION(okra_push_float, okra_push_float);
+  LOOKUP_OKRA_FUNCTION(okra_push_int, okra_push_int);
+  LOOKUP_OKRA_FUNCTION(okra_push_long, okra_push_long);
+  LOOKUP_OKRA_FUNCTION(okra_execute_with_range, okra_execute_with_range);
+  LOOKUP_OKRA_FUNCTION(okra_clearargs, okra_clearargs);
+  LOOKUP_OKRA_FUNCTION(okra_register_heap, okra_register_heap);
+  // if we made it this far, real success
+
+  gpu::initialized_gpu("Okra");
+
+  return true;
+GPU_END
+
+bool Hsail::register_natives(JNIEnv* env) {
+  jclass klass = env->FindClass("com/oracle/graal/hotspot/hsail/HSAILHotSpotBackend");
+  if (klass == NULL) {
+    if (TraceGPUInteraction) {
+      tty->print_cr("HSAILHotSpotBackend class not found");
+    }
+    return false;
+  }
+  jint status = env->RegisterNatives(klass, HSAIL_methods, sizeof(HSAIL_methods) / sizeof(JNINativeMethod));
+  if (status != JNI_OK) {
+    if (TraceGPUInteraction) {
+      tty->print_cr("Error registering natives for HSAILHotSpotBackend: %d", status);
+    }
+    return false;
+  }
+  return true;
 }
--- a/src/gpu/hsail/vm/gpu_hsail.hpp	Sun Feb 23 17:00:35 2014 -0800
+++ b/src/gpu/hsail/vm/gpu_hsail.hpp	Wed Mar 05 19:40:15 2014 -0800
@@ -26,17 +26,27 @@
 #define GPU_HSAIL_HPP
 
 class Hsail {
-  friend class gpu;
+
+private:
+
+  static JNINativeMethod HSAIL_methods[];
 
- protected:
-  static bool probe_linkage();
-  static bool initialize_gpu();
-  static unsigned int total_cores();
-  static void* generate_kernel(unsigned char *code, int code_len, const char *name);
-  static bool execute_kernel_void_1d(address kernel, int dimX, jobject args, methodHandle& mh);
+  // static native boolean initialize();
+  JNIEXPORT static jboolean initialize(JNIEnv *env, jclass);
+
+  // static native long generateKernel(byte[] targetCode, String name);
+  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);
+
   static void register_heap();
 
 public:
+
+  // Registers the implementations for the native methods in HSAILHotSpotBackend
+  static bool register_natives(JNIEnv* env);
+
 #if defined(__x86_64) || defined(AMD64) || defined(_M_AMD64)
   typedef unsigned long long CUdeviceptr;
 #else
@@ -56,7 +66,7 @@
   typedef bool (*okra_execute_with_range_func_t)(void*, jint);
   typedef bool (*okra_clearargs_func_t)(void*);
   typedef bool (*okra_register_heap_func_t)(void*, size_t);
-  
+
 public:
   static okra_create_context_func_t             _okra_create_context;
   static okra_create_kernel_func_t              _okra_create_kernel;
--- a/src/gpu/hsail/vm/hsailKernelArguments.cpp	Sun Feb 23 17:00:35 2014 -0800
+++ b/src/gpu/hsail/vm/hsailKernelArguments.cpp	Wed Mar 05 19:40:15 2014 -0800
@@ -46,7 +46,7 @@
   jvalue jValue;
   java_lang_boxing_object::get_value(arg, &jValue);
   
-  bool pushed = gpu::Hsail::_okra_push_boolean(_kernel, jValue.z);
+  bool pushed = Hsail::_okra_push_boolean(_kernel, jValue.z);
   assert(pushed == true, "arg push failed");
 }
 
@@ -58,7 +58,7 @@
   jvalue jValue;
   java_lang_boxing_object::get_value(arg, &jValue);
   
-  bool pushed = gpu::Hsail::_okra_push_byte(_kernel, jValue.b);
+  bool pushed = Hsail::_okra_push_byte(_kernel, jValue.b);
   assert(pushed == true, "arg push failed");
 }
 
@@ -70,9 +70,9 @@
   jvalue jValue;
   java_lang_boxing_object::get_value(arg, &jValue);
   if (TraceGPUInteraction) {
-    tty->print_cr("[HSAIL] HSAILKernelArguments::double value = %e", jValue.d);
+    tty->print_cr("[HSAIL] HSAILKernelArguments::do_double, _index=%d, value = %e", _index - 1, jValue.d);
   }  
-  bool pushed = gpu::Hsail::_okra_push_double(_kernel, jValue.d);
+  bool pushed = Hsail::_okra_push_double(_kernel, jValue.d);
   assert(pushed == true, "arg push failed");
 }
 
@@ -84,16 +84,16 @@
   jvalue jValue;
   java_lang_boxing_object::get_value(arg, &jValue);
   if (TraceGPUInteraction) {
-    tty->print_cr("[HSAIL] HSAILKernelArguments::float value = %f", jValue.f);
+    tty->print_cr("[HSAIL] HSAILKernelArguments::do_float, _index=%d, value = %f", _index - 1, jValue.f);
   }    
-  bool pushed = gpu::Hsail::_okra_push_float(_kernel, jValue.f);
+  bool pushed = Hsail::_okra_push_float(_kernel, jValue.f);
   assert(pushed == true, "float push failed");
 }
 
 void HSAILKernelArguments::do_int() {
   // The last int is the iteration variable in an IntStream, but we don't pass it
   // since we use the HSAIL workitemid in place of that int value
-  if (_parameter_index == _parameter_count - 1) {
+  if (isLastParameter()) {
     if (TraceGPUInteraction) {
       tty->print_cr("[HSAIL] HSAILKernelArguments::not pushing trailing int");
     }
@@ -106,8 +106,11 @@
   
   jvalue jValue;
   java_lang_boxing_object::get_value(arg, &jValue);
+  if (TraceGPUInteraction) {
+    tty->print_cr("[HSAIL] HSAILKernelArguments::do_int, _index=%d, value = %d", _index - 1, jValue.i);
+  }    
   
-  bool pushed = gpu::Hsail::_okra_push_int(_kernel, jValue.i);
+  bool pushed = Hsail::_okra_push_int(_kernel, jValue.i);
   assert(pushed == true, "arg push failed");
 }
 
@@ -118,8 +121,11 @@
   
   jvalue jValue;
   java_lang_boxing_object::get_value(arg, &jValue);
+  if (TraceGPUInteraction) {
+    tty->print_cr("[HSAIL] HSAILKernelArguments::do_long, _index=%d, value = %d", _index - 1, jValue.j);
+  }    
   
-  bool pushed = gpu::Hsail::_okra_push_long(_kernel, jValue.j);
+  bool pushed = Hsail::_okra_push_long(_kernel, jValue.j);
   assert(pushed == true, "arg push failed");  
 }
 
@@ -127,22 +133,22 @@
   oop arg = _args->obj_at(_index++);
   assert(arg->is_array(), "arg type mismatch");
   if (TraceGPUInteraction) {
-    tty->print_cr("[HSAIL] HSAILKernelArguments::do_array 0x%08x, is a %s", (address) arg, arg->klass()->external_name());
+    tty->print_cr("[HSAIL] HSAILKernelArguments::do_array, _index=%d, 0x%08x, is a %s", _index - 1, (address) arg, arg->klass()->external_name());
   }
     
-  bool pushed = gpu::Hsail::_okra_push_object(_kernel, arg);
+  bool pushed = Hsail::_okra_push_object(_kernel, arg);
   assert(pushed == true, "arg push failed");  
 }
 
 void HSAILKernelArguments::do_object() {
-  if (TraceGPUInteraction) {
-    tty->print_cr("[HSAIL] HSAILKernelArguments::do_object, _parameter_index=%d", _parameter_index);
-  }
+  
+  bool isLastParam = isLastParameter();  // determine this before incrementing _index
+
   oop arg = _args->obj_at(_index++);
 
   // check if this is last arg in signature
   // an object as last parameter requires an object stream source array to be passed
-  if (_parameter_index == _parameter_count - 1) {
+  if (isLastParam) {
     if (TraceGPUInteraction) {
       tty->print_cr("[HSAIL] HSAILKernelArguments::trailing object ref should be object source array ref");
     }
@@ -150,10 +156,10 @@
   }
 
   if (TraceGPUInteraction) {
-    tty->print_cr("[HSAIL] HSAILKernelArguments::do_object, 0x%08x is a %s", (address) arg, arg->klass()->external_name());
+    tty->print_cr("[HSAIL] HSAILKernelArguments::do_object, _index=%d, 0x%08x is a %s", _index - 1, (address) arg, arg->klass()->external_name());
   }
     
-  bool pushed = gpu::Hsail::_okra_push_object(_kernel, arg);
+  bool pushed = Hsail::_okra_push_object(_kernel, arg);
   assert(pushed == true, "arg push failed");  
 }
 
--- a/src/gpu/hsail/vm/hsailKernelArguments.hpp	Sun Feb 23 17:00:35 2014 -0800
+++ b/src/gpu/hsail/vm/hsailKernelArguments.hpp	Wed Mar 05 19:40:15 2014 -0800
@@ -26,10 +26,11 @@
 #define KERNEL_ARGUMENTS_HSAIL_HPP
 
 #include "runtime/gpu.hpp"
+#include "hsail/vm/gpu_hsail.hpp"
 #include "runtime/signature.hpp"
 
 class HSAILKernelArguments : public SignatureIterator {
-  friend class gpu::Hsail;
+  friend class Hsail;
 
 public:
 
@@ -62,7 +63,8 @@
     _parameter_count = ArgumentCount(signature).size();
 
     if (TraceGPUInteraction) {
-      tty->print_cr("[HSAIL] sig:%s  args length=%d", signature->as_C_string(), _length);
+      char buf[O_BUFLEN];
+      tty->print_cr("[HSAIL] sig:%s  args length=%d, _parameter_count=%d", signature->as_C_string(buf, O_BUFLEN), _length, _parameter_count);
     }    
     if (!_is_static) {      
       // First object in args should be 'this'
@@ -71,7 +73,7 @@
       if (TraceGPUInteraction) {
         tty->print_cr("[HSAIL] instance method, this 0x%08x, is a %s", (address) arg, arg->klass()->external_name());
       }
-      bool pushed = gpu::Hsail::_okra_push_object(kernel, arg);
+      bool pushed = Hsail::_okra_push_object(kernel, arg);
       assert(pushed == true, "'this' push failed");
     } else {
       if (TraceGPUInteraction) {
@@ -102,6 +104,11 @@
     /* TODO : To be implemented */
     guarantee(false, "do_short:NYI");
   }
+
+  bool isLastParameter() {
+      return  (_index == (_is_static ?  _parameter_count - 1 : _parameter_count));
+  }
+
 };
 
 #endif  // KERNEL_ARGUMENTS_HPP
--- a/src/gpu/ptx/vm/gpu_ptx.cpp	Sun Feb 23 17:00:35 2014 -0800
+++ b/src/gpu/ptx/vm/gpu_ptx.cpp	Wed Mar 05 19:40:15 2014 -0800
@@ -25,34 +25,77 @@
 #include "precompiled.hpp"
 #include "runtime/javaCalls.hpp"
 #include "runtime/gpu.hpp"
+#include "ptx/vm/gpu_ptx.hpp"
 #include "utilities/globalDefinitions.hpp"
 #include "utilities/ostream.hpp"
 #include "memory/allocation.hpp"
 #include "memory/allocation.inline.hpp"
+#include "memory/gcLocker.inline.hpp"
 #include "runtime/interfaceSupport.hpp"
-#include "ptxKernelArguments.hpp"
+#include "runtime/vframe.hpp"
+#include "graal/graalEnv.hpp"
+#include "graal/graalCompiler.hpp"
+
+#define T_BYTE_SIZE        1
+#define T_BOOLEAN_SIZE     4
+#define T_INT_BYTE_SIZE    4
+#define T_FLOAT_BYTE_SIZE  4
+#define T_DOUBLE_BYTE_SIZE 8
+#define T_LONG_BYTE_SIZE   8
+#define T_OBJECT_BYTE_SIZE sizeof(intptr_t)
+#define T_ARRAY_BYTE_SIZE  sizeof(intptr_t)
 
-void * gpu::Ptx::_device_context;
-int    gpu::Ptx::_cu_device = 0;
+// Entry to GPU native method implementation that transitions current thread to '_thread_in_vm'.
+#define GPU_VMENTRY(result_type, name, signature) \
+  JNIEXPORT result_type JNICALL name signature { \
+  if (TraceGPUInteraction) tty->print_cr("[CUDA] " #name); \
+  GRAAL_VM_ENTRY_MARK; \
+
+// Entry to GPU native method implementation that calls a JNI function
+// and hence cannot transition current thread to '_thread_in_vm'.
+#define GPU_ENTRY(result_type, name, signature) \
+  JNIEXPORT result_type JNICALL name signature { \
+  if (TraceGPUInteraction) tty->print_cr("[CUDA] Ptx::" #name); \
+
+#define GPU_END }
+
+#define CC (char*)  /*cast a literal from (const char*)*/
+#define FN_PTR(f) CAST_FROM_FN_PTR(void*, &(f))
 
-gpu::Ptx::cuda_cu_init_func_t gpu::Ptx::_cuda_cu_init;
-gpu::Ptx::cuda_cu_ctx_create_func_t gpu::Ptx::_cuda_cu_ctx_create;
-gpu::Ptx::cuda_cu_ctx_destroy_func_t gpu::Ptx::_cuda_cu_ctx_destroy;
-gpu::Ptx::cuda_cu_ctx_synchronize_func_t gpu::Ptx::_cuda_cu_ctx_synchronize;
-gpu::Ptx::cuda_cu_ctx_set_current_func_t gpu::Ptx::_cuda_cu_ctx_set_current;
-gpu::Ptx::cuda_cu_device_get_count_func_t gpu::Ptx::_cuda_cu_device_get_count;
-gpu::Ptx::cuda_cu_device_get_name_func_t gpu::Ptx::_cuda_cu_device_get_name;
-gpu::Ptx::cuda_cu_device_get_func_t gpu::Ptx::_cuda_cu_device_get;
-gpu::Ptx::cuda_cu_device_compute_capability_func_t gpu::Ptx::_cuda_cu_device_compute_capability;
-gpu::Ptx::cuda_cu_device_get_attribute_func_t gpu::Ptx::_cuda_cu_device_get_attribute;
-gpu::Ptx::cuda_cu_launch_kernel_func_t gpu::Ptx::_cuda_cu_launch_kernel;
-gpu::Ptx::cuda_cu_module_get_function_func_t gpu::Ptx::_cuda_cu_module_get_function;
-gpu::Ptx::cuda_cu_module_load_data_ex_func_t gpu::Ptx::_cuda_cu_module_load_data_ex;
-gpu::Ptx::cuda_cu_memcpy_dtoh_func_t gpu::Ptx::_cuda_cu_memcpy_dtoh;
-gpu::Ptx::cuda_cu_memfree_func_t gpu::Ptx::_cuda_cu_memfree;
-gpu::Ptx::cuda_cu_mem_host_register_func_t gpu::Ptx::_cuda_cu_mem_host_register;
-gpu::Ptx::cuda_cu_mem_host_get_device_pointer_func_t gpu::Ptx::_cuda_cu_mem_host_get_device_pointer;
-gpu::Ptx::cuda_cu_mem_host_unregister_func_t gpu::Ptx::_cuda_cu_mem_host_unregister;
+#define STRING                "Ljava/lang/String;"
+
+JNINativeMethod Ptx::PTX_methods[] = {
+  {CC"initialize",              CC"()Z",               FN_PTR(Ptx::initialize)},
+  {CC"generateKernel",          CC"([B" STRING ")J",   FN_PTR(Ptx::generate_kernel)},
+  {CC"getLaunchKernelAddress",  CC"()J",               FN_PTR(Ptx::get_execute_kernel_from_vm_address)},
+  {CC"getAvailableProcessors0", CC"()I",               FN_PTR(Ptx::get_total_cores)},
+  {CC"destroyContext",          CC"()V",               FN_PTR(Ptx::destroy_ptx_context)},
+};
+
+void * Ptx::_device_context = 0;
+int    Ptx::_cu_device = 0;
+
+Ptx::cuda_cu_init_func_t Ptx::_cuda_cu_init;
+Ptx::cuda_cu_ctx_create_func_t Ptx::_cuda_cu_ctx_create;
+Ptx::cuda_cu_ctx_destroy_func_t Ptx::_cuda_cu_ctx_destroy;
+Ptx::cuda_cu_ctx_synchronize_func_t Ptx::_cuda_cu_ctx_synchronize;
+Ptx::cuda_cu_ctx_get_current_func_t Ptx::_cuda_cu_ctx_get_current;
+Ptx::cuda_cu_ctx_set_current_func_t Ptx::_cuda_cu_ctx_set_current;
+Ptx::cuda_cu_device_get_count_func_t Ptx::_cuda_cu_device_get_count;
+Ptx::cuda_cu_device_get_name_func_t Ptx::_cuda_cu_device_get_name;
+Ptx::cuda_cu_device_get_func_t Ptx::_cuda_cu_device_get;
+Ptx::cuda_cu_device_compute_capability_func_t Ptx::_cuda_cu_device_compute_capability;
+Ptx::cuda_cu_device_get_attribute_func_t Ptx::_cuda_cu_device_get_attribute;
+Ptx::cuda_cu_launch_kernel_func_t Ptx::_cuda_cu_launch_kernel;
+Ptx::cuda_cu_module_get_function_func_t Ptx::_cuda_cu_module_get_function;
+Ptx::cuda_cu_module_load_data_ex_func_t Ptx::_cuda_cu_module_load_data_ex;
+Ptx::cuda_cu_memcpy_htod_func_t Ptx::_cuda_cu_memcpy_htod;
+Ptx::cuda_cu_memcpy_dtoh_func_t Ptx::_cuda_cu_memcpy_dtoh;
+Ptx::cuda_cu_memalloc_func_t Ptx::_cuda_cu_memalloc;
+Ptx::cuda_cu_memfree_func_t Ptx::_cuda_cu_memfree;
+Ptx::cuda_cu_mem_host_register_func_t Ptx::_cuda_cu_mem_host_register;
+Ptx::cuda_cu_mem_host_get_device_pointer_func_t Ptx::_cuda_cu_mem_host_get_device_pointer;
+Ptx::cuda_cu_mem_host_unregister_func_t Ptx::_cuda_cu_mem_host_unregister;
 
 #define STRINGIFY(x)     #x
 
@@ -61,7 +104,7 @@
     CAST_TO_FN_PTR(alias##_func_t, os::dll_lookup(handle, STRINGIFY(name))); \
   if (_##alias == NULL) {      \
   tty->print_cr("[CUDA] ***** Error: Failed to lookup %s", STRINGIFY(name)); \
-        return 0; \
+        return false; \
   } \
 
 #define LOOKUP_CUDA_V2_FUNCTION(name, alias)  LOOKUP_CUDA_FUNCTION(name##_v2, alias)
@@ -69,7 +112,7 @@
 /*
  * see http://en.wikipedia.org/wiki/CUDA#Supported_GPUs
  */
-int ncores(int major, int minor) {
+int Ptx::ncores(int major, int minor) {
     int device_type = (major << 4) + minor;
 
     switch (device_type) {
@@ -87,12 +130,36 @@
     }
 }
 
-bool gpu::Ptx::initialize_gpu() {
+bool Ptx::register_natives(JNIEnv* env) {
+  jclass klass = env->FindClass("com/oracle/graal/hotspot/ptx/PTXHotSpotBackend");
+  if (klass == NULL) {
+    if (TraceGPUInteraction) {
+      tty->print_cr("PTXHotSpotBackend class not found");
+    }
+    return false;
+  }
+  jint status = env->RegisterNatives(klass, PTX_methods, sizeof(PTX_methods) / sizeof(JNINativeMethod));
+  if (status != JNI_OK) {
+    if (true || TraceGPUInteraction) {
+      tty->print_cr("Error registering natives for PTXHotSpotBackend: %d", status);
+    }
+    return false;
+  }
+  return true;
+}
+
+GPU_ENTRY(jboolean, Ptx::initialize, (JNIEnv *env, jclass))
+
+  if (!link()) {
+    return false;
+  }
 
   /* Initialize CUDA driver API */
   int status = _cuda_cu_init(0);
   if (status != GRAAL_CUDA_SUCCESS) {
-    tty->print_cr("Failed to initialize CUDA device");
+    if (TraceGPUInteraction) {
+      tty->print_cr("Failed to initialize CUDA device: %d", status);
+    }
     return false;
   }
 
@@ -132,7 +199,34 @@
   }
 
   /* Get device attributes */
+  int minor, major;
   int unified_addressing;
+  float version = 0.0;
+
+  /* Get the compute capability of the device found */
+  status = _cuda_cu_device_get_attribute(&minor, GRAAL_CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MINOR, _cu_device);
+  if (status != GRAAL_CUDA_SUCCESS) {
+    tty->print_cr("[CUDA] Failed to get minor attribute of device: %d", _cu_device);
+    return false;
+  }
+  status = _cuda_cu_device_get_attribute(&major, GRAAL_CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MAJOR, _cu_device);
+  if (status != GRAAL_CUDA_SUCCESS) {
+    tty->print_cr("[CUDA] Failed to get major attribute of device: %d", _cu_device);
+    return false;
+  }
+
+  /* Check if the device supports atleast GRAAL_SUPPORTED_COMPUTE_CAPABILITY_VERSION */
+  version = (float) major + ((float) minor)/10;
+
+  if (version < GRAAL_SUPPORTED_COMPUTE_CAPABILITY_VERSION) {
+    tty->print_cr("[CUDA] Only cuda compute capability %.1f and later supported. Device %d supports %.1f",
+                  (float) GRAAL_SUPPORTED_COMPUTE_CAPABILITY_VERSION, _cu_device, version);
+    return false;
+  }
+
+  if (TraceGPUInteraction) {
+    tty->print_cr("[CUDA] Device %d supports cuda compute capability %.1f", _cu_device, version);
+  }
 
   status = _cuda_cu_device_get_attribute(&unified_addressing, GRAAL_CU_DEVICE_ATTRIBUTE_UNIFIED_ADDRESSING, _cu_device);
 
@@ -140,12 +234,18 @@
     tty->print_cr("[CUDA] Failed to query unified addressing mode of device: %d", _cu_device);
     return false;
   }
+  /* The CUDA driver runtime interaction and generated code as implemented requires
+     that the device supports Unified Addressing.
+  */
+  if (unified_addressing == 0) {
+    tty->print_cr("[CUDA] CUDA device %d does NOT have required Unified Addressing support.", _cu_device);
+    return false;
+  }
 
   if (TraceGPUInteraction) {
-    tty->print_cr("[CUDA] Unified addressing support on device %d: %d", _cu_device, unified_addressing);
+    tty->print_cr("[CUDA] Device %d has Unified Addressing support", _cu_device);
   }
 
-
   /* Get device name */
   char device_name[256];
   status = _cuda_cu_device_get_name(device_name, 256, _cu_device);
@@ -159,11 +259,24 @@
     tty->print_cr("[CUDA] Using %s", device_name);
   }
 
+  // Create CUDA context to compile and execute the kernel
+
+  status = _cuda_cu_ctx_create(&_device_context, GRAAL_CU_CTX_MAP_HOST, _cu_device);
+
+  if (status != GRAAL_CUDA_SUCCESS) {
+    tty->print_cr("[CUDA] Failed to create CUDA context for device(%d): %d", _cu_device, status);
+    return false;
+  }
+  if (TraceGPUInteraction) {
+    tty->print_cr("[CUDA] Success: Created context for device: %d", _cu_device);
+  }
+
+  gpu::initialized_gpu(device_name);
 
   return true;
-}
+GPU_END
 
-unsigned int gpu::Ptx::total_cores() {
+GPU_ENTRY(jint, Ptx::get_total_cores, (JNIEnv *env, jobject))
 
     int minor, major, nmp;
     int status = _cuda_cu_device_get_attribute(&minor,
@@ -189,7 +302,7 @@
                                            _cu_device);
 
     if (status != GRAAL_CUDA_SUCCESS) {
-        tty->print_cr("[CUDA] Failed to get numberof MPs on device: %d", _cu_device);
+        tty->print_cr("[CUDA] Failed to get number of MPs on device: %d", _cu_device);
         return 0;
     }
 
@@ -243,22 +356,32 @@
     }
 
     if (TraceGPUInteraction) {
-        tty->print_cr("[CUDA] Compatibility version of device %d: %d.%d", _cu_device, major, minor);
         tty->print_cr("[CUDA] Number of cores: %d async engines: %d can map host mem: %d concurrent kernels: %d",
                       total, async_engines, can_map_host_memory, concurrent_kernels);
         tty->print_cr("[CUDA] Max threads per block: %d warp size: %d", max_threads_per_block, warp_size);
     }
-    return (total);
+    return total;
+GPU_END
+
+GPU_ENTRY(jlong, Ptx::generate_kernel, (JNIEnv *env, jclass, jbyteArray code_handle, jstring name_handle))
+  ResourceMark rm;
+  jsize name_len = env->GetStringLength(name_handle);
+  jsize code_len = env->GetArrayLength(code_handle);
 
-}
+  char* name = NEW_RESOURCE_ARRAY(char, name_len + 1);
+  unsigned char *code = NEW_RESOURCE_ARRAY(unsigned char, code_len + 1);
 
-void *gpu::Ptx::generate_kernel(unsigned char *code, int code_len, const char *name) {
+  code[code_len] = 0;
+  name[name_len] = 0;
+
+  env->GetByteArrayRegion(code_handle, 0, code_len, (jbyte*) code);
+  env->GetStringUTFRegion(name_handle, 0, name_len, name);
 
   struct CUmod_st * cu_module;
   // Use three JIT compiler options
   const unsigned int jit_num_options = 3;
-  int *jit_options = NEW_C_HEAP_ARRAY(int, jit_num_options, mtCompiler);
-  void **jit_option_values = NEW_C_HEAP_ARRAY(void *, jit_num_options, mtCompiler);
+  int *jit_options = NEW_RESOURCE_ARRAY(int, jit_num_options);
+  void **jit_option_values = NEW_RESOURCE_ARRAY(void *, jit_num_options);
 
   // Set up PTX JIT compiler options
   // 1. set size of compilation log buffer
@@ -267,400 +390,419 @@
   jit_option_values[0] = (void *)(size_t)jit_log_buffer_size;
 
   // 2. set pointer to compilation log buffer
-  char *jit_log_buffer = NEW_C_HEAP_ARRAY(char, jit_log_buffer_size, mtCompiler);
+  char *jit_log_buffer = NEW_RESOURCE_ARRAY(char, jit_log_buffer_size);
   jit_options[1] = GRAAL_CU_JIT_INFO_LOG_BUFFER;
   jit_option_values[1] = jit_log_buffer;
 
-  // 3. set pointer to set the Maximum # of registers (32) for the kernel
+  // 3. set pointer to set the maximum number of registers (32) for the kernel
   int jit_register_count = 32;
   jit_options[2] = GRAAL_CU_JIT_MAX_REGISTERS;
   jit_option_values[2] = (void *)(size_t)jit_register_count;
 
-  /* Create CUDA context to compile and execute the kernel */
-  int status = _cuda_cu_ctx_create(&_device_context, GRAAL_CU_CTX_MAP_HOST, _cu_device);
+  // Set CUDA context to compile and execute the kernel
 
-  if (status != GRAAL_CUDA_SUCCESS) {
-    tty->print_cr("[CUDA] Failed to create CUDA context for device(%d): %d", _cu_device, status);
-    return NULL;
+  if (_device_context == NULL) {
+    tty->print_cr("[CUDA] Encountered uninitialized CUDA context for device(%d)", _cu_device);
+      return 0L;
   }
 
-  if (TraceGPUInteraction) {
-    tty->print_cr("[CUDA] Success: Created context for device: %d", _cu_device);
-  }
-
-  status = _cuda_cu_ctx_set_current(_device_context);
+  int status = _cuda_cu_ctx_set_current(_device_context);
 
   if (status != GRAAL_CUDA_SUCCESS) {
     tty->print_cr("[CUDA] Failed to set current context for device: %d", _cu_device);
-    return NULL;
+    return 0L;
   }
 
   if (TraceGPUInteraction) {
     tty->print_cr("[CUDA] Success: Set current context for device: %d", _cu_device);
-  }
-
-  if (TraceGPUInteraction) {
     tty->print_cr("[CUDA] PTX Kernel\n%s", code);
     tty->print_cr("[CUDA] Function name : %s", name);
-
   }
 
   /* Load module's data with compiler options */
   status = _cuda_cu_module_load_data_ex(&cu_module, (void*) code, jit_num_options,
-                                            jit_options, (void **)jit_option_values);
+                                        jit_options, (void **)jit_option_values);
   if (status != GRAAL_CUDA_SUCCESS) {
     if (status == GRAAL_CUDA_ERROR_NO_BINARY_FOR_GPU) {
       tty->print_cr("[CUDA] Check for malformed PTX kernel or incorrect PTX compilation options");
     }
     tty->print_cr("[CUDA] *** Error (%d) Failed to load module data with online compiler options for method %s",
                   status, name);
-    return NULL;
+    return 0L;
   }
 
   if (TraceGPUInteraction) {
     tty->print_cr("[CUDA] Loaded data for PTX Kernel");
   }
 
-  struct CUfunc_st * cu_function;
-
+  struct CUfunc_st* cu_function;
   status = _cuda_cu_module_get_function(&cu_function, cu_module, name);
 
   if (status != GRAAL_CUDA_SUCCESS) {
     tty->print_cr("[CUDA] *** Error: Failed to get function %s", name);
-    return NULL;
+    return 0L;
   }
 
   if (TraceGPUInteraction) {
     tty->print_cr("[CUDA] Got function handle for %s kernel address %p", name, cu_function);
   }
+  return (jlong) cu_function;
+GPU_END
 
-  return cu_function;
+// A PtxCall is used to manage executing a GPU kernel. In addition to launching
+// the kernel, this class releases resources allocated for the execution.
+class PtxCall: StackObj {
+ private:
+  JavaThread*  _thread;        // the thread on which this call is made
+  address      _buffer;        // buffer containing parameters and _return_value
+  int          _buffer_size;   // size (in bytes) of _buffer
+  oop*         _pinned;        // objects that have been pinned with cuMemHostRegister
+  int          _pinned_length; // length of _pinned
+  Ptx::CUdeviceptr  _ret_value;     // pointer to slot in GPU memory holding the return value
+  int          _ret_type_size; // size of the return type value
+  bool         _ret_is_object; // specifies if the return type is Object
+  bool         _gc_locked;     // denotes when execution has locked GC
+
+  bool check(int status, const char *action) {
+    if (status != GRAAL_CUDA_SUCCESS) {
+      Thread* THREAD = _thread;
+      ResourceMark rm(THREAD);
+      char* message = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, O_BUFLEN + 1);
+      jio_snprintf(message, O_BUFLEN, "[CUDA] *** Error (status=%d): %s", status, action);
+      if (TraceGPUInteraction) {
+        tty->print_cr(message);
+      }
+      if (!HAS_PENDING_EXCEPTION) {
+        SharedRuntime::throw_and_post_jvmti_exception(_thread, vmSymbols::java_lang_RuntimeException(), message);
+      }
+      return false;
+    }
+    if (TraceGPUInteraction) {
+      tty->print_cr("[CUDA] Success: %s", action);
+    }
+    return true;
+  }
+
+ public:
+  PtxCall(JavaThread* thread, address buffer, int buffer_size, oop* pinned, int encodedReturnTypeSize) : _thread(thread), _gc_locked(false),
+      _buffer(buffer), _buffer_size(buffer_size), _pinned(pinned), _pinned_length(0), _ret_value(0), _ret_is_object(encodedReturnTypeSize < 0) {
+    _ret_type_size = _ret_is_object ? -encodedReturnTypeSize : encodedReturnTypeSize;
+  }
+
+  bool is_object_return() { return _ret_is_object; }
+
+  void alloc_return_value() {
+    if (_ret_type_size != 0) {
+      if (check(Ptx::_cuda_cu_memalloc(&_ret_value, _ret_type_size), "Allocate device memory for return value")) {
+        Ptx::CUdeviceptr* retValuePtr = (Ptx::CUdeviceptr*) ((_buffer + _buffer_size) - sizeof(_ret_value));
+        *retValuePtr = _ret_value;
+      }
+    }
+  }
+
+  void pin_objects(int count, int* objectOffsets) {
+    if (count == 0) {
+      return;
+    }
+    // Once we start pinning objects, no GC must occur
+    // until the kernel has completed. This is a big
+    // hammer for ensuring we can safely pass objects
+    // to the GPU.
+    GC_locker::lock_critical(_thread);
+    _gc_locked = true;
+    if (TraceGPUInteraction) {
+      tty->print_cr("[CUDA] Locked GC");
+    }
+
+    for (int i = 0; i < count; i++) {
+      int offset = objectOffsets[i];
+      oop* argPtr = (oop*) (_buffer + offset);
+      oop obj = *argPtr;
+      if (obj != NULL) {
+        // Size (in bytes) of object
+        int objSize = obj->size() * HeapWordSize;
+        //tty->print_cr("Pinning object %d at offset %d: %p", i, offset, obj);
+        if (!check(Ptx::_cuda_cu_mem_host_register(obj, objSize, GRAAL_CU_MEMHOSTREGISTER_DEVICEMAP), "Pin object")) {
+          return;
+        }
+
+        // Record original oop so that its memory can be unpinned
+        _pinned[_pinned_length++] = obj;
+
+        // Replace host pointer to object with device pointer
+        // to object in kernel parameters buffer
+        if (!check(Ptx::_cuda_cu_mem_host_get_device_pointer((Ptx::CUdeviceptr*) argPtr, obj, 0), "Get device pointer for pinned object")) {
+          return;
+        }
+      }
+    }
+  }
+
+  void launch(address kernel, jint dimX, jint dimY, jint dimZ) {
+    // grid dimensionality
+    unsigned int gridX = 1;
+    unsigned int gridY = 1;
+    unsigned int gridZ = 1;
+    void * config[] = {
+      GRAAL_CU_LAUNCH_PARAM_BUFFER_POINTER, (char*) (address) _buffer,
+      GRAAL_CU_LAUNCH_PARAM_BUFFER_SIZE, &_buffer_size,
+      GRAAL_CU_LAUNCH_PARAM_END
+    };
+    if (check(Ptx::_cuda_cu_launch_kernel((struct CUfunc_st*) (address) kernel,
+                                      gridX, gridY, gridZ,
+                                      dimX, dimY, dimZ,
+                                      0, NULL, NULL, (void**) &config), "Launch kernel")) {
+    }
+  }
+
+  void synchronize() {
+    check(Ptx::_cuda_cu_ctx_synchronize(), "Synchronize kernel");
+  }
+
+  void unpin_objects() {
+    while (_pinned_length > 0) {
+      oop obj = _pinned[--_pinned_length];
+      assert(obj != NULL, "npe");
+      //tty->print_cr("Unpinning object %d: %p", _pinned_length, obj);
+      if (!check(Ptx::_cuda_cu_mem_host_unregister(obj), "Unpin object")) {
+        return;
+      }
+    }
+  }
+
+  oop get_object_return_value() {
+    oop return_val;
+    check(Ptx::_cuda_cu_memcpy_dtoh(&return_val, _ret_value, T_OBJECT_BYTE_SIZE), "Copy return value from device");
+    return return_val;
+  }
+
+  jlong get_primitive_return_value() {
+    jlong return_val;
+    check(Ptx::_cuda_cu_memcpy_dtoh(&return_val, _ret_value, _ret_type_size), "Copy return value from device");
+    return return_val;
+  }
+
+  void free_return_value() {
+    if (_ret_value != 0) {
+      check(Ptx::_cuda_cu_memfree(_ret_value), "Free device memory");
+      _ret_value = 0;
+    }
+  }
+
+  ~PtxCall() {
+    unpin_objects();
+    free_return_value();
+    if (_gc_locked) {
+      GC_locker::unlock_critical(_thread);
+      if (TraceGPUInteraction) {
+        tty->print_cr("[CUDA] Unlocked GC");
+      }
+      _gc_locked = false;
+    }
+  }
+};
+
+// Prints values in the kernel arguments buffer
+class KernelArgumentsPrinter: public SignatureIterator {
+  Method*       _method;
+  address       _buffer;
+  size_t        _bufferOffset;
+  outputStream* _st;
+
+private:
+
+  // Get next java argument
+  oop next_arg(BasicType expectedType);
+
+ public:
+  KernelArgumentsPrinter(Method* method, address buffer, outputStream* st) : SignatureIterator(method->signature()),
+    _method(method), _buffer(buffer), _bufferOffset(0), _st(st) {
+    if (!method->is_static()) {
+      print_oop();
+    }
+    iterate();
+  }
+
+  address next(size_t dataSz) {
+    if (is_return_type()) {
+      return _buffer;
+    }
+    if (_bufferOffset != 0) {
+      _st->print(", ");
+    }
+    _bufferOffset = align_size_up_(_bufferOffset, dataSz);
+    address result = _buffer + _bufferOffset;
+    _bufferOffset += dataSz;
+    return result;
+  }
+
+  void print_oop() {
+    oop obj = *((oop*) next(sizeof(oop)));
+    if (obj != NULL) {
+      char type[256];
+      obj->klass()->name()->as_C_string(type, 256);
+      _st->print("oop "PTR_FORMAT" (%s)", (address) obj, type);
+    } else {
+      _st->print("oop null");
+    }
+  }
+
+  bool skip() {
+    return is_return_type();
+  }
+
+  void do_bool  ()                     { if (!skip()) _st->print("bool %d",    *((jboolean*) next(sizeof(jboolean)))); }
+  void do_char  ()                     { if (!skip()) _st->print("char %c",    *((jchar*)    next(sizeof(jchar))));    }
+  void do_float ()                     { if (!skip()) _st->print("float %g",   *((jfloat*)   next(sizeof(jfloat))));   }
+  void do_double()                     { if (!skip()) _st->print("double %g",  *((jdouble*)  next(sizeof(jdouble))));  }
+  void do_byte  ()                     { if (!skip()) _st->print("byte %d",    *((jbyte*)    next(sizeof(jbyte))));    }
+  void do_short ()                     { if (!skip()) _st->print("short %d",   *((jshort*)   next(sizeof(jshort))));   }
+  void do_int   ()                     { if (!skip()) _st->print("int %d",     *((jint*)     next(sizeof(jint))));     }
+  void do_long  ()                     { if (!skip()) _st->print("long "JLONG_FORMAT,  *((jlong*)    next(sizeof(jlong))));    }
+  void do_void  ()                     { }
+  void do_object(int begin, int end)   { if (!skip()) print_oop();      }
+  void do_array (int begin, int end)   { if (!skip()) print_oop();      }
+};
+
+static void printKernelArguments(JavaThread* thread, address buffer) {
+  for (vframeStream vfst(thread); !vfst.at_end(); vfst.next()) {
+    Method* m = vfst.method();
+    if (m != NULL) {
+      ResourceMark rm;
+      stringStream st(O_BUFLEN);
+      st.print("[CUDA] Call: %s.%s(", m->method_holder()->name()->as_C_string(), m->name()->as_C_string());
+      KernelArgumentsPrinter kap(m, buffer, &st);
+      tty->print_cr("%s)", st.as_string());
+      return;
+    }
+  }
 }
 
-JRT_ENTRY(jlong, gpu::Ptx::execute_kernel_from_vm(JavaThread* thread, jlong kernel, jint dimX, jint dimY, jint dimZ,
-                                                  jlong parametersAndReturnValueBuffer,
-                                                  jint parametersAndReturnValueBufferSize,
+GPU_VMENTRY(void, Ptx::destroy_ptx_context, (void))
+    if (_device_context != NULL) {
+      int status = _cuda_cu_ctx_destroy(_device_context);
+      if (status != GRAAL_CUDA_SUCCESS) {
+        if (TraceGPUInteraction) {
+          tty->print_cr("[CUDA] Error(%d) : Failed to destroy context", status);
+        }
+      _device_context = NULL;
+      } else {
+        if (TraceGPUInteraction) {
+          tty->print_cr("[CUDA] Destroyed context", status);
+        }
+      }
+    }
+
+GPU_END
+
+GPU_VMENTRY(jlong, Ptx::get_execute_kernel_from_vm_address, (JNIEnv *env, jclass))
+  return (jlong) Ptx::execute_kernel_from_vm;
+GPU_END
+
+JRT_ENTRY(jlong, Ptx::execute_kernel_from_vm(JavaThread* thread, jlong kernel, jint dimX, jint dimY, jint dimZ,
+                                                  jlong buffer,
+                                                  jint bufferSize,
+                                                  jint objectParametersCount,
+                                                  jlong objectParametersOffsets,
+                                                  jlong pinnedObjects,
                                                   int encodedReturnTypeSize))
   if (kernel == 0L) {
     SharedRuntime::throw_and_post_jvmti_exception(thread, vmSymbols::java_lang_NullPointerException(), NULL);
     return 0L;
   }
 
-  // grid dimensionality
-  unsigned int gridX = 1;
-  unsigned int gridY = 1;
-  unsigned int gridZ = 1;
-
-  struct CUfunc_st* cu_function = (struct CUfunc_st*) (address) kernel;
-
-  void * config[5] = {
-    GRAAL_CU_LAUNCH_PARAM_BUFFER_POINTER, (char*) (address) parametersAndReturnValueBuffer,
-    GRAAL_CU_LAUNCH_PARAM_BUFFER_SIZE, &parametersAndReturnValueBufferSize,
-    GRAAL_CU_LAUNCH_PARAM_END
-  };
-
   if (TraceGPUInteraction) {
-    tty->print_cr("[CUDA] launching kernel");
-  }
-
-  bool isObjectReturn = encodedReturnTypeSize < 0;
-  int returnTypeSize = encodedReturnTypeSize < 0 ? -encodedReturnTypeSize : encodedReturnTypeSize;
-  gpu::Ptx::CUdeviceptr device_return_value;
-  int status;
-  if (returnTypeSize != 0) {
-    status = _cuda_cu_memalloc(&device_return_value, returnTypeSize);
-    if (status != GRAAL_CUDA_SUCCESS) {
-      tty->print_cr("[CUDA] *** Error (%d) Failed to allocate memory for return value pointer on device", status);
-      SharedRuntime::throw_and_post_jvmti_exception(thread, vmSymbols::java_lang_RuntimeException(), "[CUDA] Failed to allocate memory for return value pointer on device");
-      return 0L;
-    }
-    // Push device_return_value to kernelParams
-    gpu::Ptx::CUdeviceptr* returnValuePtr = (gpu::Ptx::CUdeviceptr*)
-                                               ((address) parametersAndReturnValueBuffer +
-                                                parametersAndReturnValueBufferSize - sizeof(device_return_value));
-    *returnValuePtr = device_return_value;
-  }
-
-  status = _cuda_cu_launch_kernel(cu_function,
-                                      gridX, gridY, gridZ,
-                                      dimX, dimY, dimZ,
-                                      0, NULL, NULL, (void **) &config);
-
-  if (status != GRAAL_CUDA_SUCCESS) {
-    tty->print_cr("[CUDA] Failed to launch kernel");
-    SharedRuntime::throw_and_post_jvmti_exception(thread, vmSymbols::java_lang_RuntimeException(), "[CUDA] Failed to launch kernel");
-    return 0L;
-  }
-
-  if (TraceGPUInteraction) {
-    tty->print_cr("[CUDA] Success: Kernel Launch: X: %d Y: %d Z: %d", dimX, dimY, dimZ);
+    printKernelArguments(thread, (address) buffer);
   }
 
-  status = _cuda_cu_ctx_synchronize();
+  PtxCall call(thread, (address) buffer, bufferSize, (oop*) (address) pinnedObjects, encodedReturnTypeSize);
 
-  if (status != GRAAL_CUDA_SUCCESS) {
-    tty->print_cr("[CUDA] Failed to synchronize launched kernel (%d)", status);
-    SharedRuntime::throw_and_post_jvmti_exception(thread, vmSymbols::java_lang_RuntimeException(), "[CUDA] Failed to synchronize launched kernel");
-    return 0L;
-  }
+#define TRY(action) do { \
+  action; \
+  if (HAS_PENDING_EXCEPTION) return 0L; \
+} while (0)
+
+  TRY(call.alloc_return_value());
 
-  if (TraceGPUInteraction) {
-    tty->print_cr("[CUDA] Success: Synchronized launch kernel");
-  }
+  TRY(call.pin_objects(objectParametersCount, (int*) (address) objectParametersOffsets));
+
+  TRY(call.launch((address) kernel, dimX, dimY, dimZ));
 
-  jlong primitiveReturnValue = 0L;
-  if (isObjectReturn) {
+  TRY(call.synchronize());
+
+  if (call.is_object_return()) {
     oop return_val;
-    status = gpu::Ptx::_cuda_cu_memcpy_dtoh(&return_val, device_return_value, T_OBJECT_BYTE_SIZE);
-    if (status != GRAAL_CUDA_SUCCESS) {
-      tty->print_cr("[CUDA] *** Error (%d) Failed to copy value from device argument", status);
-      SharedRuntime::throw_and_post_jvmti_exception(thread, vmSymbols::java_lang_Exception(), "[CUDA] Failed to copy value from device argument");
-      return 0L;
-    }
+    TRY(return_val = call.get_object_return_value());
     thread->set_vm_result(return_val);
-  } else if (returnTypeSize > 0) {
-    status = gpu::Ptx::_cuda_cu_memcpy_dtoh(&primitiveReturnValue, device_return_value, returnTypeSize);
-    if (status != GRAAL_CUDA_SUCCESS) {
-      tty->print_cr("[CUDA] *** Error (%d) Failed to copy value from device argument", status);
-      SharedRuntime::throw_and_post_jvmti_exception(thread, vmSymbols::java_lang_Exception(), "[CUDA] Failed to copy value from device argument");
-      return 0L;
-    }
-  }
-
-  // Free device memory allocated for result
-  if (returnTypeSize != 0) {
-    status = gpu::Ptx::_cuda_cu_memfree(device_return_value);
-    if (status != GRAAL_CUDA_SUCCESS) {
-      tty->print_cr("[CUDA] *** Error (%d) Failed to free device memory of return value", status);
-      SharedRuntime::throw_and_post_jvmti_exception(thread, vmSymbols::java_lang_Exception(), "[CUDA] Failed to free device memory of return value");
-      return 0L;
-    }
-  }
-
-  if (TraceGPUInteraction) {
-    tty->print_cr("[CUDA] Success: Freed device memory of return value");
-  }
-
-  // Destroy context
-  status = gpu::Ptx::_cuda_cu_ctx_destroy(_device_context);
-  if (status != GRAAL_CUDA_SUCCESS) {
-    tty->print_cr("[CUDA] *** Error (%d) Failed to destroy context", status);
-    SharedRuntime::throw_and_post_jvmti_exception(thread, vmSymbols::java_lang_Exception(), "[CUDA] Failed to destroy context");
     return 0L;
   }
 
-  if (TraceGPUInteraction) {
-    tty->print_cr("[CUDA] Success: Destroy context");
-  }
+  jlong return_val;
+  TRY(return_val = call.get_primitive_return_value());
+  return return_val;
 
-  return primitiveReturnValue;
+#undef TRY
+
 JRT_END
 
-bool gpu::Ptx::execute_kernel(address kernel, PTXKernelArguments &ptxka, JavaValue &ret) {
-    return gpu::Ptx::execute_warp(1, 1, 1, kernel, ptxka, ret);
-}
-
-bool gpu::Ptx::execute_warp(int dimX, int dimY, int dimZ,
-                            address kernel, PTXKernelArguments &ptxka, JavaValue &ret) {
-  // grid dimensionality
-  unsigned int gridX = 1;
-  unsigned int gridY = 1;
-  unsigned int gridZ = 1;
-
-  // thread dimensionality
-  unsigned int blockX = dimX;
-  unsigned int blockY = dimY;
-  unsigned int blockZ = dimZ;
-
-  struct CUfunc_st* cu_function = (struct CUfunc_st*) kernel;
-
-  void * config[5] = {
-    GRAAL_CU_LAUNCH_PARAM_BUFFER_POINTER, ptxka._kernelArgBuffer,
-    GRAAL_CU_LAUNCH_PARAM_BUFFER_SIZE, &(ptxka._bufferOffset),
-    GRAAL_CU_LAUNCH_PARAM_END
-  };
-
-  if (kernel == NULL) {
-    return false;
-  }
-
-  if (TraceGPUInteraction) {
-    tty->print_cr("[CUDA] launching kernel");
-  }
-
-  int status = _cuda_cu_launch_kernel(cu_function,
-                                      gridX, gridY, gridZ,
-                                      blockX, blockY, blockZ,
-                                      0, NULL, NULL, (void **) &config);
-  if (status != GRAAL_CUDA_SUCCESS) {
-    tty->print_cr("[CUDA] Failed to launch kernel");
-    return false;
-  }
-
-  if (TraceGPUInteraction) {
-    tty->print_cr("[CUDA] Success: Kernel Launch: X: %d Y: %d Z: %d", blockX, blockY, blockZ);
-  }
-
-  status = _cuda_cu_ctx_synchronize();
-
-  if (status != GRAAL_CUDA_SUCCESS) {
-    tty->print_cr("[CUDA] Failed to synchronize launched kernel (%d)", status);
-    return false;
-  }
-
-  if (TraceGPUInteraction) {
-    tty->print_cr("[CUDA] Success: Synchronized launch kernel");
-  }
-
-
-  // Get the result. TODO: Move this code to get_return_oop()
-  BasicType return_type = ptxka.get_ret_type();
-  switch (return_type) {
-     case T_INT:
-       {
-         int return_val;
-         status = gpu::Ptx::_cuda_cu_memcpy_dtoh(&return_val, ptxka._dev_return_value, T_INT_BYTE_SIZE);
-         if (status != GRAAL_CUDA_SUCCESS) {
-           tty->print_cr("[CUDA] *** Error (%d) Failed to copy value to device argument", status);
-           return false;
-         }
-         ret.set_jint(return_val);
-       }
-       break;
-     case T_BOOLEAN:
-       {
-         int return_val;
-         status = gpu::Ptx::_cuda_cu_memcpy_dtoh(&return_val, ptxka._dev_return_value, T_INT_BYTE_SIZE);
-         if (status != GRAAL_CUDA_SUCCESS) {
-           tty->print_cr("[CUDA] *** Error (%d) Failed to copy value to device argument", status);
-           return false;
-         }
-         ret.set_jint(return_val);
-       }
-       break;
-     case T_FLOAT:
-       {
-         float return_val;
-         status = gpu::Ptx::_cuda_cu_memcpy_dtoh(&return_val, ptxka._dev_return_value, T_FLOAT_BYTE_SIZE);
-         if (status != GRAAL_CUDA_SUCCESS) {
-           tty->print_cr("[CUDA] *** Error (%d) Failed to copy value to device argument", status);
-           return false;
-         }
-         ret.set_jfloat(return_val);
-       }
-       break;
-     case T_DOUBLE:
-       {
-         double return_val;
-         status = gpu::Ptx::_cuda_cu_memcpy_dtoh(&return_val, ptxka._dev_return_value, T_DOUBLE_BYTE_SIZE);
-         if (status != GRAAL_CUDA_SUCCESS) {
-           tty->print_cr("[CUDA] *** Error (%d) Failed to copy value to device argument", status);
-           return false;
-         }
-         ret.set_jdouble(return_val);
-       }
-       break;
-     case T_LONG:
-       {
-         long return_val;
-         status = gpu::Ptx::_cuda_cu_memcpy_dtoh(&return_val, ptxka._dev_return_value, T_LONG_BYTE_SIZE);
-         if (status != GRAAL_CUDA_SUCCESS) {
-           tty->print_cr("[CUDA] *** Error (%d) Failed to copy value to device argument", status);
-           return false;
-         }
-         ret.set_jlong(return_val);
-       }
-       break;
-     case T_VOID:
-       break;
-     default:
-       tty->print_cr("[CUDA] TODO *** Unhandled return type: %d", return_type);
-  }
-
-  // Free device memory allocated for result
-  status = gpu::Ptx::_cuda_cu_memfree(ptxka._dev_return_value);
-  if (status != GRAAL_CUDA_SUCCESS) {
-    tty->print_cr("[CUDA] *** Error (%d) Failed to free device memory of return value", status);
-    return false;
-  }
-
-  if (TraceGPUInteraction) {
-    tty->print_cr("[CUDA] Success: Freed device memory of return value");
-  }
-
-  // Destroy context
-  status = gpu::Ptx::_cuda_cu_ctx_destroy(_device_context);
-  if (status != GRAAL_CUDA_SUCCESS) {
-    tty->print_cr("[CUDA] *** Error (%d) Failed to destroy context", status);
-    return false;
-  }
-
-  if (TraceGPUInteraction) {
-    tty->print_cr("[CUDA] Success: Destroy context");
-  }
-
-  return (status == GRAAL_CUDA_SUCCESS);
-}
-
 #if defined(LINUX)
-static const char cuda_library_name[] = "libcuda.so";
+static const char cuda_library_name[] = "/usr/lib/libcuda.so";
 #elif defined(__APPLE__)
 static char const cuda_library_name[] = "/usr/local/cuda/lib/libcuda.dylib";
 #else
 static char const cuda_library_name[] = "";
 #endif
 
-#define STD_BUFFER_SIZE 1024
+bool Ptx::link() {
+  if (cuda_library_name == NULL) {
+    if (TraceGPUInteraction) {
+      tty->print_cr("Failed to find CUDA linkage");
+    }
+    return false;
+  }
+  char ebuf[O_BUFLEN];
+  void *handle = os::dll_load(cuda_library_name, ebuf, O_BUFLEN);
+  if (handle == NULL) {
+    if (TraceGPUInteraction) {
+      tty->print_cr("Unsupported CUDA platform: %s", ebuf);
+    }
+    return false;
+  }
 
-bool gpu::Ptx::probe_linkage() {
-  if (cuda_library_name != NULL) {
-    char *buffer = (char*)malloc(STD_BUFFER_SIZE);
-    void *handle = os::dll_load(cuda_library_name, buffer, STD_BUFFER_SIZE);
-        free(buffer);
-    if (handle != NULL) {
-      LOOKUP_CUDA_FUNCTION(cuInit, cuda_cu_init);
-      LOOKUP_CUDA_FUNCTION(cuCtxSynchronize, cuda_cu_ctx_synchronize);
-      LOOKUP_CUDA_FUNCTION(cuCtxSetCurrent, cuda_cu_ctx_set_current);
-      LOOKUP_CUDA_FUNCTION(cuDeviceGetCount, cuda_cu_device_get_count);
-      LOOKUP_CUDA_FUNCTION(cuDeviceGetName, cuda_cu_device_get_name);
-      LOOKUP_CUDA_FUNCTION(cuDeviceGet, cuda_cu_device_get);
-      LOOKUP_CUDA_FUNCTION(cuDeviceComputeCapability, cuda_cu_device_compute_capability);
-      LOOKUP_CUDA_FUNCTION(cuDeviceGetAttribute, cuda_cu_device_get_attribute);
-      LOOKUP_CUDA_FUNCTION(cuModuleGetFunction, cuda_cu_module_get_function);
-      LOOKUP_CUDA_FUNCTION(cuModuleLoadDataEx, cuda_cu_module_load_data_ex);
-      LOOKUP_CUDA_FUNCTION(cuLaunchKernel, cuda_cu_launch_kernel);
-      LOOKUP_CUDA_FUNCTION(cuMemHostRegister, cuda_cu_mem_host_register);
-      LOOKUP_CUDA_FUNCTION(cuMemHostUnregister, cuda_cu_mem_host_unregister);
+  LOOKUP_CUDA_FUNCTION(cuInit, cuda_cu_init);
+  LOOKUP_CUDA_FUNCTION(cuCtxSynchronize, cuda_cu_ctx_synchronize);
+  LOOKUP_CUDA_FUNCTION(cuCtxGetCurrent, cuda_cu_ctx_get_current);
+  LOOKUP_CUDA_FUNCTION(cuCtxSetCurrent, cuda_cu_ctx_set_current);
+  LOOKUP_CUDA_FUNCTION(cuDeviceGetCount, cuda_cu_device_get_count);
+  LOOKUP_CUDA_FUNCTION(cuDeviceGetName, cuda_cu_device_get_name);
+  LOOKUP_CUDA_FUNCTION(cuDeviceGet, cuda_cu_device_get);
+  LOOKUP_CUDA_FUNCTION(cuDeviceComputeCapability, cuda_cu_device_compute_capability);
+  LOOKUP_CUDA_FUNCTION(cuDeviceGetAttribute, cuda_cu_device_get_attribute);
+  LOOKUP_CUDA_FUNCTION(cuModuleGetFunction, cuda_cu_module_get_function);
+  LOOKUP_CUDA_FUNCTION(cuModuleLoadDataEx, cuda_cu_module_load_data_ex);
+  LOOKUP_CUDA_FUNCTION(cuLaunchKernel, cuda_cu_launch_kernel);
+  LOOKUP_CUDA_FUNCTION(cuMemHostRegister, cuda_cu_mem_host_register);
+  LOOKUP_CUDA_FUNCTION(cuMemHostUnregister, cuda_cu_mem_host_unregister);
 #if defined(__x86_64) || defined(AMD64) || defined(_M_AMD64)
-      LOOKUP_CUDA_V2_FUNCTION(cuCtxCreate, cuda_cu_ctx_create);
-      LOOKUP_CUDA_V2_FUNCTION(cuCtxDestroy, cuda_cu_ctx_destroy);
-      LOOKUP_CUDA_V2_FUNCTION(cuMemAlloc, cuda_cu_memalloc);
-      LOOKUP_CUDA_V2_FUNCTION(cuMemFree, cuda_cu_memfree);
-      LOOKUP_CUDA_V2_FUNCTION(cuMemcpyHtoD, cuda_cu_memcpy_htod);
-      LOOKUP_CUDA_V2_FUNCTION(cuMemcpyDtoH, cuda_cu_memcpy_dtoh);
-      LOOKUP_CUDA_V2_FUNCTION(cuMemHostGetDevicePointer, cuda_cu_mem_host_get_device_pointer);
+  LOOKUP_CUDA_V2_FUNCTION(cuCtxCreate, cuda_cu_ctx_create);
+  LOOKUP_CUDA_V2_FUNCTION(cuCtxDestroy, cuda_cu_ctx_destroy);
+  LOOKUP_CUDA_V2_FUNCTION(cuMemAlloc, cuda_cu_memalloc);
+  LOOKUP_CUDA_V2_FUNCTION(cuMemFree, cuda_cu_memfree);
+  LOOKUP_CUDA_V2_FUNCTION(cuMemcpyHtoD, cuda_cu_memcpy_htod);
+  LOOKUP_CUDA_V2_FUNCTION(cuMemcpyDtoH, cuda_cu_memcpy_dtoh);
+  LOOKUP_CUDA_V2_FUNCTION(cuMemHostGetDevicePointer, cuda_cu_mem_host_get_device_pointer);
 #else
-      LOOKUP_CUDA_FUNCTION(cuCtxCreate, cuda_cu_ctx_create);
-      LOOKUP_CUDA_FUNCTION(cuCtxDestroy, cuda_cu_ctx_destroy);
-      LOOKUP_CUDA_FUNCTION(cuMemAlloc, cuda_cu_memalloc);
-      LOOKUP_CUDA_FUNCTION(cuMemFree, cuda_cu_memfree);
-      LOOKUP_CUDA_FUNCTION(cuMemcpyHtoD, cuda_cu_memcpy_htod);
-      LOOKUP_CUDA_FUNCTION(cuMemcpyDtoH, cuda_cu_memcpy_dtoh);
-      LOOKUP_CUDA_FUNCTION(cuMemHostGetDevicePointer, cuda_cu_mem_host_get_device_pointer);
+  LOOKUP_CUDA_FUNCTION(cuCtxCreate, cuda_cu_ctx_create);
+  LOOKUP_CUDA_FUNCTION(cuCtxDestroy, cuda_cu_ctx_destroy);
+  LOOKUP_CUDA_FUNCTION(cuMemAlloc, cuda_cu_memalloc);
+  LOOKUP_CUDA_FUNCTION(cuMemFree, cuda_cu_memfree);
+  LOOKUP_CUDA_FUNCTION(cuMemcpyHtoD, cuda_cu_memcpy_htod);
+  LOOKUP_CUDA_FUNCTION(cuMemcpyDtoH, cuda_cu_memcpy_dtoh);
+  LOOKUP_CUDA_FUNCTION(cuMemHostGetDevicePointer, cuda_cu_mem_host_get_device_pointer);
 #endif
 
-      if (TraceGPUInteraction) {
-        tty->print_cr("[CUDA] Success: library linkage");
-      }
-      return true;
-    } else {
-      // Unable to dlopen libcuda
-      return false;
-    }
-  } else {
-    tty->print_cr("Unsupported CUDA platform");
-    return false;
+  if (TraceGPUInteraction) {
+    tty->print_cr("[CUDA] Success: library linkage");
   }
-  tty->print_cr("Failed to find CUDA linkage");
-  return false;
+  return true;
 }
--- a/src/gpu/ptx/vm/gpu_ptx.hpp	Sun Feb 23 17:00:35 2014 -0800
+++ b/src/gpu/ptx/vm/gpu_ptx.hpp	Wed Mar 05 19:40:15 2014 -0800
@@ -84,19 +84,45 @@
  * Context creation flags
  */
 
-#define GRAAL_CU_CTX_MAP_HOST 0x08
+#define GRAAL_CU_CTX_MAP_HOST            0x08
+#define GRAAL_CU_CTX_SCHED_BLOCKING_SYNC 0x04
+
+/**
+ * Support compute capability 3.0 and later
+ */
+
+#define GRAAL_SUPPORTED_COMPUTE_CAPABILITY_VERSION 3.0
 
 class Ptx {
-  friend class gpu;
+  friend class PtxCall;
+
+private:
+
+  static JNINativeMethod PTX_methods[];
+
+  // static native boolean initialize();
+  JNIEXPORT static jboolean initialize(JNIEnv* env, jclass);
+
+  // static native long generateKernel(byte[] targetCode, String name);
+  JNIEXPORT static jlong generate_kernel(JNIEnv *env, jclass, jbyteArray code_handle, jstring name_handle);
+
+  // static native long getLaunchKernelAddress();
+  JNIEXPORT static jlong get_execute_kernel_from_vm_address(JNIEnv *env, jclass);
 
- protected:
-  static bool probe_linkage();
-  static bool initialize_gpu();
-  static unsigned int total_cores();
-  static void * generate_kernel(unsigned char *code, int code_len, const char *name);
-  static bool execute_warp(int dimX, int dimY, int dimZ, address kernel, PTXKernelArguments & ka, JavaValue &ret);
-  static bool execute_kernel(address kernel, PTXKernelArguments & ka, JavaValue &ret);
+  // static native int getAvailableProcessors0();
+  JNIEXPORT static jint get_total_cores(JNIEnv *env, jobject);
+
+  JNIEXPORT static void destroy_ptx_context();
+
+  // Links the CUDA driver library functions
+  static bool link();
+
+  static int ncores(int major, int minor);
+
 public:
+  // Registers the implementations for the native methods in PTXHotSpotBackend
+  static bool register_natives(JNIEnv* env);
+
 #if defined(__x86_64) || defined(AMD64) || defined(_M_AMD64)
   typedef unsigned long long CUdeviceptr;
 #else
@@ -106,8 +132,11 @@
 typedef int CUdevice;     /* CUDA device */
 
   static jlong execute_kernel_from_vm(JavaThread* thread, jlong kernel, jint dimX, jint dimY, jint dimZ,
-                                      jlong parametersAndReturnValueBuffer,
-                                      jint parametersAndReturnValueBufferSize,
+                                      jlong buffer,
+                                      jint bufferSize,
+                                      jint objectParametersCount,
+                                      jlong objectParametersOffsets,
+                                      jlong pinnedObjects,
                                       int encodedReturnTypeSize);
 
 private:
@@ -115,6 +144,7 @@
   typedef int (*cuda_cu_ctx_create_func_t)(void*, unsigned int, CUdevice);
   typedef int (*cuda_cu_ctx_destroy_func_t)(void*);
   typedef int (*cuda_cu_ctx_synchronize_func_t)(void);
+  typedef int (*cuda_cu_ctx_get_current_func_t)(void*);
   typedef int (*cuda_cu_ctx_set_current_func_t)(void*);
   typedef int (*cuda_cu_device_get_count_func_t)(int*);
   typedef int (*cuda_cu_device_get_name_func_t)(char*, int, int);
@@ -127,12 +157,12 @@
                                               unsigned int, void*, void**, void**);
   typedef int (*cuda_cu_module_get_function_func_t)(void*, void*, const char*);
   typedef int (*cuda_cu_module_load_data_ex_func_t)(void*, void*, unsigned int, void*, void**);
-  typedef int (*cuda_cu_memalloc_func_t)(gpu::Ptx::CUdeviceptr*, size_t);
-  typedef int (*cuda_cu_memfree_func_t)(gpu::Ptx::CUdeviceptr);
-  typedef int (*cuda_cu_memcpy_htod_func_t)(gpu::Ptx::CUdeviceptr, const void*, unsigned int);
-  typedef int (*cuda_cu_memcpy_dtoh_func_t)(const void*, gpu::Ptx::CUdeviceptr,  unsigned int);
+  typedef int (*cuda_cu_memalloc_func_t)(Ptx::CUdeviceptr*, size_t);
+  typedef int (*cuda_cu_memfree_func_t)(Ptx::CUdeviceptr);
+  typedef int (*cuda_cu_memcpy_htod_func_t)(Ptx::CUdeviceptr, const void*, unsigned int);
+  typedef int (*cuda_cu_memcpy_dtoh_func_t)(const void*, Ptx::CUdeviceptr,  unsigned int);
   typedef int (*cuda_cu_mem_host_register_func_t)(void*, size_t, unsigned int);
-  typedef int (*cuda_cu_mem_host_get_device_pointer_func_t)(gpu::Ptx::CUdeviceptr*, void*, unsigned int);
+  typedef int (*cuda_cu_mem_host_get_device_pointer_func_t)(Ptx::CUdeviceptr*, void*, unsigned int);
   typedef int (*cuda_cu_mem_host_unregister_func_t)(void*);
 
 public:
@@ -152,6 +182,7 @@
   static cuda_cu_memfree_func_t                   _cuda_cu_memfree;
   static cuda_cu_memcpy_htod_func_t               _cuda_cu_memcpy_htod;
   static cuda_cu_memcpy_dtoh_func_t               _cuda_cu_memcpy_dtoh;
+  static cuda_cu_ctx_get_current_func_t           _cuda_cu_ctx_get_current;
   static cuda_cu_ctx_set_current_func_t           _cuda_cu_ctx_set_current;
   static cuda_cu_mem_host_register_func_t         _cuda_cu_mem_host_register;
   static cuda_cu_mem_host_get_device_pointer_func_t _cuda_cu_mem_host_get_device_pointer;
--- a/src/gpu/ptx/vm/ptxKernelArguments.cpp	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,332 +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.
- *
- */
-
-#include "precompiled.hpp"
-#include "ptxKernelArguments.hpp"
-#include "runtime/javaCalls.hpp"
-
-gpu::Ptx::cuda_cu_memalloc_func_t gpu::Ptx::_cuda_cu_memalloc;
-gpu::Ptx::cuda_cu_memcpy_htod_func_t gpu::Ptx::_cuda_cu_memcpy_htod;
-
-// Get next java argument
-oop PTXKernelArguments::next_arg(BasicType expectedType) {
-  assert(_index < _args->length(), "out of bounds");
-  oop arg = ((objArrayOop) (_args))->obj_at(_index++);
-  assert(expectedType == T_OBJECT ||
-         java_lang_boxing_object::is_instance(arg, expectedType), "arg type mismatch");
-  return arg;
-}
-
-/*
- * Pad kernel argument buffer to naturally align for given size.
- */
-void PTXKernelArguments::pad_kernel_argument_buffer(size_t dataSz) {
-  while ((_bufferOffset % dataSz) != 0) {
-    *((gpu::Ptx::CUdeviceptr*) &_kernelArgBuffer[_bufferOffset]) = (char) 0;
-    _bufferOffset += sizeof(char);
-  }
-  return;
-}
-void PTXKernelArguments::do_int() {
-  // If the parameter is a return value,
-  if (is_return_type()) {
-    // Allocate device memory for T_INT return value pointer on device. Size in bytes
-    int status = gpu::Ptx::_cuda_cu_memalloc(&_dev_return_value, T_INT_BYTE_SIZE);
-    if (status != GRAAL_CUDA_SUCCESS) {
-      tty->print_cr("[CUDA] *** Error (%d) Failed to allocate memory for return value pointer on device", status);
-      _success = false;
-      return;
-    }
-
-    // Kernel arguments are expected to be naturally aligned.
-    // Insert padding into kernel argument buffer, if needed.
-    pad_kernel_argument_buffer(sizeof(_dev_return_value));
-    // Push _dev_return_value to _kernelBuffer
-    *((gpu::Ptx::CUdeviceptr*) &_kernelArgBuffer[_bufferOffset]) = _dev_return_value;
-    _bufferOffset += sizeof(_dev_return_value);
-  } else {
-    // Get the next java argument and its value which should be a T_INT
-    oop arg = next_arg(T_INT);
-    // Copy the java argument value to kernelArgBuffer
-    jvalue intval;
-    if (java_lang_boxing_object::get_value(arg, &intval) != T_INT) {
-      tty->print_cr("[CUDA] *** Error: Unexpected argument type; expecting T_INT");
-      _success = false;
-      return;
-    }
-
-    // Kernel arguments are expected to be naturally aligned.
-    // Insert padding into kernel argument buffer, if needed.
-    pad_kernel_argument_buffer(sizeof(intval.i));
-    // Push _dev_return_value to _kernelBuffer
-    *((gpu::Ptx::CUdeviceptr*) &_kernelArgBuffer[_bufferOffset]) = intval.i;
-
-    // Advance _bufferOffset
-    _bufferOffset += sizeof(intval.i);
-  }
-  return;
-}
-
-void PTXKernelArguments::do_float() {
-  // If the parameter is a return value,
-  if (is_return_type()) {
-    // Allocate device memory for T_FLOAT return value pointer on device. Size in bytes
-    int status = gpu::Ptx::_cuda_cu_memalloc(&_dev_return_value, T_FLOAT_BYTE_SIZE);
-    if (status != GRAAL_CUDA_SUCCESS) {
-      tty->print_cr("[CUDA] *** Error (%d) Failed to allocate memory for return value pointer on device", status);
-      _success = false;
-      return;
-    }
-    // Kernel arguments are expected to be naturally aligned.
-    // Insert padding into kernel argument buffer, if needed.
-    pad_kernel_argument_buffer(sizeof(_dev_return_value));
-    // Push _dev_return_value to _kernelBuffer
-    *((gpu::Ptx::CUdeviceptr*) &_kernelArgBuffer[_bufferOffset]) = _dev_return_value;
-    // Advance _bufferOffset
-    _bufferOffset += sizeof(_dev_return_value);
-  } else {
-    // Get the next java argument and its value which should be a T_FLOAT
-    oop arg = next_arg(T_FLOAT);
-    // Copy the java argument value to kernelArgBuffer
-    jvalue floatval;
-    if (java_lang_boxing_object::get_value(arg, &floatval) != T_FLOAT) {
-      tty->print_cr("[CUDA] *** Error: Unexpected argument type; expecting T_FLOAT");
-      _success = false;
-      return;
-    }
-    // Kernel arguments are expected to be naturally aligned.
-    // Insert padding into kernel argument buffer, if needed.
-    pad_kernel_argument_buffer(sizeof(floatval.f));
-    *((gpu::Ptx::CUdeviceptr*) &_kernelArgBuffer[_bufferOffset]) = (gpu::Ptx::CUdeviceptr) floatval.f;
-
-    // Advance _bufferOffset
-    _bufferOffset += sizeof(floatval.f);
-  }
-  return;
-}
-
-void PTXKernelArguments::do_double() {
-  // If the parameter is a return value,
-  jvalue doubleval;
-  if (is_return_type()) {
-    // Allocate device memory for T_DOUBLE return value pointer on device. Size in bytes
-    int status = gpu::Ptx::_cuda_cu_memalloc(&_dev_return_value, T_DOUBLE_BYTE_SIZE);
-    if (status != GRAAL_CUDA_SUCCESS) {
-      tty->print_cr("[CUDA] *** Error (%d) Failed to allocate memory for return value pointer on device", status);
-      _success = false;
-      return;
-    }
-    // Kernel arguments are expected to be naturally aligned.
-    // Insert padding into kernel argument buffer, if needed.
-    pad_kernel_argument_buffer(sizeof(_dev_return_value));
-    // Push _dev_return_value to _kernelBuffer
-    *((gpu::Ptx::CUdeviceptr*) &_kernelArgBuffer[_bufferOffset]) = _dev_return_value;
-    // Advance _bufferOffset.
-    _bufferOffset += sizeof(doubleval.d);
-  } else {
-    // Get the next java argument and its value which should be a T_INT
-    oop arg = next_arg(T_FLOAT);
-    // Copy the java argument value to kernelArgBuffer
-    if (java_lang_boxing_object::get_value(arg, &doubleval) != T_DOUBLE) {
-      tty->print_cr("[CUDA] *** Error: Unexpected argument type; expecting T_INT");
-      _success = false;
-      return;
-    }
-    // Kernel arguments are expected to be naturally aligned.
-    // Insert padding into kernel argument buffer, if needed.
-    pad_kernel_argument_buffer(sizeof(doubleval.d));
-    *((gpu::Ptx::CUdeviceptr*) &_kernelArgBuffer[_bufferOffset]) = (gpu::Ptx::CUdeviceptr) doubleval.d;
-
-    // Advance _bufferOffset
-    _bufferOffset += sizeof(doubleval.d);
-    // For a 64-bit host, since size of double is 8, there is no need
-    // to pad the kernel argument buffer to ensure 8-byte alignment of
-    // the next potential argument to be pushed.
-  }
-  return;
-}
-
-void PTXKernelArguments::do_long() {
-  // If the parameter is a return value,
-  if (is_return_type()) {
-    // Allocate device memory for T_LONG return value pointer on device. Size in bytes
-    int status = gpu::Ptx::_cuda_cu_memalloc(&_dev_return_value, T_LONG_BYTE_SIZE);
-    if (status != GRAAL_CUDA_SUCCESS) {
-      tty->print_cr("[CUDA] *** Error (%d) Failed to allocate memory for return value pointer on device", status);
-      _success = false;
-      return;
-    }
-    // Kernel arguments are expected to be naturally aligned.
-    // Insert padding into kernel argument buffer, if needed.
-    pad_kernel_argument_buffer(sizeof(_dev_return_value));
-    // Push _dev_return_value to _kernelBuffer
-    *((gpu::Ptx::CUdeviceptr*) &_kernelArgBuffer[_bufferOffset]) = _dev_return_value;
-    // Advance _bufferOffset
-    _bufferOffset += sizeof(_dev_return_value);
-  } else {
-    // Get the next java argument and its value which should be a T_LONG
-    oop arg = next_arg(T_LONG);
-    // Copy the java argument value to kernelArgBuffer
-    jvalue val;
-    if (java_lang_boxing_object::get_value(arg, &val) != T_LONG) {
-      tty->print_cr("[CUDA] *** Error: Unexpected argument type; expecting T_LONG");
-      _success = false;
-      return;
-    }
-    // Kernel arguments are expected to be naturally aligned.
-    // Insert padding into kernel argument buffer, if needed.
-    pad_kernel_argument_buffer(sizeof(val.j));
-    *((gpu::Ptx::CUdeviceptr*) &_kernelArgBuffer[_bufferOffset]) = val.j;
-
-    // Advance _bufferOffset
-    _bufferOffset += sizeof(val.j);
-    // For a 64-bit host, since size of long is 8, there is no need
-    // to pad the kernel argument buffer to ensure 8-byte alignment of
-    // the next potential argument to be pushed.
-  }
-  return;
-}
-
-void PTXKernelArguments::do_byte() {
-  // If the parameter is a return value,
-  if (is_return_type()) {
-    // Allocate device memory for T_BYTE return value pointer on device. Size in bytes
-    int status = gpu::Ptx::_cuda_cu_memalloc(&_dev_return_value, T_BYTE_SIZE);
-    if (status != GRAAL_CUDA_SUCCESS) {
-      tty->print_cr("[CUDA] *** Error (%d) Failed to allocate memory for return value pointer on device", status);
-      _success = false;
-      return;
-    }
-    // Kernel arguments are expected to be naturally aligned.
-    // Insert padding into kernel argument buffer, if needed.
-    pad_kernel_argument_buffer(sizeof(_dev_return_value));
-    // Push _dev_return_value to _kernelBuffer
-    *((gpu::Ptx::CUdeviceptr*) &_kernelArgBuffer[_bufferOffset]) = _dev_return_value;
-
-    // Advance _bufferOffset
-    _bufferOffset += sizeof(_dev_return_value);
-  } else {
-    // Get the next java argument and its value which should be a T_BYTE
-    oop arg = next_arg(T_BYTE);
-    // Copy the java argument value to kernelArgBuffer
-    jvalue val;
-    if (java_lang_boxing_object::get_value(arg, &val) != T_BYTE) {
-      tty->print_cr("[CUDA] *** Error: Unexpected argument type; expecting T_BYTE");
-      _success = false;
-      return;
-    }
-    // Kernel arguments are expected to be naturally aligned.
-    // Insert padding into kernel argument buffer, if needed.
-    pad_kernel_argument_buffer(sizeof(val.b));
-    *((gpu::Ptx::CUdeviceptr*) &_kernelArgBuffer[_bufferOffset]) = val.b;
-
-    // Advance _bufferOffset
-    _bufferOffset += sizeof(val.b);
-    // For a 64-bit host, since size of T_BYTE is 8, there is no need
-    // to pad the kernel argument buffer to ensure 8-byte alignment of
-    // the next potential argument to be pushed.
-  }
-  return;
-}
-
-void PTXKernelArguments::do_bool() {
-  // If the parameter is a return value,
-  if (is_return_type()) {
-    // Allocate device memory for T_BYTE return value pointer on device. Size in bytes
-    int status = gpu::Ptx::_cuda_cu_memalloc(&_dev_return_value, T_BOOLEAN_SIZE);
-    if (status != GRAAL_CUDA_SUCCESS) {
-      tty->print_cr("[CUDA] *** Error (%d) Failed to allocate memory for return value pointer on device", status);
-      _success = false;
-      return;
-    }
-    // Kernel arguments are expected to be naturally aligned.
-    // Insert padding into kernel argument buffer, if needed.
-    pad_kernel_argument_buffer(sizeof(_dev_return_value));
-    // Push _dev_return_value to _kernelBuffer
-    *((gpu::Ptx::CUdeviceptr*) &_kernelArgBuffer[_bufferOffset]) = _dev_return_value;
-    _bufferOffset += sizeof(_dev_return_value);
-  } else {
-    // Get the next java argument and its value which should be a T_BOOLEAN
-    oop arg = next_arg(T_BOOLEAN);
-    // Copy the java argument value to kernelArgBuffer
-    jvalue val;
-    if (java_lang_boxing_object::get_value(arg, &val) != T_BOOLEAN) {
-      tty->print_cr("[CUDA] *** Error: Unexpected argument type; expecting T_BOOLEAN");
-      _success = false;
-      return;
-    }
-    // Kernel arguments are expected to be naturally aligned.
-    // Insert padding into kernel argument buffer, if needed.
-    pad_kernel_argument_buffer(sizeof(val.z));
-    *((gpu::Ptx::CUdeviceptr*) &_kernelArgBuffer[_bufferOffset]) = val.z;
-
-    // Advance _bufferOffset
-    _bufferOffset += sizeof(val.z);
-  }
-  return;
-}
-
-void PTXKernelArguments::do_array(int begin, int end) {
-  // Get the next java argument and its value which should be a T_ARRAY
-  oop arg = next_arg(T_OBJECT);
-  assert(arg->is_array(), "argument value not an array");
-  // Size of array argument
-  int argSize = arg->size() * HeapWordSize;
-  // Device pointer to array argument.
-  gpu::Ptx::CUdeviceptr arrayArgOnDev;
-  int status;
-
-  // Register host memory for use by the device. Size in bytes
-  status = gpu::Ptx::_cuda_cu_mem_host_register(arg, argSize, GRAAL_CU_MEMHOSTREGISTER_DEVICEMAP);
-  if (status != GRAAL_CUDA_SUCCESS) {
-    tty->print_cr("[CUDA] *** Error (%d) Failed to register host memory for array argument on device",
-                  status);
-    _success = false;
-    return;
-  }
-  // Get device pointer
-  status = gpu::Ptx::_cuda_cu_mem_host_get_device_pointer(&arrayArgOnDev, arg, 0);
-  if (status != GRAAL_CUDA_SUCCESS) {
-    tty->print_cr("[CUDA] *** Error (%d) Failed to get device pointer of mapped pinned memory of array argument.",
-                  status);
-    _success = false;
-    return;
-  }
-
-  // Kernel arguments are expected to be naturally aligned.
-  // Insert padding into kernel argument buffer, if needed.
-  pad_kernel_argument_buffer(sizeof(arrayArgOnDev));
-  // Push device array argument to _kernelBuffer
-  *((gpu::Ptx::CUdeviceptr*) &_kernelArgBuffer[_bufferOffset]) = arrayArgOnDev;
-
-  // Advance _bufferOffset
-  _bufferOffset += sizeof(arrayArgOnDev);
-  return;
-}
-
-void PTXKernelArguments::do_void() {
-  return;
-}
-
-// TODO implement other do_*
--- a/src/gpu/ptx/vm/ptxKernelArguments.hpp	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,127 +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 KERNEL_ARGUMENTS_PTX_HPP
-#define KERNEL_ARGUMENTS_PTX_HPP
-
-#include "runtime/gpu.hpp"
-#include "runtime/signature.hpp"
-
-#define T_BYTE_SIZE        1
-#define T_BOOLEAN_SIZE     4
-#define T_INT_BYTE_SIZE    4
-#define T_FLOAT_BYTE_SIZE  4
-#define T_DOUBLE_BYTE_SIZE 8
-#define T_LONG_BYTE_SIZE   8
-#define T_OBJECT_BYTE_SIZE 8
-#define T_ARRAY_BYTE_SIZE  8
-
-class PTXKernelArguments : public SignatureIterator {
-public:
-  // Buffer holding CUdeviceptr values that represent the kernel arguments
-  char _kernelArgBuffer[1024];
-  // Current offset into _kernelArgBuffer
-  size_t _bufferOffset;
-  // Device pointer holding return value
-  gpu::Ptx::CUdeviceptr _dev_return_value;
-
-private:
-  // Array of java argument oops
-  arrayOop _args;
-  // Current index into _args
-  int _index;
-  // Flag to indicate successful creation of kernel argument buffer
-  bool _success;
-
-  // Get next java argument
-  oop next_arg(BasicType expectedType);
-
- public:
-  PTXKernelArguments(Symbol* signature, arrayOop args, bool is_static) : SignatureIterator(signature) {
-    this->_return_type = T_ILLEGAL;
-    _index = 0;
-    _args = args;
-    _success = true;
-    _bufferOffset = 0;
-    _dev_return_value = 0;
-    if (!is_static) {
-      // TODO : Create a device argument for receiver object and add it to _kernelBuffer
-      tty->print_cr("{CUDA] ****** TODO: Support for execution of non-static java methods not implemented yet.");
-    }
-    // Iterate over the entire signature
-    iterate();
-    assert((_success && (_index == args->length())), "arg count mismatch with signature");
-  }
-
-  inline char* device_argument_buffer() {
-    return _kernelArgBuffer;
-  }
-
-  inline size_t device_argument_buffer_size() {
-    return _bufferOffset;
-  }
-
-  // Get the return oop value
-  oop get_return_oop();
-
-  // get device return value ptr
-  gpu::Ptx::CUdeviceptr get_dev_return_value() {
-      return _dev_return_value;
-  }
-
-  /*
-   * Pad kernel argument buffer to naturally align for given size.
-   */
-  void pad_kernel_argument_buffer(size_t);
-
-  void do_byte();
-  void do_bool();
-  void do_int();
-  void do_float();
-  void do_double();
-  void do_long();
-  void do_array(int begin, int end);
-  void do_void();
-
-  inline void do_char()   {
-    /* TODO : To be implemented */
-    guarantee(false, "do_char:NYI");
-  }
-  inline void do_short()  {
-    /* TODO : To be implemented */
-    guarantee(false, "do_short:NYI");
-  }
-  inline void do_object() {
-    /* TODO : To be implemented */
-    guarantee(false, "do_object:NYI");
-  }
-    
-  inline void do_object(int begin, int end) {
-    /* TODO : To be implemented */
-    guarantee(false, "do_object(II):NYI");
-  }
-
-};
-
-#endif  // KERNEL_ARGUMENTS_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/os/bsd/vm/gpu_bsd.cpp	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "runtime/gpu.hpp"
+#include "ptx/vm/gpu_ptx.hpp"
+#include "hsail/vm/gpu_hsail.hpp"
+#include "utilities/ostream.hpp"
+
+jobject gpu::probe_gpus(JNIEnv* env) {
+#ifdef __APPLE__
+  /*
+   * Let the CUDA driver initialization be the gate to GPU for now, pending
+   * a better detection solution for NVIDA PTX and AMD HSAIL.
+   */
+  if (Ptx::register_natives(env)) {
+    if (TraceGPUInteraction) {
+      tty->print_cr("Assuming NVidia/PTX support (APPLE)");
+    }
+    return env->NewStringUTF("PTX");
+  }
+#else
+  if (TraceGPUInteraction) {
+    tty->print_cr("Assuming no GPU (not APPLE)");
+  }
+#endif
+  return env->NewStringUTF("");
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/os/linux/vm/gpu_linux.cpp	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "runtime/gpu.hpp"
+#include "ptx/vm/gpu_ptx.hpp"
+#include "hsail/vm/gpu_hsail.hpp"
+#include "utilities/ostream.hpp"
+
+/*
+ * Probe for CUDA device on PCI bus using /proc/bus/pci/devices. Do
+ * not rely on CUDA tool kit being installed. We will check if CUDA
+ * library is installed later.
+ */
+
+static unsigned int nvidia_vendor_id = 0x10de;
+static unsigned int amd_vendor_id = 0x1002;
+
+#define PCI_DRIVER_NAME_START_POS 255
+
+jobject gpu::probe_gpus(JNIEnv* env) {
+  bool hsail = false;
+  bool ptx = false;
+
+  if (Hsail::register_natives(env)) {
+    hsail = true;
+  }
+
+  /*
+   * Open /proc/bus/pci/devices to look for the first GPU device. For
+   * now, we will just find the first GPU device. Will need to revisit
+   * this to support execution on multiple GPU devices, if they exist.
+   */
+  FILE *pci_devices = fopen("/proc/bus/pci/devices", "r");
+  char contents[4096];
+  unsigned int bus_num_devfn_ign;
+  unsigned int vendor;
+  unsigned int device;
+  const char *driver_name_string = "nvidia";
+  const int driver_name_string_len = strlen(driver_name_string);
+
+  if (pci_devices == NULL) {
+    tty->print_cr("*** Failed to open /proc/bus/pci/devices");
+    return NULL;
+  }
+
+  while (fgets(contents, sizeof(contents)-1, pci_devices)) {
+    sscanf(contents, "%04x%04x%04x", &bus_num_devfn_ign, &vendor, &device);
+    if (vendor == nvidia_vendor_id) {
+      /* Check if this device is registered to be using nvidia driver */
+      if (strncmp(&contents[PCI_DRIVER_NAME_START_POS],
+                  driver_name_string, driver_name_string_len) == 0) {
+        if (TraceGPUInteraction) {
+          tty->print_cr("Found supported nVidia device [vendor=0x%04x, device=0x%04x]", vendor, device);
+        }
+        if (!ptx && Ptx::register_natives(env)) {
+          ptx = true;
+        }
+      }
+    }
+  }
+
+  // Close file pointer.
+  fclose(pci_devices);
+
+  const char* gpus = "";
+  if (ptx && hsail) {
+    gpus = "PTX,HSAIL";
+  } else if (ptx) {
+    gpus = "PTX";
+  } else if (hsail) {
+    gpus = "HSAIL";
+  }
+  return env->NewStringUTF(gpus);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/os/windows/vm/gpu_windows.cpp	Wed Mar 05 19:40:15 2014 -0800
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "runtime/gpu.hpp"
+#include "hsail/vm/gpu_hsail.hpp"
+#include "utilities/ostream.hpp"
+
+jobject gpu::probe_gpus(JNIEnv* env) {
+  // TODO: add detection of PTX/NVidia
+  if (Hsail::register_natives(env)) {
+    return env->NewStringUTF("HSAIL");
+  }
+  return env->NewStringUTF("");
+}
--- a/src/os_gpu/bsd_ptx/vm/gpu_bsd.cpp	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,47 +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.
- *
- */
-
-#include "runtime/gpu.hpp"
-#include "utilities/ostream.hpp"
-
-
-void gpu::probe_gpu() {
-#ifdef __APPLE__
-  /*
-   * Let the CUDA driver initialization be the gate to GPU for now, pending
-   * a better detection solution for NVIDA PTX and AMD HSAIL.
-   */
-  set_available(true);
-  set_target_il_type(gpu::PTX);
-  if (TraceGPUInteraction) {
-    tty->print_cr("gpu_bsd::probe_gpu(APPLE): %d", gpu::is_available());
-  }
-#else
-  if (TraceGPUInteraction) {
-    tty->print_cr("gpu_bsd::probe_gpu(not APPLE)");
-  }
-  set_available(false);
-#endif
-}
-
--- a/src/os_gpu/bsd_ptx/vm/gpu_bsd.hpp	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +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 OS_BSD_VM_GPU_BSD_HPP
-#define OS_BSD_VM_GPU_BSD_HPP
-
-
-class Bsd {
-  friend class gpu;
-
- protected:
-  static bool probe_gpu();
-#ifdef __APPLE__
-  static bool probe_gpu_apple();
-#endif
-};
-
-#endif // OS_BSD_VM_GPU_BSD_HPP
--- a/src/os_gpu/linux_ptx/vm/gpu_linux.cpp	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,104 +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.
- *
- */
-
-#include "runtime/gpu.hpp"
-#include "utilities/ostream.hpp"
-
-void gpu::probe_gpu() {
-  set_available(gpu::Linux::probe_gpu());
-  if (TraceGPUInteraction) {
-    tty->print_cr("gpu_linux::probe_gpu(): %d", gpu::is_available());
-  }
-}
-
-/*
- * Probe for CUDA device on PCI bus using /proc/bus/pci/devices. Do
- * not rely on CUDA tool kit being installed. We will check if CUDA
- * library is installed later.
- */
-
-static unsigned int nvidia_vendor_id = 0x10de;
-static unsigned int amd_vendor_id = 0x1002;
-
-bool gpu::Linux::probe_gpu() {
-
-  /*
-   * The simulator only depends on shared libraries.
-   * That linkage is checked in a later step.
-   */
-  if (UseHSAILSimulator) {
-      set_target_il_type(gpu::HSAIL);
-      if (TraceGPUInteraction) {
-        tty->print_cr("Setup HSAIL Simulator");
-      }
-      return true;
-  }
-
-  /* 
-   * Open /proc/bus/pci/devices to look for the first GPU device. For
-   * now, we will just find the first GPU device. Will need to revisit
-   * this to support execution on multiple GPU devices, if they exist.
-   */
-  FILE *pci_devices = fopen("/proc/bus/pci/devices", "r");
-  char contents[4096];
-  unsigned int bus_num_devfn_ign;
-  unsigned int vendor;
-  unsigned int device;
-  bool gpu_device_exists = false;
-  if (pci_devices == NULL) {
-    tty->print_cr("*** Failed to open /proc/bus/pci/devices");
-    return gpu_device_exists;
-  }
-
-  while (fgets(contents, sizeof(contents)-1, pci_devices)) {
-    sscanf(contents, "%04x%04x%04x", &bus_num_devfn_ign, &vendor, &device);
-    /* Break after finding the first GPU device. */
-    if (vendor == nvidia_vendor_id) {
-      gpu_device_exists = true;
-      set_target_il_type(gpu::PTX);
-      if (TraceGPUInteraction) {
-        tty->print_cr("Found supported nVidia GPU device vendor : 0x%04x device 0x%04x", vendor, device);
-      }
-      break;
-       /*
-        * Remove AMD detection until we decide how to detect real HSA hardware.
-        * In the current form this check does not work correctly on AMD CPU system with 
-        * Nvidia GPU.
-        *
-        * } else if (vendor == amd_vendor_id) {
-        *   gpu_device_exists = true;
-        *   set_target_il_type(gpu::HSAIL);
-        *   if (TraceGPUInteraction) {
-        *     tty->print_cr("Found supported AMD GPU device vendor : 0x%04x device 0x%04x", vendor, device);
-        *   }
-        *   break;
-        */
-    }
-  }
-
-  // Close file pointer.
-  fclose(pci_devices);
-
-  return gpu_device_exists;
-}
--- a/src/os_gpu/linux_ptx/vm/gpu_linux.hpp	Sun Feb 23 17:00:35 2014 -0800
+++ /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.
- *
- */
-
-#ifndef OS_BSD_VM_GPU_LINUX_HPP
-#define OS_BSD_VM_GPU_LINUX_HPP
-
-
-class Linux {
-  friend class gpu;
-
- protected:
-  static bool probe_gpu();
-};
-
-#endif // OS_BSD_VM_GPU_LINUX_HPP
--- a/src/os_gpu/windows_hsail/vm/gpu_windows.cpp	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,47 +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.
- *
- */
-
-#include "precompiled.hpp"
-#include "runtime/gpu.hpp"
-#include "utilities/ostream.hpp"
-
-void gpu::probe_gpu() {
-  set_available(gpu::Windows::probe_gpu());
-  if (TraceGPUInteraction) {
-    tty->print_cr("probe_gpu(): %d", gpu::is_available());
-  }
-}
-
-bool gpu::Windows::probe_gpu() {
-    
-  /*
-   * We will check the HSA environment in the libraries,
-   * so nothing to do here.
-   * The HSA library linkage is checked in a later step.
-   */  
-  bool gpu_device_exists = true;
-  set_target_il_type(gpu::HSAIL);
-
-  return gpu_device_exists;
-}
--- a/src/os_gpu/windows_hsail/vm/gpu_windows.hpp	Sun Feb 23 17:00:35 2014 -0800
+++ /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.
- *
- */
-
-#ifndef OS_WINDOWS_VM_GPU_WINDOWS_HPP
-#define OS_WINDOWS_VM_GPU_WINDOWS_HPP
-
-
-class Windows {
-  friend class gpu;
-
- protected:
-  static bool probe_gpu();
-};
-
-#endif // OS_WINDOWS_VM_GPU_WINDOWS_HPP
--- a/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputEdge.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputEdge.java	Wed Mar 05 19:40:15 2014 -0800
@@ -24,6 +24,8 @@
 package com.sun.hotspot.igv.data;
 
 import java.util.Comparator;
+import java.util.WeakHashMap;
+import java.lang.ref.WeakReference;
 
 /**
  *
@@ -32,7 +34,7 @@
 public class InputEdge {
 
     public enum State {
-
+        IMMUTABLE,
         SAME,
         NEW,
         DELETED
@@ -61,12 +63,12 @@
             }
     };
 
-    private char toIndex;
-    private char fromIndex;
-    private int from;
-    private int to;
+    private final char toIndex;
+    private final char fromIndex;
+    private final int from;
+    private final int to;
+    private final String label;
     private State state;
-    private String label;
 
     public InputEdge(char toIndex, int from, int to) {
         this((char) 0, toIndex, from, to, null);
@@ -85,11 +87,38 @@
         this.label = label;
     }
 
+    static WeakHashMap<InputEdge, WeakReference<InputEdge>> immutableCache = new WeakHashMap<>();
+
+    public static synchronized InputEdge createImmutable(char fromIndex, char toIndex, int from, int to, String label) {
+        InputEdge edge = new InputEdge(fromIndex, toIndex, from, to, label, State.IMMUTABLE);
+        WeakReference<InputEdge> result = immutableCache.get(edge);
+        if (result != null) {
+            InputEdge edge2 = result.get();
+            if (edge2 != null) {
+                return edge2;
+            }
+        }
+        immutableCache.put(edge, new WeakReference<>(edge));
+        return edge;
+    }
+
+    public InputEdge(char fromIndex, char toIndex, int from, int to, String label, State state) {
+        this.toIndex = toIndex;
+        this.fromIndex = fromIndex;
+        this.from = from;
+        this.to = to;
+        this.state = state;
+        this.label = label;
+    }
+
     public State getState() {
         return state;
     }
 
     public void setState(State x) {
+        if (state == State.IMMUTABLE) {
+            throw new InternalError("Can't change immutable instances");
+        }
         this.state = x;
     }
 
@@ -123,7 +152,12 @@
             return false;
         }
         InputEdge conn2 = (InputEdge) o;
-        return conn2.fromIndex == fromIndex && conn2.toIndex == toIndex && conn2.from == from && conn2.to == to;
+        boolean result = conn2.fromIndex == fromIndex && conn2.toIndex == toIndex && conn2.from == from && conn2.to == to;
+        if (result && (state == State.IMMUTABLE || conn2.state == State.IMMUTABLE)) {
+            // Immutable instances must be exactly the same
+            return conn2.label == label && conn2.state == state;
+        }
+        return result;
     }
 
     @Override
--- a/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputGraph.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputGraph.java	Wed Mar 05 19:40:15 2014 -0800
@@ -32,19 +32,19 @@
 public class InputGraph extends Properties.Entity implements FolderElement {
 
     private Map<Integer, InputNode> nodes;
-    private Set<InputEdge> edges;
+    private List<InputEdge> edges;
     private Folder parent;
     private Group parentGroup;
     private Map<String, InputBlock> blocks;
-    private Set<InputBlockEdge> blockEdges;
+    private List<InputBlockEdge> blockEdges;
     private Map<Integer, InputBlock> nodeToBlock;
 
     public InputGraph(String name) {
         setName(name);
         nodes = new LinkedHashMap<>();
-        edges = new LinkedHashSet<>();
+        edges = new ArrayList<>();
         blocks = new LinkedHashMap<>();
-        blockEdges = new LinkedHashSet<>();
+        blockEdges = new ArrayList<>();
         nodeToBlock = new LinkedHashMap<>();
     }
     
@@ -234,7 +234,7 @@
     }
 
     public Collection<InputEdge> getEdges() {
-        return Collections.unmodifiableSet(edges);
+        return Collections.unmodifiableList(edges);
     }
 
     public void removeEdge(InputEdge c) {
@@ -283,7 +283,7 @@
     }
 
     public Collection<InputBlockEdge> getBlockEdges() {
-        return Collections.unmodifiableSet(blockEdges);
+        return Collections.unmodifiableList(blockEdges);
     }
 
     @Override
--- a/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/Properties.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/Properties.java	Wed Mar 05 19:40:15 2014 -0800
@@ -320,6 +320,9 @@
     }
 
     public void setProperty(String name, String value) {
+        setPropertyInternal(name.intern(), value != null ? value.intern() : null);
+    }
+    private void setPropertyInternal(String name, String value) {
 
         for (int i = 0; i < map.length; i += 2) {
             if (map[i] != null && map[i].equals(name)) {
@@ -353,7 +356,8 @@
 
     public void add(Properties properties) {
         for (Property p : properties) {
-            setProperty(p.getName(), p.getValue());
+            // Already interned
+            setPropertyInternal(p.getName(), p.getValue());
         }
     }
 
--- a/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/BinaryParser.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/BinaryParser.java	Wed Mar 05 19:40:15 2014 -0800
@@ -35,6 +35,8 @@
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 import javax.swing.SwingUtilities;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
 
 public class BinaryParser implements GraphParser {
     private static final int BEGIN_GROUP = 0x00;
@@ -72,7 +74,10 @@
     private final ReadableByteChannel channel;
     private final GraphDocument rootDocument;
     private final Deque<Folder> folderStack;
+    private final Deque<byte[]> hashStack;
     private final ParseMonitor monitor;
+
+    private MessageDigest digest;
     
     private enum Length {
         S,
@@ -259,7 +264,12 @@
         this.channel = channel;
         this.rootDocument = rootDocument;
         folderStack = new LinkedList<>();
+        hashStack = new LinkedList<>();
         this.monitor = monitor;
+        try {
+            this.digest = MessageDigest.getInstance("SHA-256");
+        } catch (NoSuchAlgorithmException e) {
+        }
     }
     
     private void fill() throws IOException {
@@ -274,6 +284,11 @@
         while (buffer.remaining() < i) {
             fill();
         }
+        buffer.mark();
+        byte[] result = new byte[i];
+        buffer.get(result);
+        digest.update(result);
+        buffer.reset();
     }
     
     private int readByte() throws IOException {
@@ -312,7 +327,7 @@
         char[] chars = new char[len];
         buffer.asCharBuffer().get(chars);
         buffer.position(buffer.position() + len * 2);
-        return new String(chars);
+        return new String(chars).intern();
     }
 
     private byte[] readBytes() throws IOException {
@@ -340,7 +355,7 @@
             }
         }
         sb.append(']');
-        return sb.toString();
+        return sb.toString().intern();
     }
     
     private String readDoublesToString() throws IOException {
@@ -357,7 +372,7 @@
             }
         }
         sb.append(']');
-        return sb.toString();
+        return sb.toString().intern();
     }
     
     private String readPoolObjectsToString() throws IOException {
@@ -373,7 +388,7 @@
             }
         }
         sb.append(']');
-        return sb.toString();
+        return sb.toString().intern();
     }
     
     private <T> T readPoolObject(Class<T> klass) throws IOException {
@@ -536,7 +551,7 @@
                         throw new IOException("Unknown type");
                 }
             case PROPERTY_SUBGRAPH:
-                InputGraph graph = parseGraph(null);
+                InputGraph graph = parseGraph("");
                 new Group(null).addElement(graph);
                 return graph;
             default:
@@ -547,6 +562,7 @@
     @Override
     public GraphDocument parse() throws IOException {
         folderStack.push(rootDocument);
+        hashStack.push(null);
         if (monitor != null) {
             monitor.setState("Starting parsing");
         }
@@ -589,6 +605,7 @@
                     });
                 }
                 folderStack.push(group);
+                hashStack.push(null);
                 if (callback != null && parent instanceof GraphDocument) {
                     callback.started(group);
                 }
@@ -599,6 +616,7 @@
                     throw new IOException("Unbalanced groups");
                 }
                 folderStack.pop();
+                hashStack.pop();
                 break;
             }
             default:
@@ -629,7 +647,17 @@
             monitor.updateProgress();
         }
         String title = readPoolObject(String.class);
-        return parseGraph(title);
+        digest.reset();
+        InputGraph graph = parseGraph(title);
+        byte[] d = digest.digest();
+        byte[] hash = hashStack.peek();
+        if (hash != null && Arrays.equals(hash, d)) {
+            graph.getProperties().setProperty("_isDuplicate", "true");
+        } else {
+            hashStack.pop();
+            hashStack.push(d);
+        }
+        return graph;
     }
 
     private InputGraph parseGraph(String title) throws IOException {
@@ -752,7 +780,7 @@
         for (Edge e : edges) {
             char fromIndex = e.input ? 1 : e.num;
             char toIndex = e.input ? e.num : 0;
-            graph.addEdge(new InputEdge(fromIndex, toIndex, e.from, e.to, e.label));
+            graph.addEdge(InputEdge.createImmutable(fromIndex, toIndex, e.from, e.to, e.label));
         }
     }
     
@@ -809,7 +837,7 @@
             m.appendReplacement(sb, result);
         }
         m.appendTail(sb);
-        return sb.toString();
+        return sb.toString().intern();
     }
     
     private static class Edge {
@@ -824,7 +852,7 @@
         public Edge(int from, int to, char num, String label, boolean input) {
             this.from = from;
             this.to = to;
-            this.label = label;
+            this.label = label != null ? label.intern() : label;
             this.num = num;
             this.input = input;
         }
--- a/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/DiagramViewModel.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/DiagramViewModel.java	Wed Mar 05 19:40:15 2014 -0800
@@ -43,6 +43,7 @@
 
     // Warning: Update setData method if fields are added
     private Group group;
+    private ArrayList<InputGraph> graphs;
     private Set<Integer> hiddenNodes;
     private Set<Integer> onScreenNodes;
     private Set<Integer> selectedNodes;
@@ -56,6 +57,7 @@
     private ChangedEvent<DiagramViewModel> hiddenNodesChangedEvent;
     private ChangedEvent<DiagramViewModel> viewPropertiesChangedEvent;
     private boolean showNodeHull;
+    private boolean hideDuplicates;
     private ChangedListener<FilterChain> filterChainChangedListener = new ChangedListener<FilterChain>() {
 
         @Override
@@ -83,6 +85,10 @@
 
         boolean groupChanged = (group == newModel.group);
         this.group = newModel.group;
+        if (groupChanged) {
+            filterGraphs();
+        }
+
         diagramChanged |= (filterChain != newModel.filterChain);
         this.filterChain = newModel.filterChain;
         diagramChanged |= (sequenceFilterChain != newModel.sequenceFilterChain);
@@ -122,11 +128,33 @@
         viewPropertiesChangedEvent.fire();
     }
 
+    public boolean getHideDuplicates() {
+        return hideDuplicates;
+    }
+
+    public void setHideDuplicates(boolean b) {
+        System.err.println("setHideDuplicates: " + b);
+        hideDuplicates = b;
+        InputGraph currentGraph = getFirstGraph();
+        if (hideDuplicates) {
+            // Back up to the unhidden equivalent graph
+            int index = graphs.indexOf(currentGraph);
+            while (graphs.get(index).getProperties().get("_isDuplicate") != null) {
+                index--;
+            }
+            currentGraph = graphs.get(index);
+        }
+        filterGraphs();
+        selectGraph(currentGraph);
+        viewPropertiesChangedEvent.fire();
+    }
+
     public DiagramViewModel(Group g, FilterChain filterChain, FilterChain sequenceFilterChain) {
-        super(calculateStringList(g));
+        super(Arrays.asList("default"));
 
         this.showNodeHull = true;
         this.group = g;
+        filterGraphs();
         assert filterChain != null;
         this.filterChain = filterChain;
         assert sequenceFilterChain != null;
@@ -165,7 +193,7 @@
         @Override
         public void changed(Group source) {
             assert source == group;
-            setPositions(calculateStringList(source));
+            filterGraphs();
             setSelectedNodes(selectedNodes);
         }
     };
@@ -211,7 +239,7 @@
                 }
                 InputNode last = null;
                 int index = 0;
-                for (InputGraph g : group.getGraphs()) {
+                for (InputGraph g : graphs) {
                     Color curColor = colors.get(index);
                     InputNode cur = g.getNode(id);
                     if (cur != null) {
@@ -316,16 +344,24 @@
         diagramChanged();
     }
 
-    private static List<String> calculateStringList(Group g) {
-        List<String> result = new ArrayList<>();
-        for (InputGraph graph : g.getGraphs()) {
-            result.add(graph.getName());
+    /*
+     * Select the set of graphs to be presented.
+     */
+    private void filterGraphs() {
+        ArrayList<InputGraph> result = new ArrayList<>();
+        List<String> positions = new ArrayList<>();
+        for (InputGraph graph : group.getGraphs()) {
+            String duplicate = graph.getProperties().get("_isDuplicate");
+            if (duplicate == null || !hideDuplicates) {
+                result.add(graph);
+                positions.add(graph.getName());
+            }
         }
-        return result;
+        this.graphs = result;
+        setPositions(positions);
     }
 
     public InputGraph getFirstGraph() {
-        List<InputGraph> graphs = group.getGraphs();
         if (getFirstPosition() < graphs.size()) {
             return graphs.get(getFirstPosition());
         }
@@ -333,7 +369,6 @@
     }
 
     public InputGraph getSecondGraph() {
-        List<InputGraph> graphs = group.getGraphs();
         if (getSecondPosition() < graphs.size()) {
             return graphs.get(getSecondPosition());
         }
@@ -341,7 +376,12 @@
     }
 
     public void selectGraph(InputGraph g) {
-        int index = group.getGraphs().indexOf(g);
+        int index = graphs.indexOf(g);
+        if (index == -1 && hideDuplicates) {
+            // A graph was selected that's currently hidden, so unhide and select it.
+            setHideDuplicates(false);
+            index = graphs.indexOf(g);
+        }
         assert index != -1;
         setPositions(index, index);
     }
--- a/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/EditorTopComponent.java	Sun Feb 23 17:00:35 2014 -0800
+++ b/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/EditorTopComponent.java	Wed Mar 05 19:40:15 2014 -0800
@@ -78,6 +78,7 @@
     private InstanceContent content;
     private InstanceContent graphContent;
     private OverviewAction overviewAction;
+    private HideDuplicatesAction hideDuplicatesAction;
     private PredSuccAction predSuccAction;
     private SelectionModeAction selectionModeAction;
     private PanModeAction panModeAction;
@@ -87,6 +88,7 @@
     private CardLayout cardLayout;
     private RangeSlider rangeSlider;
     private JToggleButton overviewButton;
+    private JToggleButton hideDuplicatesButton;
     private static final String PREFERRED_ID = "EditorTopComponent";
     private static final String SATELLITE_STRING = "satellite";
     private static final String SCENE_STRING = "scene";
@@ -207,6 +209,14 @@
 
         rangeSliderModel.getDiagramChangedEvent().addListener(diagramChangedListener);
         rangeSliderModel.selectGraph(diagram.getGraph());
+        rangeSliderModel.getViewPropertiesChangedEvent().addListener(new ChangedListener<DiagramViewModel>() {
+                @Override
+                public void changed(DiagramViewModel source) {
+                    hideDuplicatesButton.setSelected(getModel().getHideDuplicates());
+                    hideDuplicatesAction.setState(getModel().getHideDuplicates());
+                }
+            });
+
 
         toolBar.add(NextDiagramAction.get(NextDiagramAction.class));
         toolBar.add(PrevDiagramAction.get(PrevDiagramAction.class));
@@ -230,6 +240,12 @@
         toolBar.add(button);
         predSuccAction.addPropertyChangeListener(this);
 
+        hideDuplicatesAction = new HideDuplicatesAction();
+        hideDuplicatesButton = new JToggleButton(hideDuplicatesAction);
+        hideDuplicatesButton.setSelected(false);
+        toolBar.add(hideDuplicatesButton);
+        hideDuplicatesAction.addPropertyChangeListener(this);
+
         toolBar.addSeparator();
         toolBar.add(UndoAction.get(UndoAction.class));
         toolBar.add(RedoAction.get(RedoAction.class));
@@ -477,6 +493,9 @@
             } else {
                 showScene();
             }
+        } else if (evt.getSource() == this.hideDuplicatesAction) {
+            boolean b = (Boolean) hideDuplicatesAction.getValue(HideDuplicatesAction.STATE);
+            this.getModel().setHideDuplicates(b);
         } else if (evt.getSource() == this.selectionModeAction || evt.getSource() == this.panModeAction) {
             if (panModeAction.isSelected()) {
                 scene.setInteractionMode(DiagramViewer.InteractionMode.PANNING);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/HideDuplicatesAction.java	Wed Mar 05 19:40:15 2014 -0800
@@ -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.sun.hotspot.igv.view.actions;
+
+import java.awt.event.ActionEvent;
+import javax.swing.AbstractAction;
+import javax.swing.Action;
+import javax.swing.ImageIcon;
+import org.openide.util.ImageUtilities;
+
+/**
+ *
+ * @author Tom Rodriguez
+ */
+public class HideDuplicatesAction extends AbstractAction {
+
+    private boolean state;
+    public static final String STATE = "state";
+
+    public HideDuplicatesAction() {
+        putValue(AbstractAction.SMALL_ICON, new ImageIcon(ImageUtilities.loadImage(iconResource())));
+        putValue(Action.SHORT_DESCRIPTION, "Hide graphs which are the same as the previous graph");
+        setState(false);
+    }
+
+    @Override
+    public void actionPerformed(ActionEvent ev) {
+        setState(!state);
+    }
+
+    public void setState(boolean b) {
+        this.putValue(STATE, b);
+        this.state = b;
+    }
+
+    protected String iconResource() {
+        return "com/sun/hotspot/igv/view/images/hideDuplicates.png";
+    }
+}
Binary file src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/images/hideDuplicates.png has changed
--- a/src/share/vm/classfile/systemDictionary.hpp	Sun Feb 23 17:00:35 2014 -0800
+++ b/src/share/vm/classfile/systemDictionary.hpp	Wed Mar 05 19:40:15 2014 -0800
@@ -197,8 +197,6 @@
   do_klass(HotSpotInstalledCode_klass,            com_oracle_graal_hotspot_meta_HotSpotInstalledCode,           Opt) \
   do_klass(HotSpotNmethod_klass,                  com_oracle_graal_hotspot_meta_HotSpotNmethod,                 Opt) \
   do_klass(HotSpotJavaType_klass,                 com_oracle_graal_hotspot_meta_HotSpotJavaType,                Opt) \
-  do_klass(HotSpotMethodData_klass,               com_oracle_graal_hotspot_meta_HotSpotMethodData,              Opt) \
-  do_klass(HotSpotResolvedJavaField_klass,        com_oracle_graal_hotspot_meta_HotSpotResolvedJavaField,       Opt) \
   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) \
--- a/src/share/vm/classfile/vmSymbols.hpp	Sun Feb 23 17:00:35 2014 -0800
+++ b/src/share/vm/classfile/vmSymbols.hpp	Wed Mar 05 19:40:15 2014 -0800
@@ -308,8 +308,6 @@
   template(com_oracle_graal_hotspot_meta_HotSpotInstalledCode,       "com/oracle/graal/hotspot/meta/HotSpotInstalledCode")            \
   template(com_oracle_graal_hotspot_meta_HotSpotNmethod,             "com/oracle/graal/hotspot/meta/HotSpotNmethod")                  \
   template(com_oracle_graal_hotspot_meta_HotSpotJavaType,            "com/oracle/graal/hotspot/meta/HotSpotJavaType")                 \
-  template(com_oracle_graal_hotspot_meta_HotSpotMethodData,          "com/oracle/graal/hotspot/meta/HotSpotMethodData")               \
-  template(com_oracle_graal_hotspot_meta_HotSpotResolvedJavaField,   "com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField")        \
   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")             \
@@ -361,20 +359,6 @@
   template(setOption_name,                        "setOption")                                                                        \
   template(setOption_signature,                   "(Ljava/lang/String;)Z")                                                            \
   template(finalizeOptions_name,                  "finalizeOptions")                                                                  \
-  template(createUnresolvedJavaMethod_name,       "createUnresolvedJavaMethod")                                                       \
-  template(createUnresolvedJavaMethod_signature,  "(Ljava/lang/String;Ljava/lang/String;Lcom/oracle/graal/api/meta/JavaType;)Lcom/oracle/graal/api/meta/JavaMethod;") \
-  template(createSignature_name,                  "createSignature")                                                                  \
-  template(createSignature_signature,             "(Ljava/lang/String;)Lcom/oracle/graal/api/meta/Signature;")                        \
-  template(createJavaField_name,                  "createJavaField")                                                                  \
-  template(createJavaField_signature,             "(Lcom/oracle/graal/api/meta/JavaType;Ljava/lang/String;Lcom/oracle/graal/api/meta/JavaType;IIZ)Lcom/oracle/graal/api/meta/JavaField;") \
-  template(createResolvedJavaMethod_name,         "createResolvedJavaMethod")                                                         \
-  template(createResolvedJavaMethod_signature,    "(Lcom/oracle/graal/api/meta/JavaType;J)Lcom/oracle/graal/api/meta/ResolvedJavaMethod;") \
-  template(createUnresolvedJavaType_name,         "createUnresolvedJavaType")                                                         \
-  template(createUnresolvedJavaType_signature,    "(Ljava/lang/String;)Lcom/oracle/graal/api/meta/JavaType;")                         \
-  template(createResolvedJavaType_name,           "createResolvedJavaType")                                                           \
-  template(createResolvedJavaType_signature,      "(Ljava/lang/Class;)Lcom/oracle/graal/api/meta/ResolvedJavaType;") \
-  template(createPrimitiveJavaType_name,          "createPrimitiveJavaType")                                                          \
-  template(createPrimitiveJavaType_signature,     "(I)Lcom/oracle/graal/api/meta/JavaType;")                                          \
   template(getVMToCompiler_name,                  "getVMToCompiler")                                                                  \
   template(getVMToCompiler_signature,             "()Lcom/oracle/graal/hotspot/bridge/VMToCompiler;")                                 \
   template(runtime_name,                          "runtime")                                                                          \
--- a/src/share/vm/compiler/compileBroker.cpp	Sun Feb 23 17:00:35 2014 -0800
+++ b/src/share/vm/compiler/compileBroker.cpp	Wed Mar 05 19:40:15 2014 -0800
@@ -1472,6 +1472,16 @@
 
 
 // ------------------------------------------------------------------
+// CompileBroker::assign_compile_id_unlocked
+//
+// Public wrapper for assign_compile_id that acquires the needed locks
+uint CompileBroker::assign_compile_id_unlocked(Thread* thread, methodHandle method, int osr_bci) {
+  MutexLocker locker(MethodCompileQueue_lock, thread);
+  return assign_compile_id(method, osr_bci);
+}
+
+
+// ------------------------------------------------------------------
 // CompileBroker::is_compile_blocking
 //
 // Should the current thread be blocked until this compilation request
--- a/src/share/vm/compiler/compileBroker.hpp	Sun Feb 23 17:00:35 2014 -0800
+++ b/src/share/vm/compiler/compileBroker.hpp	Wed Mar 05 19:40:15 2014 -0800
@@ -321,6 +321,7 @@
   static void init_compiler_threads(int c1_compiler_count, int c2_compiler_count);
   static bool compilation_is_complete  (methodHandle method, int osr_bci, int comp_level);
   static bool compilation_is_prohibited(methodHandle method, int osr_bci, int comp_level);
+  static uint assign_compile_id        (methodHandle method, int osr_bci);
   static bool is_compile_blocking      (methodHandle method, int osr_bci);
   static void preload_classes          (methodHandle method, TRAPS);
 
@@ -385,7 +386,8 @@
                                  int hot_count,
                                  const char* comment, Thread* thread);
 
-  static uint assign_compile_id        (methodHandle method, int osr_bci);
+  // Acquire any needed locks and assign a compile id
+  static uint assign_compile_id_unlocked(Thread* thread, methodHandle method, int osr_bci);
 
   static void compiler_thread_loop();
   static uint get_compilation_id() { return _compilation_id; }
--- a/src/share/vm/gc_implementation/g1/vmStructs_g1.hpp	Sun Feb 23 17:00:35 2014 -0800
+++ b/src/share/vm/gc_implementation/g1/vmStructs_g1.hpp	Wed Mar 05 19:40:15 2014 -0800
@@ -68,6 +68,7 @@
                                                                               \
   declare_type(G1CollectedHeap, SharedHeap)                                   \
                                                                               \
+  declare_type(G1OffsetTableContigSpace, ContiguousSpace)                     \
   declare_type(HeapRegion, ContiguousSpace)                                   \
   declare_toplevel_type(HeapRegionSeq)                                        \
   declare_toplevel_type(HeapRegionSetBase)                                    \
--- a/src/share/vm/graal/graalCodeInstaller.cpp	Sun Feb 23 17:00:35 2014 -0800
+++ b/src/share/vm/graal/graalCodeInstaller.cpp	Wed Mar 05 19:40:15 2014 -0800
@@ -22,6 +22,7 @@
  */
 
 #include "precompiled.hpp"
+#include "compiler/compileBroker.hpp"
 #include "compiler/disassembler.hpp"
 #include "runtime/javaCalls.hpp"
 #include "graal/graalEnv.hpp"
@@ -419,6 +420,10 @@
     methodHandle method = getMethodFromHotSpotMethod(HotSpotCompiledNmethod::method(compiled_code));
     jint entry_bci = HotSpotCompiledNmethod::entryBCI(compiled_code);
     jint id = HotSpotCompiledNmethod::id(compiled_code);
+    if (id == -1) {
+      // Make sure a valid compile_id is associated with every compile
+      id = CompileBroker::assign_compile_id_unlocked(Thread::current(), method, entry_bci);
+    }
     result = GraalEnv::register_method(method, nm, entry_bci, &_offsets, _custom_stack_area_offset, &buffer, stack_slots, _debug_recorder->_oopmaps, &_exception_handler_table,
         GraalCompiler::instance(), _debug_recorder, _dependencies, NULL, id, false, leaf_graph_ids, installed_code, speculation_log);
     cb = nm;
@@ -803,7 +808,6 @@
 
 void CodeInstaller::site_Mark(CodeBuffer& buffer, jint pc_offset, oop site) {
   oop id_obj = CompilationResult_Mark::id(site);
-  arrayOop references = (arrayOop) CompilationResult_Mark::references(site);
 
   if (id_obj != NULL) {
     assert(java_lang_boxing_object::is_instance(id_obj, T_INT), "Integer id expected");
--- a/src/share/vm/graal/graalCompiler.cpp	Sun Feb 23 17:00:35 2014 -0800
+++ b/src/share/vm/graal/graalCompiler.cpp	Wed Mar 05 19:40:15 2014 -0800
@@ -28,7 +28,6 @@
 #include "graal/graalJavaAccess.hpp"
 #include "graal/graalVMToCompiler.hpp"
 #include "graal/graalCompilerToVM.hpp"
-#include "graal/graalCompilerToGPU.hpp"
 #include "graal/graalEnv.hpp"
 #include "graal/graalRuntime.hpp"
 #include "runtime/arguments.hpp"
@@ -72,13 +71,6 @@
   }
   env->RegisterNatives(klass, CompilerToVM_methods, CompilerToVM_methods_count());
   
-  klass = env->FindClass("com/oracle/graal/hotspot/bridge/CompilerToGPUImpl");
-  if (klass == NULL) {
-    tty->print_cr("graal CompilerToGPUImpl class not found");
-    vm_abort(false);
-  }
-  env->RegisterNatives(klass, CompilerToGPU_methods, CompilerToGPU_methods_count());
-
   ResourceMark rm;
   HandleMark hm;
   {
@@ -219,30 +211,21 @@
   TRACE_graal_1("GraalCompiler::print_timers");
 }
 
-Handle GraalCompiler::get_JavaTypeFromSignature(Symbol* signature, KlassHandle loading_klass, TRAPS) {
+KlassHandle GraalCompiler::get_KlassFromSignature(Symbol* signature, KlassHandle loading_klass) {
   BasicType field_type = FieldType::basic_type(signature);
-  // If the field is a pointer type, get the klass of the
-  // field.
+  // If the field is a pointer type, get the klass of the field.
   if (field_type == T_OBJECT || field_type == T_ARRAY) {
-    KlassHandle klass = GraalEnv::get_klass_by_name(loading_klass, signature, false);
-    if (klass.is_null()) {
-      Handle signature_string = java_lang_String::create_from_symbol(signature, CHECK_NH);
-      return VMToCompiler::createUnresolvedJavaType(signature_string, CHECK_NH);
-    } else {
-      return VMToCompiler::createResolvedJavaType(klass->java_mirror(), CHECK_NH);
-    }
-  } else {
-    return VMToCompiler::createPrimitiveJavaType(field_type, CHECK_NH);
+    return GraalEnv::get_klass_by_name(loading_klass, signature, false);
   }
+  return NULL;
 }
 
-Handle GraalCompiler::get_JavaType(constantPoolHandle cp, int index, KlassHandle loading_klass, TRAPS) {
+KlassHandle GraalCompiler::get_Klass(constantPoolHandle cp, int index, KlassHandle loading_klass, Symbol*& klass_name) {
   bool is_accessible = false;
 
   KlassHandle klass = GraalEnv::get_klass_by_index(cp, index, is_accessible, loading_klass);
-  oop catch_class = NULL;
   if (klass.is_null()) {
-    Symbol* klass_name = NULL;
+    klass_name = NULL;
     {
       // We have to lock the cpool to keep the oop from being resolved
       // while we are accessing it. But we must release the lock before
@@ -252,7 +235,9 @@
       if (tag.is_klass()) {
         // The klass has been inserted into the constant pool
         // very recently.
-        return VMToCompiler::createResolvedJavaType(cp->resolved_klass_at(index)->java_mirror(), CHECK_NH);
+        klass = cp->resolved_klass_at(index);
+        klass_name = klass->name();
+        return klass;
       } else if (tag.is_symbol()) {
         klass_name = cp->symbol_at(index);
       } else {
@@ -260,16 +245,10 @@
         klass_name = cp->unresolved_klass_at(index);
       }
     }
-    Handle klass_name_string = java_lang_String::create_from_symbol(klass_name, CHECK_NH);
-    return VMToCompiler::createUnresolvedJavaType(klass_name_string, CHECK_NH);
   } else {
-    return VMToCompiler::createResolvedJavaType(klass->java_mirror(), CHECK_NH);
+    klass_name = klass->name();
   }
-}
-
-Handle GraalCompiler::get_JavaField(int offset, int flags, Symbol* field_name, Handle field_holder, Handle field_type, TRAPS) {
-  Handle name = java_lang_String::create_from_symbol(field_name, CHECK_NH);
-  return VMToCompiler::createJavaField(field_holder, name, field_type, offset, flags, false, CHECK_NH);
+  return klass;
 }
 
 BasicType GraalCompiler::kindToBasicType(jchar ch) {
--- a/src/share/vm/graal/graalCompiler.hpp	Sun Feb 23 17:00:35 2014 -0800
+++ b/src/share/vm/graal/graalCompiler.hpp	Wed Mar 05 19:40:15 2014 -0800
@@ -71,34 +71,13 @@
   // Print compilation timers and statistics
   virtual void print_timers();
 
-  static Handle get_JavaTypeFromSignature(Symbol* signature, KlassHandle accessor, TRAPS);
-  static Handle get_JavaType(constantPoolHandle cp, int index, KlassHandle accessor, TRAPS);
-  static Handle get_JavaField(int offset, int flags, Symbol* field_name, Handle field_holder, Handle field_type, TRAPS);
+  static KlassHandle get_KlassFromSignature(Symbol* signature, KlassHandle loading_klass);
+  static KlassHandle get_Klass(constantPoolHandle cp, int index, KlassHandle accessor, Symbol*& klass_name);
 
   void exit();
 
   static BasicType kindToBasicType(jchar ch);
 
-  static int to_cp_index_u2(int index) {
-    // Tag.
-    return index + ConstantPool::CPCACHE_INDEX_TAG;
-  }
-
-  static int to_cp_index(int raw_index, Bytecodes::Code bc) {
-    int cp_index;
-    if (bc == Bytecodes::_invokedynamic) {
-      cp_index = raw_index;
-      assert(ConstantPool::is_invokedynamic_index(cp_index), "not an invokedynamic constant pool index");
-    } else {
-      assert(bc == Bytecodes::_getfield        || bc == Bytecodes::_putfield  ||
-             bc == Bytecodes::_getstatic       || bc == Bytecodes::_putstatic ||
-             bc == Bytecodes::_invokeinterface || bc == Bytecodes::_invokevirtual ||
-             bc == Bytecodes::_invokespecial   || bc == Bytecodes::_invokestatic, err_msg("unexpected invoke opcode: %d %s", bc, Bytecodes::name(bc)));
-      cp_index = to_cp_index_u2(raw_index);
-    }
-    return cp_index;
-  }
-
   static BufferBlob* initialize_buffer_blob();
 };
 
--- a/src/share/vm/graal/graalCompilerToGPU.cpp	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,269 +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.
- */
-
-#include "precompiled.hpp"
-
-#include "memory/oopFactory.hpp"
-#include "graal/graalCompiler.hpp"
-#include "graal/graalEnv.hpp"
-#include "graal/graalJavaAccess.hpp"
-#include "runtime/gpu.hpp"
-#include "runtime/javaCalls.hpp"
-# include "ptx/vm/ptxKernelArguments.hpp"
-
-// Entry to native method implementation that transitions current thread to '_thread_in_vm'.
-#define C2V_VMENTRY(result_type, name, signature) \
-  JNIEXPORT result_type JNICALL c2v_ ## name signature { \
-  TRACE_graal_3("CompilerToGPU::" #name); \
-  GRAAL_VM_ENTRY_MARK; \
-
-// Entry to native method implementation that calls a JNI function
-// and hence cannot transition current thread to '_thread_in_vm'.
-#define C2V_ENTRY(result_type, name, signature) \
-  JNIEXPORT result_type JNICALL c2v_ ## name signature { \
-  TRACE_graal_3("CompilerToGPU::" #name); \
-
-#define C2V_END }
-
-
-C2V_ENTRY(jlong, generateKernel, (JNIEnv *env, jobject, jbyteArray code, jstring name))
-  if (gpu::is_available() == false || gpu::has_gpu_linkage() == false && gpu::is_initialized()) {
-    if (TraceGPUInteraction) {
-      tty->print_cr("generateKernel - not available / no linkage / not initialized");
-    }
-    return 0;
-  }
-  jboolean is_copy;
-  jbyte *bytes = env->GetByteArrayElements(code, &is_copy);
-  jint len = env->GetArrayLength(code);
-  const char *namestr = env->GetStringUTFChars(name, &is_copy);
-  void *kernel = gpu::generate_kernel((unsigned char *)bytes, len, namestr);
-  if (kernel == NULL) {
-    tty->print_cr("[CUDA] *** Error: Failed to compile kernel");
-  } else if (TraceGPUInteraction) {
-    tty->print_cr("[CUDA] Generated kernel");
-  }
-  env->ReleaseByteArrayElements(code, bytes, 0);
-  env->ReleaseStringUTFChars(name, namestr);
-
-  return (jlong)kernel;
-C2V_END
-
-C2V_VMENTRY(jobject, executeExternalMethodVarargs, (JNIEnv *env, jobject, jobject args, jobject hotspotInstalledCode))
-  ResourceMark rm;
-  HandleMark hm;
-
-  if (gpu::is_available() == false || gpu::has_gpu_linkage() == false && gpu::is_initialized()) {
-    tty->print_cr("executeExternalMethodVarargs - not available / no linkage / not initialized");
-    return NULL;
-  }
-  jlong nmethodValue = HotSpotInstalledCode::codeBlob(hotspotInstalledCode);
-  nmethod* nm = (nmethod*) (address) nmethodValue;
-  methodHandle mh = nm->method();
-  Symbol* signature = mh->signature();
-
-  // start value is the kernel
-  jlong startValue = HotSpotInstalledCode::codeStart(hotspotInstalledCode);
-
-  PTXKernelArguments ptxka(signature, (arrayOop) JNIHandles::resolve(args), mh->is_static());
-  JavaValue result(ptxka.get_ret_type());
-  if (!gpu::execute_kernel((address)startValue, ptxka, result)) {
-    return NULL;
-  }
-
-  if (ptxka.get_ret_type() == T_VOID) {
-    return NULL;
-  } else if (ptxka.get_ret_type() == T_OBJECT || ptxka.get_ret_type() == T_ARRAY) {
-    return JNIHandles::make_local((oop) result.get_jobject());
-  } else {
-    oop o = java_lang_boxing_object::create(ptxka.get_ret_type(), (jvalue *) result.get_value_addr(), CHECK_NULL);
-    if (TraceGPUInteraction) {
-      switch (ptxka.get_ret_type()) {
-        case T_INT:
-          tty->print_cr("GPU execution returned (int) %d", result.get_jint());
-          break;
-        case T_LONG:
-          tty->print_cr("GPU execution returned (long) %ld", result.get_jlong());
-          break;
-        case T_FLOAT:
-          tty->print_cr("GPU execution returned (float) %f", result.get_jfloat());
-          break;
-        case T_DOUBLE:
-          tty->print_cr("GPU execution returned (double) %f", result.get_jdouble());
-          break;
-        default:
-          tty->print_cr("**** Value returned by GPU not yet handled");
-          break;
-        }
-    }
-    return JNIHandles::make_local(o);
-  }
-C2V_END
-
-C2V_VMENTRY(jobject, executeParallelMethodVarargs, (JNIEnv *env,
-                                                          jobject,
-                                                          jint dimX, jint dimY, jint dimZ,
-                                                          jobject args, jobject hotspotInstalledCode))
-  ResourceMark rm;
-  HandleMark hm;
-
-  if (gpu::is_available() == false || gpu::has_gpu_linkage() == false && gpu::is_initialized()) {
-    tty->print_cr("executeParallelMethodVarargs - not available / no linkage / not initialized");
-    return NULL;
-  }
-  jlong nmethodValue = HotSpotInstalledCode::codeBlob(hotspotInstalledCode);
-  nmethod* nm = (nmethod*) (address) nmethodValue;
-  methodHandle mh = nm->method();
-  Symbol* signature = mh->signature();
-
-  // start value is the kernel
-  jlong startValue = HotSpotInstalledCode::codeStart(hotspotInstalledCode);
-
-  if (UseHSAILSimulator) {
-    gpu::execute_kernel_void_1d((address)startValue, dimX, args, mh);
-    return NULL;
-  }
-
-  PTXKernelArguments ptxka(signature, (arrayOop) JNIHandles::resolve(args), mh->is_static());
-  JavaValue result(ptxka.get_ret_type());
-  if (!gpu::execute_warp(dimX, dimY, dimZ, (address) startValue, ptxka, result)) {
-    return NULL;
-  }
-
-  if (ptxka.get_ret_type() == T_VOID) {
-    return NULL;
-  } else if (ptxka.get_ret_type() == T_OBJECT || ptxka.get_ret_type() == T_ARRAY) {
-    return JNIHandles::make_local((oop) result.get_jobject());
-  } else {
-    oop o = java_lang_boxing_object::create(ptxka.get_ret_type(), (jvalue *) result.get_value_addr(), CHECK_NULL);
-    if (TraceGPUInteraction) {
-      switch (ptxka.get_ret_type()) {
-        case T_INT:
-          tty->print_cr("GPU execution returned %d", result.get_jint());
-          break;
-        case T_FLOAT:
-          tty->print_cr("GPU execution returned %f", result.get_jfloat());
-          break;
-        case T_DOUBLE:
-          tty->print_cr("GPU execution returned %g", result.get_jdouble());
-          break;
-        default:
-          tty->print_cr("GPU returned unhandled");
-          break;
-      }
-    }
-    return JNIHandles::make_local(o);
-  }
-C2V_END
-
-JRT_ENTRY(jlong, invalidLaunchKernel(JavaThread* thread))
-  SharedRuntime::throw_and_post_jvmti_exception(thread, vmSymbols::java_lang_LinkageError(), "invalid kernel launch function");
-  return 0L;
-JRT_END
-
-C2V_VMENTRY(jlong, getLaunchKernelAddress, (JNIEnv *env, jobject))
-  if (gpu::get_target_il_type() == gpu::PTX) {
-    return (jlong) gpu::Ptx::execute_kernel_from_vm;
-  }
-  return (jlong) invalidLaunchKernel;
-C2V_END
-
-C2V_VMENTRY(jboolean, deviceInit, (JNIEnv *env, jobject))
-  if (gpu::is_available() == false || gpu::has_gpu_linkage() == false) {
-    if (TraceGPUInteraction) {
-      tty->print_cr("deviceInit - not available / no linkage");
-    }
-    return false;
-  }
-  if (gpu::is_initialized()) {
-    tty->print_cr("deviceInit - already initialized");
-    return true;
-  }
-  gpu::initialize_gpu();
-  return gpu::is_initialized();
-C2V_END
-
-C2V_VMENTRY(jint, availableProcessors, (JNIEnv *env, jobject))
-  if (gpu::is_available() == false || gpu::has_gpu_linkage() == false) {
-    if (TraceGPUInteraction) {
-      tty->print_cr("deviceInit - not available / no linkage");
-    }
-    return false;
-  }
-  return gpu::available_processors();
-C2V_END
-
-C2V_VMENTRY(jboolean, deviceDetach, (JNIEnv *env, jobject))
-return true;
-C2V_END
-
-
-#define CC (char*)  /*cast a literal from (const char*)*/
-#define FN_PTR(f) CAST_FROM_FN_PTR(void*, &(c2v_ ## f))
-
-#define RESOLVED_TYPE         "Lcom/oracle/graal/api/meta/ResolvedJavaType;"
-#define TYPE                  "Lcom/oracle/graal/api/meta/JavaType;"
-#define METHOD                "Lcom/oracle/graal/api/meta/JavaMethod;"
-#define FIELD                 "Lcom/oracle/graal/api/meta/JavaField;"
-#define SIGNATURE             "Lcom/oracle/graal/api/meta/Signature;"
-#define CONSTANT_POOL         "Lcom/oracle/graal/api/meta/ConstantPool;"
-#define CONSTANT              "Lcom/oracle/graal/api/meta/Constant;"
-#define KIND                  "Lcom/oracle/graal/api/meta/Kind;"
-#define LOCAL                 "Lcom/oracle/graal/api/meta/Local;"
-#define RUNTIME_CALL          "Lcom/oracle/graal/api/code/RuntimeCall;"
-#define EXCEPTION_HANDLERS    "[Lcom/oracle/graal/api/meta/ExceptionHandler;"
-#define REFLECT_METHOD        "Ljava/lang/reflect/Method;"
-#define REFLECT_CONSTRUCTOR   "Ljava/lang/reflect/Constructor;"
-#define REFLECT_FIELD         "Ljava/lang/reflect/Field;"
-#define STRING                "Ljava/lang/String;"
-#define OBJECT                "Ljava/lang/Object;"
-#define CLASS                 "Ljava/lang/Class;"
-#define STACK_TRACE_ELEMENT   "Ljava/lang/StackTraceElement;"
-#define HS_RESOLVED_TYPE      "Lcom/oracle/graal/hotspot/meta/HotSpotResolvedObjectType;"
-#define HS_RESOLVED_JAVA_TYPE "Lcom/oracle/graal/hotspot/meta/HotSpotResolvedJavaType;"
-#define HS_RESOLVED_METHOD    "Lcom/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod;"
-#define HS_RESOLVED_FIELD     "Lcom/oracle/graal/hotspot/meta/HotSpotResolvedJavaField;"
-#define HS_COMPILED_CODE      "Lcom/oracle/graal/hotspot/HotSpotCompiledCode;"
-#define HS_CONFIG             "Lcom/oracle/graal/hotspot/HotSpotVMConfig;"
-#define HS_METHOD             "Lcom/oracle/graal/hotspot/meta/HotSpotMethod;"
-#define HS_INSTALLED_CODE     "Lcom/oracle/graal/hotspot/meta/HotSpotInstalledCode;"
-#define METHOD_DATA           "Lcom/oracle/graal/hotspot/meta/HotSpotMethodData;"
-#define METASPACE_METHOD      "J"
-#define METASPACE_METHOD_DATA "J"
-#define NMETHOD               "J"
-#define GPUSPACE_METHOD       "J"
-
-JNINativeMethod CompilerToGPU_methods[] = {
-  {CC"generateKernel",                CC"([B" STRING ")"GPUSPACE_METHOD,          FN_PTR(generateKernel)},
-  {CC"deviceInit",                    CC"()Z",                                    FN_PTR(deviceInit)},
-  {CC"deviceDetach",                  CC"()Z",                                    FN_PTR(deviceDetach)},
-  {CC"availableProcessors",           CC"()I",                                    FN_PTR(availableProcessors)},
-  {CC"executeExternalMethodVarargs",  CC"(["OBJECT HS_INSTALLED_CODE")"OBJECT,    FN_PTR(executeExternalMethodVarargs)},
-  {CC"executeParallelMethodVarargs",  CC"(III["OBJECT HS_INSTALLED_CODE")"OBJECT, FN_PTR(executeParallelMethodVarargs)},
-  {CC"getLaunchKernelAddress",        CC"()J",                                    FN_PTR(getLaunchKernelAddress)},
-};
-
-int CompilerToGPU_methods_count() {
-  return sizeof(CompilerToGPU_methods) / sizeof(JNINativeMethod);
-}
-
--- a/src/share/vm/graal/graalCompilerToGPU.hpp	Sun Feb 23 17:00:35 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +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.
- */
-
-#ifndef SHARE_VM_GRAAL_GRAAL_COMPILER_TO_GPU_HPP
-#define SHARE_VM_GRAAL_GRAAL_COMPILER_TO_GPU_HPP
-
-#include "prims/jni.h"
-
-extern JNINativeMethod CompilerToGPU_methods[];
-int CompilerToGPU_methods_count();
-
-
-#endif // SHARE_VM_GRAAL_GRAAL_COMPILER_TO_GPU_HPP
--- a/src/share/vm/graal/graalCompilerToVM.cpp	Sun Feb 23 17:00:35 2014 -0800
+++ b/src/share/vm/graal/graalCompilerToVM.cpp	Wed Mar 05 19:40:15 2014 -0800
@@ -40,6 +40,7 @@
 #include "gc_implementation/g1/heapRegion.hpp"
 #include "runtime/javaCalls.hpp"
 #include "runtime/vmStructs.hpp"
+#include "runtime/gpu.hpp"
 
 
 Method* getMethodFromHotSpotMethod(oop hotspot_method) {
@@ -196,9 +197,14 @@
   HotSpotResolvedJavaMethod::set_ignoredBySecurityStackWalk(hotspot_method, method->is_ignored_by_security_stack_walk());
 C2V_END
 
-C2V_VMENTRY(jboolean, isMethodCompilable,(JNIEnv *, jobject, jlong metaspace_method))
+C2V_VMENTRY(jboolean, canInlineMethod,(JNIEnv *, jobject, jlong metaspace_method))
   methodHandle method = asMethod(metaspace_method);
-  return !method->is_not_compilable() && !CompilerOracle::should_not_inline(method);
+  return !method->is_not_compilable() && !CompilerOracle::should_not_inline(method) && !method->dont_inline();
+C2V_END
+
+C2V_VMENTRY(jboolean, shouldInlineMethod,(JNIEnv *, jobject, jlong metaspace_method))
+  methodHandle method = asMethod(metaspace_method);
+  return CompilerOracle::should_inline(method) || method->force_inline();
 C2V_END
 
 C2V_ENTRY(jint, getCompiledCodeSize, (JNIEnv *env, jobject, jlong metaspace_method))
@@ -251,53 +257,57 @@
   return JNIHandles::make_local(THREAD, result);
 C2V_END
 
-C2V_VMENTRY(jobject, lookupAppendixInPool, (JNIEnv *env, jobject, jlong metaspace_constant_pool, jint index, jbyte opcode))
-  Bytecodes::Code bc = (Bytecodes::Code) (((int) opcode) & 0xFF);
-  index = GraalCompiler::to_cp_index(index, bc);
+C2V_VMENTRY(jobject, lookupAppendixInPool, (JNIEnv *env, jobject, jlong metaspace_constant_pool, jint index))
   constantPoolHandle cp = (ConstantPool*) metaspace_constant_pool;
   oop appendix_oop = ConstantPool::appendix_at_if_loaded(cp, index);
   return JNIHandles::make_local(THREAD, appendix_oop);
 C2V_END
 
-C2V_VMENTRY(jobject, lookupMethodInPool, (JNIEnv *env, jobject, jlong metaspace_constant_pool, jint index, jbyte opcode))
+C2V_VMENTRY(jlong, lookupMethodInPool, (JNIEnv *env, jobject, jlong metaspace_constant_pool, jint index, jbyte opcode, jlongArray unresolvedInfo_handle))
   constantPoolHandle cp = (ConstantPool*) metaspace_constant_pool;
   instanceKlassHandle pool_holder(cp->pool_holder());
 
   Bytecodes::Code bc = (Bytecodes::Code) (((int) opcode) & 0xFF);
-  int cp_index = GraalCompiler::to_cp_index(index, bc);
 
-  methodHandle method = GraalEnv::get_method_by_index(cp, cp_index, bc, pool_holder);
+  methodHandle method = GraalEnv::get_method_by_index(cp, index, bc, pool_holder);
   if (!method.is_null()) {
-    Handle holder = VMToCompiler::createResolvedJavaType(method->method_holder()->java_mirror(), CHECK_NULL);
-    return JNIHandles::make_local(THREAD, VMToCompiler::createResolvedJavaMethod(holder, method(), THREAD));
+    return (jlong) method();
   } else {
-    // Get the method's name and signature.
-    Handle name = java_lang_String::create_from_symbol(cp->name_ref_at(cp_index), CHECK_NULL);
-    Handle signature  = java_lang_String::create_from_symbol(cp->signature_ref_at(cp_index), CHECK_NULL);
+    // Get the unresolved method's name and signature.
+    typeArrayOop unresolvedInfo = (typeArrayOop) JNIHandles::resolve(unresolvedInfo_handle);
+    assert(unresolvedInfo != NULL && unresolvedInfo->length() == 4, "must be");
+    unresolvedInfo->long_at_put(0, (jlong) cp->name_ref_at(index));
+    unresolvedInfo->long_at_put(1, (jlong) cp->signature_ref_at(index));
     Handle type;
     if (bc != Bytecodes::_invokedynamic) {
-      int holder_index = cp->klass_ref_index_at(cp_index);
-      type = GraalCompiler::get_JavaType(cp, holder_index, cp->pool_holder(), CHECK_NULL);
+      int holder_index = cp->klass_ref_index_at(index);
+      Symbol* klass_name = NULL;
+      KlassHandle klass = GraalCompiler::get_Klass(cp, holder_index, cp->pool_holder(), klass_name);
+      unresolvedInfo->long_at_put(2, (jlong) klass_name);
+      unresolvedInfo->long_at_put(3, (jlong) klass());
     } else {
-      type = Handle(SystemDictionary::MethodHandle_klass()->java_mirror());
+      unresolvedInfo->long_at_put(3, (jlong) SystemDictionary::MethodHandle_klass());
     }
-    return JNIHandles::make_local(THREAD, VMToCompiler::createUnresolvedJavaMethod(name, signature, type, THREAD));
+    return 0L;
   }
 C2V_END
 
-C2V_VMENTRY(jobject, lookupTypeInPool, (JNIEnv *env, jobject, jlong metaspace_constant_pool, jint index))
+C2V_VMENTRY(jlong, lookupTypeInPool, (JNIEnv *env, jobject, jlong metaspace_constant_pool, jint index, jlongArray unresolvedTypeName_handle))
   ConstantPool* cp = (ConstantPool*) metaspace_constant_pool;
-  Handle result = GraalCompiler::get_JavaType(cp, index, cp->pool_holder(), CHECK_NULL);
-  return JNIHandles::make_local(THREAD, result());
+  Symbol* klass_name = NULL;
+  KlassHandle klass = GraalCompiler::get_Klass(cp, index, cp->pool_holder(), klass_name);
+  typeArrayOop unresolvedTypeName = (typeArrayOop) JNIHandles::resolve(unresolvedTypeName_handle);
+  unresolvedTypeName->long_at_put(0, (jlong) klass_name);
+  return (jlong) klass();
 C2V_END
 
-C2V_VMENTRY(void, lookupReferencedTypeInPool, (JNIEnv *env, jobject, jlong metaspace_constant_pool, jint index, jbyte op))
+C2V_VMENTRY(void, loadReferencedTypeInPool, (JNIEnv *env, jobject, jlong metaspace_constant_pool, jint index, jbyte op))
   ConstantPool* cp = (ConstantPool*) metaspace_constant_pool;
   Bytecodes::Code bc = (Bytecodes::Code) (((int) op) & 0xFF);
   if (bc != Bytecodes::_checkcast && bc != Bytecodes::_instanceof && bc != Bytecodes::_new && bc != Bytecodes::_anewarray
       && bc != Bytecodes::_multianewarray && bc != Bytecodes::_ldc && bc != Bytecodes::_ldc_w && bc != Bytecodes::_ldc2_w)
   {
-    index = cp->remap_instruction_operand_from_cache(GraalCompiler::to_cp_index(index, bc));
+    index = cp->remap_instruction_operand_from_cache(index);
   }
   constantTag tag = cp->tag_at(index);
   if (tag.is_field_or_method()) {
@@ -313,42 +323,44 @@
   }
 C2V_END
 
-C2V_VMENTRY(jobject, lookupFieldInPool, (JNIEnv *env, jobject, jlong metaspace_constant_pool, jint index, jbyte opcode))
+C2V_VMENTRY(jboolean, lookupFieldInPool, (JNIEnv *env, jobject, jlong metaspace_constant_pool, jint index, jbyte opcode, jlongArray info_handle))
   ResourceMark rm;
 
-  int cp_index = GraalCompiler::to_cp_index_u2(index);
   constantPoolHandle cp = (ConstantPool*) metaspace_constant_pool;
 
-  int nt_index = cp->name_and_type_ref_index_at(cp_index);
-  int sig_index = cp->signature_ref_index_at(nt_index);
-  Symbol* signature = cp->symbol_at(sig_index);
+  int nt_index = cp->name_and_type_ref_index_at(index);
+  int type_index = cp->signature_ref_index_at(nt_index);
+  Symbol* type_name = cp->symbol_at(type_index);
   int name_index = cp->name_ref_index_at(nt_index);
   Symbol* name = cp->symbol_at(name_index);
-  int holder_index = cp->klass_ref_index_at(cp_index);
-  Handle holder = GraalCompiler::get_JavaType(cp, holder_index, cp->pool_holder(), CHECK_NULL);
-  instanceKlassHandle holder_klass;
+  int holder_index = cp->klass_ref_index_at(index);
+  Symbol* holder_name = NULL;
+  KlassHandle holder = GraalCompiler::get_Klass(cp, holder_index, cp->pool_holder(), holder_name);
+  KlassHandle type = GraalCompiler::get_KlassFromSignature(type_name, cp->pool_holder());
+  typeArrayOop info = (typeArrayOop) JNIHandles::resolve(info_handle);
+  assert(info != NULL && info->length() == 7, "must be");
+  info->long_at_put(0, (jlong) name);
+  info->long_at_put(1, (jlong) type_name);
+  info->long_at_put(2, (jlong) type());
+  info->long_at_put(3, (jlong) holder_name);
+  info->long_at_put(4, (jlong) holder());
 
   Bytecodes::Code code = (Bytecodes::Code)(((int) opcode) & 0xFF);
-  int offset = -1;
-  AccessFlags flags;
-  if (holder->klass() == SystemDictionary::HotSpotResolvedObjectType_klass()) {
+  if (!holder.is_null()) {
+    int offset = -1;
     fieldDescriptor result;
-    LinkResolver::resolve_field_access(result, cp, cp_index, Bytecodes::java_code(code), true, false, Thread::current());
+    LinkResolver::resolve_field_access(result, cp, index, Bytecodes::java_code(code), true, false, Thread::current());
 
     if (HAS_PENDING_EXCEPTION) {
       CLEAR_PENDING_EXCEPTION;
     } else {
-      offset = result.offset();
-      flags = result.access_flags();
-      holder_klass = result.field_holder();
-      holder = VMToCompiler::createResolvedJavaType(holder_klass->java_mirror(), CHECK_NULL);
+      info->long_at_put(4, (jlong) result.field_holder());
+      info->long_at_put(5, (jlong) result.access_flags().as_int());
+      info->long_at_put(6, (jlong) result.offset());
+      return true;
     }
   }
-
-  Handle type = GraalCompiler::get_JavaTypeFromSignature(signature, cp->pool_holder(), CHECK_NULL);
-  Handle field_handle = GraalCompiler::get_JavaField(offset, flags.as_int(), name, holder, type, THREAD);
-
-  return JNIHandles::make_local(THREAD, field_handle());
+  return false;
 C2V_END
 
 C2V_VMENTRY(jlong, resolveMethod, (JNIEnv *, jobject, jobject resolved_type, jstring name, jstring signature))
@@ -373,29 +385,6 @@
   return Dependencies::find_finalizable_subclass(klass) != NULL;
 C2V_END
 
-C2V_VMENTRY(jobject, getInstanceFields, (JNIEnv *, jobject, jobject klass))
-  ResourceMark rm;
-
-  instanceKlassHandle k = java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaClass(klass));
-  GrowableArray<Handle> fields(k->java_fields_count());
-
-  for (AllFieldStream fs(k()); !fs.done(); fs.next()) {
-    if (!fs.access_flags().is_static()) {
-      Handle type = GraalCompiler::get_JavaTypeFromSignature(fs.signature(), k, THREAD);
-      int flags = fs.access_flags().as_int();
-      bool internal = fs.access_flags().is_internal();
-      Handle name = java_lang_String::create_from_symbol(fs.name(), THREAD);
-      Handle field = VMToCompiler::createJavaField(JNIHandles::resolve(klass), name, type, fs.offset(), flags, internal, THREAD);
-      fields.append(field());
-    }
-  }
-  objArrayHandle field_array = oopFactory::new_objArray(SystemDictionary::HotSpotResolvedJavaField_klass(), fields.length(), CHECK_NULL);
-  for (int i = 0; i < fields.length(); ++i) {
-    field_array->obj_at_put(i, fields.at(i)());
-  }
-  return JNIHandles::make_local(THREAD, field_array());
-C2V_END
-
 C2V_VMENTRY(jlong, getClassInitializer, (JNIEnv *, jobject, jobject klass))
   instanceKlassHandle k(THREAD, java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaClass(klass)));
   Method* clinit = k->class_initializer();
@@ -553,7 +542,15 @@
   //------------------------------------------------------------------------------------------------
 
   set_int("graalCountersThreadOffset", in_bytes(JavaThread::graal_counters_offset()));
-  set_int("graalCountersSize", (jint) GRAAL_COUNTERS_SIZE);
+  set_int("graalCountersSize", (jint) GraalCounterSize);
+
+  //------------------------------------------------------------------------------------------------
+
+  set_long("dllLoad", (jlong) os::dll_load);
+  set_long("dllLookup", (jlong) os::dll_lookup);
+  #if defined(TARGET_OS_FAMILY_bsd) || defined(TARGET_OS_FAMILY_linux)
+  set_long("rtldDefault", (jlong) RTLD_DEFAULT);
+  #endif
 
 #undef set_boolean
 #undef set_int
@@ -669,6 +666,9 @@
   } else {
     Disassembler::decode(cb, &st);
   }
+  if (st.size() <= 0) {
+    return NULL;
+  }
 
   Handle result = java_lang_String::create_from_platform_dependent_str(st.as_string(), CHECK_NULL);
   return JNIHandles::make_local(result());
@@ -813,20 +813,32 @@
 C2V_END
 
 C2V_VMENTRY(jlongArray, collectCounters, (JNIEnv *env, jobject))
-  typeArrayOop arrayOop = oopFactory::new_longArray(GRAAL_COUNTERS_SIZE, CHECK_NULL);
+  typeArrayOop arrayOop = oopFactory::new_longArray(GraalCounterSize, CHECK_NULL);
   JavaThread::collect_counters(arrayOop);
   return (jlongArray) JNIHandles::make_local(arrayOop);
 C2V_END
 
+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);
+#else
+  return env->NewStringUTF("");
+#endif
+C2V_END
+
 C2V_VMENTRY(int, allocateCompileId, (JNIEnv *env, jobject, jobject hotspot_method, int entry_bci))
   HandleMark hm;
   ResourceMark rm;
   Method* method = getMethodFromHotSpotMethod(JNIHandles::resolve(hotspot_method));
-  MutexLocker locker(MethodCompileQueue_lock, thread);
-  return CompileBroker::assign_compile_id(method, entry_bci);
+  return CompileBroker::assign_compile_id_unlocked(THREAD, method, entry_bci);
 C2V_END
 
 
+C2V_VMENTRY(jboolean, isMature, (JNIEnv *env, jobject, jlong metaspace_method_data))
+  MethodData* mdo = asMethodData(metaspace_method_data);
+  return mdo != NULL && mdo->is_mature();
+C2V_END
+
 #define CC (char*)  /*cast a literal from (const char*)*/
 #define FN_PTR(f) CAST_FROM_FN_PTR(void*, &(c2v_ ## f))
 
@@ -840,12 +852,12 @@
 #define STACK_TRACE_ELEMENT   "Ljava/lang/StackTraceElement;"
 #define HS_RESOLVED_TYPE      "Lcom/oracle/graal/hotspot/meta/HotSpotResolvedObjectType;"
 #define HS_RESOLVED_METHOD    "Lcom/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod;"
-#define HS_RESOLVED_FIELD     "Lcom/oracle/graal/hotspot/meta/HotSpotResolvedJavaField;"
 #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 METASPACE_KLASS       "J"
 #define METASPACE_METHOD      "J"
+#define METASPACE_METHOD_DATA "J"
 #define METASPACE_CONSTANT_POOL "J"
 
 JNINativeMethod CompilerToVM_methods[] = {
@@ -857,17 +869,17 @@
   {CC"getStackTraceElement",          CC"("METASPACE_METHOD"I)"STACK_TRACE_ELEMENT,                     FN_PTR(getStackTraceElement)},
   {CC"initializeMethod",              CC"("METASPACE_METHOD HS_RESOLVED_METHOD")V",                     FN_PTR(initializeMethod)},
   {CC"doNotInlineOrCompile",          CC"("METASPACE_METHOD")V",                                        FN_PTR(doNotInlineOrCompile)},
-  {CC"isMethodCompilable",            CC"("METASPACE_METHOD")Z",                                        FN_PTR(isMethodCompilable)},
+  {CC"canInlineMethod",               CC"("METASPACE_METHOD")Z",                                        FN_PTR(canInlineMethod)},
+  {CC"shouldInlineMethod",            CC"("METASPACE_METHOD")Z",                                        FN_PTR(shouldInlineMethod)},
   {CC"getCompiledCodeSize",           CC"("METASPACE_METHOD")I",                                        FN_PTR(getCompiledCodeSize)},
   {CC"lookupType",                    CC"("STRING CLASS"Z)"METASPACE_KLASS,                             FN_PTR(lookupType)},
   {CC"lookupConstantInPool",          CC"("METASPACE_CONSTANT_POOL"I)"OBJECT,                           FN_PTR(lookupConstantInPool)},
-  {CC"lookupAppendixInPool",          CC"("METASPACE_CONSTANT_POOL"IB)"OBJECT,                          FN_PTR(lookupAppendixInPool)},
-  {CC"lookupMethodInPool",            CC"("METASPACE_CONSTANT_POOL"IB)"METHOD,                          FN_PTR(lookupMethodInPool)},
-  {CC"lookupTypeInPool",              CC"("METASPACE_CONSTANT_POOL"I)"TYPE,                             FN_PTR(lookupTypeInPool)},
-  {CC"lookupReferencedTypeInPool",    CC"("METASPACE_CONSTANT_POOL"IB)V",                               FN_PTR(lookupReferencedTypeInPool)},
-  {CC"lookupFieldInPool",             CC"("METASPACE_CONSTANT_POOL"IB)"FIELD,                           FN_PTR(lookupFieldInPool)},
+  {CC"lookupAppendixInPool",          CC"("METASPACE_CONSTANT_POOL"I)"OBJECT,                           FN_PTR(lookupAppendixInPool)},
+  {CC"lookupMethodInPool",            CC"("METASPACE_CONSTANT_POOL"IB[J)"METASPACE_METHOD,              FN_PTR(lookupMethodInPool)},
+  {CC"lookupTypeInPool",              CC"("METASPACE_CONSTANT_POOL"I[J)"METASPACE_KLASS,                FN_PTR(lookupTypeInPool)},
+  {CC"loadReferencedTypeInPool",      CC"("METASPACE_CONSTANT_POOL"IB)V",                               FN_PTR(loadReferencedTypeInPool)},
+  {CC"lookupFieldInPool",             CC"("METASPACE_CONSTANT_POOL"IB[J)Z",                             FN_PTR(lookupFieldInPool)},
   {CC"resolveMethod",                 CC"("HS_RESOLVED_TYPE STRING STRING")"METASPACE_METHOD,           FN_PTR(resolveMethod)},
-  {CC"getInstanceFields",             CC"("HS_RESOLVED_TYPE")["HS_RESOLVED_FIELD,                       FN_PTR(getInstanceFields)},
   {CC"getClassInitializer",           CC"("HS_RESOLVED_TYPE")"METASPACE_METHOD,                         FN_PTR(getClassInitializer)},
   {CC"hasFinalizableSubclass",        CC"("HS_RESOLVED_TYPE")Z",                                        FN_PTR(hasFinalizableSubclass)},
   {CC"getMaxCallTargetOffset",        CC"(J)J",                                                         FN_PTR(getMaxCallTargetOffset)},
@@ -888,7 +900,9 @@
   {CC"readUnsafeUncompressedPointer", CC"("OBJECT"J)"OBJECT,                                            FN_PTR(readUnsafeUncompressedPointer)},
   {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"("HS_RESOLVED_METHOD"I)I",                                     FN_PTR(allocateCompileId)},
+  {CC"isMature",                      CC"("METASPACE_METHOD_DATA")Z",                                   FN_PTR(isMature)},
 };
 
 int CompilerToVM_methods_count() {
--- a/src/share/vm/graal/graalGlobals.hpp	Sun Feb 23 17:00:35 2014 -0800
+++ b/src/share/vm/graal/graalGlobals.hpp	Wed Mar 05 19:40:15 2014 -0800
@@ -55,6 +55,12 @@
   product(intx, TraceGraal, 0,                                              \
           "Trace level for Graal")                                          \
                                                                             \
+  product(intx, GraalCounterSize, 0,                                        \
+          "Reserved size for benchmark counters")                           \
+                                                                            \
+  product(bool, GraalCountersExcludeCompiler, true,                         \
+          "Exclude Graal compiler threads from benchmark counters")         \
+                                                                            \
   product(bool, GraalDeferredInitBarriers, true,                            \
           "Defer write barriers of young objects")                          \
                                                                             \
--- a/src/share/vm/graal/graalJavaAccess.hpp	Sun Feb 23 17:00:35 2014 -0800
+++ b/src/share/vm/graal/graalJavaAccess.hpp	Wed Mar 05 19:40:15 2014 -0800
@@ -169,7 +169,6 @@
   end_class                                                                                                                                                    \
   start_class(CompilationResult_Mark)                                                                                                                          \
     oop_field(CompilationResult_Mark, id, "Ljava/lang/Object;")                                                                                                \
-    oop_field(CompilationResult_Mark, references, "[Lcom/oracle/graal/api/code/CompilationResult$Mark;")                                                       \
   end_class                                                                                                                                                    \
   start_class(DebugInfo)                                                                                                                                       \
     oop_field(DebugInfo, bytecodePosition, "Lcom/oracle/graal/api/code/BytecodePosition;")                                                                     \
--- a/src/share/vm/graal/graalVMToCompiler.cpp	Sun Feb 23 17:00:35 2014 -0800
+++ b/src/share/vm/graal/graalVMToCompiler.cpp	Wed Mar 05 19:40:15 2014 -0800
@@ -171,80 +171,3 @@
   JavaCalls::call_interface(&result, vmToCompilerKlass(), vmSymbols::compileTheWorld_name(), vmSymbols::void_method_signature(), &args, THREAD);
   check_pending_exception("Error while calling compileTheWorld");
 }
-
-oop VMToCompiler::createJavaField(Handle holder, Handle name, Handle type, int index, int flags, jboolean internal, TRAPS) {
-  assert(!holder.is_null(), "just checking");
-  assert(!name.is_null(), "just checking");
-  assert(!type.is_null(), "just checking");
-  JavaValue result(T_OBJECT);
-  JavaCallArguments args;
-  args.push_oop(instance());
-  args.push_oop(holder);
-  args.push_oop(name);
-  args.push_oop(type);
-  args.push_int(index);
-  args.push_int(flags);
-  args.push_int(internal);
-  JavaCalls::call_interface(&result, vmToCompilerKlass(), vmSymbols::createJavaField_name(), vmSymbols::createJavaField_signature(), &args, THREAD);
-  check_pending_exception("Error while calling createJavaField");
-  assert(result.get_type() == T_OBJECT, "just checking");
-  return (oop) result.get_jobject();
-}
-
-oop VMToCompiler::createUnresolvedJavaMethod(Handle name, Handle signature, Handle holder, TRAPS) {
-  assert(!name.is_null(), "just checking");
-  JavaValue result(T_OBJECT);
-  JavaCallArguments args;
-  args.push_oop(instance());
-  args.push_oop(name);
-  args.push_oop(signature);
-  args.push_oop(holder);
-  JavaCalls::call_interface(&result, vmToCompilerKlass(), vmSymbols::createUnresolvedJavaMethod_name(), vmSymbols::createUnresolvedJavaMethod_signature(), &args, THREAD);
-  check_pending_exception("Error while calling createUnresolvedJavaMethod");
-  return (oop) result.get_jobject();
-}
-
-oop VMToCompiler::createResolvedJavaMethod(Handle holder, Method* method, TRAPS) {
-  assert(!holder.is_null(), "just checking");
-  assert(method != NULL, "just checking");
-  JavaValue result(T_OBJECT);
-  JavaCallArguments args;
-  args.push_oop(instance());
-  args.push_oop(holder);
-  args.push_long((jlong) (address) method);
-  JavaCalls::call_interface(&result, vmToCompilerKlass(), vmSymbols::createResolvedJavaMethod_name(), vmSymbols::createResolvedJavaMethod_signature(), &args, THREAD);
-  check_pending_exception("Error while calling createResolvedJavaMethod");
-  assert(result.get_type() == T_OBJECT, "just checking");
-  return (oop) result.get_jobject();
-}
-
-oop VMToCompiler::createPrimitiveJavaType(int basic_type, TRAPS) {
-  JavaValue result(T_OBJECT);
-  JavaCallArguments args;
-  args.push_oop(instance());
-  args.push_int(basic_type);
-  JavaCalls::call_interface(&result, vmToCompilerKlass(), vmSymbols::createPrimitiveJavaType_name(), vmSymbols::createPrimitiveJavaType_signature(), &args, THREAD);
-  check_pending_exception("Error while calling createPrimitiveJavaType");
-  return (oop) result.get_jobject();
-}
-
-oop VMToCompiler::createUnresolvedJavaType(Handle name, TRAPS) {
-  assert(!name.is_null(), "just checking");
-  JavaValue result(T_OBJECT);
-  JavaCallArguments args;
-  args.push_oop(instance());
-  args.push_oop(name);
-  JavaCalls::call_interface(&result, vmToCompilerKlass(), vmSymbols::createUnresolvedJavaType_name(), vmSymbols::createUnresolvedJavaType_signature(), &args, THREAD);
-  check_pending_exception("Error while calling createUnresolvedJavaType");
-  return (oop) result.get_jobject();
-}
-
-oop VMToCompiler::createResolvedJavaType(Handle java_mirror, TRAPS) {
-  JavaValue result(T_OBJECT);
-  JavaCallArguments args;
-  args.push_oop(instance());
-  args.push_oop(java_mirror);
-  JavaCalls::call_interface(&result, vmToCompilerKlass(), vmSymbols::createResolvedJavaType_name(), vmSymbols::createResolvedJavaType_signature(), &args, THREAD);
-  check_pending_exception("Error while calling createResolvedJavaType");
-  return (oop) result.get_jobject();
-}
--- a/src/share/vm/graal/graalVMToCompiler.hpp	Sun Feb 23 17:00:35 2014 -0800
+++ b/src/share/vm/graal/graalVMToCompiler.hpp	Wed Mar 05 19:40:15 2014 -0800
@@ -74,24 +74,6 @@
 
   // public abstract void compileTheWorld();
   static void compileTheWorld();
-
-  // public abstract JavaField createJavaField(JavaType holder, String name, JavaType type, int flags, int offset);
-  static oop createJavaField(Handle holder, Handle name, Handle type, int index, int flags, jboolean internal, TRAPS);
-
-  // public abstract JavaMethod createUnresolvedJavaMethod(String name, String signature, JavaType holder);
-  static oop createUnresolvedJavaMethod(Handle name, Handle signature, Handle holder, TRAPS);
-
-  // public abstract JavaMethod createResolvedJavaMethod(JavaType holder, long metaspaceMethod);
-  static oop createResolvedJavaMethod(Handle holder, Method* method, TRAPS);
-
-  // public abstract JavaType createUnresolvedJavaType(String name);
-  static oop createUnresolvedJavaType(Handle name, TRAPS);
-
-  // public abstract ResolvedJavaType createResolvedJavaType(Class javaMirror);
-  static oop createResolvedJavaType(Handle java_mirror, TRAPS);
-
-  // public abstract JavaType createPrimitiveJavaType(int basicType);
-  static oop createPrimitiveJavaType(int basicType, TRAPS);
 };
 
 inline void check_pending_exception(const char* message, bool dump_core = false) {
--- a/src/share/vm/graal/vmStructs_graal.hpp	Sun Feb 23 17:00:35 2014 -0800
+++ b/src/share/vm/graal/vmStructs_graal.hpp	Wed Mar 05 19:40:15 2014 -0800
@@ -34,11 +34,14 @@
 
 #define VM_TYPES_GRAAL(declare_type, declare_toplevel_type)                   \
 
-#define VM_INT_CONSTANTS_GRAAL(declare_constant)                              \
-  declare_constant(Deoptimization::Reason_aliasing)                           \
-  declare_constant(GraalEnv::ok)                                              \
-  declare_constant(GraalEnv::dependencies_failed)                             \
-  declare_constant(GraalEnv::cache_full)                                      \
-  declare_constant(GraalEnv::code_too_large)                                  \
+#define VM_INT_CONSTANTS_GRAAL(declare_constant, declare_preprocessor_constant)                   \
+  declare_constant(Deoptimization::Reason_aliasing)                                               \
+  declare_constant(GraalEnv::ok)                                                                  \
+  declare_constant(GraalEnv::dependencies_failed)                                                 \
+  declare_constant(GraalEnv::cache_full)                                                          \
+  declare_constant(GraalEnv::code_too_large)                                                      \
+                                                                                                  \
+  declare_preprocessor_constant("JVM_ACC_SYNTHETIC", JVM_ACC_SYNTHETIC)                           \
+  declare_preprocessor_constant("JVM_RECOGNIZED_FIELD_MODIFIERS", JVM_RECOGNIZED_FIELD_MODIFIERS) \
 
 #endif // SHARE_VM_GRAAL_VMSTRUCTS_GRAAL_HPP
--- a/src/share/vm/runtime/arguments.cpp	Sun Feb 23 17:00:35 2014 -0800
+++ b/src/share/vm/runtime/arguments.cpp	Wed Mar 05 19:40:15 2014 -0800
@@ -131,9 +131,6 @@
 SystemProperty *Arguments::_java_home = NULL;
 SystemProperty *Arguments::_java_class_path = NULL;
 SystemProperty *Arguments::_sun_boot_class_path = NULL;
-#ifdef GRAAL
-SystemProperty *Arguments::_graal_gpu_isalist = NULL;
-#endif
 
 char* Arguments::_meta_index_path = NULL;
 char* Arguments::_meta_index_dir = NULL;
@@ -197,9 +194,6 @@
   _sun_boot_class_path = new SystemProperty("sun.boot.class.path", NULL,  true);
 
   _java_class_path = new SystemProperty("java.class.path", "",  true);
-#ifdef GRAAL
-  _graal_gpu_isalist = new SystemProperty("graal.gpu.isalist", NULL, true);
-#endif
 
   // Add to System Property list.
   PropertyList_add(&_system_properties, _java_ext_dirs);
@@ -209,9 +203,6 @@
   PropertyList_add(&_system_properties, _java_home);
   PropertyList_add(&_system_properties, _java_class_path);
   PropertyList_add(&_system_properties, _sun_boot_class_path);
-#ifdef GRAAL
-  PropertyList_add(&_system_properties, _graal_gpu_isalist);
-#endif
 
   // Set OS specific system properties values
   os::init_system_properties_values();
@@ -3844,24 +3835,6 @@
     }
   }
 
-#ifdef GRAAL
-  if (_graal_gpu_isalist->value() == NULL) {
-    // Initialize the graal.gpu.isalist system property if
-    // a) it was not explicitly defined by the user and
-    // b) at least one GPU is available.
-    // GPU offload can be disabled by setting the property
-    // to the empty string on the command line
-    if (gpu::is_available() && gpu::has_gpu_linkage()) {
-      if (gpu::get_target_il_type() == gpu::PTX) {
-        _graal_gpu_isalist->append_value("PTX");
-      }
-      if (gpu::get_target_il_type() == gpu::HSAIL) {
-        _graal_gpu_isalist->append_value("HSAIL");
-      }
-    }
-  }
-#endif
-
   return JNI_OK;
 }
 
--- a/src/share/vm/runtime/compilationPolicy.cpp	Sun Feb 23 17:00:35 2014 -0800
+++ b/src/share/vm/runtime/compilationPolicy.cpp	Wed Mar 05 19:40:15 2014 -0800
@@ -163,53 +163,37 @@
 
 bool CompilationPolicy::can_be_offloaded_to_gpu(methodHandle m) {
 #ifdef GRAAL
-  if (GPUOffload) {
-    // Check if this method can be offloaded to GPU.
-    // 1. Offload it to GPU if it is a Lambda method
+  if (GPUOffload && gpu::initialized_gpus() > 0) {
+    // Check if this method can be off-loaded to GPU.
     if (m->is_synthetic()) {
-      // A lambda method is a syntheric method.
+      // A lambda method is a synthetic method.
       Symbol * klass_name = m->method_holder()->name();
       Symbol * method_name = m->name();
-      bool offloadToGPU = false;
       {
         ResourceMark rm;
         if (klass_name != NULL) {
-          if (klass_name != NULL && method_name != NULL) {
-            const char* lambdaPrefix = "lambda$";
-            char* methodPrefix = strstr(method_name->as_C_string(), lambdaPrefix);
-            if (methodPrefix != 0) {
-              if ((strncmp(lambdaPrefix, methodPrefix, strlen(lambdaPrefix)) == 0)) {
-                offloadToGPU = true;
+          const char* javaClass = "java/";
+          // Exclude java library classes - for now
+          if (strncmp(klass_name->as_C_string(), javaClass, strlen(javaClass))) {
+            if (method_name != NULL) {
+              const char* lambdaPrefix = "lambda$";
+              char* methodPrefix = strstr(method_name->as_C_string(), lambdaPrefix);
+              if (methodPrefix != 0) {
+                if ((strncmp(lambdaPrefix, methodPrefix, strlen(lambdaPrefix)) == 0)) {
+                  if (TraceGPUInteraction) {
+                    char buf[O_BUFLEN];
+                    tty->print_cr("Selected lambda method %s for GPU offload", m->name_and_sig_as_C_string(buf, O_BUFLEN));
+                  }
+                  return true;
+                }
               }
             }
           }
         }
       }
-      if (offloadToGPU) {
-        // If GPU is available and the necessary linkage is available
-        // return true indicatin that this method must be compiled.
-        if (gpu::is_available() && gpu::has_gpu_linkage()) {
-          if (TraceGPUInteraction) {
-            tty->print("Compiling Lambda method ");
-            m->print_short_name();
-            switch (gpu::get_target_il_type()) {
-            case gpu::PTX :
-              tty->print_cr("to PTX");
-              break;
-            case gpu::HSAIL :
-              tty->print_cr("to HSAIL");
-              break;
-            default :
-              tty->print_cr("to Unknown GPU!!!");
-            }
-          }
-          return true;
-        }
-      }
     }
   }
 #endif
-
   return false;
 }
 
--- a/src/share/vm/runtime/deoptimization.cpp	Sun Feb 23 17:00:35 2014 -0800
+++ b/src/share/vm/runtime/deoptimization.cpp	Wed Mar 05 19:40:15 2014 -0800
@@ -1347,7 +1347,7 @@
     DeoptReason reason = trap_request_reason(trap_request);
     DeoptAction action = trap_request_action(trap_request);
 #ifdef GRAAL
-    short debug_id = trap_request_debug_id(trap_request);
+    int debug_id = trap_request_debug_id(trap_request);
 #endif
     jint unloaded_class_index = trap_request_index(trap_request); // CP idx or -1
 
@@ -1359,7 +1359,7 @@
     ScopeDesc*      trap_scope  = cvf->scope();
     
     if (TraceDeoptimization) {
-      tty->print_cr("  bci=%d pc=%d, relative_pc=%d, method=%s" GRAAL_ONLY(", debug_id=%d"), trap_scope->bci(), fr.pc(), fr.pc() - nm->code_begin(), trap_scope->method()->name()->as_C_string()
+      tty->print_cr("  bci=%d pc=%d, relative_pc=%d, method=%s" GRAAL_ONLY(", debug_id=%d"), trap_scope->bci(), fr.pc(), fr.pc() - nm->code_begin(), trap_scope->method()->name_and_sig_as_C_string()
 #ifdef GRAAL
           , debug_id
 #endif
@@ -2038,7 +2038,7 @@
   const char* reason = trap_reason_name(trap_request_reason(trap_request));
   const char* action = trap_action_name(trap_request_action(trap_request));
 #ifdef GRAAL
-  short debug_id = trap_request_debug_id(trap_request);
+  int debug_id = trap_request_debug_id(trap_request);
 #endif
   size_t len;
   if (unloaded_class_index < 0) {
--- a/src/share/vm/runtime/deoptimization.hpp	Sun Feb 23 17:00:35 2014 -0800
+++ b/src/share/vm/runtime/deoptimization.hpp	Wed Mar 05 19:40:15 2014 -0800
@@ -294,10 +294,9 @@
       // standard action for unloaded CP entry
       return _unloaded_action;
   }
-  static short trap_request_debug_id(int trap_request) {
+  static int trap_request_debug_id(int trap_request) {
       if (trap_request < 0)
-        return (DeoptAction)
-          ((~(trap_request) >> _debug_id_shift) & right_n_bits(_debug_id_bits));
+        return ((~(trap_request) >> _debug_id_shift) & right_n_bits(_debug_id_bits));
       else
         // standard action for unloaded CP entry
         return 0;
--- a/src/share/vm/runtime/globals.hpp	Sun Feb 23 17:00:35 2014 -0800
+++ b/src/share/vm/runtime/globals.hpp	Wed Mar 05 19:40:15 2014 -0800
@@ -3840,9 +3840,6 @@
   product(bool , AllowNonVirtualCalls, false,                               \
           "Obey the ACC_SUPER flag and allow invokenonvirtual calls")       \
                                                                             \
-  product(bool, UseHSAILSimulator, false,                                   \
-          "Run code on HSAIL Simulator")                                    \
-                                                                            \
   diagnostic(ccstr, SharedArchiveFile, NULL,                                \
           "Override the default location of the CDS archive file")          \
                                                                             \
--- a/src/share/vm/runtime/gpu.cpp	Sun Feb 23 17:00:35 2014 -0800
+++ b/src/share/vm/runtime/gpu.cpp	Wed Mar 05 19:40:15 2014 -0800
@@ -26,85 +26,11 @@
 #include "runtime/gpu.hpp"
 #include "runtime/handles.hpp"
 
-bool gpu::_available = false;    // does the hardware exist?
-bool gpu::_gpu_linkage = false;  // is the driver library to access the GPU installed
-bool gpu::_initialized = false;  // is the GPU device initialized
-gpu::TargetGPUIL gpu::_targetIL = gpu::NONE; // No GPU detected yet.
-
-void gpu::init() {
-#if defined(TARGET_OS_FAMILY_bsd) || defined(TARGET_OS_FAMILY_linux) || defined(TARGET_OS_FAMILY_windows)
-  gpu::probe_gpu();
-  if (gpu::get_target_il_type() == gpu::PTX) {
-    set_gpu_linkage(gpu::Ptx::probe_linkage());
-  } else if (gpu::get_target_il_type() == gpu::HSAIL) {
-    set_gpu_linkage(gpu::Hsail::probe_linkage());
-  } else {
-    set_gpu_linkage(false);
-  }
-#endif
-}
-
-void gpu::initialize_gpu() {
-  if (gpu::has_gpu_linkage()) {
-    if (gpu::get_target_il_type() == gpu::PTX) {
-      set_initialized(gpu::Ptx::initialize_gpu());
-    } else if (gpu::get_target_il_type() == gpu::HSAIL) {
-      set_initialized(gpu::Hsail::initialize_gpu());
-    }
-  }
-}
-
-void * gpu::generate_kernel(unsigned char *code, int code_len, const char *name) {
-  if (gpu::has_gpu_linkage()) {
-    if (gpu::get_target_il_type() == gpu::PTX) {
-      return (gpu::Ptx::generate_kernel(code, code_len, name));
-    } else if (gpu::get_target_il_type() == gpu::HSAIL) {
-      return (gpu::Hsail::generate_kernel(code, code_len, name));
-    }
-  }
-  return NULL;
-}
+int gpu::_initialized_gpus = 0;
 
-bool gpu::execute_kernel(address kernel, PTXKernelArguments & ptxka, JavaValue& ret) {
-    if (gpu::has_gpu_linkage()) {
-        if (gpu::get_target_il_type() == gpu::PTX) {
-            return (gpu::Ptx::execute_kernel(kernel, ptxka, ret));
-        }
-        // Add kernel execution functionality of other GPUs here
+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);
     }
-    return false;
-}
-
-// This is HSAIL specific to work with Sumatra JDK
-bool gpu::execute_kernel_void_1d(address kernel, int dimX, jobject args, methodHandle& mh) {
-    if (gpu::has_gpu_linkage()) {
-        if (gpu::get_target_il_type() == gpu::HSAIL) {
-            return (gpu::Hsail::execute_kernel_void_1d(kernel, dimX, args, mh));
-        }
-    }
-    return false;
-    
 }
-
-
-bool gpu::execute_warp(int dimX, int dimY, int dimZ,
-                       address kernel, PTXKernelArguments & ptxka, JavaValue& ret) {
-    if (gpu::has_gpu_linkage()) {
-        if (gpu::get_target_il_type() == gpu::PTX) {
-            return (gpu::Ptx::execute_warp(dimX, dimY, dimZ, kernel, ptxka, ret));
-        }
-        // Add kernel execution functionality of other GPUs here
-    }
-    return false;
-}
-
-int gpu::available_processors() {
-    if (gpu::has_gpu_linkage()) {
-        if (gpu::get_target_il_type() == gpu::PTX) {
-            return (gpu::Ptx::total_cores());
-        }
-        // Add kernel execution functionality of other GPUs here
-    }
-    return 0;
-}
-
--- a/src/share/vm/runtime/gpu.hpp	Sun Feb 23 17:00:35 2014 -0800
+++ b/src/share/vm/runtime/gpu.hpp	Wed Mar 05 19:40:15 2014 -0800
@@ -27,85 +27,23 @@
 
 #include "runtime/atomic.hpp"
 #include "oops/symbol.hpp"
-
-class PTXKernelArguments;
-
-// gpu defines the interface to the graphics processor; this includes traditional
-// GPU services such as graphics kernel load and execute.
-
-
-class gpu: AllStatic {
-public:
-
-  enum TargetGPUIL { NONE = 0, PTX = 1, HSAIL = 2};
-  static void init(void);
-
-  static void probe_gpu();
-
-  static void initialize_gpu();
+#include "utilities/array.hpp"
 
-  static int available_processors();
-  
-  static void * generate_kernel(unsigned char *code, int code_len, const char *name);
-
-  static bool execute_warp(int dimX, int dimY, int dimZ,
-                           address kernel, PTXKernelArguments & ptxka, JavaValue & ret);
-
-  static bool execute_kernel(address kernel, PTXKernelArguments & ptxka, JavaValue & ret);
+// Defines the interface to the graphics processor(s).
+class gpu : AllStatic {
+ private:
+  static int _initialized_gpus;  // number of initialize GPU devices
 
-  // No return value from HSAIL kernels
-  static bool execute_kernel_void_1d(address kernel, int dimX, jobject args, methodHandle& mh);
-
-  static void set_available(bool value) {
-    _available = value;
-  }
-
-  static bool is_available() { return _available; }
-
-  static void set_initialized(bool value) {
-    _initialized = value;
-  }
+ public:
 
-  static bool is_initialized() { return _initialized; }
-
-  static void set_gpu_linkage(bool value) {
-    _gpu_linkage = value;
-  }
-
-  static bool has_gpu_linkage() { return _gpu_linkage; }
-
-  static void set_target_il_type(TargetGPUIL value) {
-    _targetIL = value;
-  }
-
-  static enum gpu::TargetGPUIL get_target_il_type() {
-    return _targetIL;
-  }
+  // Notification of a GPU device that has been initialized.
+  static void initialized_gpu(const char* name);
 
-protected:
-  static bool _available;
-  static bool _gpu_linkage;
-  static bool _initialized;
-  static TargetGPUIL _targetIL;
-
-  // Platform dependent stuff
-#ifdef TARGET_OS_FAMILY_linux
-# include "gpu_linux.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_solaris
-#endif
-#ifdef TARGET_OS_FAMILY_windows
-# include "gpu_windows.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_bsd
-# include "gpu_bsd.hpp"
-#endif
-
-public:
-# include "ptx/vm/gpu_ptx.hpp"
-# include "hsail/vm/gpu_hsail.hpp"
-
+  // 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; }
 };
 
-
 #endif // SHARE_VM_RUNTIME_GPU_HPP
--- a/src/share/vm/runtime/sharedRuntime.hpp	Sun Feb 23 17:00:35 2014 -0800
+++ b/src/share/vm/runtime/sharedRuntime.hpp	Wed Mar 05 19:40:15 2014 -0800
@@ -402,6 +402,12 @@
                                                       const VMRegPair *regs,
                                                       AdapterFingerPrint* fingerprint);
 
+  static void gen_i2c_adapter(MacroAssembler *_masm,
+                              int total_args_passed,
+                              int comp_args_on_stack,
+                              const BasicType *sig_bt,
+                              const VMRegPair *regs);
+
   // OSR support
 
   // OSR_migration_begin will extract the jvm state from an interpreter
--- a/src/share/vm/runtime/thread.cpp	Sun Feb 23 17:00:35 2014 -0800
+++ b/src/share/vm/runtime/thread.cpp	Wed Mar 05 19:40:15 2014 -0800
@@ -1418,31 +1418,27 @@
 
 #ifdef GRAAL
 
-#if GRAAL_COUNTERS_SIZE > 0
-jlong JavaThread::_graal_old_thread_counters[GRAAL_COUNTERS_SIZE];
+jlong* JavaThread::_graal_old_thread_counters;
 
 bool graal_counters_include(oop threadObj) {
-  return !GRAAL_COUNTERS_EXCLUDE_COMPILER_THREADS || threadObj == NULL || threadObj->klass() != SystemDictionary::CompilerThread_klass();
+  return !GraalCountersExcludeCompiler || threadObj == NULL || threadObj->klass() != SystemDictionary::CompilerThread_klass();
 }
 
 void JavaThread::collect_counters(typeArrayOop array) {
-  MutexLocker tl(Threads_lock);
-  for (int i = 0; i < array->length(); i++) {
-    array->long_at_put(i, _graal_old_thread_counters[i]);
-  }
-  for (JavaThread* tp = Threads::first(); tp != NULL; tp = tp->next()) {
-    if (graal_counters_include(tp->threadObj())) {
-      for (int i = 0; i < array->length(); i++) {
-        array->long_at_put(i, array->long_at(i) + tp->_graal_counters[i]);
+  if (GraalCounterSize > 0) {
+    MutexLocker tl(Threads_lock);
+    for (int i = 0; i < array->length(); i++) {
+      array->long_at_put(i, _graal_old_thread_counters[i]);
+    }
+    for (JavaThread* tp = Threads::first(); tp != NULL; tp = tp->next()) {
+      if (graal_counters_include(tp->threadObj())) {
+        for (int i = 0; i < array->length(); i++) {
+          array->long_at_put(i, array->long_at(i) + tp->_graal_counters[i]);
+        }
       }
     }
   }
 }
-#else
-void JavaThread::collect_counters(typeArrayOop array) {
-  // empty
-}
-#endif // GRAAL_COUNTERS_SIZE > 0
 
 #endif // GRAAL
 
@@ -1486,11 +1482,12 @@
   _graal_alternate_call_target = NULL;
   _graal_implicit_exception_pc = NULL;
   _graal_compiling = false;
-#if GRAAL_COUNTERS_SIZE > 0
-  for (int i = 0; i < GRAAL_COUNTERS_SIZE; i++) {
-    _graal_counters[i] = 0;
+  if (GraalCounterSize > 0) {
+    _graal_counters = NEW_C_HEAP_ARRAY(jlong, GraalCounterSize, mtInternal);
+    memset(_graal_counters, 0, sizeof(jlong) * GraalCounterSize);
+  } else {
+    _graal_counters = NULL;
   }
-#endif // GRAAL_COUNTER_SIZE > 0
 #endif // GRAAL
   (void)const_cast<oop&>(_exception_oop = NULL);
   _exception_pc  = 0;
@@ -1680,13 +1677,14 @@
   if (_thread_profiler != NULL) delete _thread_profiler;
   if (_thread_stat != NULL) delete _thread_stat;
 
-#if defined(GRAAL) && (GRAAL_COUNTERS_SIZE > 0)
-  if (graal_counters_include(threadObj())) {
-    for (int i = 0; i < GRAAL_COUNTERS_SIZE; i++) {
+#ifdef GRAAL
+  if (GraalCounterSize > 0 && graal_counters_include(threadObj())) {
+    for (int i = 0; i < GraalCounterSize; i++) {
       _graal_old_thread_counters[i] += _graal_counters[i];
     }
+    FREE_C_HEAP_ARRAY(jlong, _graal_counters, mtInternal);
   }
-#endif
+#endif // GRAAL
 }
 
 
@@ -3394,14 +3392,6 @@
   jint parse_result = Arguments::parse(args);
   if (parse_result != JNI_OK) return parse_result;
 
-#ifdef GRAAL
-  if (GPUOffload) {
-    // Probe for existance of supported GPU and initialize it if one
-    // exists.
-    gpu::init();
-  }
-#endif
-
   os::init_before_ergo();
 
   jint ergo_result = Arguments::apply_ergo();
@@ -3461,6 +3451,15 @@
   // Initialize global data structures and create system classes in heap
   vm_init_globals();
 
+#ifdef GRAAL
+  if (GraalCounterSize > 0) {
+    JavaThread::_graal_old_thread_counters = NEW_C_HEAP_ARRAY(jlong, GraalCounterSize, mtInternal);
+    memset(JavaThread::_graal_old_thread_counters, 0, sizeof(jlong) * GraalCounterSize);
+  } else {
+    JavaThread::_graal_old_thread_counters = NULL;
+  }
+#endif // GRAAL
+
   // Attach the main thread to this os thread
   JavaThread* main_thread = new JavaThread();
   main_thread->set_thread_state(_thread_in_vm);
@@ -4112,6 +4111,12 @@
 
   delete thread;
 
+#ifdef GRAAL
+  if (GraalCounterSize > 0) {
+    FREE_C_HEAP_ARRAY(jlong, JavaThread::_graal_old_thread_counters, mtInternal);
+  }
+#endif // GRAAL
+
   // exit_globals() will delete tty
   exit_globals();
 
--- a/src/share/vm/runtime/thread.hpp	Sun Feb 23 17:00:35 2014 -0800
+++ b/src/share/vm/runtime/thread.hpp	Wed Mar 05 19:40:15 2014 -0800
@@ -922,16 +922,10 @@
   address   _graal_implicit_exception_pc;  // pc at which the most recent implicit exception occurred
   bool      _graal_compiling;
 
-  // number of counters, increase as needed. 0 == disabled
-#define GRAAL_COUNTERS_SIZE (0)
-#define GRAAL_COUNTERS_EXCLUDE_COMPILER_THREADS (true)
-
-#if GRAAL_COUNTERS_SIZE > 0
-  jlong     _graal_counters[GRAAL_COUNTERS_SIZE];
-  static jlong _graal_old_thread_counters[GRAAL_COUNTERS_SIZE];
-#endif // GRAAL_COUNTERS_SIZE > 0
+  jlong*    _graal_counters;
 
  public:
+  static jlong* _graal_old_thread_counters;
   static void collect_counters(typeArrayOop array);
  private:
 #endif // GRAAL
@@ -1394,11 +1388,7 @@
 #ifdef GRAAL
   static ByteSize graal_alternate_call_target_offset() { return byte_offset_of(JavaThread, _graal_alternate_call_target); }
   static ByteSize graal_implicit_exception_pc_offset() { return byte_offset_of(JavaThread, _graal_implicit_exception_pc); }
-#if GRAAL_COUNTERS_SIZE > 0
   static ByteSize graal_counters_offset()        { return byte_offset_of(JavaThread, _graal_counters      ); }
-#else
-  static ByteSize graal_counters_offset()        { return in_ByteSize(0); }
-#endif // GRAAL_COUNTERS_SIZE > 0
 #endif // GRAAL
   static ByteSize exception_oop_offset()         { return byte_offset_of(JavaThread, _exception_oop       ); }
   static ByteSize exception_pc_offset()          { return byte_offset_of(JavaThread, _exception_pc        ); }
--- a/src/share/vm/runtime/vmStructs.cpp	Sun Feb 23 17:00:35 2014 -0800
+++ b/src/share/vm/runtime/vmStructs.cpp	Wed Mar 05 19:40:15 2014 -0800
@@ -568,8 +568,6 @@
   nonstatic_field(Space,                       _bottom,                                       HeapWord*)                             \
   nonstatic_field(Space,                       _end,                                          HeapWord*)                             \
                                                                                                                                      \
-     static_field(HeapRegion,                  LogOfHRGrainBytes,                             int)                                   \
-                                                                                                                                     \
   nonstatic_field(ThreadLocalAllocBuffer,      _start,                                        HeapWord*)                             \
   nonstatic_field(ThreadLocalAllocBuffer,      _top,                                          HeapWord*)                             \
   nonstatic_field(ThreadLocalAllocBuffer,      _end,                                          HeapWord*)                             \
@@ -813,6 +811,34 @@
      static_field(StubRoutines,                _cipherBlockChaining_decryptAESCrypt,          address)                               \
      static_field(StubRoutines,                _updateBytesCRC32,                             address)                               \
      static_field(StubRoutines,                _crc_table_adr,                                address)                               \
+     static_field(StubRoutines,                _jbyte_arraycopy,                              address)                               \
+     static_field(StubRoutines,                _jshort_arraycopy,                             address)                               \
+     static_field(StubRoutines,                _jint_arraycopy,                               address)                               \
+     static_field(StubRoutines,                _jlong_arraycopy,                              address)                               \
+     static_field(StubRoutines,                _oop_arraycopy,                                address)                               \
+     static_field(StubRoutines,                _oop_arraycopy_uninit,                         address)                               \
+     static_field(StubRoutines,                _jbyte_disjoint_arraycopy,                     address)                               \
+     static_field(StubRoutines,                _jshort_disjoint_arraycopy,                    address)                               \
+     static_field(StubRoutines,                _jint_disjoint_arraycopy,                      address)                               \
+     static_field(StubRoutines,                _jlong_disjoint_arraycopy,                     address)                               \
+     static_field(StubRoutines,                _oop_disjoint_arraycopy,                       address)                               \
+     static_field(StubRoutines,                _oop_disjoint_arraycopy_uninit,                address)                               \
+     static_field(StubRoutines,                _arrayof_jbyte_arraycopy,                      address)                               \
+     static_field(StubRoutines,                _arrayof_jshort_arraycopy,                     address)                               \
+     static_field(StubRoutines,                _arrayof_jint_arraycopy,                       address)                               \
+     static_field(StubRoutines,                _arrayof_jlong_arraycopy,                      address)                               \
+     static_field(StubRoutines,                _arrayof_oop_arraycopy,                        address)                               \
+     static_field(StubRoutines,                _arrayof_oop_arraycopy_uninit,                 address)                               \
+     static_field(StubRoutines,                _arrayof_jbyte_disjoint_arraycopy,             address)                               \
+     static_field(StubRoutines,                _arrayof_jshort_disjoint_arraycopy,            address)                               \
+     static_field(StubRoutines,                _arrayof_jint_disjoint_arraycopy,              address)                               \
+     static_field(StubRoutines,                _arrayof_jlong_disjoint_arraycopy,             address)                               \
+     static_field(StubRoutines,                _arrayof_oop_disjoint_arraycopy,               address)                               \
+     static_field(StubRoutines,                _arrayof_oop_disjoint_arraycopy_uninit,        address)                               \
+     static_field(StubRoutines,                _checkcast_arraycopy,                          address)                               \
+     static_field(StubRoutines,                _checkcast_arraycopy_uninit,                   address)                               \
+     static_field(StubRoutines,                _unsafe_arraycopy,                             address)                               \
+     static_field(StubRoutines,                _generic_arraycopy,                            address)                               \
                                                                                                                                      \
   /*****************/                                                                                                                \
   /* SharedRuntime */                                                                                                                \
@@ -1505,8 +1531,6 @@
            declare_type(EdenSpace,                    ContiguousSpace)    \
            declare_type(OffsetTableContigSpace,       ContiguousSpace)    \
            declare_type(TenuredSpace,                 OffsetTableContigSpace) \
-           declare_type(G1OffsetTableContigSpace,     ContiguousSpace)    \
-           declare_type(HeapRegion,                   G1OffsetTableContigSpace) \
   declare_toplevel_type(BarrierSet)                                       \
            declare_type(ModRefBarrierSet,             BarrierSet)         \
            declare_type(CardTableModRefBS,            ModRefBarrierSet)   \
@@ -2312,6 +2336,9 @@
   declare_constant(JVM_ACC_PROMOTED_FLAGS)                                \
   declare_constant(JVM_ACC_FIELD_ACCESS_WATCHED)                          \
   declare_constant(JVM_ACC_FIELD_MODIFICATION_WATCHED)                    \
+  declare_constant(JVM_ACC_FIELD_INTERNAL)                                \
+  declare_constant(JVM_ACC_FIELD_STABLE)                                  \
+  declare_constant(JVM_ACC_FIELD_HAS_GENERIC_SIGNATURE)                   \
                                                                           \
   declare_constant(JVM_CONSTANT_Utf8)                                     \
   declare_constant(JVM_CONSTANT_Unicode)                                  \
@@ -2467,13 +2494,14 @@
                                                                           \
   declare_constant(Symbol::max_symbol_length)                             \
                                                                           \
-  /*************************************************/                     \
-  /* ConstantPool* layout enum for InvokeDynamic */                     \
-  /*************************************************/                     \
+  /***********************************************/                       \
+  /* ConstantPool* layout enum for InvokeDynamic */                       \
+  /***********************************************/                       \
                                                                           \
-  declare_constant(ConstantPool::_indy_bsm_offset)                 \
-  declare_constant(ConstantPool::_indy_argc_offset)                \
-  declare_constant(ConstantPool::_indy_argv_offset)                \
+  declare_constant(ConstantPool::_indy_bsm_offset)                        \
+  declare_constant(ConstantPool::_indy_argc_offset)                       \
+  declare_constant(ConstantPool::_indy_argv_offset)                       \
+  declare_constant(ConstantPool::CPCACHE_INDEX_TAG)                       \
                                                                           \
   /********************************/                                      \
   /* ConstantPoolCacheEntry enums */                                      \
@@ -3060,7 +3088,8 @@
                    GENERATE_C2_PREPROCESSOR_VM_INT_CONSTANT_ENTRY)
 
 #ifdef GRAAL
-  VM_INT_CONSTANTS_GRAAL(GENERATE_VM_INT_CONSTANT_ENTRY)
+  VM_INT_CONSTANTS_GRAAL(GENERATE_VM_INT_CONSTANT_ENTRY,
+                         GENERATE_PREPROCESSOR_VM_INT_CONSTANT_ENTRY)
 #endif
 
 #if INCLUDE_ALL_GCS